【问题标题】:Objects are not rendering except when very close (almost intersecting with camera) in OpenGL除非在 OpenGL 中非常靠近(几乎与相机相交),否则对象不会渲染
【发布时间】:2014-10-14 12:48:44
【问题描述】:

我正在尝试创建一个简单的程序,该程序将在原点显示犹他茶壶并用相机查看它,但是茶壶在相机非常靠近之前根本不会渲染(因此它们几乎重合)。起初,我以为我可能渲染了错误的多边形面,但是当我将它从 CCW 更改为 CW 时,这个问题并没有得到纠正。我添加了一个函数,每次按下 z 时,该函数会在 -z 方向上沿 z 轴向下移动相机。在相机非常接近原点之前,什么都不会渲染。然后相机通过,场景不再渲染。我尝试了各种照明和相机位置,但没有任何帮助。我不再知道要改变什么。任何帮助表示赞赏。有问题的代码如下。

#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>

void display(void);
void reshape(int x, int y);
void init(void);
void keyboard(unsigned char, int, int);


int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(800, 600);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("Test");
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0;
}


void init(void)
{
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
}

float camx = 0.0, camy = 0.0, camz = 5.0;

void display(void)
{
    glMatrixMode (GL_PROJECTION);

    glLoadIdentity();
    gluPerspective(30.0, 1.3, 0.1, 200.0);
    glLoadIdentity();
    gluLookAt(camx, camy, camz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glFrontFace(GL_CCW);
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glColor3f(1.0, 0.0, 0.0);
    glutSolidTeapot(1.0);

    glFlush();
}


void reshape (int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
}

void keyboard(unsigned char key, int x, int y)
{
    if (key == 'z') {
        camz -= .3;
        glutPostRedisplay();
    }
}

【问题讨论】:

    标签: opengl camera clipping


    【解决方案1】:

    gluPerspectivegluLookAtglLoadIdentity 都以glMatrixMode 指定的当前活动矩阵为目标,因此这段代码是无意义的。

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity();
    // ^^^ write an identity projection 
    gluPerspective(30.0, 1.3, 0.1, 200.0);
    // ^^^ overwrites identity with your desired projection matrix
    glLoadIdentity();
    // ^^^ overwrites identity your desired projection matrix with identity
    gluLookAt(camx, camy, camz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    // ^^^ overwrites your identity with a view transform that 
    // shouldn't be in the projection matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    // ^^^ Loads identity into the modelview matrix
    

    最终结果是您的项目矩阵包含一个视图矩阵,而您的视图矩阵为空(标识)。因为您没有投影矩阵,所以您基本上默认所有三个维度上的正交投影为 -1 到 1(也称为标准化设备坐标)。

    试试这个:

    // Specify that you're targeting the projection matrix
    glMatrixMode (GL_PROJECTION);
    // set the projection 
    gluPerspective(30.0, 1.3, 0.1, 200.0);
    
    // specify that you're targeting the modelview matrix
    glMatrixMode(GL_MODELVIEW);
    // set the camera.
    gluLookAt(camx, camy, camz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    

    我相当肯定glLoadIdentity 根本没有必要,因为gluPerspectivegluLookAt 都完全填充了有源矩阵。

    【讨论】:

    • 我对 display() 函数进行了这些更改,但现在整个屏幕最初是红色(茶壶的颜色),并且只要我移动相机,整个屏幕就会变成黑色(清晰的颜色)。我正在清除深度缓冲区和颜色缓冲区,但它仍然无法正常工作。
    • 您还需要删除绘图代码中间的另一个 glLoadIdentity()。在你完全弄清楚矩阵的东西之前,我也会改用铁丝茶壶。
    • 非常感谢。这段代码终于奏效了!感谢您的所有帮助。
    猜你喜欢
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多