缩放 3D 对象会产生奇怪的结果

Scaling an 3D object gives weird results

我在一个场景中有两个对象 - 一个立方体和一个平面。我希望飞机大得多,因为它将代表地面。

当我加载我的模型文件时,我的两个对象的宽度和深度都相同。

这是我的 onDrawFrame 事件:

gl.glClear( GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT );

gl.glEnable( GL10.GL_CULL_FACE );
gl.glCullFace( GL10.GL_BACK );
gl.glFrontFace( GL10.GL_CCW );

gl.glLoadIdentity();

// draw the cube   
gl.glTranslatef( 0.0f, 0.0f, 0.0f );
gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
gl.glVertexPointer( 3, GL10.GL_FLOAT, 0, vertexBuffer );
gl.glDrawElements( GL10.GL_TRIANGLES, cubeIndices.length, GL10.GL_UNSIGNED_SHORT, indexBufferCube );
gl.glDisableClientState( GL10.GL_VERTEX_ARRAY );

// draw the plane
gl.glTranslatef( 0.0f, 0.0f, 0.0f );
gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
gl.glVertexPointer( 3, GL10.GL_FLOAT, 0, vertexBufferPlane );
gl.glDrawElements( GL10.GL_TRIANGLES, planeIndices.length, GL10.GL_UNSIGNED_SHORT, indexBufferPlane );
gl.glDisableClientState( GL10.GL_VERTEX_ARRAY );

问题是当我尝试缩放 'plane' 并执行此操作时:

// draw the cube   
gl.glTranslatef( 0.0f, 0.0f, 0.0f );
gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
gl.glVertexPointer( 3, GL10.GL_FLOAT, 0, vertexBuffer );
gl.glDrawElements( GL10.GL_TRIANGLES, cubeIndices.length, GL10.GL_UNSIGNED_SHORT, indexBufferCube );
gl.glDisableClientState( GL10.GL_VERTEX_ARRAY );

// draw the plane
gl.glTranslatef( 0.0f, 0.0f, 0.0f );
gl.glScalef( 2f, 2f, 2f ); // make the plane 2x bigger
gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
gl.glVertexPointer( 3, GL10.GL_FLOAT, 0, vertexBufferPlane );
gl.glDrawElements( GL10.GL_TRIANGLES, planeIndices.length, GL10.GL_UNSIGNED_SHORT, indexBufferPlane );
gl.glDisableClientState( GL10.GL_VERTEX_ARRAY );

我在场景中导航时得到非常奇怪的结果,平面和立方体以不同的速度移动,不同步。我在滥用 glScalef 函数吗?

我想做的就是让 'plane' 模型变大,立方体保持相同大小,当我使用 GLU.gluLookAt 在世界各地移动时,它们 'move' 与另一个。有什么建议么?

首先,请确保在绘制每个对象时使用 gl.glPushMatrix()gl.glPopMatrix(),否则一个对象的变换可能会与其他对象叠加:

// draw the cube   
gl.glPushMatrix();
{
  gl.glTranslatef( 0.0f, 0.0f, 0.0f );
  gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
  gl.glVertexPointer( 3, GL10.GL_FLOAT, 0, vertexBuffer );
  gl.glDrawElements( GL10.GL_TRIANGLES, cubeIndices.length, GL10.GL_UNSIGNED_SHORT, indexBufferCube );
  gl.glDisableClientState( GL10.GL_VERTEX_ARRAY );
}
gl.glPopMatrix()

// draw the plane
gl.glPushMatrix();
{
  gl.glTranslatef( 0.0f, 0.0f, 0.0f );
  gl.glScalef( 2f, 2f, 2f ); // make the plane 2x bigger
  gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
  gl.glVertexPointer( 3, GL10.GL_FLOAT, 0, vertexBufferPlane );
  gl.glDrawElements( GL10.GL_TRIANGLES, planeIndices.length, GL10.GL_UNSIGNED_SHORT, indexBufferPlane );
  gl.glDisableClientState( GL10.GL_VERTEX_ARRAY );
}
gl.glPopMatrix()

其次,您需要考虑的是,当您应用缩放时,对象将围绕其枢轴缩放,枢轴位置取决于您创建网格的方式。

例如,对于您的平面和立方体,轴心需要位于 (0,0,0),这意味着立方体和平面的所有顶点位置都需要相对于 (0, 0,0) 并且枢轴位于对象的 "center" 处。

如果枢轴不在对象的中心,那么当你像你一样以统一的方式缩放时(每个轴上的比例相同)它会在某些轴上比其他轴上拉伸得更多,你会得到奇怪的结果。