澄清关于使用OpenGL模型视图矩阵和矩阵变换



我已经能够使用模型视图矩阵和glTranslatef()gluLookAt()等函数来转换对象或整个场景的视角,但是当我试图同时做这两件事时,我遇到了问题。

似乎无论我使用gluLookAt()的参数如何,我绘制的对象都是从相同的角度显示的。我试过在不同的其他不同的glPushMatrix()glPopMatrix的使用中调用函数,这是基于我在其他线程中读到的,没有运气。这是我现在有的。物体应该移动,但我只能让它们从一个视点出现。

例如,因为它们应该在xy平面上移动,并且逆时针旋转,我认为将z_0更改为-30会使它们看起来是顺时针移动,但它似乎没有任何区别。在它之前有一长串常数,我省略了。最终的目标是建立一个太阳系的简单模型。

    GLfloat time = 0.0;
GLfloat inc = 0.01;
// viewing parameters
GLint winWidth = 600, winHeight = 600;
GLfloat x_0 = 0.0, y_0 = 0.0, z_0 = 30.0;
GLfloat xref = 0.0, yref = 0.0, zref = 0.0;
GLfloat Vx = 0.0, Vy= 1.0, Vz = 0.0;
GLfloat xwMin = -50.0, ywMin = -50.0, xwMax = 50.0, ywMax = 50.0;
GLfloat dnear = .3, dfar = 10.0;
void view(void) {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(x_0, y_0, z_0, xref, yref, zref, Vx, Vy, Vz);
}
void init(void) {
    view();
    glEnable(GL_DEPTH_TEST);
}
void drawPlanet(GLfloat maj, GLfloat min, GLfloat x0, GLfloat theta,
        GLfloat size) {
    GLfloat x = maj * cosf(theta) + x0;
    GLfloat y = min * sinf(theta);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glTranslatef(x, y, 0);
    glutSolidSphere(size, 25, 25);
    glPopMatrix();
}
void display(void) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);
    drawPlanet(MERCURY_MAJOR, MERCURY_MINOR, MERCURY_CENTER,
        time / MERCURY_YEAR, MERCURY_SIZE);
    drawPlanet(MARS_MAJOR, MARS_MINOR, MARS_CENTER,
        time / MARS_YEAR, MARS_SIZE);
    drawPlanet(URANUS_MAJOR, URANUS_MINOR, URANUS_CENTER,
        time / URANUS_YEAR, URANUS_SIZE);
    glFlush();
}
void idle(void) {
    time += inc;
    display();
    glutSwapBuffers();
}
int main (int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(0,0);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH);
    glutCreateWindow("");
    init();
    glutDisplayFunc(display);
    glutIdleFunc(idle);
    glutMainLoop();
}

如果有人看到我错过了什么,我真的很感激一个解释或指导一些额外的阅读,这将帮助我解决这个问题。

你犯了典型的OpenGL新手错误,把你的矩阵操作分散到各处。你从不初始化 OpenGL矩阵状态。在进入显示功能时,始终将其设置为新鲜。这使得事情更容易被发现。

你也可能把OpenGL误认为是一个场景图,glPush/PopMatrix"神奇地"建立了一个转换层次。

glPushMatrix——你可能知道——复制当前堆栈矩阵的顶部并将其压入堆栈。这个想法是创建临时副本,进一步的转换可以在这些副本上进行倍增。

现在让我们看一下稍微不同形式的代码:

void display(void) {
    glViewport(…);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(x_0, y_0, z_0, xref, yref, zref, Vx, Vy, Vz);
    glColor3f(1.0, 1.0, 1.0);
    {
        GLfloat x = maj * cosf(theta) + x0;
        GLfloat y = min * sinf(theta);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glLoadIdentity(); // <<<<<<<<<
        glTranslatef(x, y, 0);
        glutSolidSphere(size, 25, 25);
        glPopMatrix();
    }

你看到这里发生了什么吗?你重置你的modelview矩阵为恒等式,然后转换那个。您之前创建的查看矩阵将被完全丢弃,并且对球体绘制没有影响。

删除我标记的glLoadIdentity(),事情应该工作得很好

相关内容

  • 没有找到相关文章

最新更新