2
votes

I have a strange problem with opengl es(Android) .Some textures doesn't drawing correct ,its like the texture cordinates are changed , but other textures are rendering normal .For example i have this : enter image description here

i get this:

enter image description here

(the resume and the circle are other textures that drawning fine with the same texture coordinates /vertices)

I load the textures like this:

 GLuint texture;
  glGenTextures(1, &texture);
  glBindTexture(GL_TEXTURE_2D, texture);

  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);

  if(alpha)glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) image_data);
  else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*) image_data);

and rendering like this:

//int to fixed point
#define iX(x) (x<<16)
//float ti fixed point
#define fX(x) ((int)(x * (1  << 16)))

int square[12] = {
    fX(-0.5), fX(-0.5), 0,
    fX(0.5), fX(-0.5), 0,
    fX(-0.5), fX(0.5), 0,
    fX(0.5), fX(0.5), 0
};

int texCoords[8] = {
    fX(0), fX(0),
    fX(1), fX(0),
    fX(0),fX(1),
    fX(1),fX(1)
};

void Render(int type)
{

    if(type==RENDER_2D)gltviewOrtho();

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_TEXTURE_2D);

    glBindTexture(GL_TEXTURE_2D, id);
    glVertexPointer(3, GL_FIXED, 0, square);
    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
    /////////////////////////////////////////////////////
    glPushMatrix();

    if(align==ALIGN_CENTER)glTranslatef(x,y,z);

    if(align==ALIGN_LEFT)glTranslatef(x-scalex/2,y,z);
    if(align==ALIGN_LEFT+ALIGN_TOP)glTranslatef(x-scalex/2,y+scaley/2,z);
    if(align==ALIGN_LEFT+ALIGN_BOTTOM)glTranslatef(x-scalex/2,y-scaley/2,z);

    if(align==ALIGN_RIGHT)glTranslatef(x+scalex/2,y,z);
    if(align==ALIGN_RIGHT+ALIGN_TOP)glTranslatef(x+scalex/2,y+scaley/2,z);
    if(align==ALIGN_RIGHT+ALIGN_BOTTOM)glTranslatef(x+scalex/2,y-scaley/2,z);

    if(align==ALIGN_BOTTOM)glTranslatef(x,y-scaley/2,z);
    if(align==ALIGN_TOP)glTranslatef(x,y+scaley/2,z);

    glScalef(scalex,scaley,0);
    glColor4f(r,g,b,a);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glPopMatrix();
    ////////////////////////////////////////////////////
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    if(type==RENDER_2D)gltviewPerspective();


}
1
I bet that width * 3 is not a multiple of 4! (and that textures are RGB and not RGBA)Luca
omg how i missed that!!! I was searching for hours in the code and i totaly forgot about the pot textures!SteveL
It is not becuase POT textures, but because the pixel transfer scanline length (investigate on glPixelStore).Luca
well my textures was 250 x 480 soo i made it 256x512 and it works fine ....SteveL

1 Answers

3
votes

The pixel unpack alignment while uploading textures is 4: this mean that each texture line shall start with a byte-alignment of 4.

If your data is tighly packed, using a 250 pixel-wide RGB bitmap requires a 2 byte alignment: infact each bitmap line is defined by 750 bytes, that are not multiple of 4.

Essentially, the texture uploader ignore 2 bytes at each line, because it thinks that the bitmap line is long 752 bytes.

To resolve your issue, set the pixel alignment before uploading texture:

    glPixelStorei(GL_UNPACK_ALIGNMENT, 2)

Don't waste memory if you are able to use NPOT textures.