views:

175

answers:

2

When drawing OpenGL ES textures, they seem to "snap" to round pixel locations, as though the draw location was being rounded. ie. drawing at (x:1.1, y:5.4) actually draws at (x:1, y:5). This causes the textures to appear to "jump" when scrolling, rather than move smoothly.

Yes, I'm using floating point types for my vertices, etc.

Drawing lines, etc. works fine with non-round locations.

There are only two factors in the texture's location:

  1. translation of the viewport: glTranslatef(viewWidth/2.0f, viewHeight/2.0f, 0.0f);

  2. The draw location: glVertexPointer(...); // see below

I'm using the following code to draw the texture:

glTranslatef(scrollX, scrollY, 0.0f);

...

glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);

// Overlay map.
glTexCoordPointer(2, GL_FLOAT, 0, textureSTs);
glBindTexture(GL_TEXTURE_2D, texture.glTtextureKeyD);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

GLfloat vertices[] = {
 x1, y2,
 x1, y1,
 x2, y1,
 x2, y2,
};
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

Am I missing something?

+1  A: 

are your x1, y2, x1, y1, x2, y1, x2, y2,

floats or are they being truncated?

also the code that is setting x1, y1 etc are you casting to floats before doing division multiplication etc?

x1 = (float)somevar * 0.5f

and the same for scrollX which you are feeding into gltranslate

PeanutPower
good guess, but I'm using CGFloats.
Matthew Chen
so all the operands are floats in your math statements?
PeanutPower
maybe try calling glLoadIdentity to make sure your translate is a clean one ?
PeanutPower
if they are snapping to round pixel locations what if you intentionally truncate to a whole number e.g. using ceiling or floor so you would at least get consistent movement between 1, 2, 3, 4
PeanutPower
+2  A: 

Your image uploading code is most likely using GL_NEAREST filtering, if you want to get good filtering for inbetween pixel values your best bet is GL_LINEAR filtering. Try putting glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); after the bind. Using FSAA can also reduce the effect.

Another possibility is in your texture coordinates, try adjusting them by 1/2 a pixel. So if your texture is 256*256 add .5/256 to the floating point value of each coordinate.

Medran
That was exactly the problem. Thanks Medran and PeanutPower.
Matthew Chen