aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.zig2
-rw-r--r--src/render.zig85
2 files changed, 48 insertions, 39 deletions
diff --git a/src/main.zig b/src/main.zig
index 794a3e3..2ee6bc6 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -81,7 +81,7 @@ pub fn main() !void {
};
verts = try std.BoundedArray([2]f32, level.Layer.MAX_VERTS).fromSlice(vert_coords1[0..]);
- layer = level.Layer{ .height = 1, .vertices = verts, .vertical_texture = 3, .horizontal_texture = 2 };
+ 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);
}
diff --git a/src/render.zig b/src/render.zig
index 20b879f..aac8e6b 100644
--- a/src/render.zig
+++ b/src/render.zig
@@ -233,8 +233,8 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
dist_x = (ppos_y - @intToFloat(f32, ipos_y)) * dx_for_y_step;
}
- var top_of_floor: f32 = 0;
- var bottom_of_ceiling: f32 = PlaneHeight;
+ // var top_of_floor: f32 = 0;
+ // var bottom_of_ceiling: f32 = PlaneHeight;
var distance: f32 = 0;
var next_distance: f32 = 0;
@@ -262,6 +262,7 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
}
var highest_drawn: f32 = 0;
+ var highest_drawn_same_square = false;
var lowest_drawn: f32 = PlaneHeight - 1;
var still_drawing = true;
@@ -286,6 +287,8 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
next_distance = dist_x;
next_hit_horizontal = true;
}
+
+ highest_drawn_same_square = false;
}) {
const cell = map.lookup(ipos_x, ipos_y);
@@ -324,7 +327,7 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
const adj_distance = distance + hit.local_dist;
// project the top of the bottom and the bottom of the top
- top_of_floor = PlaneHeight / 2 + PlaneDist * (layer.height - pheight) / adj_distance;
+ const top_of_floor = PlaneHeight / 2 + PlaneDist * (layer.height - pheight) / adj_distance;
const draw_lower = layer.height > 0 and top_of_floor > highest_drawn;
// Are we able to see any vertical faces?
@@ -337,35 +340,38 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
// used for texel indexing
const inv_nom_len = adj_distance / PlaneDist;
+ // which texture index?
const td = @floatToInt(c_uint, constants.TextureDim);
- if (draw_lower) {
- // which texture index?
- const t_lower_off = layer.vertical_texture * td;
- // Note the bizarre 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;
- const constrained_bottom = std.math.max(highest_drawn, top_of_floor - proj_height);
- const stop = @floatToInt(usize, PlaneWidth * (PlaneHeight - constrained_bottom)) + col;
- const pix_y = @floatToInt(usize, std.math.ceil(std.math.max(PlaneHeight - constrained_top - 1, 0)));
- var pix_index = pix_y * @floatToInt(usize, PlaneWidth) + col;
- var texel_y: f32 = std.math.max((top_of_floor - constrained_top) / nominal_length, 0);
+ const t_lower_off = layer.vertical_texture * td;
- // now we have what we need to draw the face,
- // and update the z-buffer.
- while (pix_index < stop) : ({
- pix_index += @floatToInt(usize, PlaneWidth);
- texel_y += inv_nom_len;
- }) {
- const ty = @floatToInt(c_uint, std.math.modf(texel_y).fpart * constants.TextureDim);
- const texel = walls_image.getPixel(.{ .x = t_lower_off + texcol, .y = ty });
+ // Note the bizarre 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;
- pixels[pix_index] = texel;
- self.z_buffer[pix_index] = adj_distance;
- }
- highest_drawn = constrained_top;
+ // 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) 0 else highest_drawn, top_of_floor - proj_height);
+ const stop = @floatToInt(usize, PlaneWidth * (PlaneHeight - constrained_bottom)) + col;
+ const pix_y = @floatToInt(usize, std.math.ceil(std.math.max(PlaneHeight - constrained_top - 1, 0)));
+ var pix_index = pix_y * @floatToInt(usize, PlaneWidth) + col;
+ var texel_y: f32 = std.math.max((top_of_floor - constrained_top) / nominal_length, 0);
+
+ // now we have what we need to draw the face,
+ // and update the z-buffer.
+ while (pix_index < stop) : ({
+ pix_index += @floatToInt(usize, PlaneWidth);
+ texel_y += inv_nom_len;
+ }) {
+ const ty = @floatToInt(c_uint, std.math.modf(texel_y).fpart * constants.TextureDim);
+ const texel = walls_image.getPixel(.{ .x = t_lower_off + texcol, .y = ty });
+
+ pixels[pix_index] = texel;
+ self.z_buffer[pix_index] = adj_distance;
}
+ highest_drawn = constrained_top;
}
- previous_layer_height = layer.height;
+
// do we potentially draw horizontal surfaces?
if (highest_drawn < PlaneHeight / 2) {
// Note: next_top can never exceed PlaneHeight / 2 in
@@ -375,43 +381,46 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
// than it). If the wall is shorter then the back edge
// is at most the horizon. Similarly so for next_bottom
const next_top = PlaneHeight / 2 + PlaneDist * (layer.height - pheight) / next_distance;
- if (true) { // next_top > highest_drawn
+ if (next_top > highest_drawn) {
const toff = layer.horizontal_texture * @floatToInt(c_uint, constants.TextureDim);
- top_of_floor = std.math.ceil(std.math.min(std.math.min(next_top, lowest_drawn), PlaneHeight / 2 - 1));
+ var top = std.math.ceil(std.math.min(std.math.min(next_top, lowest_drawn), PlaneHeight / 2 - 1));
const thresh = std.math.ceil(highest_drawn);
- const itop = @floatToInt(usize, std.math.max(top_of_floor, 0));
+ highest_drawn = top;
+ highest_drawn_same_square = true;
+
+ const itop = @floatToInt(usize, std.math.max(top, 0));
const ptop = @floatToInt(usize, PlaneHeight) - itop - 1;
var pix_index = ptop * @floatToInt(usize, PlaneWidth) + col - 1;
- while (top_of_floor > thresh) : ({
- top_of_floor -= 1;
+ while (top >= thresh) : ({
+ top -= 1;
pix_index += @floatToInt(usize, PlaneWidth);
}) {
- const row_dist = (pheight - layer.height) * PlaneDist / (PlaneHeight / 2 - top_of_floor);
+ const row_dist = (pheight - layer.height) * PlaneDist / (PlaneHeight / 2 - top);
// draw the correct pixel
const sx = ppos_x + row_dist * cosra;
const sy = ppos_y + row_dist * sinra;
const rx = std.math.modf(sx).fpart;
const ry = std.math.modf(sy).fpart;
- if (@floatToInt(i32, sx) == ipos_x and @floatToInt(i32, sy) == ipos_y and pointInPoly(rx, ry, layer.vertices.constSlice())) {
+ if (@floatToInt(i32, sx) == ipos_x and @floatToInt(i32, sy) == ipos_y and pointInPoly(rx, ry, layer.vertices.constSlice()) and self.z_buffer[pix_index] == std.math.inf(f32)) {
const px = @floatToInt(c_uint, constants.TextureDim * rx);
const py = @floatToInt(c_uint, constants.TextureDim * ry);
const val = surfaces_image.getPixel(.{ .x = toff + px, .y = py });
pixels[pix_index] = val;
- // TODO ???
- // if (top_of_floor > highest_drawn) highest_drawn = top_of_floor;
- // if (layer.height > 0) self.z_buffer[pix_index] = row_dist;
+ if (layer.height > 0) self.z_buffer[pix_index] = row_dist;
}
}
}
}
+
+ previous_layer_height = layer.height;
}
}
}
// Have we filled this column?
- if (top_of_floor > lowest_drawn or bottom_of_ceiling < highest_drawn) {
+ if (highest_drawn >= lowest_drawn) {
still_drawing = false;
}
}