diff --git a/README.md b/README.md index 49b7324..29963a4 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,12 @@ - **Rust nightly** (edition 2024) - Required for [pxl8d](pxl8d) server - **SDL3** - System package or auto-vendored -## License +### License pxl8 is free and open source. All code in this repository is licensed under: - Mozilla Public License, Version 2.0 ([LICENSE](LICENSE) or https://mozilla.org/MPL/2.0/) -Third-party dependencies (Fennel, linenoise, LuaJIT, miniz, SDL3) retain their original licenses. -
@@@@@@@@@@@@@@@@@@@@@**^^""~~~"^@@^*@*@@**@@@@@@@@@
@@@@@@@@@@@@@*^^'"~ , - ' '; ,@@b. ' -e@@@@@@@@@
diff --git a/demo/mod/first_person3d.fnl b/demo/mod/first_person3d.fnl
index 81d25be..bc3fa85 100644
--- a/demo/mod/first_person3d.fnl
+++ b/demo/mod/first_person3d.fnl
@@ -343,7 +343,7 @@
(pxl8.push_target)
(pxl8.begin_frame_3d camera lights {
- :ambient 25
+ :ambient 2
:dither true
:fog_density 0.0
:celestial_dir [0.5 -0.8 0.3]
diff --git a/pxl8d/src/procgen.rs b/pxl8d/src/procgen.rs
index f6fb97e..a344792 100644
--- a/pxl8d/src/procgen.rs
+++ b/pxl8d/src/procgen.rs
@@ -533,8 +533,9 @@ fn compute_vertex_light(
let light_dir = to_light.normalize();
let ndotl = normal.dot(light_dir).max(0.0);
- let attenuation = (1.0 - dist / light.radius).max(0.0);
- let attenuation = attenuation * attenuation;
+ let dist_sq = to_light.dot(to_light);
+ let radius_sq = light.radius * light.radius;
+ let attenuation = (1.0 - dist_sq / radius_sq).max(0.0);
total += light.intensity * ndotl * attenuation;
}
@@ -1056,7 +1057,7 @@ pub fn generate_rooms(params: &ProcgenParams) -> Bsp {
Some(LightSource {
position: Vec3::new(cx, light_height, cz),
- intensity: 1.8,
+ intensity: 1.5,
radius: 160.0,
})
}).collect();
diff --git a/src/gfx/pxl8_gfx.h b/src/gfx/pxl8_gfx.h
index 81b83cf..196b486 100644
--- a/src/gfx/pxl8_gfx.h
+++ b/src/gfx/pxl8_gfx.h
@@ -21,6 +21,14 @@ typedef struct pxl8_gfx_stats {
u64 triangles;
} pxl8_gfx_stats;
+enum {
+ PXL8_CLIP_INSIDE = 0,
+ PXL8_CLIP_LEFT = 1,
+ PXL8_CLIP_RIGHT = 2,
+ PXL8_CLIP_BOTTOM = 4,
+ PXL8_CLIP_TOP = 8,
+};
+
typedef enum pxl8_gfx_effect {
PXL8_GFX_EFFECT_GLOWS = 0,
} pxl8_gfx_effect;
diff --git a/src/gfx/pxl8_render.c b/src/gfx/pxl8_render.c
index ee7954a..76417e7 100644
--- a/src/gfx/pxl8_render.c
+++ b/src/gfx/pxl8_render.c
@@ -630,10 +630,18 @@ static void rasterize_triangle(
}
}
+static inline u8 clip_outcode(i32 x, i32 y, i32 xmin, i32 ymin, i32 xmax, i32 ymax) {
+ u8 code = PXL8_CLIP_INSIDE;
+ if (x < xmin) code |= PXL8_CLIP_LEFT;
+ else if (x > xmax) code |= PXL8_CLIP_RIGHT;
+ if (y < ymin) code |= PXL8_CLIP_TOP;
+ else if (y > ymax) code |= PXL8_CLIP_BOTTOM;
+ return code;
+}
+
static void draw_line_clipped(
u8* fb,
u32 fb_w,
- u32 fb_h,
i32 x0,
i32 y0,
i32 x1,
@@ -644,18 +652,45 @@ static void draw_line_clipped(
i32 clip_max_x,
i32 clip_max_y
) {
+ u8 c0 = clip_outcode(x0, y0, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
+ u8 c1 = clip_outcode(x1, y1, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
+
+ for (;;) {
+ if ((c0 | c1) == 0) break;
+ if (c0 & c1) return;
+
+ u8 out = c0 ? c0 : c1;
+ i32 x, y;
+ i32 dx = x1 - x0;
+ i32 dy = y1 - y0;
+
+ if (out & PXL8_CLIP_BOTTOM) {
+ x = x0 + dx * (clip_max_y - y0) / dy;
+ y = clip_max_y;
+ } else if (out & PXL8_CLIP_TOP) {
+ x = x0 + dx * (clip_min_y - y0) / dy;
+ y = clip_min_y;
+ } else if (out & PXL8_CLIP_RIGHT) {
+ y = y0 + dy * (clip_max_x - x0) / dx;
+ x = clip_max_x;
+ } else {
+ y = y0 + dy * (clip_min_x - x0) / dx;
+ x = clip_min_x;
+ }
+
+ if (out == c0) { x0 = x; y0 = y; c0 = clip_outcode(x0, y0, clip_min_x, clip_min_y, clip_max_x, clip_max_y); }
+ else { x1 = x; y1 = y; c1 = clip_outcode(x1, y1, clip_min_x, clip_min_y, clip_max_x, clip_max_y); }
+ }
+
i32 dx = abs(x1 - x0);
i32 dy = -abs(y1 - y0);
i32 sx = x0 < x1 ? 1 : -1;
i32 sy = y0 < y1 ? 1 : -1;
i32 err = dx + dy;
+ i32 w = (i32)fb_w;
- while (true) {
- if (x0 >= clip_min_x && x0 <= clip_max_x && y0 >= clip_min_y && y0 <= clip_max_y) {
- if (x0 >= 0 && y0 >= 0 && x0 < (i32)fb_w && y0 < (i32)fb_h) {
- fb[y0 * (i32)fb_w + x0] = color;
- }
- }
+ for (;;) {
+ fb[y0 * w + x0] = color;
if (x0 == x1 && y0 == y1) break;
i32 e2 = 2 * err;
if (e2 >= dy) { err += dy; x0 += sx; }
@@ -1305,11 +1340,11 @@ static void execute_draw(
}
u8 wire_color = v0->color ? v0->color : 15;
- draw_line_clipped(fb, fb_w, fb_h, sx0, sy0, sx1, sy1, wire_color,
+ draw_line_clipped(fb, fb_w, sx0, sy0, sx1, sy1, wire_color,
clip_min_x, clip_min_y, clip_max_x, clip_max_y);
- draw_line_clipped(fb, fb_w, fb_h, sx1, sy1, sx2, sy2, wire_color,
+ draw_line_clipped(fb, fb_w, sx1, sy1, sx2, sy2, wire_color,
clip_min_x, clip_min_y, clip_max_x, clip_max_y);
- draw_line_clipped(fb, fb_w, fb_h, sx2, sy2, sx0, sy0, wire_color,
+ draw_line_clipped(fb, fb_w, sx2, sy2, sx0, sy0, wire_color,
clip_min_x, clip_min_y, clip_max_x, clip_max_y);
} else {
tri_setup setup;