Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [glsl]Using pixel shader with backbuffer

This thread is locked; no one can reply to it. rss feed Print
[glsl]Using pixel shader with backbuffer
jmasterx
Member #11,410
October 2009

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
Member #261
April 2000
avatar

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
Member #11,410
October 2009

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

Mark Oates
Member #1,146
March 2001
avatar

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
Member #7,537
July 2006
avatar

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
Member #261
April 2000
avatar

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
Member #11,410
October 2009

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
Member #358
May 2000

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

--
"Either help out or stop whining" - Evert

jmasterx
Member #11,410
October 2009

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

gnolam
Member #2,030
March 2002
avatar

Consult the First Rule of Program Optimization. :P

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

jmasterx
Member #11,410
October 2009

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
Member #476
June 2000
avatar

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.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

jmasterx
Member #11,410
October 2009

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
Member #261
April 2000
avatar

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
Member #11,410
October 2009

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

Go to: