OpenGL通过FBO渲染到纹理—错误的显示与正常的纹理

off-screen rendering to a texture-bound offscreen framebuffer object should be so trivial but I'm having a problem I cannot wrap my head around.

My full sample program (2D only for now!) is here:

http://pastebin.com/hSvXzhJT

See below for some descriptions.

I'm creating an rgba texture object 512x512, bind it to an FBO. No depth or other render buffers are needed at this point, strictly 2D.

The following extremely simple shaders render to this texture:

Vertex shader:

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

In aPos this just gets a VBO containing 4 xy coords for a quad (-1, -1 :: 1, -1 :: 1, 1 :: -1, 1)

So although the framebuffer resolution should theoretically by 512x512 obviously the shader renders its "texture" onto a "full-(off)screen quad", following GLs -1..1 coords paradigm.

Fragment shader:

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

So it sets a fully opaque color with red fixed at 0.25 and green/blue depending on x/y anywhere between 0 and 1.

At this point my assumption is that a 512x512 texture is rendered showing only the -1..1 full-(off)screen quad, fragment-shaded for green/blue from 0..1.

So this is my off-screen setup. On-screen, I have another real visible full-screen quad with 4 xyz coords { -1, -1, 1 ::: 1, -1, 1 ::: 1, 1, 1 ::: -1, 1, 1 }. Again, for now this is 2D so no matrices and so z is always 1.

This quad is drawn by a different shader, simply rendering a given texture, text-book GL-101 style. In my sample program linked above I have a simple boolean toggle doRtt, when this is false (the default), render-to-texture is not performed at all and this shader simply shows uses texture.jpg from the current directory.

This doRtt=false mode shows that the second on-screen quad-renderer is "correct" for my current requirements and performs the texturing as I want it to: repeated twice vertically and twice horizontally (later will be clamped, repeat is just for testing here), otherwise scaling with NO texture filtering or mipmapping.

So no matter how the window (and thus view port) is resized, we always see a full-screen quad with a single texture repeated twice horizontally, twice vertically.

Now, with doRtt=true, the second shader still does its job but the texture is never fully correctly scaled -- or drawn, this I'm not sure since unfortunately we can't just say "hey gl save this FBO to disk for debugging purposes".

The RTT shader DOES perform some partial rendering (or maybe a full one, again can't be sure what's happening off-screen...) Especially when you resize the viewport a lot smaller than the default size you see the breaks between the texture repeats, and not all colors to be expected from our very simple RTT fragment shader are indeed shown.

(A) either: the 512x512 texture is created correctly but not mapped correctly by my code (but then why is with doRtt=false any given texture.jpg file using the exact same simple textured-quad-shader showing just fine?)

(B) or: the 512x512 texture is not rendered correctly and somehow the rtt frag shader changes its output depending on the window resolution -- but why? The off-screen quad is always at -1..1 for x and y, the vertex shader always maps this to fragment coords 0..1, the RTT texture always stays at 512x512 for this simple test!

Note, BOTH the off-screen quad AND the on-screen quad never change their coords and are always "full-screen" (-1..1 in both dimensions).

Again, this should be so simple. What on earth am I missing?

Specs: OpenGL 4.2 (but the code doesn't need any 4.2 features obviously!), Nvidia Quadro 5010M, openSuse 12.1 64bit, Golang Weekly 22-Feb-2012.

douren0558
douren0558 万一Pastebin掉线了,也可以在这里找到完全相同的源文件:dl.dropbox.com/u/2166329/testrtt.go-路径中也带有texture.jpg。
8 年多之前 回复

1个回答



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

此外,使用FBO渲染rttFrameTex时也无需绑定它。 仅当您在着色器中读取纹理时,才需要绑定纹理。</ p>
</ div>

展开原文

原文

First of all - try checking OpenGL errors. Call glGetError() after each OpenGL function. Also you must set correct viewport for drawing. Before drawing to FBO call glViewport(0, 0, 512, 512). Before drawing to screen call glViewport(0, 0, display_width, display_height).

Also there is no need to bind rttFrameTex when you are rendering to it using FBO. Binding texture is needed only when you are reading texture in shader.

dongta1824
dongta1824 ...我改为支持您的问题。
8 年多之前 回复
duanbo7517
duanbo7517 这就是所有需要的! 太神奇了,感谢您抽出一些时间来帮助我完成此工作-之前我没有进行“使用视口的实验”,但无济于事,但是现在它可以立即工作,再次感谢! 声誉> = 15的人可以支持MÄrtiņš
8 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问