我尝试使用 glRotatef 围绕自己的轴旋转.obj 3d模型。但它没有按照我的意愿工作。
代码
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);
}
问题
第一次旋转 yrot 效果非常好:无论模型的位置如何,它总是围绕自己的 z 旋转(好吧,我要围绕 y 所以它并不完美。但至少它使用了自己的一个轴!)
现在,当我要求'xrot'时,它围绕 x screen 轴旋转。不是它自己的 x 。有人知道为什么吗?
说明
答案 0 :(得分:1)
操作顺序很重要。矩阵乘法链中的变换(每个OpenGL变换调用实际上只是一个矩阵乘法)在反向"中行动,即,首先应用乘以变换矩阵的最后一个变换。每次转型都会影响到当地的#34;原点。
您的第一次转换是围绕y轴的旋转。然后应用x轴旋转,但这发生在新的局部坐标系中。
现在当我要求' xrot'它围绕x屏轴旋转。不是它自己的x。有人知道为什么吗?
在您的特定转换链中,x轴旋转恰好与屏幕的x轴对齐。
我注意到onDrawFrame一直在运行。然而,该模型并未在y上持续翻译1.2f。
OpenGL不是场景图。它甚至没有"知道"什么型号。它只绘制单个点,线和三角形,一次一个,它就是它。如果场景中发生了某些变化,则必须重新绘制所有内容。函数glRotate
,glTranslate
等不会对模型起作用。他们所做的只是操纵当前活动的转换矩阵中的值。当你最终绘制一些东西时,它只是用于转换传入顶点向量的矩阵(不仅仅是位置,固定函数中还有其他属性的矩阵,使用着色器时一切都是可能的)。无论如何,在开始绘制新帧时,您希望将矩阵重置为已知状态。这是glLoadIdentity
的作用。所以你重新开始每一帧。
仅当z!= 0时(我不知道为什么)。
在每次迭代时,z
的值可能会集成到代码中其他位置的其他变量中。
答案 1 :(得分:0)
以下是解决方案:
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);
}
使用此解决方案,我们不会在每个周期都 LoadIdentity 。我们保持相同的矩阵。
然后我们计算无穷小旋转并将它们应用于全局矩阵。
因此,在模型的任何位置,我们都可以转动其本地 x 或 y 轴。
感谢datenwolf向我展示正确的方向。