Sanitize the spec files

Yes, I am aware that the spec file will not be migrated to a comprehensive, parseable format (XML?) during the next two decades. :slight_smile:
However, it would already be a great improvement if the spec files (and thus the API) was at least designed so one has a chance of parsing it without guessing and generating somewhat more type-safe headers.

In particular, this means:

  1. Agree on a consistent naming scheme, adhere to and enforce it. Please, for the sake of all that’s good. The official online manpages have functions and constants prefixed with “gl” (which I deem a good thing, since that’s consistent with the code you write), but the specification documents and spec files do not.
    ARB approved extensions have functions and constants that are “ARB”-postfixed in their specification files to identify them as such and not GL prefixed at the same time (please, decide for one, either GL and ARB, or neither).
    Except… when that’s not true. ARB extensions that model functionality present in a higher core version have function names identical to the identical core functions, both in the spec files and in reality. This makes sense insofar as they are indeed the same functions as their core counterparts, however, the extension name gives no hint to this, making it unnecessarily confusing, error-prone, and hard to parse.
    Most (all?) of these extensions have been amended with a comment in their “Issues” section in the mean time, but that is a poor solution. Naming these extensions differently would be less ambiguous (BRA would be a good choice to indicate that it’s really a backwards-extension, or if people find the association with female underwear too repulsive, something like BACK or DOWN or COMPAT would do too… anything that gives the user a darn clue).

([SIZE=1]all of that in principle true for non-ARB extensions as well)[/SIZE]

  1. No general (as in “GLenum in value”) parameters.
    Some functions have “sane” definitions, such as e.g. glDrawElements which has param mode BeginMode, which translates to [POINTS, LINES, LINE_LOOP, TRIANGLES…] as specified in enum.spec.
    On the other hand, glBeginTransformFeedback, which takes a subset of these same modes (but not all of them!), accepts GLenum. Which basically means that glBeginTransformFeedback(QUAD_STRIP) is perfectly valid, and even glBeginTransformFeedback(GL_QUADS | GL_LINES) (eh…?) is valid. Or, even more nonsensical, glBeginTransformFeedback(GL_TIME_ELAPSED)or glBeginTransformFeedback(GL_VERTEX_SHADER)are entirely in accordance with the spec, and the compiler has no way of detecting and raising an error. Of course the above examples robably won’t happen in this form, but it is entirely conceivable that someone accidentially feeds a harmless looking enum to the wrong function, resulting in silent failure where a compilation error could be raised.
    Assuming one wanted to write a custom “gl.h/glext.h generator” that outputs more typesafe versions of the standard headers (something I’d actually do!), this is not possible at all because the relevant information is not captured in the spec file. When encountering GLenum, what else can one use but… GLenum? Without divination powers that’s as good as it gets.

  2. No freetext #Also: or #Also in: or #Aliases … above or # … already declared in comments that hold important information without also providing that information in a structured, parseable format. It is for example needlessly complicated for a parser (and a human!) to figure out what is going on when encountering comments like “# FramebufferTextureLayer already declared in ARB_framebuffer_object” or “passthru: /* OpenGL 3.0 also reuses entry points from these extensions: */” at the end of a section.

  3. Did someone mention a XML spec would be good?

Yes, I am aware that the spec file will not be migrated to a comprehensive, parseable format (XML?) during the next two decades.

cough

Agree on a consistent naming scheme, adhere to and enforce it.

There is a common naming scheme: the name of the function is “BindBuffer”. The name for this function used by C, to avoid conflicts with other names because there’s only one way to do that in C, is glBindBuffer. A valid C++ name for it would be gl::BindBuffer.

The prefixes exist only when you’re talking about a specific language binding, not the concept of the function. This makes it possible to have a binding that doesn’t do stupid things like gl::glBindBuffer, which is redundant.

Except… when that’s not true. ARB extensions that model functionality present in a higher core version have function names identical to the identical core functions, both in the spec files and in reality. This makes sense insofar as they are indeed the same functions as their core counterparts, however, the extension name gives no hint to this, making it unnecessarily confusing, error-prone, and hard to parse.

Nonsense. Those are Core OpenGL extensions. They don’t have ARB suffixes because they are simultaneously core features and extensions.

ARB_vertex_buffer_object is not the same as the 1.5 buffer object stuff. They don’t use the same functions (glBindBufferARB vs. glBindBuffer), and the interaction between them is not specified. There is no guarantee that glBindBufferARB could take, for example, GL_UNIFORM_BUFFER.

By contrast, ARB_vertex_array_object is the same as the 3.0 vertex array object functionality. They use the same functions, they use the same enumerators, etc. When ARB_vertex_attrib_binding comes around and adds functions that change VAO state, it is automatically compatible with ARB_vertex_array_object

