[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] ctx.uniform1f with a bool uniform



Let's start off with the error. 0x502 = GL_INVALID_OPERATION.

Looking at the man pages for glUniform( ), I see a lot of different reason that can't apply to your situation (e.g. specifying integer for float values, using > 1 count for scalar, etc.), except this one: "GL_INVALID_OPERATION is generated if there is no current program object." 
I didn't see glUseProgram( ), so that is the problem. And I guess it makes sense, you could potentially have tens of programs, which call should glUniform( ) affect if it isn't a parameter to the function call?

Patrick


On Tue, May 4, 2010 at 7:36 PM, Gregg Tavares <gman@google.com> wrote:
I ran into this issue today, testing uniforms, that apparently setting a bool uniform with glUniform1f generates an error even though the specs all say it should succeed.

From the OpenGL ES 2.0 spec, section 2.10.4

When loading values for a uniform declared as a boolean, a boolean vector,
an array of booleans, or an array of boolean vectors, both the Uniform*i{v} and
Uniform*f{v} set of commands can be used to load boolean values. Type conver-
sion is done by the GL. The uniform is set to FALSE if the input value is 0 or 0.0f,
and set to TRUE otherwise.

The OpenGL 2.1, 3.3 and 4.0 spec all have the same language. 

Here's my test code in C++. Maybe there is an error?

   const char* vsrc =
       "attribute vec4 pos;\n"
       "void main (void) {\n"
       "  gl_Position = pos;\n"
       "}\n";
   const char* fsrc =
       "uniform bool color;\n"
       "void main (void) {\n"
       "  gl_FragColor = vec4(float(color), 0.0, 0.0, 1.0);\n"
       "}\n";
   GLuint vs = glCreateShader(GL_VERTEX_SHADER);
   GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
   GLuint prg = glCreateProgram();
   glShaderSource(vs, 1, &vsrc, NULL);
   glShaderSource(fs, 1, &fsrc, NULL);
   glCompileShader(vs);
   glCompileShader(fs);
   glAttachShader(prg, vs);
   glAttachShader(prg, fs);
   glLinkProgram(prg);
   GLint success;
   glGetProgramiv(prg, GL_LINK_STATUS, &success);
   printf("Link: %s\n", success ? "good" : "*BAD*");

   GLint bloc = glGetUniformLocation(prg, "color");
   printf("Loc : %d\n", bloc);
  
   printf("err : %04x\n", glGetError());
   glUniform1f(bloc, 0.0f);
   printf("err : %04x\n", glGetError());

The output of the above program is

Link: good
Loc : 0
err : 0000
err : 0502

As far as I can tell that error is incorrect. Yet I've tried this on Windows7 with an NVidia Quadro FX 380, A Macbook Pro with GeForce 8600M GT and another Macbook Pro with some ATI Radeon X1600.

If my C code above is bad then color me embarrassed but please point out what I'm missing. Otherwise this is important because if the code above is correct, then the WebGL spec currently requires that the same code in WebGL not get an error and so implementations have to do more work to work around the apparent bug all these drivers.