Jump to content
  • Advertisement
Sign in to follow this  
TravisGesslein

OpenGL Combining two blending functions

This topic is 2689 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello.

I have a Sprite class which renders parts of its texture invisible using ordinary blending:


(Note, this is Java, using LWJGL, that's why a GL11 is in front of everything)

GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);


(I'm manually setting the alpha of certain pixels in the texture to 1.0)

However, I'd now like to combine this blending by also somehow factoring in the alpha values which are already stored in the color buffer.

To be more precise, I'm rendering an invisible light into the RGBA buffer only using alpha values. It starts out with a vertex in the middle of the light with full light intensity as its alpha value and draws the points around it in a triangle fan with 0 alpha. This way, OpenGL interpolates the alpha values for me, creating a smooth decrease in light intensity from the middle of the light to its edge.


GL11.glBegin(GL11.GL_TRIANGLE_FAN);
GL11.glColor4f(0.0f,0.0f,0.0f, m_intensity);
GL11.glVertex3f(m_position.x, m_position.y, m_depth);

GL11.glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
for(int i=0;i<m_vertices.size();++i)
{
Vector2f pos = m_vertices.get(i);
GL11.glVertex3f(m_position.x + pos.x,m_position.y + pos.y,m_depth);
}

GL11.glEnd();


Now, my lights are drawn before everything else on the screen. I basically fill the buffer with alpha values, then render everything else on top of it using this kind of blending:


GL11.glBlendFunc(GL11.GL_DST_ALPHA,GL11.GL_ONE);


This also works fine and everything that is drawn where the light would be is brightened according to its distance to the center of the light... however, this way of blending geometry and the way my sprites are rendered now conflict.

I can only choose either one of those two, but I'd like to do both at the same time. Is there a way to combine blending functions together? I guess it would be possible too just render the sprites quad twice, once using ordinary blending to mask out certain parts of the texture, and after that again using DST_ALPHA blending to add the light intensities to the color. But this sounds really painful, especially since draw calls using glBegin and glEnd to the graphics card are limited (as far as I know even top notch modern cards can't handle more than a couple of thousand per frame at 60fps due to all the overhead).

This would really help me out a lot, thank you :)

Share this post


Link to post
Share on other sites
Advertisement
Ideas that may work (w/o having proven them):

* Render the mask in a 1st pass into the stencil buffer. In he 2nd pass use the stencil buffer for masking and the alpha channel for light blending. Besides the effort of 2 passes, this method doesn't work with "soft masking".

* [s]Render the light into a texture instead of into the frame buffer. Then use texture combiners for blending with the lighting, and standard blending for the masking. Texture combiners are in the core from version 1.3 to 3.0 inclusively; below 1.3 they may be available by extension, and above 3.0 they are deprecated. This method requires only 1 pass.[/s] EDIT: Nonsense; this suffers form the different texture co-ordinate sets.

* Render the light into a texture instead of into the frame buffer. Then use GLSL to write a fragment shader that does the light blending. You can the use standard blending and/or fragment discarding for the masking. This method only requires only 1 pass, is valid for newer OpenGL versions, and is most flexible.

Share this post


Link to post
Share on other sites

Ideas that may work (w/o having proven them):

* Render the mask in a 1st pass into the stencil buffer. In he 2nd pass use the stencil buffer for masking and the alpha channel for light blending. Besides the effort of 2 passes, this method doesn't work with "soft masking".

* [s]Render the light into a texture instead of into the frame buffer. Then use texture combiners for blending with the lighting, and standard blending for the masking. Texture combiners are in the core from version 1.3 to 3.0 inclusively; below 1.3 they may be available by extension, and above 3.0 they are deprecated. This method requires only 1 pass.[/s] EDIT: Nonsense; this suffers form the different texture co-ordinate sets.

* Render the light into a texture instead of into the frame buffer. Then use GLSL to write a fragment shader that does the light blending. You can the use standard blending and/or fragment discarding for the masking. This method only requires only 1 pass, is valid for newer OpenGL versions, and is most flexible.



Thanks! I'm rendering to texture now (didn't think it would be that simple). Thanks for the advice!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!