Inertia's picture


For the mentioned upcoming release, here are minor issues I came around. Nothing serious, and too small issues to create a new topic for them alone.

1) The enum GetTextureParameter doesn't contain GL_TEXTURE_COMPRESSED.

2) Glu.ErrorString expects different type as parameter, than what is returned by GL.GetError(); Unnecessary cast? Don't see any other use for these commands.

3) KeyboardDevice.cs
public bool KeyRepeat
Documentation unclear about "on", true/false might be better.

4) GL.Color could use a Vector overload, colors can be nicely stored in Vector3/4. The function was also behaving a bit weird always expecting (int) for fixed-point types. E.g. (byte)255 for RGB would result in black as it got cast to int32. Anything but byte/float is not really useful?

5) GL.Material could aswell use a Vector4 overload. I understand why this is difficult for all functions where modes can expect different types for their own parameters, but I think this is a special case where this would make sense. How about adding GL.Materialv4, which can be used for convenience with a Vector4 for specifying colors (ambient/diffuse/specular/emissive), where shininess can still be set through default GL.Material().
This is just something to consider, the current implementation is fine.

Ironically 3) was the point where I decided that it'd be quicker to implement that "keystroke manager" in a few minutes than going through documentation. All I wanted was Glut-like handling for a handful of toggles and getting other functions further, no offense/critique against your design - just a subjective decision for that small project.


Comment viewing options

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

Thanks! This explanation is so good it should definitely be quoted in the upcoming book. So far I thought the EXT/NV/SGI&Co prefixes were related to patent status only.

I was just pondering because the .spec file did contain glDrawElementsInstancedEXT() when I checked, but it doesn't show in intellisense when writing OpenTK apps. I've found an enum called ExtDrawInstanced, but it appeared to be empty. I'm aware that my graphics card cannot handle the extension, was just curious if it's really just a glDrawElements() function with a repeat count.

Edit: It appears that there is a functions generated in GL.cs called DrawElementsInstance() and DrawArraysInstance(), it just does not work with Intellisense (not CLS compliant?). It answers my question though, seems the parameters they expect are almost identical.

Inertia's picture

7 continued) I've now run multiple times into similar problems, where I had to go through versionX enums to find a token, or use the search function to figure out where the token is located. Am I missing something obvious how to find them faster? Or do I really have to remember which extensions were introduced in which version of OpenGL? I was under the impression that all extensions available to OpenGL 1.2 would be available in 1.3 up to 2.1 too.

I can c&p examples if you need to know where specifically the problems were, but it turned out they were all solvable by using search. However the code isn't pretty when casting from one enum to another, thus my question if I'm missing something here?

the Fiddler.'s picture

No, you're not missing anything, this is the way the specs are defined. Even though a function may be updated to accept new values, the corresponding enum is not - the new values are added either as an extension enum (Arb, Ext etc) or in the corresponding VersionXY enum. Ugly, but this is the way they decided to make the specs - even if they themselves don't follow these rules always (this is the reason every enum is littered with SGI-specific values). The easiest solution right now is to cast from Enums.All to the correct type.

It would be great if you could post a list of the affected functions/values. Since the GL2 specs won't be updated anymore, it is fair game to edit and add tokens were it makes sense - it won't be long before most problematic cases are covered.

