@@ -324,6 +324,7 @@ void swBindTexture(uint32_t id);
324
324
#ifdef RLSW_IMPL
325
325
326
326
#include <stdlib.h>
327
+ #include <stddef.h>
327
328
#include <math.h>
328
329
329
330
/* === Defines and Macros === */
@@ -519,10 +520,10 @@ static inline float sw_lerp(float a, float b, float t)
519
520
return a + t * (b - a );
520
521
}
521
522
522
- static inline sw_vertex_t sw_lerp_vertex (const sw_vertex_t * a , const sw_vertex_t * b , float t )
523
+ static inline sw_vertex_t sw_lerp_vertex_PNTCH (const sw_vertex_t * a , const sw_vertex_t * b , float t )
523
524
{
524
525
sw_vertex_t result ;
525
- for (int i = 0 ; i < sizeof (sw_vertex_t ) / sizeof (float ); i ++ ) {
526
+ for (int i = 0 ; i < offsetof (sw_vertex_t , screen ) / sizeof (float ); i ++ ) {
526
527
((float * )& result )[i ] = sw_lerp (((float * )a )[i ], ((float * )b )[i ], t );
527
528
}
528
529
return result ;
@@ -1031,7 +1032,7 @@ static inline bool sw_triangle_clip_w(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON
1031
1032
for (int i = 0 ; i < inputCounter ; i ++ ) {
1032
1033
char currDot = (input [i ].homogeneous [3 ] < SW_CLIP_EPSILON ) ? -1 : 1 ;
1033
1034
if (prevDot * currDot < 0 ) {
1034
- polygon [(* vertexCounter )++ ] = sw_lerp_vertex (prevVt , & input [i ],
1035
+ polygon [(* vertexCounter )++ ] = sw_lerp_vertex_PNTCH (prevVt , & input [i ],
1035
1036
(SW_CLIP_EPSILON - prevVt -> homogeneous [3 ]) / (input [i ].homogeneous [3 ] - prevVt -> homogeneous [3 ]));
1036
1037
}
1037
1038
if (currDot > 0 ) {
@@ -1070,7 +1071,7 @@ static inline bool sw_triangle_clip_xyz(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYG
1070
1071
for (int i = 0 ; i < inputCounter ; i ++ ) {
1071
1072
char currDot = (input [i ].homogeneous [iAxis ] <= input [i ].homogeneous [3 ]) ? 1 : -1 ;
1072
1073
if (prevDot * currDot <= 0 ) {
1073
- polygon [(* vertexCounter )++ ] = sw_lerp_vertex (prevVt , & input [i ], (prevVt -> homogeneous [3 ] - prevVt -> homogeneous [iAxis ]) /
1074
+ polygon [(* vertexCounter )++ ] = sw_lerp_vertex_PNTCH (prevVt , & input [i ], (prevVt -> homogeneous [3 ] - prevVt -> homogeneous [iAxis ]) /
1074
1075
((prevVt -> homogeneous [3 ] - prevVt -> homogeneous [iAxis ]) - (input [i ].homogeneous [3 ] - input [i ].homogeneous [iAxis ])));
1075
1076
}
1076
1077
if (currDot > 0 ) {
@@ -1096,7 +1097,7 @@ static inline bool sw_triangle_clip_xyz(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYG
1096
1097
for (int i = 0 ; i < inputCounter ; i ++ ) {
1097
1098
char currDot = (- input [i ].homogeneous [iAxis ] <= input [i ].homogeneous [3 ]) ? 1 : -1 ;
1098
1099
if (prevDot * currDot <= 0 ) {
1099
- polygon [(* vertexCounter )++ ] = sw_lerp_vertex (prevVt , & input [i ], (prevVt -> homogeneous [3 ] + prevVt -> homogeneous [iAxis ]) /
1100
+ polygon [(* vertexCounter )++ ] = sw_lerp_vertex_PNTCH (prevVt , & input [i ], (prevVt -> homogeneous [3 ] + prevVt -> homogeneous [iAxis ]) /
1100
1101
((prevVt -> homogeneous [3 ] + prevVt -> homogeneous [iAxis ]) - (input [i ].homogeneous [3 ] + input [i ].homogeneous [iAxis ])));
1101
1102
}
1102
1103
if (currDot > 0 ) {
@@ -1162,17 +1163,13 @@ static inline void sw_triangle_project_and_clip(sw_vertex_t polygon[SW_MAX_CLIPP
1162
1163
static inline void FUNC_NAME(const sw_texture_t* tex, const sw_vertex_t* start, \
1163
1164
const sw_vertex_t* end, float yDu, float yDv) \
1164
1165
{ \
1165
- /* Calculate the horizontal width and avoid division by zero */ \
1166
- float dx = end -> screen [0 ] - start -> screen [0 ]; \
1167
- if (fabsf (dx ) < 1e-4f ) return ; \
1168
- \
1169
1166
/* Convert and center the screen coordinates */ \
1170
1167
int xStart = (int )(start -> screen [0 ] + 0.5f ); \
1171
1168
int xEnd = (int )(end -> screen [0 ] + 0.5f ); \
1172
1169
int y = (int )(start -> screen [1 ] + 0.5f ); \
1173
1170
\
1174
1171
/* Calculate the initial interpolation parameter and its increment */ \
1175
- float dt = 1.0f / dx ; \
1172
+ float dt = 1.0f / ( end -> screen [ 0 ] - start -> screen [ 0 ]); \
1176
1173
float t = (xStart - start -> screen [0 ]) * dt ; \
1177
1174
\
1178
1175
float xDu , xDv ; \
@@ -1295,20 +1292,20 @@ static inline void FUNC_NAME(const sw_vertex_t* v0, const sw_vertex_t* v1, const
1295
1292
float x1 = v1 -> screen [0 ], y1 = v1 -> screen [1 ]; \
1296
1293
float x2 = v2 -> screen [0 ], y2 = v2 -> screen [1 ]; \
1297
1294
\
1298
- /* Reject degenerate triangles */ \
1299
- float height = y2 - y0 ; \
1300
- if (height < 1e-4f ) return ; \
1295
+ /* Compute height differences */ \
1296
+ float h20 = y2 - y0 ; \
1297
+ float h10 = y1 - y0 ; \
1298
+ float h21 = y2 - y1 ; \
1301
1299
\
1302
- /* Precompute the inverse of the triangle height and */ \
1303
- /* edge lengths with checks to avoid division by zero. */ \
1304
- float inv_height = 1.0f / height ; \
1305
- float inv_y1y0 = (y1 - y0 > 1e-4f ) ? 1.0f / (y1 - y0 ) : 0.0f ; \
1306
- float inv_y2y1 = (y2 - y1 > 1e-4f ) ? 1.0f / (y2 - y1 ) : 0.0f ; \
1300
+ /* Precompute the inverse values without additional checks */ \
1301
+ float invH20 = (h20 > 1e-6f ) ? 1.0f / h20 : 0.0f ; \
1302
+ float invH10 = (h10 > 1e-6f ) ? 1.0f / h10 : 0.0f ; \
1303
+ float invH21 = (h21 > 1e-6f ) ? 1.0f / h21 : 0.0f ; \
1307
1304
\
1308
1305
/* Pre-calculation of slopes (dx/dy) */ \
1309
- float dx02 = (x2 - x0 ) * inv_height ; \
1310
- float dx01 = (x1 - x0 ) * inv_y1y0 ; \
1311
- float dx12 = (x2 - x1 ) * inv_y2y1 ; \
1306
+ float dx02 = (x2 - x0 ) * invH20 ; \
1307
+ float dx01 = (x1 - x0 ) * invH10 ; \
1308
+ float dx12 = (x2 - x1 ) * invH21 ; \
1312
1309
\
1313
1310
/* Y bounds (vertical clipping) */ \
1314
1311
int yTop = (int )(y0 + 0.5f ); \
@@ -1318,8 +1315,8 @@ static inline void FUNC_NAME(const sw_vertex_t* v0, const sw_vertex_t* v1, const
1318
1315
/* Global calculation of vertical texture gradients for the triangle */ \
1319
1316
float yDu , yDv ; \
1320
1317
if (ENABLE_TEXTURE ) { \
1321
- yDu = (v2 -> texcoord [0 ] - v0 -> texcoord [0 ]) * inv_height ; \
1322
- yDv = (v2 -> texcoord [1 ] - v0 -> texcoord [1 ]) * inv_height ; \
1318
+ yDu = (v2 -> texcoord [0 ] - v0 -> texcoord [0 ]) * invH20 ; \
1319
+ yDv = (v2 -> texcoord [1 ] - v0 -> texcoord [1 ]) * invH20 ; \
1323
1320
} \
1324
1321
\
1325
1322
/* Initializing scanline variables */ \
@@ -1328,45 +1325,71 @@ static inline void FUNC_NAME(const sw_vertex_t* v0, const sw_vertex_t* v1, const
1328
1325
\
1329
1326
/* Scanline for the upper part of the triangle */ \
1330
1327
for (int y = yTop ; y < yMiddle ; y ++ ) { \
1328
+ \
1329
+ /* Discard the lines that are degenerate */ \
1330
+ if (fabsf (xRight - xLeft ) <= 1e-6f ) { \
1331
+ goto discardTL ; \
1332
+ } \
1333
+ \
1334
+ /* Calculation of interpolation factors */ \
1331
1335
float dy = (float )y - y0 ; \
1332
- float t1 = dy * inv_height ; \
1333
- float t2 = dy * inv_y1y0 ; \
1336
+ float t1 = dy * invH20 ; \
1337
+ float t2 = dy * invH10 ; \
1334
1338
\
1335
1339
/* Vertex interpolation */ \
1336
- start = sw_lerp_vertex (v0 , v2 , t1 ); \
1337
- end = sw_lerp_vertex (v0 , v1 , t2 ); \
1340
+ start = sw_lerp_vertex_PNTCH (v0 , v2 , t1 ); \
1341
+ end = sw_lerp_vertex_PNTCH (v0 , v1 , t2 ); \
1338
1342
start .screen [0 ] = xLeft ; \
1339
1343
start .screen [1 ] = (float )y ; \
1340
1344
end .screen [0 ] = xRight ; \
1341
1345
end .screen [1 ] = (float )y ; \
1342
1346
\
1343
- if (xLeft > xRight ) { sw_vertex_t tmp = start ; start = end ; end = tmp ; } \
1347
+ if (xLeft > xRight ) { \
1348
+ sw_vertex_t tmp = start ; \
1349
+ start = end ; \
1350
+ end = tmp ; \
1351
+ } \
1352
+ \
1344
1353
FUNC_SCANLINE (tex , & start , & end , yDu , yDv ); \
1345
1354
\
1346
1355
/* Incremental update */ \
1356
+ discardTL : \
1347
1357
xLeft += dx02 ; \
1348
1358
xRight += dx01 ; \
1349
1359
} \
1350
1360
\
1351
1361
/* Scanline for the lower part of the triangle */ \
1352
1362
xRight = x1 ; /* Restart the right side from the second vertex */ \
1353
1363
for (int y = yMiddle ; y < yBottom ; y ++ ) { \
1364
+ \
1365
+ /* Discard the lines that are degenerate */ \
1366
+ if (fabsf (xRight - xLeft ) <= 1e-6f ) { \
1367
+ goto discardBL ; \
1368
+ } \
1369
+ \
1370
+ /* Calculation of interpolation factors */ \
1354
1371
float dy = (float )y - y0 ; \
1355
- float t1 = dy * inv_height ; \
1356
- float t2 = (float )(y - y1 ) * inv_y2y1 ; \
1372
+ float t1 = dy * invH20 ; \
1373
+ float t2 = (float )(y - y1 ) * invH21 ; \
1357
1374
\
1358
1375
/* Vertex interpolation */ \
1359
- start = sw_lerp_vertex (v0 , v2 , t1 ); \
1360
- end = sw_lerp_vertex (v1 , v2 , t2 ); \
1376
+ start = sw_lerp_vertex_PNTCH (v0 , v2 , t1 ); \
1377
+ end = sw_lerp_vertex_PNTCH (v1 , v2 , t2 ); \
1361
1378
start .screen [0 ] = xLeft ; \
1362
1379
start .screen [1 ] = (float )y ; \
1363
1380
end .screen [0 ] = xRight ; \
1364
1381
end .screen [1 ] = (float )y ; \
1365
1382
\
1366
- if (xLeft > xRight ) { sw_vertex_t tmp = start ; start = end ; end = tmp ; } \
1383
+ if (xLeft > xRight ) { \
1384
+ sw_vertex_t tmp = start ; \
1385
+ start = end ; \
1386
+ end = tmp ; \
1387
+ } \
1388
+ \
1367
1389
FUNC_SCANLINE (tex , & start , & end , yDu , yDv ); \
1368
1390
\
1369
1391
/* Incremental update */ \
1392
+ discardBL : \
1370
1393
xLeft += dx02 ; \
1371
1394
xRight += dx12 ; \
1372
1395
} \
0 commit comments