2012-03-09 106 views
6

离屏渲染到纹理绑定的离屏帧缓冲区对象应该是如此微不足道,但我有一个问题,我无法环绕我的头。OpenGL渲染到纹理通过FBO - 不正常的显示与普通纹理

我的全样本程序(!2D现在只)是在这里:

http://pastebin.com/hSvXzhJT

的一些描述,请参阅下文。

我创建了一个rgba纹理对象512x512,将它绑定到一个FBO。在这一点上,不需要深度或其他渲染缓冲区,严格来说是2D。

以下非常简单的着色器渲染到这个纹理:

顶点着色器:

varying vec2 vPos; attribute vec2 aPos; 
void main (void) { 
    vPos = (aPos + 1)/2; 
    gl_Position = vec4(aPos, 0.0, 1.0); 
} 

在此者刚刚获得含4个XY COORDS为四(一VBO -1,-1 :: -1,-1 :: 1,-1 :: 1)

因此,尽管帧缓冲区分辨率理论上应该是512x512,但着色器显然会将其“纹理”渲染到“全屏幕(四屏)四边形” GLs -1..1协调范式。

片段着色器:

varying vec2 vPos; 
void main (void) { 
    gl_FragColor = vec4(0.25, vPos, 1); 
} 

因此它设置完全不透明的颜色有红色取决于X/Y轴固定在0.25和绿色/蓝色的任何地方在这一点上我的假设0和1之间

是渲染的512x512纹理仅显示-1..1全 - (关)屏幕四边形,从0..1开始为绿色/蓝色片段着色。

所以这是我的离屏设置。在屏幕上,我还有另一个真正可见的全屏四元组,包含4个xyz坐标{-1,-1,1 ::: 1,-1,1 ::: 1,1,1 ...... -1,1, 1}。再次,现在这是2D,所以没有矩阵,所以z总是1.

这个四边形是由不同的着色器绘制的,只是渲染给定的纹理,文本书GL-101样式。在我上面链接的示例程序中,我有一个简单的布尔切换doRtt,当这是false(默认)时,render-to-texture完全不会执行,并且此着色器仅显示当前目录中的使用texture.jpg。

这个doRtt = false模式表明第二个屏幕四格渲染器对于我当前的要求是“正确的”,并执行纹理处理,如我所愿:垂直重复两次,水平重复两次(稍后将被钳制,重复仅用于测试),否则使用NO纹理过滤或mipmapping进行缩放。

因此,无论窗口(以及视口)如何调整大小,我们总是会看到一个全屏四边形,其中单个纹理水平重复两次,垂直两次。

现在,在doRtt = true的情况下,第二个着色器仍然可以完成它的工作,但纹理从来没有完全正确缩放 - 或者绘制过,我不确定,因为不幸我们不能只说“嘿gl保存这个FBO到磁盘进行调试“。

RTT着色器执行一些局部渲染(或者可能是完整渲染,再次无法确定屏幕外发生了什么......)特别是当您调整视口的尺寸比默认尺寸小很多时,您会看到纹理重复之间的中断,并且并非从我们非常简单的RTT片段着色器中预期的所有颜色都会显示出来。 (A):512x512纹理创建正确,但没有被我的代码正确映射(但为什么与doRtt = false任何给定的texture.jpg文件使用完全相同的简单纹理四色着色器显示就好?)

(B)或:512x512纹理渲染不正确,rtt碎片着色器根据窗口分辨率改变其输出 - 但为什么?对于x和y,屏幕四边形总是在-1..1处,顶点着色器总是将这个映射到片段坐标0..1,对于这个简单的测试,RTT纹理始终保持在512x512!

请注意,屏幕四方和屏幕四方都不会更改它们的坐标,并且始终为“全屏”(两个维度均为-1..1)。

再次,这应该是如此简单。我究竟在想什么?

规格:OpenGL 4.2(但代码显然不需要任何4.2特性!),Nvidia Quadro 5010M,openSuse 12.1 64bit,Golang Weekly 22-Feb-2012。

+0

如果是引擎收录下来,完全相同的源文件也正在于此:http://dl.dropbox.com/u/2166329/testrtt.go - 与路径texture.jpg了。 – metaleap 2012-03-09 06:19:25

回答

10

首先 - 尝试检查OpenGL错误。在每个OpenGL函数之后调用glGetError()。你也必须为绘图设置正确的视口。在绘制到FBO之前调用glViewport(0,0,512,512)。在绘制屏幕前调用glViewport(0,0,display_width,display_height)。

也没有必要绑定rttFrameTex当您使用FBO渲染它。只有在读取着色器中的纹理时才需要绑定纹理。

+0

这就是所需要的!令人惊讶的是,thx需要一些时间来帮助我解决这个问题 - 我之前做过“观察端口实验”,但没有成功,但现在它立即奏效,再次感谢! 能够有人> = 15的声望upvoteMārtiņš? – metaleap 2012-03-09 08:02:37

+0

@PhilS。 ...我反而提出了你的问题。 – 2012-03-09 08:21:28