134 lines
4.1 KiB
Zig
134 lines
4.1 KiB
Zig
pub const papyrus = @import("papyrus");
|
|
const core = @import("core");
|
|
const rend = @import("rend");
|
|
const std = @import("std");
|
|
const sdl = @import("sdl3");
|
|
const gpu = sdl.gpu;
|
|
|
|
allocator: std.mem.Allocator,
|
|
runtime: *papyrus.PapyrusRuntime,
|
|
screenContext: *papyrus.Context,
|
|
|
|
quadMesh: ?rend.IndexedMesh = null,
|
|
quadMeshName: core.Name,
|
|
|
|
stringArena: std.heap.ArenaAllocator,
|
|
drawList: papyrus.DrawList,
|
|
first: bool = true,
|
|
|
|
rectPipeline: *gpu.GPUGraphicsPipeline = undefined,
|
|
// textPipeline: *gpu.GPUGraphicsPipeline = undefined,
|
|
|
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "ui.runtime");
|
|
|
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
|
const self: *@This() = try allocator.create(@This());
|
|
core.engine_logs("UI module started");
|
|
|
|
self.* = .{
|
|
.allocator = allocator,
|
|
.screenContext = undefined,
|
|
.runtime = try papyrus.PapyrusRuntime.create(allocator),
|
|
.stringArena = std.heap.ArenaAllocator.init(allocator),
|
|
.quadMeshName = core.MakeName("m_screenPlane"),
|
|
.drawList = papyrus.DrawList.init(allocator),
|
|
};
|
|
|
|
self.screenContext = try self.runtime.addContext();
|
|
|
|
return self;
|
|
}
|
|
|
|
pub fn setup(self: *@This()) !void {
|
|
core.graphics_log("imgui startup", .{});
|
|
try rend.registerRendererObject(@This(), self);
|
|
}
|
|
|
|
pub fn destroy(self: *@This()) void {
|
|
self.screenContext.destroy();
|
|
self.runtime.destroy();
|
|
self.allocator.destroy(self);
|
|
}
|
|
|
|
pub fn createTextPipeline() !void {}
|
|
|
|
pub fn createRectPipeline(self: *@This()) !void {
|
|
const ctx = rend.context();
|
|
const vertex = try ctx.loadShader("rect.vert", rect_vert.LoadArgs);
|
|
const fragment = try ctx.loadShader("rect.frag", rect_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 = ctx.swapchainTargetFormat,
|
|
.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState),
|
|
},
|
|
};
|
|
|
|
pci.rasterizer_state.fill_mode = .fillmodeFill;
|
|
self.rectPipeline = ctx.device.createGPUGraphicsPipeline(&pci);
|
|
}
|
|
|
|
pub fn postRender(p: *anyopaque, cmd: *gpu.GPUCommandBuffer) void {
|
|
const self: *@This() = @ptrCast(@alignCast(p));
|
|
|
|
if (self.quadMesh == null) {
|
|
self.quadMesh = rend.getMeshByName(&self.quadMeshName);
|
|
}
|
|
|
|
self.drawToTarget(self.screenContext, rend.context().state.swapchainTargetTexture.?);
|
|
|
|
_ = cmd;
|
|
}
|
|
|
|
pub fn drawToTarget(self: *@This(), ctx: *papyrus.Context, targetTexture: *gpu.GPUTexture) void {
|
|
ctx.makeDrawList(&self.drawList, &self.stringArena) catch return;
|
|
|
|
if (self.first) {
|
|
self.first = false;
|
|
|
|
for (self.drawList.items) |item| {
|
|
core.engine_log("{any}", .{item});
|
|
}
|
|
}
|
|
|
|
const cmd = rend.context().state.cmd.?;
|
|
|
|
const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
|
.texture = targetTexture,
|
|
.load_op = .loadopLoad,
|
|
.store_op = .storeopStore,
|
|
});
|
|
|
|
const pass = cmd.beginGPURenderPass(&targetInfo, 1, null);
|
|
pass.bindGPUVertexBuffers(1, &.{ .buffer = rend.context().meshPool.vertexBuffer, .offset = 0 }, 1);
|
|
pass.bindGPUIndexBuffer(&.{ .buffer = rend.context().meshPool.indexBuffer, .offset = 0 }, .indexelementsize32bit);
|
|
for (self.drawList.items) |item| {
|
|
switch (item.primitive) {
|
|
.Rect => {},
|
|
.Text => {},
|
|
}
|
|
}
|
|
|
|
pass.endGPURenderPass();
|
|
}
|
|
|
|
pub const rect_frag = @import("rect.frag");
|
|
pub const rect_vert = @import("rect.vert");
|