# glTranslate, how exactly does it work?

I have some trouble understanding how does glTranslate work. At first I thought it would just simply add values to axis to do the transformation.

However then I have created two objects that would load bitmaps, one has matrix set to GL_TEXTURE:

public class Background
{
float[] vertices = new float[]
{ 0f, -1f, 0.0f,
4f, -1f, 0.0f,
0f, 1f, 0.0f,
4f, 1f, 0.0f };

....
private float backgroundScrolled = 0;
public void scrollBackground(GL10 gl)
{
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glTranslatef(0f, 0f, 0f);
gl.glPushMatrix();

gl.glMatrixMode(GL10.GL_TEXTURE);
gl.glTranslatef(backgroundScrolled, 0.0f, 0.0f);
gl.glPushMatrix();

this.draw(gl);
gl.glPopMatrix();

backgroundScrolled += 0.01f;
}
}


and another to GL_MODELVIEW:

public class Box
{
float[] vertices = new float[]
{ 0.5f, 0f, 0.0f,
1f, 0f, 0.0f,
0.5f, 0.5f, 0.0f,
1f, 0.5f, 0.0f };

....

private float boxScrolled = 0;
public void scrollBackground(GL10 gl)
{
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glTranslatef(0f, 0f, 0f);
gl.glPushMatrix();

gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glTranslatef(boxScrolled, 0.0f, 0.0f);
gl.glPushMatrix();

this.draw(gl);
gl.glPopMatrix();

boxScrolled+= 0.01f;
}
}


Now they are both drawn in Renderer.OnDraw. However background moves exactly 5 times faster. If I multiply boxScrolled by 5 they will be in sinc and will move together. If I modify backgrounds vertices to be

    float[] vertices = new float[]
{ 1f, -1f, 0.0f,
0f, -1f, 0.0f,
1f, 1f, 0.0f,
0f, 1f, 0.0f };


It will also be in sinc with the box. So, what is going under glTranslate?

• maybe the problem is with number of glpush/glpop calls you make. note that in every function you are calling glpush twice and glpop only once. – Ali1S232 Jun 8 '12 at 12:03
• Not perhaps, its for sure, OpenGL has a stack with only 32 units per type of matrix, if im not mistaken. This allows some rendering depth in your scene tree, but not too much. But like that, the program should crash within a second :) – Grimshaw Jun 8 '12 at 12:06
• well, i don't think so, as I've said, if I modify backgrounds vertices, to be from 0 to 1 in x axis, it works just fine. – mykk Jun 8 '12 at 12:11
• I think that second glPushMatrix should be deleted. glPushMatrix is something like backup of your current matrix. So if you are pushing and not poping, stack is overflowed... – zacharmarz Jun 8 '12 at 12:34
• And second thing: glTranslate is not adding something to coordinates. It's changing curent matrix (modelview or texture in your case). Modelview matrix is used to multiply vertex coordinate, texture matrix to multiply texture coordinates. – zacharmarz Jun 8 '12 at 12:40

Your glPushMatrix and glPopMatrix count should be equal. It's first problem.

But main problem is in matrix mode. In first case (background), you are using texture matrix, which is modified by glTranslate. It means, that in every step texture coordinates will be multiplied by this translation.

Because texture coordinates are in range <0,1>, and your background rectangle is wide 4 units, it will not be translated by 0.01 every frame, but it will be translated by 0.04 units in world.

In second case (box), you are changing modelview matrix. Which will cause to translate your box by 0.01 units every frame in world.

When you change background rectangle to new coordinates (x coordinates are 0 and 1), then every frame texture coordinates are really translated by 0.01 units.

• Thank you! I've got it kinda figured after your comments and now it is much clearer – mykk Jun 8 '12 at 13:16
• (i just want to add that background is 5 units wide) – mykk Jun 8 '12 at 14:04

glTranslatef

glTranslatef translates (a special case of "transforming") the matrix corresponding to the currently selected matrix mode. So calling it after glMatrixMode(GL_MODELVIEW) means you transform the model-view matrix, and after glMatrixMode(GL_TEXTURE) you transform the texture matrix. See the Wikipedia article about translation matrices to learn more about this.

The model-view matrix is applied to object coordinates to get eye coordinates, which means absolute world coordinates are transformed to coordinates relative to the "camera". (Before the object is actually rendered its coordinates are transformed a number of extra times, details are in the OpenGL FAQ regarding transformations, but they aren't important right now.)

The texture matrix does something completely different, it is applied to texture coordinates before they are mapped. Using it will allow you to achieve a scrolling, rotating, scaling, or perspective-warping texture effect.

Hopefully you will see now that these two matrices aren't interchangeable in the way you think they are. They are applied in different stages of the rendering process. When the results of transforming both matrices align on your screen, it is purely a coincidence that also depended on your objects' positions and texture coordinates, amongst others.

Some minor extra remarks

Then something else, the commenters are right in saying you should balance your calls to glPush/PopMatrix. Without seeing the rest of your code, and knowing what other objects are being rendered, it's hard to tell, but it's possible that part of the effect you are experiencing (the translation scaling by a factor of 5) is due to the model-view matrix for one object incorrectly being applied to another object because it is still on the matrix stack.

Furthermore:

• Calling glMatrixMode in succession with the same arguments won't change anything as the OpenGL state stays the same.
• glLoadIdentity loads the identity matrix: a matrix that returns the exact same coordinates it was applied to. It could be seen as a "reset" of the current matrix. Calling it multiple times won't have any effect (unless you do something to the current matrix in between).
• glTranslatef(0f, 0f, 0f) won't have any effect.

What exactly does glTranslate do? First of all it computes a translation matrix - this is just an identity matrix with the translation values in slots 3 (for x), 7 (for y) and 11 (for z) (assuming column-major). Then it multiplies the current matrix by this translation matrix to get a new matrix, which it then replaces the current matrix with. That's basically it.