3

My app draws a mixture of point sprites and standard quad textures. Until recently, I was using a single shader program for this - however a branch in the fragment shader (to decide whether to use point sprite coords/colors) was seriously throttling the performance of my rendering. My fragment shader originally looked like this:

precision highp float;

uniform sampler2D u_textureSprite;
uniform bool u_isSprite;

varying vec4 v_color;
varying vec2 v_textureCoord;

void main()
{    
    vec4 textureColor = texture2D(u_textureSprite, u_isSprite ? gl_PointCoord : v_textureCoord);  
    if (u_isSprite) {
        gl_FragColor = v_color * textureColor;
    }
    else {
        gl_FragColor = textureColor;
    }
}

Reading Apple's recommendations in the OpenGL ES Programming guide makes it sound like an easy job to use multiple shader programs... just create another one as normal and call glUseProgram() before the relevant draw code. However, since doing this I cannot get the texture rendering to work. The two new fragment shaders are:

pointSprite.fsh:

precision highp float;

uniform sampler2D s_textureSprite;

varying vec4 v_color;

void main()
{    
    vec4 textureColor = texture2D(s_textureSprite, gl_PointCoord);
    gl_FragColor = v_color * textureColor;
}

texture.fsh:

precision highp float;

uniform sampler2D s_texture;


varying vec2 v_textureCoord;

void main()

{    
    gl_FragColor = texture2D(s_texture, v_textureCoord);
}

Pretty trivial, I think. If I ignore all calls to draw the texture, I can see that point sprites are being rendered just fine. Texture quads, however, just render to a solid grey color - incidentally this grey color does not match any of the glClearColor() colors, I believe it is a color from some point of the texture that it is trying to render.

A little sample code for a texture render is as follows:

- (void)drawTexture:(GLuint)texture {
    glUseProgram(programs[PROGRAM_TEXTURE]);


    glBindTexture(GL_TEXTURE_2D, texture);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjects[VBO_TEXTURE_VERTICES]);

    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(ISTextureData), (void*)offsetof(ISTextureData, vertex));
    glEnableVertexAttribArray(ATTRIB_VERTEX);
    glVertexAttribPointer(ATTRIB_TEXTURE_COORD, 2, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ISTextureData), (void*)offsetof(ISTextureData, textureCoord));
    glEnableVertexAttribArray(ATTRIB_TEXTURE_COORD);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexBufferObjects[VBO_TEXTURE_INDICIES]);
    glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
}

This code works when not dealing with multiple shaders. Or am I being careless, and the texture fragment shader code is wrong?

Thanks

EDIT:

Well it's been a number of long and painful hours, and what's really irritating is that it's somehow not a code issue, but something to do with the name of the project directory.

My Xcode project directory is named as such: "ProjectName (current)". This is the project I was having trouble with. I have since discovered that changing this folder name to anything different makes the app work, and properly render the background texture. Just to clarify - the app previously worked normally with the exception of the rendering of a background texture in OpenGL, and after renaming the project folder everything works fine.

Any ideas why this might be?

Stuart
  • 36,683
  • 19
  • 101
  • 139

2 Answers2

2

Where do you set up the texture uniform for your shaders? You need to assign the number of the appropriate texture unit to use for the texture uniform, using code like the following:

glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, sphereDepthMappingTexture);
glUniform1i(sphereDepthPrecalculatedDepthTextureUniform, 2);

The second argument in glUniform1i() here is the number of the texture unit to pull the texture from.

By default, this uniform would be 0, corresponding to GL_TEXTURE0, which is why it might have worked in the first place, but if you switched the active texture unit to something else you no longer would be able to read the texture in your shader.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • @Brad Hi, thanks for the assistance. It's interesting you should mention that, as I did previously have code similar to that after trawling through some programming guides, however I removed it because I had obviously set it up wrong and it had no effect. I have edited my question with some more details about this. – Stuart Apr 21 '11 at 17:29
  • 1
    @StuDev - In response to your update: the texture unit used for your texture is what you specify in `glActiveTexture()`, if you then use `glBindTexture()` to bind it to that unit. In your case above, 0 is the correct value, just as 2 is the correct one in my example. Your uniform identifier is just used by `glUniform1i()` to address the correct uniform, and is independent of the texture unit value. – Brad Larson Apr 21 '11 at 17:58
  • @Brad: I see, so it would appear the problem lies elsewhere. I have also noticed that I have called `glBindAttribLocation()` for my `ATTRIB_VERTEX` twice; once for each program. Is this the correct thing to do? I have tried tweaking with no joy... (sorry about this - I've not had much luck finding examples of multiple shaders in ES2.0 so far!). – Stuart Apr 21 '11 at 18:08
  • 1
    @StuDev - Unfortunately, I don't think that either of the sample applications I have [here](http://www.sunsetlakesoftware.com/sites/default/files/ColorTracking.zip) and [here](http://www.sunsetlakesoftware.com/sites/default/files/ShaderExamples.zip) use multiple shaders for rendering to one scene at a given time, although they do use textures, so you could check against that. The next version of Molecules does, and I will be releasing the source to that, but the application isn't quite ready yet. I've not had any problems with multiple shaders that I didn't have with individual ones. – Brad Larson Apr 21 '11 at 18:32
  • @Brad: I think I'm making some progress here. I skipped back to a working project before I changed to two shaders and have been gradually retracing my steps. It's looking good so far... I'd just like to pin down the silly mistake that broke my code the first time around! I'll post back here when I've found it. – Stuart Apr 21 '11 at 18:39
  • @Brad: Incidentally, thanks for the links. I have read through one of your articles about optimising Molecules, [Lessons from Molecules: OpenGL ES](http://www.sunsetlakesoftware.com/2008/08/05/lessons-molecules-opengl-es) (hope you don't mind the plug!). I found it really useful, thanks - it was that article that convinced me that pursuing the VBO approach was worth it, and the code really aided my understanding of them. Keep it up! :) – Stuart Apr 21 '11 at 18:42
  • @StuDev - If you're interested in more information, videos from my class are up on iTunes U: http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=407243028 , including a recent course on OpenGL ES 2.0. I also have a few more geometry tuning tips in this recent answer: http://stackoverflow.com/questions/5718846/how-can-i-optimize-the-rendering-of-a-large-model-in-opengl-es-1-1/5721102#5721102 – Brad Larson Apr 21 '11 at 20:44
  • @Brad: That's excellent, I'm downloading the series now. Sounds like some useful topics in there - that one on multithreading might actually get me started on that topic finally! I think I might be getting to grips with ideas of OpenGL performance enhancement now - Apple's "Best Practices for Working with Vertex/Texture Data" is handy, as well as the new OpenGL analysis tools that came with Xcode 4. Pretty much the last thing on the list for my app now is VAOs. Thanks again for the help. – Stuart Apr 21 '11 at 22:11
0

This, strangely, turned out to be somehow related to the name of the project directory. My Xcode project directory was named as such: "ProjectName (current)". This is the project I was having trouble with. Changing this folder name to anything different made the app work, and properly render the background texture. Very strange.

Stuart
  • 36,683
  • 19
  • 101
  • 139