【问题标题】:Instanced cubes only displaying once实例化的立方体只显示一次
【发布时间】:2020-04-19 08:06:43
【问题描述】:

我正在尝试创建四个彼此相邻的立方体。我想尝试实例化这些立方体,因为稍后我将绘制超过四个立方体。我一直在遵循一些不同的教程来创建纹理立方体: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();
    }
}

顶点着色器:

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

希望这会改变立场。这只是将单个立方体移动到另一个位置,并没有显示任何其他立方体。我在这里做错了什么?

【问题讨论】:

  • “希望这会改变立场。” 不,它不会——它应该怎么做?您必须在每个实例中使用不同的 MVP 矩阵,正如我在回答您之前的问题 Instancing cubes next to each other OpenGL 中提到的

标签: c++ opengl glsl c++17 shader


【解决方案1】:

您必须在每个实例中使用不同的MVP 矩阵,正如我在您上一个问题Instancing cubes next to each other 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;
}  

【讨论】:

  • 我已经修改了我的顶点着色器,现在可以看到创建了多个立方体但都在同一个位置有办法改变位置。另外,如果存在差异,使用 MVP 矩阵或使用顶点着色器中的偏移量会有什么区别
  • @Dextron 请阅读着色器中的评论。可能偏移量不够大。 (您必须使用大于 0.1 的值)。您可能想改用制服。
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多