2
votes

I am attempting to render to a texture on the iPhone using openGL ES 2.0.

To test, I am rendering a polygon (just a simple circle). The circle is supposed to render fully red (rgba color is (1, 0, 0, 1)) but for some reason, it's resulting color will be the multiplication of it's color with whatever I initialize the render texture as.

For example :

Texture init color :     (1,   1,   1,   1)
Circle color :           (1,   0,   0,   1)
Resulting circle color : (1,   0,   0,   1) //This is as expected

Texture init color :     (0.5, 0.5, 0.5, 1) 
Circle color :           (1,   0,   0,   1) 
Resulting circle color : (0.5, 0,   0,   1) //This is unexpected.  

The background color shouldn't be factored in at all.

If I render the circle with darker red (0.5, 0, 0, 1), the fact that it's multiplying the color rather than adding it is more evident.

Texture init color :     (1,   1,   1,   1)
Circle color :           (0.5, 0,   0,   1)
Resulting circle color : (0.5, 0,   0,   1) //This is as expected

Texture init color :     (0.5,  0.5, 0.5, 1)
Circle color :           (0.5,  0,   0,   1)
Resulting circle color : (0.25, 0,   0,   1) //This is unexpected.  

My intuition is saying this is a problem with the blend mode but the problem persists even if I set the glBlendFunc to (GL_ONE, GL_ZERO).

This could also be due to the fact that the rendering uses premultiplied values but again, I am using very simple values here and full alpha which should ignore this problem but I might be wrong.

Question : Why are the colors multiplying with the background color?


My RenderTexture setup :

glBindTexture(GL_TEXTURE_2D, 0);

glGenFramebuffers(1, &m_frameBuffer);
glGenTextures(1, &m_textureId);

glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);
glBindTexture(GL_TEXTURE_2D, m_textureId);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MathUtil::NextPowerOf2(m_width), MathUtil::NextPowerOf2(m_height), 0, GL_RGBA, GL_UNSIGNED_BYTE, m_data);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textureId, 0);

glViewport(0, 0, m_width, m_height);

When I render an object, I call the following :

glEnable(GL_BLEND);
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO);

glDrawElements(GL_TRIANGLES, (GLsizei)(m_offset / 4) * 6, GL_UNSIGNED_SHORT, (void*)0);

Finally, I read the values from the render texture with glReadPixels (glGetTexImage isn't available for iPhone's openGL ES 2.0 I believe) to confirm these values.

glReadPixels(0, 0, MathUtil::NextPowerOf2(m_width), MathUtil::NextPowerOf2(m_height), GL_RGBA, GL_UNSIGNED_BYTE, m_data);
1
Odd. What happens if you disable blending?Reto Koradi
Disabling blending doesn't change the resulting rgba (altho it changes how it's displayed) After further testing, I've found that the renderToTarget method works if nothing else is rendered to screen. If I render other polys (to the screen, not to the render texture), it causes this behaviour. This would indicate that some other gl call I am using is causing the behaviour. However, I wouldn't even know where to start to get this effect. I'll be isolating code to update the question with these new findingsGodfather

1 Answers

0
votes

After a lot of testing, it was found that the problem occurred because of openGL settings that weren't properly reset between setting the render target from the screen to the texture (and vice versa).

My solution was to refresh all gl bindings and calls (like the shader program) after the target was setup.

Unfortunately, I don't know exactly which call or combination of calls was causing this odd behaviour.