[glsl]Using pixel shader with backbuffer
jmasterx

I started with the ex_opengl_pixelshader and added a timer to regulate fps. I'm now trying to get it to use the backbuffer rather than shading a memory bitmap like the example.

I first changed the bitmap for a call to al_get_backbuffer, this, obviously resulted in crazy flicker because of double buffer. So in the render loop I added:

#SelectExpand
1 glUseProgramObjectARB(tinter); 2 loc = glGetUniformLocationARB(tinter, "ratio"); 3 glUniform1fARB(loc, ratio); 4 loc = glGetUniformLocationARB(tinter, "r"); 5 glUniform1fARB(loc, r); 6 loc = glGetUniformLocationARB(tinter, "g"); 7 glUniform1fARB(loc, g); 8 loc = glGetUniformLocationARB(tinter, "b"); 9 glUniform1fARB(loc, b); 10 11 loc = glGetUniformLocationARB(tinter, "backBuffer"); 12 glUniform1iARB(loc, al_get_opengl_texture(al_get_backbuffer(al_get_current_display()))); 13 glUseProgramObjectARB(0); 14 15 al_flip_display();

But this still resulted in massive flicker. What am I doing wrong?

Thanks

Trent Gamblin

Here's a brief lesson on how pixel shaders work. First you want to set the target bitmap (your backbuffer in this case). That does not get passed into the shader (ex_opengl_shader might be wrong, I didn't look at it). The sampler(s) you set are the textures you want to draw to the target. Now what happens is for each destination pixel, your fragment shader function gets called. You use the texture coordinates (gl_TexCoord or pass them as varying's into the fragment shader from the vertex shader) to look up pixels in the texture your drawing. Then you do whatever you want with those pixels/colors and when you're done you set gl_FragColor to the result. You have no control over which pixel gets written, you simply process "whatever" destination pixel you're given (You can "find out" which pixel you're drawing with gl_FragCoord and that is sometimes useful for some algorithms too).

jmasterx

Ah Thanks for the excellent explanation, it really put things into perspective for me :)

Mark Oates

Is it possible to get pixel information about the target bitmap when drawing to it? Or would you have to do something, like, copy the target bitmap to another bitmap and use it along with the image you're drawing?

Aaron Bolyard

You cannot, in a pixel shader, use the same texture for both destination and source (if I understood your question correctly, Mark). This is because of the concurrent nature of pixel shaders. It's similar to threading, in that the source may be different between reads.

Trent Gamblin

I think the question was can you read the destination regardless of its also the source or not. Well Aaron may have hinted at that anyway as the only way it would seem remotely possible is to also pass it in as a sampler, but alas, that does not work.

jmasterx

Is it possible with Allegro to set the fragment shader target to the front buffer because with the backbuffer it does each fragment written to it, but in my case I want to do post processing to the final result as a whole without blitting to an off screen bitmap first.

Thanks

Elias

What is the problem with using an off-screen buffer?

jmasterx

Well there's no need to waste memory and sync during resize if it is not needed.

gnolam

Consult the First Rule of Program Optimization. :P

jmasterx

It's not that I'm trying to do premature optimization, I just thought it was possible to do this. If the proper way is to blit to another buffer first then I will by all means do so :), unless you mean don't use shaders?

Thomas Fjellstrom
gnolam said:

Consult the First Rule of Program Optimization.

Do not talk about Fi^H^HProgram Optimization?

jmasterx said:

Is it possible with Allegro to set the fragment shader target to the front buffer because with the backbuffer it does each fragment written to it, but in my case I want to do post processing to the final result as a whole without blitting to an off screen bitmap first.

The hardware provides accelerated drawing, and accelerated page-flipping. By default every context includes at least 2 pages of vram for tear free drawing.

If you were drawing direct to the front buffer (which isn't always possible iirc), you'd get a crazy amount of tearing.

jmasterx

If you were drawing direct to the front buffer (which isn't always possible iirc), you'd get a crazy amount of tearing.

Oh of course, but I wouldn't be doing that, my goal would be to somehow blit everything to the backbuffer then when the page gets flipped it goes through my shader, but it seems like blitting to a bitmap first, rendering to texture essentially, is the ideal solution.

Trent Gamblin

Yeah, you can't do that AFAIA because though Allegro treats the backbuffer and bitmaps the same, the backbuffer is not a texture, just a dummy "fake" bitmap.

jmasterx

Cool, by rendering into another buffer first, resizing on windows is somehow dynamic and does not stretch!

Thread #607466. Printed from Allegro.cc