That’s what “core extensions” mean. And that’s why it’s important to know what is and isn’t a core extension.

The real problem is that the only way to tell that something is a core extension is to actually look at it. The spec files won’t tell you.

Naming these extensions differently would be less ambiguous (BRA would be a good choice to indicate that it’s really a backwards-extension, or if people find the association with female underwear too repulsive, something like BACK or DOWN or COMPAT would do too… anything that gives the user a darn clue).

Well they’re not going to retroactively rename over half of their ARB extensions; that would break plenty of code. They’re also not going to adopt a brand new convention, as this would make everything inconsistent (thus working against your desire for consistency).

Also, again, it’s not for backwards compatibility. It’s more for forwards compatibility: being able to use ARB_separate_shader_objects as an extension on 3.3 hardware, but as a core feature with well-defined interoperability with other extensions and core features.

As opposed to ARB_vertex_buffer_object, who’s interaction with GL_UNIFORM_BUFFER is unspecified.

the compiler has no way of detecting and raising an error.

What compiler? Certainly not a C compiler of any kind. And certainly not a C++ compiler. Not unless you put your enums in a C++11 strongly-typed enumeration or something.

In any case, while this would be nice where possible (obviously glActiveTexture can’t do it) consider the fact that it took me maybe 2-3 days of work to turn the .spec files into XML. The work it would take to collate all of this information, across innumerable extensions and functions and so forth, would be immense. You’re looking at a good month+ of 8 hour days.

If they can’t take the time to turn the .spec files into XML (and either port their processing systems to use the XML or simply have a reverse transformation process to go from the now source XML to the .spec format), then they certainly don’t have the time to collate this kind of data. This data actually was initially used in the 1.1/1.2 era, but it isn’t any anymore, due to the explosion of new functions, extension functions providing new parameters, etc. It just became too much to be able to do.

[QUOTE=Alfonse Reinheart;1244194]cough[/QUOTE]That one looks great, thank you for the link (and for the work!).

(Now of course, such a thing needs to be maintained, and it doesn’t really help if a single person is running after the entire industry while they’re still making additions in the old format for years to come, just because that’s what they’re used to. Really, as someone – you – has already done the annoying work, I see no hindrance – other than being stubborn – to finally switch toolchains and use a format that’s legible)

There is a common naming scheme: the name of the function is “BindBuffer”. The name for this function used by C, to avoid conflicts with other names because there’s only one way to do that in C, is glBindBuffer.

The reference page for your example (http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml) states:

Name
glBindBuffer — bind a named buffer object

C Specification
void glBindBuffer(GLenum target, GLuint buffer);
If my reading skills don’t fail me, what the reference page lists under “Name” has very much not the same naming convention as in the specification (PDF file).
Don’t get me wrong, I’m fine with the name and the C function prototype being the same (it’s a whole lot easier without having to “translate” in your head every time!), but it should really be the same everywhere.

By contrast, ARB_vertex_array_object
That’s one example of what I am talking about. This extension has an “ARB” name. Thus, the expected behaviour is that BindVertexArray should be called BindVertexArrayARB, since that’s what procedure names look like in an “ARB” extension. Note that my issue is not that I don’t understand the reason why this is not the case.
My issue is that it is not obvious from the name what’s going on, but it should be. Nor is there a kind of “header field” in the extension specs for that, nor is it easily readable from the GL spec file. As you correctly said: you have to know. But you should never have to know, or worse, have to guess.

What compiler? Certainly not a C compiler of any kind. And certainly not a C++ compiler. Not unless you put your enums in a C++11 strongly-typed enumeration or something.
A plain normal C++98 compiler could do such a thing, though admittedly it would take extra effort to avoid previous declaration errors in enums that have identically named members.
Readily available C++11 compilers could use strongly typed enums as you’ve correctly stated (GCC has support for that kind of thing since around 2009). However, if every type is just “GLenum” then the best compiler in the world is without power.

If my reading skills don’t fail me, what the reference page lists under “Name” has very much not the same naming convention as in the specification (PDF file).

And? The man pages are not the source documentation. The source of all of this stuff is the OpenGL specification and the .spec files. They don’t have prefixes because the prefixes are a C thing that everyone keeps assuming is the “real” name of the function.

Call me old school, but the blue book always referred glBegin, right?

  • Nigel

It’s not about “old school” or “new school”. The OpenGL specification, all extension specifications, and the related .spec files that provide these declarations, all are in agreement: it’s called [var]Begin[/var]. The “gl” prefix is very popular and common and widespread, but as far as the spec is concerned, that’s an implementation detail used to get around the lack of real namespace support in C.