aboutsummaryrefslogtreecommitdiff
path: root/src/render.zig
diff options
context:
space:
mode:
authortslil clingman <>2021-10-22 17:21:10 -0400
committertslil clingman <>2021-10-22 17:36:22 -0400
commit5cecadb81ccab1a2e6ff264349f5fa73a720db9f (patch)
tree999831c7d77f954e8fb65667e6922f2d2db6e2e9 /src/render.zig
parent852a98fe4a56109f0f4947611a75d7a0eaea0bb5 (diff)
Specialise layers to be either lists of vertices or squares
Diffstat (limited to 'src/render.zig')
-rw-r--r--src/render.zig44
1 files changed, 40 insertions, 4 deletions
diff --git a/src/render.zig b/src/render.zig
index 72121f2..6c54a00 100644
--- a/src/render.zig
+++ b/src/render.zig
@@ -316,9 +316,40 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
}
var previous_layer_height: f32 = 0;
- var previous_highest_drawn:f32 = highest_drawn;
+ var previous_highest_drawn: f32 = highest_drawn;
for (cell.lower_layers.constSlice()) |layer| {
- if (hitDistLocalCoords(ray0_x, ray0_y, ray1_x, ray1_y, layer.vertices.constSlice())) |hit| {
+ const should_try_to_draw_layer = switch (layer.polygon) {
+ .square => hit: {
+ // we have to compute texture_frac by hand.
+ var texfrac : f32 = undefined;
+ // Using the notation in the below diagram,
+ // we want face_i to have [0.25i, 0.25(i+1)]
+ // of the texture.
+
+ // <---2---
+ // | ^
+ // 3 |
+ // | 1
+ // v |
+ // ---0--->
+
+ if (hit_horizontal) {
+ // a horizontal hit means we take the horizontal coordinate
+ texfrac = std.math.modf(distance * cosra + ppos_x).fpart / 4;
+ // we're either 0 or 2, if sinra < 0 then we're 2
+ if (sinra < 0) texfrac = 0.50 + (0.25 - texfrac);
+ } else {
+ // a vertical hit means we take the vertical coordinate
+ texfrac = std.math.modf(distance * sinra + ppos_y).fpart / 4;
+ // we're either 1 or 3, if cosra < 0 then we're 1
+ if (cosra < 0) texfrac += 0.25 else texfrac = 0.75 + (0.25 - texfrac);
+ }
+
+ break :hit LocalCoordHit{ .local_dist = 0, .texture_frac = texfrac };
+ },
+ .vertices => |vs| hitDistLocalCoords(ray0_x, ray0_y, ray1_x, ray1_y, vs.constSlice()),
+ };
+ if (should_try_to_draw_layer) |hit| {
// TODO: Correct for fisheye? Is this what FOV_SCALE does?
const adj_distance = distance + hit.local_dist * FOV_SCALE;
@@ -397,14 +428,19 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
const sy = ppos_y + row_dist * sinra;
// only proceed if it's in the current square
- if (@floatToInt(i32, sx) != ipos_x or @floatToInt(i32, sy) != ipos_y) continue;
+ if (sx < 0 or sy < 0 or @floatToInt(i32, sx) != ipos_x or @floatToInt(i32, sy) != ipos_y) continue;
// where does it land in the square?
const rx = std.math.modf(sx).fpart;
const ry = std.math.modf(sy).fpart;
// is it in the polygon?
- if (pointInPoly(rx, ry, layer.vertices.constSlice())) {
+ const should_be_drawn = switch (layer.polygon) {
+ .square => true,
+ .vertices => |vs| pointInPoly(rx, ry, vs.constSlice()),
+ };
+
+ if (should_be_drawn) {
const px = @floatToInt(c_uint, constants.TextureDim * rx);
const py = @floatToInt(c_uint, constants.TextureDim * ry);
pixels[pix_index] = surfaces_image.getPixel(.{ .x = toff + px, .y = py });