OpenGL深度不起作用,三角形消失

Posted

技术标签:

【中文标题】OpenGL深度不起作用,三角形消失【英文标题】:OpenGL Depth Not working, Triangles Disappear 【发布时间】:2012-06-14 01:03:04 【问题描述】:

由于某种原因,我无法检测到我无法为任何三角形设置 z 索引。三角形将以相同的深度显示,从 1 到 -1(含),但之后它会消失。我没有应用任何 MVP 矩阵(试图首先弄清楚这一点),并且我希望能够看到我的三角形随着 z 值的减小而变小。这是我目前所拥有的:

//My main function
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_ALPHA|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("Window");

if (init_resources()) 
    glutDisplayFunc(onDisplay);
    glutIdleFunc(idle);
    glEnable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glutKeyboardFunc(keyboard);
    glutMouseFunc(mouse);
    glutMainLoop();


//And in my display function
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);

还有我的顶点着色器:

gl_Position = vec4(coord2d, 0.0, 1.0);

glGetIntegerv(GL_DEPTH_BITS, &depth) 也返回 24。

编辑:完整代码

Sprite *sprite1;
Sprite *sprite2;

GLuint program;
GLuint cameraAttribute;

int init_resources()
   

    //Link shaders, create program and attach shaders
    GLint link_ok = GL_FALSE;
    GLuint vs, fs;
    if ((vs = create_shader("vertShader.sh", GL_VERTEX_SHADER))   == 0) return 0;
    if ((fs = create_shader("fragShader.sh", GL_FRAGMENT_SHADER)) == 0) return 0;

    program = glCreateProgram();
    glAttachShader(program, vs);
    glAttachShader(program, fs);


    glLinkProgram(program);
    glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
    if (!link_ok) 
        fprintf(stderr, "glLinkProgram:");
        print_log(program);
        return 0;
    

    //Create Attributes
    cameraAttribute = glGetUniformLocation(program, "camera");
    if(cameraAttribute == -1)
        cout << "Error!";
    


    //Init sprites
    sprite1 = new Sprite();
    sprite2 = new Sprite();


    return 1;


void onDisplay()

    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
    glUseProgram(program);


    sprite1->render();
    sprite2->render();

    glutSwapBuffers();


void idle()


    //Create Projection Matrix to change clip space.
    mat4 projectionMatrix = perspective(60.0f, (float)glutGet(GLUT_WINDOW_WIDTH) / (float)glutGet(GLUT_WINDOW_HEIGHT), 0.1f, 100.f);
    glUniformMatrix4fv(cameraAttribute, 1, GL_FALSE, &projectionMatrix[0][0]);



void free_resources()

    glDeleteProgram(program);



int main(int argc, char* argv[]) 
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA|GLUT_ALPHA|GLUT_DOUBLE|GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutCreateWindow("My Second Triangle");
    glEnable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);

    if (init_resources()) 
        glutDisplayFunc(onDisplay);
        glutIdleFunc(idle);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        //uses glGetError to check for how many errors there are.
        cout << CheckGLErrors() << "\n";

        glutMainLoop();
    


    free_resources();
    return 0;

还有我的精灵文件:

#include "Sprite.h"

Sprite::Sprite()
    init();



void Sprite::init()

    GLfloat triangle_vertices[] = 
        0.0,  0.8f,
        -0.8f, -0.8f,
        0.8f, -0.8f,
    ;

    //Set attributes
    locationAttribute = glGetAttribLocation(program, "coord2d");
    if (locationAttribute == -1) 
        fprintf(stderr, "Could not bind attribute location");
    

    translationUniform = glGetUniformLocation(program, "translationUniform");
    if(translationUniform == -1)
        fprintf(stderr, "Could not bind attribute transformation");
    


    //Create buffer
    glGenBuffers(1, &mainBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, mainBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_vertices), triangle_vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);

    glVertexAttribPointer(
                          locationAttribute, // attribute
                          2,                 // number of elements per vertex, here (x,y)
                          GL_FLOAT,          // the type of each element
                          GL_FALSE,          // take our values as-is
                          0,                 // no extra data between each position
                          0                  // offset of first element
    );

    glBindBuffer(GL_ARRAY_BUFFER, 0);


