Почему на моем экране не отображается куб с этим кодом в окне GLFW? - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть набор кода (скопированный из различных учебных пособий), который должен нарисовать случайный куб с изменяющимся цветом, который камера перемещает каждую секунду или около того (с переменной, пока не использующей таймеры). В прошлом это работало до того, как я переместил свой код в отдельные классы и поместил его в основную функцию, но теперь я не вижу ничего в главном окне, кроме пустого фона. Я не могу точно указать здесь какую-либо конкретную проблему, так как я не получаю никаких ошибок или исключений, и мой собственный код определяется мной;когда я отлаживал, каждая переменная имела ожидаемое мной значение, и шейдеры, которые я использовал (в строковой форме), работали в прошлом, прежде чем я реорганизовал свой код. Я могу распечатать вершины куба в том же объеме, что и функция glDrawArrays(), и они также имеют правильные значения. По сути, я понятия не имею, что не так с моим кодом, из-за которого ничего не рисуется.

Мое лучшее предположение, что я вызвал - или забыл вызвать - некоторую функцию opengl неправильно с неправильными данными в одном изтри метода моего Model класса. В моей программе я создаю объект Model (после инициализации glfw и glad, который затем вызывает конструктор Model), обновляю его время от времени (время не имеет значения) с помощью функции update(),затем выводите его на мой экран каждый раз, когда мой основной цикл выполняется с помощью функции draw().

Возможные места ошибок кода:

    Model::Model(std::vector<GLfloat> vertexBufferData, std::vector<GLfloat> colorBufferData) {

        mVertexBufferData = vertexBufferData;
        mColorBufferData = colorBufferData;

        // Generate 1 buffer, put the resulting identifier in vertexbuffer
        glGenBuffers(1, &VBO);
        // The following commands will talk about our 'vertexbuffer' buffer
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        // Give our vertices to OpenGL.
        glBufferData(GL_ARRAY_BUFFER, sizeof(mVertexBufferData), &mVertexBufferData.front(), GL_STATIC_DRAW);

        glGenBuffers(1, &CBO);
        glBindBuffer(GL_ARRAY_BUFFER, CBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(mColorBufferData), &mColorBufferData.front(), GL_STATIC_DRAW);

        // Create and compile our GLSL program from the shaders
        programID = loadShaders(zachos::DATA_DEF);
        glUseProgram(programID);
    }

    void Model::update() {
        for (int v = 0; v < 12 * 3; v++) {
            mColorBufferData[3 * v + 0] = (float)std::rand() / RAND_MAX;
            mColorBufferData[3 * v + 1] = (float)std::rand() / RAND_MAX;
            mColorBufferData[3 * v + 2] = (float)std::rand() / RAND_MAX;
        }
        glBufferData(GL_ARRAY_BUFFER, sizeof(mColorBufferData), &mColorBufferData.front(), GL_STATIC_DRAW);
    }

    void Model::draw() {

        // Setup some 3D stuff
        glm::mat4 mvp = Mainframe::projection * Mainframe::view * model;

        GLuint MatrixID = glGetUniformLocation(programID, "MVP");
        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);

        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glVertexAttribPointer(
            0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  // size
            GL_FLOAT,           // type
            GL_FALSE,           // normalized?
            0,                  // stride
            (void*)0            // array buffer offset
        );
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, CBO);
        glVertexAttribPointer(
            1,                                // attribute. No particular reason for 1, but must match the layout in the shader.
            3,                                // size
            GL_FLOAT,                         // type
            GL_FALSE,                         // normalized?
            0,                                // stride
            (void*)0                          // array buffer offset
        );

        // Draw the array
        glDrawArrays(GL_TRIANGLES, 0, mVertexBufferData.size() / 3);

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
    };

Мой вопрос прост, как получается моя программане будет рисовать куб на моем экране? Проблема в этих трех функциях или в другом месте? При необходимости я могу предоставить более общую информацию о процессе рисования, хотя я полагаю, что предоставленного мной кода достаточно, поскольку я буквально просто вызываю model.draw().

1 Ответ

1 голос
/ 06 ноября 2019

sizeof (std :: vector) обычно будет всего 24 байта (поскольку структура обычно содержит 3 указателя). Таким образом, в основном в оба ваших буфера загружено 6 поплавков, что недостаточно для вершин для одного треугольника, не говоря уже о кубе!

Вместо этого вы должны вызывать size () для вектора при загрузке данных вбуферы вершин.

glBufferData(GL_ARRAY_BUFFER,
   mVertexBufferData.size() * sizeof(float), ///< this!
   mVertexBufferData.data(), ///< prefer calling data() here!
   GL_STATIC_DRAW);
...