Smilinger's picture

Nothing but the background is drawn

Hi :)

I have started learning OpenGL, but I have run into two problems. My program is 2D and so far I have tried to draw primitives (triangle fan, polygon and quads) and now I also want to try applying textures to quads. For some reason, the texture is not drawn (I have used the example code and also read some code found on this forum). I found a topic about textures not drawn on some computers, so I tried to run my program on a friend's computer. But she cannot even see the primitives! I have searched Google, and I think I have to use Vertex Arrays, but I am not that far in learning yet, so is there some way I can get it to work without?

So, to sum up:

* Primitives (triangle fan, polygon and quad) are not drawn on some computers
* Textures does not show up on any computer.

If anyone is interested, the code is as follows:

    class Program
    {
        static int GameWidth = 1024;
        static int GameHeight = 768;
 
        static int texture;
 
        static void Main(string[] args)
        {
            GameWindow gw = new GameWindow(GameWidth, GameHeight);
 
            gw.Load += new EventHandler<EventArgs>(gw_Load);
            gw.RenderFrame += new EventHandler<FrameEventArgs>(gw_RenderFrame);
            gw.Resize += new EventHandler<EventArgs>(gw_Resize);
            gw.Unload += new EventHandler<EventArgs>(gw_Unload);
 
            gw.Run();
 
            //Console.Read();
        }
 
        static void gw_Unload(object sender, EventArgs e)
        {
            GL.DeleteTextures(1, ref texture);
        }
 
        static void gw_Load(object sender, EventArgs e)
        {
            Bitmap bitmap = new Bitmap("falling1.png");
            GL.Enable(EnableCap.Texture2D);
 
            GL.GenTextures(1, out texture);
            GL.BindTexture(TextureTarget.Texture2D, texture);
 
            BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
 
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
                OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
 
            bitmap.UnlockBits(data);
 
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
        }
 
        static void gw_Resize(object sender, EventArgs e)
        {
            GameWindow gw = (GameWindow)sender;
            int w = gw.Width;
            int h = gw.Height;
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(0, GameWidth, 0, GameHeight, -1, 1); // Bottom-left corner pixel has coordinate (0, 0)
            GL.DepthFunc(DepthFunction.Never);
            GL.Viewport(0, 0, w, h); // Use all of the glControl painting area
        }
 
        static void gw_RenderFrame(object sender, FrameEventArgs e)
        {
            GameWindow gw = (GameWindow)sender;
            GL.Clear(ClearBufferMask.ColorBufferBit);
 
            GL.ClearColor(Color.SkyBlue);
 
            GL.MatrixMode(MatrixMode.Modelview);
 
            DrawGround(gw);
            DrawSun();
            DrawPiece();
 
            gw.SwapBuffers();
        }
 
        public static void DrawPiece()
        {
            GL.LoadIdentity();
            GL.BindTexture(TextureTarget.Texture2D, texture);
 
            GL.Translate(100, 100, 0);
 
            GL.Begin(BeginMode.Quads);
 
            //GL.Color3(Color.Red);
            GL.TexCoord2(0.0f, 0.0f); GL.Vertex2(0, 0);
            GL.TexCoord2(1.0f, 0f); GL.Vertex2(30, 0);
            GL.TexCoord2(1.0f, 1.0f); GL.Vertex2(30, 120);
            GL.TexCoord2(0.0f, 1.0f); GL.Vertex2(0, 120);
 
            GL.End();
        }
 
        public static void DrawSun()
        {
            float radius = 120.0f;
            int steps = 12;
 
            float step = (2.0f * (float)Math.PI) / steps;
 
            GL.LoadIdentity();
            GL.Translate(200, 600, 0);
 
            GL.Enable(EnableCap.Blend);
            //GL.BlendFunc(BlendingFactorSrc.OneMinusDstAlpha, BlendingFactorDest.DstAlpha);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
 
            GL.Begin(BeginMode.TriangleFan);
            GL.Color3(1.0F, 0.890f, 0.694f);
            GL.Vertex2(0, 0);
 
 
            GL.Color4(1.0F, 0.890f, 0.694f, 0);
 
            for (float t = 0; t <= (2*Math.PI+0.01); t += step)
            {
                GL.Vertex2(radius * (float)Math.Cos(t), radius * (float)Math.Sin(t));
            }
 
            GL.Disable(EnableCap.Blend);
 
            GL.End();
        }
 
        public static void DrawGround(GameWindow gameWindow)
        {
            // TODO: precompute these points
            int points = 100;
            int groundHeight = 200;
            int hillHeight = 70;
 
            Vector2[] bezPoints = new Vector2[3] { new Vector2(0, groundHeight), new Vector2(GameWidth / 2, groundHeight+hillHeight), new Vector2(GameWidth, groundHeight) };
            BezierCurve bz = new BezierCurve(bezPoints);
            Vector2[] approxPoints = new Vector2[points];
 
            float step = 1.0f / points;
            float t = step;
            for (int i = 1; i < points-1; i++)
            {
                approxPoints[i] = bz.CalculatePoint(t);
                t += step;
            }
 
            approxPoints[0] = bezPoints[0];
            approxPoints[points - 1] = bezPoints[2];
 
            GL.LoadIdentity();
 
 
 
            // TODO: Change to QUAD
            GL.Begin(BeginMode.Polygon);
            GL.Color3(Color.DarkGreen);
            GL.Vertex2(GameWidth, groundHeight);
            GL.Color3(Color.Green);
            GL.Vertex2(GameWidth, 0);
            GL.Vertex2(0, 0);
            GL.Color3(Color.DarkGreen);
            GL.Vertex2(0, groundHeight);
 
            GL.Color3(Color.DarkGreen);
            for (int j = 1; j < points-1; j++)
            {
                GL.Vertex2(approxPoints[j]);
            }
 
            GL.End();
        }
    }

