1
0
Fork 0
mirror of https://git.coom.tech/drummyfish/raycastlib.git synced 2024-11-21 20:29:59 +01:00

Improve texture performance! (scaling)

This commit is contained in:
Miloslav Číž 2019-09-30 17:15:54 +02:00
parent 6424dba6d2
commit 784b3f8a49

View file

@ -26,7 +26,7 @@
author: Miloslav "drummyfish" Ciz author: Miloslav "drummyfish" Ciz
license: CC0 1.0 license: CC0 1.0
version: 0.84 version: 0.85
*/ */
#include <stdint.h> #include <stdint.h>
@ -89,14 +89,6 @@
slightly slower if on). */ slightly slower if on). */
#endif #endif
#ifndef RCL_ACCURATE_WALL_TEXTURING
#define RCL_ACCURATE_WALL_TEXTURING 0 /**< If turned on, vertical wall texture
coordinates will always be calculated
with more precise (but slower) method,
otherwise RCL_MIN_TEXTURE_STEP will be
used to decide the method. */
#endif
#ifndef RCL_COMPUTE_FLOOR_DEPTH #ifndef RCL_COMPUTE_FLOOR_DEPTH
#define RCL_COMPUTE_FLOOR_DEPTH 1 /**< Whether depth should be computed for #define RCL_COMPUTE_FLOOR_DEPTH 1 /**< Whether depth should be computed for
floor pixels - turns this off if not floor pixels - turns this off if not
@ -140,15 +132,12 @@
#define RCL_CAMERA_COLL_STEP_HEIGHT (RCL_UNITS_PER_SQUARE / 2) #define RCL_CAMERA_COLL_STEP_HEIGHT (RCL_UNITS_PER_SQUARE / 2)
#endif #endif
#ifndef RCL_MIN_TEXTURE_STEP #ifndef RCL_TEXTURE_INTERPOLATION_SCALE
#if RCL_TEXTURE_VERTICAL_STRETCH == 1 #define RCL_TEXTURE_INTERPOLATION_SCALE 1024 /**< This says scaling of fixed
#define RCL_MIN_TEXTURE_STEP 12 /**< Specifies the minimum step in pixels poit vertical texture coord
that can be used to compute texture computation. This should be power
coordinates in a fast way. Smallet step of two! Higher number can look more
should be faster (but less accurate). */ accurate but may cause overflow. */
#else
#define RCL_MIN_TEXTURE_STEP 24
#endif
#endif #endif
#define RCL_HORIZON_DEPTH (11 * RCL_UNITS_PER_SQUARE) /**< What depth the #define RCL_HORIZON_DEPTH (11 * RCL_UNITS_PER_SQUARE) /**< What depth the
@ -1139,86 +1128,59 @@ static inline int16_t _RCL_drawWall(
{ {
_RCL_UNUSED(height) _RCL_UNUSED(height)
height = RCL_absVal(height);
pixelInfo->isWall = 1; pixelInfo->isWall = 1;
RCL_Unit limit = RCL_clamp(yTo,limit1,limit2); RCL_Unit limit = RCL_clamp(yTo,limit1,limit2);
RCL_Unit wallLength = RCL_absVal(yTo - yFrom - 1); RCL_Unit wallLength = RCL_nonZero(RCL_absVal(yTo - yFrom - 1));
wallLength = RCL_nonZero(wallLength);
RCL_Unit wallPosition = RCL_absVal(yFrom - yCurrent) - increment; RCL_Unit wallPosition = RCL_absVal(yFrom - yCurrent) - increment;
RCL_Unit coordStep = RCL_COMPUTE_WALL_TEXCOORDS ? RCL_Unit heightScaled = height * RCL_TEXTURE_INTERPOLATION_SCALE;
_RCL_UNUSED(heightScaled);
RCL_Unit coordStepScaled = RCL_COMPUTE_WALL_TEXCOORDS ?
#if RCL_TEXTURE_VERTICAL_STRETCH == 1 #if RCL_TEXTURE_VERTICAL_STRETCH == 1
RCL_UNITS_PER_SQUARE / wallLength ((RCL_UNITS_PER_SQUARE * RCL_TEXTURE_INTERPOLATION_SCALE) / wallLength)
#else #else
height / wallLength (heightScaled / wallLength)
#endif #endif
: 1; : 0;
pixelInfo->texCoords.y = RCL_COMPUTE_WALL_TEXCOORDS ? pixelInfo->texCoords.y = RCL_COMPUTE_WALL_TEXCOORDS ?
wallPosition * coordStep : 0; (wallPosition * coordStepScaled) : 0;
if (increment < 0) if (increment < 0)
{ {
coordStep *= -1; coordStepScaled *= -1;
pixelInfo->texCoords.y = pixelInfo->texCoords.y =
#if RCL_TEXTURE_VERTICAL_STRETCH == 1 #if RCL_TEXTURE_VERTICAL_STRETCH == 1
RCL_UNITS_PER_SQUARE - pixelInfo->texCoords.y; (RCL_UNITS_PER_SQUARE * RCL_TEXTURE_INTERPOLATION_SCALE)
- pixelInfo->texCoords.y;
#else #else
height - pixelInfo->texCoords.y; heightScaled - pixelInfo->texCoords.y;
#endif #endif
wallPosition = wallLength - wallPosition;
} }
#if RCL_ACCURATE_WALL_TEXTURING == 1 RCL_Unit textureCoordScaled = pixelInfo->texCoords.y;
if (1)
#else
if (RCL_absVal(coordStep) < RCL_MIN_TEXTURE_STEP)
/* for the sake of performance there are two-versions of the loop - it's
better to branch early than inside the loop */
#endif
{
for (RCL_Unit i = yCurrent + increment; for (RCL_Unit i = yCurrent + increment;
increment == -1 ? i >= limit : i <= limit; // TODO: is efficient? increment == -1 ? i >= limit : i <= limit; // TODO: is efficient?
i += increment) i += increment)
{ {
// more expensive texture coord computing
pixelInfo->position.y = i; pixelInfo->position.y = i;
#if RCL_COMPUTE_WALL_TEXCOORDS == 1 #if RCL_COMPUTE_WALL_TEXCOORDS == 1
#if RCL_TEXTURE_VERTICAL_STRETCH == 1
pixelInfo->texCoords.y = pixelInfo->texCoords.y =
(wallPosition * RCL_UNITS_PER_SQUARE) / wallLength; textureCoordScaled / RCL_TEXTURE_INTERPOLATION_SCALE;
#else
pixelInfo->texCoords.y = (wallPosition * height) / wallLength;
#endif
#endif
wallPosition += increment; textureCoordScaled += coordStepScaled;
RCL_PIXEL_FUNCTION(pixelInfo);
}
}
else
{
for (RCL_Unit i = yCurrent + increment;
increment == -1 ? i >= limit : i <= limit; // TODO: is efficient?
i += increment)
{
// cheaper texture coord computing
pixelInfo->position.y = i;
#if RCL_COMPUTE_WALL_TEXCOORDS == 1
pixelInfo->texCoords.y += coordStep;
#endif #endif
RCL_PIXEL_FUNCTION(pixelInfo); RCL_PIXEL_FUNCTION(pixelInfo);
} }
}
return limit; return limit;
} }