C++ OpenGL 纹理立方体缺少三角形

C++ OpenGL Textured Cube Missing Triangles

在我努力掌握 OpenGL 的过程中,当我遇到这个问题时,我正试图制作一个带纹理的立方体: 只有我的立方体的一部分正在渲染。应该有 12 个三角形,但只渲染了其中的 3 个。我看过很多教程,但我似乎找不到我们代码之间的 problem/main 区别。这是我的:

...

int main(int argc, char* argv[]) {
    if (!setupGLFW()) return 1;
    setupApple();

    glfwWindowHint(GLFW_SAMPLES, 4);

    GLFWwindow* window = glfwCreateWindow(WIN_WIDTH, WIN_HEIGHT, "Textured Cube", NULL, NULL);
    if (!window) {
        log_msg(LOG_ERROR, "Could not open a GLFW3 window!\n");

        return 1;
    }

    glfwMakeContextCurrent(window);

    if (!setupGLEW()) return 1;

    glClearColor(0.5, 0.5, 0.5, 1.0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    static const int vertices = 12 * 3;
    static const GLfloat points[] = {
        -1.0, -1.0, -1.0,
        -1.0, -1.0,  1.0,
        -1.0,  1.0,  1.0,
         1.0,  1.0, -1.0,
        -1.0, -1.0, -1.0,
        -1.0,  1.0, -1.0,
         1.0, -1.0,  1.0,
        -1.0, -1.0, -1.0,
         1.0, -1.0, -1.0,
         1.0,  1.0, -1.0,
         1.0, -1.0, -1.0,
        -1.0, -1.0, -1.0,
        -1.0, -1.0, -1.0,
        -1.0,  1.0,  1.0,
        -1.0,  1.0, -1.0,
         1.0, -1.0,  1.0,
        -1.0, -1.0,  1.0,
        -1.0, -1.0, -1.0,
        -1.0,  1.0,  1.0,
        -1.0, -1.0,  1.0,
         1.0, -1.0,  1.0,
         1.0,  1.0,  1.0,
         1.0, -1.0, -1.0,
         1.0,  1.0, -1.0,
         1.0, -1.0, -1.0,
         1.0,  1.0,  1.0,
         1.0, -1.0,  1.0,
         1.0,  1.0,  1.0,
         1.0,  1.0, -1.0,
        -1.0,  1.0, -1.0,
         1.0,  1.0,  1.0,
        -1.0,  1.0, -1.0,
        -1.0,  1.0,  1.0,
         1.0,  1.0,  1.0,
        -1.0,  1.0,  1.0,
         1.0, -1.0,  1.0
    };


    static const GLfloat textureCoords[] = {
        0, 0,
        1, 0,
        0, 1,
        0, 1,
        1, 0,
        1, 1,
        0, 0,
        1, 0,
        0, 1,
        0, 1,
        1, 0,
        1, 1,
        0, 0,
        1, 0,
        0, 1,
        0, 1,
        1, 0,
        1, 1,
        0, 0,
        1, 0,
        0, 1,
        0, 1,
        1, 0,
        1, 1,
        0, 0,
        1, 0,
        0, 1,
        0, 1,
        1, 0,
        1, 1,
        0, 0,
        1, 0,
        0, 1,
        0, 1,
        1, 0,
        1, 1,
    };

    GLuint pointBuffer;
    glGenBuffers(1, &pointBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, pointBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices * 3, points, GL_STATIC_DRAW);

    GLuint textureBuffer;
    glGenBuffers(1, &textureBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices * 2, textureCoords, GL_STATIC_DRAW);

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glBindBuffer(GL_ARRAY_BUFFER, pointBuffer);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    GLuint program = getProgramFromFiles("text_cube.vs.glsl", "text_cube.fs.glsl");
    glm::mat4 MVP = calculateMVP();
    GLuint texture = loadBMP("uvtemplate.bmp");

    if (!program) {
        log_msg(LOG_ERROR, "There was a problem opening shader.\n");

        // clean up
        return 1;
    }

    if (!texture) {
        log_msg(LOG_ERROR, "There was a problem opening shader.\n");

        // clean up
        return 1;
    }

    glUseProgram(program);

    GLuint MVPID = glGetUniformLocation(program, "MVP");
    GLuint textureID = glGetUniformLocation(program, "cube_texture");

    glUniformMatrix4fv(MVPID, 1, GL_FALSE, &MVP[0][0]);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glUniform1i(textureID, 0);

    while (!glfwWindowShouldClose(window) && glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, vertices);

        glfwPollEvents();
        glfwSwapBuffers(window);
    }

    // clean up
    return 0;
} 

请注意,错误不在 setupGLFW()setupApple()setupGLEW()getProgramFromFiles()calculateMVP()loadBMP() ,或者我的顶点和片段着色器,它们在不同的文件中。这编译得很好,因为我包括 myglutils.h 中的 GLFWGLEW 这是 uvtemplate.bmp,它是一个 512x512 图像:

如果你们能帮助我,我将不胜感激。谢谢!

问题是对 glBufferData() 的调用。您以浮点数设置大小,但必须使用 sizeof(GLfloat) 以字节为单位指定它。这就是 OpenGL 没有收到您的所有数据的原因。

void glBufferData
    (
    GLenum target,
    GLsizeiptr size,
    const GLvoid* data,
    GLenum usage
    );

所以你需要替换:

glBufferData(GL_ARRAY_BUFFER, vertices * 3, points, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, vertices * 2, textureCoords, GL_STATIC_DRAW);

与:

glBufferData(GL_ARRAY_BUFFER, vertices * 3 * sizeof(GLfloat), points, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, vertices * 2 * sizeof(GLfloat), textureCoords, GL_STATIC_DRAW);