2D Dynamic Lighting in OpenGL! Sort of...

Member
Posts: 110
Joined: 2009.07
Post: #16
BTW:

I've just implemented this for the iPhone.
However, there is a major pitfall to avoid.

If you read any guides to coding openGL for the iPhone they state that in order to maximise performance you should set the eaglLayer properties thus:

Code:
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGB565, kEAGLDrawablePropertyColorFormat, nil];

Note the setting of the colour format to RGB565.
If you do this, it causes any render-to-texture operation to come out as black on the iPhone only. On the simulator it's fine. I'd have attributed this to the loss of alpha, but... then why does it work on the simulator? And further, why do none of the blend modes produce anything on screen?

My code all works fine if I use kEAGLColorFormatRGBA8. This is not acceptable, and slows down my app disproportionately.

Someone smarter than me will no doubt tell me why this black texture problem only happens on the iPhone, but I feel that - as I've just wasted 2 days tracking down a 'why does this work in the sim but not on hardware' problem - someone else may be saved some trouble by coming here.

I would be interested to know if anyone has had any luck using RGB565 and rendering to texture - at the moment, the performance hit is such that it is actually quicker to split my sprites into multiple polys and hand-light, using 'distance from lamp' equations.

http://www.fluttermind.com
Fluttermind - Games for Everyone
Quote this message in a reply
Sage
Posts: 1,234
Joined: 2002.10
Post: #17
Madrayken Wrote:Note the setting of the colour format to RGB565.
If you do this, it causes any render-to-texture operation to come out as black
Certainly not. The format of the texture being rendered to is orthogonal to the format of the system framebuffer. If you use CopyTexImage to copy from framebuffer to texture, you'd get only color and no alpha channel. But you should never use CopyTexImage, you should render directly using an FBO.

Quote:I'd have attributed this to the loss of alpha, but... then why does it work on the simulator? And further, why do none of the blend modes produce anything on screen?

The simulator stores everything with 8 bits per channel. It doesn't really support 565. You can introspect this with glGetInteger(GL_RED_BITS...) etc.

You should look at your blend modes and the order of operations to see if you are depending on destination alpha, which won't work with 565. If you did exactly what metacollin described, it should still work, since he doesn't depend on destination alpha, only source alpha when drawing the initial lights.
Quote this message in a reply
Member
Posts: 110
Joined: 2009.07
Post: #18
arekkusu Wrote:Certainly not. The format of the texture being rendered to is orthogonal to the format of the system framebuffer. If you use CopyTexImage to copy from framebuffer to texture, you'd get only color and no alpha channel. But you should never use CopyTexImage, you should render directly using an FBO..

I'm having a go at frame buffers at the moment. They've proven a little tricky.

arekkusu Wrote:The simulator stores everything with 8 bits per channel. It doesn't really support 565. You can introspect this with glGetInteger(GL_RED_BITS...) etc.

Ah, so I should expect to find this sort of thing on a regular basis. Ouch.

arekkusu Wrote:You should look at your blend modes and the order of operations to see if you are depending on destination alpha, which won't work with 565. If you did exactly what metacollin described, it should still work, since he doesn't depend on destination alpha, only source alpha when drawing the initial lights.

Interesting. So, given a texture (copied from the screen and now in 565 format):

Code:
glBlendFunc(GL_DST_COLOR, GL_ZERO);

...should provide the intended, blended result? As I say, it doesn't. I'm not sure what I'm missing.

When I drew my original lights, I used:
Code:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
I tried using metacolin's suggested:
Code:
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
but my lightmap remained resolutely at the original cleared texture colour.

FYI: my render order was:

Set up a 128 by 128 view.
Clear it to my ambient colour.
Draw multiple lightmaps (white circles alpha-ing out toward the edges) to it using:
Code:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Bind to my render texture, then copy the current frame to the lightmap texture:
Code:
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, tx_w, tx_h);

Now I have my lightmap (or more of a shadow mask, really) in memory, in 565 format.

