aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortslil clingman <>2021-10-17 15:30:14 -0400
committertslil clingman <>2021-10-17 15:30:14 -0400
commitc376543f5b2c9593bee3664b7c1cb67f8802f79c (patch)
treef71e44bdd7e3a755d744a3e1246f6a7197062732 /src
parent61856ed5407a227aab35d7b800daad883c265dd9 (diff)
Texture scaling
Diffstat (limited to 'src')
-rw-r--r--src/level.zig1
-rw-r--r--src/main.zig14
-rw-r--r--src/render.zig108
3 files changed, 59 insertions, 64 deletions
diff --git a/src/level.zig b/src/level.zig
index 81a0e67..f277b19 100644
--- a/src/level.zig
+++ b/src/level.zig
@@ -22,6 +22,7 @@ pub const Layer = struct {
height : f32 = 0,
vertical_texture : u8 = 0,
+ vertical_texture_scale : f32 = 4,
horizontal_texture : u8 = 0,
// What happened to this error? Is it comptime?
vertices: std.BoundedArray([2]f32, MAX_VERTS),
diff --git a/src/main.zig b/src/main.zig
index 6e535b9..e542a0a 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -53,14 +53,14 @@ pub fn main() !void {
while (y < 10) : (y += 1) {
// HACK
const vert_coords0 = [_][2]f32{
- .{ 0.25, 0.25 },
- .{ 0.75, 0.25 },
- .{ 0.75, 0.75 },
- .{ 0.25, 0.75 },
- .{ 0.25, 0.25 },
+ .{ 0.00, 0.00 },
+ .{ 1.00, 0.00 },
+ .{ 1.00, 1.00 },
+ .{ 0.00, 1.00 },
+ .{ 0.00, 0.00 },
};
var verts = try std.BoundedArray([2]f32, level.Layer.MAX_VERTS).fromSlice(vert_coords0[0..]);
- var layer = level.Layer{ .height = 1, .vertices = verts };
+ var layer = level.Layer{ .height = 0.5, .vertices = verts };
try map.cells.items[07 * 16 + y].lower_layers.append(layer);
const vert_coords1 = [_][2]f32{
@@ -83,7 +83,7 @@ pub fn main() !void {
};
verts = try std.BoundedArray([2]f32, level.Layer.MAX_VERTS).fromSlice(vert_coords1[0..]);
- layer = level.Layer{ .height = 2, .vertices = verts, .vertical_texture = 3 };
+ layer = level.Layer{ .height = 1, .vertices = verts, .vertical_texture = 3 };
try map.cells.items[07 * 16 + y].lower_layers.append(layer);
// map.cells.items[y * 16 + 15] = level.Cell{ .floor_height = level.Cell.DEFAULT_HEIGHT, .lower_texture = 2 };
// map.cells.items[15 * 16 + y] = level.Cell{ .floor_height = level.Cell.DEFAULT_HEIGHT };
diff --git a/src/render.zig b/src/render.zig
index 27bd0cc..f81ce4f 100644
--- a/src/render.zig
+++ b/src/render.zig
@@ -71,7 +71,7 @@ fn fasterColourBlend(onto: Colour, from: Colour) Colour {
const LocalCoordHit = struct {
local_dist: f32,
- frac: f32,
+ texture_frac: f32,
};
// The primary observation is: if a line segment AB disconnects the unit square,
@@ -132,11 +132,14 @@ fn hitDistLocalCoords(
// indexes it along vp->v which we use for texture mapping.
const denom = (rdx * vdy - vdx * rdy);
const t = (vdx * (ray0_y - vp[1]) - vdy * (ray0_x - vp[0])) / denom;
- const frac = crossp / denom;
+ const side_frac = crossp / denom;
const new_distance = rdist * t;
if (ret_val == null or (new_distance < ret_val.?.local_dist)) {
- ret_val = LocalCoordHit{ .local_dist = new_distance, .frac = frac };
+ ret_val = LocalCoordHit{
+ .local_dist = new_distance,
+ .texture_frac = (side_frac + @intToFloat(f32, i - 1)) / @intToFloat(f32, vertices.len),
+ };
}
}
}
@@ -434,10 +437,11 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
ray1_y = std.math.modf(next_distance * sinra + ppos_y).fpart;
}
+ var previous_layer_height: f32 = 0;
for (cell.lower_layers.constSlice()) |layer| {
- if (hitDistLocalCoords(ray0_x, ray0_y, ray1_x, ray1_y, layer.vertices.constSlice())) |dist_frac| {
+ if (hitDistLocalCoords(ray0_x, ray0_y, ray1_x, ray1_y, layer.vertices.constSlice())) |hit| {
// TODO: Correct for fisheye?
- const adj_distance = distance + dist_frac.local_dist;
+ 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;
@@ -448,7 +452,8 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
// Are we able to see any vertical faces?
if (draw_lower) {
- const texstrip = @floatToInt(c_uint, constants.TextureDim * dist_frac.frac);
+ const tex_strip = std.math.modf(layer.vertical_texture_scale * hit.texture_frac).fpart;
+ const texcol = @floatToInt(c_uint, constants.TextureDim * tex_strip);
// height of a unit-height wall at this distance
const nominal_length = PlaneDist / adj_distance;
@@ -461,7 +466,7 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
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 * nominal_length;
+ 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)));
@@ -475,7 +480,7 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
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 + texstrip, .y = ty });
+ const texel = walls_image.getPixel(.{ .x = t_lower_off + texcol, .y = ty });
pixels[pix_index] = texel;
self.z_buffer[pix_index] = adj_distance;
@@ -483,28 +488,46 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
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
+ // the body of the next block. If the wall is taller
+ // than us the back edge is lower than the front one so
+ // this check will fail as we just drew it (or higher
+ // 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 (false and next_top > highest_drawn) {
+ const toff = cell.floor_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));
+ const thresh = std.math.ceil(highest_drawn);
- // if (draw_upper) {
- // const proj_default_end = PlaneHeight / 2 + PlaneDist * (level.Cell.DEFAULT_HEIGHT - pheight) / adj_distance;
- // const constrained_top = std.math.min(lowest_drawn, proj_default_end);
- // const constrained_bottom = std.math.ceil(std.math.max(bottom_of_ceiling, highest_drawn));
- // const stop = @floatToInt(usize, PlaneWidth * (PlaneHeight - constrained_bottom)) + col;
- // const t_upper_off = cell.upper_texture * td;
- // 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 = constants.TextureDim - (constrained_top - constrained_bottom) / nominal_length;
- // 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_upper_off + texstrip, .y = ty });
+ const itop = @floatToInt(usize, std.math.max(top_of_floor, 0));
+ const ptop = @floatToInt(usize, PlaneHeight) - itop - 1;
+ var pix_index = ptop * @floatToInt(usize, PlaneWidth) + col;
+ while (top_of_floor > thresh) : ({
+ top_of_floor -= 1;
+ pix_index += @floatToInt(usize, PlaneWidth);
+ }) {
+ const row_dist = (pheight - cell.floor_height) * PlaneDist / (PlaneHeight / 2 - top_of_floor);
+ // draw the correct pixel
+ const sx = std.math.modf(ppos_x + row_dist * cosra).fpart;
+ const sy = std.math.modf(ppos_y + row_dist * sinra).fpart;
+ const px = @floatToInt(c_uint, constants.TextureDim * std.math.fabs(sx));
+ const py = @floatToInt(c_uint, constants.TextureDim * std.math.fabs(sy));
+ const val = surfaces_image.getPixel(.{ .x = toff + px, .y = py });
+ pixels[pix_index] = val;
- // pixels[pix_index] = texel;
- // self.z_buffer[pix_index] = adj_distance;
- // }
- // lowest_drawn = constrained_bottom;
- // }
+ // record in the z_buffer only if we're above the floor!
+ if (cell.floor_height > 0) self.z_buffer[pix_index] = row_dist;
+ }
+ // OVERDRAW
+ // highest_drawn = next_top;
+ }
}
}
}
@@ -520,35 +543,6 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
// const next_top = PlaneHeight / 2 + PlaneDist * (cell.floor_height - pheight) / next_distance;
// const next_bottom = PlaneHeight / 2 + PlaneDist * (cell.ceiling_height - pheight) / next_distance;
- // // draw floor?
- // if (false and next_top > highest_drawn) {
- // const toff = cell.floor_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));
- // const thresh = std.math.ceil(highest_drawn);
-
- // const itop = @floatToInt(usize, std.math.max(top_of_floor, 0));
- // const ptop = @floatToInt(usize, PlaneHeight) - itop - 1;
- // var pix_index = ptop * @floatToInt(usize, PlaneWidth) + col;
- // while (top_of_floor > thresh) : ({
- // top_of_floor -= 1;
- // pix_index += @floatToInt(usize, PlaneWidth);
- // }) {
- // const row_dist = (pheight - cell.floor_height) * PlaneDist / (PlaneHeight / 2 - top_of_floor);
- // // draw the correct pixel
- // const sx = std.math.modf(ppos_x + row_dist * cosra);
- // const sy = std.math.modf(ppos_y + row_dist * sinra);
- // const px = @floatToInt(c_uint, constants.TextureDim * std.math.fabs(sx.fpart));
- // const py = @floatToInt(c_uint, constants.TextureDim * std.math.fabs(sy.fpart));
- // const val = surfaces_image.getPixel(.{ .x = toff + px, .y = py });
- // pixels[pix_index] = val;
-
- // // record in the z_buffer only if we're above the floor!
- // if (cell.floor_height > 0) self.z_buffer[pix_index] = row_dist;
- // }
- // highest_drawn = next_top;
- // }
-
// // draw ceiling?
// if (false and cell.draw_down and next_bottom < lowest_drawn) {
// const toff = cell.ceiling_texture * @floatToInt(c_uint, constants.TextureDim);