aboutsummaryrefslogtreecommitdiff
path: root/src/render.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/render.zig')
-rw-r--r--src/render.zig32
1 files changed, 22 insertions, 10 deletions
diff --git a/src/render.zig b/src/render.zig
index 1cec3a6..647e7f8 100644
--- a/src/render.zig
+++ b/src/render.zig
@@ -289,9 +289,7 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
}) {
const cell = map.lookup(ipos_x, ipos_y);
- // Are we drawing vertical surfaces?
-
- // TODO: not quite right, ``anything vertical'' not just ``anything''
+ // Are we drawing this cell?
if (cell.lower_layers.len > 0) {
var ray0_x: f32 = undefined;
var ray0_y: f32 = undefined;
@@ -342,14 +340,16 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
const td = @floatToInt(c_uint, constants.TextureDim);
const t_lower_off = layer.vertical_texture * td;
- // Note the bizarre rounding we have to do to avoid artifacts
+ // Note the rounding we have to do to avoid
+ // artifacts
const constrained_top = std.math.floor(std.math.min(top_of_floor, lowest_drawn));
const proj_height = (layer.height - previous_layer_height) * nominal_length;
// if we're above the layer that set the
// highest_drawn values, we can draw down
// into it (for walls over floors)
- const constrained_bottom = std.math.max(if (highest_drawn_same_square) previous_highest_drawn else highest_drawn, top_of_floor - proj_height);
+ const alternate_bottom = if (highest_drawn_same_square) previous_highest_drawn else highest_drawn;
+ const constrained_bottom = std.math.max(alternate_bottom, top_of_floor - proj_height);
const stop_top = std.math.max(0, PlaneHeight - constrained_bottom);
const stop = @floatToInt(usize, PlaneWidth * stop_top) + col;
const pix_y = @floatToInt(usize, std.math.ceil(std.math.max(PlaneHeight - constrained_top - 1, 0)));
@@ -377,13 +377,16 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
// than it). If the wall is shorter then the back edge
// is at most the horizon.
const next_top = PlaneHeight / 2 + PlaneDist * (layer.height - pheight) / next_distance;
+
if (next_top > highest_drawn) {
highest_drawn_same_square = true;
const toff = layer.horizontal_texture * @floatToInt(c_uint, constants.TextureDim);
var top = std.math.ceil(std.math.min(std.math.min(next_top, lowest_drawn), PlaneHeight / 2 - 1));
- const thresh = highest_drawn;
+ // TODO: Literal corner case. Clip the bottom of a wall to see this
+ const thresh = if (highest_drawn_same_square) previous_highest_drawn else highest_drawn;
+ // const thresh = highest_drawn;
const itop = @floatToInt(usize, top);
const ptop = @floatToInt(usize, PlaneHeight) - itop;
@@ -392,10 +395,19 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
top -= 1;
pix_index += @floatToInt(usize, PlaneWidth);
}) {
+ // where would the source of this pixel be?
const row_dist = (pheight - layer.height) * PlaneDist / (PlaneHeight / 2 - top);
- // draw the correct pixel
- const rx = std.math.modf(ppos_x + row_dist * cosra).fpart;
- const ry = std.math.modf(ppos_y + row_dist * sinra).fpart;
+ const sx = ppos_x + row_dist * cosra;
+ 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;
+
+ // 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 px = @floatToInt(c_uint, constants.TextureDim * rx);
const py = @floatToInt(c_uint, constants.TextureDim * ry);
@@ -403,7 +415,7 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
if (top > highest_drawn) {
highest_drawn = top;
}
- if (layer.height > 0) self.z_buffer[pix_index] = row_dist;
+ self.z_buffer[pix_index] = row_dist;
}
}
}