【问题标题】:gluPerspective messes up 3D objectsgluPerspective 弄乱了 3D 对象
【发布时间】:2014-04-23 19:11:47
【问题描述】:
void drawTire(void)
{
    GLint num_of_tri = 32;
    GLfloat vertex[3]; 
    const GLfloat delta_angle = 2.0*PI/float(num_of_tri);

    //Draw Front tire
    glBegin(GL_TRIANGLE_FAN);
        glColor3f(0.5, 0.5, 0.5);

        vertex[0] = vertex[1] = vertex[2] = 0.0;
        glVertex3fv(vertex);

        for(int i = 0; i < num_of_tri ; i++)
        {
            vertex[0] = cos(delta_angle*i) * wheelRadius; //wheel Radius is 1.0
            vertex[1] = sin(delta_angle*i) * wheelRadius;
            vertex[2] = 0.0;
            glVertex3fv(vertex);
        }
        vertex[0] = 1.0 * wheelRadius;
        vertex[1] = 0.0 * wheelRadius;
        vertex[2] = 0.0;
        glVertex3fv(vertex);
    glEnd();

    //Draw Back Tire
    const GLfloat depth = -wheelRadius/1.5; 
    glBegin(GL_TRIANGLE_FAN);
        glColor3f(1.0, 0.0, 0.0);
        vertex[0] = vertex[1] = 0.0;
        vertex[2] = depth;
        glVertex3fv(vertex);

        for(int i = 0; i < num_of_tri ; i++)
        {
            vertex[0] = cos(delta_angle*i) * wheelRadius;
            vertex[1] = sin(delta_angle*i) * wheelRadius;
            vertex[2] = depth;
            glVertex3fv(vertex);
        }
        vertex[0] = 1.0 * wheelRadius;
        vertex[1] = 0.0 * wheelRadius;
        vertex[2] = depth;
        glVertex3fv(vertex);
    glEnd();

    //Connect Front&Back
    glBegin(GL_QUADS);
        glColor3f(0.0, 0.0, 0.0);
        for(int i = 0; i < num_of_tri; i++)
        {
            vertex[0] = cos(delta_angle*i) * wheelRadius;
            vertex[1] = sin(delta_angle*i) * wheelRadius;
            vertex[2] = 0;
            glVertex3fv(vertex);

            vertex[0] = cos(delta_angle*i) * wheelRadius;
            vertex[1] = sin(delta_angle*i) * wheelRadius;
            vertex[2] = depth;
            glVertex3fv(vertex);

            vertex[0] = cos(delta_angle*((i + 1)%num_of_tri)) * wheelRadius;
            vertex[1] = sin(delta_angle*((i + 1)%num_of_tri)) * wheelRadius;
            vertex[2] = depth;
            glVertex3fv(vertex);

            vertex[0] = cos(delta_angle*((i + 1)%num_of_tri)) * wheelRadius;
            vertex[1] = sin(delta_angle*((i + 1)%num_of_tri)) * wheelRadius;
            vertex[2] = 0;
            glVertex3fv(vertex);
        }
    glEnd();

    glFlush();
}

我正在使用上面的代码来绘制一个(某种)3D 车轮。此代码似乎有效。
这是我的初始化函数:

void init(void)
{    
    glClearColor (1.0, 1.0, 1.0, 0.0);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective(45.0f, (GLfloat)1366/(GLfloat)768, 0.1f, 100.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0, 0.0, 5.0, 0, 0, 0, 0, 1, 0);
}

这是我的显示功能:

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
drawTire();
glFlush();
}

结果是车轮弄乱了,如下所示:http://postimg.org/image/fuf9o75ub/

轮胎的前部(相机应该看到的一侧)是灰色的。相机不知何故看着轮胎的背面,它是红色的。
另外,还显示了轮胎一侧(与地面接触的一侧。我不知道如何命名),这很奇怪(黑色)。

为什么 gluPerspective 会弄乱 3D 对象,如何解决这个问题? (我试过改变视野...结果几乎一样)

【问题讨论】:

  • 为什么你在GL_DEPTH_BUFFER_BIT 中两次or-ing 在你的glClear() 通话中?
  • 您在创建 GL 上下文时是否请求了深度缓冲区?您是否启用了深度测试?
  • 错字,对不起。我删除了所有关于深度的东西。结果还是一样
  • @user130955 呃,没有。您需要启用深度测试并清除深度缓冲区。
  • 嗯,这完成了工作。非常感谢!

标签: opengl camera glut


【解决方案1】:

目前,您没有使用深度测试。这意味着最后渲染的图元是“顶部”的图元,因为没有深度测试,OpenGL 无法知道像素在渲染后的“深度”。

为了解决这个问题,OpenGL 使用了一个深度缓冲区,它是一个隐藏的屏幕大小的缓冲区,用于存储每个像素与相机的距离。启用深度测试后,当 OpenGL 渲染片段时,它首先检查片段的深度并将其与深度缓冲区中的值进行比较。如果片段的深度值小于存储的值(注 1),则 OpenGL 会断定片段位于已渲染对象的前面并写入片段。否则,它位于对象后面并忽略片段。

要使用深度测试,您首先需要确保在创建上下文时分配了深度缓冲区。这取决于您使用的窗口库,但通常默认情况下它们会为您提供深度缓冲区。

然后您需要致电glEnable(GL_DEPTH_TEST) 开始使用深度测试。

此外,您需要在重新渲染场景时清除深度缓冲区中的深度值。将glClear(GL_COLOR_BUFFER_BIT) 更改为glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

这就是使用深度测试所需的全部内容。


(注 1):更具体地说,它使用 glDepthFunc 设置的任何函数,尽管 99% 的时间是 GL_LESSGL_LEQUAL

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 2020-01-16
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多