diff options
| author | tslil clingman <> | 2021-10-17 18:40:18 -0400 |
|---|---|---|
| committer | tslil clingman <> | 2021-10-17 18:40:18 -0400 |
| commit | 260e1ae4b4d84cb28aebb4e7d1f1b54ed046e77b (patch) | |
| tree | db386872e64d0027a5295e6c10deb5476e6280f4 /src/render.zig | |
| parent | e371561831715146b42fa68ed16b5d792132cb99 (diff) | |
Still z_buffer issues, what is happening
Diffstat (limited to 'src/render.zig')
| -rw-r--r-- | src/render.zig | 85 |
1 files changed, 47 insertions, 38 deletions
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; } } |
