2

I am about to go mad because of texture mapping of openGL. It nevers maps the right thing, please have a look.

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, speed.texID);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

glBegin(GL_QUADS);
    glTexCoord2f(1,0); 
    glVertex2f(210, 638);   //Top-Left
    glTexCoord2f(1,1);
    glVertex2f(210, 438);   //Top-Right
    glTexCoord2f(0,1); 
    glVertex2f(10, 438);    //Bottom-Right
    glTexCoord2f(0,0);
    glVertex2f(10, 638);    //Bottom-Left
glEnd();
glDisable(GL_TEXTURE_2D);

After this code output image becomes this: enter image description here

But I want it to be like this: enter image description here

When I change the texture to something else, it maps it correctly but apparently not this one. Why do you think this could be?

hevele
  • 903
  • 6
  • 20
  • 38
  • Well, if this code works with other textures (i.e. other parameter to `glBindTexture`) maybe it's worth examining how you create this particular texture. – Anton Tykhyy Jan 14 '13 at 10:26
  • For a start, (210, 638) is *Top-Right* in Cartesian coordinates. – Brett Hale Jan 14 '13 at 10:28
  • 3
    If other textures work, chances are this texture is an odd size or different format, and has been loaded without observing some necessary padding. – JasonD Jan 14 '13 at 10:34
  • @JasonD What's more, the texture is 199x200. I highly suspect a bug in the code that reads the texture. – Calvin1602 Jan 14 '13 at 10:36
  • Thanks JasonD, it really was odd size problem. I can't believe I spent hours to fix this. – hevele Jan 14 '13 at 10:39

2 Answers2

4

If other textures work, chances are this texture is an odd size or different format, and has been loaded without observing some necessary padding.

It is common for texture formats to need to be an even number of pixels, or to be rounded to some other multiple.

The 45-degree slant to the texture is also indicative of this kind of issue, as it often results from an extra pixel being read (or skipped) every line at some point in the pipeline.

Possible fixes for this are:

  • Change the dimensions of your texture, such that there will be no padding.
  • Change the loading of your texture, such that the padding is consistent with what GL expects
  • Tell GL how your texture is packed, using glPixelStorei()
JasonD
  • 16,464
  • 2
  • 29
  • 44
  • The issue is a simple omission of setting the pixel alignment, see Felix K.'s answer. There's no need to make dimensions even sized. Sorry, but in this form your answer is deceptively not correct. Please fix it. – datenwolf Jan 14 '13 at 11:31
1

If you are working with textures which cannot be aligned to 4 bytes you have to care about a few things, one is to set the correct pixel pack and unpack alignment:

glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

For more information see here.

Felix K.
  • 6,201
  • 2
  • 38
  • 71
  • Pixel alignment considerations are independent of NPOT format or not. For example if you have RGB pixels (i.e. no alpha channel) you can not make a 4 byte alignment regardless of NPOT or not. Also GL_One is rather uncommon. Just write '1'. GL_PACK_ALIGNMENT is for getting back image data from OpenGL (glReadPixels), you don't need to set it for uploading a texture. – datenwolf Jan 14 '13 at 11:07
  • @datenwolf Changed my answer. Thanks. Never said he should use `GL_One`, it's just a sample code. – Felix K. Jan 14 '13 at 11:12
  • Well, `GL_One` is not even a standard token, whereever you got it from, it's not the original OpenGL specification. `GL_ONE` (capital letters) exists, but this is meant for `glBlendFunc`. And there's neither a `GL_Two`, nor a `GL_Four`. Plaease change this into a number literal. – datenwolf Jan 14 '13 at 11:29
  • @datenwolf A sorry i forgot that i'm using a .NET wrapper which defines them `public enum PixelStoreValue : int { One, Two, Four }`. Just changed it to `GL_One` because i thought in OpenGL GL_One is used too. – Felix K. Jan 14 '13 at 11:35
  • 1
    It makes sense to have this enum in .net, as this enforces strong static typisation of this particular parameter. If you look at OpenGL wrappers in other strong statically typed languages, like Haskell, OCaml, Go and such you'll find similar enumerations. – datenwolf Jan 14 '13 at 13:27