我在使用 FBO 时遇到问题。
我的窗口大小是 1200x300。
当我创建一个 1200x300 的 FBO 时,一切都很好。
但是,当我创建大小为 2400x600 的 FBO(实际上,两个轴都大两倍)并尝试渲染完全相同的图元时,我只使用了 FBO 实际面积的四分之一。
FBO 与窗口大小相同:
FBO 大两倍(可以注意到三角形剪裁):
我将这两个三角形渲染到 FBO 中,然后渲染一个带有 FBO 纹理的全屏四边形。我用这种松绿色清除了 FBO,所以我确定第二张图片上的所有空白空间实际上都来自 FBO。
// init() of the program
albedo = new RenderTarget(2400, 600, 24 /*depth*/); // in first case, params are 1200, 300, 24
// draw()
RenderTarget::set(albedo); // render to fbo
RenderTarget::clearColor(0.0f, 0.3f, 0.3f, 1.0f);
RenderTarget::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// render triangles ...
glDrawArrays(GL_TRIANGLES, 0, 6);
// now it's time to render a fullscreen quad
RenderTarget::set(); // render to back-buffer
RenderTarget::clearColor(0.3f, 0.0f, 0.0f, 1.0f);
RenderTarget::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, albedo->texture());
glUniform1i(albedoUnifLoc, 0);
RenderTarget::drawFSQ(); // draw fullscreen quad
我没有任何类型的相机,我不在任何地方使用 glViewport
,我总是发送要在单位平方空间中绘制的图元的坐标(x 和 y 坐标都在[-1,1] 范围)。
问题是,我做错了什么,我该如何解决?
另外一个问题是,glViewport
是否与当前绑定(bind)的帧缓冲区相关?据我了解,该函数仅用于设置将要进行绘图的窗口上的矩形区域。
任何建议将不胜感激。我尝试在网上搜索问题,唯一相似的是在this SO question ,但对我没有帮助。
最佳答案
您需要使用渲染目标的大小调用 glViewport()
。唯一可以不调用它就可以逃脱的情况是当您渲染到窗口时,并且窗口永远不会调整大小。这是因为默认视口(viewport)与初始窗口大小相匹配。来自规范:
In the initial state, w and h are set to the width and height, respectively, of the window into which the GL is to do its rendering.
如果你想渲染到一个与你的窗口大小不同的 FBO,你必须使用 FBO 的大小调用 glViewport()
。而当你返回渲染到窗口时,你需要再次调用 glViewport()
与窗口大小。
视口(viewport)尺寸不是每个帧缓冲区状态。我一直认为这是有道理的,但它不是这样定义的。因此,每当您调用 glViewport()
时,您都在更改全局(即每个上下文)状态,与当前绑定(bind)的帧缓冲区无关。
关于opengl - 绘制不同尺寸的FBO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27030024/