Instead of making the user count lines from the shader log, we'll now
emit #line directives and a file number->name mapping to make it easier
to figure out which file and line the error message comes from.
Replace the hardcoded VAI_ constants with that. The VAI constants are now
moved to C4DrawGL as C4SSA_ constants, similar to the C4SSU ones. This allows
to introduce other attributes to replace vertex positions, normals, colors
and texture coordinates with attributes in later commits. This, in turn, is
needed because the built-in attributes are no longer available in the OpenGL
core profile.
Also, while at it, cleanup C4Shader a bit. Use std::vector<> instead of
maintaining an own array of uniform names. Delete the vertex and fragment
objects after the full shader program has been linked. Make sure that
C4Shader::Init keeps the old program in place if the new one cannot be
compiled or linked.
The C++ standard library comes with perfectly fine implementations of
these functions, so there's no point in reimplementing them just for the
hell of it.
The solution is slightly hacky and not entirely stable, but for fine-
tuning this functionality is essential.
While I was at it, also reduced refresh interval so it doesn't have a
chance to lag the game.
For whatever reason, the shader code that was passed to the compiler was
different from the code that got written to the shader log. This is a
huge pain in the ass when trying to debug shader errors because the line
information is completely wrong. I assume this decision was a premature
optimization, so I've removed it and we'll now log the exact same code
as the shader compiler sees.
Several rendering changes have resulted in a non-rendering build that
failed to build from source. Dummy out all of these functions to make it
work again.
Doing skinning on the GPU shows a noticeable performance improvement in
pretty much any situation, but especially so in scenes with lots of
animated objects with high polygon counts.
Calling CStdGL::CheckGLError calls glGetError, which is really, really
slow because it has to flush the pipeline to check whether there's an
error or not. Plus it's not like we can do anything about it anyway. If
you want to be notified when an error happens, pass --debug-opengl to
the executable.
Instead of transforming all vertices on the CPU every time an animation
progresses, we now only recalculate the skeleton, leaving the heavy
lifting for the GPU. This also means we no longer have to push all
vertices onto the bus every frame, because the mesh isn't changing and
can therefore be stored in a GL_STATIC_DRAW VBO when it's first loaded.
The downside of this approach is that there's only a limited number of
uniforms and vertex attributes we can pass to the shader. At the moment
these limits are a maximum of 128 bones per skeleton, and no vertex can
be influenced by more than 8 bones at once. So far this is no problem,
as the most complex skeleton in the base game uses less than 64 bones
and no more than 6 bone weights per vertex.
gluErrorString returns latin-1 encoded strings. Our code expects to
receive UTF-8 encoded strings everywhere, so make sure that the strings
are converted before passing them on.
This allows to ignore slice declarations using `#define slice(x)`, which
mill be useful for custom mesh material shaders, allowing to write them
such that they can be used standalone in a mesh viewer but also as slices
for OpenClonk, in which case lighting and color modulation will be applied
automatically.
Turns out we actually can't optimise out the second texture normal
lookup - it makes a noticeable difference in-game. Also there was
possible slice collision, it might be worth warning about this kind
of stuff.
Also removed unused variable, and made error messages more consistent
in terms of whitespace.
The idea here is that we compose shaders out of "slices", which can
come from the engine ("built-in"), from files or possibly even from
models. This should allow us to more easily share the code between
different rendering shaders (e.g. for lights / normals).
TODO: Workarounds not yet implemented, so this might degrade less
gracefully.