diff --git a/engine/rend/shaders/lit_mesh.frag.hlsl b/engine/rend/shaders/lit_mesh.frag.hlsl index f8771da..b711fe6 100644 --- a/engine/rend/shaders/lit_mesh.frag.hlsl +++ b/engine/rend/shaders/lit_mesh.frag.hlsl @@ -240,6 +240,11 @@ float4 main( + col * BlinnPhong(Normal, WorldPos, lightPos, lightColor) + col * DirectionalLight(Normal, WorldPos, DirectionalShadowFragPos); + if((texMode & 0x2) > 0) // full bright no lighting bit + { + c2 = col; + } + float4 rv = float4(pow(c2, 1.0 / 2.2), alpha); diff --git a/engine/rend/src/meshes/MeshComponent.zig b/engine/rend/src/meshes/MeshComponent.zig index a8e9305..253aee8 100644 --- a/engine/rend/src/meshes/MeshComponent.zig +++ b/engine/rend/src/meshes/MeshComponent.zig @@ -9,14 +9,11 @@ texture: ?*Texture = null, entity: core.Entity = undefined, -textureMode: u32 = 0, // bit +textureMode: ComponentTextureMode = .{}, // bit // DEBUG for-fun function, completely override what happens when the renderer tries to render this mesh. cmrf: ?rend.renderer.CustomMeshRenderFunc = null, cmrf_ctx: ?*anyopaque = null, -pub const textureMode_default = 0; -pub const textureMode_videoYUV = 0x10; - pub var BaseContainer: *MeshSet = undefined; pub const ComponentName = "Mesh"; @@ -25,6 +22,22 @@ pub const ScriptExports: []const []const u8 = &.{ // "setTexture", }; +pub const ComponentTextureMode = packed struct(u32) { + // 0 - 3 + noSrgb: bool = false, + fullbright: bool = false, + pad1: bool = false, + pad2: bool = false, + + // 4 - 8 + samplerMode: enum(u4) { + simple = 0, + videoYUV = 1, + } = .simple, + + rsvd: u24 = 0, +}; + pub fn initECS(self: *@This(), handle: core.SetHandle) void { // get the mesh component self.entity = core.Entity{ .handle = handle }; diff --git a/engine/rend/src/sgpu/renderer.zig b/engine/rend/src/sgpu/renderer.zig index dd6f7c5..15ab3e8 100644 --- a/engine/rend/src/sgpu/renderer.zig +++ b/engine/rend/src/sgpu/renderer.zig @@ -392,7 +392,7 @@ pub const Renderer = struct { transform = repr.transform; } uploadMapped[i].Model = @bitCast(transform); - uploadMapped[i].textureMode = object.textureMode; + uploadMapped[i].textureMode = @bitCast(object.textureMode); } } diff --git a/extras/doomplayer/src/doom.zig b/extras/doomplayer/src/doom.zig index 5a196a5..c24942f 100644 --- a/extras/doomplayer/src/doom.zig +++ b/extras/doomplayer/src/doom.zig @@ -8,6 +8,10 @@ texture: *gpu.GPUTexture = undefined, width: u32, height: u32, +inputEnabled: bool = false, + +sensitivity: f32 = 1.0, + fn log(comptime fmt: []const u8, args: anytype) void { core.engine_log("[Doomplayer] " ++ fmt, args); } @@ -24,6 +28,7 @@ pub fn create(allocator: std.mem.Allocator) !*@This() { try self.setup(); + self.sensitivity = core.configVar(f32, "doomplayer.sensitivity", 1.0); gDoom = self; return self; @@ -43,6 +48,22 @@ pub fn setup(self: *@This()) !void { c.doom_init(1, @constCast(@ptrCast(@alignCast(&.{"doom"}))), 8); } +fn sdlToDoomButton(button: c_uint) c_uint { + switch (button) { + sdl3_c.SDL_BUTTON_LEFT => { + return c.DOOM_LEFT_BUTTON; + }, + sdl3_c.SDL_BUTTON_RIGHT => { + return c.DOOM_RIGHT_BUTTON; + }, + sdl3_c.SDL_BUTTON_MIDDLE => { + return c.DOOM_MIDDLE_BUTTON; + }, + else => {}, + } + return 0; +} + fn sdlToDoomScancode(sdlScancode: c_uint) c_int { switch (sdlScancode) { sdl3_c.SDL_SCANCODE_TAB => { @@ -271,16 +292,22 @@ fn sdlToDoomScancode(sdlScancode: c_uint) c_int { var gDoom: *@This() = undefined; pub fn processFunc(e: *sdl3.Event) void { + if (!gDoom.inputEnabled) { + return; + } + switch (e.type) { else => {}, sdl3_c.SDL_EVENT_MOUSE_MOTION => { - c.doom_mouse_move(@intFromFloat(e.motion.xrel * 4), @intFromFloat(e.motion.yrel * 4)); + c.doom_mouse_move(@intFromFloat(e.motion.xrel * 4 * gDoom.sensitivity), @intFromFloat(e.motion.yrel * 4 * gDoom.sensitivity)); }, sdl3_c.SDL_EVENT_MOUSE_BUTTON_DOWN => { - c.doom_key_down(sdlToDoomScancode(e.button.button)); + log("pushing mouse button down to doom {d}", .{e.button.button}); + c.doom_button_down(sdlToDoomButton(e.button.button)); }, sdl3_c.SDL_EVENT_MOUSE_BUTTON_UP => { - c.doom_key_down(sdlToDoomScancode(e.button.button)); + log("pushing mouse button up to doom {d}", .{e.button.button}); + c.doom_button_up(sdlToDoomButton(e.button.button)); }, sdl3_c.SDL_EVENT_KEY_DOWN => { if (!e.key.repeat) { @@ -373,6 +400,13 @@ pub fn tick(self: *@This(), dt: f64) void { const cmd = rend.context().device.acquireGPUCommandBuffer(); self.releaseAndUploadFrameBuffer(cmd); _ = cmd.submitGPUCommandBuffer(); + + if (self.inputEnabled) { + if (ig.begin("doom settings", null, .{})) { + _ = ig.sliderFloat("sensitivity", &self.sensitivity, 0.1, 20, null, .{}); + ig.end(); + } + } } fn bindVideoTextures(p: ?*anyopaque) void { @@ -397,7 +431,8 @@ pub fn createEntity(self: *@This()) !core.Entity { if (entity.addComponent(rend.MeshComponent)) |mesh| { mesh.cmrf = bindVideoTextures; mesh.cmrf_ctx = self; - mesh.textureMode = 0x1; + mesh.textureMode.fullbright = true; + mesh.textureMode.noSrgb = true; mesh.setMesh("m_plane"); } return entity; diff --git a/extras/videoplayer/src/videoplayer.zig b/extras/videoplayer/src/videoplayer.zig index 030a265..8067c4f 100644 --- a/extras/videoplayer/src/videoplayer.zig +++ b/extras/videoplayer/src/videoplayer.zig @@ -267,7 +267,7 @@ pub fn createVideoPlayerEntity(self: *@This()) !core.Entity { if (entity.addComponent(rend.MeshComponent)) |mesh| { mesh.cmrf = bindVideoTextures; mesh.cmrf_ctx = self; - mesh.textureMode = 0x10; + mesh.textureMode.samplerMode = .videoYUV; mesh.setMesh("m_plane"); } return entity; diff --git a/projects/content/_shaders/dxil/lit_mesh.frag.dxil b/projects/content/_shaders/dxil/lit_mesh.frag.dxil index 92682aa..177d655 100644 Binary files a/projects/content/_shaders/dxil/lit_mesh.frag.dxil and b/projects/content/_shaders/dxil/lit_mesh.frag.dxil differ diff --git a/projects/content/_shaders/msl/lit_mesh.frag.msl b/projects/content/_shaders/msl/lit_mesh.frag.msl index 3555b42..cec1381 100644 --- a/projects/content/_shaders/msl/lit_mesh.frag.msl +++ b/projects/content/_shaders/msl/lit_mesh.frag.msl @@ -47,101 +47,101 @@ 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 Texture0 [[texture(0)]], texture2d Texture1 [[texture(1)]], texture2d Texture2 [[texture(2)]], texture2d DirectionalShadowDepthMap [[texture(3)]], sampler Sampler0 [[sampler(0)]], sampler Sampler1 [[sampler(1)]], sampler Sampler2 [[sampler(2)]], sampler DirectionalShadowSampler [[sampler(3)]]) { main0_out out = {}; - int _97 = int(scene._m0[in.in_var_TEXCOORD4].textureMode); - int _98 = _97 & 240; - float4 _132; - if (_98 == 16) + int _98 = int(scene._m0[in.in_var_TEXCOORD4].textureMode); + int _99 = _98 & 240; + float4 _133; + if (_99 == 16) { - 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); + 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 _131; - if (_98 == 0) + float4 _132; + if (_99 == 0) { - _131 = Texture0.sample(Sampler0, in.in_var_TEXCOORD0); + _132 = Texture0.sample(Sampler0, in.in_var_TEXCOORD0); } else { - _131 = _86; + _132 = _86; } - _132 = _131; + _133 = _132; } - float4 _138; - if ((_97 & 1) == 1) + float4 _139; + if ((_98 & 1) == 1) { - _138 = powr(_132, float4(2.2000000476837158203125)); + _139 = powr(_133, float4(2.2000000476837158203125)); } else { - _138 = _132; + _139 = _133; } - if (_138.w < 0.00999999977648258209228515625) + if (_139.w < 0.00999999977648258209228515625) { discard_fragment(); } - float3 _192; + float3 _193; do { - float3 _149 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1; - float _150 = length(_149); - float _151 = _150 * _150; - float _157; - if (_150 > 2.0) + float3 _150 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1; + float _151 = length(_150); + float _152 = _151 * _151; + float _158; + if (_151 > 2.0) { - _157 = 0.5 / _151; + _158 = 0.5 / _152; } else { - _157 = 1.0 / _151; + _158 = 1.0 / _152; } - float _162; - if (_150 > 4.0) + float _163; + if (_151 > 4.0) { - _162 = _157 * 0.5; + _163 = _158 * 0.5; } else { - _162 = _157; + _163 = _158; } - float _164 = (_150 > 15.0) ? 0.0 : _162; - float _166 = (_164 > 1.0) ? 1.0 : _164; + float _165 = (_151 > 15.0) ? 0.0 : _163; + float _167 = (_165 > 1.0) ? 1.0 : _165; if (length(in.in_var_TEXCOORD2) < 0.100000001490116119384765625) { - _192 = (in.in_var_TEXCOORD1 * float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5)) * _166; + _193 = (in.in_var_TEXCOORD1 * float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5)) * _167; break; } - float3 _173 = fast::normalize(_149); - _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); + float3 _174 = fast::normalize(_150); + _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); break; } while(false); - float3 _209 = ((in.in_var_TEXCOORD3.xyz / float3(in.in_var_TEXCOORD3.w)) * 0.5) + float3(0.5); - float3 _211; - _211.x = _209.x; - float2 _212 = _211.xy; - _212.y = -_209.y; - float _219; - int _222; - int _224; - _219 = 0.0; - _222 = 0; - _224 = -4; + float3 _210 = ((in.in_var_TEXCOORD3.xyz / float3(in.in_var_TEXCOORD3.w)) * 0.5) + float3(0.5); + float3 _212; + _212.x = _210.x; + float2 _213 = _212.xy; + _213.y = -_210.y; float _220; int _223; - for (; _224 <= 4; _219 = _220, _222 = _223, _224++) + int _225; + _220 = 0.0; + _223 = 0; + _225 = -4; + float _221; + int _224; + for (; _225 <= 4; _220 = _221, _223 = _224, _225++) { - _223 = _222; - _220 = _219; - for (int _233 = -4; _233 <= 4; ) + _224 = _223; + _221 = _220; + for (int _234 = -4; _234 <= 4; ) { - _223++; - _220 += float((in.in_var_TEXCOORD3.z - 0.004999999888241291046142578125) > DirectionalShadowDepthMap.sample(DirectionalShadowSampler, (_212 + float2(float(_233) * 0.000244140625, float(_224) * 0.000244140625))).x); - _233++; + _224++; + _221 += float((in.in_var_TEXCOORD3.z - 0.004999999888241291046142578125) > DirectionalShadowDepthMap.sample(DirectionalShadowSampler, (_213 + float2(float(_234) * 0.000244140625, float(_225) * 0.000244140625))).x); + _234++; continue; } } - out.out_var_SV_Target0 = float4(powr(_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))))), float3(0.4545454680919647216796875)), _138.w); + 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); return out; } diff --git a/projects/content/_shaders/spv/lit_mesh.frag.spv b/projects/content/_shaders/spv/lit_mesh.frag.spv index c74ceb9..fe17a6a 100644 Binary files a/projects/content/_shaders/spv/lit_mesh.frag.spv and b/projects/content/_shaders/spv/lit_mesh.frag.spv differ diff --git a/projects/content/sampleGameEngine.ini b/projects/content/sampleGameEngine.ini index 8de5178..09d4062 100644 --- a/projects/content/sampleGameEngine.ini +++ b/projects/content/sampleGameEngine.ini @@ -2,3 +2,6 @@ name="Sample Game" width=1920 height=1080 + +[doom] +sensitivity=6.0 diff --git a/projects/sampleGame/main.zig b/projects/sampleGame/main.zig index 2b49966..01e7ed6 100644 --- a/projects/sampleGame/main.zig +++ b/projects/sampleGame/main.zig @@ -20,6 +20,12 @@ doomplayer: *DoomPlayer = undefined, videoplayerObject: core.Entity = undefined, doomplayerObject: core.Entity = undefined, +inputEnabled: bool = true, + +videoFullbright: bool = false, + +moveLight: bool = true, + pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); pub fn init(allocator: std.mem.Allocator) !*@This() { @@ -56,21 +62,21 @@ const assetReferences = [_]assets.AssetImportReference{ "t_empire", .{ .path = "textures/lost_empire-RGBA.png" }, ), - // assets.MakeImportRefOptions( - // "Texture", - // "t_skybox", - // .{ - // .textureCube = true, - // .textureList = &.{ - // "sky_air/cube_right.png", // cubemapfacePositivex, right - // "sky_air/cube_left.png", // cubemapfacePositivex, right - // "sky_air/cube_up.png", // cubemapfacePositivex, right - // "sky_air/cube_down.png", // cubemapfacePositivex, right - // "sky_air/cube_back.png", // cubemapfacePositivex, right - // "sky_air/cube_front.png", // cubemapfacePositivex, right - // }, - // }, - // ), + assets.MakeImportRefOptions( + "Texture", + "t_skybox", + .{ + .textureCube = true, + .textureList = &.{ + "sky_air/cube_right.png", // cubemapfacePositivex, right + "sky_air/cube_left.png", // cubemapfacePositivex, right + "sky_air/cube_up.png", // cubemapfacePositivex, right + "sky_air/cube_down.png", // cubemapfacePositivex, right + "sky_air/cube_back.png", // cubemapfacePositivex, right + "sky_air/cube_front.png", // cubemapfacePositivex, right + }, + }, + ), }; pub fn prepare(self: *@This()) !void { @@ -89,7 +95,7 @@ pub fn prepare(self: *@This()) !void { 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")); exitInput.addKey(.escape, .keyDown); @@ -181,6 +187,13 @@ pub fn prepare(self: *@This()) !void { shaderReload.activate(); } + { + const input = try core.ActionBinding.create(core.MakeName("toggleDoom")); + input.addKey(.f2, .keyDown); + _ = input.data.addListener(self, toggleDoom); + input.activate(); + } + { const input = try core.ActionBinding.create(core.MakeName("toggleMouseLook")); input.addKey(.t, .keyDown); @@ -193,7 +206,17 @@ pub fn prepare(self: *@This()) !void { fn onMouseLook(ctx: ?*anyopaque, axis: core.Vector2f) void { const self: *@This() = @ptrCast(@alignCast(ctx)); - self.fpcamera.addMouseMovement(axis); + if (self.inputEnabled) { + self.fpcamera.addMouseMovement(axis); + } +} + +fn toggleDoom(ctx: ?*anyopaque, action: core.ActionEvent) void { + const self: *@This() = @ptrCast(@alignCast(ctx)); + _ = action; + + self.doomplayer.inputEnabled = !self.doomplayer.inputEnabled; + self.inputEnabled = !self.doomplayer.inputEnabled; } fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void { @@ -276,24 +299,37 @@ pub fn tick(self: *@This(), dt: f64) void { var movement = self.fpcamera.getForwardXZ().fmul(self.moveVector.z * fdt * self.cameraSpeed); movement = movement.add(self.fpcamera.getRightXZ().fmul(self.moveVector.x * fdt * self.cameraSpeed)); movement = movement.add(.{ .y = self.verticalMove * fdt * self.cameraSpeed }); - const pos = self.fpcamera.getPosition().add(movement); - self.fpcamera.setPosition(pos); self.centerDist += self.centerDistMove * fdt; + const pos = self.fpcamera.getPosition().add(movement); + + if (self.inputEnabled) { + self.fpcamera.setPosition(pos); + } + self.fpcamera.resolve(); const forward = self.fpcamera.getForward(); const debugCenter = self.fpcamera.getPosition().add(forward.fmul(self.centerDist)); - core.debugSphere(debugCenter, 0.3, .{}); - core.debugSphere(debugCenter, 0.1, .{ .color = .{ .x = 1.0 } }); - - rend.context().lightPosition = debugCenter; + if (self.moveLight) { + core.debugSphere(debugCenter, 0.3, .{}); + core.debugSphere(debugCenter, 0.1, .{ .color = .{ .x = 1.0 } }); + rend.context().lightPosition = debugCenter; + } // show a window with the current camera's position if (ig.begin("meh", &self.showWindow, .{})) { ig.textFmt("x:{d:.03} y:{d:.03} z:{d:.03}", .{ pos.x, pos.y, pos.z }) catch return; + if (ig.checkbox("video fullbright", &self.videoFullbright)) { + if (self.videoplayerObject.fetch(rend.MeshComponent)) |mesh| { + mesh.textureMode.fullbright = self.videoFullbright; + } + } + + if (ig.checkbox("move lights ", &self.moveLight)) {} + ig.end(); } }