为什么从帧缓冲区创建的纹理未正确映射

问题描述 投票:1回答:1

我正在创建一个大小为1920 X 1080的自定义帧缓冲区,然后将此帧缓冲区的纹理映射到大小为800 X 600的默认帧缓冲区中的全屏矩形。

我在自定义帧缓冲区的屏幕中央绘制了一个矩形,并且在映射纹理后,我期望该矩形出现在中央。

但是矩形显示在左下角。

当我在自定义缓冲区中绘制全屏矩形并将其映射到大小为800 X 600的默认帧缓冲区中的全屏矩形时,而不是全屏显示时,它覆盖了整个左下角。

SCR_WIDTH = 800;
SCR_HEIGHT = 600;
int main(int argc, char *argv[])
{

    QApplication a(argc, argv);
    cont.SetName("RootItem");
    TreeModel* model = new TreeModel("RootElement", &cont);
    WavefrontRenderer w(model);
    w.show();
    glfwInit();
    int return_code;
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);  
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Renderer", nullptr, nullptr);   // Create the render window
    glfwSetWindowPos(window, 1120, 480);
    glfwFocusWindow(window);    
    glfwMakeContextCurrent(window);
    GLenum GlewInitResult;
    glewExperimental = GL_TRUE;
    GlewInitResult = glewInit();    
    glEnable(GL_MULTISAMPLE);
    glEnable(GL_DEPTH_TEST);    
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    ResourceManager::LoadShader("C:\\Shaders\\Test\\Vert.txt", "C:\\Shaders\\Test\\Frag.txt", nullptr, "ScreenShader");

    //create a texture object
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glBindTexture(GL_TEXTURE_2D, 0);


    // create a  renderbuffer object for depthbuffer
    glGenRenderbuffers(1, &rboDepthId);
    glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1920, 1080);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);

    // create a  framebuffer
    glGenFramebuffers(1, &fboMsaaId);
    glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);

    // attach colorbuffer image to FBO
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId , 0);

    // attach depthbuffer image to FBO
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepthId);
    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);   
    while (!glfwWindowShouldClose(window))
    {
        glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);
        glClearColor(1.0, 0.0, 0.0, 1.0);
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        w.render(); // Do rendering here    
        ResourceManager::GetShader("ScreenShader").Use();       
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glDisable(GL_DEPTH_TEST);
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glClear(GL_COLOR_BUFFER_BIT);
        ResourceManager::GetShader("ScreenShader").Use();
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, textureId);
        renderQuad();
        glfwPollEvents();
        glfwSwapBuffers(window);
          }
     glfwTerminate();   
     return  a.exec();


}

///////////////////////////////////////////////// ///////////////////////////////////////////////////// /渲染四边形功能定义

unsigned int quadVAO = 0;
unsigned int quadVBO;
void renderQuad()
{
    if (quadVAO == 0)
    {
        float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
        // positions   // texCoords
        -1.0f,  1.0f,  0.0f, 1.0f,
        -1.0f, -1.0f,  0.0f, 0.0f,
         1.0f, -1.0f,  1.0f, 0.0f,

        -1.0f,  1.0f,  0.0f, 1.0f,
         1.0f, -1.0f,  1.0f, 0.0f,
         1.0f,  1.0f,  1.0f, 1.0f
        };
        //  VAO
        glGenVertexArrays(1, &quadVAO);
        glGenBuffers(1, &quadVBO);
        glBindVertexArray(quadVAO);
        glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));

    }

    glBindVertexArray(quadVAO);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
    glBindVertexArray(0);
}
opengl glsl framebuffer
1个回答
0
投票
当您在不同大小的帧缓冲区之间切换时,必须将视口调整为新的大小。用glViewport设置视口。可以通过glViewport获得默认帧缓冲区的大小(更改窗口大小时,窗口帧缓冲区的大小也会更改)。此外,OpenGL是一个状态引擎。状态是持久的,直到再次更改,甚至超出框架为止。如果第一遍使用glfwGetFramebufferSize,但第二遍没有使用glfwGetFramebufferSize,则深度测试必须在循环中bs开启和关闭:

Depth Test

© www.soinside.com 2019 - 2024. All rights reserved.