Add tracy profiler, use multi draw indirect for shadows, use Bistro scene
This commit is contained in:
parent
551f92c64e
commit
b4c3bcba94
BIN
assets/bistro.glb
(Stored with Git LFS)
Normal file
BIN
assets/bistro.glb
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -154,7 +154,7 @@ EvalMaterial evalMaterial() {
|
||||
result.albedo = textureSize(materials[materialIdx].albedo_map, 0) == ivec2(0) ? vec4(pow(materials[materialIdx].albedo.rgb, vec3(2.2)), materials[materialIdx].albedo.a) : texture(materials[materialIdx].albedo_map, VertexOut.uv * materials[materialIdx].albedo_map_uv_scale);
|
||||
float fMetallic = textureSize(materials[materialIdx].metallic_map, 0) == ivec2(0) ? materials[materialIdx].metallic : texture(materials[materialIdx].metallic_map, VertexOut.uv * materials[materialIdx].metallic_map_uv_scale).b;
|
||||
result.metallic = fMetallic > 0.1;
|
||||
result.roughness = max(1.0, textureSize(materials[materialIdx].roughness_map, 0) == ivec2(0) ? materials[materialIdx].roughness : texture(materials[materialIdx].roughness_map, VertexOut.uv * materials[materialIdx].roughness_map_uv_scale).g);
|
||||
result.roughness = max(0.01, textureSize(materials[materialIdx].roughness_map, 0) == ivec2(0) ? materials[materialIdx].roughness : texture(materials[materialIdx].roughness_map, VertexOut.uv * materials[materialIdx].roughness_map_uv_scale).g);
|
||||
result.emission = textureSize(materials[materialIdx].emission_map, 0) == ivec2(0) ? materials[materialIdx].emission : texture(materials[materialIdx].emission_map, VertexOut.uv * materials[materialIdx].emission_map_uv_scale).rgb;
|
||||
|
||||
return result;
|
||||
@ -169,7 +169,7 @@ vec3 schlickFresnel(EvalMaterial mat, float LDotH) {
|
||||
return f0 + (1 - f0) * pow(1.0 - LDotH, 5);
|
||||
}
|
||||
|
||||
const float eps = 0.0000001;
|
||||
const float eps = 0.0001;
|
||||
|
||||
float geomSmith(EvalMaterial mat, float DotVal) {
|
||||
float k = (mat.roughness + 1.0) * (mat.roughness + 1.0) / 8.0;
|
||||
@ -299,7 +299,7 @@ vec3 microfacetModel(EvalMaterial mat, int light_idx, vec3 P, vec3 N) {
|
||||
|
||||
shadow_mult = sum / 16.0;
|
||||
}
|
||||
shadow_mult = clamp(shadow_mult, 0.2, 1.0);
|
||||
shadow_mult = clamp(shadow_mult, 0.3, 1.0);
|
||||
|
||||
vec3 specBrdf = 0.25 * ggxDistribution(mat, NDotH) * schlickFresnel(mat, LDotH) * geomSmith(mat, NDotL) * geomSmith(mat, NDotV);
|
||||
|
||||
@ -311,6 +311,7 @@ void main() {
|
||||
sampler2D normal_map = materials[materialIdx].normal_map;
|
||||
vec2 normal_map_uv_scale = materials[materialIdx].normal_map_uv_scale;
|
||||
EvalMaterial material = evalMaterial();
|
||||
material.roughness = material.albedo.a < 1.0 ? 1.0 : material.roughness;
|
||||
|
||||
vec3 N = textureSize(normal_map, 0) == ivec2(0) ? vec3(0.5) : vec3(texture(normal_map, VertexOut.uv * normal_map_uv_scale).xy, 0);
|
||||
N = N * 2.0 - 1.0;
|
||||
|
@ -4,8 +4,10 @@ layout(std140, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
};
|
||||
|
||||
// Uniforms
|
||||
layout(location = 1) uniform mat4 model;
|
||||
layout(std430, binding = 3) readonly buffer DrawCmdDatas {
|
||||
// Access by gl_DrawID
|
||||
mat4 transforms[];
|
||||
};
|
||||
|
||||
// Input, output blocks
|
||||
|
||||
@ -14,6 +16,7 @@ layout(location = 1) uniform mat4 model;
|
||||
layout(location = 0) in vec3 aPos;
|
||||
|
||||
void main() {
|
||||
mat4 model = transforms[gl_DrawID];
|
||||
gl_Position = projection * view * model * vec4(aPos.xyz, 1.0);
|
||||
}
|
||||
#endif // VERTEX_SHADER
|
||||
|
@ -23,6 +23,10 @@ pub fn build(b: *Build) void {
|
||||
"Prioritize performance, safety, or binary size for build time tools",
|
||||
) orelse .Debug;
|
||||
|
||||
const tracy = b.dependency("zig-tracy", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
const zalgebra_dep = b.dependency("zalgebra", .{});
|
||||
|
||||
const assets_mod = b.addModule("assets", .{ .root_source_file = .{ .src_path = .{ .owner = b, .sub_path = "src/assets/root.zig" } } });
|
||||
@ -62,6 +66,8 @@ pub fn build(b: *Build) void {
|
||||
l.root_module.addImport("zalgebra", zalgebra_dep.module("zalgebra"));
|
||||
l.root_module.addImport("assets", assets_mod);
|
||||
l.root_module.addImport("asset_manifest", asset_manifest_mod);
|
||||
l.root_module.addImport("tracy", tracy.module("tracy"));
|
||||
l.linkLibrary(tracy.artifact("tracy"));
|
||||
}
|
||||
|
||||
const install_lib = b.addInstallArtifact(lib, .{ .dest_dir = .{ .override = .prefix } });
|
||||
@ -150,6 +156,8 @@ const asset_extensions = [_][]const u8{
|
||||
"glsl",
|
||||
"prog",
|
||||
"png",
|
||||
"dds",
|
||||
"tga",
|
||||
"jpg",
|
||||
"exr",
|
||||
"fbx",
|
||||
|
@ -27,6 +27,10 @@
|
||||
.url = "https://github.com/sergeypdev/zalgebra/tarball/43371bf211ad574cde90f653fea171f1cccb1716",
|
||||
.hash = "1220e1439198c5206dbb924420aac0f57dd11fd4b6639e1aa9559abc09f91bfd2c9a",
|
||||
},
|
||||
.@"zig-tracy" = .{
|
||||
.url = "https://github.com/sergeypdev/zig-tracy/tarball/2b818574810a66deacc424298c1a7679ca6e4375",
|
||||
.hash = "1220638bc94d67225a620e1abd71d85b299c8b764490fd51233ed73d76ee44cc5835",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
// This makes *all* files, recursively, included in this package. It is generally
|
||||
|
@ -24,6 +24,7 @@ const checkGLError = @import("Render.zig").checkGLError;
|
||||
const BuddyAllocator = @import("BuddyAllocator.zig");
|
||||
const Vec2 = @import("zalgebra").Vec2;
|
||||
const Vec3 = @import("zalgebra").Vec3;
|
||||
const tracy = @import("tracy");
|
||||
|
||||
pub const AssetId = assets.AssetId;
|
||||
pub const Handle = assets.Handle;
|
||||
@ -158,6 +159,9 @@ pub fn resolveMaterial(self: *AssetManager, handle: Handle.Material) formats.Mat
|
||||
|
||||
// TODO: proper watching
|
||||
pub fn watchChanges(self: *AssetManager) void {
|
||||
const zone = tracy.initZone(@src(), .{ .name = "AssetManager.watchChanges" });
|
||||
defer zone.deinit();
|
||||
|
||||
var iter = self.loaded_assets.iterator();
|
||||
while (iter.next()) |entry| {
|
||||
const gop = self.modified_times.getOrPut(self.allocator, entry.key_ptr.*) catch return;
|
||||
|
163
src/Render.zig
163
src/Render.zig
@ -7,6 +7,7 @@ const globals = @import("globals.zig");
|
||||
pub const Material = @import("formats.zig").Material;
|
||||
const math = @import("math.zig");
|
||||
const formats = @import("formats.zig");
|
||||
const tracy = @import("tracy");
|
||||
|
||||
const za = @import("zalgebra");
|
||||
const Vec2 = za.Vec2;
|
||||
@ -438,13 +439,17 @@ pub fn draw(self: *Render, cmd: DrawCommand) void {
|
||||
}
|
||||
|
||||
pub fn finish(self: *Render) void {
|
||||
const ginit = globals.g_init;
|
||||
const zone = tracy.initZone(@src(), .{ .name = "Render.finish" });
|
||||
defer zone.deinit();
|
||||
|
||||
const camera_projection = self.camera.projection();
|
||||
const view_proj = camera_projection.mul(self.camera.view_mat);
|
||||
|
||||
// Sort draw calls: opaque -> blended
|
||||
{
|
||||
const zoneSort = tracy.initZone(@src(), .{ .name = "Render.finish_sortDraws" });
|
||||
defer zoneSort.deinit();
|
||||
|
||||
const cmds = self.command_buffer[0..self.command_count];
|
||||
std.mem.sortUnstable(DrawCommand, cmds, self, struct {
|
||||
pub fn lessThan(render: *const Render, lhs: DrawCommand, rhs: DrawCommand) bool {
|
||||
@ -500,6 +505,9 @@ pub fn finish(self: *Render) void {
|
||||
|
||||
// Light shadow maps
|
||||
{
|
||||
const zoneShadowmaps = tracy.initZone(@src(), .{ .name = "Render.finish_shadowmaps" });
|
||||
defer zoneShadowmaps.deinit();
|
||||
|
||||
gl.enable(gl.DEPTH_CLAMP);
|
||||
defer gl.disable(gl.DEPTH_CLAMP);
|
||||
|
||||
@ -737,55 +745,62 @@ pub fn finish(self: *Render) void {
|
||||
checkGLError();
|
||||
defer gl.deleteBuffers(1, &draw_cmd_data_buf);
|
||||
|
||||
const materials = self.materials_pbr_ssbo.getInstance(self.tripple_buffer_index);
|
||||
materials.count.* = 0;
|
||||
|
||||
var material_map = std.StringHashMap(i32).init(self.frame_arena);
|
||||
|
||||
var materials_count: usize = 0;
|
||||
var rendered_count: usize = 0;
|
||||
cmds: for (self.command_buffer[0..self.command_count]) |*cmd| {
|
||||
const mesh = self.assetman.resolveMesh(cmd.mesh);
|
||||
const aabb = math.AABB.fromMinMax(mesh.aabb.min, mesh.aabb.max);
|
||||
|
||||
if (!self.world_camera_frustum.intersectAABB(aabb.transform(cmd.transform))) {
|
||||
continue;
|
||||
// Prepare indirect draw commands
|
||||
{
|
||||
const zonePrepareInidirectDraws = tracy.initZone(@src(), .{ .name = "Render.finish_PrepareInidirectDraws" });
|
||||
defer zonePrepareInidirectDraws.deinit();
|
||||
|
||||
const materials = self.materials_pbr_ssbo.getInstance(self.tripple_buffer_index);
|
||||
materials.count.* = 0;
|
||||
|
||||
var material_map = std.StringHashMap(i32).init(self.frame_arena);
|
||||
|
||||
var materials_count: usize = 0;
|
||||
cmds: for (self.command_buffer[0..self.command_count]) |*cmd| {
|
||||
const mesh = self.assetman.resolveMesh(cmd.mesh);
|
||||
// const aabb = math.AABB.fromMinMax(mesh.aabb.min, mesh.aabb.max);
|
||||
|
||||
// if (!self.world_camera_frustum.intersectAABB(aabb.transform(cmd.transform))) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
const material: Material = if (cmd.material_override) |mat| mat else mesh.material;
|
||||
|
||||
// Opaque objects are drawn, start rendering alpha blended objects
|
||||
if (material.blend_mode == .AlphaBlend and !switched_to_alpha_blend) {
|
||||
break :cmds;
|
||||
// switched_to_alpha_blend = true;
|
||||
// gl.enable(gl.BLEND);
|
||||
// gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
const material_bytes = std.mem.asBytes(&material);
|
||||
const material_copy = self.frame_arena.alloc(u8, material_bytes.len) catch @panic("OOM");
|
||||
@memcpy(material_copy, material_bytes);
|
||||
const gop = material_map.getOrPut(material_copy) catch @panic("OOM");
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = @intCast(materials_count);
|
||||
materials.data[materials_count] = MaterialPBR.fromMaterial(self.assetman, &material);
|
||||
materials_count += 1;
|
||||
}
|
||||
|
||||
draw_cmd_data[rendered_count] = DrawCommandData{
|
||||
.transform = cmd.transform,
|
||||
.material_index = gop.value_ptr.*,
|
||||
};
|
||||
|
||||
draw_indirect_cmds[rendered_count] = DrawIndirectCmd{
|
||||
.count = mesh.indices.count,
|
||||
.instance_count = 1,
|
||||
.first_index = mesh.indices.offset / 4,
|
||||
.base_vertex = mesh.indices.base_vertex,
|
||||
.base_instance = 0,
|
||||
};
|
||||
|
||||
rendered_count += 1;
|
||||
}
|
||||
|
||||
const material: Material = if (cmd.material_override) |mat| mat else mesh.material;
|
||||
|
||||
// Opaque objects are drawn, start rendering alpha blended objects
|
||||
if (material.blend_mode == .AlphaBlend and !switched_to_alpha_blend) {
|
||||
break :cmds;
|
||||
// switched_to_alpha_blend = true;
|
||||
// gl.enable(gl.BLEND);
|
||||
// gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
const material_bytes = std.mem.asBytes(&material);
|
||||
const material_copy = self.frame_arena.alloc(u8, material_bytes.len) catch @panic("OOM");
|
||||
@memcpy(material_copy, material_bytes);
|
||||
const gop = material_map.getOrPut(material_copy) catch @panic("OOM");
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = @intCast(materials_count);
|
||||
materials.data[materials_count] = MaterialPBR.fromMaterial(self.assetman, &material);
|
||||
materials_count += 1;
|
||||
}
|
||||
|
||||
draw_cmd_data[rendered_count] = DrawCommandData{
|
||||
.transform = cmd.transform,
|
||||
.material_index = gop.value_ptr.*,
|
||||
};
|
||||
|
||||
draw_indirect_cmds[rendered_count] = DrawIndirectCmd{
|
||||
.count = mesh.indices.count,
|
||||
.instance_count = 1,
|
||||
.first_index = mesh.indices.offset / 4,
|
||||
.base_vertex = mesh.indices.base_vertex,
|
||||
.base_instance = 0,
|
||||
};
|
||||
|
||||
rendered_count += 1;
|
||||
}
|
||||
|
||||
{
|
||||
@ -992,8 +1007,6 @@ pub fn finish(self: *Render) void {
|
||||
}
|
||||
|
||||
self.gl_fences[self.tripple_buffer_index] = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
c.SDL_GL_SwapWindow(ginit.window);
|
||||
//c.SDL_Delay(1);
|
||||
}
|
||||
|
||||
pub fn pointLightRange(self: *const PointLight) f32 {
|
||||
@ -1044,26 +1057,50 @@ const cube_camera_dirs = [6]CubeCameraDir{
|
||||
};
|
||||
|
||||
fn renderShadow(self: *Render, frustum: *const math.Frustum) void {
|
||||
const zone = tracy.initZone(@src(), .{ .name = "Render.renderShadow" });
|
||||
defer zone.deinit();
|
||||
_ = frustum; // autofix
|
||||
self.assetman.vertex_heap.vertices.bind(Render.Attrib.Position.value());
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer);
|
||||
|
||||
// TODO: this wastes space in temp allocator
|
||||
var draw_indirect_cmds = std.ArrayList(DrawIndirectCmd).init(self.frame_arena);
|
||||
var transforms = std.ArrayList(Mat4).init(self.frame_arena);
|
||||
|
||||
for (self.command_buffer[0..self.command_count]) |*cmd| {
|
||||
const mesh = self.assetman.resolveMesh(cmd.mesh);
|
||||
const aabb = math.AABB.fromMinMax(mesh.aabb.min, mesh.aabb.max);
|
||||
// const aabb = math.AABB.fromMinMax(mesh.aabb.min, mesh.aabb.max);
|
||||
|
||||
if (!frustum.intersectAABBSkipNear(aabb.transform(cmd.transform))) {
|
||||
continue;
|
||||
}
|
||||
// if (!frustum.intersectAABBSkipNear(aabb.transform(cmd.transform))) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
gl.uniformMatrix4fv(Uniform.ModelMatrix.value(), 1, gl.FALSE, @ptrCast(&cmd.transform.data));
|
||||
mesh.positions.bind(Render.Attrib.Position.value());
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indices.buffer);
|
||||
const draw_indirect_cmd = draw_indirect_cmds.addOne() catch @panic("OOM");
|
||||
const transform = transforms.addOne() catch @panic("OOM");
|
||||
|
||||
gl.drawElementsBaseVertex(
|
||||
gl.TRIANGLES,
|
||||
@intCast(mesh.indices.count),
|
||||
mesh.indices.type,
|
||||
@ptrFromInt(mesh.indices.offset),
|
||||
mesh.indices.base_vertex,
|
||||
);
|
||||
draw_indirect_cmd.* = .{
|
||||
.count = mesh.indices.count,
|
||||
.instance_count = 1,
|
||||
.first_index = mesh.indices.offset / 4,
|
||||
.base_vertex = mesh.indices.base_vertex,
|
||||
.base_instance = 0,
|
||||
};
|
||||
|
||||
transform.* = cmd.transform;
|
||||
}
|
||||
|
||||
var bufs = [2]gl.GLuint{ 0, 0 };
|
||||
gl.createBuffers(bufs.len, &bufs);
|
||||
checkGLError();
|
||||
defer _ = gl.deleteBuffers(bufs.len, &bufs);
|
||||
|
||||
gl.namedBufferStorage(bufs[0], @intCast(@sizeOf(DrawIndirectCmd) * draw_indirect_cmds.items.len), draw_indirect_cmds.items.ptr, 0);
|
||||
gl.namedBufferStorage(bufs[1], @intCast(@sizeOf(Mat4) * transforms.items.len), transforms.items.ptr, 0);
|
||||
|
||||
gl.bindBuffer(gl.DRAW_INDIRECT_BUFFER, bufs[0]);
|
||||
gl.bindBufferBase(gl.SHADER_STORAGE_BUFFER, SSBO.DrawCommandData.value(), bufs[1]);
|
||||
|
||||
gl.multiDrawElementsIndirect(gl.TRIANGLES, gl.UNSIGNED_INT, null, @intCast(draw_indirect_cmds.items.len), 0);
|
||||
}
|
||||
|
||||
pub fn checkGLError() void {
|
||||
|
331
src/game.zig
331
src/game.zig
@ -15,6 +15,7 @@ const Mat4 = za.Mat4;
|
||||
const Quat = za.Quat;
|
||||
const a = @import("asset_manifest");
|
||||
const windows = std.os.windows;
|
||||
const tracy = @import("tracy");
|
||||
|
||||
pub extern "dwmapi" fn DwmEnableMMCSS(fEnableMMCSS: windows.BOOL) callconv(windows.WINAPI) windows.HRESULT;
|
||||
pub extern "dwmapi" fn DwmFlush() callconv(windows.WINAPI) void;
|
||||
@ -161,6 +162,7 @@ const mesh_program = a.ShaderPrograms.mesh;
|
||||
|
||||
export fn game_init(global_allocator: *std.mem.Allocator) void {
|
||||
loadGL();
|
||||
tracy.startupProfiler();
|
||||
|
||||
std.log.debug("game_init\n", .{});
|
||||
globals.g_mem = global_allocator.create(GameMemory) catch @panic("OOM");
|
||||
@ -188,8 +190,8 @@ export fn game_init(global_allocator: *std.mem.Allocator) void {
|
||||
|
||||
_ = globals.g_mem.world.addEntity(.{
|
||||
.flags = .{ .dir_light = true, .rotate = true },
|
||||
.transform = .{ .rot = Quat.fromEulerAngles(Vec3.new(20, 0, 0)) },
|
||||
.light = .{ .color_intensity = Vec4.new(1, 1, 0.83, 0.7) },
|
||||
.transform = .{ .rot = Quat.fromEulerAngles(Vec3.new(70, 0, 0)) },
|
||||
.light = .{ .color_intensity = Vec4.new(std.math.pow(f32, 1, 2.2), std.math.pow(f32, 0.9568627450980393, 2.2), std.math.pow(f32, 0.9176470588235294, 2.2), 1.0) },
|
||||
.rotate = .{ .axis = Vec3.up(), .rate = -10 },
|
||||
});
|
||||
|
||||
@ -224,70 +226,72 @@ export fn game_init(global_allocator: *std.mem.Allocator) void {
|
||||
// });
|
||||
|
||||
// Plane
|
||||
_ = globals.g_mem.world.addEntity(.{
|
||||
.flags = .{ .mesh = true },
|
||||
.transform = .{ .scale = Vec3.one().scale(10) },
|
||||
.mesh = .{
|
||||
.handle = a.Meshes.plane.Plane,
|
||||
.material = .{
|
||||
.albedo = Vec4.one(),
|
||||
.normal_map = a.Textures.@"tile.norm",
|
||||
},
|
||||
.override_material = true,
|
||||
},
|
||||
});
|
||||
// _ = globals.g_mem.world.addEntity(.{
|
||||
// .flags = .{ .mesh = true },
|
||||
// .transform = .{ .scale = Vec3.one().scale(10) },
|
||||
// .mesh = .{
|
||||
// .handle = a.Meshes.plane.Plane,
|
||||
// .material = .{
|
||||
// .albedo = Vec4.one(),
|
||||
// .normal_map = a.Textures.@"tile.norm",
|
||||
// },
|
||||
// .override_material = true,
|
||||
// },
|
||||
// });
|
||||
|
||||
// 10 dielectric bunnies
|
||||
{
|
||||
for (0..100) |y| {
|
||||
for (0..10) |x| {
|
||||
_ = globals.g_mem.world.addEntity(.{
|
||||
.transform = .{ .pos = Vec3.new(@as(f32, @floatFromInt(x)) * 0.3 - 0.3 * 4.5, 0, @as(f32, @floatFromInt(y)) * 0.3 - 0.3 * 4.5) },
|
||||
// {
|
||||
// for (0..100) |y| {
|
||||
// for (0..1) |x| {
|
||||
// _ = globals.g_mem.world.addEntity(.{
|
||||
// .transform = .{ .pos = Vec3.new(@as(f32, @floatFromInt(x)) * 0.3 - 0.3 * 4.5, 0, @as(f32, @floatFromInt(y)) * 0.3 - 0.3 * 4.5) },
|
||||
|
||||
.flags = .{ .mesh = true },
|
||||
.mesh = .{
|
||||
.handle = a.Meshes.bunny.BunnyStanfordUVUnwrapped_res1_bun_zipper_res1,
|
||||
.material = .{
|
||||
.albedo_map = a.Textures.bunny_tex1,
|
||||
// .normal_map = a.Textures.@"tile.norm",
|
||||
.roughness = @as(f32, @floatFromInt(y)) / 100.0,
|
||||
},
|
||||
.override_material = true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// 10 metallic bunnies
|
||||
{
|
||||
for (0..10) |i| {
|
||||
_ = globals.g_mem.world.addEntity(.{
|
||||
.transform = .{ .pos = Vec3.new(@as(f32, @floatFromInt(i)) * 0.3 - 0.3 * 4.5, 0.3, 0) },
|
||||
// .flags = .{ .mesh = true },
|
||||
// .mesh = .{
|
||||
// .handle = a.Meshes.bunny.BunnyStanfordUVUnwrapped_res1_bun_zipper_res1,
|
||||
// .material = .{
|
||||
// .albedo_map = a.Textures.bunny_tex1,
|
||||
// // .normal_map = a.Textures.@"tile.norm",
|
||||
// .roughness = @as(f32, @floatFromInt(y)) / 100.0,
|
||||
// },
|
||||
// .override_material = true,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // 10 metallic bunnies
|
||||
// {
|
||||
// for (0..10) |i| {
|
||||
// _ = globals.g_mem.world.addEntity(.{
|
||||
// .transform = .{ .pos = Vec3.new(@as(f32, @floatFromInt(i)) * 0.3 - 0.3 * 4.5, 0.3, 0) },
|
||||
|
||||
.flags = .{ .mesh = true },
|
||||
.mesh = .{
|
||||
.handle = a.Meshes.bunny.BunnyStanfordUVUnwrapped_res1_bun_zipper_res1,
|
||||
.material = .{
|
||||
.blend_mode = .AlphaBlend,
|
||||
.albedo = Vec4.new(1.000, 0.766, 0.336, 0.5),
|
||||
// .albedo_map = a.Textures.bunny_tex1,
|
||||
// .normal_map = a.Textures.@"tile.norm",
|
||||
.roughness = @as(f32, @floatFromInt(i + 1)) / 10.0,
|
||||
.metallic = 1.0,
|
||||
},
|
||||
.override_material = true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
// .flags = .{ .mesh = true },
|
||||
// .mesh = .{
|
||||
// .handle = a.Meshes.bunny.BunnyStanfordUVUnwrapped_res1_bun_zipper_res1,
|
||||
// .material = .{
|
||||
// .blend_mode = .AlphaBlend,
|
||||
// .albedo = Vec4.new(1.000, 0.766, 0.336, 0.5),
|
||||
// // .albedo_map = a.Textures.bunny_tex1,
|
||||
// // .normal_map = a.Textures.@"tile.norm",
|
||||
// .roughness = @as(f32, @floatFromInt(i + 1)) / 10.0,
|
||||
// .metallic = 1.0,
|
||||
// },
|
||||
// .override_material = true,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
const scene = globals.g_mem.world.createScene(globals.g_assetman.resolveScene(a.Scenes.amd_ryzen_9.scene));
|
||||
const scene = globals.g_mem.world.createScene(globals.g_assetman.resolveScene(a.Scenes.bistro.scene));
|
||||
const ent = globals.g_mem.world.getEntity(scene) orelse @panic("WTF");
|
||||
ent.data.transform.pos = Vec3.new(0, 1, 0);
|
||||
ent.data.transform.scale = Vec3.one().scale(0.2);
|
||||
ent.data.transform.pos = Vec3.new(0, 0, 0);
|
||||
// ent.data.transform.scale = Vec3.one().scale(1.0);
|
||||
}
|
||||
|
||||
export fn game_update() bool {
|
||||
const zoneGameUpdate = tracy.initZone(@src(), .{});
|
||||
defer zoneGameUpdate.deinit();
|
||||
const ginit = globals.g_init;
|
||||
const gmem = globals.g_mem;
|
||||
// std.debug.print("FPS: {d}\n", .{1.0 / g_mem.delta_time});
|
||||
@ -298,108 +302,112 @@ export fn game_update() bool {
|
||||
var move = Vec3.zero();
|
||||
var look = Vec2.zero();
|
||||
|
||||
while (c.SDL_PollEvent(&event) != 0) {
|
||||
switch (event.type) {
|
||||
c.SDL_QUIT => {
|
||||
return false;
|
||||
},
|
||||
c.SDL_MOUSEMOTION => {
|
||||
if (gmem.mouse_focus) {
|
||||
look.xMut().* += @floatFromInt(event.motion.xrel);
|
||||
look.yMut().* += @floatFromInt(event.motion.yrel);
|
||||
}
|
||||
},
|
||||
c.SDL_MOUSEBUTTONUP => {
|
||||
if (!gmem.mouse_focus) {
|
||||
_ = c.SDL_SetRelativeMouseMode(c.SDL_TRUE);
|
||||
{
|
||||
const zone = tracy.initZone(@src(), .{ .name = "SDL poll events" });
|
||||
defer zone.deinit();
|
||||
while (c.SDL_PollEvent(&event) != 0) {
|
||||
switch (event.type) {
|
||||
c.SDL_QUIT => {
|
||||
return false;
|
||||
},
|
||||
c.SDL_MOUSEMOTION => {
|
||||
if (gmem.mouse_focus) {
|
||||
look.xMut().* += @floatFromInt(event.motion.xrel);
|
||||
look.yMut().* += @floatFromInt(event.motion.yrel);
|
||||
}
|
||||
},
|
||||
c.SDL_MOUSEBUTTONUP => {
|
||||
if (!gmem.mouse_focus) {
|
||||
_ = c.SDL_SetRelativeMouseMode(c.SDL_TRUE);
|
||||
|
||||
gmem.mouse_focus = true;
|
||||
}
|
||||
},
|
||||
c.SDL_MOUSEWHEEL => {
|
||||
if (gmem.mouse_focus) {
|
||||
gmem.free_cam.move_speed = @max(gmem.free_cam.move_speed + event.wheel.preciseY * 0.1, 0);
|
||||
}
|
||||
},
|
||||
c.SDL_KEYUP, c.SDL_KEYDOWN => {
|
||||
const pressed = event.key.state == c.SDL_PRESSED;
|
||||
gmem.mouse_focus = true;
|
||||
}
|
||||
},
|
||||
c.SDL_MOUSEWHEEL => {
|
||||
if (gmem.mouse_focus) {
|
||||
gmem.free_cam.move_speed = @max(gmem.free_cam.move_speed + event.wheel.preciseY * 0.1, 0);
|
||||
}
|
||||
},
|
||||
c.SDL_KEYUP, c.SDL_KEYDOWN => {
|
||||
const pressed = event.key.state == c.SDL_PRESSED;
|
||||
|
||||
switch (event.key.keysym.scancode) {
|
||||
// Toggle fullscreen
|
||||
c.SDL_SCANCODE_RETURN => {
|
||||
if (event.type == c.SDL_KEYDOWN and event.key.keysym.mod & c.KMOD_ALT > 0) {
|
||||
toggleFullScreen() catch continue;
|
||||
}
|
||||
},
|
||||
// Toggle vsync
|
||||
c.SDL_SCANCODE_F10 => {
|
||||
if (event.type == c.SDL_KEYDOWN) {
|
||||
const newSwap: c_int = if (ginit.vsync) 0 else 1;
|
||||
sdl_try(c.SDL_GL_SetSwapInterval(newSwap)) catch continue;
|
||||
ginit.vsync = !ginit.vsync;
|
||||
}
|
||||
},
|
||||
// Freeze view frustum
|
||||
c.SDL_SCANCODE_F8 => {
|
||||
if (event.type == c.SDL_KEYDOWN) {
|
||||
gmem.render.update_view_frustum = !gmem.render.update_view_frustum;
|
||||
}
|
||||
},
|
||||
// Expand camera far
|
||||
c.SDL_SCANCODE_F7 => {
|
||||
if (event.type == c.SDL_KEYDOWN) {
|
||||
if (gmem.render.camera.far == 10) {
|
||||
gmem.render.camera.far = 50;
|
||||
} else {
|
||||
gmem.render.camera.far = 10;
|
||||
}
|
||||
}
|
||||
},
|
||||
c.SDL_SCANCODE_ESCAPE => {
|
||||
if (event.type == c.SDL_KEYUP) {
|
||||
if (ginit.fullscreen) {
|
||||
switch (event.key.keysym.scancode) {
|
||||
// Toggle fullscreen
|
||||
c.SDL_SCANCODE_RETURN => {
|
||||
if (event.type == c.SDL_KEYDOWN and event.key.keysym.mod & c.KMOD_ALT > 0) {
|
||||
toggleFullScreen() catch continue;
|
||||
} else if (gmem.mouse_focus) {
|
||||
_ = c.SDL_SetRelativeMouseMode(c.SDL_FALSE);
|
||||
gmem.mouse_focus = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
c.SDL_SCANCODE_W => {
|
||||
gmem.input_state.forward = pressed;
|
||||
},
|
||||
c.SDL_SCANCODE_S => {
|
||||
gmem.input_state.backward = pressed;
|
||||
},
|
||||
c.SDL_SCANCODE_A => {
|
||||
gmem.input_state.left = pressed;
|
||||
},
|
||||
c.SDL_SCANCODE_D => {
|
||||
gmem.input_state.right = pressed;
|
||||
},
|
||||
c.SDL_SCANCODE_SPACE => {
|
||||
gmem.input_state.up = pressed;
|
||||
},
|
||||
c.SDL_SCANCODE_LCTRL => {
|
||||
gmem.input_state.down = pressed;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
c.SDL_WINDOWEVENT => {
|
||||
switch (event.window.event) {
|
||||
c.SDL_WINDOWEVENT_SIZE_CHANGED => {
|
||||
c.SDL_GL_GetDrawableSize(ginit.window, &ginit.width, &ginit.height);
|
||||
std.log.debug("w: {}, h: {}\n", .{ ginit.width, ginit.height });
|
||||
},
|
||||
// Toggle vsync
|
||||
c.SDL_SCANCODE_F10 => {
|
||||
if (event.type == c.SDL_KEYDOWN) {
|
||||
const newSwap: c_int = if (ginit.vsync) 0 else 1;
|
||||
sdl_try(c.SDL_GL_SetSwapInterval(newSwap)) catch continue;
|
||||
ginit.vsync = !ginit.vsync;
|
||||
}
|
||||
},
|
||||
// Freeze view frustum
|
||||
c.SDL_SCANCODE_F8 => {
|
||||
if (event.type == c.SDL_KEYDOWN) {
|
||||
gmem.render.update_view_frustum = !gmem.render.update_view_frustum;
|
||||
}
|
||||
},
|
||||
// Expand camera far
|
||||
c.SDL_SCANCODE_F7 => {
|
||||
if (event.type == c.SDL_KEYDOWN) {
|
||||
if (gmem.render.camera.far == 10) {
|
||||
gmem.render.camera.far = 50;
|
||||
} else {
|
||||
gmem.render.camera.far = 10;
|
||||
}
|
||||
}
|
||||
},
|
||||
c.SDL_SCANCODE_ESCAPE => {
|
||||
if (event.type == c.SDL_KEYUP) {
|
||||
if (ginit.fullscreen) {
|
||||
toggleFullScreen() catch continue;
|
||||
} else if (gmem.mouse_focus) {
|
||||
_ = c.SDL_SetRelativeMouseMode(c.SDL_FALSE);
|
||||
gmem.mouse_focus = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
c.SDL_SCANCODE_W => {
|
||||
gmem.input_state.forward = pressed;
|
||||
},
|
||||
c.SDL_SCANCODE_S => {
|
||||
gmem.input_state.backward = pressed;
|
||||
},
|
||||
c.SDL_SCANCODE_A => {
|
||||
gmem.input_state.left = pressed;
|
||||
},
|
||||
c.SDL_SCANCODE_D => {
|
||||
gmem.input_state.right = pressed;
|
||||
},
|
||||
c.SDL_SCANCODE_SPACE => {
|
||||
gmem.input_state.up = pressed;
|
||||
},
|
||||
c.SDL_SCANCODE_LCTRL => {
|
||||
gmem.input_state.down = pressed;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
c.SDL_WINDOWEVENT => {
|
||||
switch (event.window.event) {
|
||||
c.SDL_WINDOWEVENT_SIZE_CHANGED => {
|
||||
c.SDL_GL_GetDrawableSize(ginit.window, &ginit.width, &ginit.height);
|
||||
std.log.debug("w: {}, h: {}\n", .{ ginit.width, ginit.height });
|
||||
|
||||
gl.viewport(0, 0, ginit.width, ginit.height);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
gl.viewport(0, 0, ginit.width, ginit.height);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -438,6 +446,8 @@ export fn game_update() bool {
|
||||
|
||||
// Update
|
||||
{
|
||||
const zone = tracy.initZone(@src(), .{ .name = "update entities" });
|
||||
defer zone.deinit();
|
||||
for (gmem.world.entities[0..gmem.world.entity_count]) |*ent| {
|
||||
if (!ent.data.flags.active) continue;
|
||||
|
||||
@ -449,6 +459,8 @@ export fn game_update() bool {
|
||||
|
||||
// Render
|
||||
{
|
||||
const zone = tracy.initZone(@src(), .{ .name = "game.render()" });
|
||||
defer zone.deinit();
|
||||
gmem.render.begin();
|
||||
defer gmem.render.finish();
|
||||
|
||||
@ -503,7 +515,15 @@ export fn game_update() bool {
|
||||
}
|
||||
}
|
||||
|
||||
globals.g_assetman.watchChanges();
|
||||
{
|
||||
const zone = tracy.initZone(@src(), .{ .name = "SDL_GL_SwapWindow" });
|
||||
defer zone.deinit();
|
||||
c.SDL_GL_SwapWindow(ginit.window);
|
||||
}
|
||||
tracy.frameMark();
|
||||
//c.SDL_Delay(1);
|
||||
|
||||
// globals.g_assetman.watchChanges();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -514,6 +534,7 @@ export fn game_shutdown() void {
|
||||
gmem.global_allocator.free(gmem.frame_fba.buffer);
|
||||
gmem.global_allocator.destroy(gmem);
|
||||
gl.disable(gl.DEBUG_OUTPUT);
|
||||
tracy.shutdownProfiler();
|
||||
}
|
||||
|
||||
export fn game_shutdown_window() void {
|
||||
|
@ -44,7 +44,7 @@ pub fn resolveAssetTypeByExtension(path: []const u8) ?AssetType {
|
||||
if (std.mem.endsWith(u8, path, ".glsl")) {
|
||||
return .Shader;
|
||||
}
|
||||
if (std.mem.endsWith(u8, path, ".png") or std.mem.endsWith(u8, path, ".jpg") or std.mem.endsWith(u8, path, ".exr")) {
|
||||
if (std.mem.endsWith(u8, path, ".png") or std.mem.endsWith(u8, path, ".jpg") or std.mem.endsWith(u8, path, ".exr") or std.mem.endsWith(u8, path, ".dds") or std.mem.endsWith(u8, path, ".tga")) {
|
||||
return .Texture;
|
||||
}
|
||||
return null;
|
||||
|
Loading…
x
Reference in New Issue
Block a user