added skybox objs

This commit is contained in:
Peter Li 2025-05-02 08:51:10 -07:00
parent 274255556d
commit 68af570278
3 changed files with 276 additions and 92 deletions

View File

@ -0,0 +1,148 @@
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
allocator: std.mem.Allocator,
device: *gpu.GPUDevice = undefined,
skyboxMesh: ?rend.IndexedMesh = null,
skyboxTexture: ?*rend.Texture = null,
skyboxTextureName: ?core.Name = null,
skyboxPipeline: *gpu.GPUGraphicsPipeline = undefined,
skyboxColor: core.colors.Color = .{ .r = 71.0 / 256.0, .g = 200.0 / 256.0, .b = 1.0, .a = 1.0 },
skyboxMeshName: core.Name = core.DefineName("m_skybox"),
sampler: *gpu.GPUSampler = undefined,
pub fn create(allocator: std.mem.Allocator) !*@This() {
const self = try allocator.create(@This());
self.* = .{ .allocator = allocator };
return self;
}
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
self.device = device;
_ = try core.fs().installFileBytesMount("embedded:skybox_mesh.obj", @constCast(&skybox_mesh_obj), true);
try assets.load(
assets.MakeImportRefOptions(
"Mesh",
"m_skybox",
.{ .path = "embedded:skybox_mesh.obj" },
),
);
try self.createPipeline();
}
fn createPipeline(self: *@This()) !void {
const ctx = rend.context();
const vertex = try ctx.loadShader("skybox.vert", skybox_vert.LoadArgs);
const fragment = try ctx.loadShader("skybox.frag", skybox_frag.LoadArgs);
var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo);
pci.vertex_shader = vertex;
pci.fragment_shader = fragment;
var attributes = try ctx.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),
};
pci.target_info.num_color_targets = 1;
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
.{
.format = self.device.getGPUSwapchainTextureFormat(ctx.window),
.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState),
},
};
pci.rasterizer_state.fill_mode = .fillmodeFill;
self.skyboxPipeline = self.device.createGPUGraphicsPipeline(&pci);
self.sampler = self.device.createGPUSampler(&std.mem.zeroInit(gpu.GPUSamplerCreateInfo, .{
.min_filter = .filterNearest,
.mag_filter = .filterNearest,
.mipmap_mode = .samplermipmapmodeNearest,
.address_mode_u = .sampleraddressmodeRepeat,
.address_mode_v = .sampleraddressmodeRepeat,
.address_mode_w = .sampleraddressmodeRepeat,
}));
}
pub fn destroy(self: *@This()) void {
self.allocator.destroy(self);
}
pub fn render(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
.texture = rend.context().swapchainTexture.?,
.clear_color = self.skyboxColor,
.load_op = .loadopClear,
.store_op = .storeopStore,
});
if (self.skyboxMesh == null) {
self.skyboxMesh = rend.getMeshByName(&self.skyboxMeshName);
}
if (self.skyboxTexture == null) {
if (self.skyboxTextureName) |*name| {
self.skyboxTexture = rend.getTexture(name);
}
}
if (self.skyboxTexture) |skyboxTexture| {
if (self.skyboxMesh) |skyboxMesh| {
const ctx = rend.context();
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null);
self.uploadSkyboxUniforms(cmd);
renderpass.bindGPUVertexStorageBuffers(0, &ctx.ssboScene, 1);
renderpass.bindGPUVertexBuffers(0, &.{ .buffer = ctx.meshPool.vertexBuffer, .offset = 0 }, 1);
renderpass.bindGPUIndexBuffer(&.{ .buffer = ctx.meshPool.indexBuffer, .offset = 0 }, .indexelementsize32bit);
renderpass.bindGPUGraphicsPipeline(self.skyboxPipeline);
renderpass.bindGPUFragmentSamplers(0, &.{ .texture = skyboxTexture.texture, .sampler = self.sampler }, 1);
renderpass.drawGPUIndexedPrimitives(skyboxMesh.index.size, 1, skyboxMesh.index.start, @intCast(skyboxMesh.vertex.start), 0);
renderpass.endGPURenderPass();
}
}
}
pub fn uploadSkyboxUniforms(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
_ = self;
var data = std.mem.zeroes([@sizeOf(skybox_vert.Uniforms) / 8 + 1]usize);
const ptr: *skybox_vert.Uniforms = @ptrCast(@alignCast(&data));
if (rend.context().activeCamera) |camera| {
ptr.ViewProjection = @bitCast(camera.noTranslate);
}
cmd.pushGPUVertexUniformData(0, &data, @sizeOf(skybox_vert.Uniforms));
}
const skybox_mesh_obj align(8) = @embedFile("embedded/skybox.obj").*;
const std = @import("std");
const core = @import("core");
const rend = @import("../rend.zig");
const sdl3 = @import("sdl3");
const gpu = sdl3.gpu;
const assets = @import("assets");
const skybox_vert = @import("skybox.vert");
const skybox_frag = @import("skybox.frag");
const renderer = rend.renderer;

