mOfl's picture

Small version issues with OpenTK, OpenGL and Cg

Hiya everyone,

I'm using OpenTK quite successfully in my .NET 4.0 application which is basically a neat little rendering framework for all the daily stuff that needs to be rendered. That framework uses one of the newest OpenTK versions from the SVN (not sure what revision it was, but I can look it up on my other PC if it matters) and a modified version of the Tao Cg bindings for Cg 3.0. Now I noticed some strange behavior when creating the contexts. You might or might not be familiar with Cg, but you have to set up a Cg context as well and choose profiles out of quite a few possible shader profiles (where, of course, the later profiles are more comprehensive). In my application, I extend the GameWindow class for my window, so the creation process looks like this:

public Window(
    int width,
    int height,
    GraphicsMode mode,
    string title,
    GameWindowFlags options,
    VSyncMode vsyncMode)
    : base(width, height, mode, title, options, DisplayDevice.Default, 4, 2, GraphicsContextFlags.Default)
    this.VSync = vsyncMode;
    this.cgContext = CgNet.Context.Create();
    this.cgContext.ParameterSettingMode = ParameterSettingMode.Deferred;
    this.errorHandlerDelegate = MessageHandler.CgErrorEventHandler;
    Cg.SetErrorHandler(this.errorHandlerDelegate, IntPtr.Zero);

If I now use GL.GetString(StringName.Version), I get returned "4.1.0" on my GeForce GTX 480. Although I request version 4.2, a 4.1 context is set - is this due to the fact that my OpenTK is probably from 3 months ago when 4.2 was not yet released and some bindings are missing? Well, that's not the matter anyways, I'm perfectly fine with a 4.1 context, but!

As I said, I have to choose Cg profiles as well:

ProfileType fragmentShaderProfile = CgGL.GetLatestProfile(ProfileClass.Fragment);
ProfileType vertexShaderProfile = CgGL.GetLatestProfile(ProfileClass.Vertex);

Doing this with the requested version 4.2, I get the fragment and vertex shader profiles Gp5Fp and Gp5Vp, which is great. Everything works fine. If I request an OpenGL 4.1 context instead, GL.GetString(StringName.Version) returns "4.1.0", too, but the Cg shader profiles are "Unknown" and the whole thing is going down :( Do you know why this happens? As the Cg calls are made after the OpenGL context is created which is a 4.1 context in both cases, Cg should not behave any differently, but it does.

Well, it's definitely only a small flaw and it's kind of a niche question because the combination of OpenTK, Cg 3.0 and OpenGL 4.x might not be that common, but if I can only use a 4.1 context right now, I would like to be able to request a 4.1 context, it just looks a bit more deterministic ;)

Anyways, I'm glad you guys keep working on OpenTK, it's a really great tool!



Comment viewing options

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

Seems that OpenTK creates core profile contexts for OpenGL 3.2+, which aren't supported by Cg. I'm not sure why 4.2 works, but the driver might fall back to a 4.1 compatibility profile context for some reason.

mOfl's picture

Thanks for that one, you were right. Although having read about the missing support of the core profiles, I did not really interpret this information at all. Requesting a OpenGL 4.1 context does in fact set up a core profile context in which the Cg context fails, where requesting a OpenGL 4.2 context (or some other contexts like 3.4) will lead to compatibility profile context, and not only that, but to the highest compatible working context, which is 4.1 in my case. Everything makes sense now, I think I solved the world. There is no spoon and the cake is a lie. I even found a marvellous proof for P != NP, but this margin is too small to contain it.

For faster results of future generations - you can check whether you have a core profile or not with the ContextProfileMask bit:

bool core = false;
int contextProfileMask = 0;
GL.GetInteger((GetPName) (All.ContextProfileMask), out contextProfileMask);
if ((contextProfileMask & (int) (All.ContextCoreProfileBit)) != 0) {
    core = true;
mOfl's picture

I have to resurrect this one...

Can someone explain to me why one cannot set the WGL_CONTEXT_PROFILE_MASK_ARB flag on contex creation because it is not implemented? As seen in this thread (Cg does not currently support Core profiles, so a Compatibility profile has to be requested), it could be useful to be able to set the WGL_CONTEXT_DEBUG_BIT_ARB or WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB when creating the GameWindow/context.

Or is it possible and I just don't see it?