Optimize rendering

This commit is contained in:
Miloslav Ciz 2025-04-24 16:55:35 +02:00
parent c22f17ef8c
commit 5265552c57
8 changed files with 117 additions and 89 deletions

View file

@ -10,6 +10,9 @@
Some comments:
- The module uses small3dlib, a tiny software rasterization library. This
module knows nothing about I/O (windows, canvases, ...), it just say where
to draw pixels and what colors they should have.
- The map 3D model is divided into 4x4x4 chunks, i.e. 64 in total, out of
which only 8 are loaded at any time, depending on where the camera is and
where it is looking. This is to save resources, we don't draw the far away
@ -17,6 +20,10 @@
- Extremely simple LOD of far away chunks is implemented: we keep an 8x8x8
bit array of where there is empty space and where there is "something", then
for far away areas with "something" we just draw some 2D rectangles.
- RENDERING IS THE BOTTLENECK OF PERFORMANCE, it takes even much more time
than physics simulation, i.e. care should be taken to make code here very
optimized, namely the _LCR_pixelFunc3D function, as it is called for every
rasterized pixel.
*/
#define S3L_RESOLUTION_X LCR_EFFECTIVE_RESOLUTION_X
@ -108,12 +115,12 @@ struct
// pixel function precomputed values:
uint32_t previousTriID;
int triUVs[6];
int texSubsampleCount;
unsigned int flatAndTransparent; /**< If non-zero, transparent (dithered)
polygons will be drawn without texture,
with color stored in this variable. */
uint_fast16_t texSubsampleCount;
uint_fast16_t flatAndTransparent; /**< If non-zero, transparent (dithered)
polygons will be drawn without texture,
with color stored in this variable. */
#if LCR_SETTING_PARTICLES
uint16_t particleColor; /**< 0x0000 means no particles active. */
uint_fast16_t particleColor; /**< 0x0000 means no particles active. */
#endif
} LCR_renderer;
@ -338,7 +345,7 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
LCR_gameDrawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent);
#else // LCR_SETTING_POTATO_GRAPHICS
// once we get a new triangle, we precompute things for it:
// New triangle? Precompute stuff for it:
if (pixel->triangleID != LCR_renderer.previousTriID)
{
LCR_renderer.previousTriID = pixel->triangleID;
@ -483,10 +490,14 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
}
}
/* Bottleneck: code from here below will be ran for every rasterized pixel,
optimizing it may significantly improve rendering performance. */
if (LCR_renderer.flatAndTransparent)
{
if (pixel->x % 2 == pixel->y % 2)
LCR_gameDrawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent);
if ((pixel->x % 2) == (pixel->y % 2))
LCR_gameDrawPixelXYUnsafe(
pixel->x,pixel->y,LCR_renderer.flatAndTransparent);
else
S3L_zBufferWrite(pixel->x,pixel->y,S3L_MAX_DEPTH);
/* ^ Clear z-buffer if we didn't draw the pixel. Without this further
@ -1034,8 +1045,7 @@ uint8_t _LCR_buildMapModel(void)
LCR_IMAGE_WALL_CONCRETE : LCR_IMAGE_WALL_WOOD;
}
else
{ // TODO: tidy this mess?
{
if (LCR_mapBlockIsAccelerator(blockType))
triData |= LCR_IMAGE_GROUND_ACCEL;
else if (LCR_mapBlockIsFan(blockType))