Made terrain its own struct
This commit is contained in:
parent
c0b8d021d4
commit
1475fd2101
6 changed files with 93 additions and 26 deletions
|
|
@ -17,6 +17,7 @@ pub const Resources = struct {
|
||||||
camera: *Camera,
|
camera: *Camera,
|
||||||
renderer: *Renderer,
|
renderer: *Renderer,
|
||||||
input: *Input,
|
input: *Input,
|
||||||
|
terrain: rendering.Terrain,
|
||||||
delta_time: f32 = 0.0,
|
delta_time: f32 = 0.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,6 @@ mesh: Mesh,
|
||||||
transforms: std.ArrayList(math.Transform),
|
transforms: std.ArrayList(math.Transform),
|
||||||
previous_time: std.time.Instant,
|
previous_time: std.time.Instant,
|
||||||
current_image: usize,
|
current_image: usize,
|
||||||
terrain_vertex: vk.Buffer,
|
|
||||||
terrain_index: vk.Buffer,
|
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_handle: vk.c.VkSurfaceKHR) !Self {
|
pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_handle: vk.c.VkSurfaceKHR) !Self {
|
||||||
const instance: vk.Instance = .{ .handle = instance_handle };
|
const instance: vk.Instance = .{ .handle = instance_handle };
|
||||||
|
|
@ -49,27 +47,7 @@ pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_hand
|
||||||
const terrain_fragment_shader = try device.initShader("terrain_frag");
|
const terrain_fragment_shader = try device.initShader("terrain_frag");
|
||||||
defer device.deinitShader(terrain_fragment_shader);
|
defer device.deinitShader(terrain_fragment_shader);
|
||||||
|
|
||||||
var terrain_pipeline = try vk.TerrainPipeline.init(graphics_pipeline, terrain_vertex_shader, terrain_fragment_shader);
|
const terrain_pipeline = try vk.TerrainPipeline.init(graphics_pipeline, terrain_vertex_shader, terrain_fragment_shader);
|
||||||
|
|
||||||
const perlin: math.PerlinNoise = .{ .seed = 54321 };
|
|
||||||
const heightmap = try allocator.alloc(u32, 700 * 700);
|
|
||||||
defer allocator.free(heightmap);
|
|
||||||
for (0..700) |x| {
|
|
||||||
for (0..700) |y| {
|
|
||||||
const scale = 0.01;
|
|
||||||
var pixel = (perlin.fbm(@as(f64, @floatFromInt(x)) * scale, @as(f64, @floatFromInt(y)) * scale, 8, 3, 0.5) * 3);
|
|
||||||
pixel = std.math.pow(f64, pixel, 1.2);
|
|
||||||
const gray: u32 = @intFromFloat(pixel * 255);
|
|
||||||
const color: u32 = (255 << 24) | (gray << 16) | (gray << 8) | gray;
|
|
||||||
|
|
||||||
heightmap[x*700 + y] = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const terrain_vertex, const terrain_index = try Mesh.terrain(allocator, device, 700, 700, 10);
|
|
||||||
const heightmap_texture = try Texture.fromBytes(@alignCast(@ptrCast(heightmap)), device, 700, 700);
|
|
||||||
//const heightmap_texture = try Texture.init("assets/textures/heightmap.png", device);
|
|
||||||
try terrain_pipeline.setHeightmap(device, heightmap_texture);
|
|
||||||
const texture = try Texture.init("assets/textures/container.png", device);
|
const texture = try Texture.init("assets/textures/container.png", device);
|
||||||
const diffuse = try Texture.init("assets/textures/container_specular.png", device);
|
const diffuse = try Texture.init("assets/textures/container_specular.png", device);
|
||||||
|
|
||||||
|
|
@ -116,8 +94,6 @@ pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_hand
|
||||||
.previous_time = try std.time.Instant.now(),
|
.previous_time = try std.time.Instant.now(),
|
||||||
.mesh = mesh,
|
.mesh = mesh,
|
||||||
.current_image = undefined,
|
.current_image = undefined,
|
||||||
.terrain_vertex = terrain_vertex,
|
|
||||||
.terrain_index = terrain_index,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
70
src/rendering/Terrain.zig
Normal file
70
src/rendering/Terrain.zig
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const vk = @import("vulkan.zig");
|
||||||
|
const Mesh = @import("Mesh.zig");
|
||||||
|
const math = @import("math");
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub const Generator = struct {
|
||||||
|
octaves: u32,
|
||||||
|
lacunarity: f64,
|
||||||
|
gain: f64,
|
||||||
|
scale: f64 = 0.01,
|
||||||
|
multiplier: f64,
|
||||||
|
exponent: f64 = 1.0,
|
||||||
|
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
seed: u64,
|
||||||
|
resolution: f32 = 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
heightmap: []f64,
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
seed: u64,
|
||||||
|
|
||||||
|
texture: vk.Texture,
|
||||||
|
vertex_buffer: vk.Buffer,
|
||||||
|
index_buffer: vk.Buffer,
|
||||||
|
|
||||||
|
pub fn init(allocator: std.mem.Allocator, device: vk.Device, generator: Generator) !Self {
|
||||||
|
const perlin: math.PerlinNoise = .{ .seed = generator.seed };
|
||||||
|
const heightmap = try allocator.alloc(f64, generator.width * generator.height);
|
||||||
|
const heightmap_data = try allocator.alloc(u32, generator.width * generator.height);
|
||||||
|
defer allocator.free(heightmap_data);
|
||||||
|
for (0..generator.width) |x| {
|
||||||
|
for (0..generator.height) |y| {
|
||||||
|
var pixel = (perlin.fbm(@as(f64, @floatFromInt(x)) * generator.scale, @as(f64, @floatFromInt(y)) * generator.scale, generator.octaves, generator.lacunarity, generator.gain) * generator.multiplier);
|
||||||
|
pixel = std.math.pow(f64, pixel, generator.exponent);
|
||||||
|
const gray: u32 = @intFromFloat(pixel * 255);
|
||||||
|
const color: u32 = (255 << 24) | (gray << 16) | (gray << 8) | gray;
|
||||||
|
|
||||||
|
heightmap[x*generator.width + y] = pixel;
|
||||||
|
heightmap_data[x*generator.width + y] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const vertex_buffer, const index_buffer = try Mesh.terrain(allocator, device, generator.width, generator.height, generator.resolution);
|
||||||
|
const heightmap_texture = try vk.Texture.fromBytes(@alignCast(@ptrCast(heightmap_data)), device, generator.width, generator.height);
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.heightmap = heightmap,
|
||||||
|
.width = generator.width,
|
||||||
|
.height = generator.height,
|
||||||
|
.seed = generator.seed,
|
||||||
|
.vertex_buffer = vertex_buffer,
|
||||||
|
.index_buffer = index_buffer,
|
||||||
|
.texture = heightmap_texture,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Self, allocator: std.mem.Allocator, device: vk.Device) !void {
|
||||||
|
allocator.free(self.heightmap);
|
||||||
|
self.vertex_buffer.deinit(device.handle);
|
||||||
|
self.index_buffer.deinit(device.handle);
|
||||||
|
self.texture.deinit(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getHeight(self: Self, x: usize, y: usize) f64 {
|
||||||
|
return self.heightmap[x*self.width + y];
|
||||||
|
}
|
||||||
|
|
@ -3,3 +3,4 @@ pub const vk = @import("vulkan.zig");
|
||||||
pub const Camera = @import("Camera.zig");
|
pub const Camera = @import("Camera.zig");
|
||||||
pub const Renderer = @import("Renderer.zig");
|
pub const Renderer = @import("Renderer.zig");
|
||||||
pub const lights = @import("lights.zig");
|
pub const lights = @import("lights.zig");
|
||||||
|
pub const Terrain = @import("Terrain.zig");
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ export fn sideros_init(init: api.GameInit) callconv(.c) void {
|
||||||
.camera = &camera,
|
.camera = &camera,
|
||||||
.renderer = undefined,
|
.renderer = undefined,
|
||||||
.input = &input,
|
.input = &input,
|
||||||
|
.terrain = undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
ecs.hooks.init(allocator) catch @panic("TODO: handle this");
|
ecs.hooks.init(allocator) catch @panic("TODO: handle this");
|
||||||
|
|
@ -143,6 +144,23 @@ export fn sideros_init(init: api.GameInit) callconv(.c) void {
|
||||||
pool = ecs.Pool.init(allocator, &resources) catch @panic("TODO: Gracefully handle error");
|
pool = ecs.Pool.init(allocator, &resources) catch @panic("TODO: Gracefully handle error");
|
||||||
// TODO(ernesto): I think this @ptrCast are unavoidable but maybe not?
|
// TODO(ernesto): I think this @ptrCast are unavoidable but maybe not?
|
||||||
renderer = Renderer.init(allocator, @ptrCast(init.instance), @ptrCast(init.surface)) catch @panic("TODO: Gracefully handle error");
|
renderer = Renderer.init(allocator, @ptrCast(init.instance), @ptrCast(init.surface)) catch @panic("TODO: Gracefully handle error");
|
||||||
|
|
||||||
|
resources.terrain = rendering.Terrain.init(allocator, renderer.device, .{
|
||||||
|
.octaves = 8,
|
||||||
|
.lacunarity = 3.0,
|
||||||
|
.gain = 0.5,
|
||||||
|
.scale = 0.01,
|
||||||
|
.multiplier = 3.0,
|
||||||
|
.exponent = 1.2,
|
||||||
|
|
||||||
|
.width = 700,
|
||||||
|
.height = 700,
|
||||||
|
.seed = 12345678,
|
||||||
|
.resolution = 10.0,
|
||||||
|
}) catch @panic("TODO: handle this");
|
||||||
|
|
||||||
|
renderer.terrain_pipeline.setHeightmap(renderer.device, resources.terrain.texture) catch @panic("TODO: handle this");
|
||||||
|
|
||||||
pool.addSystemGroup(&[_]ecs.System{systems.render, systems.moveCamera}, true) catch @panic("TODO: Gracefuly handle error");
|
pool.addSystemGroup(&[_]ecs.System{systems.render, systems.moveCamera}, true) catch @panic("TODO: Gracefuly handle error");
|
||||||
pool.resources.renderer = &renderer;
|
pool.resources.renderer = &renderer;
|
||||||
pool.tick();
|
pool.tick();
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ const Input = ecs.Input;
|
||||||
pub fn render(pool: *ecs.Pool) anyerror!void {
|
pub fn render(pool: *ecs.Pool) anyerror!void {
|
||||||
var renderer = pool.resources.renderer;
|
var renderer = pool.resources.renderer;
|
||||||
const camera = pool.resources.camera;
|
const camera = pool.resources.camera;
|
||||||
|
const terrain = pool.resources.terrain;
|
||||||
|
|
||||||
const now = try std.time.Instant.now();
|
const now = try std.time.Instant.now();
|
||||||
const delta_time: f32 = @as(f32, @floatFromInt(now.since(renderer.previous_time))) / @as(f32, 1_000_000_000.0);
|
const delta_time: f32 = @as(f32, @floatFromInt(now.since(renderer.previous_time))) / @as(f32, 1_000_000_000.0);
|
||||||
|
|
@ -21,7 +22,7 @@ pub fn render(pool: *ecs.Pool) anyerror!void {
|
||||||
renderer.setLightCount(2);
|
renderer.setLightCount(2);
|
||||||
|
|
||||||
try renderer.beginTerrain();
|
try renderer.beginTerrain();
|
||||||
renderer.device.drawTerrain(@as(u32, @intCast(renderer.terrain_index.size/@sizeOf(u32))), renderer.current_frame, renderer.terrain_vertex, renderer.terrain_index);
|
renderer.device.drawTerrain(@as(u32, @intCast(terrain.index_buffer.size/@sizeOf(u32))), renderer.current_frame, terrain.vertex_buffer, terrain.index_buffer);
|
||||||
|
|
||||||
try renderer.beginGraphics();
|
try renderer.beginGraphics();
|
||||||
for (renderer.transforms.items, 0..) |transform, i| {
|
for (renderer.transforms.items, 0..) |transform, i| {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue