OpenGL-移动相机时线条消失

OpenGL-移动相机时线条消失,opengl,Opengl,我写了一个程序来画一条线 当我将相机移到正z轴时,该线有时会消失(特别是当z轴大于10000时) 有一些测试结果 当z设置为20541时,可以看到该线 当z设置20542时,无法看到该线 当z设置为30320时,可以看到该线 当z设置为30321时,无法看到该线 等等 代码见附件。怎么了 附言。 代码是由OpenGL1.0编写的,但是当我使用OpenGL3.0+glm库编写时,仍然可以得到相同的测试结果 #include <glut.h> /* System Info ------

我写了一个程序来画一条线

当我将相机移到正z轴时,该线有时会消失(特别是当z轴大于10000时)

有一些测试结果

当z设置为20541时,可以看到该线

当z设置20542时,无法看到该线

当z设置为30320时,可以看到该线

当z设置为30321时,无法看到该线

等等

代码见附件。怎么了

附言。 代码是由OpenGL1.0编写的,但是当我使用OpenGL3.0+glm库编写时,仍然可以得到相同的测试结果

#include <glut.h>

/*
System Info
-------------
OS: Win7 professional 64-bit SP1
CPU: Intel i3-4170 @ 3.70GHz
GPU: HD Graphics 4400
*/

void display(void) {
    // 20541 ok, 20542 not visible
    // 30320 ok, 30321 not visible
    const GLfloat z = 20541;

    const GLfloat far = 1000, near = 0.1;

    GLfloat vertices[4 * 3] = {
        -far, -far, z - far,
        far, far, z - far,
    };

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0, 0, z, 0, 0, z - 1, 0, 1, 0);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-0.1, 0.1, -0.1, 0.1, near, far);

    glColor3f(0, 1, 1); // blue

    glBegin(GL_LINES);
    glVertex3f(vertices[0], vertices[1], vertices[2]);
    glVertex3f(vertices[3], vertices[4], vertices[5]);
    glEnd();

    glFlush();
}

int main() {
    glutCreateWindow("");
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}
#包括
/*
系统信息
-------------
操作系统:Win7 professional 64位SP1
CPU:Intel i3-4170@3.70GHz
GPU:HD图形4400
*/
作废显示(作废){
//20541正常,20542不可见
//30320正常,30321不可见
常量GLfloat z=20541;
常量GLfloat远=1000,近=0.1;
GLfloat顶点[4*3]={
-远,远,z,远,
远,远,z-远,
};
glMatrixMode(GLU模型视图);
glLoadIdentity();
gluLookAt(0,0,z,0,0,z-1,0,1,0);
glMatrixMode(GL_投影);
glLoadIdentity();
glFrustum(-0.1,0.1,-0.1,0.1,近,远);
glColor3f(0,1,1);//蓝色
glBegin(GL_行);
glVertex3f(顶点[0],顶点[1],顶点[2]);
glVertex3f(顶点[3],顶点[4],顶点[5]);
格伦德();
glFlush();
}
int main(){
创建窗口(“”);
glutDisplayFunc(显示器);
glutMainLoop();
返回0;
}

这个问题似乎是浮点运算的数值不稳定。由于投影的点正好位于远平面上,因此当浮点结果略大于预期结果时,它们会被剪裁

让我们假定GPU基本上做了C++实现:

glm::vec4 test_fp(float z)
{
    //Construct matrices
    auto ortho = glm::frustum(-0.1f, 0.1f, -0.1f, 0.1f, 0.1f, 1000.0f);
    auto lookat = glm::lookAt(glm::vec3(0, 0, z), glm::vec3(0, 0, z - 1.0f), glm::vec3(0, 1, 0));

    //We are only interested in the z-value
    glm::vec4 tvec(0, 0, z - 1000.0f, 1);

    //Calculate ndc vector
    auto result = ortho * lookat * tvec;

    //Homogenize
    result /= result.w;

    return result;
}
现在使用您提供的值调用此函数时,我们会得到以下结果:

auto a = test_fp(20541.0); //< [0, 0, 1.00000000, 1]
auto b = test_fp(20542.0); //< [0, 0, 1.00000191, 1]
auto c = test_fp(30320.0); //< [0, 0, 1.00000000, 1]
auto d = test_fp(30321.0); //< [0, 0, 1.00000191, 1]
auto a=test_fp(20541.0);//<[0, 0, 1.00000000, 1]
自动b=测试_fp(20542.0);/<[0, 0, 1.00000191, 1]
自动c=测试_fp(30320.0);//<[0, 0, 1.00000000, 1]
自动d=测试_fp(30321.0);//<[0, 0, 1.00000191, 1]

如您所见,
b
d
的结果与数学正确结果不同,略高于1.0。由于1.0以上的值位于远平面的后面,因此它们会被剪裁掉并且不可见,这正是您的行为。

我没有仔细查看,但我猜线条会移出
剪裁平面。您正在使用不推荐使用的OpenGL(自2007年以来!)。您的
glutInit()
调用在哪里?谢谢。你真是个专业人士。您所说的是OpenGL规范的一部分。