Saturday, March 12, 2011

Open GLES 2.0 - Dumb Shit To Check List

Below is a series of things that you need to check when creating applications for OpenGLES 2.0. These are the things that may cause lots of pain but might not necessarily cause the program to crash, instead just giving "weird" results. This is what I found when developing for OpenGLES 2.0 on Xperia X10i with the Android NDK(r4):
  1. If you declare an attribute in the vertex shader, but don't use it, it can be optimized out. Which means that if you try to bind a variable to it, it won't be available to bind to.
    In Vertex Shader:
    attribute vec4 myattr; // no further references

    In code:
    int myattrHandle = glGetAttribLocation(shaderProgramID, "myattr");
    // myattrHandle == -1;

    // which means that later on if you try this, you're gonna generate an error
    glVertexAttribPointer(myattrHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) someArrayOfMyAttr);
    This can be frustrating if you're just checking that you're getting your values in to the shader whilst you're creating your shaders.
  2. The unwanted rainbow effect. Make sure your array sizes are spot on. For example, you declare this:
    float colors[] = new float[12];
    float vertex[] = new float[16];
    float indices[] = {1,2,3,2,3,4};
    // ...populate colors and vertex and indices....
    // ...call your glVertexAttribPointer() to add colors and vertex. Even though there aren't enough colors per vertex, THIS MAY SUCCEED WITHOUT CRASHING

    // make the call to glDrawElements()
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT,
    (const GLvoid*) &indices[0]);
    Now what happens is, you don't have enough colours in your color array for each vertex, so OpenGL just uses whatever it finds in memory at the place where the colours SHOULD be and uses that. Naturally this is entirely random and you usually end up with a "rainbow" effect, and it's different each time you run your app. Sometimes your app will crash anyway, but not always, presumably when another program tries to use that memory.
  3. If you are declaring your shaders like this:
    static const char* vertexShader = " \
    attribute vec4 colour; \
    attribute vec4 vertex; \";
    then you can't put comments in the shader with //. I'm not sure why, this may be something to do with C++, or the NDK, or GLSL itself; but this will invalidate your vertex shader and you'll end up with "Invalid vertex shader, cannot link program"
  4. If you specify a uniform in your vertex shader, and then try and get hold of it with
    glGetAttribLocation by accident instead of glGetUniformLocation, then it won't crash, there won't be an error produced in the log, you just won't be able to assign a variable to your shader when you render.
  5. ...to be continued...

No comments:

Post a Comment