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.

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.

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.

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.

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.

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.