aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.zig10
-rw-r--r--src/player.zig72
2 files changed, 36 insertions, 46 deletions
diff --git a/src/main.zig b/src/main.zig
index 283de07..3c95d20 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -90,12 +90,8 @@ pub fn main() !void {
defer walls_image.destroy();
// Load sprite textures
- var object_textures = try sf.Texture.createFromFile("objects.png");
- defer object_textures.destroy();
- object_textures.setSmooth(false);
-
- var objects_sprite = try sf.Sprite.createFromTexture(object_textures);
- defer objects_sprite.destroy();
+ var objects_image = try sf.Image.createFromFile("objects.png");
+ defer objects_image.destroy();
// Load floor image
var surfaces_image = try sf.Image.createFromFile("surfaces.png");
@@ -171,7 +167,7 @@ pub fn main() !void {
try player.renderWorld(
window,
- objects_sprite,
+ objects_image,
walls_image,
surfaces_image,
rendered_surfaces_texture,
diff --git a/src/player.zig b/src/player.zig
index 98f0b47..8ad3a1e 100644
--- a/src/player.zig
+++ b/src/player.zig
@@ -26,32 +26,6 @@ const Colour = @import("sfml").graphics.Color;
const level = @import("level.zig");
const constants = @import("constants.zig");
-fn renderSlice(
- window: RenderWindow,
- sprite: Sprite,
- col: i32, // which column
- top: f32, // top of wall
- height: f32, // how tall
- draw_frac: f32, // how much to draw, as a fraction; > 1 means repeat texture
- texfrac: f32, // how far along the texture
- texture: u8, // which texture index
-) void {
- // we need ceil here so that we draw always to or past the edge of the screen
- const draw_height = @floatToInt(c_int, std.math.ceil(draw_frac * constants.TextureDim));
- const total_height = height * constants.VFact;
-
- const xpos = @intToFloat(f32, col) * constants.HFact;
- const ypos = constants.ScreenHeight / 2 + (constants.PlaneHeight / 2 - top) * constants.VFact;
-
- const tind = texture * @floatToInt(c_int, constants.TextureDim);
- const left = tind + @floatToInt(c_int, texfrac * constants.TextureDim);
-
- sprite.setPosition(.{ .x = xpos, .y = ypos });
- sprite.setScale(.{ .x = constants.HFact, .y = total_height / constants.TextureDim });
- sprite.setTextureRect(.{ .top = 0, .left = left, .width = 1, .height = draw_height });
- window.draw(sprite, null);
-}
-
fn playerDistComp(pos: [2]f32, lhs: level.Object, rhs: level.Object) bool {
const lx = lhs.pos_x - pos[0];
const ly = lhs.pos_y - pos[1];
@@ -148,7 +122,7 @@ pub fn Player(PlaneWidth: f32, PlaneHeight: f32) type {
pub fn renderWorld(
self: *@This(),
window: RenderWindow,
- objects_sprite: Sprite,
+ objects_image: Image,
walls_image: Image,
surfaces_image: Image,
rendered_surfaces_texture: Texture,
@@ -161,7 +135,7 @@ pub fn Player(PlaneWidth: f32, PlaneHeight: f32) type {
self.z_buffer.set(i, std.math.inf(f32));
}
- var pixels = [_]Colour{Colour.fromRGBA(0, 0, 0, 0)} ** (PlaneWidth * PlaneHeight);
+ var pixels = [_]Colour{Colour.Transparent} ** (PlaneWidth * PlaneHeight);
// then draw all the walls and populate the z_buffer, while also
// rendering the surfaces below the horizon to the pixel array
@@ -174,15 +148,20 @@ pub fn Player(PlaneWidth: f32, PlaneHeight: f32) type {
try rendered_surfaces_texture.updateFromPixels(&pixels, null);
window.draw(rendered_surfaces_sprite, null);
- // use the z_buffer to render sprites
- self.renderObjects(window, objects_sprite, map);
+ // TODO: use the z_buffer to render sprites, reset the
+ // pixel array as a cheap hack to avoid colour mixing ...
+ pixels = [_]Colour{Colour.Transparent} ** (PlaneWidth * PlaneHeight);
+ self.renderObjects(objects_image, map, &pixels);
+ try rendered_surfaces_texture.updateFromPixels(&pixels, null);
+ window.draw(rendered_surfaces_sprite, null);
+
}
fn renderObjects(
self: @This(),
- window: RenderWindow,
- objects_sprite: Sprite,
+ objects_image: Image,
map: level.Map,
+ pixels: []Colour,
) void {
std.sort.sort(level.Object, map.objects.items,
// Wow, context with an arbitrary type! No macros, just
@@ -229,25 +208,40 @@ pub fn Player(PlaneWidth: f32, PlaneHeight: f32) type {
// Something is on the screen, let's draw it!
const start = std.math.max(0, left);
- const end = @floatToInt(i32, std.math.min(left + width, PlaneWidth - 1));
+ const end = @floatToInt(usize, std.math.min(left + width, PlaneWidth - 1));
+
+ const inv_height = 1 / height;
var tex_frac: f32 = std.math.clamp((start - left) / width, 0, 1);
- var col: i32 = @floatToInt(i32, start);
+ var col: usize = @floatToInt(usize, start);
const tex_frac_step = 1 / width;
while (col < end) : ({
col += 1;
tex_frac += tex_frac_step;
}) {
var bottom = std.math.min(top, PlaneHeight);
- while (bottom >= 0 and bottom >= top - height) : (bottom -= 1) {
- const index = @intCast(usize, col * @floatToInt(i32, PlaneHeight) + @floatToInt(i32, bottom));
+ var pix_y = @floatToInt(usize, std.math.ceil(std.math.max(PlaneHeight - bottom, 0)));
+ var texel_y = (top - bottom) / height;
+ while (pix_y < PlaneHeight and bottom >= top - height) : ({
+ bottom -= 1;
+ pix_y += 1;
+ texel_y += inv_height;
+ }) {
+ const index = col * @floatToInt(usize, PlaneHeight) + @floatToInt(usize, bottom);
if (self.z_buffer.get(index) < scaled_perp_distance) {
- bottom += 1;
break;
+ } else {
+ const tx = @floatToInt(c_uint, tex_frac * constants.TextureDim);
+ const toff = obj.texture * @floatToInt(c_uint, constants.TextureDim);
+ const ty = @floatToInt(c_uint, texel_y * constants.TextureDim);
+ const texel = objects_image.getPixel(.{ .x = toff + tx, .y = ty });
+ const pix_index = @floatToInt(usize, PlaneWidth) * pix_y + col;
+ // TODO: currently i have a cheap hack to
+ // avoid colour mixing. Is there a better
+ // way to do this?
+ pixels[pix_index] = texel;
}
}
- const draw_frac = std.math.clamp((top - bottom) / height, 0, 1);
- renderSlice(window, objects_sprite, col, top, height, draw_frac, tex_frac, obj.texture);
}
}
}