Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to render a Texture via OpenGL. But instead of the texture black circles on a green background are rendered. (They scale, depending what the rotation of the texture is)

Example:

enter image description here

The texture I'm trying to render is the following:

enter image description here

This is the code I use to render the texture, it's located in my Sprite-class.

    public void Render()
    {
        Matrix4 matrix = Matrix4.CreateTranslation(-OriginX, -OriginY, 0) *
                        Matrix4.CreateRotationZ(Rotation) *
                        Matrix4.CreateTranslation(X, Y, 0);


        Vector2[] corners =
        {
            new Vector2(0,0), //top left
            new Vector2(Width ,0),//top right
            new Vector2(Width,Height),//bottom rigth
            new Vector2(0,Height)//bottom left
        };

        //copy the corners to the uv coordinates
        Vector2[] uv = corners.ToArray<Vector2>();

//transform the coordinates
        for (int i = 0; i < 4; i++) corners[i] = new Vector2(Vector3.Transform(new Vector3(corners[i]), matrix));
        //GL.Color3(TintColor);
        GL.BindTexture(TextureTarget.Texture2D, _ID);
        GL.Begin(BeginMode.Quads);
        {
            for (int i = 0; i < 4; i++)
            {
                GL.TexCoord2(uv[i]);
                GL.Vertex3(corners[i].X, corners[i].Y, _layerDepth);
            }
        }
        GL.End();

        if (EnableDebugDraw)
        {
            GL.Color3(Color.Violet);
            GL.PointSize(3);
            GL.Begin(BeginMode.Points);
            {
                for (int i = 0; i < 4; i++) GL.Vertex2(corners[i]);
            }
            GL.End();

            GL.Color3(Color.Green);
            GL.Begin(BeginMode.Points);
            GL.Vertex2(X, Y);
            GL.End();
        }

    }

This is how I setup OpenGL.

    public static void SetupGL()
    {
        GL.Enable(EnableCap.AlphaTest);
        GL.AlphaFunc(AlphaFunction.Greater, 0.1f);

        GL.Enable(EnableCap.Texture2D);
        GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);

    }

With this function I load the texture:

public static uint LoadTexture(string path)
    {
        uint id;
        GL.GenTextures(1, out id);
        GL.BindTexture(TextureTarget.Texture2D, id);

        Bitmap bitmap = new Bitmap(path);

        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);
        return id;
    }

And here I call Sprite.Render()

protected override void OnRenderFrame(FrameEventArgs e)
    {
        GL.ClearColor(Color.MidnightBlue);
        GL.Clear(ClearBufferMask.ColorBufferBit);
        _sprite.Render();
        SwapBuffers();
        base.OnRenderFrame(e);
    }

As I stole this code from the Textures-Example from OpenTK, I don't understand why this doesn't work.

share|improve this question

2 Answers 2

up vote 5 down vote accepted

First of all, your UVs look suspicious to me:

    Vector2[] corners =
    {
        new Vector2(0,0), //top left
        new Vector2(Width ,0),//top right
        new Vector2(Width,Height),//bottom rigth
        new Vector2(0,Height)//bottom left
    };

    //copy the corners to the uv coordinates
    Vector2[] uv = corners.ToArray<Vector2>();

Normally the UVs for a sprite would range from 0 to 1, not from 0 to width/height. This is probably why you've got a bunch of circles showing up; your UV mapping is accidentally squeezing the texture down to a tiny size and causing those circles to appear as an artifact.

Second, your texture loading logic looks suspicious. Your LockBits call specifies ARGB format, while your TexImage2D call specifies RGBA internal format. I'm not sure which is the correct one, but presumably they should match. This could be why the texture is turning green and black - the color channels are getting swapped around wrongly.

share|improve this answer
    
You're right. That's the reason there are multiple circles. The uv space is [0,1] and by default the sampler wraps around when the index is out of bounds. –  rootlocus Nov 20 '12 at 18:30
    
With the fixed uvs I now see my picture, however the colors are strange (white is green). According to this stackoverflow.com/questions/11645368/… the format is correct –  vinzBad Nov 20 '12 at 18:39
    
When I disable the debug-view, my texture gets rendered correctly :) –  vinzBad Nov 20 '12 at 18:42
3  
@vinzBad Ahh, that's because the GL.Color3(Color.Green) in the debug-draw code is remaining in effect. You can cancel it by adding a call to set the color to white before drawing your sprites. –  Nathan Reed Nov 20 '12 at 18:57
    
yep, this solved it :) –  vinzBad Nov 20 '12 at 18:57

Have a close look at this part of the code:

Bitmap bitmap = new Bitmap(path);

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
);

There seems to be a difference between the format of your BitmapData ( Format32bppArgb ) and the format you specify to GL.TexImage2D.

Also, having a quick look at the API page for glTexImage2D you can see that the internalformat and format parameters must have the same value. Yours differ: Rgba, Bgra. Make sure you use the same format everywhere ( namely Argb ).

Hope this helps.

share|improve this answer
    
According to this is the format just right: stackoverflow.com/a/11672859/725126 –  vinzBad Nov 20 '12 at 18:42

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.