From e4baa0810748bd3de93d1eaf216288ad67a86295 Mon Sep 17 00:00:00 2001 From: tslil clingman <> Date: Fri, 3 Sep 2021 21:09:07 -0400 Subject: Working on floor casting, but it's not quite right The way floors are currently rendered the textures will always appear ``under'' the walls. This is not intended for shorter walls, the floor should be atop them. I might be able to fix this by switching to vertical scan-line rendering of floors -- although i understand that that is less efficient -- and doing this at the same time as wall rendering. --- src/main.zig | 105 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 44 deletions(-) (limited to 'src/main.zig') diff --git a/src/main.zig b/src/main.zig index aef559f..2d12975 100644 --- a/src/main.zig +++ b/src/main.zig @@ -39,21 +39,19 @@ fn renderWall( texfrac: f32, // how far along the texture texture: u8, // which texture index ) void { - const hFact = screenWidth / planeWidth; - const vFact = screenHeight / planeHeight; // 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 * wallTextureDim)); - const total_length = total_height * vFact; + const draw_height = @floatToInt(c_int, std.math.ceil(draw_frac * TextureDim)); + const total_length = total_height * VFact; - const xpos = @intToFloat(f32, col) * hFact; - const ypos = (screenHeight + vFact * planeHeight) / 2 - top * vFact; + const xpos = @intToFloat(f32, col) * HFact; + const ypos = ScreenHeight / 2 + (PlaneHeight / 2 - top) * VFact; - const tind = @as(c_int, texture) * @floatToInt(c_int, 1 + wallTextureDim); - const left = tind + @floatToInt(c_int, texfrac * wallTextureDim); + const tind = @as(c_int, texture) * @floatToInt(c_int, 1 + TextureDim); + const left = tind + @floatToInt(c_int, texfrac * TextureDim); sprite.setPosition(.{ .x = xpos, .y = ypos }); - sprite.setScale(.{ .x = hFact, .y = total_length / wallTextureDim }); + sprite.setScale(.{ .x = HFact, .y = total_length / TextureDim }); sprite.setTextureRect(.{ .top = 0, .left = left, .width = 1, .height = draw_height }); window.draw(sprite, null); } @@ -64,9 +62,11 @@ pub fn main() !void { // Setup player and map //-------------------------------------------------------------------------- - var player = Player.new(15.75, 1.5, // pos - PI / 2.0, // ang - @intToFloat(f32, planeWidth), @intToFloat(f32, planeHeight)); + var player = try Player(PlaneWidth, PlaneHeight).new( + 15, // x coord + 1.5, // y coord + PI / 2.0, // angle + ); var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); @@ -83,45 +83,53 @@ pub fn main() !void { } map.cells.items[y * 15 + 15] = Cell{ .height = MAX_HEIGHT, .wall_texture = 1 }; - map.cells.items[y * 15 + 14] = Cell{ .height = MAX_HEIGHT / 1.5, .wall_texture = 1 }; + map.cells.items[y * 15 + 14] = Cell{ .height = MAX_HEIGHT / 3, .wall_texture = 1, .floor_texture = 1 }; // Initialise SFML //-------------------------------------------------------------------------- - var window = try sf.RenderWindow.create(.{ .x = screenWidth, .y = screenHeight }, 32, "zirc", sf.window.Style.none); + var window = try sf.RenderWindow.create(.{ .x = ScreenWidth, .y = ScreenHeight }, 32, "zirc", sf.window.Style.none); defer window.destroy(); - window.setFramerateLimit(30); - - var backRect = try sf.RectangleShape.create(.{ .x = screenWidth, .y = screenHeight / 2 }); - defer backRect.destroy(); - - backRect.setPosition(.{ .x = 0, .y = screenHeight / 2 }); - backRect.setFillColor(sf.Color.fromRGB(50, 50, 50)); + window.setFramerateLimit(60); // Load the background skybox, really `skycylinder', and assign it to a // sprite -- it's set to repeating so that it goes on forever. We need to - // scale the sprite so that drawing 1/4 of backTextureWidth fills the screen - // horizontally, and drawing backTextureHeight fills half of the screen + // scale the sprite so that drawing 1/4 of backTextureWidth fills the Screen + // horizontally, and drawing backTextureHeight fills half of the Screen // vertically. - var backTexture = try sf.Texture.createFromFile("back.png"); - defer backTexture.destroy(); + var back_texture = try sf.Texture.createFromFile("back.png"); + defer back_texture.destroy(); + + back_texture.setSmooth(false); // looks worse => better! + back_texture.setRepeated(true); + + var back_sprite = try sf.Sprite.createFromTexture(back_texture); + defer back_sprite.destroy(); - backTexture.setSmooth(false); // looks worse => better! - backTexture.setRepeated(true); + back_sprite.setScale(.{ .x = 4.0 * ScreenWidth / BackTextureWidth, .y = ScreenHeight / (2 * BackTextureHeight) }); - var backSprite = try sf.Sprite.createFromTexture(backTexture); - defer backSprite.destroy(); + // Load wall textures + var wall_textures = try sf.Texture.createFromFile("walls.png"); + defer wall_textures.destroy(); + wall_textures.setSmooth(false); // looks worse => better! - backSprite.setScale(.{ .x = 4.0 * screenWidth / backTextureWidth, .y = screenHeight / (2 * backTextureHeight) }); + var walls_sprite = try sf.Sprite.createFromTexture(wall_textures); + defer walls_sprite.destroy(); - // Load brick texture! - var wallTexture = try sf.Texture.createFromFile("walls.png"); - defer wallTexture.destroy(); - wallTexture.setSmooth(false); // looks worse => better! + // Load floor textures + var floors_image = try sf.Image.createFromFile("floors.png"); + defer floors_image.destroy(); - var wallSprite = try sf.Sprite.createFromTexture(wallTexture); - defer wallSprite.destroy(); + var rendered_floors_texture = try sf.Texture.create(.{ .x = PlaneWidth, .y = PlaneHeight / 2 }); + defer rendered_floors_texture.destroy(); + rendered_floors_texture.setSmooth(false); + + var rendered_floors_sprite = try sf.Sprite.createFromTexture(rendered_floors_texture); + defer rendered_floors_sprite.destroy(); + + rendered_floors_sprite.setPosition(.{ .x = 0, .y = ScreenHeight / 2 }); + rendered_floors_sprite.setScale(.{ .x = HFact, .y = VFact }); // Start your engines! //-------------------------------------------------------------------------- @@ -133,6 +141,9 @@ pub fn main() !void { if (isKeyPressed(.Escape)) window.close(); + if (isKeyPressed(.C)) player.height -= 0.1; + if (isKeyPressed(.V)) player.height += 0.1; + const rotation = 2.0 * PI / 100.0; if (isKeyPressed(.R)) player.ang += rotation; if (isKeyPressed(.T)) player.ang -= rotation; @@ -159,18 +170,24 @@ pub fn main() !void { window.clear(sf.Color.fromRGB(100, 100, 100)); - const back_scroll = @floatToInt(i32, -backTextureWidth * player.ang / (2 * PI)); - backSprite.setTextureRect(sf.IntRect{ + // First the background + const back_scroll = @floatToInt(i32, -BackTextureWidth * player.ang / (2 * PI)); + back_sprite.setTextureRect(sf.IntRect{ .left = back_scroll, // fix location of texture in the sky .top = 0, - // scaling ensures that the next two paint it across the width of - // the screen, and for half the height of the screen - .width = backTextureWidth / 4.0, // 1/4 of texture per screen - .height = backTextureHeight, // full height of texture visible + // scaling ensures that the next two dimensions paint it across the + // width of the Screen, and for half the height of the screen + .width = BackTextureWidth / 4.0, // 1/4 of texture per screen + .height = BackTextureHeight, // full height of texture visible }); - window.draw(backSprite, null); + window.draw(back_sprite, null); + + // Then render the walls + try player.renderFloorsToTexture(floors_image, rendered_floors_texture, map); + window.draw(rendered_floors_sprite, null); - player.renderMapUsing(window, wallSprite, map, renderWall); + // Finally the world + player.renderWorld(window, walls_sprite, map, renderWall); window.display(); -- cgit v1.3.1