DrawPiece uses a texture on a quad
DrawGround uses polygon
DrawSun uses triangle fan

I am aware that a lot of the code can be optimized, but if you do have any ideas that you think I might not though of, please do tell :)

Thanks in advance

Mark

Inline Images

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Smilinger's picture

Update: A simple triangle works on both computers. But the other things still do not.
Update 2: I have discovered the GetError function! It seems that the ground-function works (Polygon), but when I try to draw the sun with TriangleFan, I get InvalidOperation. The error comes exactly after calling GL.Begin(BeginMode.TriangleFan);

FingersLingers's picture

Runs on my machine, Also Gave Inv Operation, Your Blend was a bit wrong, here is the corrected DrawSun() function, Also on mine it is displaying the texture (My wierd Texture) on the screen in the ground just under the sun

        public static void DrawSun() {
            float radius = 120.0f;
            int steps = 12;
 
            float step = (2.0f * (float)Math.PI) / steps;
 
            GL.LoadIdentity();
            GL.Translate(200, 600, 0);
 
            GL.Enable(EnableCap.Blend);
            //GL.BlendFunc(BlendingFactorSrc.OneMinusDstAlpha, BlendingFactorDest.DstAlpha);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
 
            GL.Begin(BeginMode.TriangleFan);
            GL.Color4(1.0f, 0.890f, 0.694f, 1.0f);
            GL.Vertex2(0, 0);
 
 
 
            for (float t = 0; t <= (2 * Math.PI + 0.01); t += step) {
                GL.Color4(1.0f, 0.890f, 0.694f, 0.0f);
                GL.Vertex2(radius * (float)Math.Cos(t), radius * (float)Math.Sin(t));
            }
 
            GL.End();
 
            GL.Disable(EnableCap.Blend);
        }

Regards :D

Smilinger's picture

Thank you for your corrections! I should enable (and then disable) blending only when I need it, right? Everything works for me now, also the textures. I had forgotten that the height and width had to be powers of two (then I just need a nice way to apply it to quads with H and W which are not powers of 2).

I still get the Operation Invalid when drawing the sun, though, so I am guessing that it still doesn't work on my friend's computer (she's AFK at the moment). The textures work for her, though, so I do have some progress :).

FingersLingers's picture

Great to Hear, but a point to help, To check if you can use Non-Power of Two Textures, Use something like this

if ((GL.GetString(StringName.Extensions).IndexOf("ARB_texture_non_power_of_two")<0) {
 // Oh heck, we cannot use Non-Power of Two Textures
}

Also, To use POT tex with a funny looking quad, easiest way to map it is to adjust your Tex Coords.

Regards :D

Smilinger's picture

Cool, thanks. I guess my computer kind of sucks when my gfx card doesn't have support for NPOT textures :P

FingersLingers's picture

LOL, Don't feel alone bro, My secondary Dev machine runs a ATI Radeon that supports GL4, BUT it has issues with NPOT Textures ...... So don't feel left out :D