commit fca4c34
shrub
·
2026-07-30 13:24:05 +0000 UTC
parent 9fd0111
licar taught me
1 files changed,
+47,
-21
+47,
-21
1@@ -15,6 +15,8 @@
2 #define S3L_MAX_HEIGHT (4096)
3
4 #define S3L_MAX_PIXELS (S3L_MAX_WIDTH * S3L_MAX_HEIGHT)
5+#define S3L_PERSPECTIVE_CORRECTION 2
6+#define S3L_NEAR_CROSS_STRATEGY 1
7 #define S3L_Z_BUFFER 1
8 #define S3L_PIXEL_FUNCTION small3dlib_pixel
9 #include <small3dlib.h>
10@@ -48,6 +50,8 @@ typedef struct {
11
12 RendererMesh* active_mesh;
13 RendererTexture* active_texture;
14+ u32 active_triangle;
15+ i32 tri_uvs[6];
16 } RendererState;
17
18 typedef struct {
19@@ -194,11 +198,12 @@ static S3L_Vec4 clip_to_screen(const ClipVertex* v)
20 float inv_w = 1.0f / v->w;
21 float ndc_x = v->x * inv_w;
22 float ndc_y = v->y * inv_w;
23- float ndc_z = v->z * inv_w;
24
25 r.x = (S3L_Unit)((ndc_x * 0.5f + 0.5f) * (float)(ren.width - 1));
26 r.y = (S3L_Unit)((0.5f - ndc_y * 0.5f) * (float)(ren.height - 1));
27- r.z = (S3L_Unit)((ndc_z * 0.5f + 0.5f) * 1048576.0f) + 1;
28+ r.z = (S3L_Unit)(v->w * (float)S3L_F);
29+ if (r.z < 1)
30+ r.z = 1;
31 r.w = S3L_F;
32
33 return r;
34@@ -206,15 +211,9 @@ static S3L_Vec4 clip_to_screen(const ClipVertex* v)
35
36 static u32 sample_texture(const RendererMesh* mesh, const RendererTexture* texture, const S3L_PixelInfo* pixel)
37 {
38- u32 tri = (u32)pixel->triangleIndex * 3;
39- const MGVertex* a = &mesh->vtc[mesh->idc[tri + 0]];
40- const MGVertex* b = &mesh->vtc[mesh->idc[tri + 1]];
41- const MGVertex* c = &mesh->vtc[mesh->idc[tri + 2]];
42- float ba = (float)pixel->barycentric[0] / (float)S3L_F;
43- float bb = (float)pixel->barycentric[1] / (float)S3L_F;
44- float bc = (float)pixel->barycentric[2] / (float)S3L_F;
45- float u = a->u * ba + b->u * bb + c->u * bc;
46- float v = a->v * ba + b->v * bb + c->v * bc;
47+ u32 tri;
48+ const MGVertex* v[3];
49+ int barycentric[3];
50 i32 x;
51 i32 y;
52 u8* texel;
53@@ -222,17 +221,40 @@ static u32 sample_texture(const RendererMesh* mesh, const RendererTexture* textu
54 if (!texture || !texture->pixels)
55 return 0xffffffff;
56
57- while (u < 0.0f)
58- u += 1.0f;
59- while (v < 0.0f)
60- v += 1.0f;
61- while (u >= 1.0f)
62- u -= 1.0f;
63- while (v >= 1.0f)
64- v -= 1.0f;
65+ if (ren.active_triangle != (u32)pixel->triangleIndex) {
66+ ren.active_triangle = pixel->triangleIndex;
67+ tri = (u32)pixel->triangleIndex * 3;
68+ v[0] = &mesh->vtc[mesh->idc[tri + 0]];
69+ v[1] = &mesh->vtc[mesh->idc[tri + 1]];
70+ v[2] = &mesh->vtc[mesh->idc[tri + 2]];
71+
72+ ren.tri_uvs[0] = (i32)(v[0]->u * (float)texture->width);
73+ ren.tri_uvs[1] = (i32)(v[0]->v * (float)texture->height);
74+ ren.tri_uvs[2] = (i32)(v[1]->u * (float)texture->width);
75+ ren.tri_uvs[3] = (i32)(v[1]->v * (float)texture->height);
76+ ren.tri_uvs[4] = (i32)(v[2]->u * (float)texture->width);
77+ ren.tri_uvs[5] = (i32)(v[2]->v * (float)texture->height);
78+ }
79
80- x = (i32)(u * (float)texture->width);
81- y = (i32)(v * (float)texture->height);
82+ /*licar taught me*/
83+ /*https://en.wikipedia.org/wiki/Barycentric_coordinate_system*/
84+ barycentric[0] = pixel->barycentric[0] / 8;
85+ barycentric[1] = pixel->barycentric[1] / 8;
86+ barycentric[2] = pixel->barycentric[2] / 8;
87+
88+ x = (barycentric[0] * ren.tri_uvs[0] +
89+ barycentric[1] * ren.tri_uvs[2] +
90+ barycentric[2] * ren.tri_uvs[4]) / (S3L_F / 8);
91+ y = (barycentric[0] * ren.tri_uvs[1] +
92+ barycentric[1] * ren.tri_uvs[3] +
93+ barycentric[2] * ren.tri_uvs[5]) / (S3L_F / 8);
94+
95+ x %= texture->width;
96+ y %= texture->height;
97+ if (x < 0)
98+ x += texture->width;
99+ if (y < 0)
100+ y += texture->height;
101
102 texel = texture->pixels + ((y * texture->width + x) * 4);
103 return ((u32)texel[0]) |
104@@ -257,6 +279,7 @@ void renderer_backend_create(MGContext* ctx)
105 ren.pass = 0;
106 ren.active_mesh = NULL;
107 ren.active_texture = NULL;
108+ ren.active_triangle = (u32)-1;
109 }
110
111 void renderer_backend_begin(void)
112@@ -309,6 +332,7 @@ void renderer_backend_destroy(void)
113 ren.ctx = NULL;
114 ren.active_mesh = NULL;
115 ren.active_texture = NULL;
116+ ren.active_triangle = (u32)-1;
117 ren.pass = 0;
118 }
119
120@@ -376,6 +400,7 @@ void renderer_backend_mesh_draw(MGMesh mesh, MGTexture texture, const MGMat4* mv
121
122 ren.active_mesh = rmesh;
123 ren.active_texture = rtexture;
124+ ren.active_triangle = (u32)-1;
125
126 for (tri = 0; tri < rmesh->ic; tri += 3) {
127 ClipVertex ca;
128@@ -403,6 +428,7 @@ void renderer_backend_mesh_draw(MGMesh mesh, MGTexture texture, const MGMat4* mv
129
130 ren.active_mesh = NULL;
131 ren.active_texture = NULL;
132+ ren.active_triangle = (u32)-1;
133 }
134
135 void renderer_backend_mesh_destroy(MGMesh id)