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

Improve texturing

This commit is contained in:
Miloslav Číž 2018-09-22 13:19:50 +02:00
parent 5cc6ba7b25
commit e3f9b17756

View file

@ -70,6 +70,14 @@
2: octagonal approximation (LQ) */ 2: octagonal approximation (LQ) */
#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
@ -116,8 +124,8 @@
#ifndef RCL_MIN_TEXTURE_STEP #ifndef RCL_MIN_TEXTURE_STEP
#define RCL_MIN_TEXTURE_STEP 12 /**< Specifies the minimum step in pixels that #define RCL_MIN_TEXTURE_STEP 12 /**< Specifies the minimum step in pixels that
can be used to compute texture coordinates in can be used to compute texture coordinates in
a fast way. Smallet step will trigger a more a fast way. Smallet step should be faster
expensive way of computing texture coords. */ (but less accurate). */
#endif #endif
#define HORIZON_DEPTH (12 * RCL_UNITS_PER_SQUARE) /**< What depth the horizon #define HORIZON_DEPTH (12 * RCL_UNITS_PER_SQUARE) /**< What depth the horizon
@ -961,7 +969,6 @@ RCL_Unit RCL_adjustDistance(RCL_Unit distance, RCL_Camera *camera,
// ^ prevent division by zero // ^ prevent division by zero
} }
static inline int16_t _drawWall( static inline int16_t _drawWall(
RCL_Unit yCurrent, RCL_Unit yCurrent,
RCL_Unit yFrom, RCL_Unit yFrom,
@ -985,7 +992,13 @@ static inline int16_t _drawWall(
pixelInfo->texCoords.y = RCL_COMPUTE_WALL_TEXCOORDS ? pixelInfo->texCoords.y = RCL_COMPUTE_WALL_TEXCOORDS ?
wallPosition * coordStep : 0; wallPosition * coordStep : 0;
if (coordStep < RCL_MIN_TEXTURE_STEP) // two-version loop #if RCL_ACCURATE_WALL_TEXTURING == 1
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?
@ -1024,9 +1037,6 @@ static inline int16_t _drawWall(
return limit; return limit;
} }
void _columnFunctionComplex(RCL_HitResult *hits, uint16_t hitCount, uint16_t x, void _columnFunctionComplex(RCL_HitResult *hits, uint16_t hitCount, uint16_t x,
RCL_Ray ray) RCL_Ray ray)
{ {
@ -1190,7 +1200,6 @@ void _columnFunctionSimple(RCL_HitResult *hits, uint16_t hitCount, uint16_t x,
{ {
int16_t y = 0; int16_t y = 0;
int16_t wallHeightScreen = 0; int16_t wallHeightScreen = 0;
int16_t coordHelper = 0;
int16_t wallStart = _RCL_middleRow; int16_t wallStart = _RCL_middleRow;
int16_t wallEnd = _RCL_middleRow; int16_t wallEnd = _RCL_middleRow;
int16_t heightOffset = 0; int16_t heightOffset = 0;
@ -1267,15 +1276,6 @@ void _columnFunctionSimple(RCL_HitResult *hits, uint16_t hitCount, uint16_t x,
wallStart = _RCL_middleRow - wallHeightScreen + heightOffset + wallStart = _RCL_middleRow - wallHeightScreen + heightOffset +
RCL_normalizedWallHeight; RCL_normalizedWallHeight;
coordHelper = -1 * wallStart;
coordHelper = coordHelper >= 0 ? coordHelper : 0;
wallEnd = RCL_clamp(wallStart + wallHeightScreen,0,
_RCL_camera.resolution.y);
// ^ intentionally allow outside screen
wallStart = RCL_clamp(wallStart,0,_RCL_camResYLimit);
} }
} }
@ -1310,46 +1310,10 @@ void _columnFunctionSimple(RCL_HitResult *hits, uint16_t hitCount, uint16_t x,
p.hit.textureCoord -= p.hit.doorRoll; p.hit.textureCoord -= p.hit.doorRoll;
#endif #endif
RCL_Unit coordStep = 1;
#if RCL_COMPUTE_WALL_TEXCOORDS == 1
p.texCoords.x = p.hit.textureCoord; p.texCoords.x = p.hit.textureCoord;
coordStep = RCL_UNITS_PER_SQUARE / RCL_nonZero(wallHeightScreen);
p.texCoords.y = coordStep * coordHelper;
#endif
if (coordStep < RCL_MIN_TEXTURE_STEP) /* instead of branching inside a y = _drawWall(y - 1,wallStart,wallStart + wallHeightScreen - 1,-1,
critical loop, have two versions of _RCL_camera.resolution.y,1,&p);
the loop and branch early (here) */
{
while (y < wallEnd)
{
// more expensive and accurate version of texture coords computation
p.position.y = y;
#if RCL_COMPUTE_WALL_TEXCOORDS == 1
p.texCoords.y = (RCL_UNITS_PER_SQUARE * coordHelper) /
RCL_nonZero(wallHeightScreen);
#endif
RCL_PIXEL_FUNCTION(&p);
++coordHelper;
++y;
}
}
else
{
while (y < wallEnd)
{
// cheaper texture coord computation
p.position.y = y;
RCL_PIXEL_FUNCTION(&p);
#if RCL_COMPUTE_WALL_TEXCOORDS == 1
p.texCoords.y += coordStep;
#endif
++y;
}
}
// draw floor // draw floor