4

我已经检查了有关此主题的其他问题,但他们的解决方案对我不起作用。我有点不知所措。我的 GLEventListener 实现中有以下函数。

public void init(GLAutoDrawable gl) {
    GL2 gl2 = gl.getGL().getGL2();

    gl2.glMatrixMode(GL2.GL_PROJECTION);
    gl2.glLoadIdentity();
    GLU glu = GLU.createGLU(gl2);
    glu.gluPerspective(45.0f, 1, 0.1f,100.0f);
    gl2.glMatrixMode(GL2.GL_MODELVIEW);
    gl2.glLoadIdentity();
    gl2.glViewport(0, 0, width, height);
    gl2.glEnable(GL.GL_DEPTH_TEST);
}

private void render(GLAutoDrawable drawable) {

    GL2 gl = drawable.getGL().getGL2();
    GLU glu = GLU.createGLU(gl);

    gl.glClear(GL.GL_COLOR_BUFFER_BIT);
    gl.glMatrixMode(GL2.GL_MODELVIEW);
    gl.glLoadIdentity();
    glu.gluLookAt(5,  0, 20, 
                  0, 30,  0, 
                  0,  1,  0);

    gl2.glPushMatrix();
    gl2.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );                
    gl2.glLoadIdentity();
    gl2.glTranslatef(x, y, z);        
    gl2.glBegin( GL2.GL_QUADS );
        gl2.glColor3f( 1, 0, 0 );

        //24 glVertex3f calls & some colour changes go here.
        gl2.glVertex3f(...)

    gl2.glEnd();
    gl2.glPopMatrix();

    gl.glFlush();
}

我将什么值放入 gluLookAt() 矩阵并不重要,视图不会改变。我最终还是看到了立方体的同一张脸。

有任何想法吗?

谢谢

4

1 回答 1

6

编辑:回应原始问题中的编辑。将原文留在下面,因为人们似乎觉得它很有用。

我认为您的问题出在您的立方体绘图代码中。检查下面的评论:glLoadIdentity调用完全符合您的预期 - 强制立方体出现在您面前:

gl2.glPushMatrix();     
gl2.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
/** Try removing the following glLoadIdentity call below.
  * That call was blowing out the MODELVIEW matrix - it's removing your 
  * gluLookAt call and returning to the identity.
  * As a result, the cube will always be right there in front of you.
  */
// gl2.glLoadIdentity();
gl2.glTranslatef(x, y, z);
gl2.glBegin( GL2.GL_QUADS );
gl2.glColor3f( 1, 0, 0 ); //24 glVertex3f calls & some colour changes go here.
gl2.glVertex3f(...)
gl2.glEnd();
gl2.glPopMatrix(); 

这是有关相关调用将做什么的非常快速的解释。有关更多信息,请参阅文档:

gl2.glPushMatrix(); // This preserves current MODEL_VIEW matrix so you can get back here.
                    // Think of it as a checkpoint save in a game.
                    // Most of your objects will be wrapped in push and pop.
gl2.glLoadIdentity(); // This erases the MODEL_VIEW and replaces it with an identity.
                      // This un-does your previous gluLookAt call.  You will rarely use
                      // this inside an object (but it's not impossible).
                      // Does not apply here so don't use.
gl2.glTranslatef(x, y, z); // This is what puts your object out in space for you to find
                           // as opposed to putting it at the origin.  Most objects will
                           // have a translate (and likely a rotate as well).
                           // Note that the order of operations matters:
                           // translate and then rotate != rotate and then translate.
// QUAD strip code with vertices and colors - you're okay with these.
gl2.glPopMatrix(); // This brings back the MODEL_VIEW that you originally saved by pushing
                   // it.

OpenGL 中的矩阵代码的好处在于,一旦您获得了您理解的示例代码组合,您将始终将其作为参考。当我从IrisGL切换到 OpenGL 时,我花了一点时间来移植我的实用程序,然后我再也没有回头。

原始:您需要添加立方体绘制代码 - 如果您将立方体放在 (0, 30, 0) 附近,则代码很可能正在执行您的要求。

检查 OpenGL 常见问题解答,有一个特定的问题和答案可能与您正在做的事情相关:8.080 为什么 gluLookAt 不起作用? 我将引用整个答案,因为确实没有很好的休息,但请访问OpenGL FAQ,答案很可能在那里:

这通常是由不正确的转换引起的。

假设您在 Projection 矩阵堆栈上使用 gluPerspective(),并将 zNear 和 zFar 作为第三个和第四个参数,您需要在 ModelView 矩阵堆栈上设置 gluLookAt,并传递参数以使您的几何图形介于 zNear 和 zFar 之间。

当您尝试了解查看转换时,通常最好尝试一段简单的代码。假设您正在尝试查看以原点为中心的单位球体。您需要按如下方式设置转换:

 glMatrixMode(GL_PROJECTION);
 glLoadIdentity(); 
 gluPerspective(50.0, 1.0, 3.0, 7.0); 
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity(); 
 gluLookAt(0.0, 0.0, 5.0,
           0.0, 0.0, 0.0,
           0.0, 1.0, 0.0);

请务必注意 Projection 和 ModelView 转换如何协同工作。

在此示例中,投影变换设置了 50.0 度的视野,纵横比为 1.0。zNear 剪裁平面是眼前 3.0 个单位,zFar 剪裁平面是眼前 7.0 个单位。这留下了 4.0 个单位的 Z 体积距离,为单位球体提供了充足的空间。

ModelView 变换将眼睛位置设置为 (0.0, 0.0, 5.0),注视点是我们单位球体中心的原点。请注意,眼睛位置距离观察点 5.0 个单位。这很重要,因为眼睛前方 5.0 个单位的距离位于投影变换定义的 Z 体积的中间。如果 gluLookAt() 调用将眼睛放在 (0.0, 0.0, 1.0),它将产生到原点的 1.0 距离。这不足以将球体包含在视图体积中,它会被 zNear 剪裁平面剪裁。

类似地,如果您将眼睛放置在 (0.0, 0.0, 10.0) 处,则到注视点的 10.0 距离将导致单位球体距离眼睛 10.0 个单位,并且远离放置在 7.0 个单位的 zFar 剪裁平面。

如果这让您感到困惑,请阅读 OpenGL 红皮书或 OpenGL 规范中的转换。了解了物体坐标空间、眼睛坐标空间、剪辑坐标空间之后,上面的内容应该就清楚了。此外,尝试使用小型测试程序。如果您在主应用程序项目中无法获得正确的转换,那么编写一小段代码尝试用更简单的几何图形重现问题可能会很有教育意义。

于 2011-02-24T16:08:38.337 回答