Reputation: 11
I try to rotate a .obj 3d model around its own axis using glRotatef. But it's not working as I wish.
Code
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL10.GL_LIGHTING);
gl.glLoadIdentity();
gl.glTranslatef(0f, -1.2f, -z);
gl.glRotatef(xrot, 1f, 0f, 0f);
gl.glRotatef(yrot, 0f, 1f, 0f);
model.draw(gl);
}
Problem
The first rotation yrot works pretty good : no matter the position of the model, it always rotates around its own z (well, I ask to rotate around y so it's not perfect. But at least it uses one of its own axis!)
Now when I ask for 'xrot' it rotates around x screen axis. Not its own x. Does someone know why?
Remarks
Upvotes: 1
Views: 221
Reputation: 11
Here is a solution :
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL10.GL_LIGHTING);
if(flag==0) {
gl.glLoadIdentity();
gl.glTranslatef(0f, -1f, -z);
flag=1; xrotold=0; yrotold=0;
}
else{
float dxrot=xrot-xrotold;
float dyrot=yrot-yrotold;
gl.glRotatef(dxrot, 1f, 0f, 0f);
gl.glRotatef(dyrot, 0f, 1f, 0f);
yrotold=yrot;
xrotold=xrot;
}
model.draw(gl);
}
With this solution, we don't LoadIdentity every cycle. We keep the same matrix.
Then we calculate the infinitesimal rotations and apply them to the global matrix.
Thus, at any position of the model, we can turn around its local x or y axis.
Thank you datenwolf for showing me the right direction.
Upvotes: 0
Reputation: 162327
Order of operations matters. The transformations in a chain of matrix multiplications (every OpenGL transformation call actually is just a matrix multiplication) act "in reverse", i.e. the very last transformation multiplied onto the transformation matrix is applied first. And each transformation acts on the "local" origin.
Your first transformation is a rotation about the y axis. Then the x axis rotation is applied, but this happens in the new local coordinate system.
Now when I ask for 'xrot' it rotates around x screen axis. Not its own x. Does someone know why?
In your particular chain of transformations the x axis rotation happens to align with the screen's x axis.
I noticed that onDrawFrame is constantly running. However the model is not constantly translating by 1.2f on y.
OpenGL is not a scene graph. It doesn't even "know" what models are. It just draws single points, lines and triangles, one at a time and that's it. If something changes in the scene, all has to be redrawn. The functions glRotate
, glTranslate
and so on, don't act on models. All they do is manipulate the values in the currently active transformation matrix. And when you finally draw something it's just this matrix that is used to transform the incoming vertex vectors (not just position, there are also matrices for other attributes in fixed function and when using shaders everything is possible). Anyway, when starting drawing a new frame you want to reset the matrices into a known state. That's what glLoadIdentity
does. So every frame you start anew.
Only when z != 0. (I don't know why).
Probably the value of z
gets integrated into some other variable somewhere else in your code at each iteration.
Upvotes: 1