Does the shader collect good / valid practice in OpenGL ES during rendering?

System: Android 4.03, OpenGL ES 2.0

Problem: When glAttachShader is called after the first frame has already been processed by another program / shader, some devices (Galaxy S3) crash with the error "GL_INVALID_VALUE" (details are not available on the error stack). Other devices (Asus eee TF101) do a great job of this. An error does not always occur, and sometimes "GL_INVALID_ENUM". If I force all the shaders to compile immediately upon the first call to onDrawFrame, it works on all (my) devices.

Questions: Are there any states in which the openGL (ES) machine is unable to compile the shader? Is it possible that linked buffers, textures, or activated attribute arrays prevent the shader from attaching to the program? If so, what is the ideal state to ensure before connecting shaders and linking the program? Is it really possible to compile shaders after other objects have already been processed using other shaders?

Background: I am developing an Android library that will allow me to use openGL graphics in a more object-oriented way (using objects such as "scene", "material", "model", etc.) to easily write games. Scenes, models, etc. Created in a thread other than the GL context. Only when onDrawFrame collides with one of these objects will it bind the buffer object, bind textures, and compile the shader within the correct stream. I would like to avoid compiling all the shaders at the beginning of my code. The shader source is compiled depending on the requirements of the material, model and scene (for example: Material: include bump-mapping, Model: include matrix-palette-skimming, scene: include fog). When the model is removed from the scene, I will remove the shader again - and if I add another model, the new shader must be compiled ad-hoc.

At this stage, I try to be as concise as possible without publishing the code - you can imagine that extracting the appropriate parts from this library is difficult.

+4
source share
2 answers

If you copy the BasicGLSurfaceView sample code that comes with the Android developer kit to start your project, then the first call

checkGlError 

after attaching the vertex shader. However, you could use an invalid value or enumeration much earlier or elsewhere in your code. But this will only be called by this call after glAttachShader.

In my case, I deleted the texture that was still linked as the render target for the framebuffer. My earlier Android device, which was slower, compiled the shader before uninstalling, my new device somehow managed to call

 glFramebufferTexture2D 

before compiling the shader. All this has something to do with queueEvent and my poor understanding of thread safety.

Thanks for your efforts, TraxNet and Prateek Nina.

0
source

It is perfectly correct to compile during rendering, although it is discouraged, since the driver needs to take resources (CPU) for this. Some drivers indicate that my trigger overwrites the driver-side shader, as some states are entered into the shader. It is wise to reorganize your drawing calls into chunks that share the same driver state (preferably a shader program, as one of the most expensive operations performed by the driver).

TIP. Be sure to use all the variables, uniforms, and attributes declared in your shader. Otherwise, the Mali driver deletes them at compile time and when you try to get a uniform location, location and son, the drivers returns GL_INVALID_VALUE.

Hope this helps.

+2
source

All Articles