HDR color targets!

This commit is contained in:
Peter Li 2025-05-06 16:23:50 -07:00
parent c2429d3fe6
commit 77a118ee8d
25 changed files with 468 additions and 152 deletions

View File

@ -15,7 +15,7 @@ const modulelist = @import("modulelist.zig").list;
const std = @import("std"); const std = @import("std");
pub const NwArgs = struct { pub const NwArgs = struct {
useGPA: bool = true, // slower zig based memory allocator, provides detailed tracking of leaks and memory violations useGPA: bool = false, // slower zig based memory allocator, provides detailed tracking of leaks and memory violations
vulkanValidation: bool = true, vulkanValidation: bool = true,
fastTest: bool = false, fastTest: bool = false,
dmt: bool = false, // detailed memory tracking, implements a timeline for tracking all memory allocations dmt: bool = false, // detailed memory tracking, implements a timeline for tracking all memory allocations

View File

@ -557,6 +557,14 @@ pub const Rotation = struct {
return .{}; return .{};
} }
pub fn add(self: @This(), other: @This()) Rotation {
const m1 = zm.quatToMat(self.quat);
const m2 = zm.quatToMat(other.quat);
const r = zm.mul(m1, m2);
return .{ .quat = zm.matToQuat(r) };
}
pub fn eulerX(o: f32) @This() { pub fn eulerX(o: f32) @This() {
return .{ return .{
.quat = zm.matToQuat(zm.rotationX((o))), .quat = zm.matToQuat(zm.rotationX((o))),

View File

@ -57,7 +57,7 @@ pub const Impl = struct {
//const renderpass = cmd.beginGPURenderPass(color_target_infos: [*c]const GPUColorTargetInfo, num_color_targets: u32, depth_stencil_target_info: [*c]const GPUDepthStencilTargetInfo); //const renderpass = cmd.beginGPURenderPass(color_target_infos: [*c]const GPUColorTargetInfo, num_color_targets: u32, depth_stencil_target_info: [*c]const GPUDepthStencilTargetInfo);
var targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroes(gpu.GPUColorTargetInfo); var targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroes(gpu.GPUColorTargetInfo);
targetInfo.texture = rend.context().state.swapchainTexture.?; targetInfo.texture = rend.context().state.swapchainTargetTexture.?;
targetInfo.clear_color = .{ .r = 0.0, .g = 0.0, .b = 0.0, .a = 0.0 }; targetInfo.clear_color = .{ .r = 0.0, .g = 0.0, .b = 0.0, .a = 0.0 };
targetInfo.load_op = .loadopLoad; targetInfo.load_op = .loadopLoad;
targetInfo.store_op = .storeopStore; targetInfo.store_op = .storeopStore;

View File

@ -44,6 +44,9 @@ pub fn build(b: *std.Build) void {
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "skybox.frag", b.path("shaders/skybox.frag.json")); sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "skybox.frag", b.path("shaders/skybox.frag.json"));
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "skybox.vert", b.path("shaders/skybox.vert.json")); sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "skybox.vert", b.path("shaders/skybox.vert.json"));
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "postProc.frag", b.path("shaders/postProc.frag.json"));
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "postProc.vert", b.path("shaders/postProc.vert.json"));
// ========== tests ========== // ========== tests ==========
const tests = b.addTest(.{ const tests = b.addTest(.{
.target = target, .target = target,

View File

@ -154,7 +154,6 @@ float shadowCalculationPCF(float3 fragPos, float4 DirectionalShadowFragPos)
float3 DirectionalLight(float3 normal, float3 fragPos, float4 DirectionalShadowFragPos) float3 DirectionalLight(float3 normal, float3 fragPos, float4 DirectionalShadowFragPos)
{ {
float3 lightDir = directionalLight.xyz; float3 lightDir = directionalLight.xyz;
float diff = max(dot(lightDir, normal), 0.0); float diff = max(dot(lightDir, normal), 0.0);
float3 diffuse = diff * directionalLightColor.xyz; float3 diffuse = diff * directionalLightColor.xyz;
@ -174,6 +173,14 @@ float3 DirectionalLight(float3 normal, float3 fragPos, float4 DirectionalShadow
return diffuse; return diffuse;
} }
float3 reinhard2(float3 x) {
const float L_white = 4.0;
const float3 a = 1.0 + x / (L_white * L_white);
const float3 x2 = x * a;
const float3 x3 = 1.0 + x;
return x2 / x3;
}
float4 main( float4 main(
@ -242,7 +249,7 @@ float4 main(
if((texMode & 0x2) > 0) // full bright no lighting bit if((texMode & 0x2) > 0) // full bright no lighting bit
{ {
c2 = col; c2 = col * 4;
} }

View File

@ -0,0 +1,12 @@
Texture2D<float4> Texture0 : register(t0, space2);
SamplerState Sampler0 : register(s0, space2);
float4 main(float2 UV : TEXCOORD0) : SV_Target0
{
float2 uv = UV;
uv.y *= -1;
float4 color = Texture0.Sample(Sampler0, uv);
return color;
}

View File

@ -0,0 +1,38 @@
{
"entryPoints" : [
{
"name" : "main",
"mode" : "frag"
}
],
"inputs" : [
{
"type" : "vec2",
"name" : "in.var.TEXCOORD0",
"location" : 0
}
],
"outputs" : [
{
"type" : "vec4",
"name" : "out.var.SV_Target0",
"location" : 0
}
],
"separate_images" : [
{
"type" : "texture2D",
"name" : "Texture0",
"set" : 2,
"binding" : 0
}
],
"separate_samplers" : [
{
"type" : "sampler",
"name" : "Sampler0",
"set" : 2,
"binding" : 0
}
]
}

View File

@ -0,0 +1,26 @@
struct Input
{
float3 Position : TEXCOORD0;
float3 Normal : TEXCOORD1;
float4 Color : TEXCOORD2;
float2 UV : TEXCOORD3;
uint Bones : TEXCOORD4;
uint weights : TEXCOORD5;
uint Instance : SV_InstanceID;
};
struct Output
{
float2 UV : TEXCOORD0;
float4 Position : SV_Position;
};
Output main(Input input)
{
Output output;
output.Position = float4(input.Position, 1.0);
output.UV = input.UV;
return output;
}

View File

@ -0,0 +1,27 @@
{
"entryPoints" : [
{
"name" : "main",
"mode" : "vert"
}
],
"inputs" : [
{
"type" : "vec3",
"name" : "in.var.TEXCOORD0",
"location" : 0
},
{
"type" : "vec2",
"name" : "in.var.TEXCOORD3",
"location" : 3
}
],
"outputs" : [
{
"type" : "vec2",
"name" : "out.var.TEXCOORD0",
"location" : 0
}
]
}

View File

@ -197,7 +197,7 @@ pub fn createPipeline(self: *@This()) !*gpu.GPUGraphicsPipeline {
pci.target_info.num_color_targets = 1; pci.target_info.num_color_targets = 1;
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
.{ .{
.format = self.device.getGPUSwapchainTextureFormat(rend.context().window), .format = rend.context().hdrTextureFormat,
.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState),
}, },
}; };

View File

@ -61,7 +61,7 @@ fn createPipeline(self: *@This()) !void {
pci.target_info.num_color_targets = 1; pci.target_info.num_color_targets = 1;
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
.{ .{
.format = self.device.getGPUSwapchainTextureFormat(ctx.window), .format = ctx.hdrTextureFormat,
.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState),
}, },
}; };
@ -85,7 +85,7 @@ pub fn destroy(self: *@This()) void {
pub fn render(self: *@This(), cmd: *gpu.GPUCommandBuffer) void { pub fn render(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{ const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
.texture = rend.context().state.swapchainTexture.?, .texture = rend.context().state.targetTexture,
.clear_color = self.skyboxColor, .clear_color = self.skyboxColor,
.load_op = .loadopClear, .load_op = .loadopClear,
.store_op = .storeopStore, .store_op = .storeopStore,
@ -102,6 +102,7 @@ pub fn render(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
} }
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null); const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null);
if (self.skyboxTexture) |skyboxTexture| { if (self.skyboxTexture) |skyboxTexture| {
if (self.skyboxMesh) |skyboxMesh| { if (self.skyboxMesh) |skyboxMesh| {
const ctx = rend.context(); const ctx = rend.context();

View File

@ -0,0 +1,15 @@
# Blender 4.4.3
# www.blender.org
o Plane
v -1.000000 1.000000 0.000000
v 1.000000 1.000000 0.000000
v -1.000000 -1.000000 -0.000000
v 1.000000 -1.000000 -0.000000
vn -0.0000 1.0000 -0.0000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
s 0
f 1/1/1 2/2/1 4/3/1 3/4/1

View File

@ -72,6 +72,12 @@ pub const Renderer = struct {
state: RendererState = .{}, state: RendererState = .{},
// swapchainTexture: ?*gpu.GPUTexture = undefined, // swapchainTexture: ?*gpu.GPUTexture = undefined,
swapchainTargetFormat: gpu.GPUTextureFormat = undefined,
hdrTextureFormat: gpu.GPUTextureFormat = undefined,
postProcessingPipeline: *gpu.GPUGraphicsPipeline = undefined,
screenPlane: ?rend.IndexedMesh = null,
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
pub const MaxObjectCount = 50000; pub const MaxObjectCount = 50000;
@ -86,9 +92,28 @@ pub const Renderer = struct {
try core.defineComponent(rend.MeshComponent, allocator); try core.defineComponent(rend.MeshComponent, allocator);
try core.defineComponent(rend.CameraComponent, allocator); try core.defineComponent(rend.CameraComponent, allocator);
self.hdrTextureFormat = .textureformatR16g16b16a16Float;
return self; return self;
} }
pub fn createHDRTexture(self: *@This()) !void {
var gci = std.mem.zeroes(gpu.GPUTextureCreateInfo);
gci.type = .texturetype2d;
gci.format = self.hdrTextureFormat;
gci.width = @intCast(platform.getInstance().windowExtent.x);
gci.height = @intCast(platform.getInstance().windowExtent.y);
gci.layer_count_or_depth = 1;
gci.num_levels = 1;
gci.sample_count = .samplecount1;
gci.usage = .{
.textureusageSampler = true,
.textureusageColorTarget = true,
};
self.state.targetTexture = self.device.createGPUTexture(&gci);
}
pub fn startRenderer(self: *@This()) !void { pub fn startRenderer(self: *@This()) !void {
self.device = gpu.createGPUDevice(.{ self.device = gpu.createGPUDevice(.{
.shaderformatSpirv = true, .shaderformatSpirv = true,
@ -110,6 +135,8 @@ pub const Renderer = struct {
try self.createMeshPipeline(); try self.createMeshPipeline();
try self.createBuffers(); try self.createBuffers();
try self.createDepthTexture(); try self.createDepthTexture();
try self.createHDRTexture();
try self.createPostProcessingPipeline();
self.meshPool = try self.createRendererObject(MeshPool); self.meshPool = try self.createRendererObject(MeshPool);
self.textureList = try self.createRendererEngineObject(TextureList); self.textureList = try self.createRendererEngineObject(TextureList);
@ -141,6 +168,8 @@ pub const Renderer = struct {
_ = try core.fs().installFileBytesMount("embedded:plane.obj", @constCast(&plane_obj), true); _ = try core.fs().installFileBytesMount("embedded:plane.obj", @constCast(&plane_obj), true);
_ = try core.fs().installFileBytesMount("embedded:screenPlane.obj", @constCast(&screenPlane_obj), true);
try assets.load( try assets.load(
assets.MakeImportRefOptions( assets.MakeImportRefOptions(
"Mesh", "Mesh",
@ -148,6 +177,49 @@ pub const Renderer = struct {
.{ .path = "embedded:plane.obj" }, .{ .path = "embedded:plane.obj" },
), ),
); );
try assets.load(
assets.MakeImportRefOptions(
"Mesh",
"m_screenPlane",
.{ .path = "embedded:screenPlane.obj" },
),
);
}
pub fn createPostProcessingPipeline(self: *@This()) !void {
const vertex = try self.loadShader("postProc.vert", postProcVert.LoadArgs);
const fragment = try self.loadShader("postProc.frag", postProcFrag.LoadArgs);
var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo);
pci.vertex_shader = vertex;
pci.fragment_shader = fragment;
var attributes = try self.generateVertexAttributeList();
defer attributes.deinit();
pci.vertex_input_state = .{
.num_vertex_buffers = 1,
.vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{
.{ .slot = 0, .pitch = @sizeOf(rend.MeshVertex), .input_rate = .vertexinputrateVertex, .instance_step_rate = 0 },
},
.num_vertex_attributes = @intCast(attributes.items.len),
.vertex_attributes = @ptrCast(attributes.items.ptr),
};
core.graphics_log("hdr texture format format: {any}", .{self.hdrTextureFormat});
pci.target_info.num_color_targets = 1;
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
.{
.format = self.swapchainTargetFormat,
.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState),
},
};
pci.rasterizer_state.cull_mode = .cullmodeNone;
pci.rasterizer_state.fill_mode = .fillmodeFill;
self.postProcessingPipeline = self.device.createGPUGraphicsPipeline(&pci);
} }
pub fn createDirectionalShadowsPipeline(self: *@This()) !void { pub fn createDirectionalShadowsPipeline(self: *@This()) !void {
@ -340,12 +412,14 @@ pub const Renderer = struct {
pci.depth_stencil_state.enable_depth_write = true; pci.depth_stencil_state.enable_depth_write = true;
pci.depth_stencil_state.write_mask = 0xff; pci.depth_stencil_state.write_mask = 0xff;
self.swapchainTargetFormat = self.device.getGPUSwapchainTextureFormat(self.window);
core.graphics_log("swapchain format: {any}", .{self.swapchainTargetFormat});
pci.target_info.has_depth_stencil_target = true; pci.target_info.has_depth_stencil_target = true;
pci.target_info.depth_stencil_format = self.depthFormat; pci.target_info.depth_stencil_format = self.depthFormat;
pci.target_info.num_color_targets = 1; pci.target_info.num_color_targets = 1;
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
.{ .{
.format = self.device.getGPUSwapchainTextureFormat(self.window), .format = self.hdrTextureFormat,
.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState),
}, },
}; };
@ -606,8 +680,8 @@ pub const Renderer = struct {
pub fn draw(self: *@This()) void { pub fn draw(self: *@This()) void {
const cmd = self.state.cmd.?; const cmd = self.state.cmd.?;
if (cmd.waitAndAcquireGPUSwapchainTexture(self.window, @ptrCast(&self.state.swapchainTexture), null, null)) { if (cmd.waitAndAcquireGPUSwapchainTexture(self.window, @ptrCast(&self.state.swapchainTargetTexture), null, null)) {
if (self.state.swapchainTexture == null) { if (self.state.swapchainTargetTexture == null) {
_ = cmd.submitGPUCommandBuffer(); _ = cmd.submitGPUCommandBuffer();
return; return;
} }
@ -623,7 +697,7 @@ pub const Renderer = struct {
// can cache this // can cache this
const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{ const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
.texture = self.state.swapchainTexture.?, .texture = self.state.targetTexture,
.load_op = .loadopLoad, .load_op = .loadopLoad,
.store_op = .storeopStore, .store_op = .storeopStore,
}); });
@ -640,6 +714,8 @@ pub const Renderer = struct {
self.state.pass = cmd.beginGPURenderPass(&targetInfo, 1, &depthTarget); self.state.pass = cmd.beginGPURenderPass(&targetInfo, 1, &depthTarget);
const renderpass = self.state.pass.?; const renderpass = self.state.pass.?;
renderpass.setGPUScissor(&self.scissor);
//renderpass.bindGPUGraphicsPipeline(self.testPipeline); //renderpass.bindGPUGraphicsPipeline(self.testPipeline);
renderpass.bindGPUFragmentSamplers(1, &.{ .sampler = self.blockySampler, .texture = self.defaultTexture.texture }, 1); renderpass.bindGPUFragmentSamplers(1, &.{ .sampler = self.blockySampler, .texture = self.defaultTexture.texture }, 1);
renderpass.bindGPUFragmentSamplers(2, &.{ .sampler = self.blockySampler, .texture = self.defaultTexture.texture }, 1); renderpass.bindGPUFragmentSamplers(2, &.{ .sampler = self.blockySampler, .texture = self.defaultTexture.texture }, 1);
@ -654,8 +730,6 @@ pub const Renderer = struct {
renderpass.bindGPUFragmentSamplers(self.shadowDepthTextureSlot, &.{ .texture = self.shadowDepthTexture, .sampler = self.blockySampler }, 1); renderpass.bindGPUFragmentSamplers(self.shadowDepthTextureSlot, &.{ .texture = self.shadowDepthTexture, .sampler = self.blockySampler }, 1);
// todo move into materials system // todo move into materials system
renderpass.setGPUScissor(&self.scissor);
try self.uploadUniforms(cmd); try self.uploadUniforms(cmd);
//rendering each mesh //rendering each mesh
{ {
@ -686,15 +760,35 @@ pub const Renderer = struct {
for (self.postMesh.items) |interface| { for (self.postMesh.items) |interface| {
interface.func(interface.ptr, cmd, renderpass); interface.func(interface.ptr, cmd, renderpass);
} }
renderpass.endGPURenderPass(); renderpass.endGPURenderPass();
{
const postProcTargetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
.texture = self.state.swapchainTargetTexture.?,
.load_op = .loadopDontCare,
.store_op = .storeopStore,
});
const postProcPass = cmd.beginGPURenderPass(&postProcTargetInfo, 1, null);
postProcPass.bindGPUGraphicsPipeline(self.postProcessingPipeline);
postProcPass.bindGPUFragmentSamplers(0, &.{ .sampler = self.blockySampler, .texture = self.state.targetTexture }, 1);
// post processing + hdr etc...
if (self.screenPlane == null) {
self.screenPlane = getMesh("m_screenPlane");
}
if (self.screenPlane) |mesh| {
postProcPass.drawGPUIndexedPrimitives(mesh.index.size, 1, mesh.index.start, @intCast(mesh.vertex.start), 0);
}
postProcPass.endGPURenderPass();
}
for (self.postRenders.items) |interface| { for (self.postRenders.items) |interface| {
interface.func(interface.ptr, cmd); interface.func(interface.ptr, cmd);
} }
// renderpass.drawGPUPrimitives(3, 1, 0, 0);
} }
_ = cmd.submitGPUCommandBuffer(); _ = cmd.submitGPUCommandBuffer();
@ -734,6 +828,9 @@ const lit_mesh_frag = @import("lit_mesh.frag");
const depthOnly = @import("depthOnly.frag"); const depthOnly = @import("depthOnly.frag");
const sample_vert = @import("sample.vert"); const sample_vert = @import("sample.vert");
const postProcVert = @import("postProc.vert");
const postProcFrag = @import("postProc.frag");
const MeshVertices = meshes_vert.Scene; const MeshVertices = meshes_vert.Scene;
const MeshUniforms = meshes_vert.Uniforms; const MeshUniforms = meshes_vert.Uniforms;
@ -801,10 +898,12 @@ pub const RendererState = struct {
copyPass: ?*gpu.GPURenderPass = null, copyPass: ?*gpu.GPURenderPass = null,
pass: ?*gpu.GPURenderPass = null, pass: ?*gpu.GPURenderPass = null,
cmd: ?*gpu.GPUCommandBuffer = null, cmd: ?*gpu.GPUCommandBuffer = null,
swapchainTexture: ?*gpu.GPUTexture = null, swapchainTargetTexture: ?*gpu.GPUTexture = null,
targetTexture: *gpu.GPUTexture = undefined,
}; };
pub const CustomMeshRenderFunc = *const fn (?*anyopaque) void; pub const CustomMeshRenderFunc = *const fn (?*anyopaque) void;
pub const GPUTextureType = gpu.GPUTexture; pub const GPUTextureType = gpu.GPUTexture;
const plane_obj align(8) = @embedFile("embedded/plane.obj").*; const plane_obj align(8) = @embedFile("embedded/plane.obj").*;
const screenPlane_obj align(8) = @embedFile("embedded/screenPlane.obj").*;

View File

@ -7,18 +7,75 @@ texture: *gpu.GPUTexture = undefined,
width: u32, width: u32,
height: u32, height: u32,
inputEnabled: bool = false, inputEnabled: bool = false,
sensitivity: f32 = 1.0, sensitivity: f32 = 1.0,
entity: core.Entity,
fn log(comptime fmt: []const u8, args: anytype) void { fn log(comptime fmt: []const u8, args: anytype) void {
core.engine_log("[Doomplayer] " ++ fmt, args); core.engine_log("[Doomplayer] " ++ fmt, args);
} }
pub fn create(allocator: std.mem.Allocator) !*@This() { pub const DoomCanvas = struct {
data: core.GameObjectData = undefined,
entity: core.Entity,
first: bool = false,
pub fn create(alloc: std.mem.Allocator) !*@This() {
var first: bool = false;
if (gDoom == null) {
first = true;
gDoom = try createDoom(alloc);
}
if (gDoom) |doomCtx| {
const self = try alloc.create(@This());
self.first = first;
const entity = try core.createEntity();
const scene = entity.addComponent(core.Scene).?;
const size = 5.0;
const h: f32 = @floatFromInt(doomCtx.height);
const w: f32 = @floatFromInt(doomCtx.width);
scene.setScale(size, size, size * (h / w));
scene.setRotation(core.Rotation.eulerX(core.radians(90.0)));
scene.setPosition(.{ .z = 30 });
if (entity.addComponent(rend.MeshComponent)) |mesh| {
mesh.cmrf = bindVideoTextures;
mesh.cmrf_ctx = doomCtx;
mesh.textureMode.fullbright = true;
mesh.textureMode.noSrgb = true;
mesh.setMesh("m_plane");
}
self.entity = entity;
return self;
}
return error.ContextNotReady;
}
pub fn tick(self: *@This(), dt: f64) void {
if (self.first) {
gDoom.?.tick(dt);
}
}
pub fn getEntity(self: *@This()) core.Entity {
return self.entity;
}
pub fn destroy(self: *@This()) void {
self.entity.destroy();
if (self.first) {
gDoom.?.destroy();
}
self.data.release(self);
}
};
pub fn createDoom(allocator: std.mem.Allocator) !*@This() {
const self = try allocator.create(@This()); const self = try allocator.create(@This());
self.* = .{ self.* = .{
.allocator = allocator, .allocator = allocator,
@ -28,8 +85,6 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
log("initialized", .{}); log("initialized", .{});
try self.setup();
self.sensitivity = core.configVar(f32, "doomplayer.sensitivity", 1.0); self.sensitivity = core.configVar(f32, "doomplayer.sensitivity", 1.0);
gDoom = self; gDoom = self;
@ -44,11 +99,13 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
c.doom_set_default_int("mouse_move", 0); // Mouse will not move forward c.doom_set_default_int("mouse_move", 0); // Mouse will not move forward
c.doom_init(1, @constCast(@ptrCast(@alignCast(&.{"doom"}))), 8); c.doom_init(1, @constCast(@ptrCast(@alignCast(&.{"doom"}))), 8);
self.entity = try self.createEntity();
return self; return self;
} }
pub fn getEntity(self: *@This()) core.Entity {
return self.entity;
}
fn sdlToDoomButton(button: c_uint) c_uint { fn sdlToDoomButton(button: c_uint) c_uint {
switch (button) { switch (button) {
sdl3_c.SDL_BUTTON_LEFT => { sdl3_c.SDL_BUTTON_LEFT => {
@ -290,17 +347,18 @@ fn sdlToDoomScancode(sdlScancode: c_uint) c_int {
return c.DOOM_KEY_UNKNOWN; return c.DOOM_KEY_UNKNOWN;
} }
var gDoom: *@This() = undefined; pub var gDoom: ?*@This() = null;
pub fn processFunc(e: *sdl3.Event) void { pub fn processFunc(e: *sdl3.Event) void {
if (!gDoom.inputEnabled) { if (gDoom) |ctx| {
if (!ctx.inputEnabled) {
return; return;
} }
switch (e.type) { switch (e.type) {
else => {}, else => {},
sdl3_c.SDL_EVENT_MOUSE_MOTION => { sdl3_c.SDL_EVENT_MOUSE_MOTION => {
c.doom_mouse_move(@intFromFloat(e.motion.xrel * 4 * gDoom.sensitivity), @intFromFloat(e.motion.yrel * 4 * gDoom.sensitivity)); c.doom_mouse_move(@intFromFloat(e.motion.xrel * 4 * ctx.sensitivity), @intFromFloat(e.motion.yrel * 4 * ctx.sensitivity));
}, },
sdl3_c.SDL_EVENT_MOUSE_BUTTON_DOWN => { sdl3_c.SDL_EVENT_MOUSE_BUTTON_DOWN => {
c.doom_button_down(sdlToDoomButton(e.button.button)); c.doom_button_down(sdlToDoomButton(e.button.button));
@ -319,6 +377,7 @@ pub fn processFunc(e: *sdl3.Event) void {
} }
}, },
} }
}
} }
fn getFrameLength(self: @This()) c_int { fn getFrameLength(self: @This()) c_int {
@ -418,26 +477,6 @@ fn bindVideoTextures(p: ?*anyopaque) void {
} }
// creates a video player entity // creates a video player entity
pub fn createEntity(self: *@This()) !core.Entity {
const entity = try core.createEntity();
const scene = entity.addComponent(core.Scene).?;
const size = 5.0;
const h: f32 = @floatFromInt(self.height);
const w: f32 = @floatFromInt(self.width);
scene.setScale(size, size, size * (h / w));
scene.setRotation(core.Rotation.eulerX(core.radians(90.0)));
scene.setPosition(.{ .z = 30 });
if (entity.addComponent(rend.MeshComponent)) |mesh| {
mesh.cmrf = bindVideoTextures;
mesh.cmrf_ctx = self;
mesh.textureMode.fullbright = true;
mesh.textureMode.noSrgb = true;
mesh.setMesh("m_plane");
}
return entity;
}
pub fn destroy(self: *@This()) void { pub fn destroy(self: *@This()) void {
core.engine_logs("[Videoplayer] destroying player"); core.engine_logs("[Videoplayer] destroying player");

View File

@ -3,6 +3,7 @@ objectList: *core.GameObjectList,
windowOpen: bool = true, windowOpen: bool = true,
spawnFuncs: std.ArrayListUnmanaged(SpawnEntry) = .{}, spawnFuncs: std.ArrayListUnmanaged(SpawnEntry) = .{},
spawnPosition: core.Vectorf = .{}, spawnPosition: core.Vectorf = .{},
spawnRotation: core.Rotation = .{},
pub const SpawnEntry = struct { pub const SpawnEntry = struct {
typeName: []const u8, typeName: []const u8,
@ -44,6 +45,9 @@ pub fn addSpawnFunction(self: *@This(), comptime name: []const u8, comptime T: t
pub fn prepareEntity(self: *@This(), entity: core.Entity) void { pub fn prepareEntity(self: *@This(), entity: core.Entity) void {
if (entity.fetch(core.Scene)) |scene| { if (entity.fetch(core.Scene)) |scene| {
scene.setPosition(self.spawnPosition); scene.setPosition(self.spawnPosition);
scene.setRotation(scene.getRotation().add(self.spawnRotation));
_ = scene.getAndResolveTransform();
} }
} }

Binary file not shown.

Binary file not shown.

View File

@ -47,101 +47,110 @@ struct main0_in
fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], const device type_StructuredBuffer_Scene& scene [[buffer(1)]], texture2d<float> Texture0 [[texture(0)]], texture2d<float> Texture1 [[texture(1)]], texture2d<float> Texture2 [[texture(2)]], texture2d<float> DirectionalShadowDepthMap [[texture(3)]], sampler Sampler0 [[sampler(0)]], sampler Sampler1 [[sampler(1)]], sampler Sampler2 [[sampler(2)]], sampler DirectionalShadowSampler [[sampler(3)]]) fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], const device type_StructuredBuffer_Scene& scene [[buffer(1)]], texture2d<float> Texture0 [[texture(0)]], texture2d<float> Texture1 [[texture(1)]], texture2d<float> Texture2 [[texture(2)]], texture2d<float> DirectionalShadowDepthMap [[texture(3)]], sampler Sampler0 [[sampler(0)]], sampler Sampler1 [[sampler(1)]], sampler Sampler2 [[sampler(2)]], sampler DirectionalShadowSampler [[sampler(3)]])
{ {
main0_out out = {}; main0_out out = {};
int _98 = int(scene._m0[in.in_var_TEXCOORD4].textureMode); int _97 = int(scene._m0[in.in_var_TEXCOORD4].textureMode);
int _99 = _98 & 240; int _98 = _97 & 240;
float4 _133;
if (_99 == 16)
{
float3 _120 = float3(Texture0.sample(Sampler0, in.in_var_TEXCOORD0).x, Texture1.sample(Sampler1, in.in_var_TEXCOORD0).x, Texture2.sample(Sampler2, in.in_var_TEXCOORD0).x) + float3(-0.0625, -0.5, -0.5);
_133 = float4(dot(_120, float3(1.164000034332275390625, 0.0, 1.7929999828338623046875)), dot(_120, float3(1.164000034332275390625, -0.212999999523162841796875, -0.53299999237060546875)), dot(_120, float3(1.164000034332275390625, 2.111999988555908203125, 0.0)), 1.0);
}
else
{
float4 _132; float4 _132;
if (_99 == 0) if (_98 == 16)
{ {
_132 = Texture0.sample(Sampler0, in.in_var_TEXCOORD0); float3 _119 = float3(Texture0.sample(Sampler0, in.in_var_TEXCOORD0).x, Texture1.sample(Sampler1, in.in_var_TEXCOORD0).x, Texture2.sample(Sampler2, in.in_var_TEXCOORD0).x) + float3(-0.0625, -0.5, -0.5);
_132 = float4(dot(_119, float3(1.164000034332275390625, 0.0, 1.7929999828338623046875)), dot(_119, float3(1.164000034332275390625, -0.212999999523162841796875, -0.53299999237060546875)), dot(_119, float3(1.164000034332275390625, 2.111999988555908203125, 0.0)), 1.0);
} }
else else
{ {
_132 = _86; float4 _131;
} if (_98 == 0)
_133 = _132;
}
float4 _139;
if ((_98 & 1) == 1)
{ {
_139 = powr(_133, float4(2.2000000476837158203125)); _131 = Texture0.sample(Sampler0, in.in_var_TEXCOORD0);
} }
else else
{ {
_139 = _133; _131 = _86;
} }
if (_139.w < 0.00999999977648258209228515625) _132 = _131;
}
float4 _138;
if ((_97 & 1) == 1)
{
_138 = powr(_132, float4(2.2000000476837158203125));
}
else
{
_138 = _132;
}
if (_138.w < 0.00999999977648258209228515625)
{ {
discard_fragment(); discard_fragment();
} }
float3 _193; float3 _192;
do do
{ {
float3 _150 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1; float3 _149 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1;
float _151 = length(_150); float _150 = length(_149);
float _152 = _151 * _151; float _151 = _150 * _150;
float _158; float _157;
if (_151 > 2.0) if (_150 > 2.0)
{ {
_158 = 0.5 / _152; _157 = 0.5 / _151;
} }
else else
{ {
_158 = 1.0 / _152; _157 = 1.0 / _151;
} }
float _163; float _162;
if (_151 > 4.0) if (_150 > 4.0)
{ {
_163 = _158 * 0.5; _162 = _157 * 0.5;
} }
else else
{ {
_163 = _158; _162 = _157;
} }
float _165 = (_151 > 15.0) ? 0.0 : _163; float _164 = (_150 > 15.0) ? 0.0 : _162;
float _167 = (_165 > 1.0) ? 1.0 : _165; float _166 = (_164 > 1.0) ? 1.0 : _164;
if (length(in.in_var_TEXCOORD2) < 0.100000001490116119384765625) if (length(in.in_var_TEXCOORD2) < 0.100000001490116119384765625)
{ {
_193 = (in.in_var_TEXCOORD1 * float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5)) * _167; _192 = (in.in_var_TEXCOORD1 * float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5)) * _166;
break; break;
} }
float3 _174 = fast::normalize(_150); float3 _173 = fast::normalize(_149);
_193 = ((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_174, in.in_var_TEXCOORD2), 0.0)) * _167) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_174 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _167); _192 = ((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_173, in.in_var_TEXCOORD2), 0.0)) * _166) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_173 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _166);
break; break;
} while(false); } while(false);
float3 _210 = ((in.in_var_TEXCOORD3.xyz / float3(in.in_var_TEXCOORD3.w)) * 0.5) + float3(0.5); float3 _209 = ((in.in_var_TEXCOORD3.xyz / float3(in.in_var_TEXCOORD3.w)) * 0.5) + float3(0.5);
float3 _212; float3 _211;
_212.x = _210.x; _211.x = _209.x;
float2 _213 = _212.xy; float2 _212 = _211.xy;
_213.y = -_210.y; _212.y = -_209.y;
float _219;
int _222;
int _224;
_219 = 0.0;
_222 = 0;
_224 = -4;
float _220; float _220;
int _223; int _223;
int _225; for (; _224 <= 4; _219 = _220, _222 = _223, _224++)
_220 = 0.0;
_223 = 0;
_225 = -4;
float _221;
int _224;
for (; _225 <= 4; _220 = _221, _223 = _224, _225++)
{ {
_224 = _223; _223 = _222;
_221 = _220; _220 = _219;
for (int _234 = -4; _234 <= 4; ) for (int _233 = -4; _233 <= 4; )
{ {
_224++; _223++;
_221 += float((in.in_var_TEXCOORD3.z - 0.004999999888241291046142578125) > DirectionalShadowDepthMap.sample(DirectionalShadowSampler, (_213 + float2(float(_234) * 0.000244140625, float(_225) * 0.000244140625))).x); _220 += float((in.in_var_TEXCOORD3.z - 0.004999999888241291046142578125) > DirectionalShadowDepthMap.sample(DirectionalShadowSampler, (_212 + float2(float(_233) * 0.000244140625, float(_224) * 0.000244140625))).x);
_234++; _233++;
continue; continue;
} }
} }
out.out_var_SV_Target0 = float4(powr(select(_139.xyz * ((float3(0.100000001490116119384765625) + _193) + ((Uniforms.directionalLightColor.xyz * precise::max(dot(Uniforms.directionalLight.xyz, in.in_var_TEXCOORD2), 0.0)) * (1.0 - (_220 / float(_223))))), _139.xyz, bool3((_98 & 2) > 0)), float3(0.4545454680919647216796875)), _139.w); float3 _262;
if ((_97 & 2) > 0)
{
_262 = _138.xyz * 4.0;
}
else
{
_262 = _138.xyz * ((float3(0.100000001490116119384765625) + _192) + ((Uniforms.directionalLightColor.xyz * precise::max(dot(Uniforms.directionalLight.xyz, in.in_var_TEXCOORD2), 0.0)) * (1.0 - (_219 / float(_222)))));
}
out.out_var_SV_Target0 = float4(powr(_262, float3(0.4545454680919647216796875)), _138.w);
return out; return out;
} }

View File

@ -0,0 +1,24 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 out_var_SV_Target0 [[color(0)]];
};
struct main0_in
{
float2 in_var_TEXCOORD0 [[user(locn0)]];
};
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> Texture0 [[texture(0)]], sampler Sampler0 [[sampler(0)]])
{
main0_out out = {};
float2 _19 = in.in_var_TEXCOORD0;
_19.y = -_19.y;
out.out_var_SV_Target0 = Texture0.sample(Sampler0, _19);
return out;
}

View File

@ -0,0 +1,25 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float2 out_var_TEXCOORD0 [[user(locn0)]];
float4 gl_Position [[position]];
};
struct main0_in
{
float3 in_var_TEXCOORD0 [[attribute(0)]];
float2 in_var_TEXCOORD3 [[attribute(3)]];
};
vertex main0_out main0(main0_in in [[stage_in]])
{
main0_out out = {};
out.out_var_TEXCOORD0 = in.in_var_TEXCOORD3;
out.gl_Position = float4(in.in_var_TEXCOORD0, 1.0);
return out;
}

Binary file not shown.

Binary file not shown.

View File

@ -16,9 +16,7 @@ showWindow: bool = true,
fpcamera: *FpCamera = undefined, fpcamera: *FpCamera = undefined,
videoplayer: *VideoPlayer = undefined, videoplayer: *VideoPlayer = undefined,
doomplayer: *DoomPlayer = undefined,
videoplayerObject: core.Entity = undefined, videoplayerObject: core.Entity = undefined,
doomplayerObject: core.Entity = undefined,
objectSpawner: *extras.ObjectSpawner = undefined, objectSpawner: *extras.ObjectSpawner = undefined,
@ -119,15 +117,13 @@ pub fn prepare(self: *@This()) !void {
self.objectSpawner = try extras.ObjectSpawner.create(self.allocator); self.objectSpawner = try extras.ObjectSpawner.create(self.allocator);
try self.objectSpawner.addSpawnFunction("fox", FoxObject); try self.objectSpawner.addSpawnFunction("fox", FoxObject);
try self.objectSpawner.addSpawnFunction("doomplayer", DoomPlayer.DoomCanvas);
try assets.loadList(assetReferences); try assets.loadList(assetReferences);
self.videoplayer = try VideoPlayer.create(self.allocator); self.videoplayer = try VideoPlayer.create(self.allocator);
try self.videoplayer.startPlayback("LAPWING2.ogv"); try self.videoplayer.startPlayback("LAPWING2.ogv");
self.videoplayerObject = try self.videoplayer.createVideoPlayerEntity(); self.videoplayerObject = try self.videoplayer.createVideoPlayerEntity();
self.doomplayer = try DoomPlayer.create(self.allocator);
self.doomplayerObject = try self.doomplayer.createEntity();
rend.setSkyboxTexture("t_skybox"); rend.setSkyboxTexture("t_skybox");
const exitInput = try core.ActionBinding.create(core.MakeName("exit")); const exitInput = try core.ActionBinding.create(core.MakeName("exit"));
@ -158,26 +154,6 @@ pub fn prepare(self: *@This()) !void {
empireMesh.setTexture("t_empire"); empireMesh.setTexture("t_empire");
} }
{
// const fox = try core.createEntity();
// const scene = fox.addComponent(core.Scene).?;
// _ = scene;
// // scene.setScale();
// const mesh = fox.addComponent(rend.MeshComponent).?;
// mesh.setMesh("m_fox");
// mesh.setTexture("t_fox");
}
{
// const lightbox = try core.createEntity();
// const scene = lightbox.addComponent(core.Scene).?;
// scene.setPosition(.{ .z = 20 });
// scene.setScale(0.1, 0.1, 0.1);
// const mesh = lightbox.addComponent(rend.MeshComponent).?;
// mesh.setMesh("m_default_cube");
// mesh.setTexture("t_default");
}
const moveInput = try core.Axis2dBinding.create(core.MakeName("movement")); const moveInput = try core.Axis2dBinding.create(core.MakeName("movement"));
moveInput.addKey(.w, 1.0, .y); moveInput.addKey(.w, 1.0, .y);
@ -248,8 +224,11 @@ fn toggleDoom(ctx: ?*anyopaque, action: core.ActionEvent) void {
const self: *@This() = @ptrCast(@alignCast(ctx)); const self: *@This() = @ptrCast(@alignCast(ctx));
_ = action; _ = action;
self.doomplayer.inputEnabled = !self.doomplayer.inputEnabled; self.inputEnabled = !self.inputEnabled;
self.inputEnabled = !self.doomplayer.inputEnabled;
if (DoomPlayer.gDoom) |c| {
c.inputEnabled = !self.inputEnabled;
}
} }
fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void { fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void {
@ -328,7 +307,6 @@ pub fn tick(self: *@This(), dt: f64) void {
extras.inputDebugger.tick(); extras.inputDebugger.tick();
self.objectSpawner.tick(dt); self.objectSpawner.tick(dt);
self.videoplayer.tick(dt); self.videoplayer.tick(dt);
self.doomplayer.tick(dt);
self.fpcamera.tick(dt); self.fpcamera.tick(dt);
var movement = self.fpcamera.getForwardXZ().fmul(self.moveVector.z * fdt * self.cameraSpeed); var movement = self.fpcamera.getForwardXZ().fmul(self.moveVector.z * fdt * self.cameraSpeed);
@ -347,6 +325,7 @@ pub fn tick(self: *@This(), dt: f64) void {
const forward = self.fpcamera.getForward(); const forward = self.fpcamera.getForward();
const debugCenter = self.fpcamera.getPosition().add(forward.fmul(self.centerDist)); const debugCenter = self.fpcamera.getPosition().add(forward.fmul(self.centerDist));
self.objectSpawner.spawnPosition = debugCenter; self.objectSpawner.spawnPosition = debugCenter;
self.objectSpawner.spawnRotation = core.Rotation.eulerY(core.radians(self.fpcamera.yaw));
if (self.moveLight) { if (self.moveLight) {
core.debugSphere(debugCenter, 0.3, .{}); core.debugSphere(debugCenter, 0.3, .{});
@ -376,7 +355,7 @@ pub fn tick(self: *@This(), dt: f64) void {
} }
pub fn deinit(self: *@This()) void { pub fn deinit(self: *@This()) void {
self.doomplayer.destroy(); // self.doomplayer.destroy();
self.fpcamera.destroy(); self.fpcamera.destroy();
self.objectSpawner.destroy(); self.objectSpawner.destroy();