简体   繁体   中英

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

Drawing with a regular VBO on older GLSL versions is not a problem but for whatever reason I get this result when using GLSL 3.3.

It should be drawing a 2x2 plane on each axis.

(Lighter colors are closer to the far plane, darker are closer to the near plane) 问题图片

One of the major changes with 3.3 was that you have to provide uniforms with your Model View Projection matrixes as opposed to using the old provided ones.

I don't know what I'm doing wrong but I'm almost certain it's something to do with the Model View Projection data. Here is the relevant code.

Main draw method

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 Array & Shader

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
};

Init

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();
    }
}

Turns out I'm an idiot and it was just a typo kind of error.

I define GLuint vbo in the init method AND on the scope of the program as well but the actual value of the vbo is only put into local variable. display() didn't have visibility of the vbo at all.

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

It's always the little things that cause ridiculous bugs. <_>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM