saving before stash

This commit is contained in:
Peter Li 2025-04-18 19:54:59 -07:00
parent b9f3f75972
commit ff101925ff
26 changed files with 434 additions and 57 deletions

View File

@ -391,6 +391,8 @@ pub const Binding = union(BindingType) {
p.magnitude.x = std.math.clamp(p.magnitude.x, -1.0, 1.0); p.magnitude.x = std.math.clamp(p.magnitude.x, -1.0, 1.0);
p.magnitude.y = std.math.clamp(p.magnitude.y, -1.0, 1.0); p.magnitude.y = std.math.clamp(p.magnitude.y, -1.0, 1.0);
// core.engine_log(" >> {any} > routeBindingEvent magnitude {d} {d}", .{ key, p.magnitude.x, p.magnitude.y });
// for (p.data.listeners.items) |listener| { // for (p.data.listeners.items) |listener| {
// listener.func(listener.ctx, p.magnitude); // listener.func(listener.ctx, p.magnitude);
// } // }
@ -562,11 +564,14 @@ pub const InputStack = struct {
fn routeKeyEvent(self: *@This(), key: Key, event: ActionEvent) void { fn routeKeyEvent(self: *@This(), key: Key, event: ActionEvent) void {
// for all bindings in reverse order from this layer, route the input, stop the // for all bindings in reverse order from this layer, route the input, stop the
// route if the input was consumed // route if the input was consumed
// core.engine_log(" >> {any} > routeKeyEvent 1", .{key});
if (self.active.bindingStack.items.len == 0) { if (self.active.bindingStack.items.len == 0) {
return; return;
} }
// core.engine_log(" >> {any} > routeKeyEvent 2", .{key});
var i: i32 = @intCast(self.active.bindingStack.items.len - 1); var i: i32 = @intCast(self.active.bindingStack.items.len - 1);
// core.engine_log(" >> {any} > routeKeyEvent 2 binding count : {d}", .{ key, i });
while (i >= 0) : (i -= 1) { while (i >= 0) : (i -= 1) {
const binding = self.active.bindingStack.items[@intCast(i)]; const binding = self.active.bindingStack.items[@intCast(i)];
var consumed: bool = false; var consumed: bool = false;
@ -597,6 +602,7 @@ pub const InputStack = struct {
.key => |key| { .key => |key| {
const keyEvent: ActionEvent = key.action; // @enumFromInt(@as(u8, @intCast(key.action))); const keyEvent: ActionEvent = key.action; // @enumFromInt(@as(u8, @intCast(key.action)));
if (keyEvent != .keyHeld) { if (keyEvent != .keyHeld) {
// core.engine_log("converted: {any}", .{keyEvent});
self.routeKeyEvent(key.key, keyEvent); self.routeKeyEvent(key.key, keyEvent);
} }
}, },

View File

@ -151,6 +151,8 @@ pub const PlatformInstance = struct {
else => {}, else => {},
} }
} }
inputStack.sendAxisUpdates();
} }
pub fn getCursorPosition(self: *@This()) core.Vector2f { pub fn getCursorPosition(self: *@This()) core.Vector2f {

View File

@ -34,6 +34,7 @@ pub fn build(b: *std.Build) void {
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "sample.vert", b.path("shaders/sample.vert.json")); sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "sample.vert", b.path("shaders/sample.vert.json"));
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "meshes.vert", b.path("shaders/meshes.vert.json")); sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "meshes.vert", b.path("shaders/meshes.vert.json"));
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "lit_mesh.frag", b.path("shaders/lit_mesh.frag.json"));
// ========== tests ========== // ========== tests ==========
const tests = b.addTest(.{ const tests = b.addTest(.{

View File

@ -0,0 +1,5 @@
float4 main(float2 UV : TEXCOORD0) : SV_Target0
{
return float4(UV, 0.0, 1.0);
}

View File

@ -0,0 +1,22 @@
{
"entryPoints" : [
{
"name" : "main",
"mode" : "frag"
}
],
"inputs" : [
{
"type" : "vec2",
"name" : "in.var.TEXCOORD0",
"location" : 0
}
],
"outputs" : [
{
"type" : "vec4",
"name" : "out.var.SV_Target0",
"location" : 0
}
]
}

View File

@ -13,6 +13,7 @@ struct Input
struct Output struct Output
{ {
float2 TexCoord : TEXCOORD0; float2 TexCoord : TEXCOORD0;
float4 Position : SV_Position; float4 Position : SV_Position;
}; };
@ -25,8 +26,8 @@ StructuredBuffer<Scene> scene: register(t0, space0);
cbuffer Uniforms : register(b0, space1) cbuffer Uniforms : register(b0, space1)
{ {
float4x4 ViewProjection; float4x4 ViewProjection : packoffset(c0);
float time; float time: packoffset(c16);
}; };
Output main(Input input) Output main(Input input)

View File

@ -48,7 +48,7 @@
{ {
"name" : "time", "name" : "time",
"type" : "float", "type" : "float",
"offset" : 64 "offset" : 256
} }
] ]
} }
@ -86,7 +86,7 @@
{ {
"type" : "_10", "type" : "_10",
"name" : "type.Uniforms", "name" : "type.Uniforms",
"block_size" : 68, "block_size" : 260,
"set" : 1, "set" : 1,
"binding" : 0 "binding" : 0
} }

