PDA

View Full Version : Wrapping OpenGL: Is there a more general glUniform function?



Goran Milovanovic
07-19-2013, 03:55 PM
I'm trying to create a Python API that wraps OpenGL in some fairly convenient ways. For example:



program.uniforms["world"] = transform.gl_matrix


Converting from Python to the appropriate C pointer is relatively easy, but the fact that there's a different glUniform* function for each and every GLSL type ... that's somewhat troublesome, because (unless there's a better way) I'll have to wrap each and every glUniform* function.

Now, I can write a script to auto-generate that wrapping, but I would really prefer something like this:



void glUniform(GLint loc, GLsizei size, GLvoid* data)


Basically, a function that would just take the data, and stuff it into the uniform (if the sizes match); something that doesn't require calling a completely different function for what is essentially a float*.

Does something like that exist, or is there some other way to do this?

Any insight would be appreciated.

carsten neumann
07-19-2013, 09:02 PM
Don't you have to examine the declared type of the uniform (using e.g. glGetProgramResource (http://www.opengl.org/wiki/GLAPI/glGetProgramResource)) and the type of the data passed in already, so that you can check if the user passed in integers or floats for vec{2,3,4}, ivec{2,3,4}, uvec{2,3,4} uniforms respectively and perform a conversion in case of mismatch? Otherwise the interface is not only convenient, but also easy to accidentally misuse ;)

Goran Milovanovic
07-19-2013, 10:02 PM
I have this mapping: GLSL_TYPE -> wrapped_glUniformCall

I use glGetActiveUniform to get the names/types, and create this mapping: uniform_name -> wrapped_glUniformCall

And that's just to know which function to call for each uniform; I don't really do any conversion/checking - I just cast to whatever the function requires.

I don't mind misuse, as long as I get to cut down on the wrapper code (which is my goal in this case).

Alfonse Reinheart
07-20-2013, 12:48 AM
I don't mind misuse, as long as I get to cut down on the wrapper code (which is my goal in this case).

Maybe you should pay more attention to misuse. People will use your code more often than you will write it. Making an interface that is more error prone just because it's easier to write is a bad idea. You're basically trading your implementation time for the time of anyone who must debug applications written against your API.

Goran Milovanovic
07-20-2013, 02:42 AM
People will use your code more often than you will write it.

I can virtually guarantee that no one will use my code; This is just a small hobby project, started for educational purposes. In the unlikely event that it becomes something more than that, I will endeavor to think carefully about safety issues, but for now, I just want to write a very simple implementation.

Actually, in this case, while I'm willing to sacrifice safety, I'm not actively trying to avoid it - I just don't want to have wrappers for so many different functions (all of which basically do the same thing).

mhagain
07-20-2013, 03:05 AM
I can virtually guarantee that no one will use my code; This is just a small hobby project, started for educational purposes. In the unlikely event that it becomes something more than that, I will endeavor to think carefully about safety issues, but for now, I just want to write a very simple implementation.

"People" includes yourself.

GClements
07-20-2013, 07:09 AM
Basically, a function that would just take the data, and stuff it into the uniform (if the sizes match); something that doesn't require calling a completely different function for what is essentially a float*.

Does something like that exist, or is there some other way to do this?

Create a lookup table mapping type and size to the correct function, e.g.
http://code.google.com/p/makehuman/source/browse/trunk/makehuman/lib/shader.py

Note that the code wraps each uniform in an object, so that you only need to call glGetActiveUniform() once per uniform, rather than every time the value is updated.

Goran Milovanovic
07-20-2013, 01:59 PM
Create a lookup table mapping type and size to the correct function.

Note that the code wraps each uniform in an object, so that you only need to call glGetActiveUniform() once per uniform, rather than every time the value is updated.

Yes, that's basically my current setup, except, instead of a uniform object, I simply store the location in a name -> loc dictionary.

I was looking for a function that would make those lookup tables unnecessary, but I guess it doesn't exist.

thokra
07-22-2013, 04:37 AM
I was looking for a function that would make those lookup tables unnecessary, but I guess it doesn't exist.

Even with explicit uniform locations there needs to be a mapping to ensure a stable interface between the application and your shader program(s). So, you'd still have a mapping which doesn't involve a name, but the semantics of the uniform, e.g. "loc_0 -> shadow map" or "loc_1 -> current time". I've only skimmed some of the above answers, but handling type mismatches becomes easier with explicit uniform locations since you know the type of the uniform you assign a location to. So you could expand the location->semantics mapping to location->(semantics, type).

Of course, these semantics may vary from program to program and IMHO, it's not that easy to establish a stable, explicit uniform interface as it is with explicit attributes.