View File

@ -0,0 +1,40 @@
# Blender v3.6.4 OBJ File: ''
# www.blender.org
mtllib skybox.mtl
o Cube
v 100.000000 100.000000 -100.000000
v 100.000000 -100.000000 -100.000000
v 100.000000 100.000000 100.000000
v 100.000000 -100.000000 100.000000
v -100.000000 100.000000 -100.000000
v -100.000000 -100.000000 -100.000000
v -100.000000 100.000000 100.000000
v -100.000000 -100.000000 100.000000
vt 0.625000 0.500000
vt 0.625000 0.750000
vt 0.875000 0.750000
vt 0.875000 0.500000
vt 0.375000 0.750000
vt 0.375000 1.000000
vt 0.625000 1.000000
vt 0.375000 0.000000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.625000 0.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.375000 0.500000
vn 0.0000 -1.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
usemtl Material
s off
f 1/1/1 3/2/1 7/3/1 5/4/1
f 4/5/2 8/6/2 7/7/2 3/2/2
f 8/8/3 6/9/3 5/10/3 7/11/3
f 6/12/4 8/13/4 4/5/4 2/14/4
f 2/14/5 4/5/5 3/2/5 1/1/5
f 6/9/6 2/14/6 1/1/6 5/10/6

View File

@ -63,16 +63,18 @@ pub const Renderer = struct {
shadowDepthDebugOutput: *gpu.GPUTexture = undefined, shadowDepthDebugOutput: *gpu.GPUTexture = undefined,
shadowCastingPipeline: *gpu.GPUGraphicsPipeline = undefined, shadowCastingPipeline: *gpu.GPUGraphicsPipeline = undefined,
skyboxSystem: *SkyboxSystem = undefined,
// transients DO NOT TOUCH // transients DO NOT TOUCH
swapchainTexture: ?*gpu.GPUTexture = undefined, swapchainTexture: ?*gpu.GPUTexture = undefined,
skyboxMesh: ?rend.IndexedMesh = null, // skyboxMesh: ?rend.IndexedMesh = null,
skyboxTexture: ?*rend.Texture = null, // skyboxTexture: ?*rend.Texture = null,
skyboxTextureName: ?core.Name = null, // skyboxTextureName: ?core.Name = null,
skyboxPipeline: *gpu.GPUGraphicsPipeline = undefined, // skyboxPipeline: *gpu.GPUGraphicsPipeline = undefined,
skyboxColor: core.colors.Color = .{ .r = 71.0 / 256.0, .g = 200.0 / 256.0, .b = 1.0, .a = 1.0 }, // skyboxColor: core.colors.Color = .{ .r = 71.0 / 256.0, .g = 200.0 / 256.0, .b = 1.0, .a = 1.0 },
skyboxMeshName: core.Name = core.DefineName("m_skybox"), // skyboxMeshName: core.Name = core.DefineName("m_skybox"),
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
@ -138,7 +140,7 @@ pub const Renderer = struct {
self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem); self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem);
try self.createDirectionalShadowsPipeline(); try self.createDirectionalShadowsPipeline();
try self.setupSkybox(); self.skyboxSystem = try self.createRendererEngineObject(SkyboxSystem);
} }
pub fn createDirectionalShadowsPipeline(self: *@This()) !void { pub fn createDirectionalShadowsPipeline(self: *@This()) !void {
@ -146,49 +148,49 @@ pub const Renderer = struct {
try self.createShadowCastingPipeline(); try self.createShadowCastingPipeline();
} }
pub fn setupSkybox(self: *@This()) !void { // pub fn setupSkybox(self: *@This()) !void {
try assets.load( // try assets.load(
assets.MakeImportRefOptions( // assets.MakeImportRefOptions(
"Mesh", // "Mesh",
"m_skybox", // "m_skybox",
.{ .path = "meshes/skybox.obj" }, // .{ .path = "meshes/skybox.obj" },
), // ),
); // );
try self.createSkyboxPipeline(); // try self.createSkyboxPipeline();
} // }
pub fn createSkyboxPipeline(self: *@This()) !void { // pub fn createSkyboxPipeline(self: *@This()) !void {
const vertex = try self.loadShader("skybox.vert", skybox_vert.LoadArgs); // const vertex = try self.loadShader("skybox.vert", skybox_vert.LoadArgs);
const fragment = try self.loadShader("skybox.frag", skybox_frag.LoadArgs); // const fragment = try self.loadShader("skybox.frag", skybox_frag.LoadArgs);
var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo); // var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo);
pci.vertex_shader = vertex; // pci.vertex_shader = vertex;
pci.fragment_shader = fragment; // pci.fragment_shader = fragment;
var attributes = try self.generateVertexAttributeList(); // var attributes = try self.generateVertexAttributeList();
defer attributes.deinit(); // defer attributes.deinit();
pci.vertex_input_state = .{ // pci.vertex_input_state = .{
.num_vertex_buffers = 1, // .num_vertex_buffers = 1,
.vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{ // .vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{
.{ .slot = 0, .pitch = @sizeOf(rend.MeshVertex), .input_rate = .vertexinputrateVertex, .instance_step_rate = 0 }, // .{ .slot = 0, .pitch = @sizeOf(rend.MeshVertex), .input_rate = .vertexinputrateVertex, .instance_step_rate = 0 },
}, // },
.num_vertex_attributes = @intCast(attributes.items.len), // .num_vertex_attributes = @intCast(attributes.items.len),
.vertex_attributes = @ptrCast(attributes.items.ptr), // .vertex_attributes = @ptrCast(attributes.items.ptr),
}; // };
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.device.getGPUSwapchainTextureFormat(self.window),
.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), // .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState),
}, // },
}; // };
pci.rasterizer_state.fill_mode = .fillmodeFill; // pci.rasterizer_state.fill_mode = .fillmodeFill;
self.skyboxPipeline = self.device.createGPUGraphicsPipeline(&pci); // self.skyboxPipeline = self.device.createGPUGraphicsPipeline(&pci);
} // }
pub fn createSamplers(self: *@This()) !void { pub fn createSamplers(self: *@This()) !void {
core.engine_log("creating blocky sampler", .{}); core.engine_log("creating blocky sampler", .{});
@ -479,17 +481,6 @@ pub const Renderer = struct {
return rv; return rv;
} }
pub fn uploadSkyboxUniforms(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
var data = std.mem.zeroes([@sizeOf(skybox_vert.Uniforms) / 8 + 1]usize);
const ptr: *skybox_vert.Uniforms = @ptrCast(@alignCast(&data));
if (self.activeCamera) |camera| {
ptr.ViewProjection = @bitCast(camera.noTranslate);
}
cmd.pushGPUVertexUniformData(0, &data, @sizeOf(skybox_vert.Uniforms));
}
pub fn uploadUniforms(self: *@This(), cmd: *gpu.GPUCommandBuffer) !void { pub fn uploadUniforms(self: *@This(), cmd: *gpu.GPUCommandBuffer) !void {
{ {
var data = std.mem.zeroes([@sizeOf(meshes_vert.Uniforms) / 8 + 1]usize); var data = std.mem.zeroes([@sizeOf(meshes_vert.Uniforms) / 8 + 1]usize);
@ -570,10 +561,6 @@ pub const Renderer = struct {
const cmd = self.device.acquireGPUCommandBuffer(); const cmd = self.device.acquireGPUCommandBuffer();
self.frameUploads(); self.frameUploads();
for (self.preDraws.items) |interface| {
interface.func(interface.ptr, cmd);
}
// mesh pre-iteration // mesh pre-iteration
const container = rend.MeshComponent.BaseContainer; const container = rend.MeshComponent.BaseContainer;
const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount); const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount);
@ -590,7 +577,9 @@ pub const Renderer = struct {
} }
} }
self.drawDirectionalShadowMap(cmd); for (self.preDraws.items) |interface| {
interface.func(interface.ptr, cmd);
}
self.draw(cmd); self.draw(cmd);
} }
@ -653,41 +642,50 @@ pub const Renderer = struct {
_ = cmd.submitGPUCommandBuffer(); _ = cmd.submitGPUCommandBuffer();
return; return;
} }
// render the skybox
// preMeshPasses
self.drawDirectionalShadowMap(cmd);
//
// draw skybox
{ {
if (self.skyboxMesh == null) { self.skyboxSystem.render(cmd);
self.skyboxMesh = getMeshByName(&self.skyboxMeshName);
}
if (self.skyboxTexture == null) {
if (self.skyboxTextureName) |*name| {
self.skyboxTexture = getTexture(name);
}
}
if (self.skyboxTexture) |skyboxTexture| {
if (self.skyboxMesh) |skyboxMesh| {
const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
.texture = self.swapchainTexture.?,
.clear_color = self.skyboxColor,
.load_op = .loadopClear,
.store_op = .storeopStore,
});
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null);
self.uploadSkyboxUniforms(cmd);
renderpass.bindGPUGraphicsPipeline(self.skyboxPipeline);
renderpass.bindGPUFragmentSamplers(0, &.{ .texture = skyboxTexture.texture, .sampler = self.blockySampler }, 1);
renderpass.drawGPUIndexedPrimitives(skyboxMesh.index.size, 1, skyboxMesh.index.start, @intCast(skyboxMesh.vertex.start), 0);
renderpass.endGPURenderPass();
}
}
} }
// render the skybox
// {
// if (self.skyboxMesh == null) {
// self.skyboxMesh = getMeshByName(&self.skyboxMeshName);
// }
// if (self.skyboxTexture == null) {
// if (self.skyboxTextureName) |*name| {
// self.skyboxTexture = getTexture(name);
// }
// }
//
// if (self.skyboxTexture) |skyboxTexture| {
// if (self.skyboxMesh) |skyboxMesh| {
// const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
// .texture = self.swapchainTexture.?,
// .clear_color = self.skyboxColor,
// .load_op = .loadopClear,
// .store_op = .storeopStore,
// });
//
// const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null);
//
// self.uploadSkyboxUniforms(cmd);
// renderpass.bindGPUGraphicsPipeline(self.skyboxPipeline);
// renderpass.bindGPUFragmentSamplers(0, &.{ .texture = skyboxTexture.texture, .sampler = self.blockySampler }, 1);
// renderpass.drawGPUIndexedPrimitives(skyboxMesh.index.size, 1, skyboxMesh.index.start, @intCast(skyboxMesh.vertex.start), 0);
// renderpass.endGPURenderPass();
// }
// }
// }
// 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.swapchainTexture.?, .texture = self.swapchainTexture.?,
.clear_color = self.skyboxColor,
.load_op = .loadopLoad, .load_op = .loadopLoad,
.store_op = .storeopStore, .store_op = .storeopStore,
}); });
@ -788,9 +786,6 @@ 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 skybox_vert = @import("skybox.vert");
const skybox_frag = @import("skybox.frag");
const MeshVertices = meshes_vert.Scene; const MeshVertices = meshes_vert.Scene;
const MeshUniforms = meshes_vert.Uniforms; const MeshUniforms = meshes_vert.Uniforms;
@ -802,6 +797,7 @@ pub const MeshPool = mesh_pool.MeshPool;
pub const TextureList = @import("TextureList.zig"); pub const TextureList = @import("TextureList.zig");
const DebugDrawSystem = @import("DebugDrawSystem.zig"); const DebugDrawSystem = @import("DebugDrawSystem.zig");
const SkyboxSystem = @import("SkyboxSystem.zig");
// debug api // debug api
@ -842,7 +838,7 @@ pub fn registerRendererObject(comptime T: type, object: *anyopaque) !void {
} }
pub fn setSkyboxTexture(name: []const u8) void { pub fn setSkyboxTexture(name: []const u8) void {
gRenderer.skyboxTextureName = core.MakeName(name); gRenderer.skyboxSystem.skyboxTextureName = core.MakeName(name);
} }
pub const getMesh = mesh_pool.getMesh; pub const getMesh = mesh_pool.getMesh;