mickey
mickey

Reputation: 413

OpenGl texture questions

Texturing headache...

I can't understand where i go wrong here. My problem is that the texture is not aligned. The image on the left is the OpenGl textured quad, and the right is the original. Notice how the columns are offset in the textured quad.

Mis-aligned texture

I don't know if i am not loading the texture properly, or make a mistake during uploading it to videomemory, or simply use the wrong texCoords...

The image is a bmp (R8 G8 B8 A8) and the mistake lies somewhere in here:

(Loading of bitmap and uploading of texture)

        Bitmap fontBmp = new Bitmap("font2.bmp");
        MemoryStream ms = new MemoryStream();

        fontBmp.Save(ms, ImageFormat.Bmp);
        int imageWidth = fontBmp.Width;
        int imageHeight = fontBmp.Height;
        byte[] fontBytes = ms.GetBuffer();
        fontBmp.Dispose();
        ms.Dispose();

        Gl.glBindTexture(Gl.GL_TEXTURE_2D, (int)TexId.font);
        Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);
        Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
        Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);
        Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
        Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
        Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_MODULATE); // Try GL_DECAL...
        Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, imageWidth, imageHeight, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, fontBytes);

(The quad...)

        Gl.glTexCoord2f(0f + (0.5f / 128f), (127f / 128f) + (0.5f / 128f));
        Gl.glVertex2i(50, 50);

        Gl.glTexCoord2f(0f + (0.5f / 128f), 0f + (0.5f / 128f)); 
        Gl.glVertex2i(50, this.Height - 50);

        Gl.glTexCoord2f((127f / 128f) + (0.5f / 128f), 0f + (0.5f / 128f)); 
        Gl.glVertex2i(this.Width - 50, this.Height - 50);

        Gl.glTexCoord2f((127f / 128f) + (0.5f / 128f), (127f / 128f) + (0.5f / 128f)); 
        Gl.glVertex2i(this.Width - 50, 50);

Does anyone spot anything causing this?

Upvotes: 1

Views: 966

Answers (2)

Ben Voigt
Ben Voigt

Reputation: 283941

The problem is NOT your texture coordinates.

The problem is that you're loading the texture wrong. You're forgetting to remove the bitmap header, so all the real data is shifted over, and the end of each line is shifted onto the beginning of the next line.

Texture wrapping would wrap pixels from the right back onto the same line, but the out-of-place region is shifted down one row. Texture wrapping also wouldn't occur with the "clamp to edge" mode you've enabled.

Upvotes: 2

jakeva
jakeva

Reputation: 2835

Your problem is your glTexCoord coordinates. If you do

    Gl.glTexCoord2f(0f, 0f);
    Gl.glVertex2i(50, 50);

    Gl.glTexCoord2f(0f, 1f); 
    Gl.glVertex2i(50, this.Height - 50);

    Gl.glTexCoord2f(1f, 1f); 
    Gl.glVertex2i(this.Width - 50, this.Height - 50);

    Gl.glTexCoord2f(1f, 0f); 
    Gl.glVertex2i(this.Width - 50, 50);

,for instance, it should give you aligned positioning. Texture coordinates are from 0 to 1. If you changed the 1's to 2's in my example, your texture would repeat twice in each direction giving you four copies of it on that quad.

Note, this is untested code, I may have the wrong order of texture coordinates, but the point is that you should not use pixel dimensions but rather parameterize your texture dimensions to a [0,1] scale.

The reason is your texture parameters are set to wrap. Taking 0 to mean the beginning of the texture and 1 to mean 100% of its dimension, if you specify some non integer, then it will begin or end in the middle of your texture, whereas any nonzero integer is some multiple of the size of your texture and so it will appear to repeat.

EDIT: This is also required to get the effect I'm talking about, to replace the setting you have for the GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T.

    Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
    Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);

Upvotes: 0

Related Questions