Faking multiple colored light sources in OpenGL ES

by ingvar 3. juli 2010 14:04

I wanted to make a little 2D game for the iPhone. I wanted the game play to be happening at night and for the player to be able to see anything at all I needed to some light into the game world. I wanted multiple light sources and if possible colored light. Also, I wanted to be able to easily switch to dawn or even full day light. I wanted to be able to ‘shape’ the light, like the light cones from a cars headlights and not just light spots. So I came up with the idea of rendering light sprites to a texture that is bound to a off screen frame buffer and then blend this texture onto the 2D rendered world. This method keeps the number of textures to a minimum with a large amount of light ‘sources’ - though they are still fakes.

Here is the two light textures used in this example. The one the left is used for the car and the one on the right is used for the three light spots. I have putted both textures on a blue background because they contain transparent areas. I used OpenGL to scale and change the color of when rederingen the three light spots.

Car head lights Spot""

Here is the rendered 2D world:

2D World

Here is the final rendered light texture:

Final light texture

Here is the final result:

Final combined result

So lets dive into the code. Below is a series of code fragments that shows how to implement the method I have just described.

Here is what you need to do to make the texture that we will render to:

/* Create the texture */
glGenTextures(1, &textureFramebufferTexture);
glBindTexture(GL_TEXTURE_2D, textureFramebufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

/* Create the offscreen framebuffer and bind this to the texture */
glGenFramebuffersOES(1, &textureFramebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFramebuffer);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, textureFramebufferTexture, 0);
glBindTexture(GL_TEXTURE_2D, 0);

/* Now you can render to the textureFramebuffer like any other frame buffer */

This is how to render to that texture frame buffer. It is just like any other frame buffer:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFramebuffer);

/* Do your rendering - standard OpenGL ES */

 

This is how I rendered the light textures:

glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glBlendFunc(GL_ONE, GL_ONE);
/* Make the spot red */
glColor4f(1.0, 0.6, 0.6, 1.0);
glBindTexture(GL_TEXTURE_2D, spotTexture);

glLoadIdentity();
glTranslatef(spotX, spotY, 0.0);
glScalef(2.0, 2.0, 0.0);
glVertexPointer(2, GL_FLOAT, 0, spotVertices);
glNormalPointer(GL_FLOAT, 0, spotNormals);
glTexCoordPointer(2, GL_FLOAT, 0, spotTextureCoords); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

And finally how to render the texture onto the rendered 2D world. It is like rendering any other texture, so no surprises here:

/* Use normal back buffer */
glBindFramebufferOES(GL_FRAMEBUFFER_OES, frameBuffer);
glColor4f(1.0, 1.0, 1.0, 1.0);
glBindTexture(GL_TEXTURE_2D, textureFramebufferTexture);
glBlendFunc(GL_DST_COLOR, GL_ZERO);

/* Render the texture */
glVertexPointer(2, GL_SHORT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

 

Tags: , ,

iPhone

Comments (8) -

blog
blog United States
10-07-2010 22:45:27 #

Hey bro, I have gone through this blog. I found it very interesting and helpful. Just to let you know, the blog is kinda slow to load.

ingvar
ingvar Denmark
11-07-2010 08:56:29 #

Hey bro, I have gone through this blog. I found it very interesting and helpful. Just to let you know, the blog is kinda slow to load.

Thx man! Yea, its where I get my website hostet. If the site haven't had any visitors for some time, its really slow at first visit.

Gaz Pieprzowy
Gaz Pieprzowy United Kingdom
03-01-2011 14:38:17 #

That "pet project" for the iPhone looks quite nice Smile

- Gaz

ingvar
ingvar United States
03-01-2011 17:35:43 #

@Gaz, thx Smile The project kinda died when i got the this multible colored lights working. Hope i get the time and the motivation to use it for some small fun game in the future Smile

iphone development company
iphone development company United States
12-05-2011 16:02:06 #

Hi, Ingvar, I just have one question... Why have you picked to develop 2d game? 3d is harder to develop, of course, but it will be more popular.

image consultant Sydney
image consultant Sydney United States
01-07-2011 03:38:08 #

Nice article as for me. It would be great to read something more concerning this theme. The only thing it would also be great to see on this blog is some pics of some gadgets.

John
John United States
14-07-2011 17:34:25 #

Great!!!!

Bedford flower
Bedford flower United States
10-08-2011 09:19:20 #

I’d have to check with you here. Which is not something I usually do! I enjoy reading a post that will make people think. Also, thanks for allowing me to comment! thank you!
http://halifax-florist.com/ offer beautiful fresh floral designs in traditional or contemporary styles. . They have a beautiful and varied collection of flowers that are certain to delight. They provide excellent service from the local flower experts.

About the author

Martin Ingvar Kofoed Jensen

Architect and Senior Developer at Composite on the open source project Composite C1 - C#/4.0, LINQ, Azure, Parallel and much more!

Follow me on Twitter

Read more about me here.

Read press and buzz about my work and me here.

Stack Overflow

Month List