kvark's picture

using GL.Uniform* with generics

Project:The Open Toolkit library
Version:0.9.9-0
Component:Code
Category:support request
Priority:normal
Assigned:kvark
Status:closed
Description

U'm using Boo + OpenTK and I need to support generic uniform parameters. My class structure for shaders and parameters is based on generics and requires to call one of the GL.Uniform* functions on the lowest level. I'd like to have a mapping between Type -> Uniform func that is resolved at compile/assembly time, but not at runtime. AFAIK, DotNET doesn't support generic specialization... How can it be achieved?


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

#1

I have encountered the same issue, but haven't been able to find any good solution. As far as I can see, the only way to resolve this at compile time is to avoid generics altogether and overload on each type you wish to support.

kvark's picture

#2

Thanks, Fiddler. Now I know this to be a common problem.
I have one solution in mind, that is very general and difficult to implement:

1) create a simple macros that will generate specialization methods for the lowest-level generic method that calls GL.Uniform*:
It should accept function name and a list of types and produce number of specializations:
genFunc( GL.Uniform1, int, single )
genFunc( GL.Uniform4, Vector4 )

2) create a complex method attribute that needs to be applied to the generic methods/classes that call this lower-level method. This attribute should automatically produce specializations according to the existing specializations of methods/classes that current method/class refers to. The attribute should be applied to all other higher levels as well. Moreover, the generic classes/methods should appear in the code in the order from lowest level to highest. This will guarantee that all the necessary specializations exist for used methods/classes when parsing current generic method/class.

In the result I expect all the generic classes/methods to be specialized from the point of high-level object creation to the lowest level GL.Uniform* calls. This is nearly what a typical C++ compiler does with templates AFAIK.

Currently I have this attribute working for methods only... It's written by one of Boo core developers (cedric). I'm not 100% sure it's going to work if I extend it for classes, but theoretically it's a suitable solution, especially if count the future applications of such 'Specializator' attribute. I just wanted to know, how other programmers deal with this problem...

See my Boo issue for father info:
http://jira.codehaus.org/browse/BOO-1213

kvark's picture

#3

Assigned to:Anonymous» kvark
Status:open» closed

Finally I've finished implementing support for generic uniform parameters for shader.
First of all, my solution works only for Boo language (http://boo.codehaus.org) thanks to it's powerful AST manipulation abilities through custom attributes.

Here's the project's page on ohloh:
https://www.ohloh.net/p/kri
Here are the files containing the implementation:
http://kri.googlecode.com/svn/trunk/engine/core/Shader.boo
http://kri.googlecode.com/svn/trunk/ext/AutoSpecialize.boo

The principle is the following:
1) There is a data[of T] method of the ShaderProg class that calls GL.Uniform* internally. It's declared as a generic method, but the applied attribute ext.SpecReplaceMethod makes several specializations for specified types, replacing some dummy method by the required GL.Uniform.
2) There is a RepUniform[of T] class that calls ShaderProg.data[of T] somewhere inside. We can't make specializations for classes the same easy as we do with methods....

3) There is a param[of T] method of the ShaderAuto class that attaches some parameters to the shader. It requires specializations for types like int,single,Vector4,etc. But instead of just replacing some dummy method by specified, it does the following (using ext.SpecMethodClass attribute):
3.1) looks for a generic type used with specified name (RepUniform)
3.2) clones it, setting the new name to RepUniform_type (where Type is int,single,Vector4,etc)
3.3) replace all occurrences of generic parameter with a specified type
This allows artificially created classes (like RepUniform_int) that are not actually visible by the user, to call specialized ShaderProg.data and required GL.Uniform* therefore without additional effort from the user.

This solution can be adapted for some other class topologies as well, but you are still required to program in Boo in order to use it...
I'm open to any suggestions and questions about it.