Экземплярные кубы отображаются только один раз - PullRequest
2 голосов
/ 19 апреля 2020

Я пытаюсь создать четыре куба, которые находятся рядом друг с другом. Я хочу попробовать эти кубики, потому что я буду рисовать много больше, чем четыре куба позже. Я следовал нескольким различным урокам, чтобы создать текстурированный куб: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/, а затем создать экземпляр этого куба: https://learnopengl.com/Advanced-OpenGL/Instancing Когда я запускаю свою программу, я получаю только один показанный куб. Я использую камеру для перемещения по окну, позволяя мне видеть любые другие возможные кубы, которые будут показывать только один куб.

Это моя основная функция:

int main(){
    if (!glfwInit()) {
        std::cout << "Failed to initialize GLFW!" << std::endl;
    }
    //GLFWwindow* window;
    int width = 1024; int height = 700;
    window = glfwCreateWindow(width, height, "Paradise", NULL, NULL);
    if (!window) {
        std::cout << "Failed to initialize window!" << std::endl;
    }
    glfwMakeContextCurrent(window);

    if (glewInit() != GLEW_OK) {
        std::cout << "failed to initialize GLEW!" << std::endl;
    }
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    static const GLfloat g_vertex_buffer_data[] = {
    -1.0f,-1.0f,-1.0f, // triangle 1 : begin
    -1.0f,-1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f, // triangle 1 : end
    1.0f, 1.0f,-1.0f, // triangle 2 : begin
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f, // triangle 2 : end
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f
    };

    static const GLfloat g_uv_buffer_data[] = {
    0.000059f, 1.0f - 0.000004f,
    0.000103f, 1.0f - 0.336048f,
    0.335973f, 1.0f - 0.335903f,
    1.000023f, 1.0f - 0.000013f,
    0.667979f, 1.0f - 0.335851f,
    0.999958f, 1.0f - 0.336064f,
    0.667979f, 1.0f - 0.335851f,
    0.336024f, 1.0f - 0.671877f,
    0.667969f, 1.0f - 0.671889f,
    1.000023f, 1.0f - 0.000013f,
    0.668104f, 1.0f - 0.000013f,
    0.667979f, 1.0f - 0.335851f,
    0.000059f, 1.0f - 0.000004f,
    0.335973f, 1.0f - 0.335903f,
    0.336098f, 1.0f - 0.000071f,
    0.667979f, 1.0f - 0.335851f,
    0.335973f, 1.0f - 0.335903f,
    0.336024f, 1.0f - 0.671877f,
    1.000004f, 1.0f - 0.671847f,
    0.999958f, 1.0f - 0.336064f,
    0.667979f, 1.0f - 0.335851f,
    0.668104f, 1.0f - 0.000013f,
    0.335973f, 1.0f - 0.335903f,
    0.667979f, 1.0f - 0.335851f,
    0.335973f, 1.0f - 0.335903f,
    0.668104f, 1.0f - 0.000013f,
    0.336098f, 1.0f - 0.000071f,
    0.000103f, 1.0f - 0.336048f,
    0.000004f, 1.0f - 0.671870f,
    0.336024f, 1.0f - 0.671877f,
    0.000103f, 1.0f - 0.336048f,
    0.336024f, 1.0f - 0.671877f,
    0.335973f, 1.0f - 0.335903f,
    0.667969f, 1.0f - 0.671889f,
    1.000004f, 1.0f - 0.671847f,
    0.667979f, 1.0f - 0.335851f
    };

    GLuint Texture = loadBMP_custom("uvtemplate.bmp");

    const int cubeAmount = 4;
    glm::vec2 cubes[cubeAmount];
    int index = 0;
    //float offset = 0.1f;
    for (int x = 0; x < cubeAmount; x++) {
        std::cout << x << std::endl;
        glm::vec2 translation;
        translation.x = (float)x / 10.0f; // divide by ten so 3 become 0.3 creates less space
        cubes[index++] = translation;
    }

    GLuint programID = LoadShaders("Shader.vs", "Shader.fs");

    //store instanced data in an array buffer
    unsigned int instanceVBO;
    glGenBuffers(1, &instanceVBO);
    glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2)* cubeAmount, &cubes[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

    GLuint texturebuffer;
    glGenBuffers(1, &texturebuffer);
    glBindBuffer(GL_ARRAY_BUFFER, texturebuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_uv_buffer_data), g_uv_buffer_data, GL_STATIC_DRAW);

    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
    glBindBuffer(GL_ARRAY_BUFFER, 1);
    glVertexAttribDivisor(2, 1);


    glEnable(GL_CULL_FACE);

    while (!glfwWindowShouldClose(window)) {
        glClearColor(0.0f / 255.0f, 170.0f / 255.0f, 204.0f / 255.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(programID);

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

        computeMatricesFromInputs();
        glm::mat4 ProjectionMatrix = getProjectionMatrix();
        glm::mat4 ViewMatrix = getViewMatrix();
        glm::mat4 ModelMatrix = glm::mat4(1.0);
        glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;

        GLuint MatrixID = glGetUniformLocation(programID, "MVP");
        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
        //glDrawArrays(GL_TRIANGLES, 0, 12*3);
        glDrawArraysInstanced(GL_TRIANGLES, 0, 12 * 3, 4);
        glDisableVertexAttribArray(0);

        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, texturebuffer);
        glVertexAttribPointer(
            1,
            2,
            GL_FLOAT,
            GL_FALSE,
            0,
            (void*)0
        );
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}

Vertex Shader :

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;

out vec2 UV;

uniform mat4 MVP;

void main(){
    gl_Position = MVP * vec4(vertexPosition_modelspace,1);
    UV = vertexUV;
}

Фрагментный шейдер:

#version 440 core

in vec2 UV;

out vec3 color;

uniform sampler2D myTextureSampler;

void main(){
    color = texture( myTextureSampler, UV ).rgb;
}

Я подумал, что это может произойти, поскольку все четыре куба находятся в одной позиции, и я попытался изменить положение каждого куба. изменив:

for (int x = 0; x < cubeAmount; x++) {
    std::cout << x << std::endl;
    glm::vec2 translation;
    translation.x = (float)x / 10.0f;
    cubes[index++] = translation;
}

на это:

for (int x = 0; x < cubeAmount; x++) {
    std::cout << x << std::endl;
    glm::vec2 translation;
    translation.x = (float)x / 20.0f;
    cubes[index++] = translation;
}

в надежде, что это изменит позицию. Это только переместило единственный куб в другое место и не показывало никаких других кубов. Что я тут не так сделал?

1 Ответ

2 голосов
/ 19 апреля 2020

Вы должны использовать разные матрицы MVP в каждом случае, как я упоминал в ответе на предыдущий вопрос Создание кубов рядом друг с другом OpenGL .

В качестве альтернативы вы можете вычислить перевод в зависимости от gl_InstanceID в вершинном шейдере. Например:

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;

out vec2 UV;

uniform mat4 MVP;

void main(){
    const float offset = 0.1; // this is just a guess, probably you have to adapt it

    vec3 pos = vertexPosition_modelspace;
    pos.x += float(gl_InstanceID) * offset;

    gl_Position = MVP * vec4(pos, 1.0);
    UV = vertexUV;
}  
...