Как получить движение камеры при использовании кадровых буферов openGL - PullRequest
0 голосов
/ 16 апреля 2020

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

До сих пор у меня есть текстура для успешного рендеринга на квад, что я Затем я вывожу на экран, который в целях тестирования в основном такой же, как когда я не использовал fbo. Моя проблема возникает, когда я пытаюсь заставить движение камеры отображаться с использованием визуализированной текстуры. я знаю, что это определенно возможно, так как существует множество примеров, но я не смог заставить их работать с моим кодом. Я почти уверен, что моя проблема связана с моими шейдерами, но я просмотрел множество веб-сайтов, учебных пособий по YouTube, примеров openGL и не нашел ничего, что работает. Насколько я знаю, я должен визуализировать сцену как обычно, поэтому я использовал те же шейдеры, которые работали для меня ранее на начальном этапе рендеринга, но я использовал мое fbo вместо стандартного fbo

для простоты я только что рендерил точечный куб, так как он быстрее, чем генерирует фрактал каждый раз.

вот основные настройки fbo, texture и rbo:

GLuint fbo;
GLuint texturebuffer;
GLuint rbo;
void initFBO(){
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    glGenTextures(1, &texturebuffer);
    glBindTexture(GL_TEXTURE_2D, texturebuffer);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WINDOW_WIDTH, WINDOW_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texturebuffer, 0);

    glGenRenderbuffers(1, &rbo);
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, WINDOW_WIDTH, WINDOW_HEIGHT);
    glBindRenderbuffer(GL_RENDERBUFFER, 0); // once rbo memory allocated unbind
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
}

вот основной и ничейный l oop:

int main(){
    if(!setup())
        return -1;

    // // white background
    glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    // GLuint programID = LoadShaders( "new_vertex_shader", "new_fragment_shader" ); // custom shader
    GLuint programID = LoadShaders("new_vertex_shader", "new_fragment_shader");
    GLuint modelMatrixID = glGetUniformLocation(programID, "model");
    GLuint viewMatrixID = glGetUniformLocation(programID, "view");    
    GLuint matrixID = glGetUniformLocation(programID, "MVP");

    GLuint quad_programID = LoadShaders( "screen_vertex_shader", "screen_fragment_shader" );
    GLuint textureID = glGetUniformLocation(quad_programID, "screenTexture");

    // initialise mvp matrices
    glm::mat4 ProjectionMatrix = perspective(radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);
    glm::mat4 ViewMatrix = translate(mat4(1.0f), vec3(0,0,-RADIUS));
    glm::mat4 ModelMatrix = mat4(1.0f);
    glm::mat4 MVP;

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    GLfloat cube[24] = {
        0.5,0.5,0.5,
        0.5,-0.5,0.5,
        -0.5,0.5,0.5,
        -0.5,-0.5,0.5,
        0.5,0.5,-0.5,
        0.5,-0.5,-0.5,
        -0.5,-0.5,-0.5,
        -0.5,0.5,-0.5
    };
    glBufferData(GL_ARRAY_BUFFER, sizeof(cube),cube, GL_STATIC_DRAW);

    glfwSetMouseButtonCallback(window, mouseCallback);


    // ################# main draw loop #######################
    while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 ){

        // render to fbo first
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glEnable(GL_DEPTH_TEST);
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        computeMatricesFromInputs();
        ProjectionMatrix = getProjectionMatrix();
        ViewMatrix = getViewMatrix();
        ModelMatrix = getModelMatrix();
        MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;

        // Use our shader
        glUseProgram(programID);

        // Send our transformation to the currently bound shader in the "MVP" uniform
        glUniformMatrix4fv(matrixID, 1, GL_FALSE, &MVP[0][0]);
        glUniformMatrix4fv(modelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]);
        glUniformMatrix4fv(viewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);

        // render scene as normal
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); // index buffer
        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
        );

        glPointSize(POINT_SIZE);
        glDrawArrays(GL_POINTS, 0, sizeof(cube));
        glDisableVertexAttribArray(0);


        // bind back to default frame buffer to show on screen
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glDisable(GL_DEPTH_TEST);
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(quad_programID);

        glEnableVertexAttribArray(0);
        glBindVertexArray(quad_vertex_buffer);

        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
        );
        glDrawArrays(GL_POINTS, 0, sizeof(cube));
        glDisableVertexAttribArray(0);

        // Swap buffers
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

вершинный шейдер:

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;

// Values that stay constant for the whole mesh.
uniform mat4 MVP;
uniform mat4 view;
uniform mat4 model;

void main(){

    // Output position of the vertex, in clip space : MVP * position
    gl_Position =  MVP * vec4(vertexPosition_modelspace,1.0);

}

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

#version 330 core

// Output data
out vec3 color;

void main(){

    // Output color = black 
    color = vec3(0,0,0);

}

экран четырехвершинного шейдера :

#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;

out vec2 TexCoords;

void main()
{
    TexCoords = aTexCoords;
    gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
}

фрагмент экрана шейдера:

#version 330 core
out vec4 FragColour;

in vec2 TexCoords;

uniform sampler2D screenTexture;

void main()
{
    FragColour = texture(screenTexture, TexCoords);
}

извините, если это довольно большой блок кода, я не совсем уверен, где ошибка будет l ie и я немного новичок в использовании openGL. заранее большое спасибо за любую помощь.

1 Ответ

0 голосов
/ 16 апреля 2020

glEnableVertexAttribArray изменяет состояние объекта Vertex Array . Это должно быть сделано после связывания VAO с помощью glBindVertexArray.
Я предполагаю, что quad_vertex_buffer - это объект массива вершин, хотя имя "vertex_buffer" вводит в заблуждение.

glBindVertexArray(quad_vertex_buffer);
glEnableVertexAttribArray(0);

Когда вы рисуете квадрант пространства экрана (2-й проход), вы должны использовать тип примитив , который генерирует (заполненный) многоугольник (вероятно, GL_TRIANGLES или * 1017). *), а не тип точечного примитива GL_POINTS:

glDrawArrays(GL_POINTS, 0, sizeof(cube));

glDrawArrays(GL_TRIANGLE_STRIP, 0, sizeof(cube))
...