Inertia's picture
  1. Agreed, commonly used things like Multitexture, Blending, Texture Compression, Shadow & Cube Maps, VBO, FBO, 3D Textures and Shaders could really be integrated. Besides the 3D Textures that's pretty much standard for years now. It should still be the user's responsibility to check for availability for extensions before using them, but make them all available by default. An additional bonus would be the possibility of inline documentation, ideally referring to chapters in the book if available.

    Basically merge all versions together, I dunno for others, but personally I prefer 1 enum with 30 options over 3 enums with 10 each. The Sgi extensions aren't imho that bad, although they would be better legible when uppercase since it's more clear that it's the vendor name and not part of the parameter name.


  2. Some random quotes:
    (TextureTarget) Version13.TextureCubeMapPositiveX   & Co.
    (TextureTarget) Version13.TextureCubeMap
    (EnableCap) Version13.TextureCubeMap // yes, this is correct. it's both Texturetarget and Enablecap
    (GetTextureParameter) Version13.TextureCompressed
    (TextureParameterName) Version12.TextureBaseLevel
    (TextureParameterName) Version12.TextureMaxLevel
    Glu.Build2DMipmap(TextureTarget, (int) PixelInternalFormat, ....  // cast

    Not really exotic functionality, mostly from the port of my DDS manager to OpenTK. I've never really liked DevIL's behaviour when working with dds files (namely no ability to flip images) and made the manager completely independent from Tao by writing a custom dds loader that can handle flipping images upside-down for OpenGL. This allows for future inclusion of loading cube maps or volume textures and eases adding formats besides S3TC, like ATi's 3Dc Normal formats or the GF8 Lumina formats.

  3. I've also noticed that many of the SGI extensions have the same hex-value as their core/ARB pendants, i'd recommend to comment out all duplicate tokens. Here's an example of what I had in mind:

    From current Enums.cs from OpenTK 3.13

    GetTextureParameter.TextureMaxLevelSgis = ((int)SgisTextureLod.TextureMaxLevelSgis)
    TextureTarget.TextureMaxLevelSgis = ((int)SgisTextureLod.TextureMaxLevelSgis) // incorrect TextureTarget, should be in TextureParameterName, same for LOD
    SgisTextureLod.TextureMaxLevelSgis = ((int)0x813d)
    SgisTextureLod.TextureMaxLevel = ((int)0x813d)
    Version12.TextureMaxLevel = ((int)0x813d)
    All.TextureMaxLevelSgis = ((int)0x813d)
    All.TextureMaxLevel = ((int)0x813d)

    What I had in mind:

    // This enum is the only one where actual values are assigned.
    public enum All : int
    TextureMaxLevel = 0x813d;
    TextureMaxLevelSGI = 0x813d; // add this at all for compatibility? Noone would ever use it imho, since there's the v1.2 core one.
    // These enums ideally never assign any numbers, they take them from All-enum
    public enum TextureParameterName : int
    TextureMaxLevel = (int) All.TextureMaxLevel;
    public enum GetTextureParameter : int
    TextureMaxLevel = (int) All.TextureMaxLevel;

    What do you think?

    I don't know really how much your generator can help here, but If the All-enum could be sorted by ascending/descending values, it'd be pretty simple to find duplicate tokens (there's really no point keeping the SGI ones in the example above, since they hold the same value. If vendor and core extensions aren't equal, they'll be listed ofcourse).
    Regarding the All-enum, I personally try to avoid it and rather find the the proper OpenTK enum as parameter. Ideally you could write programs without using that All-enum at all, but rather the specialized enums, or not?

  4. Another issue would be that some OpenTK-functions do expect a parameter from the Version15 enum (VBO), how would this be handled?
  5. "can not be attached to this post, because the disk quota of 512 KB has been reached." cannot upload any more images ><
  6. Another Enum that should be created is one defining integer types for GL.Draw(Range)Elements(Instanced), currently one function uses All, one uses Version12, etc.

    GL.Ext.DrawElementsInstance( BeginMode.Triangles, Indices.Length, ExtDrawInstanced, Indices, primcount ) is just wrong, the way I understand it that function is merely GL.DrawElements with primcount added, and returns gl_PrimitiveID in the Shader which is the current iteration of primcount. Both should use the same type enum, and as GL.DrawRangeElements. Quote from the redbook on glDrawElements: "type must be one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT"

    public enum IndexType : int
      UnsignedByte = (int) All.UnsignedByte,
      UnsignedShort = (int) All.UnsignedShort,
      UnsignedInt = (int) All.UnsignedInt
  7. One more thing I'd appreciate is if the enum OpenGL.Enums.PixelInternalFormat would contain a non-OpenGL value, which would be "Invalid = 0". In my Texture loading I do examine pixel formats, and if there is any error with TexImage the pixel format returned is 0 (which could then be compared as PixelInternalFormat.Invalid rather than comparing with (PixelInternalFormat)0.)
    Something like this would probably make sense for a few more enums, which can be queried from OpenGL and where 0 is unused.
Inertia's picture

8. GL.VertexAttribPointer currently expects a Version20 parameter, this will always lead to errors when actually using that enum instead of just casting from All-enum to it.


public enum AttribType : int
            Byte = All.Byte,
            UnsignedByte = All.UnsignedByte,
            Short = All.Short,
            UnsignedShort = All.UnsignedShort,
            Int = All.Int,
            UnsignedInt = All.UnsignedInt,
            Float = All.Float,
            Double = All.Double

Edit: ....or use the existing enum ColorPointerType

There's alot more Shader-functions using Version20 enum, does it help if I look them up and post proper enums, or do you rather verify this on your own? Or would you prefer if I don't bother you with it an go through SVN?

9. What's the policy about refactoring existing enums so the name describes it's usage a little better? Is this possible at all or will break too much?

10. Actually I'm considering to keep using 2.1 instead of GL 3.0, because
a) There's tons of code/drivers out for GL 2.1 already and GL 3.0 will probably suffer from immaturity before 2009 (i.e. driver availability, documentation in form of books). Sure, GL 2.1 will not receive any large changes anymore, but still all graphic cards built 2008/2009 will have drivers for it. It won't just vanish.
b) When sticking with VBO/FBO/Shaders and avoid fixed-functionality wherever possible, it shouldn't be too complicated writing another codepath for GL3 at some later point.
c) OpenTK makes programming GL 2.1 noticably more elegant, I've ported a few of my Tao apps now and there is no functionality in Tao.OpenGL that is missing in OpenTK. The code actually got more compact too, because I could remove alot of enums that are already given by OpenTK.
d) Window initialization and binding the entry points is alot faster in OpenTK (far less than a second in OpenTK, while ~5 seconds with Tao 2.0 bundled OpenGL.)
e) I do like Immediate Mode. Especially when prototyping something quickly (like the ms3d loader and torusknots in it's early stages) I don't want to be bothered with providing a nicely formated input for VBOs.
f) These are just a few to mention, essentially it all boils down to GL 2 isn't that bad, it just requires a cleanup.