View File

@ -0,0 +1,96 @@
fov: f32 = 70.0,
altFov: f32 = 70.0,
aspect: f32 = 16.0 / 9.0,
near_clipping: f32 = 0.1,
far_clipping: f32 = 10000.0,
transform: core.Transform = zm.identity(),
worldTransform: Mat = zm.identity(),
projection: Mat = makePerspective(
core.radians(70.0), // angle
16.0 / 9.0,
0.1,
200000,
),
projectionAlt: Mat = makePerspective(
core.radians(70.0), // angle
16.0 / 9.0,
0.0001,
1000,
),
yaw: f32 = 0,
pitch: f32 = 0,
roll: f32 = 0,
final: Mat = zm.identity(),
finalAlt: Mat = zm.identity(),
entity: core.Entity = undefined,
pub fn initECS(self: *@This(), handle: core.SetHandle) void {
self.entity = core.Entity.fromHandle(handle);
}
pub fn updateProjections(self: *@This()) core.Transform {
self.projection = zm.perspectiveFovRh(core.radians(self.fov), 16.0 / 9.0, 0.1, 200000);
self.projection[1][1] *= -1;
self.projectionAlt = zm.perspectiveFovRh(core.radians(self.altFov), 16.0 / 9.0, 0.01, 200000);
self.projectionAlt[1][1] *= -1;
}
pub fn resolve(self: *@This()) void {
const scene = self.entity.get(core.Scene).?;
const position = scene.getPosition();
{
var base = core.zm.identity();
base = mul(core.zm.rotationY(-self.yaw), base);
base = mul(core.zm.rotationX(self.pitch), base);
base = mul(core.zm.rotationZ(self.roll), base);
const pr2 = core.scene.SceneObjectPosRot{
.position = position,
};
self.worldTransform = mul(base, pr2.toTransform());
}
// calculate viewProjections
{
var base = core.zm.rotationY(self.yaw + core.radians(180.0));
base = mul(base, core.zm.rotationX(self.pitch));
base = mul(base, core.zm.rotationZ(self.roll));
self.transform = base;
self.transform = mul(zm.translationV(position.fmul(-1).toZm()), self.transform);
self.final = mul(self.transform, self.projection);
self.finalAlt = mul(self.transform, self.projectionAlt);
}
}
fn makePerspective(fov: f32, aspect: f32, near: f32, far: f32) Mat {
const proj = core.zm.perspectiveFovRh(
core.radians(fov),
aspect,
near,
far,
);
// proj[1][1] *= -1;
return proj;
}
pub var BaseContainer: *core.SparseMap(@This()) = undefined;
pub const ComponentName = "Camera";
pub const ScriptExports: []const []const u8 = &.{};
pub const EcsComponentDefinition = ecs.DefineComponent(@This(), .set);
const core = @import("core");
const ecs = core.ecs;
const zm = core.zm;
const mul = zm.mul;
const Mat = core.Mat;
const std = @import("std");

View File

@ -0,0 +1,5 @@
fov: f32 = 70.0,
altFov: f32 = 70.0,
aspect: f32 = 16.0 / 9.0,
near_clipping: f32 = 0.1,
far_clipping: f32 = 10000.0,

View File

