More modern opengl in simpledisplay, document undocumented on, tip on default template args

Posted 2020-08-24

Core D Development Statistics

In the community

Community announcements

See more at the announce forum.

What Adam is working on

Document undocumented for extern(C)

On *, undocumented functions are now included in the generated files, with a note that says "undocumented in source". (This is the existing --document-undocumented switch to adrdox, just passed by default on the website now.) If you want to rebuild your own site, just click the little "clear cache" button at the bottom of the sites, just remember it will take a while and you must leave the tab open until it is done.

The reason I made this change is to help make bindings easier to use. If you look here for example you will see a lot of undocumented extern(C) functions.

The generator now raises awareness that those bindings are actually there and how the function prototype was translated, and the auto-generated note tells you it may be possible to get more information on the web.

Hopefully, bindings authors and consumers will find this useful.

But, the reasons I didn't to this before are:

  • I sometimes explicitly leave functions undocumented because I'm not committed to supporting them. This is why it specifically says "undocumented in source" to warn users perhaps the author undocumented it for a reason.
  • It can lead to a lot of extra spam in the documentation. Authors can use private to still remove things there but I think it is useful to see it is there anyway if it is accessible.
  • It gives poor results for things like druntime with a bunch of versioned overloads being listed even though it doesn't make sense in documentation. This is a quality-of-implementation issue inside adrdox but an issue nonetheless.

Still, upon user request, I thought about it and am trying it since I think the benefits will outweigh the downsides right now. Let me know if you disagree.

Modern OpenGL in simpledisplay

A user asked me how to use a shader in simpledisplay. I described the process: set the flag, create the window, load OpenGL again with bindbc or glbindGetAddress or whatever, then do it with the glEtc functions.

Well, as I described it, I realized that's kinda a pain and I can do better... but I've never actually used a shader before. I personally am pretty happy with legacy opengl for my purposes. Heck, simpledisplay only really supports creating the modern contexts because ketmar contributed the necessary code alongside the nanovega module.

But, since it was almost there, I spent some time to take it further. See the new example in the docs:

Note arsd version 8.5 is not formally released yet so you must get the ~master branch from git instead.

The new things in that example are gl3.loadDynamicLibrary(); and the OpenGlShader class.

Since not long ago, simpledisplay loads all its graphics apis from the OS dynamically. This allows user code to detect the absence of X11 and gracefully fallback. But it also provides a nice little framework for other dynamic loads.

I write a simple interface listing the functions:

interface GL3 {
	extern(System) @nogc nothrow:

	void glGenVertexArrays(GLsizei, GLuint*);
	void glBindVertexArray(GLuint);
	void glDeleteVertexArrays(GLsizei, const(GLuint)*);
	void glGenerateMipmap(GLenum);
	// etc etc etc

Then my mixin template scans it and defines the function pointers to load, as well as the loadDynamicLibrary function you can call when you're ready.

So if there's enums and functions missing from the new bindings (and I know there are!) that you need, adding them is easy. PRs welcome!

Then, compiling the shader was tedious to translate things from C and D style, so I made the helper class for that, and a function glBufferDataSlice which just takes a D slice instead of a C pointer to simplify that a little. (I wanted to overload it with the real glBufferData function, but D won't let me overload function pointers and freestanding functions. Alas. Actually, I crashed the compiler entirely but couldn't minimize the reproduction. lol)

While this is still work in progress, as you can see in the example, modern opengl with simpledisplay is going from "possible" to "easier". But since I so rarely even care to use this, no promises as to when I'll continue developing it.

Tip of the Week

void foo(T = int, W)(W w) { } works! Yes, you can put default template arguments before implicitly inferred arguments from runtime parameters.

This means you can call it foo(5) or foo("string")... or foo!float(4) or foo!Object("string"), giving a lot of flexibility in, say, specifying a desired return type as well as parameters.

It looks weird seeing a default arg before one without a default, but it works exactly because all the ones after it are still inferred so the compiler doesn't need it specified to figure out how to use it.