绘制不同尺寸的FBO

Posted

技术标签:

【中文标题】绘制不同尺寸的FBO【英文标题】:Drawing to different size FBO 【发布时间】:2014-11-20 01:08:28 【问题描述】:

我在使用 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 是否与当前绑定的帧缓冲区有关?据我了解,该函数只是用来设置要在其中进行绘图的窗口上的矩形区域。

任何建议将不胜感激。我尝试在网上搜索问题,唯一类似的事情是在this SO question,但它没有帮助我。

【问题讨论】:

【参考方案1】:

您需要使用渲染目标的大小调用glViewport()。唯一可以不调用它就可以逃脱的情况是当您渲染到窗口时,并且窗口永远不会调整大小。这是因为默认视口与初始窗口大小相匹配。来自规范:

在初始状态下,w 和 h 分别设置为 GL 要在其中进行渲染的窗口的宽度和高度。

如果要渲染到与窗口大小不同的 FBO,则必须使用 FBO 的大小调用 glViewport()。而当你返回渲染到窗口时,你需要再次调用glViewport()与窗口大小。

视口尺寸不是每个帧缓冲区状态。我一直认为这是有道理的,但它不是这样定义的。因此,无论何时调用 glViewport(),您都在更改全局(即每个上下文)状态,与当前绑定的帧缓冲区无关。

【讨论】:

它奏效了,出乎意料。谢谢你。看来是我内部代码有问题,不过你的解决方案确实不错。

以上是关于绘制不同尺寸的FBO的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 上针对不同的屏幕尺寸和密度重用可绘制图像

c_cpp DrawEllipse()函数(绘制不同角度,相同尺寸的椭圆)

渲染到屏幕和 FBO 给出不同的结果

渲染到窗口帧缓冲区和 FBO 以保存全尺寸纹理图像

如何处理不同的图像尺寸

OpenGL 帧缓冲区 + LibGDX