We now actively track how far behind / in front of an
ideal timestep we are during each frame, and try to
catch up / delay approximate this timing.
Therefore we use more precise timers and sleep functions
(nanosleep if available). We also delay **before** the
final buffer swap so the frame displays at more consistent
points in time.
Not only should this provide a somewhat more consistent
looking map scrolling at lower frame rates, it also
guarantees that we don't fall out of sync eg. with the
Audio during longer cutscenes.
'Graphics.frameReset()' now finally has a function, in
that it resets the ideal timestep approximation, which I
beliefe was also its job in the original RMXP engine.
I'm not sure how well this will work when the frame rate
is set to the monitor refresh rate and vsync is turned on.
Very likely unnecessary frame skips will occur here and there
due to imprecise timers. In the future we should probably
check if the frame rate is equal to or higher than the
monitor rate, and disable frame skip accordingly.
These changes currently break the F2 FPS display (it shows
a value that's slightly too high).
Releasing a Tilemap atlas into the pool on every map switch
will blow out tons of smaller textures for very little gain,
as atlas textures are already pretty much impossible to
recycle anywhere but in new Tilemaps.
This reverts commit 34d4103111.
Turns out we need at least GLSL 1.50, for which we'd
have to throw our OpenGL 2.0 compatibility in the water.
Nope, not yet.
Using "SDL2/SDL_xxx.h" instead of "SDL_xxx.h" caused
the include paths provided by pkg-config to be ignored,
and headers from a standard include path to be used instead.
If consecutive scanrows in the scene list have no foreign
elements in between them, we batch them up and draw them
in one glDrawElements() call.
This should reduce the Tilemap induced draw calls on
average by at least 50 percent.
This should be almost as fast as reading unencrypted
files from disk now. I also don't see any possible further
optimizations, so this is probably as fast as it gets.
This implementation is also heaps better than the old
one as it doesn't use a (differently sized) aux texture,
meaning the Bitmap discards its old texture and aquires
one of same size, making reuse through the TexPool a
lot more likely. It also saves on the aux texture blits
and binding switches.
As the setup / resource acquisition far outweighs the
actual rendering cost, operation time is relatively
constant no matter how many divisions are used.
This should make graphics.cpp somewhat easier to navigate/read.
GL_EXT_timer_query is also made optional, and if it's not present
dummy functions will be called instead.
The 'tainted' area of a Bitmap describes what parts are no
longer in a 'cleared' state. When we blit to a fully cleared
are of a Bitmap at full opacity, we can completely disregard
the existing pixels in the operation, meaning we can skip any
blending calculations and just blit / upload straight to the
texture. This greatly speeds up text message rendering.
In the process, pixman has become a new dependency for mkxp,
but the results of this optimization are well worth it!
The atlas packing algorithm has been reworked to pack autotiles
and tileset very efficiently into a texture, splitting the tileset
in multiple ways and eliminating the previous duplication of image
data in the atlas across "frames". Animation, which these frames
were designed for, is now done via duplicated buffer frames,
ie. each animation frame has its own VBO and IBO data. This was
not done to save on VRAM (hardly less memory is used), but to
make place for the new atlas layout.
Thanks to this new layout, even with a max texture size of 2048,
one can use tilesets with up to 15000 height. Of course, such
a tileset couldn't be stored in a regular Bitmap to begin with,
which is why I also introduced a hack called "mega surfaces":
software surfaces stored in RAM and wrapped inside a Bitmap,
whose sole purpose is to be passed to a Tilemap as tilesets.
Various other minor changes and fixes are included.
The drawing is now completely shader based, which makes away
with all usage of the depracted matrix stack. This also allows
us to do things like simple translations and texture coordinate
translation directly instead of doing everything indirectly
through matrices.
Fixed vertex attributes ('vertexPointer()' etc) are also
replaced with user defined attribute arrays.