add drawing texture support
This commit is contained in:
parent
47d3dad1c3
commit
76668e841d
20
src/app.zig
20
src/app.zig
@ -17,14 +17,9 @@ bg: Platform.Color,
|
|||||||
show_first_window: bool,
|
show_first_window: bool,
|
||||||
check: bool,
|
check: bool,
|
||||||
player_pos: Vec2,
|
player_pos: Vec2,
|
||||||
|
tex: Gfx.TextureId,
|
||||||
|
|
||||||
pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
||||||
self.* = App{
|
|
||||||
.bg = .black,
|
|
||||||
.player_pos = .init(100, 100),
|
|
||||||
.show_first_window = true,
|
|
||||||
.check = false,
|
|
||||||
};
|
|
||||||
const cwd = std.Io.Dir.cwd();
|
const cwd = std.Io.Dir.cwd();
|
||||||
const sokoban_spritesheet = try cwd.readFileAlloc(
|
const sokoban_spritesheet = try cwd.readFileAlloc(
|
||||||
plt.io,
|
plt.io,
|
||||||
@ -37,6 +32,17 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
|||||||
var image = try STBImage.load(sokoban_spritesheet);
|
var image = try STBImage.load(sokoban_spritesheet);
|
||||||
defer image.deinit();
|
defer image.deinit();
|
||||||
|
|
||||||
|
const tex = try Gfx.initTexture();
|
||||||
|
try Gfx.setTexture(tex, image.rgba8_pixels, image.width, image.height);
|
||||||
|
|
||||||
|
self.* = App{
|
||||||
|
.bg = .black,
|
||||||
|
.player_pos = .init(100, 100),
|
||||||
|
.show_first_window = true,
|
||||||
|
.check = false,
|
||||||
|
.tex = tex
|
||||||
|
};
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +68,7 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
|||||||
self.player_pos = self.player_pos.add(dir.multiplyScalar(50 * dt));
|
self.player_pos = self.player_pos.add(dir.multiplyScalar(50 * dt));
|
||||||
|
|
||||||
Gfx.setClearColor(self.bg);
|
Gfx.setClearColor(self.bg);
|
||||||
Gfx.drawRectangle(self.player_pos, .init(100, 100), .rgb(200, 0, 0));
|
Gfx.drawTexture(self.tex, self.player_pos, .init(100, 100), .rgb(200, 0, 0));
|
||||||
Gfx.drawRectangle(self.player_pos.add(.init(0, 200)), .init(100, 100), .rgb(200, 200, 0));
|
Gfx.drawRectangle(self.player_pos.add(.init(0, 200)), .init(100, 100), .rgb(200, 200, 0));
|
||||||
|
|
||||||
if (ImGUI.beginWindow(.{
|
if (ImGUI.beginWindow(.{
|
||||||
|
|||||||
231
src/graphics.zig
231
src/graphics.zig
@ -16,25 +16,32 @@ const Color = @import("./color.zig");
|
|||||||
const shd = @import("shader");
|
const shd = @import("shader");
|
||||||
const SlotMapType = @import("slot_map.zig").SlotMapType;
|
const SlotMapType = @import("slot_map.zig").SlotMapType;
|
||||||
|
|
||||||
|
|
||||||
const State = struct {
|
const State = struct {
|
||||||
|
gpa: std.mem.Allocator,
|
||||||
|
|
||||||
shader: sg.Shader,
|
shader: sg.Shader,
|
||||||
pipeline: sg.Pipeline,
|
pipeline: sg.Pipeline,
|
||||||
bindings: sg.Bindings,
|
bindings: sg.Bindings,
|
||||||
|
|
||||||
default_image: sg.Image,
|
default_texture: TextureId,
|
||||||
default_view: sg.View,
|
|
||||||
default_sampler: sg.Sampler,
|
default_sampler: sg.Sampler,
|
||||||
|
|
||||||
quads_buffer: [2048]Quad,
|
quads_buffer: [2048]Quad,
|
||||||
quads: std.ArrayList(Quad),
|
quads: std.ArrayList(Quad),
|
||||||
|
|
||||||
clear_color: Color,
|
clear_color: Color,
|
||||||
|
|
||||||
|
textures_buffer: [max_textures]Texture,
|
||||||
|
textures_slotmap: TextureSlotMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const max_textures = 64;
|
||||||
|
const TextureSlotMap = SlotMapType(std.math.IntFittingRange(0, max_textures-1), u8);
|
||||||
|
pub const TextureId = TextureSlotMap.Id;
|
||||||
|
|
||||||
var g_state: State = undefined;
|
var g_state: State = undefined;
|
||||||
|
|
||||||
pub fn init(logger: sg.Logger) void {
|
pub fn init(gpa: std.mem.Allocator, logger: sg.Logger) !void {
|
||||||
const self = &g_state;
|
const self = &g_state;
|
||||||
|
|
||||||
sg.setup(.{
|
sg.setup(.{
|
||||||
@ -45,27 +52,6 @@ pub fn init(logger: sg.Logger) void {
|
|||||||
const shader = sg.makeShader(shd.mainShaderDesc(sg.queryBackend()));
|
const shader = sg.makeShader(shd.mainShaderDesc(sg.queryBackend()));
|
||||||
assert(shader.id != sg.invalid_id);
|
assert(shader.id != sg.invalid_id);
|
||||||
|
|
||||||
var pixels: [8 * 8 * 4]u8 = undefined;
|
|
||||||
@memset(&pixels, 0xFF);
|
|
||||||
var image_data: sg.ImageData = .{};
|
|
||||||
image_data.mip_levels[0] = sg.asRange(&pixels);
|
|
||||||
const default_image = sg.makeImage(.{
|
|
||||||
.type = ._2D,
|
|
||||||
.width = 8,
|
|
||||||
.height = 8,
|
|
||||||
.num_mipmaps = 1,
|
|
||||||
.pixel_format = .RGBA8,
|
|
||||||
.data = image_data,
|
|
||||||
.label = "default-texture"
|
|
||||||
});
|
|
||||||
assert(default_image.id != sg.invalid_id);
|
|
||||||
|
|
||||||
const default_view = sg.makeView(.{
|
|
||||||
.texture = .{ .image = default_image },
|
|
||||||
.label = "default-view"
|
|
||||||
});
|
|
||||||
assert(default_view.id != sg.invalid_id);
|
|
||||||
|
|
||||||
const default_sampler = sg.makeSampler(.{
|
const default_sampler = sg.makeSampler(.{
|
||||||
.min_filter = .NEAREST,
|
.min_filter = .NEAREST,
|
||||||
.mag_filter = .NEAREST,
|
.mag_filter = .NEAREST,
|
||||||
@ -109,7 +95,7 @@ pub fn init(logger: sg.Logger) void {
|
|||||||
|
|
||||||
bindings.vertex_buffers[0] = sg.makeBuffer(.{
|
bindings.vertex_buffers[0] = sg.makeBuffer(.{
|
||||||
.size = @sizeOf(Quad) * max_quads,
|
.size = @sizeOf(Quad) * max_quads,
|
||||||
.usage = .{ .vertex_buffer = true, .dynamic_update = true },
|
.usage = .{ .vertex_buffer = true, .stream_update = true },
|
||||||
.label = "quad-vertices"
|
.label = "quad-vertices"
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -133,25 +119,38 @@ pub fn init(logger: sg.Logger) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.* = State{
|
self.* = State{
|
||||||
|
.gpa = gpa,
|
||||||
.shader = shader,
|
.shader = shader,
|
||||||
.pipeline = pipeline,
|
.pipeline = pipeline,
|
||||||
.bindings = bindings,
|
.bindings = bindings,
|
||||||
.default_image = default_image,
|
|
||||||
.default_view = default_view,
|
|
||||||
.default_sampler = default_sampler,
|
.default_sampler = default_sampler,
|
||||||
.quads_buffer = undefined,
|
.quads_buffer = undefined,
|
||||||
.quads = .initBuffer(&self.quads_buffer),
|
.quads = .initBuffer(&self.quads_buffer),
|
||||||
.clear_color = .black
|
.clear_color = .black,
|
||||||
|
.textures_buffer = undefined,
|
||||||
|
.textures_slotmap = .init(try .initCapacity(gpa, max_textures)),
|
||||||
|
.default_texture = undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
const width = 8;
|
||||||
|
const height = 8;
|
||||||
|
|
||||||
|
var pixels: [width * height * 4]u8 = undefined;
|
||||||
|
@memset(&pixels, 0xFF);
|
||||||
|
|
||||||
|
self.default_texture = try initTexture();
|
||||||
|
try setTexture(self.default_texture, &pixels, width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit() void {
|
pub fn deinit() void {
|
||||||
const self = &g_state;
|
const self = &g_state;
|
||||||
|
|
||||||
|
self.textures_slotmap.deinit(self.gpa);
|
||||||
|
|
||||||
sg.destroyPipeline(self.pipeline);
|
sg.destroyPipeline(self.pipeline);
|
||||||
sg.destroyShader(self.shader);
|
sg.destroyShader(self.shader);
|
||||||
sg.destroyImage(self.default_image);
|
|
||||||
sg.destroyView(self.default_view);
|
|
||||||
sg.destroySampler(self.default_sampler);
|
sg.destroySampler(self.default_sampler);
|
||||||
sg.shutdown();
|
sg.shutdown();
|
||||||
}
|
}
|
||||||
@ -197,6 +196,11 @@ pub fn beginFrame() void {
|
|||||||
.action = pass_action,
|
.action = pass_action,
|
||||||
.swapchain = sglue.swapchain()
|
.swapchain = sglue.swapchain()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
assert(self.textures_slotmap.exists(self.default_texture));
|
||||||
|
const default_texture = self.textures_buffer[self.default_texture.index];
|
||||||
|
self.bindings.views[shd.VIEW_tex] = default_texture.view;
|
||||||
|
self.bindings.samplers[shd.SMP_smp] = self.default_sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This will always have a 1-frame delay.
|
// TODO: This will always have a 1-frame delay.
|
||||||
@ -213,11 +217,17 @@ pub fn flush() void {
|
|||||||
if (self.quads.items.len == 0) {
|
if (self.quads.items.len == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
defer self.quads.clearRetainingCapacity();
|
||||||
|
|
||||||
sg.updateBuffer(
|
const vertex_buffer = self.bindings.vertex_buffers[0];
|
||||||
self.bindings.vertex_buffers[0],
|
|
||||||
sg.asRange(self.quads.items)
|
const data = sg.asRange(self.quads.items);
|
||||||
);
|
if (sg.queryBufferWillOverflow(vertex_buffer, data.size)) {
|
||||||
|
log.warn("Vertex buffer overflow", .{});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.bindings.vertex_buffer_offsets[0] = sg.appendBuffer(vertex_buffer, data);
|
||||||
|
|
||||||
// TODO: Rectify `window_size` vs `gfx.window_size`
|
// TODO: Rectify `window_size` vs `gfx.window_size`
|
||||||
const window_size = Vec2.init(sapp.widthf(), sapp.heightf());
|
const window_size = Vec2.init(sapp.widthf(), sapp.heightf());
|
||||||
@ -229,15 +239,10 @@ pub fn flush() void {
|
|||||||
.projection = createProjectionMatrix(window_size)
|
.projection = createProjectionMatrix(window_size)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.bindings.views[shd.VIEW_tex] = self.default_view;
|
|
||||||
self.bindings.samplers[shd.SMP_smp] = self.default_sampler;
|
|
||||||
|
|
||||||
sg.applyPipeline(self.pipeline);
|
sg.applyPipeline(self.pipeline);
|
||||||
sg.applyBindings(self.bindings);
|
sg.applyBindings(self.bindings);
|
||||||
sg.applyUniforms(shd.UB_vs_params, sg.asRange(&vs_params));
|
sg.applyUniforms(shd.UB_vs_params, sg.asRange(&vs_params));
|
||||||
sg.draw(0, @intCast(self.quads.items.len * 6), 1);
|
sg.draw(0, @intCast(self.quads.items.len * 6), 1);
|
||||||
|
|
||||||
self.quads.clearRetainingCapacity();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn endFrame() void {
|
pub fn endFrame() void {
|
||||||
@ -258,34 +263,9 @@ pub fn drawQuad(quad: Quad) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawRectangle(pos: Vec2, size: Vec2, color: Color) void {
|
pub fn drawRectangle(pos: Vec2, size: Vec2, color: Color) void {
|
||||||
const color_vec4 = Vec4{
|
const self = &g_state;
|
||||||
.x = color.r,
|
|
||||||
.y = color.g,
|
drawTexture(self.default_texture, pos, size, color);
|
||||||
.z = color.b,
|
|
||||||
.w = color.a,
|
|
||||||
};
|
|
||||||
drawQuad(Quad{
|
|
||||||
Vertex{
|
|
||||||
.position = pos,
|
|
||||||
.color = color_vec4,
|
|
||||||
.texcoord = .init(0, 0)
|
|
||||||
},
|
|
||||||
Vertex{
|
|
||||||
.position = pos.add(.{ .x = size.x, .y = 0 }),
|
|
||||||
.color = color_vec4,
|
|
||||||
.texcoord = .init(1, 0)
|
|
||||||
},
|
|
||||||
Vertex{
|
|
||||||
.position = pos.add(.{ .x = 0, .y = size.y }),
|
|
||||||
.color = color_vec4,
|
|
||||||
.texcoord = .init(0, 1)
|
|
||||||
},
|
|
||||||
Vertex{
|
|
||||||
.position = pos.add(size),
|
|
||||||
.color = color_vec4,
|
|
||||||
.texcoord = .init(1, 1)
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawLine(from: Vec2, to: Vec2, color: Vec4, width: f32) void {
|
pub fn drawLine(from: Vec2, to: Vec2, color: Vec4, width: f32) void {
|
||||||
@ -320,6 +300,121 @@ pub fn drawLine(from: Vec2, to: Vec2, color: Vec4, width: f32) void {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn initTexture() !TextureId {
|
||||||
|
const self = &g_state;
|
||||||
|
const id = try self.textures_slotmap.insertBounded();
|
||||||
|
|
||||||
|
const image = sg.allocImage();
|
||||||
|
assert(image.id != sg.invalid_id);
|
||||||
|
|
||||||
|
const view = sg.allocView();
|
||||||
|
assert(view.id != sg.invalid_id);
|
||||||
|
|
||||||
|
const texture = &self.textures_buffer[id.index];
|
||||||
|
texture.* = .{
|
||||||
|
.image = image,
|
||||||
|
.view = view
|
||||||
|
};
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinitTexture(id: TextureId) void {
|
||||||
|
const self = &g_state;
|
||||||
|
if (self.textures_slotmap.remove(id)) {
|
||||||
|
const texture = self.textures_buffer[id.index];
|
||||||
|
const bound_view = &self.bindings.views[shd.VIEW_tex];
|
||||||
|
if (texture.view.id == bound_view.id) {
|
||||||
|
bound_view.* = self.default_view;
|
||||||
|
}
|
||||||
|
|
||||||
|
sg.destroyView(texture.view);
|
||||||
|
sg.destroyImage(texture.image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setTexture(id: TextureId, rgba8_pixels: [*]const u8, width: u32, height: u32) !void {
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.textures_slotmap.exists(id)) {
|
||||||
|
return error.NotFound;
|
||||||
|
}
|
||||||
|
const texture = &self.textures_buffer[id.index];
|
||||||
|
|
||||||
|
if (sg.queryImageState(texture.image) == .VALID) {
|
||||||
|
sg.uninitImage(texture.image);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pixel_count = width*height;
|
||||||
|
|
||||||
|
var image_data: sg.ImageData = .{};
|
||||||
|
image_data.mip_levels[0] = sg.asRange(rgba8_pixels[0..(pixel_count*4)]);
|
||||||
|
sg.initImage(texture.image, .{
|
||||||
|
.type = ._2D,
|
||||||
|
.width = @intCast(width),
|
||||||
|
.height = @intCast(height),
|
||||||
|
.num_mipmaps = 1,
|
||||||
|
.pixel_format = .RGBA8,
|
||||||
|
.data = image_data,
|
||||||
|
});
|
||||||
|
assert(sg.queryImageState(texture.image) == .VALID);
|
||||||
|
|
||||||
|
if (sg.queryViewState(texture.view) == .ALLOC) {
|
||||||
|
sg.initView(texture.view, .{
|
||||||
|
.texture = .{ .image = texture.image }
|
||||||
|
});
|
||||||
|
assert(sg.queryViewState(texture.view) == .VALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn drawTexture(id: TextureId, pos: Vec2, size: Vec2, color: Color) void {
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.textures_slotmap.exists(id)) {
|
||||||
|
// TODO: Draw purple-black texture
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const texture = self.textures_buffer[id.index];
|
||||||
|
|
||||||
|
const bound_view = &self.bindings.views[shd.VIEW_tex];
|
||||||
|
if (bound_view.id != texture.view.id) {
|
||||||
|
flush();
|
||||||
|
bound_view.* = texture.view;
|
||||||
|
}
|
||||||
|
|
||||||
|
const color_vec4 = Vec4{
|
||||||
|
.x = color.r,
|
||||||
|
.y = color.g,
|
||||||
|
.z = color.b,
|
||||||
|
.w = color.a,
|
||||||
|
};
|
||||||
|
drawQuad(Quad{
|
||||||
|
Vertex{
|
||||||
|
.position = pos,
|
||||||
|
.color = color_vec4,
|
||||||
|
.texcoord = .init(0, 0)
|
||||||
|
},
|
||||||
|
Vertex{
|
||||||
|
.position = pos.add(.{ .x = size.x, .y = 0 }),
|
||||||
|
.color = color_vec4,
|
||||||
|
.texcoord = .init(1, 0)
|
||||||
|
},
|
||||||
|
Vertex{
|
||||||
|
.position = pos.add(.{ .x = 0, .y = size.y }),
|
||||||
|
.color = color_vec4,
|
||||||
|
.texcoord = .init(0, 1)
|
||||||
|
},
|
||||||
|
Vertex{
|
||||||
|
.position = pos.add(size),
|
||||||
|
.color = color_vec4,
|
||||||
|
.texcoord = .init(1, 1)
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const Texture = struct {
|
||||||
|
image: sg.Image,
|
||||||
|
view: sg.View,
|
||||||
|
};
|
||||||
|
|
||||||
// const SlotMap = SlotMapType(u16, u8);
|
// const SlotMap = SlotMapType(u16, u8);
|
||||||
//
|
//
|
||||||
// const TextureId = u64;
|
// const TextureId = u64;
|
||||||
|
|||||||
@ -18,6 +18,7 @@ const ig = @import("cimgui");
|
|||||||
const ImGUI = @This();
|
const ImGUI = @This();
|
||||||
|
|
||||||
const State = struct {
|
const State = struct {
|
||||||
|
enabled: bool,
|
||||||
frame: ?Allocator
|
frame: ?Allocator
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ pub fn init(logger: simgui.Logger) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.* = State{
|
self.* = State{
|
||||||
|
.enabled = true,
|
||||||
.frame = null
|
.frame = null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -57,10 +59,15 @@ pub fn event(e: sapp.Event) bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return simgui.handleEvent(e);
|
return simgui.handleEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn beginFrame(frame: Allocator) void {
|
pub fn beginFrame(enabled: bool, frame: Allocator) void {
|
||||||
if (!build_options.has_imgui) {
|
if (!build_options.has_imgui) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -68,6 +75,11 @@ pub fn beginFrame(frame: Allocator) void {
|
|||||||
const self = &g_state;
|
const self = &g_state;
|
||||||
|
|
||||||
self.frame = frame;
|
self.frame = frame;
|
||||||
|
self.enabled = enabled;
|
||||||
|
|
||||||
|
if (!self.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
simgui.newFrame(.{
|
simgui.newFrame(.{
|
||||||
.width = sapp.width(),
|
.width = sapp.width(),
|
||||||
@ -105,6 +117,10 @@ pub fn endFrame() void {
|
|||||||
if (!build_options.has_imgui) {
|
if (!build_options.has_imgui) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// if (ig.igBegin("Game", null, ig.ImGuiWindowFlags_None)) {
|
// if (ig.igBegin("Game", null, ig.ImGuiWindowFlags_None)) {
|
||||||
@ -140,6 +156,10 @@ pub fn beginWindow(opts: WindowOptions) bool {
|
|||||||
if (!build_options.has_imgui) {
|
if (!build_options.has_imgui) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (opts.open != null and opts.open.?.* == false) {
|
if (opts.open != null and opts.open.?.* == false) {
|
||||||
return false;
|
return false;
|
||||||
@ -180,6 +200,10 @@ pub fn endWindow() void {
|
|||||||
if (!build_options.has_imgui) {
|
if (!build_options.has_imgui) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ig.igEnd();
|
ig.igEnd();
|
||||||
}
|
}
|
||||||
@ -196,6 +220,10 @@ pub fn text(comptime fmt: []const u8, args: anytype) void {
|
|||||||
if (!build_options.has_imgui) {
|
if (!build_options.has_imgui) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ig.igTextUnformatted(formatString(fmt, args));
|
ig.igTextUnformatted(formatString(fmt, args));
|
||||||
}
|
}
|
||||||
@ -204,6 +232,10 @@ pub fn button(label: []const u8) bool {
|
|||||||
if (!build_options.has_imgui) {
|
if (!build_options.has_imgui) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return ig.igButton(formatString("{s}", .{label}));
|
return ig.igButton(formatString("{s}", .{label}));
|
||||||
}
|
}
|
||||||
@ -219,6 +251,10 @@ pub fn slider(opts: SliderOptions) bool {
|
|||||||
if (!build_options.has_imgui) {
|
if (!build_options.has_imgui) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return ig.igSliderFloat(
|
return ig.igSliderFloat(
|
||||||
formatString("{s}", .{opts.label}),
|
formatString("{s}", .{opts.label}),
|
||||||
@ -232,6 +268,10 @@ pub fn checkbox(label: []const u8, value: *bool) bool {
|
|||||||
if (!build_options.has_imgui) {
|
if (!build_options.has_imgui) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return ig.igCheckbox(
|
return ig.igCheckbox(
|
||||||
formatString("{s}", .{label}),
|
formatString("{s}", .{label}),
|
||||||
@ -243,6 +283,10 @@ pub fn separator() void {
|
|||||||
if (!build_options.has_imgui) {
|
if (!build_options.has_imgui) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ig.igSeparator();
|
ig.igSeparator();
|
||||||
}
|
}
|
||||||
@ -257,6 +301,10 @@ pub fn colorEdit(opts: ColorEditOptions) bool {
|
|||||||
if (!build_options.has_imgui) {
|
if (!build_options.has_imgui) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const self = &g_state;
|
||||||
|
if (!self.enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const label = formatString("{s}", .{opts.label});
|
const label = formatString("{s}", .{opts.label});
|
||||||
var color: [4]f32 = .{
|
var color: [4]f32 = .{
|
||||||
|
|||||||
@ -24,7 +24,7 @@ const shd = @import("shader");
|
|||||||
|
|
||||||
pub const ImGUI = @import("./imgui.zig");
|
pub const ImGUI = @import("./imgui.zig");
|
||||||
pub const Gfx = @import("./graphics.zig");
|
pub const Gfx = @import("./graphics.zig");
|
||||||
const Input = @import("./input.zig");
|
pub const Input = @import("./input.zig");
|
||||||
|
|
||||||
fn PlatformType(App: type) type {
|
fn PlatformType(App: type) type {
|
||||||
return struct {
|
return struct {
|
||||||
@ -57,7 +57,7 @@ fn PlatformType(App: type) type {
|
|||||||
self.last_frame_at = self.started_at;
|
self.last_frame_at = self.started_at;
|
||||||
self.input = Input.init(window_size);
|
self.input = Input.init(window_size);
|
||||||
|
|
||||||
Gfx.init(.{
|
try Gfx.init(self.gpa, .{
|
||||||
.func = sokolLogCallback
|
.func = sokolLogCallback
|
||||||
});
|
});
|
||||||
ImGUI.init(.{
|
ImGUI.init(.{
|
||||||
@ -103,9 +103,7 @@ fn PlatformType(App: type) type {
|
|||||||
|
|
||||||
{
|
{
|
||||||
Gfx.beginFrame();
|
Gfx.beginFrame();
|
||||||
if (self.show_imgui) {
|
ImGUI.beginFrame(self.show_imgui, self.frame_arena.allocator());
|
||||||
ImGUI.beginFrame(self.frame_arena.allocator());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (@hasDecl(App, "frame")) {
|
if (@hasDecl(App, "frame")) {
|
||||||
const plt = Frame{
|
const plt = Frame{
|
||||||
@ -121,9 +119,7 @@ fn PlatformType(App: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Gfx.flush();
|
Gfx.flush();
|
||||||
if (self.show_imgui) {
|
|
||||||
ImGUI.endFrame();
|
ImGUI.endFrame();
|
||||||
}
|
|
||||||
Gfx.endFrame();
|
Gfx.endFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user