opengl es - Using a FrameBufferObject with several Color Texture attachments -
i'm implementing in program gaussian blur effect. job need render first blur information (the 1 on y axis) in specific texture (let's call tex_1) , use same information contained in tex_1 input information second render pass (for x axis) fill other texture (let's call tex_2) containing final gaussian blur result.
a practice should create 2 frame buffers (fbos) texture attached each of them , linked both gl_color_attachment0 (for example). wonder 1 thing:
is possible fill these 2 textures using same fbo ?
so have enable gl_color_attachment0 , gl_color_attachment1 , bind desired texture correct render pass follow :
pseudo code:
framebuffer->bind() { framebuffer->gettexture(gl_color_attachment0)->bind(); //tex_1 { //bind external texture blur //draw code (y axis blur pass) here... //-> write result in texture color_attachement0 (tex_1) } framebuffer->gettexture(gl_color_attachment1)->bind(); //tex_2 { //bind here first texture (tex_1) filled above in first render pass //draw code (x axis blur pass) here... //-> use texture in fs compute final result //within color_attachement1 (tex_2) -> final result } } framebuffer->unbind()
but in mind there problem because need each render pass bind external texture input in fragment shader. consequently, first binding of texture (the color_attachment) lost!
so exist way solve problem using 1 fbo or need use 2 separate fbos ?
i can think of @ least 3 distinct options this. 3rd 1 not work in opengl es, i'll explain anyway because might tempted try otherwise, , supported in desktop opengl.
i'm going use pseudo-code cut down on typing , improve readability.
2 fbos, 1 attachment each
this straightforward approach. use separate fbo each texture. during setup, have:
attach(fbo1, attachment0, tex1) attach(fbo2, attachment0, tex2)
then rendering:
bindfbo(fbo1) render pass 1 bindfbo(fbo2) bindtexture(tex1) render pass 2
1 fbo, 1 attachment
in approach, use 1 fbo, , attach texture want render each time. during setup, create fbo, without attaching yet.
then rendering:
bindfbo(fbo1) attach(fbo1, attachment0, tex1) render pass 1 attach(fbo1, attachment0, tex2) bindtexture(tex1) render pass 2
1 fbo, 2 attachments
this seems had in mind. have 1 fbo, , attach both textures different attachment points of fbo. during setup:
attach(fbo1, attachment0, tex1) attach(fbo1, attachment1, tex2)
then rendering:
bindfbo(fbo1) drawbuffer(attachment0) render pass 1 drawbuffer(attachment1) bindtexture(tex1) render pass 2
this renders tex2
in pass 2 because attached attachment1
, , set draw buffer attachment1
.
the major caveat does not work opengl es. in es 2.0 (without using extensions) it's non-starter because supports single color buffer.
in es 3.0/3.1, there more subtle restriction: not have gldrawbuffer()
call full opengl, gldrawbuffers()
. call try is:
glenum bufs[1] = {gl_color_attachment1}; gldrawbuffers(bufs, 1);
this totally valid in full opengl, produce error in es 3.0/3.1 because violates following constraint spec:
if gl bound draw framebuffer object, ith buffer listed in bufs must color_attachmenti or none.
in other words, way render gl_color_attachment1
have @ least 2 draw buffers. following call valid:
glenum bufs[2] = {gl_none, gl_color_attachment1}; gldrawbuffers(bufs, 2);
but make work, you'll need fragment shader produces 2 outputs, first 1 not used. now, agree approach not appealing opengl es.
conclusion
for opengl es, first 2 approaches above work, , both absolutely fine use. don't think there's strong reason choose 1 on other. recommend first approach, though.
you might think using 1 fbo save resources. keep in mind fbos objects contain state, use little memory. creating additional fbo insignificant.
most people prefer first approach. thinking can configure both fbos during setup, , need glbindframebuffer()
calls switch between them. binding different object considered cheaper modifying existing object, need second approach.
Comments
Post a Comment