From e17d2b74ca4640183ceca5ba9cc741d3ff3c8f36 Mon Sep 17 00:00:00 2001 From: kayomn Date: Sat, 6 Jul 2024 16:00:40 +0100 Subject: [PATCH] Fix coordinate systems to be consistent between backends --- src/ona/gfx.zig | 15 +++- src/ona/gfx/device.zig | 140 ++++++----------------------- src/ona/gfx/shaders/render_2d.frag | 5 +- src/ona/gfx/shaders/render_2d.vert | 18 ++-- src/ona/gfx/spirv.zig | 12 +++ 5 files changed, 55 insertions(+), 135 deletions(-) diff --git a/src/ona/gfx.zig b/src/ona/gfx.zig index 8c314ee..912b24d 100644 --- a/src/ona/gfx.zig +++ b/src/ona/gfx.zig @@ -62,10 +62,10 @@ pub const Assets = struct { .indices = &.{0, 1, 2, 0, 2, 3}, .vertices = &.{ - .{.xy = .{-width, height}, .uv = .{0, 1}}, - .{.xy = .{width, height}, .uv = .{1, 1}}, - .{.xy = .{width, -height}, .uv = .{1, 0}}, - .{.xy = .{-width, -height}, .uv = .{0, 0}}, + .{.xy = .{-width, -height}, .uv = .{0, 1}}, + .{.xy = .{width, -height}, .uv = .{1, 1}}, + .{.xy = .{width, height}, .uv = .{1, 0}}, + .{.xy = .{-width, height}, .uv = .{0, 0}}, }, }, }); @@ -211,6 +211,13 @@ pub const Queue = struct { var renders = coral.stack.Sequential(device.RenderChain){.allocator = coral.heap.allocator}; }; +pub const Rect = struct { + left: f32, + top: f32, + right: f32, + bottom: f32, +}; + pub const Transform2D = extern struct { xbasis: Point2D = .{1, 0}, ybasis: Point2D = .{0, 1}, diff --git a/src/ona/gfx/device.zig b/src/ona/gfx/device.zig index 60a2f73..b5b9eca 100644 --- a/src/ona/gfx/device.zig +++ b/src/ona/gfx/device.zig @@ -623,11 +623,15 @@ const Rendering2D = struct { defer spirv_unit.deinit(); - try spirv_unit.compile(shader_spirv[0 ..], .vertex); - try spirv_unit.compile(shader_spirv[0 ..], .fragment); + const shader_spirv = spirv.embed_shader("./shaders/render_2d.spv"); + + try spirv_unit.compile(shader_spirv, .vertex); + + std.log.info("{s}\n", .{spirv_unit.shader_desc.vs.source}); + + try spirv_unit.compile(shader_spirv, .fragment); std.log.info("{s}\n", .{spirv_unit.shader_desc.fs.source}); - std.log.info("{s}", .{spirv_unit.shader_desc.vs.source}); return .{ .batching_pipeline = sokol.gfx.makePipeline(.{ @@ -735,7 +739,13 @@ const Rendering2D = struct { const render_target = resource_cast(render_texture).payload.render_target; pass.attachments = render_target.attachments; - frame.projection = orthographic_projection(0.0, @floatFromInt(render_target.width), 0.0, @floatFromInt(render_target.height), -1.0, 1.0); + + frame.projection = orthographic_projection(-1.0, 1.0, .{ + .left = 0, + .top = 0, + .right = @floatFromInt(render_target.width), + .bottom = @floatFromInt(render_target.height), + }); } else { var target_width, var target_height = [_]c_int{0, 0}; @@ -751,115 +761,16 @@ const Rendering2D = struct { .gl = .{.framebuffer = 0}, }; - frame.projection = orthographic_projection(0.0, @floatFromInt(target_width), @floatFromInt(target_height), 0.0, -1.0, 1.0); + frame.projection = orthographic_projection(-1.0, 1.0, .{ + .left = 0, + .top = 0, + .right = @floatFromInt(target_width), + .bottom = @floatFromInt(target_height), + }); } sokol.gfx.beginPass(pass); } - - const shader_spirv = &[_]u32{ - 0x07230203, 0x00010000, 0x00110000, 0x0000006f, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, - 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, - 0x0008000f, 0x00000004, 0x00000002, 0x6e69616d, 0x00000000, 0x00000003, 0x00000004, 0x00000005, - 0x0010000f, 0x00000000, 0x00000006, 0x6e69616d, 0x00000000, 0x00000007, 0x00000008, 0x00000009, - 0x0000000a, 0x0000000b, 0x0000000c, 0x0000000d, 0x0000000e, 0x0000000f, 0x00000010, 0x00000011, - 0x00030010, 0x00000002, 0x00000007, 0x00030003, 0x00000002, 0x000001ae, 0x00030003, 0x00000002, - 0x000001ae, 0x00040005, 0x00000002, 0x6e69616d, 0x00000000, 0x00040005, 0x00000003, 0x65786574, - 0x0000006c, 0x00030005, 0x00000012, 0x00786574, 0x00030005, 0x00000013, 0x00706d73, 0x00030005, - 0x00000004, 0x00007675, 0x00040005, 0x00000005, 0x6f6c6f63, 0x00000072, 0x00040005, 0x00000006, - 0x6e69616d, 0x00000000, 0x00060005, 0x00000014, 0x6c726f77, 0x6f705f64, 0x69746973, 0x00006e6f, - 0x00060005, 0x00000007, 0x74736e69, 0x65636e61, 0x69726f5f, 0x006e6967, 0x00040005, 0x00000008, - 0x6873656d, 0x0079785f, 0x00060005, 0x00000009, 0x74736e69, 0x65636e61, 0x6162785f, 0x00736973, - 0x00060005, 0x0000000a, 0x74736e69, 0x65636e61, 0x6162795f, 0x00736973, 0x00070005, 0x00000015, - 0x6a6f7270, 0x65746365, 0x6f705f64, 0x69746973, 0x00006e6f, 0x00050005, 0x00000016, 0x6a6f7250, - 0x69746365, 0x00006e6f, 0x00080006, 0x00000016, 0x00000000, 0x6a6f7270, 0x69746365, 0x6d5f6e6f, - 0x69727461, 0x00000078, 0x00030005, 0x00000017, 0x00000000, 0x00060005, 0x00000018, 0x505f6c67, - 0x65567265, 0x78657472, 0x00000000, 0x00060006, 0x00000018, 0x00000000, 0x505f6c67, 0x7469736f, - 0x006e6f69, 0x00070006, 0x00000018, 0x00000001, 0x505f6c67, 0x746e696f, 0x657a6953, 0x00000000, - 0x00070006, 0x00000018, 0x00000002, 0x435f6c67, 0x4470696c, 0x61747369, 0x0065636e, 0x00030005, - 0x0000000b, 0x00000000, 0x00060005, 0x0000000c, 0x74736e69, 0x65636e61, 0x7065645f, 0x00006874, - 0x00040005, 0x0000000d, 0x6f6c6f63, 0x00000072, 0x00060005, 0x0000000e, 0x74736e69, 0x65636e61, - 0x6e69745f, 0x00000074, 0x00050005, 0x00000019, 0x74636572, 0x736f705f, 0x00000000, 0x00060005, - 0x0000000f, 0x74736e69, 0x65636e61, 0x6365725f, 0x00000074, 0x00050005, 0x0000001a, 0x74636572, - 0x7a69735f, 0x00000065, 0x00030005, 0x00000010, 0x00007675, 0x00040005, 0x00000011, 0x6873656d, - 0x0076755f, 0x00040047, 0x00000003, 0x0000001e, 0x00000000, 0x00040047, 0x00000012, 0x00000022, - 0x00000000, 0x00040047, 0x00000012, 0x00000021, 0x00000000, 0x00040047, 0x00000013, 0x00000022, - 0x00000000, 0x00040047, 0x00000013, 0x00000021, 0x00000000, 0x00040047, 0x00000004, 0x0000001e, - 0x00000001, 0x00040047, 0x00000005, 0x0000001e, 0x00000000, 0x00040047, 0x00000007, 0x0000001e, - 0x00000004, 0x00040047, 0x00000008, 0x0000001e, 0x00000000, 0x00040047, 0x00000009, 0x0000001e, - 0x00000002, 0x00040047, 0x0000000a, 0x0000001e, 0x00000003, 0x00040048, 0x00000016, 0x00000000, - 0x00000005, 0x00050048, 0x00000016, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000016, - 0x00000000, 0x00000007, 0x00000010, 0x00030047, 0x00000016, 0x00000002, 0x00040047, 0x00000017, - 0x00000022, 0x00000000, 0x00040047, 0x00000017, 0x00000021, 0x00000000, 0x00050048, 0x00000018, - 0x00000000, 0x0000000b, 0x00000000, 0x00050048, 0x00000018, 0x00000001, 0x0000000b, 0x00000001, - 0x00050048, 0x00000018, 0x00000002, 0x0000000b, 0x00000003, 0x00030047, 0x00000018, 0x00000002, - 0x00040047, 0x0000000c, 0x0000001e, 0x00000006, 0x00040047, 0x0000000d, 0x0000001e, 0x00000000, - 0x00040047, 0x0000000e, 0x0000001e, 0x00000005, 0x00040047, 0x0000000f, 0x0000001e, 0x00000007, - 0x00040047, 0x00000010, 0x0000001e, 0x00000001, 0x00040047, 0x00000011, 0x0000001e, 0x00000001, - 0x00020013, 0x0000001b, 0x00030021, 0x0000001c, 0x0000001b, 0x00030016, 0x0000001d, 0x00000020, - 0x00040017, 0x0000001e, 0x0000001d, 0x00000004, 0x00040020, 0x0000001f, 0x00000003, 0x0000001e, - 0x0004003b, 0x0000001f, 0x00000003, 0x00000003, 0x00090019, 0x00000020, 0x0000001d, 0x00000001, - 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000021, 0x00000000, - 0x00000020, 0x0004003b, 0x00000021, 0x00000012, 0x00000000, 0x0002001a, 0x00000022, 0x00040020, - 0x00000023, 0x00000000, 0x00000022, 0x0004003b, 0x00000023, 0x00000013, 0x00000000, 0x0003001b, - 0x00000024, 0x00000020, 0x00040017, 0x00000025, 0x0000001d, 0x00000002, 0x00040020, 0x00000026, - 0x00000001, 0x00000025, 0x0004003b, 0x00000026, 0x00000004, 0x00000001, 0x00040020, 0x00000027, - 0x00000001, 0x0000001e, 0x0004003b, 0x00000027, 0x00000005, 0x00000001, 0x00040015, 0x00000028, - 0x00000020, 0x00000000, 0x0004002b, 0x00000028, 0x00000029, 0x00000003, 0x00040020, 0x0000002a, - 0x00000003, 0x0000001d, 0x0004002b, 0x0000001d, 0x0000002b, 0x00000000, 0x00020014, 0x0000002c, - 0x00040020, 0x0000002d, 0x00000007, 0x00000025, 0x0004003b, 0x00000026, 0x00000007, 0x00000001, - 0x0004003b, 0x00000026, 0x00000008, 0x00000001, 0x0004002b, 0x00000028, 0x0000002e, 0x00000000, - 0x00040020, 0x0000002f, 0x00000001, 0x0000001d, 0x0004003b, 0x00000026, 0x00000009, 0x00000001, - 0x0004002b, 0x00000028, 0x00000030, 0x00000001, 0x0004003b, 0x00000026, 0x0000000a, 0x00000001, - 0x00040018, 0x00000031, 0x0000001e, 0x00000004, 0x0003001e, 0x00000016, 0x00000031, 0x00040020, - 0x00000032, 0x00000002, 0x00000016, 0x0004003b, 0x00000032, 0x00000017, 0x00000002, 0x00040015, - 0x00000033, 0x00000020, 0x00000001, 0x0004002b, 0x00000033, 0x00000034, 0x00000000, 0x00040020, - 0x00000035, 0x00000002, 0x00000031, 0x0004002b, 0x0000001d, 0x00000036, 0x00000000, 0x0004002b, - 0x0000001d, 0x00000037, 0x3f800000, 0x0004001c, 0x00000038, 0x0000001d, 0x00000030, 0x0005001e, - 0x00000018, 0x0000001e, 0x0000001d, 0x00000038, 0x00040020, 0x00000039, 0x00000003, 0x00000018, - 0x0004003b, 0x00000039, 0x0000000b, 0x00000003, 0x0004003b, 0x0000002f, 0x0000000c, 0x00000001, - 0x0004003b, 0x0000001f, 0x0000000d, 0x00000003, 0x0004003b, 0x00000027, 0x0000000e, 0x00000001, - 0x0004003b, 0x00000027, 0x0000000f, 0x00000001, 0x00040020, 0x0000003a, 0x00000003, 0x00000025, - 0x0004003b, 0x0000003a, 0x00000010, 0x00000003, 0x0004003b, 0x00000026, 0x00000011, 0x00000001, - 0x00050036, 0x0000001b, 0x00000002, 0x00000000, 0x0000001c, 0x000200f8, 0x0000003b, 0x0004003d, - 0x00000020, 0x0000003c, 0x00000012, 0x0004003d, 0x00000022, 0x0000003d, 0x00000013, 0x00050056, - 0x00000024, 0x0000003e, 0x0000003c, 0x0000003d, 0x0004003d, 0x00000025, 0x0000003f, 0x00000004, - 0x00050057, 0x0000001e, 0x00000040, 0x0000003e, 0x0000003f, 0x0004003d, 0x0000001e, 0x00000041, - 0x00000005, 0x00050085, 0x0000001e, 0x00000042, 0x00000040, 0x00000041, 0x0003003e, 0x00000003, - 0x00000042, 0x00050041, 0x0000002a, 0x00000043, 0x00000003, 0x00000029, 0x0004003d, 0x0000001d, - 0x00000044, 0x00000043, 0x000500b4, 0x0000002c, 0x00000045, 0x00000044, 0x0000002b, 0x000300f7, - 0x00000046, 0x00000000, 0x000400fa, 0x00000045, 0x00000047, 0x00000046, 0x000200f8, 0x00000047, - 0x000100fc, 0x000200f8, 0x00000046, 0x000100fd, 0x00010038, 0x00050036, 0x0000001b, 0x00000006, - 0x00000000, 0x0000001c, 0x000200f8, 0x00000048, 0x0004003b, 0x0000002d, 0x00000014, 0x00000007, - 0x0004003b, 0x0000002d, 0x00000015, 0x00000007, 0x0004003b, 0x0000002d, 0x00000019, 0x00000007, - 0x0004003b, 0x0000002d, 0x0000001a, 0x00000007, 0x0004003d, 0x00000025, 0x00000049, 0x00000007, - 0x00050041, 0x0000002f, 0x0000004a, 0x00000008, 0x0000002e, 0x0004003d, 0x0000001d, 0x0000004b, - 0x0000004a, 0x0004003d, 0x00000025, 0x0000004c, 0x00000009, 0x0005008e, 0x00000025, 0x0000004d, - 0x0000004c, 0x0000004b, 0x00050081, 0x00000025, 0x0000004e, 0x00000049, 0x0000004d, 0x00050041, - 0x0000002f, 0x0000004f, 0x00000008, 0x00000030, 0x0004003d, 0x0000001d, 0x00000050, 0x0000004f, - 0x0004003d, 0x00000025, 0x00000051, 0x0000000a, 0x0005008e, 0x00000025, 0x00000052, 0x00000051, - 0x00000050, 0x00050081, 0x00000025, 0x00000053, 0x0000004e, 0x00000052, 0x0003003e, 0x00000014, - 0x00000053, 0x00050041, 0x00000035, 0x00000054, 0x00000017, 0x00000034, 0x0004003d, 0x00000031, - 0x00000055, 0x00000054, 0x0004003d, 0x00000025, 0x00000056, 0x00000014, 0x00050051, 0x0000001d, - 0x00000057, 0x00000056, 0x00000000, 0x00050051, 0x0000001d, 0x00000058, 0x00000056, 0x00000001, - 0x00070050, 0x0000001e, 0x00000059, 0x00000057, 0x00000058, 0x00000036, 0x00000037, 0x00050091, - 0x0000001e, 0x0000005a, 0x00000055, 0x00000059, 0x0007004f, 0x00000025, 0x0000005b, 0x0000005a, - 0x0000005a, 0x00000000, 0x00000001, 0x0003003e, 0x00000015, 0x0000005b, 0x0004003d, 0x00000025, - 0x0000005c, 0x00000015, 0x0004003d, 0x0000001d, 0x0000005d, 0x0000000c, 0x00050051, 0x0000001d, - 0x0000005e, 0x0000005c, 0x00000000, 0x00050051, 0x0000001d, 0x0000005f, 0x0000005c, 0x00000001, - 0x00070050, 0x0000001e, 0x00000060, 0x0000005e, 0x0000005f, 0x0000005d, 0x00000037, 0x00050041, - 0x0000001f, 0x00000061, 0x0000000b, 0x00000034, 0x0003003e, 0x00000061, 0x00000060, 0x0004003d, - 0x0000001e, 0x00000062, 0x0000000e, 0x0003003e, 0x0000000d, 0x00000062, 0x0004003d, 0x0000001e, - 0x00000063, 0x0000000f, 0x0007004f, 0x00000025, 0x00000064, 0x00000063, 0x00000063, 0x00000000, - 0x00000001, 0x0003003e, 0x00000019, 0x00000064, 0x0004003d, 0x0000001e, 0x00000065, 0x0000000f, - 0x0007004f, 0x00000025, 0x00000066, 0x00000065, 0x00000065, 0x00000002, 0x00000003, 0x0004003d, - 0x0000001e, 0x00000067, 0x0000000f, 0x0007004f, 0x00000025, 0x00000068, 0x00000067, 0x00000067, - 0x00000000, 0x00000001, 0x00050083, 0x00000025, 0x00000069, 0x00000066, 0x00000068, 0x0003003e, - 0x0000001a, 0x00000069, 0x0004003d, 0x00000025, 0x0000006a, 0x00000019, 0x0004003d, 0x00000025, - 0x0000006b, 0x00000011, 0x0004003d, 0x00000025, 0x0000006c, 0x0000001a, 0x00050085, 0x00000025, - 0x0000006d, 0x0000006b, 0x0000006c, 0x00050081, 0x00000025, 0x0000006e, 0x0000006a, 0x0000006d, - 0x0003003e, 0x00000010, 0x0000006e, 0x000100fd, 0x00010038, - }; }; const Resource = struct { @@ -919,16 +830,15 @@ fn clone_command(self: gfx.Command, arena: *std.heap.ArenaAllocator) std.mem.All }; } -fn orthographic_projection(left: f32, right: f32, bottom: f32, top: f32, zNear: f32, zFar: f32) Projection { - const width = right - left; - const height = top - bottom; - const depth = zFar - zNear; +fn orthographic_projection(near: f32, far: f32, viewport: gfx.Rect) Projection { + const width = viewport.right - viewport.left; + const height = viewport.bottom - viewport.top; return .{ .{2 / width, 0, 0, 0}, .{0, 2 / height, 0, 0}, - .{0, 0, -(2 / depth), 0}, - .{-((right + left) / width), -((top + bottom) / height), -((zFar + zNear) / depth), 1}, + .{0, 0, 1 / (far - near), 0}, + .{-((viewport.left + viewport.right) / width), -((viewport.top + viewport.bottom) / height), near / (near - far), 1}, }; } diff --git a/src/ona/gfx/shaders/render_2d.frag b/src/ona/gfx/shaders/render_2d.frag index a059a43..40e5c20 100644 --- a/src/ona/gfx/shaders/render_2d.frag +++ b/src/ona/gfx/shaders/render_2d.frag @@ -1,7 +1,6 @@ #version 430 -layout (binding = 0) uniform texture2D tex; -layout (binding = 0) uniform sampler smp; +layout (binding = 0) uniform sampler2D sprite; layout (location = 0) in vec4 color; layout (location = 1) in vec2 uv; @@ -9,7 +8,7 @@ layout (location = 1) in vec2 uv; layout (location = 0) out vec4 texel; void main() { - texel = texture(sampler2D(tex, smp), uv) * color; + texel = texture(sprite, uv) * color; if (texel.a == 0) { discard; diff --git a/src/ona/gfx/shaders/render_2d.vert b/src/ona/gfx/shaders/render_2d.vert index cea5831..f7d730e 100644 --- a/src/ona/gfx/shaders/render_2d.vert +++ b/src/ona/gfx/shaders/render_2d.vert @@ -10,27 +10,19 @@ layout (location = 5) in vec4 instance_tint; layout (location = 6) in float instance_depth; layout (location = 7) in vec4 instance_rect; +layout (location = 0) out vec4 color; +layout (location = 1) out vec2 uv; + layout (binding = 0) uniform Projection { mat4 projection_matrix; }; -layout (location = 0) out vec4 color; -layout (location = 1) out vec2 uv; - void main() { - // Calculate the world position of the vertex const vec2 world_position = instance_origin + mesh_xy.x * instance_xbasis + mesh_xy.y * instance_ybasis; const vec2 projected_position = (projection_matrix * vec4(world_position, 0, 1)).xy; + const vec2 rect_size = instance_rect.zw - instance_rect.xy; - // Set the position of the vertex in clip space gl_Position = vec4(projected_position, instance_depth, 1.0); color = instance_tint; - - // Calculate the width and height from left, top, right, bottom configuration - const vec2 rect_pos = instance_rect.xy; // left, top - const vec2 rect_size = instance_rect.zw - instance_rect.xy; // right - left, bottom - top - - // Calculate the adjusted UV coordinates using the instance_rect - uv = rect_pos + (mesh_uv * rect_size); + uv = instance_rect.xy + (mesh_uv * rect_size); } - diff --git a/src/ona/gfx/spirv.zig b/src/ona/gfx/spirv.zig index 9794360..e47f631 100644 --- a/src/ona/gfx/spirv.zig +++ b/src/ona/gfx/spirv.zig @@ -39,6 +39,7 @@ pub const Unit = struct { .{ext.SPVC_COMPILER_OPTION_GLSL_ES, @intFromBool(false)}, .{ext.SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS, @intFromBool(false)}, .{ext.SPVC_COMPILER_OPTION_GLSL_EMIT_UNIFORM_BUFFER_AS_PLAIN_UNIFORMS, @intFromBool(true)}, + .{ext.SPVC_COMPILER_OPTION_FLIP_VERTEX_Y, @intFromBool(true)}, }, }, @@ -143,6 +144,17 @@ pub const Stage = enum { vertex, }; +pub fn embed_shader(comptime path: []const u8) []const u32 { + const shader = @embedFile(path); + const alignment = @alignOf(u32); + + if ((shader.len % alignment) != 0) { + @compileError("size of file contents at " ++ path ++ " must be aligned to a multiple of 4"); + } + + return @as(*const [shader.len / alignment]u32, @ptrCast(@alignCast(shader))); +} + fn log_context_errors(userdata: ?*anyopaque, error_message: [*c]const u8) callconv(.C) void { std.debug.assert(userdata == null); std.log.err("{s}", .{error_message});