The main reason why I was looking forward to GL3 so bad, was due to Tao.OpenGL and the sheer volume of defined constants and that it's not always obvious which are valid parameters for a function. Sure, you will recall parameters you read about or used already, but honestly I do not remember all valid pixelformats that TexImage accepts. This is where OpenTK shines, the enums are restricting the options in a very intelligent way. You just cannot pass invalid parameters to a function, unless you (explicit) cast to it, which makes these kinds of problems easy to spot.

P.S. These enums aren't critical problems, but I think it's better to correct them now than waiting 3 months with it and breaking the applications built within those 3 months.

the Fiddler.'s picture

Wow, lots of material here. Let's see:

[1. Naming]
AFAIK the idea in the original specs was that enums defined in one version wouldn't be updated on later revisions. That's why there are things such as the Version15 enum, when several of its values should appear in more specific enum types. (It seems this rule was introduced by the ARB, so earlier SGI enums are littered everywhere)

I don't think it's a good idea to capitalize SGI, ARB etc in enums (against the naming conventions), but I'll add a rule to omit the SGI member if a plain one with the same name exists (see also [3])

[2. More naming]
The reason for these is the same as above (these enums were added later). If we say that OpenTK targets GL2.1 (and I think this is reasonable), we can just go in and update the original enums. It's a lot of work, but it can be done gradually.

[3. Enum members]
It would be possible to use the All enum to define everything, but a) the current way works and b) the user would never see the difference anyway. It is easy to drop duplicate entries though (prefer the plain one over any SGI, ARB etc when both appear), so I'll add that.

[4. GL enums in OpenTK functions]
Undecided... Probably create a new enum outside the GL class, but I'm leaving that for GL3.0. What do you think?

[5. Attachment limit]
Space limitations, unfortunately. Try hotlinking from some other server (use the img tag).

[6. GL.Draw(Range)Elements(Instanced)]
I'll have to check the manual, but it isn't unlikely that the .specs define the function incorrectly (the error wouldn't show up in the C-headers, so it went unnoticed).

[7. Invalid member]
Pretty easy to fix. If you know of any other such functions, post and I'll fix them.

[8. Shader-related functions and the All enum]
It seems the policy was changed around that time, for reasons unknown. These should all have actual enums (or at least Version20 etc) - if you can find the correct types, I'd be very grateful! I'll be adding those as time permits.

[9. Even more naming :)]
Well, if something is blatanly wrong or the name is misleading, ok. Otherwise, probably best left as is, to avoid breaking programs.

10. GL2.1, agreed. Personally I find the "clean start" as the biggest feature of GL3.0, but who knows when it will become a viable development platform.

Actually the biggest reason I started working on OpenTK was because I felt programming OpenGL could be so much nicer. Most of the hard work is done now (the generator takes care of most glaring problems/inconsistencies), so we just need to clean up the source material to provide a more intuitive API. One more reason to do this sooner rather than later, is to move the library in beta status and attract more users (and potential developers :) )

objarni's picture

About "breaking changes": as a developer I hardly see renaming things to a more natural name as a problem; I'd really trade the approved readability for making some small updates in my code base.

Of course, it is useful to know how many program actually use OpenTK right now. How many do you know of? Also, it is fruitful to think of the KIND of programs OpenTK is used for: most prominently games. Games, and especially casual/small games, are fresh meat meaning they will not be used for more than one year approximately. It is a whole different thing if developing a database system/library (eg. mysql) -- where the applications using the library live for decades. In such a library it would be much more important to have a "stable" API.

So as a (causal) games developer using OpenTK, please do rename stuff that is named badly! It is NO problem. Especially now when OpenTK is still in a alpha-development phase! (better sooner than later..)

Inertia's picture

1. Maybe tweak the rule so it comments out all duplicates starting at the top of the hierarchy core->arb->ext->vendor. (assuming value is really equal)
This pretty much answers 2 & 3. Thanks. defining only values in All-enum was just an idea so one could go through the list by hand finding duplicates.

4&8. In my opinion all Version 12-21 enums should be removed, as in put in appropriate enums for each function.

5. maybe you should cleanup that folder then, I had uploaded the image twice and deleted one. I'll fix a jpg version of the primitive table later.

6. The function is defined correctly, just the enum "ExtDrawInstanced" is misleading. See original post

7. Will do :)

What I wanted to suggest is refactoring BeginMode into something more appropriate like GeometryType or PrimitiveType. This will still make sense when used with GL.Begin and definitely looks better with GL.Draw*

the Fiddler.'s picture

I'll clean the folder up, but I'm still trying to find out why deleting attachments doesn't reclaim space. I'll also do something about space limitations on content posted on the manual.

Inertia's picture

Thanks, one more question though. You don't want to include texture manager into OpenTK, but how about texture loaders? Well, it's basically only 1 Function

 public static uint LoadImageDDS( string filename, bool flipimage, out TextureTarget result )

Some restrictions apply tho (only compressed DDS)