void Sprite::render()
    glBindBuffer(GL_ARRAY_BUFFER, mainBuffer);
    glDrawArrays(GL_TRIANGLES, 0, 3);


和顶点着色器:(注意,版本由解析器添加)

attribute vec2 coord2d;

uniform mat4 translationUniform;
uniform mat4 camera;


void main(void) 

    gl_Position = camera * vec4(coord2d, -1.1, 1.0);

【问题讨论】:

【参考方案1】:

glEnable(GL_BLEND | GL_DEPTH_TEST);

你不能像这样组合这些,你必须发出两个 glEnable 命令。这可能会产生错误,或者启用完全不同的东西。

您将此与使用位掩码的 glClear 混淆了。

开始在您的代码中使用glGetError,它会为您发现这个问题。

【讨论】:

谢谢,但我只是出于绝望才尝试这个。它也不适用于两个单独的语句。 嗯,这很奇怪,这不是错误。 GL_BLEND 和 GL_DEPTH_TEST 的按位或为 0xBF3,这不是我能看到的任何 opengl 合法值。无论如何,我认为我发现了其他无关的东西,我将其发布在单独的帖子中。 @bipolarpants【参考方案2】:

好的,我重新阅读了这个问题,我想我现在明白了。

三角形在 -1 到 1 之外消失,因为没有任何投影矩阵,您绘制的是标准化的设备坐标,该坐标具有 -1 到 1 的近端和远端裁剪平面。这意味着任何具有 z 值的顶点都在外面-1 到 1 的值将被剔除。

其次,你说你没有看到它随着距离变小。这是透视投影的一个特性,你没有(因为你没有投影矩阵)。使用默认投影矩阵(正交),您不会得到任何透视缩短,因此无论距离如何,您的三角形都将显示相同的大小。如果你想对场景应用透视,那么你需要一个透视矩阵:尝试应用gluPerspective(1, 45, 0.1, 100);,这应该会给你更多的东西,就像你所期望的那样(三角形将出现,z 从 -0.1 到 -100,变得越来越小接近 z=-100)。您可能需要调整这些以匹配场景的规模。

【讨论】:

好的,原来我以为可能是这样。但是当我尝试时,我在顶点着色器中使用了转换(由 GLMs 透视()创建)并且没有效果。在我交换缓冲区之前,我也刚刚在我的 onDisplay() 函数中尝试了gluPerspective(1, 45, 0.1, 100);,它也没有任何效果。即,改变 FoV 没有做任何事情,剪切平面也没有受到影响。 @bipolarpants 请发布您的完整代码,我无法从那些小 sn-ps 中看出发生了什么。 我相信这就是一切,如果有任何不清楚/错误的地方,你可以告诉我,我是 OpenGL 的新手(而且只有平庸的 C++) 出错没关系,有时每个人都是新的,但代码看起来很乱。到处都有大量未使用的代码,我无法理解您要做什么。着色器中不使用translationUniform。您生成 PV 矩阵,然后忽略它。也许从清理它开始,这样你就可以真正使用你生成的变量,也许你会在这个过程中自己解决它。 @bipolarpants @bipolarpants:另外,您将“3”设置为 glVertexAttribPointer 的大小,应该为“2”,并且您在 sprite::move 中设置矩阵元素 3-3,它应该是 4-3(翻译在最后一列)。 gluPerspective 仅影响内置矩阵堆栈,如果您使用自己的 glm 矩阵,则无效。

以上是关于OpenGL深度不起作用,三角形消失的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL - 深度测试不起作用

着色器在 2d OpenGL 中不起作用

现代 OpenGL 投影视图模型转换不起作用

OpenGL - 链接两个纹理不起作用

绘制三角形不起作用:我只看到黑屏和鼠标

简单的 OpenTK 着色器不起作用