Tao.OpenGL beta versions (last release: 2.1.0.12)
Latest Tao.OpenGl beta: 2.1.0.12
Latest Tao.Platform.Windows beta: 1.0.0.4
The zip contains the release build of the latest Tao.OpenGl.dll. It is an unsigned dll (i.e. it cannot replace 2.1.0.4 in the GAC), but it should be stable for normal development.
- Changelog
- Heavily optimized extension loading.
- GLboolean is mapped to bool instead of int.
- Several minor bugfixes.
- Removed default initializers on 'out' parameters. Parameters with an 'out' flow direction work correctly now (fixes StringBuilder and pointer problems).
- Corrected an error where StringBuilder parameters were erroneously set to null before an opengl call. Resolves crashes on GetShaderInfoLog and other functions.
- MapBuffer (and three other functions) now correctly return an IntPtr instead of void.
- Added non CLS-Compliant overloads for unsigned parameters, to improve compatibility with Tao 1.3. Fixes glLineStipple problems. Hopefuly, all old projects will work with little or no changes now.
- Now uses the unsafe 'fixed' statement to pin arrays and ref/out parameters. Results in ~1000% faster call performance (see timing information below), and fixes the behaviour of references inside arrays (ref a[5,0] will produce the expected result now).
- Generator rewritten from scratch, in preparation for OpenGL 3.0 (Long Peaks). CodeDOM was not flexible enough.
- 2.1.0.12
- 2.1.0.11
- 2.1.0.10
- 2.1.0.9
- 2.1.0.8
Everyone, please test and provide feedback on this beta, especially if you have encountered problems porting older applications (missing overloads etc.) It is important to iron out all known bugs before the next release, as OpenGL 3.0 is coming closer.
FAQ
- How do I use the IntPtr overloads?
You will have to keep in mind that there are two uses for IntPtr overloads: a) to pass a pointer, and b) to indicate the number of elements in an array. While the second use is rare, you will have to use your judgement (and the opengl reference) to differentiate between the two.As a rule of thumb, avoid the IntPtr overload unless you are passing 'opaque' data from some other Tao library.
- How do I obtain a pointer for use with an IntPtr overload?
In managed code, you are not allowed to take the address of objects, since the Garbage Collector moves objects in memory to improve efficiency.
In order to obtain an IntPtr to an object, you will have to 'pin' it first. This can be done in two ways: the unsafe (but fast) and the safe way:// Unsafe/Fast way:
unsafe {
fixed (float* data_ptr = &data[0]) {
Gl.glVertex3f((IntPtr)data_ptr);
}
}
// Safe/Slow way:
// using System.Runtime.InteropServices;
GCHandle data_handle = GCHandle.Alloc(data, GCHandleType.Pinned);
try {
Gl.glVertex3fv(data_handle.AddrOfPinnedObject());
}finally{
data_handle.Free();
}
- Which should I prefer when pinning: unsafe code or GCHandles?
Both have their strong and weak points. Unsafe code (the 'fixed' statement) is easily an order of magnitude faster than using GCHandle.Alloc(). On the other hand, you will have to enable unsafe code (which may or may not be desirable). More importantly, the 'fixed' statement can only be used on value types and arrays, not objects, so you are limited in its use.
GCHandles are slow, and consume memory. However, they can be used with any object, and do not need unsafe code.I would suggest you use the 'fixed' statement, unless not possible. You may want to take a look at the ref/out and array overloads, too, which take care of object pinning.
- How do I use the ref/out overloads?
You will generally use the ref overloads in place of pointers (IntPtr). Some code will help here:
// pass a single element to an opengl function taking a pointer:
int list;
Gl.glGenLists(1, out list);
// pass an array, starting from an element other than the first one:
float[,] data = new float[3,3];
Gl.glVertex3fv(ref data[2,0]);
- Should I use the 'ref' or the 'array' overload? They seem to do the same thing.
They are close, but not completely. Sometimes it makes sense to use the array overload, for example when you have a list of vertices (or other data) that you want to pass to an opengl function:
List data = new List();
// Add data to vector, then load it on a vertex buffer object.
Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)(data.Length * 3 * 4), data.ToArray(), Gl.STATIC_DRAW);
Other times, you may want to pass a single element to a function taking an array. Or you may want to pass an array of data to a function, starting not from an element other than a first. Or you may want to use a multidimensional array ([,,]). In these cases use the ref overload. - Performance pitfalls: What to do and what to avoid in managed code.
Let's start with some unofficial timing information on Tao.OpenGl functions.- Dummy managed call (baseline):
- Inline function: 100000000 calls/second.
- Function with try: 74500000 calls/second. <--- With try { } finally { } block
- Tao.OpenGl functions:
- GL.Vertex2f: 22400000 calls/second.
- GL.Vertex2fv: 22450000 calls/second. <--- fixed statement
- GL.ARB.ActiveTexture: 19900000 calls/second.
- GL.ColorPointer: 2350000 calls/second. <--- GCHandle.Alloc and Free
- GL.Vertex2fv: 2250000 calls/second. <--- GCHandle.Alloc and Free
All numbers taken on an athlon64 (venice) 3200+, running Vista x64 with 2GB RAM. The code was built with optimisations and x64 mode enabled. Test accuracy within 5%-10% of the numbers shown here.
What do these numbers tell us? First of all, an inline, managed function call is an order of magnitude faster than a Tao.OpenGl call. It makes sense to reduce opengl function calls, especially you are CPU bound (and they take any significant portion of your performance graphs).
Moreover, using a GCHandle is an order of magnitude slower than pinning thorugh the fixed statement. All Tao.OpenGl function have been updated to use the fixed statement internally, except for functions that have 'object' overloads. If your code makes frequent calls to such functions, and your data structures permit it, consider pinning the objects yourself and using the IntPtr overload instead.
A good rule of thumb is to avoid excess opengl calls from managed code: use vertex buffer objects or display lists instead of immediate mode and write glsl programs to utilize modern GPUs instead of CPUs. As a last resort, you can rewrite performance bottlenecks in pure C and DllImport them to C#.

