0.14 zig version, pretty build.zig, renamed SDL defs
This commit is contained in:
128
build.zig
128
build.zig
@@ -1,4 +1,5 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const Build = std.Build;
|
||||||
|
|
||||||
/// Paths specified here are compiled to SPIR-V instead of being copied over
|
/// Paths specified here are compiled to SPIR-V instead of being copied over
|
||||||
const SHADERS: []const []const u8 = &.{
|
const SHADERS: []const []const u8 = &.{
|
||||||
@@ -6,19 +7,110 @@ const SHADERS: []const []const u8 = &.{
|
|||||||
"data/shaders/basic.frag",
|
"data/shaders/basic.frag",
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *Build) void {
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const exe = step_build_main(b, target, optimize);
|
||||||
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
const copy_data = step_copy_data(b, target, optimize);
|
||||||
|
b.getInstallStep().dependOn(copy_data);
|
||||||
|
|
||||||
|
const run = b.addRunArtifact(exe);
|
||||||
|
run.step.dependOn(b.getInstallStep());
|
||||||
|
|
||||||
|
// Why is this not the default behavoir?
|
||||||
|
run.setCwd(b.path(std.fs.path.relative(b.allocator, b.build_root.path.?, b.exe_dir) catch unreachable));
|
||||||
|
|
||||||
|
if (b.args) |args| {
|
||||||
|
run.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
run_step.dependOn(&run.step);
|
||||||
|
|
||||||
|
const check_step = b.step("check", "Check for build errors");
|
||||||
|
check_step.dependOn(&exe.step);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_build_main(
|
||||||
|
b: *Build,
|
||||||
|
target: Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
) *Build.Step.Compile {
|
||||||
const exe = b.addExecutable(.{
|
const exe = b.addExecutable(.{
|
||||||
.name = "spacefarer",
|
.name = "spacefarer",
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
b.installArtifact(exe);
|
|
||||||
exe.linkLibC();
|
const sdl_module, const sdl_step = step_sdl_module(b, target, optimize);
|
||||||
exe.linkSystemLibrary("SDL3");
|
exe.root_module.addImport("sdl", sdl_module);
|
||||||
|
exe.step.dependOn(sdl_step);
|
||||||
|
|
||||||
|
return exe;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_build_sdl_translator(
|
||||||
|
b: *Build,
|
||||||
|
target: Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
) *Build.Step.Compile {
|
||||||
|
const sdl_translator = b.addExecutable(.{
|
||||||
|
.name = "sdl_header_translator",
|
||||||
|
.root_source_file = b.path("utils/sdl_translator.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
sdl_translator.linkSystemLibrary("SDL3");
|
||||||
|
return sdl_translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_translate_sdl(
|
||||||
|
b: *Build,
|
||||||
|
target: Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
) struct { *Build.Step, Build.LazyPath } {
|
||||||
|
const sdl_translator = step_build_sdl_translator(b, target, optimize);
|
||||||
|
const translate = b.addRunArtifact(sdl_translator);
|
||||||
|
const sdl_rename = translate.addOutputFileArg("sdl_rename.h");
|
||||||
|
return .{
|
||||||
|
&translate.step,
|
||||||
|
sdl_rename,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_sdl_module(
|
||||||
|
b: *Build,
|
||||||
|
target: Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
) struct { *Build.Module, *Build.Step } {
|
||||||
|
const sdl_module = b.addModule("sdl", .{
|
||||||
|
.root_source_file = b.path("lib/sdl.zig"),
|
||||||
|
.link_libc = true,
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
sdl_module.linkSystemLibrary("SDL3", .{});
|
||||||
|
|
||||||
|
const translate_step, const sdl_rename = step_translate_sdl(b, target, optimize);
|
||||||
|
sdl_module.addIncludePath(sdl_rename.dirname());
|
||||||
|
|
||||||
|
return .{
|
||||||
|
sdl_module,
|
||||||
|
translate_step,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_copy_data(
|
||||||
|
b: *Build,
|
||||||
|
target: Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
) *Build.Step {
|
||||||
|
_ = ⌖
|
||||||
|
_ = &optimize;
|
||||||
|
|
||||||
const copy_data_cmd = b.addInstallDirectory(.{
|
const copy_data_cmd = b.addInstallDirectory(.{
|
||||||
.source_dir = b.path("data"),
|
.source_dir = b.path("data"),
|
||||||
@@ -26,8 +118,21 @@ pub fn build(b: *std.Build) void {
|
|||||||
.install_subdir = "data",
|
.install_subdir = "data",
|
||||||
.exclude_extensions = &.{ "vert", "frag" },
|
.exclude_extensions = &.{ "vert", "frag" },
|
||||||
});
|
});
|
||||||
b.getInstallStep().dependOn(©_data_cmd.step);
|
const build_shaders = step_build_shaders(b, target, optimize);
|
||||||
|
|
||||||
|
copy_data_cmd.step.dependOn(build_shaders);
|
||||||
|
|
||||||
|
return ©_data_cmd.step;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_build_shaders(
|
||||||
|
b: *Build,
|
||||||
|
target: Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
) *Build.Step {
|
||||||
|
_ = ⌖
|
||||||
|
|
||||||
|
const step = b.step("shaders", "Build all shaders with `glslc`");
|
||||||
for (SHADERS) |shader_path| {
|
for (SHADERS) |shader_path| {
|
||||||
const glslc = b.addSystemCommand(&.{"glslc"});
|
const glslc = b.addSystemCommand(&.{"glslc"});
|
||||||
if (optimize != .Debug) {
|
if (optimize != .Debug) {
|
||||||
@@ -45,16 +150,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
glslc.addFileArg(b.path(shader_path));
|
glslc.addFileArg(b.path(shader_path));
|
||||||
glslc.addArg("-o");
|
glslc.addArg("-o");
|
||||||
const shader_artifact = glslc.addOutputFileArg(std.fs.path.basename(shader_path));
|
const shader_artifact = glslc.addOutputFileArg(std.fs.path.basename(shader_path));
|
||||||
b.getInstallStep().dependOn(&b.addInstallFileWithDir(shader_artifact, .bin, shader_path).step);
|
step.dependOn(&b.addInstallFileWithDir(shader_artifact, .bin, shader_path).step);
|
||||||
}
|
}
|
||||||
|
return step;
|
||||||
const run_cmd = b.addRunArtifact(exe);
|
|
||||||
run_cmd.setCwd(b.path(std.fs.path.relative(b.allocator, b.build_root.path.?, b.exe_dir) catch unreachable));
|
|
||||||
run_cmd.step.dependOn(b.getInstallStep());
|
|
||||||
if (b.args) |args| {
|
|
||||||
run_cmd.addArgs(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
const run_step = b.step("run", "Run the app");
|
|
||||||
run_step.dependOn(&run_cmd.step);
|
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,15 @@
|
|||||||
.{
|
.{
|
||||||
.name = "spacefarer",
|
.name = .spacefarer,
|
||||||
.version = "0.0.0",
|
.version = "0.0.0",
|
||||||
|
.fingerprint = 0x946ddccb5911fb15,
|
||||||
|
.minimum_zig_version = "0.14.0",
|
||||||
.dependencies = .{},
|
.dependencies = .{},
|
||||||
.paths = .{
|
.paths = .{
|
||||||
"build.zig",
|
"build.zig",
|
||||||
"build.zig.zon",
|
"build.zig.zon",
|
||||||
"src",
|
"src",
|
||||||
|
"lib",
|
||||||
|
"utils",
|
||||||
"data",
|
"data",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
pub usingnamespace @cImport({
|
pub usingnamespace @cImport({
|
||||||
@cInclude("SDL3/SDL.h");
|
@cInclude("SDL3/SDL.h");
|
||||||
|
@cInclude("sdl_rename.h");
|
||||||
});
|
});
|
20
src/game.zig
20
src/game.zig
@@ -1,5 +1,5 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const sdl = @import("sdl.zig");
|
const sdl = @import("sdl");
|
||||||
const Graphics = @import("graphics.zig");
|
const Graphics = @import("graphics.zig");
|
||||||
|
|
||||||
graphics: Graphics,
|
graphics: Graphics,
|
||||||
@@ -36,10 +36,10 @@ fn draw(self: *Self) GameError!void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn process_events(self: *Self) GameError!void {
|
fn process_events(self: *Self) GameError!void {
|
||||||
sdl.SDL_PumpEvents();
|
sdl.PumpEvents();
|
||||||
while (true) {
|
while (true) {
|
||||||
var buffer: [16]sdl.SDL_Event = undefined;
|
var buffer: [16]sdl.Event = undefined;
|
||||||
const count: usize = @intCast(sdl.SDL_PeepEvents(&buffer, buffer.len, sdl.SDL_GETEVENT, sdl.SDL_EVENT_FIRST, sdl.SDL_EVENT_LAST));
|
const count: usize = @intCast(sdl.PeepEvents(&buffer, buffer.len, sdl.GETEVENT, sdl.EVENT_FIRST, sdl.EVENT_LAST));
|
||||||
if (count == -1) return GameError.SdlError;
|
if (count == -1) return GameError.SdlError;
|
||||||
for (buffer[0..count]) |event| {
|
for (buffer[0..count]) |event| {
|
||||||
self.process_event(event);
|
self.process_event(event);
|
||||||
@@ -48,16 +48,16 @@ fn process_events(self: *Self) GameError!void {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sdl.SDL_FlushEvents(sdl.SDL_EVENT_FIRST, sdl.SDL_EVENT_LAST);
|
sdl.FlushEvents(sdl.EVENT_FIRST, sdl.EVENT_LAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_event(self: *Self, event: sdl.SDL_Event) void {
|
fn process_event(self: *Self, event: sdl.Event) void {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
sdl.SDL_EVENT_QUIT => {
|
sdl.EVENT_QUIT => {
|
||||||
self.running = false;
|
self.running = false;
|
||||||
},
|
},
|
||||||
sdl.SDL_EVENT_WINDOW_RESIZED => {
|
sdl.EVENT_WINDOW_RESIZED => {
|
||||||
if (event.window.windowID != sdl.SDL_GetWindowID(self.graphics.window)) return;
|
if (event.window.windowID != sdl.GetWindowID(self.graphics.window)) return;
|
||||||
self.graphics.resize(@intCast(event.window.data1), @intCast(event.window.data2));
|
self.graphics.resize(@intCast(event.window.data1), @intCast(event.window.data2));
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
@@ -66,7 +66,7 @@ fn process_event(self: *Self, event: sdl.SDL_Event) void {
|
|||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
self.graphics.destroy();
|
self.graphics.destroy();
|
||||||
sdl.SDL_Quit();
|
sdl.Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const GameError = error{
|
pub const GameError = error{
|
||||||
|
194
src/graphics.zig
194
src/graphics.zig
@@ -1,86 +1,86 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const sdl = @import("sdl.zig");
|
const sdl = @import("sdl");
|
||||||
const GameError = @import("game.zig").GameError;
|
const GameError = @import("game.zig").GameError;
|
||||||
|
|
||||||
window: *sdl.SDL_Window,
|
window: *sdl.Window,
|
||||||
renderer: *sdl.SDL_Renderer,
|
renderer: *sdl.Renderer,
|
||||||
device: *sdl.SDL_GPUDevice,
|
device: *sdl.GPUDevice,
|
||||||
/// Only available while drawing
|
/// Only available while drawing
|
||||||
command_buffer: ?*sdl.SDL_GPUCommandBuffer,
|
command_buffer: ?*sdl.GPUCommandBuffer,
|
||||||
|
|
||||||
shader_vert: *sdl.SDL_GPUShader,
|
shader_vert: *sdl.GPUShader,
|
||||||
shader_frag: *sdl.SDL_GPUShader,
|
shader_frag: *sdl.GPUShader,
|
||||||
|
|
||||||
vertex_buffer: *sdl.SDL_GPUBuffer,
|
vertex_buffer: *sdl.GPUBuffer,
|
||||||
depth_texture: *sdl.SDL_GPUTexture,
|
depth_texture: *sdl.GPUTexture,
|
||||||
pipeline: *sdl.SDL_GPUGraphicsPipeline,
|
pipeline: *sdl.GPUGraphicsPipeline,
|
||||||
|
|
||||||
to_resize: ?struct { u32, u32 } = null,
|
to_resize: ?struct { u32, u32 } = null,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub fn create() GameError!Self {
|
pub fn create() GameError!Self {
|
||||||
// Init
|
// Init
|
||||||
if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO | sdl.SDL_INIT_EVENTS)) return GameError.SdlError;
|
if (!sdl.Init(sdl.INIT_VIDEO | sdl.INIT_EVENTS)) return GameError.SdlError;
|
||||||
|
|
||||||
// Window and Renderer
|
// Window and Renderer
|
||||||
var renderer: ?*sdl.SDL_Renderer = null;
|
var renderer: ?*sdl.Renderer = null;
|
||||||
var window: ?*sdl.SDL_Window = null;
|
var window: ?*sdl.Window = null;
|
||||||
|
|
||||||
if (!sdl.SDL_CreateWindowAndRenderer(
|
if (!sdl.CreateWindowAndRenderer(
|
||||||
"Spacefarer",
|
"Spacefarer",
|
||||||
1600,
|
1600,
|
||||||
900,
|
900,
|
||||||
sdl.SDL_WINDOW_VULKAN | sdl.SDL_WINDOW_RESIZABLE,
|
sdl.WINDOW_VULKAN | sdl.WINDOW_RESIZABLE,
|
||||||
&window,
|
&window,
|
||||||
&renderer,
|
&renderer,
|
||||||
)) return GameError.SdlError;
|
)) return GameError.SdlError;
|
||||||
errdefer sdl.SDL_DestroyRenderer(renderer);
|
errdefer sdl.DestroyRenderer(renderer);
|
||||||
errdefer sdl.SDL_DestroyWindow(window);
|
errdefer sdl.DestroyWindow(window);
|
||||||
|
|
||||||
if (!sdl.SDL_SetRenderVSync(renderer, sdl.SDL_RENDERER_VSYNC_ADAPTIVE)) return GameError.SdlError;
|
if (!sdl.SetRenderVSync(renderer, sdl.RENDERER_VSYNC_ADAPTIVE)) return GameError.SdlError;
|
||||||
|
|
||||||
// Device
|
// Device
|
||||||
const device = sdl.SDL_CreateGPUDevice(
|
const device = sdl.CreateGPUDevice(
|
||||||
sdl.SDL_GPU_SHADERFORMAT_SPIRV,
|
sdl.GPU_SHADERFORMAT_SPIRV,
|
||||||
@import("builtin").mode == .Debug,
|
@import("builtin").mode == .Debug,
|
||||||
null,
|
null,
|
||||||
) orelse return GameError.SdlError;
|
) orelse return GameError.SdlError;
|
||||||
errdefer sdl.SDL_DestroyGPUDevice(device);
|
errdefer sdl.DestroyGPUDevice(device);
|
||||||
|
|
||||||
// Claim
|
// Claim
|
||||||
if (!sdl.SDL_ClaimWindowForGPUDevice(device, window)) return GameError.SdlError;
|
if (!sdl.ClaimWindowForGPUDevice(device, window)) return GameError.SdlError;
|
||||||
errdefer sdl.SDL_ReleaseWindowFromGPUDevice(device, window);
|
errdefer sdl.ReleaseWindowFromGPUDevice(device, window);
|
||||||
|
|
||||||
const shader_vert = try load_shader(
|
const shader_vert = try load_shader(
|
||||||
device,
|
device,
|
||||||
"data/shaders/basic.vert",
|
"data/shaders/basic.vert",
|
||||||
sdl.SDL_GPU_SHADERSTAGE_VERTEX,
|
sdl.GPU_SHADERSTAGE_VERTEX,
|
||||||
);
|
);
|
||||||
errdefer sdl.SDL_ReleaseGPUShader(device, shader_vert);
|
errdefer sdl.ReleaseGPUShader(device, shader_vert);
|
||||||
|
|
||||||
const shader_frag = try load_shader(
|
const shader_frag = try load_shader(
|
||||||
device,
|
device,
|
||||||
"data/shaders/basic.frag",
|
"data/shaders/basic.frag",
|
||||||
sdl.SDL_GPU_SHADERSTAGE_FRAGMENT,
|
sdl.GPU_SHADERSTAGE_FRAGMENT,
|
||||||
);
|
);
|
||||||
errdefer sdl.SDL_ReleaseGPUShader(device, shader_frag);
|
errdefer sdl.ReleaseGPUShader(device, shader_frag);
|
||||||
|
|
||||||
const vertex_buffer = sdl.SDL_CreateGPUBuffer(device, &.{
|
const vertex_buffer = sdl.CreateGPUBuffer(device, &.{
|
||||||
.usage = sdl.SDL_GPU_BUFFERUSAGE_VERTEX,
|
.usage = sdl.GPU_BUFFERUSAGE_VERTEX,
|
||||||
// 6 Vertices * 3 Coordinates * 4 Bytes
|
// 6 Vertices * 3 Coordinates * 4 Bytes
|
||||||
.size = 6 * 3 * 4,
|
.size = 6 * 3 * 4,
|
||||||
}) orelse return GameError.SdlError;
|
}) orelse return GameError.SdlError;
|
||||||
errdefer sdl.SDL_ReleaseGPUBuffer(device, vertex_buffer);
|
errdefer sdl.ReleaseGPUBuffer(device, vertex_buffer);
|
||||||
|
|
||||||
const transfer_buffer = sdl.SDL_CreateGPUTransferBuffer(device, &.{
|
const transfer_buffer = sdl.CreateGPUTransferBuffer(device, &.{
|
||||||
.size = 6 * 3 * 4,
|
.size = 6 * 3 * 4,
|
||||||
.usage = sdl.SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
|
.usage = sdl.GPU_TRANSFERBUFFERUSAGE_UPLOAD,
|
||||||
}) orelse return GameError.SdlError;
|
}) orelse return GameError.SdlError;
|
||||||
defer sdl.SDL_ReleaseGPUTransferBuffer(device, transfer_buffer);
|
defer sdl.ReleaseGPUTransferBuffer(device, transfer_buffer);
|
||||||
|
|
||||||
{ // Filling up transfer buffer
|
{ // Filling up transfer buffer
|
||||||
const mapped_buffer: [*c]f32 = @alignCast(@ptrCast(sdl.SDL_MapGPUTransferBuffer(device, transfer_buffer, false) orelse return GameError.SdlError));
|
const mapped_buffer: [*c]f32 = @alignCast(@ptrCast(sdl.MapGPUTransferBuffer(device, transfer_buffer, false) orelse return GameError.SdlError));
|
||||||
defer sdl.SDL_UnmapGPUTransferBuffer(device, transfer_buffer);
|
defer sdl.UnmapGPUTransferBuffer(device, transfer_buffer);
|
||||||
std.mem.copyForwards(f32, mapped_buffer[0 .. 6 * 3], &[6 * 3]f32{
|
std.mem.copyForwards(f32, mapped_buffer[0 .. 6 * 3], &[6 * 3]f32{
|
||||||
// Triangle 1
|
// Triangle 1
|
||||||
-1.0, 0.0, 0.0,
|
-1.0, 0.0, 0.0,
|
||||||
@@ -94,29 +94,29 @@ pub fn create() GameError!Self {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ // Copying data over from transfer buffer to vertex buffer
|
{ // Copying data over from transfer buffer to vertex buffer
|
||||||
const command_buffer = sdl.SDL_AcquireGPUCommandBuffer(device) orelse return GameError.SdlError;
|
const command_buffer = sdl.AcquireGPUCommandBuffer(device) orelse return GameError.SdlError;
|
||||||
const copy_pass = sdl.SDL_BeginGPUCopyPass(command_buffer) orelse return GameError.SdlError;
|
const copy_pass = sdl.BeginGPUCopyPass(command_buffer) orelse return GameError.SdlError;
|
||||||
|
|
||||||
sdl.SDL_UploadToGPUBuffer(copy_pass, &.{ .transfer_buffer = transfer_buffer }, &.{
|
sdl.UploadToGPUBuffer(copy_pass, &.{ .transfer_buffer = transfer_buffer }, &.{
|
||||||
.size = 6 * 3 * 4,
|
.size = 6 * 3 * 4,
|
||||||
.buffer = vertex_buffer,
|
.buffer = vertex_buffer,
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
sdl.SDL_EndGPUCopyPass(copy_pass);
|
sdl.EndGPUCopyPass(copy_pass);
|
||||||
if (!sdl.SDL_SubmitGPUCommandBuffer(command_buffer)) return GameError.SdlError;
|
if (!sdl.SubmitGPUCommandBuffer(command_buffer)) return GameError.SdlError;
|
||||||
}
|
}
|
||||||
|
|
||||||
const target_format = sdl.SDL_GetGPUSwapchainTextureFormat(device, window);
|
const target_format = sdl.GetGPUSwapchainTextureFormat(device, window);
|
||||||
if (target_format == sdl.SDL_GPU_TEXTUREFORMAT_INVALID) return GameError.SdlError;
|
if (target_format == sdl.GPU_TEXTUREFORMAT_INVALID) return GameError.SdlError;
|
||||||
|
|
||||||
// TODO: Clean
|
// TODO: Clean
|
||||||
var window_width: c_int = 1;
|
var window_width: c_int = 1;
|
||||||
var window_height: c_int = 1;
|
var window_height: c_int = 1;
|
||||||
if (!sdl.SDL_GetWindowSizeInPixels(window, &window_width, &window_height)) return GameError.SdlError;
|
if (!sdl.GetWindowSizeInPixels(window, &window_width, &window_height)) return GameError.SdlError;
|
||||||
const depth_texture = try create_depth_texture(device, @intCast(window_width), @intCast(window_height));
|
const depth_texture = try create_depth_texture(device, @intCast(window_width), @intCast(window_height));
|
||||||
errdefer sdl.SDL_ReleaseGPUTexture(device, depth_texture);
|
errdefer sdl.ReleaseGPUTexture(device, depth_texture);
|
||||||
|
|
||||||
const pipeline = sdl.SDL_CreateGPUGraphicsPipeline(device, &.{
|
const pipeline = sdl.CreateGPUGraphicsPipeline(device, &.{
|
||||||
.vertex_shader = shader_vert,
|
.vertex_shader = shader_vert,
|
||||||
.fragment_shader = shader_frag,
|
.fragment_shader = shader_frag,
|
||||||
.vertex_input_state = .{
|
.vertex_input_state = .{
|
||||||
@@ -124,51 +124,51 @@ pub fn create() GameError!Self {
|
|||||||
.slot = 0,
|
.slot = 0,
|
||||||
// 3 Coordinates * 4 Bytes
|
// 3 Coordinates * 4 Bytes
|
||||||
.pitch = 3 * 4,
|
.pitch = 3 * 4,
|
||||||
.input_rate = sdl.SDL_GPU_VERTEXINPUTRATE_VERTEX,
|
.input_rate = sdl.GPU_VERTEXINPUTRATE_VERTEX,
|
||||||
},
|
},
|
||||||
.num_vertex_buffers = 1,
|
.num_vertex_buffers = 1,
|
||||||
.vertex_attributes = &sdl.SDL_GPUVertexAttribute{
|
.vertex_attributes = &sdl.GPUVertexAttribute{
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.location = 0,
|
.location = 0,
|
||||||
.format = sdl.SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3,
|
.format = sdl.GPU_VERTEXELEMENTFORMAT_FLOAT3,
|
||||||
.buffer_slot = 0,
|
.buffer_slot = 0,
|
||||||
},
|
},
|
||||||
.num_vertex_attributes = 1,
|
.num_vertex_attributes = 1,
|
||||||
},
|
},
|
||||||
.primitive_type = sdl.SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
|
.primitive_type = sdl.GPU_PRIMITIVETYPE_TRIANGLELIST,
|
||||||
.rasterizer_state = .{
|
.rasterizer_state = .{
|
||||||
.cull_mode = sdl.SDL_GPU_CULLMODE_BACK,
|
.cull_mode = sdl.GPU_CULLMODE_BACK,
|
||||||
.fill_mode = sdl.SDL_GPU_FILLMODE_FILL,
|
.fill_mode = sdl.GPU_FILLMODE_FILL,
|
||||||
.front_face = sdl.SDL_GPU_FRONTFACE_CLOCKWISE,
|
.front_face = sdl.GPU_FRONTFACE_CLOCKWISE,
|
||||||
},
|
},
|
||||||
.multisample_state = .{
|
.multisample_state = .{
|
||||||
// .sample_count = 1,
|
// .sample_count = 1,
|
||||||
},
|
},
|
||||||
.depth_stencil_state = .{
|
.depth_stencil_state = .{
|
||||||
.compare_op = sdl.SDL_GPU_COMPAREOP_LESS,
|
.compare_op = sdl.GPU_COMPAREOP_LESS,
|
||||||
.enable_depth_test = true,
|
.enable_depth_test = true,
|
||||||
.enable_depth_write = true,
|
.enable_depth_write = true,
|
||||||
},
|
},
|
||||||
.target_info = .{
|
.target_info = .{
|
||||||
.depth_stencil_format = sdl.SDL_GPU_TEXTUREFORMAT_D16_UNORM,
|
.depth_stencil_format = sdl.GPU_TEXTUREFORMAT_D16_UNORM,
|
||||||
.color_target_descriptions = &sdl.SDL_GPUColorTargetDescription{
|
.color_target_descriptions = &sdl.GPUColorTargetDescription{
|
||||||
.format = target_format,
|
.format = target_format,
|
||||||
.blend_state = .{
|
.blend_state = .{
|
||||||
.enable_blend = true,
|
.enable_blend = true,
|
||||||
.alpha_blend_op = sdl.SDL_GPU_BLENDOP_ADD,
|
.alpha_blend_op = sdl.GPU_BLENDOP_ADD,
|
||||||
.color_blend_op = sdl.SDL_GPU_BLENDOP_ADD,
|
.color_blend_op = sdl.GPU_BLENDOP_ADD,
|
||||||
.color_write_mask = sdl.SDL_GPU_COLORCOMPONENT_R | sdl.SDL_GPU_COLORCOMPONENT_G | sdl.SDL_GPU_COLORCOMPONENT_B | sdl.SDL_GPU_COLORCOMPONENT_A,
|
.color_write_mask = sdl.GPU_COLORCOMPONENT_R | sdl.GPU_COLORCOMPONENT_G | sdl.GPU_COLORCOMPONENT_B | sdl.GPU_COLORCOMPONENT_A,
|
||||||
.src_alpha_blendfactor = sdl.SDL_GPU_BLENDFACTOR_ONE,
|
.src_alpha_blendfactor = sdl.GPU_BLENDFACTOR_ONE,
|
||||||
.src_color_blendfactor = sdl.SDL_GPU_BLENDFACTOR_SRC_ALPHA,
|
.src_color_blendfactor = sdl.GPU_BLENDFACTOR_SRC_ALPHA,
|
||||||
.dst_alpha_blendfactor = sdl.SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
.dst_alpha_blendfactor = sdl.GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
||||||
.dst_color_blendfactor = sdl.SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
.dst_color_blendfactor = sdl.GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.num_color_targets = 1,
|
.num_color_targets = 1,
|
||||||
.has_depth_stencil_target = true,
|
.has_depth_stencil_target = true,
|
||||||
},
|
},
|
||||||
}) orelse return GameError.SdlError;
|
}) orelse return GameError.SdlError;
|
||||||
errdefer sdl.SDL_ReleaseGPUGraphicsPipeline(pipeline);
|
errdefer sdl.ReleaseGPUGraphicsPipeline(pipeline);
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.window = window.?,
|
.window = window.?,
|
||||||
@@ -184,26 +184,26 @@ pub fn create() GameError!Self {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(self: *Self) void {
|
pub fn destroy(self: *Self) void {
|
||||||
sdl.SDL_ReleaseWindowFromGPUDevice(self.device, self.window);
|
sdl.ReleaseWindowFromGPUDevice(self.device, self.window);
|
||||||
sdl.SDL_DestroyRenderer(self.renderer);
|
sdl.DestroyRenderer(self.renderer);
|
||||||
sdl.SDL_DestroyWindow(self.window);
|
sdl.DestroyWindow(self.window);
|
||||||
|
|
||||||
sdl.SDL_ReleaseGPUGraphicsPipeline(self.device, self.pipeline);
|
sdl.ReleaseGPUGraphicsPipeline(self.device, self.pipeline);
|
||||||
sdl.SDL_ReleaseGPUTexture(self.device, self.depth_texture);
|
sdl.ReleaseGPUTexture(self.device, self.depth_texture);
|
||||||
sdl.SDL_ReleaseGPUBuffer(self.device, self.vertex_buffer);
|
sdl.ReleaseGPUBuffer(self.device, self.vertex_buffer);
|
||||||
|
|
||||||
sdl.SDL_ReleaseGPUShader(self.device, self.shader_vert);
|
sdl.ReleaseGPUShader(self.device, self.shader_vert);
|
||||||
sdl.SDL_ReleaseGPUShader(self.device, self.shader_frag);
|
sdl.ReleaseGPUShader(self.device, self.shader_frag);
|
||||||
|
|
||||||
if (self.command_buffer != null) {
|
if (self.command_buffer != null) {
|
||||||
_ = sdl.SDL_CancelGPUCommandBuffer(self.command_buffer);
|
_ = sdl.CancelGPUCommandBuffer(self.command_buffer);
|
||||||
self.command_buffer = null;
|
self.command_buffer = null;
|
||||||
}
|
}
|
||||||
sdl.SDL_DestroyGPUDevice(self.device);
|
sdl.DestroyGPUDevice(self.device);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn begin_draw(self: *Self) GameError!void {
|
pub fn begin_draw(self: *Self) GameError!void {
|
||||||
self.command_buffer = sdl.SDL_AcquireGPUCommandBuffer(self.device) orelse return GameError.SdlError;
|
self.command_buffer = sdl.AcquireGPUCommandBuffer(self.device) orelse return GameError.SdlError;
|
||||||
if (self.to_resize) |new_size| {
|
if (self.to_resize) |new_size| {
|
||||||
try self.reset_depth_texture(new_size[0], new_size[1]);
|
try self.reset_depth_texture(new_size[0], new_size[1]);
|
||||||
self.to_resize = null;
|
self.to_resize = null;
|
||||||
@@ -211,72 +211,72 @@ pub fn begin_draw(self: *Self) GameError!void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_debug(self: *Self) GameError!void {
|
pub fn draw_debug(self: *Self) GameError!void {
|
||||||
var render_target: ?*sdl.SDL_GPUTexture = null;
|
var render_target: ?*sdl.GPUTexture = null;
|
||||||
var width: u32 = 0;
|
var width: u32 = 0;
|
||||||
var height: u32 = 0;
|
var height: u32 = 0;
|
||||||
if (!sdl.SDL_WaitAndAcquireGPUSwapchainTexture(self.command_buffer, self.window, &render_target, &width, &height)) return GameError.SdlError;
|
if (!sdl.WaitAndAcquireGPUSwapchainTexture(self.command_buffer, self.window, &render_target, &width, &height)) return GameError.SdlError;
|
||||||
// Hidden
|
// Hidden
|
||||||
if (render_target == null) return;
|
if (render_target == null) return;
|
||||||
|
|
||||||
const render_pass = sdl.SDL_BeginGPURenderPass(self.command_buffer, &.{
|
const render_pass = sdl.BeginGPURenderPass(self.command_buffer, &.{
|
||||||
.clear_color = .{ .r = 0.0, .g = 0.0, .b = 1.0, .a = 1.0 },
|
.clear_color = .{ .r = 0.0, .g = 0.0, .b = 1.0, .a = 1.0 },
|
||||||
.cycle = false,
|
.cycle = false,
|
||||||
.load_op = sdl.SDL_GPU_LOADOP_CLEAR,
|
.load_op = sdl.GPU_LOADOP_CLEAR,
|
||||||
// .store_op = sdl.SDL_GPU_STOREOP_RESOLVE,
|
// .store_op = sdl.GPU_STOREOP_RESOLVE,
|
||||||
.store_op = sdl.SDL_GPU_STOREOP_STORE,
|
.store_op = sdl.GPU_STOREOP_STORE,
|
||||||
// .resolve_texture = render_target,
|
// .resolve_texture = render_target,
|
||||||
.mip_level = 0,
|
.mip_level = 0,
|
||||||
.texture = render_target,
|
.texture = render_target,
|
||||||
}, 1, &.{
|
}, 1, &.{
|
||||||
.clear_depth = 1.0,
|
.clear_depth = 1.0,
|
||||||
.load_op = sdl.SDL_GPU_LOADOP_CLEAR,
|
.load_op = sdl.GPU_LOADOP_CLEAR,
|
||||||
.store_op = sdl.SDL_GPU_STOREOP_DONT_CARE,
|
.store_op = sdl.GPU_STOREOP_DONT_CARE,
|
||||||
.stencil_load_op = sdl.SDL_GPU_STOREOP_DONT_CARE,
|
.stencil_load_op = sdl.GPU_STOREOP_DONT_CARE,
|
||||||
.stencil_store_op = sdl.SDL_GPU_STOREOP_DONT_CARE,
|
.stencil_store_op = sdl.GPU_STOREOP_DONT_CARE,
|
||||||
.texture = self.depth_texture,
|
.texture = self.depth_texture,
|
||||||
}) orelse return GameError.SdlError;
|
}) orelse return GameError.SdlError;
|
||||||
|
|
||||||
sdl.SDL_BindGPUGraphicsPipeline(render_pass, self.pipeline);
|
sdl.BindGPUGraphicsPipeline(render_pass, self.pipeline);
|
||||||
sdl.SDL_BindGPUVertexBuffers(render_pass, 0, &.{ .offset = 0, .buffer = self.vertex_buffer }, 1);
|
sdl.BindGPUVertexBuffers(render_pass, 0, &.{ .offset = 0, .buffer = self.vertex_buffer }, 1);
|
||||||
sdl.SDL_DrawGPUPrimitives(render_pass, 6, 1, 0, 0);
|
sdl.DrawGPUPrimitives(render_pass, 6, 1, 0, 0);
|
||||||
|
|
||||||
sdl.SDL_EndGPURenderPass(render_pass);
|
sdl.EndGPURenderPass(render_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn end_draw(self: *Self) GameError!void {
|
pub fn end_draw(self: *Self) GameError!void {
|
||||||
defer self.command_buffer = null;
|
defer self.command_buffer = null;
|
||||||
if (!sdl.SDL_SubmitGPUCommandBuffer(self.command_buffer)) return GameError.SdlError;
|
if (!sdl.SubmitGPUCommandBuffer(self.command_buffer)) return GameError.SdlError;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_shader(device: *sdl.SDL_GPUDevice, path: []const u8, stage: c_uint) GameError!*sdl.SDL_GPUShader {
|
fn load_shader(device: *sdl.GPUDevice, path: []const u8, stage: c_uint) GameError!*sdl.GPUShader {
|
||||||
const file = std.fs.cwd().openFile(path, .{}) catch return GameError.OSError;
|
const file = std.fs.cwd().openFile(path, .{}) catch return GameError.OSError;
|
||||||
defer file.close();
|
defer file.close();
|
||||||
|
|
||||||
const code = file.readToEndAllocOptions(std.heap.c_allocator, 1024 * 1024 * 1024, null, @alignOf(u8), 0) catch return GameError.OSError;
|
const code = file.readToEndAllocOptions(std.heap.c_allocator, 1024 * 1024 * 1024, null, @alignOf(u8), 0) catch return GameError.OSError;
|
||||||
defer std.heap.c_allocator.free(code);
|
defer std.heap.c_allocator.free(code);
|
||||||
|
|
||||||
return sdl.SDL_CreateGPUShader(device, &.{
|
return sdl.CreateGPUShader(device, &.{
|
||||||
.code = code,
|
.code = code,
|
||||||
.code_size = code.len,
|
.code_size = code.len,
|
||||||
.entrypoint = "main",
|
.entrypoint = "main",
|
||||||
.format = sdl.SDL_GPU_SHADERFORMAT_SPIRV,
|
.format = sdl.GPU_SHADERFORMAT_SPIRV,
|
||||||
.stage = stage,
|
.stage = stage,
|
||||||
}) orelse return GameError.SdlError;
|
}) orelse return GameError.SdlError;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_depth_texture(device: *sdl.SDL_GPUDevice, width: u32, height: u32) GameError!*sdl.SDL_GPUTexture {
|
fn create_depth_texture(device: *sdl.GPUDevice, width: u32, height: u32) GameError!*sdl.GPUTexture {
|
||||||
return sdl.SDL_CreateGPUTexture(device, &.{
|
return sdl.CreateGPUTexture(device, &.{
|
||||||
.format = sdl.SDL_GPU_TEXTUREFORMAT_D16_UNORM,
|
.format = sdl.GPU_TEXTUREFORMAT_D16_UNORM,
|
||||||
.layer_count_or_depth = 1,
|
.layer_count_or_depth = 1,
|
||||||
.width = width,
|
.width = width,
|
||||||
.height = height,
|
.height = height,
|
||||||
.num_levels = 1,
|
.num_levels = 1,
|
||||||
.usage = sdl.SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET,
|
.usage = sdl.GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET,
|
||||||
}) orelse return GameError.SdlError;
|
}) orelse return GameError.SdlError;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_depth_texture(self: *Self, width: u32, height: u32) GameError!void {
|
fn reset_depth_texture(self: *Self, width: u32, height: u32) GameError!void {
|
||||||
sdl.SDL_ReleaseGPUTexture(self.device, self.depth_texture);
|
sdl.ReleaseGPUTexture(self.device, self.depth_texture);
|
||||||
self.depth_texture = try create_depth_texture(self.device, width, height);
|
self.depth_texture = try create_depth_texture(self.device, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const sdl = @import("sdl.zig");
|
const sdl = @import("sdl");
|
||||||
const Game = @import("game.zig");
|
const Game = @import("game.zig");
|
||||||
|
|
||||||
pub fn run_game() !void {
|
pub fn run_game() !void {
|
||||||
|
45
utils/sdl_translator.zig
Normal file
45
utils/sdl_translator.zig
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const sdl = @cImport({
|
||||||
|
@cInclude("SDL3/SDL.h");
|
||||||
|
});
|
||||||
|
|
||||||
|
const PREFIX = "SDL_";
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
const alloc = gpa.allocator();
|
||||||
|
|
||||||
|
var arg_iter = try std.process.argsWithAllocator(alloc);
|
||||||
|
defer arg_iter.deinit();
|
||||||
|
|
||||||
|
_ = arg_iter.next();
|
||||||
|
const output = arg_iter.next().?;
|
||||||
|
|
||||||
|
const file = try std.fs.createFileAbsolute(output, .{});
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
|
const writer = file.writer();
|
||||||
|
|
||||||
|
const stdout = std.io.getStdOut();
|
||||||
|
defer stdout.close();
|
||||||
|
|
||||||
|
const out = stdout.writer();
|
||||||
|
|
||||||
|
var renamed_count: usize = 0;
|
||||||
|
for (@typeInfo(sdl).@"struct".decls) |decl| {
|
||||||
|
if (!std.mem.startsWith(u8, decl.name, PREFIX)) continue;
|
||||||
|
|
||||||
|
const new_name: []const u8 = decl.name[PREFIX.len..];
|
||||||
|
|
||||||
|
try writer.print(
|
||||||
|
\\#define {1s} {0s}
|
||||||
|
\\
|
||||||
|
, .{ decl.name, new_name });
|
||||||
|
renamed_count += 1;
|
||||||
|
}
|
||||||
|
if (renamed_count == 0) {
|
||||||
|
@panic("No SDL definitions renamed");
|
||||||
|
}
|
||||||
|
try out.print("[SDL Translator] {} SDL definitions renamed\n", .{renamed_count});
|
||||||
|
}
|
Reference in New Issue
Block a user