Add render textures
continuous-integration/drone/push Build is passing Details

This commit is contained in:
kayomn 2024-06-27 20:01:06 +01:00
parent a4280c8fe8
commit f100aa0d46
5 changed files with 605 additions and 423 deletions

View File

@ -6,8 +6,9 @@ const ona = @import("ona");
const Actors = struct { const Actors = struct {
instances: coral.stack.Sequential(ona.gfx.Point2D) = .{.allocator = coral.heap.allocator}, instances: coral.stack.Sequential(ona.gfx.Point2D) = .{.allocator = coral.heap.allocator},
quad_mesh_2d: ona.gfx.Handle = .none, quad_mesh_2d: ?*ona.gfx.Handle = null,
body_texture: ona.gfx.Handle = .none, body_texture: ?*ona.gfx.Handle = null,
render_texture: ?*ona.gfx.Handle = null,
}; };
const Player = struct { const Player = struct {
@ -24,8 +25,21 @@ pub fn main() !void {
fn load(display: coral.Write(ona.gfx.Display), actors: coral.Write(Actors), assets: coral.Write(ona.gfx.Assets)) !void { fn load(display: coral.Write(ona.gfx.Display), actors: coral.Write(Actors), assets: coral.Write(ona.gfx.Assets)) !void {
display.res.width, display.res.height = .{1280, 720}; display.res.width, display.res.height = .{1280, 720};
actors.res.body_texture = try assets.res.open_file(coral.files.bundle, "actor.bmp"); actors.res.body_texture = try assets.res.create_from_file(coral.files.bundle, "actor.bmp");
actors.res.quad_mesh_2d = try assets.res.open_quad_mesh_2d(@splat(1)); actors.res.quad_mesh_2d = try assets.res.create_quad_mesh_2d(@splat(1));
actors.res.render_texture = try assets.res.context.create(.{
.texture = .{
.format = .rgba8,
.access = .{
.render = .{
.width = display.res.width,
.height = display.res.height,
},
},
},
});
try actors.res.instances.push_grow(.{0, 0}); try actors.res.instances.push_grow(.{0, 0});
} }
@ -34,27 +48,47 @@ fn exit(actors: coral.Write(Actors)) void {
actors.res.instances.deinit(); actors.res.instances.deinit();
} }
fn render(queue: ona.gfx.Queue, actors: coral.Write(Actors)) !void { fn render(queue: ona.gfx.Queue, actors: coral.Write(Actors), display: coral.Read(ona.gfx.Display)) !void {
try queue.commands.append(.{.target = .{
.texture = actors.res.render_texture.?,
.clear_color = .{0, 0, 0, 0},
.clear_depth = 0,
}});
for (actors.res.instances.values) |instance| { for (actors.res.instances.values) |instance| {
try queue.commands.append(.{ try queue.commands.append(.{.instance_2d = .{
.instance_2d = .{ .mesh_2d = actors.res.quad_mesh_2d.?,
.mesh_2d = actors.res.quad_mesh_2d, .texture = actors.res.body_texture.?,
.texture = actors.res.body_texture,
.transform = .{ .transform = .{
.origin = instance, .origin = instance,
.xbasis = .{64, 0}, .xbasis = .{64, 0},
.ybasis = .{0, 64}, .ybasis = .{0, 64},
}, },
}, }});
});
} }
try queue.commands.append(.{.target = .{
.clear_color = null,
.clear_depth = null,
}});
try queue.commands.append(.{.instance_2d = .{
.mesh_2d = actors.res.quad_mesh_2d.?,
.texture = actors.res.render_texture.?,
.transform = .{
.origin = .{@floatFromInt(display.res.width / 2), @floatFromInt(display.res.height / 2)},
.xbasis = .{@floatFromInt(display.res.width), 0},
.ybasis = .{0, @floatFromInt(display.res.height)},
},
}});
} }
fn update(player: coral.Read(Player), actors: coral.Write(Actors), mapping: coral.Read(ona.act.Mapping)) !void { fn update(player: coral.Read(Player), actors: coral.Write(Actors), mapping: coral.Read(ona.act.Mapping)) !void {
actors.res.instances.values[0] += .{ actors.res.instances.values[0] += .{
mapping.res.axis_strength(player.res.move_x), mapping.res.axis_strength(player.res.move_x) * 10,
mapping.res.axis_strength(player.res.move_y), mapping.res.axis_strength(player.res.move_y) * 10,
}; };
} }

View File

@ -26,7 +26,7 @@ pub const Assets = struct {
}; };
}; };
pub fn open_file(self: *Assets, storage: coral.files.Storage, path: []const u8) (OpenError || Format.Error)!Handle { pub fn create_from_file(self: *Assets, storage: coral.files.Storage, path: []const u8) (OpenError || Format.Error)!*Handle {
defer { defer {
const max_cache_size = 536870912; const max_cache_size = 536870912;
@ -40,16 +40,16 @@ pub const Assets = struct {
continue; continue;
} }
return self.context.open(try format.file_desc(&self.staging_arena, storage, path)); return self.context.create(try format.file_desc(&self.staging_arena, storage, path));
} }
return .none; return error.FormatUnsupported;
} }
pub fn open_quad_mesh_2d(self: *Assets, extents: Point2D) OpenError!Handle { pub fn create_quad_mesh_2d(self: *Assets, extents: Point2D) OpenError!*Handle {
const width, const height = extents / @as(Point2D, @splat(2)); const width, const height = extents / @as(Point2D, @splat(2));
return self.context.open(.{ return self.context.create(.{
.mesh_2d = .{ .mesh_2d = .{
.indices = &.{0, 1, 2, 0, 2, 3}, .indices = &.{0, 1, 2, 0, 2, 3},
@ -66,6 +66,23 @@ pub const Assets = struct {
pub const Color = @Vector(4, f32); pub const Color = @Vector(4, f32);
pub const Command = union (enum) {
instance_2d: Instance2D,
target: Target,
pub const Instance2D = struct {
texture: *Handle,
mesh_2d: *Handle,
transform: Transform2D,
};
pub const Target = struct {
texture: ?*Handle = null,
clear_color: ?Color,
clear_depth: ?f32,
};
};
pub const Desc = union (enum) { pub const Desc = union (enum) {
texture: Texture, texture: Texture,
mesh_2d: Mesh2D, mesh_2d: Mesh2D,
@ -81,13 +98,19 @@ pub const Desc = union (enum) {
}; };
pub const Texture = struct { pub const Texture = struct {
data: []const coral.io.Byte,
width: u16,
format: Format, format: Format,
access: Access, access: Access,
pub const Access = enum { pub const Access = union (enum) {
static, static: struct {
width: u16,
data: []const coral.io.Byte,
},
render: struct {
width: u16,
height: u16,
},
}; };
pub const Format = enum { pub const Format = enum {
@ -109,17 +132,7 @@ pub const Display = struct {
clear_color: Color = colors.black, clear_color: Color = colors.black,
}; };
pub const Handle = enum (usize) { pub const Handle = opaque {};
none,
_,
pub fn index(self: Handle) ?usize {
return switch (self) {
.none => null,
_ => @intFromEnum(self) - 1,
};
}
};
pub const Input = union (enum) { pub const Input = union (enum) {
key_up: Key, key_up: Key,

File diff suppressed because it is too large Load Diff

View File

@ -72,10 +72,14 @@ pub fn bmp_file_desc(
return .{ return .{
.texture = .{ .texture = .{
.format = .rgba8,
.access = .{
.static = .{
.width = pixel_width, .width = pixel_width,
.data = pixels, .data = pixels,
.format = .rgba8, },
.access = .static, },
} }
}; };
} }

View File

@ -1,5 +1,7 @@
@header const Vec2 = @Vector(2, f32) @header pub const Vec2 = @Vector(2, f32)
@header pub const Mat4 = [4]@Vector(4, f32)
@ctype vec2 Vec2 @ctype vec2 Vec2
@ctype mat4 Mat4
@vs vs @vs vs
in vec2 mesh_xy; in vec2 mesh_xy;
@ -12,8 +14,8 @@ in vec4 instance_tint;
in float instance_depth; in float instance_depth;
in vec4 instance_rect; in vec4 instance_rect;
uniform Screen { uniform Projection {
vec2 screen_size; mat4 projection;
}; };
out vec4 color; out vec4 color;
@ -22,13 +24,10 @@ out vec2 uv;
void main() { void main() {
// Calculate the world position of the vertex // 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 world_position = instance_origin + mesh_xy.x * instance_xbasis + mesh_xy.y * instance_ybasis;
const vec2 projected_position = (projection * vec4(world_position, 0, 1)).xy;
// Convert world position to normalized device coordinates (NDC)
// Assuming the screen coordinates range from (0, 0) to (screen_size.x, screen_size.y)
const vec2 ndc_position = (vec2(world_position.x, -world_position.y) / screen_size) * 2.0 - vec2(1.0, -1.0);
// Set the position of the vertex in clip space // Set the position of the vertex in clip space
gl_Position = vec4(ndc_position, instance_depth, 1.0); gl_Position = vec4(projected_position, instance_depth, 1.0);
color = instance_tint; color = instance_tint;
// Calculate the width and height from left, top, right, bottom configuration // Calculate the width and height from left, top, right, bottom configuration