glMapBuffer should return a
glMapBuffer should return a pointer, but has no return value.
EDIT: Regression, corrected
EDIT: Regression, corrected in 2.1.0.9
Seems to work fine.
Seems to work fine. Compatibility broke with some functions like glGetObjectParameterivARB (threw an AccessViolationExcpetion), but after changing the parameters to out/ref, it is now OK.
Works here after a Rebuild
Works here after a Rebuild (On Vista) but my app doesn't use vector lists yet.
Seems to work fine.
Seems to work fine. Compatibility broke with some functions like glGetObjectParameterivARB (threw an AccessViolationExcpetion), but after changing the parameters to out/ref, it is now OK.
The exception occured when using the array overload? Can you post the function call, as it was before and after the change? I'm trying to see if this merits investigation.
Works here after a Rebuild (On Vista) but my app doesn't use vector lists yet.
Glad to hear! You will probably see a performance increase when (and if) you change it to use lists.
Yeah I need to change to
Yeah I need to change to lists now so I can take full use of color controll and display lists or something. Im quite new in Open GL so I take baby steps with my code
The exception occured when
The exception occured when using the array overload?
No, I was passing a pointer to a stack variable (although I'm not 100% sure that that was not something discouraged anyway, if it was, tell me).
Old code (does not work anymore in new beta):
int status; // local variable on stack
Gl.glGetObjectParameterivARB(GlName, Gl.GL_COMPILE_STATUS, (IntPtr)(&status));
New code:
int status;
Gl.glGetObjectParameterivARB(GlName, Gl.GL_COMPILE_STATUS, out status);
Interesting to note, that not all functions are affected. for example, glShaderSourceARB continues to work with the old code too.
Thanks, it is a regression
Thanks, it is a regression then! I'll post a new beta shortly.
The actual problem is that the status parameter in ShaderSource has an 'in' flow, while in GetObjectParameter has a flow of 'out'. The flow indicates whether changes to the parameter value should be visible the caller. The new generator leaves the flow at its default 'in' value, unless overriden (for example by using 'out status') - I'll change that to the old behavior of always specifying an 'out' flow on relevant parameters.
It now compiles fine without
It now compiles fine without the cast to (int), however, it crashes consistently with a MemoryAccessViolationException at the call to retrieve the InfoLog on both the Shader and the Program. I tried the type cast (int) and unchecked((int)_guid) and they all crash now. Sample code:
int maxLength = 8190;
int length;
Gl.glGetShaderiv(_guid, Gl.GL_INFO_LOG_LENGTH, out
maxLength);
StringBuilder log = new StringBuilder(maxLength);
=> Gl.glGetShaderInfoLog(_guid, maxLength, out length,
log);
=> crashes.
Roger
---------
Prof. Roger Crawfis
The Ohio State University
Computer Science & Engineering Dept.
Columbus, OH 43210
No access violation here,
No access violation here, but the log stays empty. Investigating.
Edit1: Found the problem, the StringBuilder is erroneously set to null before the call (it is treated as an out parameter when it's not). Working on it (let's see if the new generator architecture holds up to small rapid changes).
Edit2: Apparently it holds up well, the error is fixed
Thanks for the report, I'll upload a new beta in a few moments.
Can you post a link to the
Can you post a link to the generator code? I can put that and the 2.1.0.11 code into SVN. Thanks
Stephan, Out of curiosity,
Stephan,
Out of curiosity, what are you doing with the StringBuilder. I just changed my code-base to a little cleaner format (just changed this using CopyToHTML, so let me know if this is garbage):
----
private StringBuilder _compileLog = new StringBuilder(1024);
public string CompileLog
{
get { return _compileLog.ToString(); }
}
private void SetCompilerLog()
{
int maxLength;
Gl.glGetShaderiv(_guid, Gl.GL_INFO_LOG_LENGTH, out maxLength);
_compileLog.EnsureCapacity(maxLength);
Gl.glGetShaderInfoLog(_guid, maxLength, out maxLength, _compileLog);
}
----
Now, philosophically, not sure if Tao should be kept a very thin wrapper, or do the correct thing and call the EnsureCapacity within the glGetShaderInfoLog(). I know it does not now, as I was getting an exception at one time, but it may be a worthwile addition. Of course, this would mean the maxLengh would not be needed and would override a user explicit setting, so probably not.
Thanks for the fixes.
---------
Prof. Roger Crawfis
The Ohio State University
Computer Science & Engineering Dept.
Columbus, OH 43210
MemoryAccessViolation still
MemoryAccessViolation still on ATI machines. It works fine on my nVidia machines, but the ATI Radeon still throws an exception at the line:
Gl.glLinkProgram(_guid);
_guid has a value of 0x80000004.
I am going to revert to the 1.3 version and see if it still works. The type cast I was doing may not have been the access violation. Are you sure there are no type casts within the wrapper? Edit: I just realized you had the source in the zip file, so I just looked at it all. I do not see any problems
.
Also, the glCreate methods still return an int rather than an unsigned int. I placed this around an unchecked section to be safe, but obviously with the value above 2**31 it is not doing a type conversion.
Roger
---------
Prof. Roger Crawfis
The Ohio State University
Computer Science & Engineering Dept.
Columbus, OH 43210
MemoryAccessViolation still
MemoryAccessViolation still on ATI machines. It works fine on my nVidia machines, but the ATI Radeon still throws an exception at the line:
Gl.glLinkProgram(_guid);
_guid has a value of 0x80000004.
The value 0x80000004 is very very strange. Here (Ati X1950 Pro, 7.7 Vista x64 drivers), CreateShader calls return values like 1 and 2 - if I pass 0x80000001 or 0x80000002 I get an access violation error. It's a long shot, but what happens if you subtract 0x80000000 from _guid?
Also, the glCreate methods still return an int rather than an unsigned int.
Unfortunately, the .Net framework does not support overloading the return value, and the CLS-Compliant versions are more 'valuable'. I'll try to add the unchecked statement inside the wrapper function, so that you don't need to specify it by hand, but I don't know if anything more can be done here.
Can you post a link to the generator code? I can put that and the 2.1.0.11 code into SVN.
I'm currently hosting it at (svn co) https://opentk.svn.sourceforge.net/svnroot/opentk/branches/gl3/Source/Bi..., but the source is still a little volatile, so I'm not sure if that's a good idea yet.
I'm also thinking that it might preferable to make a separate package for the generator. Right now, it provides little benefit to the Tao end-user (has anybody ever found a reason to run it?), and it has grown enough to become a project of its own. What do you think?
I don't mind it being a
I don't mind it being a separate project, but I would like to keep it in the Mono SVN tree like Tao. That way, Tao devs can always regenerate the bindings. For instance, I use the generator for the releases.
I'm getting a runtime
I'm getting a runtime error.
IL replacement failure.
at Tao.Platform.Windows.Wgl.wglGetExtensionsStringARB(IntPtr extensionPointer, IntPtr hdc)
at Axiom.RenderSystems.OpenGL.GLSupport._initializeWgl() in C:\Projects\Open Source\Axiom3D Graphics Engine\crickhollow-svnhead\Projects\Axiom\Source\RenderSystems\OpenGL\Win32\GLHelper.cs:line 124
at Axiom.RenderSystems.OpenGL.GLSupport..ctor() in C:\Projects\Open Source\Axiom3D Graphics Engine\crickhollow-svnhead\Projects\Axiom\Source\RenderSystems\OpenGL\Win32\GLHelper.cs:line 71
at Axiom.RenderSystems.OpenGL.GLRenderSystem..ctor() in C:\Projects\Open Source\Axiom3D Graphics Engine\crickhollow-svnhead\Projects\Axiom\Source\RenderSystems\OpenGL\GLRenderSystem.cs:line 172
at Axiom.RenderSystems.OpenGL.Plugin..ctor() in C:\Projects\Open Source\Axiom3D Graphics Engine\crickhollow-svnhead\Projects\Axiom\Source\RenderSystems\OpenGL\Plugin.cs:line 59
This is the offending line of Code:
string exts = Wgl.wglGetExtensionsStringARB( wglGetExtensionsStringARB, hdc );
Borrillis
The Steward of Axiom
http://axiomengine.sf.net
Known bug - wgl extensions
Known bug - wgl extensions are unsupported since Tao 2. They are on the todo list, I'll try to provide an update soon.
Edit: I was able to run the generator on the wgl specs, and it worked! I'll have to make some things configurable (the 'wgl' prefix for example, it now prefixes functions with 'gl' and enums with 'GL_WGL_'), but all in all it works.
It will take some time, but we'll finally have working wgl extensions.
Can someone tell me what the
Can someone tell me what the plan for releases are? The latest official release was May 2007, but it was pretty buggy. Can we get many of these fizes pushed out to the Sourceforge site?
---------
Prof. Roger Crawfis
The Ohio State University
Computer Science & Engineering Dept.
Columbus, OH 43210
I don't think there is a set
I don't think there is a set release schedule. However, seeing that no code changes happened during the last two weeks, maybe now would be a good time?
------
OpenTK
Sorry that I have not taken
Sorry that I have not taken a look at this sooner. I have been pretty busy. I'll grab the latest code for Tao.OpenGL and the generator and put them into svn. Then we can start looking towards a new release soon. Thanks.
Version bindings issues and
Version bindings issues and exceptions.
With the Beta version for OpenGL (and OpenGL only), we get a version warning and subsequent crash in our C# program about version 2.0.4.. not matching 2.1.11. In C# we can easily correct this with an app.config file. Several of my students are trying to use this in C++ and it is not clear how to fix this?
Sorry to push, but the quarter has started and I have already ran into several issues, but a complete updated package would be appreciated.
---------
Prof. Roger Crawfis
The Ohio State University
Computer Science & Engineering Dept.
Columbus, OH 43210
It sounds like the binaries
It sounds like the binaries are trying to use the dll installed in the GAC (2.1.0.4) instead of the beta (2.1.1.11). I always thought that simply having the beta dll in the same directory as the exe was enough, maybe this is the problem?
I´ll try to prepare Tao.OpenGl for release during the weekend but an actual release depends on all projects being ready.
I don´t know if this is feasible, but you could try adding the beta dll to the GAC. You´d have to add a signature manually first, but it should work around the issue.
------
OpenTK
I tried to install it in the
I tried to install it in the GAC. It said it was successful, but I did not add a signature.
In anycase, what I assumed was going on is that I was using the 2.1.1.11 directly, but the Tao.Platform.Windows wanted the 2.1.0.4 and thought there might be a security issue.
We determined how to copy over the app.config for C++ based code.
Roger
---------
Prof. Roger Crawfis
The Ohio State University
Computer Science & Engineering Dept.
Columbus, OH 43210
STApostal, I was having some
STApostal, I was having some problems regenerating the bindings. I checked out the Bind code from your svn repo but did not see a solution or make file. Could you post up one so I can build the Binding exe? Thanks
Oh right, I'll run some
Oh right, I'll run some tests and pack it up for check-in. Currently it relies on Prebuild, is that ok or should I write a makefile?
The latest version contains some minor bugfixes and optimizations (mainly in size) compared to the one used for 2.1.0.11, but nothing too big. Most of the work has gone into making the generator ready for OpenGL 3.0 (when that comes out). It can also generate Wgl bindings - the current ones are not working in Tao(broken extensions), so we should update these too.
------
OpenTK
The prebuild version is
The prebuild version is fine. Thanks
Alright, ready. I tested
Alright, ready. I tested with tao-svn and as far as I can see everything builds and runs fine. Tao.GlBindGen-2.1.0.12
This isn't a patch, because the whole thing is pretty much rewritten from scratch. I've been documenting and refactoring the whole thing since last spring (but I'm still ashamed of it) - however it works. A couple of known bugs: 1) doesn't show usage parameters when launched without any arguments, 2) doesn't supress warnings for empty XML-comments. Both are easy to correct, which I'll probably do at some point.
Usage:
"Tao.GlBindGen.exe -mode:gl2 -in:../../Specifications -out:. -o:tao"Pretty self-explanatory, "-o:tao" sets the generator to Tao compatibillity mode, "-in","-out" set the input and output directory, "-mode:gl2" for OpenGL 2.1 bindings. Available parameters to "-mode:gl2,wgl,glu,glx,gl3". Gl2 and wgl work, glu,glx,gl3 are not ready yet.
I've also updated GlHelper.cs to speed-up the extension loading process and fix a couple of bugs (wrong version for Mesa, and a potential - but improbable - race condition).
Unfortunately I don't have the x64 dependencies to test every bundled example, so please run a few tests before commiting to see if everything is sane.
------
OpenTK
The link to the GlBindGen
The link to the GlBindGen does not appear to work. Can you repost it? I will upload the glhelp into svn. Thanks
For some reason I can't seem
For some reason I can't seem to edit the post above. Should have checked the link. Correct link here.
------
OpenTK
Thanks. i have uploaded the
Thanks. i have uploaded the changes to GLBind and the resultant OpenGl files into the new Sourceforge svn. Feel free to make any updates needed there