@Capehill Yeah, that surely not shaders itself issue (if i remember right, we have that non working shader with any ogles2 code, and Daniel explain before why).
Our problem now to understand why glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status); fail to set status on the first call.
Probably the only solution now is short the test case as much as possible.
But couldn't you send a glSnoop trace of this actual failure? I have been staring gl4es code a lot but since I can't be sure what functions are called it's guesswork. For example, glGetObjectParameterivARB call branches either to glGetShaderiv or glGetProgramiv.
According to gl4es code status param should be passed to OGLES2 as such so logically uninitialized value should be coming from OGLES2. But, when I tested OGLES2, surely status values for glGetShaderiv call were set in case of failure and success.
There I just run the test case like it was, without anything changed. So it failed to set "status" on the first call bring me errors from that ==0 check part, and then I exit from.
Quote:
I have been staring at gl4es code a lot but since I can't be sure what functions are called its guesswork. For example, glGetObjectParameterivARB call branches either to glGetShaderiv or glGetProgramiv.
I asked pritSeb to clarify a bit about, once he will answer i will post it there.
gl4es seems to think that passed shader object is a program object and then it calls glGetProgramiv with GL_COMPILE_STATUS which triggers GL_INVALID_ENUM and uninitialized status, because "If an error is generated, no change is made to the contents of params." - https://www.khronos.org/registry/OpenG ... /xhtml/glGetProgramiv.xml
(see next answer after that one). And basically check also other posts after this one.
Quote:
gl4es seems to think that passed ...
Did you mean it looks like a bug in gl4es, which somehow does not happen on Pandora by some reasons ?
Sorry i am a bit lost there, but did what you find anyhow explain why it didn't works first time (on first pass), but works correctly all other times ?
gl4es seems to think that passed shader object is a program object and then it calls glGetProgramiv with GL_COMPILE_STATUS which triggers GL_INVALID_ENUM and uninitialized status, because
Yes, if shader creation and program creation on Amiga side of things (ogles2.library?) return integer IDs that may match (ie. a created program could return ID 1 and a created shader could also return ID 1) then this is likely what is happening and causing the problem.
In test program print out the the return values of glCreateProgremObjectARB() (data->program) and glCreateShaderObjectARB() calls (data->vert_shader and data->frag_shader) to see what they return.
In test program print out the the return values of glCreateProgremObjectARB() (data->program) and glCreateShaderObjectARB() calls (data->vert_shader and data->frag_shader) to see what they return.
Added printfs:
/* Create one program object to rule them all */
data->program = glCreateProgramObjectARB();
printf("data->program = %d\n",data->program);
/* Create the vertex shader */
data->vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
"If an error is generated, no change is made to the contents of params."
Given that, it would be good defensive programming practice to set 'status' to 0 before making the call, so if the call aborts without setting the status at all then at least you'll get a consistent failure, rather than a random result depending on what happens to be on the stack. That would have saved kas1e a lot of time playing with printf().
We probably need to check OpenGL ES 2.0 specs what is said about program/shader id numbers. If program and shader IDs need to use the same pool, then it should be fixed in OGLES2. If not, then maybe gl4es needs to be changed.
@msteed
Yes, status should be initialized. SDL2 has some other GL examples that do initialize status variable. I could try make a PR to upstream, maybe it saves some time for someone else.
We probably need to check OpenGL ES 2.0 specs what is said about program/shader id numbers.
Nothing. ogles2.lib uses dedicated pools which complies to the standard. But you are right, this is incompatible with GL4ES' glGetObjectParameterARB API. Therefore I modified ogles2.library. From the change-log:
New context creation tag OGLES2_CCT_UNIQUE_SHADER_AND_PROGRAM_IDS. This is a helper tag to allow APIs like GL4ES' glGetObjectParameterARB to work with ogles2.library. This API asumes that the shader- and program-IDs generated by glCreateShader and glCreateProgram share the same ID pool. Note that this rule does not apply to OpenGL ES 2 (and not even 3 AFAIK). When this tag is set to TRUE then ogles2.lib will essentially half the ID-space for shaders and programs and return values from the lower half for programs (ID & 0xFF < 128) and values from the upper half for shaders (ID & 0xFF >= 128). Note that TRUE has been made the default value for that new tag for convenience. That way GL4ES doesn't have to be rebuild.
Of course I didn't test this at all. A fresh lib build is available at the link which you should have. If you find this to not work as expected, please file a std. bug report.
@Daniel Tested new lib and yeah no more error! i add for sake of tests "status" to be initialized as "1234", and all fine after first return of status value = 1, same for all other shaders.
Through to clarify was it a bug at all or not ? Just curous why it works on pandora/linux/etc. If the opengles specs have nothing saying about, intersting why they (on pandora/linux/etc) go some "same" route.
EDIT: It was a specs violation in ogles2 after all, disregard my stuff below, I was wrong.
@kas1e As I said: there's no word about that in the OpenGL ES 2 specs (unless I'm totally blind). So an implementation may chose whichever ID generation algorithm it may like. There is no rule that shader-IDs and program-IDs are related in any way. Which is logical because there's no critical function like glGetObjectParameters in GLES2.
So it was no bug in ogles2.lib.
It's a bug in GL4ES because it asumes something in its OpenGL ES 2 based implementation which the OpenGL ES 2 standard doesn't guarantee. GL4ES was just lucky so far with those other GLES2 implementations which apparently chose to implement ID generation differently.
To fix GL4ES the following would have to be done:
- glCreateShader and glCreateProgram functions must be wrapped and the IDs returned by the respective ogles2 functions must be mapped to GL4ES-internal shared IDs. Those other IDs must then be returned to the caller.
- in each function which accepts a shader- or program-ID the reverse mapping must be done and then the original ID must be passed to ogles2.
Because it was easy for me to artificially restrict ogles2.lib so that it creates IDs which work with GL4ES, I chose to do so. It also has no performance penalty. Fixing GL4ES is certainly a bit harder than that and would require this extra ID translation. The bug in GL4ES persists of course, but it doesn't affect the ogles2.lib-code-path anymore so it doesn't matter to us anymore.
@kas1e As I said: there's no word about that in the OpenGL ES 2 specs (unless I'm totally blind). So an implementation may chose whichever ID generation algorithm it may like.
@Georg Yep, you're right and I was blind. So, no bug in GL4ES, it was a bug / specs violation in ogles2.lib after all.
EDIT: Updated the lib accordingly. The helper tag has gone again, now the changelog reads like that:
- Fix: specs violation. The IDs returned by glCreateShader and glCreateProgram were independently generated. However, the standard says that the shader IDs' "name space is shared with program objects", a fact which I overread, grrmbl. For an OpenGL ES 2 implementation by itself this violation isn't really a problem but it turned out to be the source for an issue related with GL4ES: In std. GL, which GL4ES implements based on OGLES2, there's a function glGetObjectParameters which accepts shader- or program-IDs as first parameter. Now due to this bug in ogles2.lib those IDs were not unique, so that this function was not able to distinguish between shader- and program-IDs, which in turn resulted in nonsense behaviour. Thanks to George for rereading the OGLES2 specs and correcting me on that, as I asumed a bug in GL4ES here. Now the the IDs returned by glCreateShader and glCreateProgram are unique in the shared UINT32 number space.