首页 > 解决方案 > 渲染到帧缓冲区只渲染我场景的左下角

问题描述

在此处输入图像描述

当我使用小于我的窗口大小的帧缓冲区渲染相同的场景时,我只得到场景的最左下角,我希望看到中心。两个场景的渲染方式完全相同,相机位于完全相同的位置。

关于什么可能导致帧缓冲区仅渲染场景的左下角的任何想法?似乎有些东西需要按比例缩小。

这是相关代码,如果您希望我包含其他任何内容,请告诉我。我非常确信在屏幕上绘制纹理的代码是正确的,它不会进行任何缩放或平移。

我用来绘制帧缓冲区的四边形。坐标是 x,y,z 然后是纹理坐标。

float texture_test[] = {
    -0.5, -0.5, 0,      0.0f, 0.0f,
    0.5, -0.5, 0,       1.0, 0.0,
    0.5, 0.5, 0,        1.0, 1.0,

    -0.5, -0.5, 0,      0.0, 0.0,
    0.5, 0.5, 0,        1.0, 1.0,
    -0.5, 0.5, 0,       0.0, 1.0

};

初始化代码:

int WIDTH = 1440;
int HEIGHT = 900;


// Create FBO
unsigned int fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);


// Create texture
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

// ---- If I change WIDTH/10 to WIDTH and HEIGHT/10 to HEIGHT the center of the textured scene is now correct. 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH/10 , HEIGHT/10, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


// Attaches the texture to the framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);


unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, WIDTH/10, HEIGHT/10 );

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);


assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindRenderbuffer(GL_RENDERBUFFER, 0); 
glBindFramebuffer(GL_FRAMEBUFFER, 0);

主循环:

glUseProgram(shaderProgram.program_id);


// this sets uniforms for the view matrix, perspective matrix, and camera position
glw_update_camera(&shaderProgram, &cam);

glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

glClearColor(0.7, 0.7, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// this binds vertex array to the cube vertex, then set uniforms for model matrix and color then calls glDrawArrays thousands of times
draw_cubes(&shaderProgram, &main_chunk, &player, &raycast_result);


glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

glClearColor(0.7, 0.7, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// now do exact same thing for the main screen NO STATE HAS BEEN MODIFIED!!!
draw_cubes(&shaderProgram, &main_chunk, &player, &raycast_result);

标签: c++opengl

解决方案


除了相机矩阵,还必须通过调用 [ glViewport]/ https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glViewport.xhtml来定义视口映射(从 NDC 到像素坐标) (。

在您的情况下,您必须确保此视口映射将相机区域的中心映射到帧缓冲区,同时仍保持相同的比例。例如,这可以使用以下代码来完成:

int window_viewport_width, window_viewport_height;
int x = -(window_viewport_width - framebuffer_width )/ 2;
int y = -(window_viewport_height - framebuffer_height) / 2;

glViewport(x,y, window_viewport_width, window_viewport_height);

必须在渲染到帧缓冲区之前调用此代码。也不要忘记在渲染到窗口之前重置它:

//Bind framebuffer
glViewport(x, y, window_viewport_width, window_viewport_height);
glDraw*();

//Unbind framebuffer
glViewport(0, 0, window_viewport_width, window_viewport_height);
glDraw*();

如果你的意思是“看到中心”,你想看到完整的场景,那么使用下面的映射

glViewport(0, 0, framebuffer_width, framebuffer_height);

推荐阅读