Am I misunderstanding gl.glTranslatef?

Started by
6 comments, last by coolblue3000 9 years, 11 months ago

I was under the impression that gl.glTranslatef() effectively moved a sprite by the values passed in to the method (ie if I wanted a sprite to move by 2 pixels I would call gl.glTranslate(2.0f,0.0f,0.0f);

However If I do this then the sprite remains static. However If I pass in an absolute position (ie call gl.glTranslatef(52.0f,0.0f,0.0f)) my sprite moves as expected. However its starting position is out by the initial position coordinates (ie If I specify the sprite to start at 30,30 then the first draw loop draws the sprite at 62,30, once the first frame is done the sprite moves as I expect.

What is going on?

here is the draw code for my sprite.

//Reset the modelview matrix
gl.glLoadIdentity();
//drawing
//bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D,this._texture);
//point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//set the face rotation
gl.glFrontFace(GL10.GL_CW);
gl.glPushMatrix();
gl.glTranslatef(_position.x,_position.y,0.0f);//need to work out fraction of 1 that the position of the sprite represents
//point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, _textureBuffer);
//draw the vertices as a triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, _vertices.length / 3);
//gl.glPopMatrix();
//disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
Note that this passes in the absolute position and not the small extra movement.
Advertisement

First, I think I need to point a few things out:

glTranslate doesn't do anything with any sprites.

It is used to set up a matrix, which in turn is used to transform (translate, rotate, scale, skew, etc) any vertexes send in the draw call.

Nothing more, nothing less.

What this in practice means, (if it means a sprite moves or a texture animates, or the camera moves, or anything else) depends on what you define it to mean.

It depends on what other calls you have made to the matrix stack, and when you call it, and what mode the matrix stack is in.

Then to your problem:

How have you set up your view? Since you are talking about sprites, I'm assuming you have a glOrtho call somewhere, what do you send in there?

glOrtho is used to set up the view matrix, and you need to set it up correctly to make sure 1.0f to glTranslate means 1 pixel.

After checking that, You should should make sure the position of your object (sprite) is stored in a separate variable somewhere.

You can't just send in relative coordinates every frame and accumulate the position in the matrix, or it will degenerate because of accumulation of numerical errors.

You should always make sure the matrix starts from identity each draw call (glLoadIdentity), and then do a pushmatrix, translate with a fixed position, and then a popmatrix on the end.

I am setting up the view as follows

gl.glViewport(0,0,width,height); //Reset the current viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //select the projection matrix
gl.glLoadIdentity(); //Reset the Projection Matrix
gl.glOrthof(0f,1920f,1080f,0f,-1f,1f);
I have also tried putting a gl.glPopMatrix after the translatef call but this then causes my objects to remain static......

My mistake, I was putting popmatrix in the wrong place...

However this still results in no change to my original question.

To put this another way,

If I put the line gl.glTranslatef(2.0f,2.0f,0.0f); I would expect the matrix to be moved diagonally by 2 units each frame. However my matrix stays static at position 2,2

If I increment the values each frame (2,4,6 etc) then my matrix moves diagonally. However I did not think this was how glTranslatef worked?

LoadIdentity automatically resets everything back to 0. You can see the effect you're expecting if you duplicate your calls to glTranslatef back to back. But the moment you hit that LoadIdentity, everything is reset. In general, you're going to want to leave things this way and keep tracking of the accumulated movement yourself.

SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.

If I increment the values each frame (2,4,6 etc) then my matrix moves diagonally. However I did not think this was how glTranslatef worked?

This is though exactly how it does work.

The matrix is just temporary data you set up for opengl, and you should recreate it each draw call.

For each object you want to draw, you should do glPushMatrix, then any glTranslate, rotate, etc, before the draw-call then after call a glPopMatrix to reset it.

The actual position of your object is stored in _position.x and _position.y in your code.

You should update the _position elsewhere in your code, if you want your object to move.

Usually you do this in a separate function before calling the function that draws your scene.


If I increment the values each frame (2,4,6 etc) then my matrix moves diagonally. However I did not think this was how glTranslatef worked?

This is though exactly how it does work.

The matrix is just temporary data you set up for opengl, and you should recreate it each draw call.

For each object you want to draw, you should do glPushMatrix, then any glTranslate, rotate, etc, before the draw-call then after call a glPopMatrix to reset it.

The actual position of your object is stored in _position.x and _position.y in your code.

You should update the _position elsewhere in your code, if you want your object to move.

Usually you do this in a separate function before calling the function that draws your scene.

Ok, thanks, that makes more sense now.

This topic is closed to new replies.

Advertisement