met*_*eap 7 opengl framebuffer off-screen go render-to-texture
离屏渲染到纹理绑定的屏幕外帧缓冲对象应该是如此微不足道,但我遇到了一个问题,我无法绕过头脑.
我的完整示例程序(目前只有2D!)在这里:
请参阅下面的一些说明.
我正在创建一个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时,也不需要绑定它.只有在着色器中读取纹理时才需要绑定纹理.