@ -5,25 +5,47 @@ visibility: bool = true,
textureName: core.Name = core.NameInvalid, textureName: core.Name = core.NameInvalid,
meshName: core.Name = core.NameInvalid, meshName: core.Name = core.NameInvalid,
entity: core.Entity = undefined,
pub var BaseContainer: *MeshSet = undefined; pub var BaseContainer: *MeshSet = undefined;
pub const ComponentName = "Mesh"; pub const ComponentName = "Mesh";
pub const ScriptExports: []const []const u8 = &.{ pub const ScriptExports: []const []const u8 = &.{
"setMesh", "setMesh",
"setTextureByName", // "setTexture",
}; };
pub fn setMeshByName(self: *@This(), meshName: core.Name) void { pub fn initECS(self: *@This(), handle: core.SetHandle) void {
self.meshName = meshName; // get the mesh component
self.entity = core.Entity{ .handle = handle };
if (self.entity.get(core.Scene) == null) {
@panic("mesh added to something that doesn't have a scene component, not supported");
}
}
pub fn setMeshByName(self: *@This(), meshName: *core.Name) void {
self.mesh = rend.getMeshByName(meshName);
self.meshName = meshName.*;
} }
// script function // script function
pub fn setMesh(self: *@This(), meshName: []const u8) void { pub fn setMesh(self: *@This(), meshName: []const u8) void {
const name = core.MakeName(meshName); var name = core.MakeName(meshName);
self.mesh = rend.getMeshByName(core.MakeName(meshName)); self.setMeshByName(&name);
self.meshName = name;
} }
// pub fn setTextureByName(self: *@This(), n: []const u8) void {
// var name = core.MakeName(n);
// self.mesh = rend.getTextureByName(&name);
// self.textureName = name;
// }
// pub fn setTexture(self: *@This(), n: []const u8) void {
// var name = core.MakeName(n);
// self.textureName = rend.getTextureByName(&name);
// }
// animator: ?*Animator = null, todo.. implement animator // animator: ?*Animator = null, todo.. implement animator
pub const MeshSet = core.SparseSet(@This()); pub const MeshSet = core.SparseSet(@This());

View File

@ -8,6 +8,10 @@ pub const MeshUpdate = meshes.MeshUpdate;
pub const MeshVertex = meshes.MeshVertex; pub const MeshVertex = meshes.MeshVertex;
pub const IndexedMesh = meshes.IndexedMesh; pub const IndexedMesh = meshes.IndexedMesh;
// components exports
pub const MeshComponent = @import("meshes/MeshComponent.zig");
pub const CameraComponent = @import("camera/CameraComponent.zig");
// asset loaders // asset loaders
pub const gltfLoader = @import("meshes/gltfLoader.zig"); pub const gltfLoader = @import("meshes/gltfLoader.zig");
@ -20,6 +24,9 @@ pub const MeshPool = renderer.MeshPool;
pub const getMesh = renderer.getMesh; pub const getMesh = renderer.getMesh;
pub const getMeshByName = renderer.getMeshByName; pub const getMeshByName = renderer.getMeshByName;
// camera API
pub const setActiveCamera = renderer.setActiveCamera;
var rendAllocator: std.mem.Allocator = undefined; var rendAllocator: std.mem.Allocator = undefined;
pub fn getAllocator() std.mem.Allocator { pub fn getAllocator() std.mem.Allocator {
return rendAllocator; return rendAllocator;
@ -38,9 +45,14 @@ pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std
core.engine_log("starting up renderer interface", .{}); core.engine_log("starting up renderer interface", .{});
rendAllocator = allocator; rendAllocator = allocator;
try renderer.start(); try renderer.start();
try core.defineComponent(MeshComponent, allocator);
try core.defineComponent(CameraComponent, allocator);
} }
pub fn shutdown_module(allocator: std.mem.Allocator) void { pub fn shutdown_module(allocator: std.mem.Allocator) void {
core.undefineComponent(MeshComponent);
core.undefineComponent(CameraComponent);
_ = allocator; _ = allocator;
renderer.shutdown(); renderer.shutdown();
} }

View File

