OpenGL渲染到纹理 - 通过FBO - 与正常纹理不正确显示

met*_*eap 7 opengl framebuffer off-screen go render-to-texture

离屏渲染到纹理绑定的屏幕外帧缓冲对象应该是如此微不足道,但我遇到了一个问题,我无法绕过头脑.

我的完整示例程序(目前只有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);
}
Run Code Online (Sandbox Code Playgroud)

在aPos中,这只是一个包含4 xy坐标的VBO,用于四边形(-1,-1 :: 1,-1 :: 1,1:-1,1)

因此,虽然帧缓冲分辨率理论上应该是512x512,但着色器将其"纹理"渲染到"全(关)屏幕四边形"上,遵循GLs -1..1 coords范例.

片段着色器:

varying vec2 vPos;
void main (void) {
    gl_FragColor = vec4(0.25, vPos, 1);
}
Run Code Online (Sandbox Code Playgroud)

所以它设置了一个完全不透明的颜色,红色固定为0.25,绿色/蓝色取决于x/y,介于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,当这是假(默认)时,根本不执行渲染到纹理,这个着色器只显示使用当前目录中的texture.jpg.

这个doRtt = false模式显示第二个屏幕四重渲染器对于我当前的要求是"正确的"并按照我的要求执行纹理化:垂直重复两次和水平重复两次(稍后将被钳制,重复仅用于测试这里),否则使用NO纹理过滤或mipmapping进行缩放.

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

现在,使用doRtt = true,第二个着色器仍然可以完成它的工作,但纹理永远不会完全正确缩放 - 或绘制,我不确定,因为不幸的是我们不能只说"嘿gl将此FBO保存到磁盘调试目的".

RTT着色器执行一些部分渲染(或者可能是一个完整的渲染,再次无法确定屏幕外发生了什么......)特别是当您调整视口大小比默认大小小很多时,您会看到纹理之间的间隔重复,并非确实显示了我们非常简单的RTT片段着色器所期望的所有颜色.

(A)要么:512x512纹理是正确创建的,但我的代码没有正确映射(但是为什么doRtt = false任何给定的texture.jpg文件使用完全相同的简单纹理四边形着色器显示得很好?)

(B)或:512x512纹理没有正确渲染,不知何故rtt frag着色器根据窗口分辨率改变其输出 - 但为什么呢?对于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.

Mār*_*iko 11

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

当您使用FBO渲染rttFrameTex时,也不需要绑定它.只有在着色器中读取纹理时才需要绑定纹理.