SFML community forums

Help => Graphics => Topic started by: AveryBibeau on July 25, 2013, 08:55:08 am

Title: Trouble with multiple shaders/buffers
Post by: AveryBibeau on July 25, 2013, 08:55:08 am
I'm having trouble with using multiple buffers to use multiple shaders. I understand that I render to buffer1, draw it to buffer2, then continue drawing to buffer2, but I'm having trouble with the implementation. This is what I have so far and all it does is render the second light (at (100, 100)).

        void draw( sf::RenderWindow& target )
        {
                lightShader.setParameter("lightpos", sf::Vector2f( 960.f, 640.f ) );

                buffer1.clear( sf::Color::Transparent );
                buffer1.draw( buffer1Sprite, &lightShader );
                buffer1.display();

                lightShader.setParameter("lightpos", sf::Vector2f( 100.f, 100.f ) );

                buffer2.clear( sf::Color::Transparent );
                buffer2.draw( buffer1Sprite );
                buffer2.draw( buffer2Sprite, &lightShader );
                buffer2.display();

                target.draw( buffer2Sprite );
        }
 
Title: Re: Trouble with multiple shaders/buffers
Post by: Laurent on July 25, 2013, 09:05:23 am
Quote
buffer2.draw( buffer2Sprite, &lightShader );
If buffer2Sprite uses buffer2's texture, then you're trying to draw a texture on itself, which is forbidden.

You should remove this line and just have
buffer2.draw( buffer1Sprite, &lightShader  );
Title: Re: Trouble with multiple shaders/buffers
Post by: AveryBibeau on July 26, 2013, 11:02:01 pm
Ah thank you, on top of that, I forgot to use additive rendering for the lights to each buffer, I was only doing it on the final output and my shader didn't have alpha decay. Thanks for the help!
Title: Re: Trouble with multiple shaders/buffers
Post by: kdunee on July 28, 2013, 05:41:26 pm
If buffer2Sprite uses buffer2's texture, then you're trying to draw a texture on itself, which is forbidden.

@Laurent: Is it strictly forbidden? Because I use it quite a lot to save space in postprocessing and didn't have any problems so far. Of course I display() the texture first before I draw it onto itself.

Can it lead to some undefined behavior in the future or on other machines?
Title: Re: Trouble with multiple shaders/buffers
Post by: Nexus on July 28, 2013, 06:18:49 pm
Yes, it's undefined behavior -- not on other hardware or in the future, but everywhere, including your graphics card.

See OpenGL memory model (http://www.opengl.org/wiki/Memory_Model) for more information.
Title: Re: Trouble with multiple shaders/buffers
Post by: kdunee on July 28, 2013, 06:30:32 pm
Thanks for reply and the OpenGL docs. Indeed, they wrote that:

Quote
When performing a rendering operation to images attached to a Framebuffer Object, attempts to access pixels from those images will result in undefined values. Reads from images that are being written to are not coherent.
OpenGL is actually quite strict about this. It states that the value of a texture being accessed is undefined if it is at all theoretically possible for any texture read to access an image that is being written to by the fragment shader. OpenGL is quite conservative about this.

and I cannot help but be amazed, because it worked for me across 3 machines and two OS  ;)

My theory is that, since I always redraw 1:1 in terms of geometry (and use a fragment shader), it coincidentally happens to give correct (at least visually) results.