@ -72,6 +72,7 @@ pub const MeshPool = struct {
const vertexSpan = try self.addTransfer(copyPass, self.vertexBuffer, meshes.MeshVertex, &self.vertexSpans, new.vertices); const vertexSpan = try self.addTransfer(copyPass, self.vertexBuffer, meshes.MeshVertex, &self.vertexSpans, new.vertices);
var name = new.name; var name = new.name;
core.graphics_log("uploading {d} vertices and {d} indices", .{ vertexSpan.size, indexSpan.size });
try self.installedMeshes.put(self.allocator, name.handle(), .{ try self.installedMeshes.put(self.allocator, name.handle(), .{
.vertex = vertexSpan, .vertex = vertexSpan,
.index = indexSpan, .index = indexSpan,

View File

@ -14,13 +14,18 @@ pub const Renderer = struct {
shaderSuffix: []const u8 = undefined, shaderSuffix: []const u8 = undefined,
shaderformat: gpu.GPUShaderFormat = undefined, shaderformat: gpu.GPUShaderFormat = undefined,
entrypoint: []const u8 = "main", entrypoint: []const u8 = "main",
pipeline: *gpu.GPUGraphicsPipeline = undefined, testPipeline: *gpu.GPUGraphicsPipeline = undefined,
meshPipe: *gpu.GPUGraphicsPipeline = undefined,
scissor: gpu.Rect = .{ .x = 0, .y = 0, .w = 1600, .h = 900 }, scissor: gpu.Rect = .{ .x = 0, .y = 0, .w = 1600, .h = 900 },
colorBuffer: *gpu.GPUBuffer = undefined, colorBuffer: *gpu.GPUBuffer = undefined,
colorBufferTransfer: *gpu.GPUTransferBuffer = undefined, colorBufferTransfer: *gpu.GPUTransferBuffer = undefined,
window: *sdl3.Window = undefined, window: *sdl3.Window = undefined,
activeCamera: ?*rend.CameraComponent = null,
ssboScene: *gpu.GPUBuffer = undefined,
ssboSceneUpload: *gpu.GPUTransferBuffer = undefined,
meshPool: *MeshPool = undefined, meshPool: *MeshPool = undefined,
uploads: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCopyPass) void }) = .{}, uploads: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCopyPass) void }) = .{},
@ -29,6 +34,8 @@ pub const Renderer = struct {
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
pub const MaxObjectCount = 50000;
pub fn init(allocator: std.mem.Allocator) !*@This() { pub fn init(allocator: std.mem.Allocator) !*@This() {
const self = try allocator.create(@This()); const self = try allocator.create(@This());
@ -57,7 +64,7 @@ pub const Renderer = struct {
.shaderformatSpirv = true, .shaderformatSpirv = true,
.shaderformatDxil = true, .shaderformatDxil = true,
.shaderformatMsl = true, .shaderformatMsl = true,
}, false, null); }, true, null);
self.window = platform.getInstance().window; self.window = platform.getInstance().window;
@ -69,6 +76,7 @@ pub const Renderer = struct {
core.engine_log("sgpu device created, using shader format: {s}", .{self.shaderSuffix}); core.engine_log("sgpu device created, using shader format: {s}", .{self.shaderSuffix});
try self.createPipeline(); try self.createPipeline();
try self.createMeshPipeline();
try self.registerRendererObject(MeshPool); try self.registerRendererObject(MeshPool);
} }
@ -92,9 +100,94 @@ pub const Renderer = struct {
} }
} }
fn addAttribute(list: *std.ArrayList(gpu.GPUVertexAttribute), offset: *u32, size: u32, format: gpu.GPUVertexElementFormat) !void {
try list.append(.{ .location = @intCast(list.items.len), .offset = offset.* + size, .format = format, .buffer_slot = 0 });
offset.* = offset.* + size;
}
pub fn createMeshPipeline(self: *@This()) !void {
const vertex = try self.loadShader("meshes.vert", sample_vert.LoadArgs);
const fragment = try self.loadShader("lit_mesh.frag", lit_mesh_frag.LoadArgs);
var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo);
pci.vertex_shader = vertex;
pci.fragment_shader = fragment;
var attributes = std.ArrayList(gpu.GPUVertexAttribute).init(self.allocator);
defer attributes.deinit();
var offset: u32 = 0;
{
try addAttribute(&attributes, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3);
try addAttribute(&attributes, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3);
try addAttribute(&attributes, &offset, @sizeOf(f32) * 4, .vertexelementformatFloat4);
try addAttribute(&attributes, &offset, @sizeOf(f32) * 2, .vertexelementformatFloat2);
try addAttribute(&attributes, &offset, @sizeOf(u32), .vertexelementformatUint);
}
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),
};
pci.target_info.num_color_targets = 1;
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
.{
.format = self.device.getGPUSwapchainTextureFormat(self.window),
.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState),
},
};
pci.rasterizer_state.fill_mode = .fillmodeFill;
self.meshPipe = self.device.createGPUGraphicsPipeline(&pci);
// ssbo buffer
// todo.. sparse uploads
self.ssboScene = self.device.createGPUBuffer(&.{
.usage = .{ .bufferusageGraphicsStorageRead = true },
.size = MaxObjectCount * @sizeOf(meshes_vert.Scene),
.props = 0,
});
self.ssboSceneUpload = self.device.createGPUTransferBuffer(&.{
.usage = .transferbufferusageUpload,
.size = MaxObjectCount * @sizeOf(meshes_vert.Scene),
.props = 0,
});
}
pub fn uploadSSBOs(self: *@This(), copyPass: *gpu.GPUCopyPass) void {
const uploadMapped: [*]meshes_vert.Scene = self.device.mapGPUTransferBuffer(self.ssboSceneUpload, true);
self.device.unmapGPUTransferBuffer(self.ssboSceneUpload);
const container = &rend.MeshComponent.BaseContainer;
const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount);
for (0..uploadCount) |i| {
// const object = &container.dense.items[i].value;
const objectId = container.dense.items[i].sparseIndex;
var transform = core.Transform.identity();
if (core.Scene.SceneObjectContainer.get(objectId, ._repr)) |repr| {
transform = repr.transform;
}
uploadMapped[i].Model = @bitCast(transform);
}
copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.ssboSceneUpload, .offset = 0 }, &.{
.buffer = self.ssboScene,
.offset = 0,
.size = uploadCount * @sizeOf(meshes_vert.Scene),
}, true);
}
pub fn createPipeline(self: *@This()) !void { pub fn createPipeline(self: *@This()) !void {
const vertex = try self.loadShader("sample.vert", 0, 0, 1, 0); const vertex = try self.loadShader("sample.vert", sample_vert.LoadArgs);
const fragment = try self.loadShader("sample.frag", 0, 0, 0, 0); const fragment = try self.loadShader("sample.frag", .{});
var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo); var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo);
pci.fragment_shader = fragment; pci.fragment_shader = fragment;
@ -109,7 +202,7 @@ pub const Renderer = struct {
}; };
pci.rasterizer_state.fill_mode = .fillmodeFill; pci.rasterizer_state.fill_mode = .fillmodeFill;
self.pipeline = self.device.createGPUGraphicsPipeline(&pci); self.testPipeline = self.device.createGPUGraphicsPipeline(&pci);
self.colorBuffer = self.device.createGPUBuffer(&.{ self.colorBuffer = self.device.createGPUBuffer(&.{
.usage = .{ .bufferusageVertex = true }, .usage = .{ .bufferusageVertex = true },
@ -127,18 +220,12 @@ pub const Renderer = struct {
pub fn loadShader( pub fn loadShader(
self: *@This(), self: *@This(),
shaderName: []const u8, shaderName: []const u8,
num_samplers: u32, // The number of samplers defined in the shader. loadArgs: ShaderLoadArgs,
num_storage_textures: u32, // The number of storage textures defined in the shader.
num_storage_buffers: u32, // The number of storage buffers defined in the shader.
num_uniform_buffers: u32, // The number of uniform buffers defined in the shader.
) !*gpu.GPUShader { ) !*gpu.GPUShader {
const contentPath = try std.fmt.allocPrint(self.allocator, "_shaders/{s}/{s}{s}", .{ self.shaderType, shaderName, self.shaderSuffix }); const contentPath = try std.fmt.allocPrint(self.allocator, "_shaders/{s}/{s}{s}", .{ self.shaderType, shaderName, self.shaderSuffix });
defer self.allocator.free(contentPath); defer self.allocator.free(contentPath);
const mapping = try core.fs().loadFile(contentPath);
defer core.fs().unmap(mapping);
var stage: gpu.GPUShaderStage = undefined; var stage: gpu.GPUShaderStage = undefined;
if (std.mem.endsWith(u8, shaderName, ".vert")) { if (std.mem.endsWith(u8, shaderName, ".vert")) {
@ -149,21 +236,26 @@ pub const Renderer = struct {
return error.NotImplemented; return error.NotImplemented;
} }
core.engine_log("creating shader {s} => {s} {any} args: {any}", .{ shaderName, contentPath, stage, loadArgs });
const mapping = try core.fs().loadFile(contentPath);
defer core.fs().unmap(mapping);
const sci = gpu.GPUShaderCreateInfo{ const sci = gpu.GPUShaderCreateInfo{
.code = @ptrCast(mapping.bytes.ptr), .code = @ptrCast(mapping.bytes.ptr),
.entrypoint = @ptrCast(self.entrypoint.ptr), .entrypoint = @ptrCast(self.entrypoint.ptr),
.format = self.shaderformat, .format = self.shaderformat,
.code_size = mapping.bytes.len - 1, .code_size = mapping.bytes.len - 1,
.stage = stage, .stage = stage,
.num_samplers = num_samplers, .num_samplers = loadArgs.num_samplers,
.num_storage_textures = num_storage_textures, // The number of storage textures defined in the shader. .num_storage_textures = loadArgs.num_storage_textures, // The number of storage textures defined in the shader.
.num_storage_buffers = num_storage_buffers, // The number of storage buffers defined in the shader. .num_storage_buffers = loadArgs.num_storage_buffers, // The number of storage buffers defined in the shader.
.num_uniform_buffers = num_uniform_buffers, // The number of uniform buffers defined in the shader. .num_uniform_buffers = loadArgs.num_uniform_buffers, // The number of uniform buffers defined in the shader.
.props = 0, .props = 0,
}; };
const rv = self.device.createGPUShader(&sci); const rv = self.device.createGPUShader(&sci);
core.engine_log("creating shader {s} => {s} {any}", .{ shaderName, contentPath, stage });
return rv; return rv;
} }
@ -179,6 +271,11 @@ pub const Renderer = struct {
self.device.unmapGPUTransferBuffer(self.colorBufferTransfer); self.device.unmapGPUTransferBuffer(self.colorBufferTransfer);
if (self.activeCamera) |camera| {
camera.resolve();
}
// map and upload Uniforms here
const copyPass = cmd.beginGPUCopyPass(); const copyPass = cmd.beginGPUCopyPass();
defer copyPass.endGPUCopyPass(); defer copyPass.endGPUCopyPass();
copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.colorBufferTransfer, .offset = 0 }, &.{ copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.colorBufferTransfer, .offset = 0 }, &.{
@ -190,6 +287,7 @@ pub const Renderer = struct {
for (self.uploads.items) |upload| { for (self.uploads.items) |upload| {
upload.func(upload.ptr, copyPass); upload.func(upload.ptr, copyPass);
} }
if (!cmd.submitGPUCommandBuffer()) { if (!cmd.submitGPUCommandBuffer()) {
core.graphics_log("submit gpu command buffer SDL ERROR: {s}", .{sdl3.getError()}); core.graphics_log("submit gpu command buffer SDL ERROR: {s}", .{sdl3.getError()});
} }
@ -214,7 +312,7 @@ pub const Renderer = struct {
targetInfo.store_op = .storeopStore; targetInfo.store_op = .storeopStore;
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null); const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null);
renderpass.bindGPUGraphicsPipeline(self.pipeline); renderpass.bindGPUGraphicsPipeline(self.testPipeline);
renderpass.bindGPUVertexStorageBuffers(0, &self.colorBuffer, 1); renderpass.bindGPUVertexStorageBuffers(0, &self.colorBuffer, 1);
renderpass.setGPUScissor(&self.scissor); renderpass.setGPUScissor(&self.scissor);
renderpass.drawGPUPrimitives(3, 1, 0, 0); renderpass.drawGPUPrimitives(3, 1, 0, 0);
@ -225,6 +323,8 @@ pub const Renderer = struct {
} }
pub fn deinit(self: *@This()) void { pub fn deinit(self: *@This()) void {
self.device.releaseGPUGraphicsPipeline(self.testPipeline);
for (self.destroys.items) |d| { for (self.destroys.items) |d| {
d.func(d.ptr); d.func(d.ptr);
} }
@ -245,11 +345,16 @@ const core = @import("core");
const platform = @import("platform"); const platform = @import("platform");
const sdl3 = @import("sdl3"); const sdl3 = @import("sdl3");
const gpu = sdl3.gpu; const gpu = sdl3.gpu;
const SSBO_Scene = @import("sample.vert").Scene;
const meshes_vert = @import("meshes.vert"); const meshes_vert = @import("meshes.vert");
const lit_mesh_frag = @import("lit_mesh.frag");
const sample_vert = @import("sample.vert");
const MeshVertices = meshes_vert.Scene; const MeshVertices = meshes_vert.Scene;
const MeshUniforms = meshes_vert.Uniforms; const MeshUniforms = meshes_vert.Uniforms;
const ShaderLoadArgs = sdl3.shaderTypes.ShaderLoadArgs;
pub const mesh_pool = @import("mesh-pool.zig"); pub const mesh_pool = @import("mesh-pool.zig");
pub const MeshPool = mesh_pool.MeshPool; pub const MeshPool = mesh_pool.MeshPool;
@ -264,6 +369,11 @@ pub fn shutdown() void {}
pub fn context() *Renderer { pub fn context() *Renderer {
return gRenderer; return gRenderer;
} }
pub fn setActiveCamera(camera: ?*rend.CameraComponent) void {
gRenderer.activeCamera = camera;
}
pub const getMesh = mesh_pool.getMesh; pub const getMesh = mesh_pool.getMesh;
pub const getMeshByName = mesh_pool.getMeshByName; pub const getMeshByName = mesh_pool.getMeshByName;

6
lib/sdl3/build.zig vendored
View File

@ -53,6 +53,12 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("src/sdl3.zig"), .root_source_file = b.path("src/sdl3.zig"),
}); });
const shaderTypes = b.dependency("shaderTypes", .{
.target = target,
.optimize = optimize,
});
mod.addImport("shaderTypes", shaderTypes.module("shaderTypes"));
mod.addIncludePath(b.path("SDL/include")); mod.addIncludePath(b.path("SDL/include"));
mod.linkLibrary(sdl3_lib); mod.linkLibrary(sdl3_lib);

View File

@ -94,15 +94,15 @@ pub const FieldDetail = struct {
}; };
pub const ShaderLoadArgs = struct { pub const ShaderLoadArgs = struct {
num_samplers: u32, // The number of samplers defined in the shader. num_samplers: u32 = 0, // The number of samplers defined in the shader.
num_storage_textures: u32, // The number of storage textures defined in the shader. num_storage_textures: u32 = 0, // The number of storage textures defined in the shader.
num_storage_buffers: u32, // The number of storage buffers defined in the shader. num_storage_buffers: u32 = 0, // The number of storage buffers defined in the shader.
num_uniform_buffers: u32, // The number of uniform buffers defined in the shader. num_uniform_buffers: u32 = 0, // The number of uniform buffers defined in the shader.
}; };
pub const BufferInfo = union(enum(usize)) { pub const BufferInfo = union(enum(usize)) {
sampler: usize, // sampler sampler: u32, // sampler
texture: usize, // storage texture texture: u32, // storage texture
storage: usize, // storate buffer object storage: u32, // storate buffer object
uniform: usize, // uniform/push constant uniform: u32, // uniform/push constant
}; };

View File

@ -45,25 +45,27 @@ pub const float = shaderTypes.float;
pub const BufferInfo = shaderTypes.BufferInfo; pub const BufferInfo = shaderTypes.BufferInfo;
""" """
types = reflect['types']
storageIndex = 0 storageIndex = 0
if 'ssbos' in reflect:
for ssbo in reflect['ssbos']:
zs = parseTypeToZig(types, ssbo['type'], "storage", storageIndex)
storageIndex += 1
ostring += zs + "\n"
uniformIndex = 0 uniformIndex = 0
if 'ubos' in reflect:
for uniform in reflect['ubos']:
zs = parseTypeToZig(types, uniform['type'], "uniform", uniformIndex)
ostring += zs + "\n"
zs = "pub const LoadArgs = shaderTypes.ShaderLoadArgs{"
samplerIndex = 0 samplerIndex = 0
textureIndex = 0 textureIndex = 0
if 'types' in reflect:
types = reflect['types']
if 'ssbos' in reflect:
for ssbo in reflect['ssbos']:
zs = parseTypeToZig(types, ssbo['type'], "storage", ssbo['binding'])
storageIndex += 1
ostring += zs + "\n"
if 'ubos' in reflect:
for uniform in reflect['ubos']:
uniformIndex += 1
zs = parseTypeToZig(types, uniform['type'], "uniform", uniform['binding'])
ostring += zs + "\n"
zs = "pub const LoadArgs = shaderTypes.ShaderLoadArgs{"
zs += f""" zs += f"""
.num_samplers = {samplerIndex}, // The number of samplers defined in the shader. .num_samplers = {samplerIndex}, // The number of samplers defined in the shader.

View File

@ -50,3 +50,4 @@ pub fn getError() [*c]const u8 {
pub const gpu = @import("gpu.zig"); pub const gpu = @import("gpu.zig");
pub const Scancode = @import("scancode.zig").Scancode; pub const Scancode = @import("scancode.zig").Scancode;
pub const shaderTypes = @import("shaderTypes");

2
lib/tracy/build.zig vendored
View File

@ -9,7 +9,7 @@ pub fn build(b: *std.Build) void {
//const tracy_enabled = b.option(bool, "tracy", "Enables tracy integration") orelse false; //const tracy_enabled = b.option(bool, "tracy", "Enables tracy integration") orelse false;
const tracy_enabled: bool = true; //if (b.graph.env_map.hash_map.get("WITH_TRACY") != null) true else false; const tracy_enabled: bool = false; //if (b.graph.env_map.hash_map.get("WITH_TRACY") != null) true else false;
// if (b.graph.env_map.hash_map.get("WITH_TRACY")) |with_tracy| { // if (b.graph.env_map.hash_map.get("WITH_TRACY")) |with_tracy| {
// tracy_enabled = with_tracy; // tracy_enabled = with_tracy;
// } // }

Binary file not shown.

View File

@ -0,0 +1,22 @@
#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]])
{
main0_out out = {};
out.out_var_SV_Target0 = float4(in.in_var_TEXCOORD0, 0.0, 1.0);
return out;
}

View File

@ -16,6 +16,7 @@ struct type_StructuredBuffer_Scene
struct type_Uniforms struct type_Uniforms
{ {
float4x4 ViewProjection; float4x4 ViewProjection;
char _m1_pad[192];
float time; float time;
}; };

Binary file not shown.

32
projects/reflected.zig Normal file
View File

@ -0,0 +1,32 @@
pub const shaderTypes = @import("shaderTypes");
pub const int = shaderTypes.int;
pub const uint = shaderTypes.uint;
pub const vec2 = shaderTypes.vec2;
pub const u8vec4 = shaderTypes.u8vec4;
pub const vec3 = shaderTypes.vec3;
pub const vec4 = shaderTypes.vec4;
pub const mat4 = shaderTypes.mat4;
pub const float = shaderTypes.float;
pub const BufferInfo = shaderTypes.BufferInfo;
pub const Scene = struct {
Model: mat4,
pub const Buffer: BufferInfo = .{ .storage = 0 };
};
pub const Uniforms = struct {
ViewProjection: mat4,
time: float,
pub const Buffer: BufferInfo = .{ .uniform = 0 };
};
pub const LoadArgs = shaderTypes.ShaderLoadArgs{
.num_samplers = 0, // The number of samplers defined in the shader.
.num_storage_textures = 0, // The number of storage textures defined in the shader.
.num_storage_buffers = 1, // The number of storage buffers defined in the shader.
.num_uniform_buffers = 1, // The number of uniform buffers defined in the shader.
};

View File

@ -1,5 +1,12 @@
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
camera: core.Entity = undefined,
cameraSpeed: f32 = 10.0,
moveInput: *core.Axis2dBinding = undefined,
moveVector: core.Vectorf = .{},
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
pub fn init(allocator: std.mem.Allocator) !*@This() { pub fn init(allocator: std.mem.Allocator) !*@This() {
@ -24,7 +31,6 @@ const assetReferences = [_]assets.AssetImportReference{
}; };
pub fn prepare(self: *@This()) !void { pub fn prepare(self: *@This()) !void {
_ = self;
core.engine_log(">>>>>>> game prepare", .{}); core.engine_log(">>>>>>> game prepare", .{});
var z = core.tracy.ZoneN(@src(), "PREPARING GAME"); var z = core.tracy.ZoneN(@src(), "PREPARING GAME");
defer z.End(); defer z.End();
@ -38,6 +44,27 @@ pub fn prepare(self: *@This()) !void {
exitInput.addKey(.escape, .keyDown); exitInput.addKey(.escape, .keyDown);
_ = exitInput.data.addListener(null, onExit); _ = exitInput.data.addListener(null, onExit);
exitInput.activate(); exitInput.activate();
self.camera = try core.createEntity();
const scene = self.camera.addComponent(core.Scene).?;
_ = scene;
const camera = self.camera.addComponent(rend.CameraComponent).?;
rend.setActiveCamera(camera);
self.moveInput = try core.Axis2dBinding.create(core.MakeName("movement"));
self.moveInput.addKey(.w, 1.0, .y);
self.moveInput.addKey(.s, -1.0, .y);
self.moveInput.addKey(.d, 1.0, .x);
self.moveInput.addKey(.a, -1.0, .x);
_ = self.moveInput.data.addListener(self, onMove);
self.moveInput.activate();
}
fn onMove(ctx: ?*anyopaque, axis: core.Vector2f) void {
const self: *@This() = @ptrCast(@alignCast(ctx));
self.moveVector = .{ .x = -axis.x, .z = axis.y, .y = 0.0 };
} }
pub fn onExit(ctx: ?*anyopaque, action: core.ActionEvent) void { pub fn onExit(ctx: ?*anyopaque, action: core.ActionEvent) void {
@ -47,9 +74,12 @@ pub fn onExit(ctx: ?*anyopaque, action: core.ActionEvent) void {
core.exitNow(); core.exitNow();
} }
pub fn tick(self: *@This(), _: f64) void { pub fn tick(self: *@This(), dt: f64) void {
_ = self; const fdt: f32 = @floatCast(dt);
std.time.sleep(6000 * 1000); // just gonna put this here... if (self.camera.get(core.Scene)) |scene| {
scene.getPosRot().position = scene.getPosRot().position.add(self.moveVector.fmul(self.cameraSpeed * fdt));
core.engine_log(" camera position >> {any}", .{scene.getPosRot().position});
}
} }
pub fn deinit(self: *@This()) void { pub fn deinit(self: *@This()) void {