diff options
| -rw-r--r-- | src/main.zig | 85 | ||||
| -rw-r--r-- | src/render.zig | 32 | ||||
| -rw-r--r-- | walls.png | bin | 677 -> 693 bytes |
3 files changed, 75 insertions, 42 deletions
diff --git a/src/main.zig b/src/main.zig index 47f89a7..8b77440 100644 --- a/src/main.zig +++ b/src/main.zig @@ -49,40 +49,61 @@ pub fn main() !void { var map = try level.Map.new(16, 16, &gpa.allocator); defer map.deinit(); - var y: u32 = 5; - while (y < 10) : (y += 1) { - // HACK - const vert_coords0 = [_][2]f32{ - .{ 0.10, 0.10 }, - .{ 0.90, 0.10 }, - .{ 0.90, 0.90 }, - .{ 0.10, 0.90 }, - }; - var verts = try std.BoundedArray([2]f32, level.Layer.MAX_VERTS).fromSlice(vert_coords0[0..]); - var layer = level.Layer{ .height = 0.5, .vertices = verts }; - try map.cells.items[07 * 16 + y].lower_layers.append(layer); + // floor + const square_coords = [_][2]f32{ + .{ 0.00, 0.00 }, + .{ 1.00, 0.00 }, + .{ 1.00, 1.00 }, + .{ 0.00, 1.00 }, + }; - const vert_coords1 = [_][2]f32{ - .{ 0.75, 0.5 }, - .{ 0.72838634, 0.60168415 }, - .{ 0.66728264, 0.68578625 }, - .{ 0.57725424, 0.7377641 }, - .{ 0.47386786, 0.74863046 }, - .{ 0.375, 0.71650636 }, - .{ 0.29774573, 0.6469463 }, - .{ 0.2554631, 0.5519779 }, - .{ 0.25546312, 0.44802207 }, - .{ 0.29774576, 0.35305366 }, - .{ 0.37500003, 0.28349364 }, - .{ 0.47386792, 0.25136954 }, - .{ 0.5772543, 0.26223588 }, - .{ 0.6672827, 0.3142138 }, - .{ 0.7283864, 0.39831588 }, - }; - verts = try std.BoundedArray([2]f32, level.Layer.MAX_VERTS).fromSlice(vert_coords1[0..]); + var y: u32 = 0; + while (y < 16) : (y += 1) { + var x: usize = 0; + while (x < 16) : (x += 1) { + var floor_verts = try std.BoundedArray([2]f32, level.Layer.MAX_VERTS).fromSlice(square_coords[0..]); + try map.cells.items[y * 16 + x].lower_layers.append(level.Layer{ .height = 0, .vertices = floor_verts }); + if (y == 0 or y == 15 or x == 0) { + try map.cells.items[y * 16 + x].lower_layers.append(level.Layer{ .height = 2, .vertices = floor_verts }); + } else { + if (x == 15) + try map.cells.items[y * 16 + x].lower_layers.append(level.Layer{ .height = 2, .vertices = floor_verts, .vertical_texture = 2 }); + } + if (y == 7 and x >= 5 and x <= 10) { + const vert_coords0 = [_][2]f32{ + .{ 0.10, 0.10 }, + .{ 0.90, 0.10 }, + .{ 0.90, 0.90 }, + .{ 0.10, 0.90 }, + }; + var verts = try std.BoundedArray([2]f32, level.Layer.MAX_VERTS).fromSlice(vert_coords0[0..]); + var layer = level.Layer{ .height = 0.5, .vertices = verts, .vertical_texture = 3, .horizontal_texture = 1 }; - layer = level.Layer{ .height = 1, .vertices = verts, .vertical_texture = 1, .horizontal_texture = 2, .vertical_texture_scale = 2 }; - try map.cells.items[07 * 16 + y].lower_layers.append(layer); + try map.cells.items[y * 16 + x].lower_layers.append(layer); + + const vert_coords1 = [_][2]f32{ + .{ 0.75, 0.5 }, + .{ 0.72838634, 0.60168415 }, + .{ 0.66728264, 0.68578625 }, + .{ 0.57725424, 0.7377641 }, + .{ 0.47386786, 0.74863046 }, + .{ 0.375, 0.71650636 }, + .{ 0.29774573, 0.6469463 }, + .{ 0.2554631, 0.5519779 }, + .{ 0.25546312, 0.44802207 }, + .{ 0.29774576, 0.35305366 }, + .{ 0.37500003, 0.28349364 }, + .{ 0.47386792, 0.25136954 }, + .{ 0.5772543, 0.26223588 }, + .{ 0.6672827, 0.3142138 }, + .{ 0.7283864, 0.39831588 }, + }; + verts = try std.BoundedArray([2]f32, level.Layer.MAX_VERTS).fromSlice(vert_coords1[0..]); + + layer = level.Layer{ .height = 1, .vertices = verts, .vertical_texture = 1, .horizontal_texture = 2, .vertical_texture_scale = 2 }; + try map.cells.items[y * 16 + x].lower_layers.append(layer); + } + } } try map.objects.append(level.Object{ .pos_x = 1.5, .pos_y = 7.5, .pos_z = 2, .texture = 2, .height = 1, .width = 1 }); 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; } } } Binary files differ |
