System: Android 4.03, OpenGL ES 2.0
Problem: When glAttachShader is invoked after the first frame has already been rendered with another program / shader, some devices (Galaxy S3) crash with a "GL_INVALID_VALUE" error (no further details are available in the error stack). Other devices (Asus eee TF101) are perfectly fine with that. The error does not always occur and sometimes it's also a "GL_INVALID_ENUM" instead. If I force all shaders to be compiled right at the first call to onDrawFrame, it works on all (my) devices.
Questions: Are there states in which the openGL(ES) machine is incapable of compiling a shader? Is it possible that bound buffers, textures or enabled attribute arrays interfere with attaching a shader to a program? If so, what is the ideal state one must ensure before attaching shaders and linking the program? Is it even valid to compile shaders after other objects have already been rendered with other shaders?
Background: I'm developing an Android library that will allow me to use openGL graphics in a more object oriented way (using objects like "scene", "material", "model" etc.), utlimatively to write games easily. The scenes, models etc. are created in a thread different to the GL context. Only when onDrawFrame encounters one of these objects it will do the buffer object binding, texture binding and shader compilation, within the right thread. I would like to avoid to compile all shaders at the beginning of my code. The shader source is assembled depending on the requirements of the material, the model and the scene (eg: Material: include bump-mapping, Model: include matrix-palette-skimming, scene: include fog). When a model is removed from a scene, I'm going to delete the shader again - and if I add another model, the new shader should be compiled ad-hoc.
At this point I'm trying to be as concise as possible without posting code - you can imagine that extracting the relevant parts from this library is difficult.
It is perfectly valid to compile during rendering although is discouraged as the driver needs to take resources (CPU) for that. Some driver states my trigger a shader recompile at the driver side as some states are injected into the shader. It wise to reorganize your drawing calls into chunks sharing the same driver state (preferred by shader program as is one of the most expensive operations done by the driver).
TIP: Be sure to "use" all variables, uniforms and attribs declared into your shader, otherwise, the Mali driver removes them during compile and when you try to get an uniform location, an attrib location and son on, the drivers returns GL_INVALID_VALUE.
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With