Set the view to 320 by 480 view.
Clear it (just to ensure the depth buffer's clear, really).
Draw sprites using:
Code:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

Finally, draw the lightmap texture over the screen with:
Code:
glBlendFunc(GL_DST_COLOR, GL_ZERO);

As I say, it all works in the simulator. As far as I can make out, that's the correct order of operations, too, with the appropriate blend settings throughout.

I presume the only way forward is to render to a frame buffer. Metacolin desribes his travails with the copy functions, indicating that he didn't use them, but there's decent enough docs on framebuffers for me to have another hack.

http://www.fluttermind.com
Fluttermind - Games for Everyone
Quote this message in a reply
Sage
Posts: 1,234
Joined: 2002.10
Post: #19
Madrayken Wrote:I'm having a go at frame buffers at the moment. They've proven a little tricky.
Why so? Everything on the iPhone is rendering to an FBO all the time, this is a fundamental concept that everyone should understand. If the workings aren't clear from the GLES template, what would make it easier to understand?

Quote:Ah, so I should expect to find this sort of thing on a regular basis. Ouch.
You should test your application on the actual device on a regular basis.

Quote:When I drew my original lights, I used:
Code:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
OK, stop right there. Is this step correct? How do you know?
You should verify this produced your expected results, i.e. glReadPixels to check the RGBA value.

For example if you faded out your lights with an ALPHA texture, this step depends on the TexEnv you used. The default MODULATE TexEnv will not produce a usable result in the destination RGB, for the subsequent operations metacolin described. If you don't understand why, you should read the spec to learn how TexEnv works.
Quote this message in a reply
Member
Posts: 110
Joined: 2009.07
Post: #20
arekkusu Wrote:Why so? Everything on the iPhone is rendering to an FBO all the time, this is a fundamental concept that everyone should understand. If the workings aren't clear from the GLES template, what would make it easier to understand?

I don't mean that they're a tricky concept, but that my attempts to draw to a FBO apart from the primary one attached to the context seemed to result in a spurious purple polygon. Work and more reading is needed, that is all.

arekkusu Wrote:You should test your application on the actual device on a regular basis.

I do. Constantly. Hence my original post pointing out the issue. I am still new enough to be surprised by discrepancies.

arekkusu Wrote:OK, stop right there. Is this step correct? How do you know?
You should verify this produced your expected results, i.e. glReadPixels to check the RGBA value.

That's a really good idea - not something I've considered before. I tend to think of openGL as a black box unit less than keen to reveal its inner workings.
arekkusu Wrote:For example if you faded out your lights with an ALPHA texture, this step depends on the TexEnv you used. The default MODULATE TexEnv will not produce a usable result in the destination RGB, for the subsequent operations metacolin described. If you don't understand why, you should read the spec to learn how TexEnv works.

In my specific case, I merely used a .png texture with a pre-multiplied alpha component. So far I've not used glTexEnv at all - it's not turned up in any of the tutorials on NeHe, nor any of the other sources I've come across as I've been learning. Thanks for the heads up - that might be the one vital missing step.

http://www.fluttermind.com
Fluttermind - Games for Everyone
Quote this message in a reply
Sage
Posts: 1,234
Joined: 2002.10
Post: #21
Madrayken Wrote:I tend to think of openGL as a black box unit less than keen to reveal its inner workings.
This is not the case. The inner workings are described in extensive detail. And you can inspect practically everything, at any point.

Quote:So far I've not used glTexEnv at all - it's not turned up in any of the tutorials on NeHe
It's covered briefly in NeHe article #20, for bump mapping. On the desktop, TexEnv has been superseded by shaders, so recent tutorials won't mention it. But it's pretty crucial to getting anything interesting done on the MBX-based iPhones.

There are also various examples of real-world TexEnv usage in older idevgames threads.
Quote this message in a reply
Member
Posts: 110
Joined: 2009.07
Post: #22
arekkusu Wrote:This is not the case. The inner workings are described in extensive detail. And you can inspect practically everything, at any point.


It's covered briefly in NeHe article #20, for bump mapping. On the desktop, TexEnv has been superseded by shaders, so recent tutorials won't mention it. But it's pretty crucial to getting anything interesting done on the MBX-based iPhones.

There are also various examples of real-world TexEnv usage in older idevgames threads.

Thank you so much. Your help has been invaluable. You've given me much to think about, and to learn.

http://www.fluttermind.com
Fluttermind - Games for Everyone
Quote this message in a reply
Member
Posts: 110
Joined: 2009.07
Post: #23
As an epilogue, this thread led me to debugging my frame buffer object properly. A stupid mistake (somehow I forgot to get ogl to initialise the textures for the framebuffer) on my part proved to be the issue, and I now have light maps working perfectly, and - more importantly - at a good framerate.

Thanks again, arekkusu. I can now spend the remainder of my day reading around the subject rather than batting my head against a wall.

http://www.fluttermind.com
Fluttermind - Games for Everyone
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  OpenGL ES : Dynamic calculation of triangle indices akademiks 0 4,290 Sep 13, 2011 07:58 AM
Last Post: akademiks
  Lighting and changing texture colors in OpenGL agreendev 2 7,951 Aug 13, 2010 03:47 PM
Last Post: agreendev
  Lighting a sphere with OpenGL lights (normals wrong?) cecilkorik 3 8,309 Dec 27, 2007 02:40 PM
Last Post: _ibd_
  2d opengl lighting question Leroy 9 7,123 Jul 21, 2007 11:41 PM
Last Post: OneSadCookie
  GLSL now in 10.4 sort of.... Mars_999 34 15,276 May 24, 2005 12:26 AM
Last Post: Bachus