Defenestrate the bifurcators!

More API work, moving over

This update summarizes the progress during the last two weeks. Most of the work involved moving code to use the new renderer subsystem, but there was still some API work (in particular, a shader API).

API additions


Some Stellarium code requires direct usage of shaders, and I expect the amount of this code will only increase. However, shaders are an implementation detail of a Renderer backend and might differ significantly between backends (e.g. GLSL for OpenGL2/ES, HLSL for DirectX, nothing for GL1 or some custom DSL for a software renderer).

Instead of attempting to wrap all of these behind a completely generic “Shader” interface, StelRenderer can report whether it supports GLSL or not and if it does, it can create a GLSL shader - StelGLSLShader interface, which might be implemented differently between different GL based backends (in our case, StelQGLGLSLShader). This is because a generic Shader would require user code to supply shader code for any supported shader format. The user can check if GLSL is supported, if not (GL1), use shader-less code (which will work with any backend, regardless of shader support, as e.g. a GL2 backend will handle it using shaders internally), and have optional shader-based code used when GLSL is supported. If ever needed, a check for HLSL support and a HLSL shader API can be added in future.

Before drawing with a shader, the shader must be bound, which, in case of the GL2 backend, overrides default internal shaders. It also must be released after drawing to reenable default shaders.

API-wise, it is a simplified version of Qt’s QGLShader allowing to set uniforms with Stellarium data types such as Vec3f, even automatically handling transposition for matrices. Attributes are part of the vertex buffer and are set internally by the backend. Only vertex and fragment shaders are supported, but geometry shaders can be added once needed (although they should only be optional).

Other Renderer API changes

I’ve added a StelCircleArcRenderer class which handles circle arc drawing logic (previously in StelPainter) on top of *StelRenderer. The logic is basically unchanged, with slight documentation improvements. It would be good to revisit it later to add caching or further simplifications.

StelRenderer now has text drawing functionality (drawText(), setFont()). As text drawing has many optional parameters, which previously caused unreadable argument lists, a builder struct was used to emulate optional/named arguments, e.g:

renderer->drawText(TextParams(16, 16 "Hello World!").angleDegrees(30.0f).shift(8.0f, 4.0f));

I’ve’ split StelRenderer::drawRect() into drawRect() and drawTexturedRect() for more self-documenting code and to decrease number of parameters. These replace all variations of StelPainter::drawRect2d() and StelPainter::drawSprite2d(), even supporting rotation (around the center of the rectangle, which is what drawSprite2d() handled previously). Previously, drawRect2d() had many versions which made it difficult to read at call site, and drawSprite2d() had very similar functionality, except that it supported rotation and only worked with texturing.


Most of the work was moving code to the new Renderer subsystem, in particular, the code in src/core/modules . Most of these classes are based on the StelModule interface. To avoid (de-facto) singletonification of StelRenderer (which would make any future refactorings more difficult), a StelRenderer pointer is now passed through the StelModule::draw() function.

The following classes were ported:

  • StelSkyImageTile
  • StelSkyPolygon
  • TrailGroup
  • Nebula/NebulaMgr
  • Atmosphere (this required the shader API)
  • Meteor/MeteorMgr (which previously didn’t seem to be drawn)
  • ZoneArray
  • StarMgr
  • LabelMgr
  • Constellation/ConstellationMgr (work in progress)

There are still more classes that need to be ported here, as well as in plugins.

I noticed that the GeodesicGridDrawer class is never used and doesn’t conform to the StelModule API - it only compiles because StelModule member functions have default empty implementations. I.e; it seems unmaintained.

Meteor drawing didn’t work before the move, but I’m not sure if this is still the case in trunk.

Many of these classes are rather poorly documented/messy, and could use more refactoring. (Again, Meteor, for example the train data member can’t be set from outside and seems like a premature optimization.)

Other changes

  • Added the line strip primitive type.
  • StelSphereGeometry contained a stubbed SphericalTexturedPolygon class - this was removed.
  • StelRenderer now has a drawLine() member function.
  • Graceful failure when trying to load a non-power-of-two texture on a machine that does not support these textures.
  • Fixed some bugs in new SphericalRegion code, and implemented some previously stubbed functions.
  • Removed some now unused StelPainter code.
  • Various minor bugfixes and improvements.