Squeak.ru - шаблоны программирования

Экземпляры кубов отображаются только один раз

Я пытаюсь создать четыре куба, которые находятся рядом друг с другом. Я хочу попробовать, например, эти кубики, так как позже я буду рисовать намного больше, чем четыре кубика. Я использовал несколько разных руководств по созданию текстурированного куба: 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;
}

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

19.04.2020


Ответы:


1

Вы должны использовать другую матрицу 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;
}  
19.04.2020
  • Я изменил свой вершинный шейдер и теперь вижу, что создается несколько кубов, но все они находятся в одном и том же положении. Есть ли способ изменить положение? Также в чем разница между использованием матрицы MVP или использованием смещения в вершинном шейдере, если есть разница 19.04.2020
  • @Dextron Пожалуйста, прочитайте комментарий в шейдере. Вероятно, смещение недостаточно велико. (Вы должны использовать большее значение, чем 0,1). Скорее всего, вместо этого вы захотите использовать униформу. 19.04.2020
  • Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...