Simple Shader question

Started by
12 comments, last by _the_phantom_ 17 years, 10 months ago
First of all big thanx Kalindor, really big, I mean it :)

You asked me what exactly I am trying to do. Well forget about the above shaders , they where just simple examples I was trying to do , because I'm a complete noob in OpenGL/GLSL.Here's the real thing:


OK, this is gonna be long :P I'm working on a 3DStereoComputerVision on GPU Project which forced me at some point to get involved with shaders.I won't go into much detail about the Project itself, but to cut a long story short I need at some point to make a shader program which works on 3 textures. I need to read 2 given textures (A and B), make some color comparisons and depending on the result I need to (each texture has it's own texture unit):

1) modify one of the above textures(Texture A)
2) write some other data on the third texture(Texture C)

I've read some stuff about Offscreen buffers and attaching textures to them and this seems the way to go. However:

1) How can I have a Texture (Texture A in my case...) for both read and write within the same fragment shader in GLSL?
2) How does the fragment shader render to the offscreen buffers rather than the color buffer?
3) Is it possible to render with a single shader in multiple buffers? I would like to have both texture A and C modified by the same shader , rather than write two shaders , one for each texture.
4) What is the performance cost of compiling linking loading etc shaders? In my application I'm gonna have a loop and in each loop I need fixed-functionality as well as the above shader program, so I probably have to load and unload the program many times.

These are some of my basic questions... At some point I may send some code too but at the moment it's trivial because nothing really works:|

[Edited by - Gorgi on May 25, 2006 9:35:06 AM]
Advertisement
Quote:Original post by Gorgi
First of all big thanx Kalindor, really big, I mean it :)
...
You're welcome. And there's no N in my username. [grin] It doesn't bother me at all so it's no big deal, I just figured I'd correct you.
Quote:Original post by Gorgi
...
I'm working on a 3DStereoComputerVision on GPU Project which forced me at some point to get involved with shaders.
...
Sounds pretty interesting. Do you have a website or something where I can read more about it?
Quote:Original post by Gorgi
...
1) How can I have a Texture (Texture A in my case...) for both read and write within the same fragment shader in GLSL?
2) How does the fragment shader render to the offscreen buffers rather than the color buffer?
3) Is it possible to render with a single shader in multiple buffers? I would like to have both texture A and C modified by the same shader , rather than write two shaders , one for each texture.
4) What is the performance cost of compiling linking loading etc shaders? In my application I'm gonna have a loop and in each loop I need fixed-functionality as well as the above shader program, so I probably have to load and unload the program many times.
...
1) Unfortunately the answer to that is "You can't." You're going to have to "ping-pong" between textures. So you'll have another texture as a render target and output Texture A and its changes to that new texture. Then use the new texture for subsequent uses of Texture A, possibly rendering anymore changes you need to do back into the original Texture A. You keep going back and forth like that for any number of passes you need to do, hence the "ping-ponging" effect between the two textures.

2) If using GL_EXT_framebuffer_object (which I highly recommend) you do this by binding the FBO you want to render to and calling glDrawBuffer/glDrawBuffers (see next answer) with the proper attachment point(s). All the information you need can be found in the specs for it. It may be too much information however (it's a LOT of information), so you can get more help by searching these forums or asking questions of your own if you can't find the answers.

3) This is possible with the GL_ARB_draw_buffers extension. This adds the glDrawBuffers function (it's a core part of OpenGL 2.0 so you can drop the ARB at the end now) which allows you to set up to GL_MAX_DRAW_BUFFERS buffers into which to render. To render different data to different buffers you will need to write a fragment shader which outputs to gl_FragData[]. Keep in mind you can't write to both gl_FragColor and gl_FragData[] in a single shader; it's either one or the other. You can find more information about writing to gl_FragData[] in the GLSL specs (pdf).

4) You definitely don't want to be compiling and linking the shaders every time you want to use them. Do all that setup just once and then only bind the shaders when you need them. Binding shaders is the most expensive state change there is. If it's at all possible you should bind them once, do all the rendering that needs those shaders, then unbind and do all the fixed-function rendering. If you can't do it as clear cut as that, try to batch them together as much as possible so that you can minimize the amount of shader binding as much as possible.

EDIT: Added the pdf warning.
Once again I have a question guys :)


In my shaders I'd like to use both FragData[0] and FragData[1], NOT FragColor.

In a typical example to render to an FBO :

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, texNames[1], 0);

Do I have to change the "GL_COLOR_ATTACHMENT0_EXT" with something else in order to use FragData rather than FragColor?
GL_COLOR_ATTACHMENT0_EXT maps to the glFragColor and glFragData[0], to use glFragColor[1] => glFragColor[n] you have to use colour attachments GL_COLOR_ATTACHMENT1_EXT to GL_COLOR_ATTACHMENTn_EXT (where n < the max render buffers your hardware supports).

You have to tell OpenGL which colour buffers are bound for writing however via the glDrawBuffers() function.

This topic is closed to new replies.

Advertisement