来自 VBO/Shader/MVP 矩阵的乱码三角形使用 OpenGL 3.3

Garbled Triangles from VBO/Shader/MVP Matrix using OpenGL 3.3

在旧的 GLSL 版本上使用常规 VBO 绘图不是问题,但无论出于何种原因,我在使用 GLSL 3.3 时得到了这个结果。

它应该在每个轴上绘制一个 2x2 平面。

(颜色越浅越接近远平面,颜色越深越接近近平面)

3.3 的主要变化之一是您必须为模型视图投影矩阵提供制服,而不是使用旧提供的矩阵。

我不知道我做错了什么,但我几乎可以肯定这与模型视图投影数据有关。这是相关代码。

主要绘制方式

float r = 0.0f;
void display() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
    glClear(GL_COLOR_BUFFER_BIT);         // Clear the color buffer
    glClear(GL_DEPTH_BUFFER_BIT);         // And the depth buffer

    r += 0.001f;

    glUseProgram(program);
    glEnable(GL_DEPTH_TEST);

    GLuint uniformModel = glGetUniformLocation(program, "model");
    GLuint uniformView = glGetUniformLocation(program, "view");
    GLuint uniformProjection = glGetUniformLocation(program, "projection");

    glm::mat4 projection = glm::perspective(70.0f, 1.0f, 0.0f, 16.0f);
    glUniformMatrix4fv(uniformProjection, 1, GL_FALSE, glm::value_ptr(projection));

    glm::vec3 eye = glm::vec3(sin(r*0.33)*5.0f,5,cos(r*0.33)*5.0f);
    glm::vec3 center = glm::vec3(0.0f,0.0f,0.0f);
    glm::vec3 up = glm::vec3(0.0f,0.0f,1.0f);

    glm::mat4 view = glm::lookAt(eye, center, up);
    glUniformMatrix4fv(uniformView, 1, GL_FALSE, glm::value_ptr(view));

    glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f,0.0f,0.0f));

    glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));


    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(
            0,  
            3,    
            GL_FLOAT, 
            GL_FALSE, 
            0, 
            (void*)0 
    );

    glDrawElements(GL_TRIANGLES, 18, GL_UNSIGNED_INT, indices);

    glDisableVertexAttribArray(0);

    glDisable(GL_DEPTH_TEST);
    glUseProgram(0);

    glFlush();  // Render now
}

Vertex/Indices 数组和着色器

string vert
        = "#version 330 core\n"
        "layout(location = 0) in vec3 vertex;\n" 
        "uniform mat4 model;\n"
        "uniform mat4 view;\n"
        "uniform mat4 projection;\n"
        "void main(){\n" 
        " gl_Position = projection * view * model * vec4(vertex,1.0f);\n" 
        "}";
string frag
        = "#version 330 core\n"
        "out vec3 color;\n"
        "void main()\n"
        "{\n"
        " float lin = 1.0 / gl_FragCoord.w;\n"
        " float depth = (lin - 0.1) / (16.0 - 0.1);\n"
        " color = vec3(depth,depth,1.0f);\n"
        "}";

float* data = new float[36] {
    -1.0f,-1.0f,0.0f,
    1.0f,-1.0f,0.0f,
    1.0f,1.0f,0.0f,
    -1.0f,1.0f,0.0f,
    0.0f,-1.0f,-1.0f,
    0.0f,1.0f,-1.0f,
    0.0f,1.0f,1.0f,
    0.0f,-1.0f,1.0f,
    -1.0f,0.0f,-1.0f,
    1.0f,0.0f,-1.0f,
    1.0f,0.0f,1.0f,
    -1.0f,0.0f,1.0f
};

GLuint* indices = new GLuint[18] {
    0,1,2,
    0,3,2,
    4,5,6,
    4,7,6,
    8,9,10,
    8,11,10
};

初始化

const int winSize = 1024;
void glInit(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE);
    glutInitContextVersion(3,3);
    //glutInitContextFlags(GLUT_CORE_PROFILE | GLUT_DEBUG);
    glutInitWindowSize(winSize, winSize);
    glutInitWindowPosition(25, 25);
    glutCreateWindow("Loading...");
    glewExperimental = GL_TRUE;
    glewInit();
    glViewport (0, 0, winSize, winSize);
    camera.setPosition(0.0f,0.0f,4.0f);

    glGenVertexArrays(1, &vba);
    glBindVertexArray(vba);

    program = compileShader(vert, frag);

    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 3*4*3*4, data, GL_STATIC_DRAW);    


    glEnable(GL_DEPTH_TEST);
    while(!bExit) {
        string pre;
        pre.assign("Test Program - ");
        pre.append(std::to_string(fps));
        glutSetWindowTitle(pre.c_str());
        frames++;
        display();
    }
}

原来我是个白痴,这只是一种打字错误。

我在 init 方法和程序范围内定义了 GLuint vbo,但 vbo 的实际值仅放入局部变量。 display() 根本看不到 vbo。

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);

导致可笑错误的总是小事。 <_>