render trees
This commit is contained in:
parent
892fbb38be
commit
b356038f1f
177
src/app.zig
177
src/app.zig
@ -51,6 +51,7 @@ const terrain_origin_x: i32 = -80;
|
||||
const terrain_origin_y: i32 = -60;
|
||||
const terrain_width = 160;
|
||||
const terrain_height = 70;
|
||||
const terrain_tile_size = Vec2.init(32, 32);
|
||||
|
||||
const EntitySlotMap = SlotMapType(u16, u16, Entity);
|
||||
const EntityId = EntitySlotMap.Id;
|
||||
@ -179,6 +180,7 @@ const Entity = struct {
|
||||
|
||||
tree_health: u32 = 0,
|
||||
tree_max_health: u32 = 0,
|
||||
tree_seed: u64 = 0,
|
||||
|
||||
station_spawn_tree_cooldown: Nanoseconds = 0,
|
||||
station_owned_tree: ?EntityId = null,
|
||||
@ -279,9 +281,19 @@ const Upgrades = struct {
|
||||
};
|
||||
|
||||
const Shop = struct {
|
||||
minion_upgrades: []Item,
|
||||
tree_upgrades: []Item,
|
||||
fire_upgrades: []Item,
|
||||
minion_count: Shop.Item,
|
||||
minion_carry_capacity: Shop.Item,
|
||||
|
||||
tree_count: Shop.Item,
|
||||
tree_level: Shop.Item,
|
||||
|
||||
fire_speed: Shop.Item,
|
||||
fire_heat_per_wood: Shop.Item,
|
||||
fire_stack_size: Shop.Item,
|
||||
|
||||
minion_upgrades: []*Item,
|
||||
tree_upgrades: []*Item,
|
||||
fire_upgrades: []*Item,
|
||||
|
||||
const Item = struct {
|
||||
label: []const u8,
|
||||
@ -491,8 +503,8 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
||||
}
|
||||
|
||||
fn initShop(self: *App, arena: Allocator) !void {
|
||||
const minion_upgrades = try arena.dupe(Shop.Item, &.{
|
||||
Shop.Item{
|
||||
self.shop = .{
|
||||
.minion_count = Shop.Item{
|
||||
.label = "Minion count",
|
||||
.limit = 50,
|
||||
.unlocked = true,
|
||||
@ -503,9 +515,8 @@ fn initShop(self: *App, arena: Allocator) !void {
|
||||
.cost = 1,
|
||||
.cost_scaling = .initFixed(1),
|
||||
},
|
||||
Shop.Item{
|
||||
.minion_carry_capacity = Shop.Item{
|
||||
.label = "Carry capacity",
|
||||
.unlocked = true,
|
||||
|
||||
.value_ref = .initU32(&self.upgrades.minion_carry_capacity),
|
||||
.value_scaling = .initFixed(1),
|
||||
@ -513,12 +524,9 @@ fn initShop(self: *App, arena: Allocator) !void {
|
||||
.cost = 1,
|
||||
.cost_scaling = .initFixed(1),
|
||||
},
|
||||
});
|
||||
|
||||
const tree_upgrades = try arena.dupe(Shop.Item, &.{
|
||||
Shop.Item{
|
||||
.tree_count = Shop.Item{
|
||||
.label = "Tree count",
|
||||
.unlocked = true,
|
||||
|
||||
.value_ref = .initU32(&self.upgrades.tree_station_count),
|
||||
.value_scaling = .initFixed(1),
|
||||
@ -526,10 +534,9 @@ fn initShop(self: *App, arena: Allocator) !void {
|
||||
.cost = 1,
|
||||
.cost_scaling = .initFixed(1),
|
||||
},
|
||||
Shop.Item{
|
||||
.tree_level = Shop.Item{
|
||||
.label = "Tree level",
|
||||
.limit = Upgrades.tree_levels.len,
|
||||
.unlocked = true,
|
||||
|
||||
.value_ref = .initU32(&self.upgrades.tree_level),
|
||||
.value_scaling = .initFixed(1),
|
||||
@ -537,12 +544,9 @@ fn initShop(self: *App, arena: Allocator) !void {
|
||||
.cost = 1,
|
||||
.cost_scaling = .initFixed(1),
|
||||
},
|
||||
});
|
||||
|
||||
const fire_upgrades = try arena.dupe(Shop.Item, &.{
|
||||
Shop.Item{
|
||||
.fire_speed = Shop.Item{
|
||||
.label = "Burn speed",
|
||||
.unlocked = true,
|
||||
|
||||
.value_ref = .initF32(&self.upgrades.burn_speed),
|
||||
.value_scaling = .initFixed(1),
|
||||
@ -550,9 +554,8 @@ fn initShop(self: *App, arena: Allocator) !void {
|
||||
.cost = 1,
|
||||
.cost_scaling = .initFixed(1),
|
||||
},
|
||||
Shop.Item{
|
||||
.fire_heat_per_wood = Shop.Item{
|
||||
.label = "Heat per wood",
|
||||
.unlocked = true,
|
||||
|
||||
.value_ref = .initU32(&self.upgrades.burn_heat_per_wood),
|
||||
.value_scaling = .initFixed(1),
|
||||
@ -560,9 +563,8 @@ fn initShop(self: *App, arena: Allocator) !void {
|
||||
.cost = 1,
|
||||
.cost_scaling = .initFixed(1),
|
||||
},
|
||||
Shop.Item{
|
||||
.label = "Max stack size",
|
||||
.unlocked = true,
|
||||
.fire_stack_size = Shop.Item{
|
||||
.label = "Stack size",
|
||||
|
||||
.value_ref = .initU32(&self.upgrades.burn_max_stack_size),
|
||||
.value_scaling = .initFixed(1),
|
||||
@ -570,12 +572,20 @@ fn initShop(self: *App, arena: Allocator) !void {
|
||||
.cost = 1,
|
||||
.cost_scaling = .initFixed(1),
|
||||
},
|
||||
});
|
||||
|
||||
self.shop = .{
|
||||
.minion_upgrades = minion_upgrades,
|
||||
.tree_upgrades = tree_upgrades,
|
||||
.fire_upgrades = fire_upgrades,
|
||||
.minion_upgrades = try arena.dupe(*Shop.Item, &.{
|
||||
&self.shop.minion_count,
|
||||
&self.shop.minion_carry_capacity
|
||||
}),
|
||||
.tree_upgrades = try arena.dupe(*Shop.Item, &.{
|
||||
&self.shop.tree_count,
|
||||
&self.shop.tree_level
|
||||
}),
|
||||
.fire_upgrades = try arena.dupe(*Shop.Item, &.{
|
||||
&self.shop.fire_speed,
|
||||
&self.shop.fire_heat_per_wood,
|
||||
&self.shop.fire_stack_size,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
@ -617,6 +627,28 @@ fn initTerrain(self: *App) void {
|
||||
tile.sprite = self.pickRandom(Gfx.Sprite.Id, underground_tiles);
|
||||
}
|
||||
}
|
||||
|
||||
const grass_tiles = &[_]Gfx.Sprite.Id{
|
||||
self.terrain_sheet.get(113, 45),
|
||||
self.terrain_sheet.get(114, 45),
|
||||
self.terrain_sheet.get(115, 45),
|
||||
self.terrain_sheet.get(116, 45),
|
||||
self.terrain_sheet.get(117, 45),
|
||||
self.terrain_sheet.get(122, 45),
|
||||
self.terrain_sheet.get(123, 45),
|
||||
self.terrain_sheet.get(124, 45),
|
||||
self.terrain_sheet.get(125, 45),
|
||||
Gfx.getNilSprite(),
|
||||
Gfx.getNilSprite(),
|
||||
Gfx.getNilSprite(),
|
||||
Gfx.getNilSprite(),
|
||||
Gfx.getNilSprite(),
|
||||
Gfx.getNilSprite(),
|
||||
};
|
||||
for (0..terrain_width) |x| {
|
||||
const tile = self.getTerrainTile(@as(i32, @intCast(x)) + terrain_origin_x, -1);
|
||||
tile.sprite = self.pickRandom(Gfx.Sprite.Id, grass_tiles);
|
||||
}
|
||||
}
|
||||
|
||||
fn getTerrainTile(self: *App, x: i32, y: i32) *Tile {
|
||||
@ -633,8 +665,6 @@ fn getTerrainTile(self: *App, x: i32, y: i32) *Tile {
|
||||
return &self.terrain_tiles[y_u32 * terrain_width + x_u32];
|
||||
}
|
||||
|
||||
// fn getTerrainEdgeLeft(self: *App)
|
||||
|
||||
fn spawnEntity(self: *App, e: Entity) ?EntityId {
|
||||
return self.entities.insert(e) catch {
|
||||
log.warn("Failed to spawn entity {}, entity limit reached", .{e.type});
|
||||
@ -679,11 +709,14 @@ fn spawnTree(self: *App, station_id: EntityId) void {
|
||||
return;
|
||||
}
|
||||
|
||||
const rng = self.prng.random();
|
||||
|
||||
const health = self.upgrades.tree_health;
|
||||
if (self.spawnEntity(Entity{
|
||||
.type = .tree,
|
||||
.tree_health = health,
|
||||
.tree_max_health = health,
|
||||
.tree_seed = rng.int(u64),
|
||||
|
||||
.pos = station.pos
|
||||
})) |id| {
|
||||
@ -1104,10 +1137,10 @@ fn showShopPanel(
|
||||
plt: Platform.Frame,
|
||||
panel_label: []const u8,
|
||||
panel_pos: Vec2,
|
||||
shop_items: []Shop.Item
|
||||
shop_items: []*Shop.Item
|
||||
) !void {
|
||||
var unlocked_count: f32 = 0;
|
||||
for (shop_items) |*shop_item| {
|
||||
for (shop_items) |shop_item| {
|
||||
if (shop_item.unlocked) {
|
||||
unlocked_count += 1;
|
||||
}
|
||||
@ -1154,7 +1187,7 @@ fn showShopPanel(
|
||||
Gfx.transformTranslate(.init(10, -5));
|
||||
|
||||
var index: usize = 0;
|
||||
for (shop_items) |*shop_item| {
|
||||
for (shop_items) |shop_item| {
|
||||
if (!shop_item.unlocked) {
|
||||
continue;
|
||||
}
|
||||
@ -1228,7 +1261,7 @@ fn showShopPanel(
|
||||
const new_value = shop_item.value_scaling.apply(shop_item.value_ref.deref());
|
||||
Gfx.drawText(self.font, .{
|
||||
.text = try allocPrint(plt.arena, "> {f}", .{new_value}),
|
||||
.pos = .init(240, 0),
|
||||
.pos = .init(250, 0),
|
||||
.height = 24,
|
||||
.color = text_color
|
||||
});
|
||||
@ -1245,7 +1278,7 @@ fn showShopPanel(
|
||||
}
|
||||
|
||||
fn showUI(self: *App, plt: Platform.Frame) !void {
|
||||
var heat_pos = Vec2.init(0, -200);
|
||||
var heat_pos = Vec2.init(50, -200);
|
||||
|
||||
{ // Draw heat counter
|
||||
var builder = Gfx.TextBuilder.init(plt.arena);
|
||||
@ -1285,13 +1318,13 @@ fn showDebugScaling(label: []const u8, scaling: *Shop.Item.Scaling) void {
|
||||
_ = ImGUI.inputF32Drag(.{ .label = "quadratic", .value = &scaling.quadratic });
|
||||
}
|
||||
|
||||
fn showDebugShopItems(self: *App, label: []const u8, shop_items: []Shop.Item) void {
|
||||
fn showDebugShopItems(self: *App, label: []const u8, shop_items: []*Shop.Item) void {
|
||||
_ = self; // autofix
|
||||
ImGUI.pushID(.{ .string = label });
|
||||
defer ImGUI.popID();
|
||||
|
||||
_ = ImGUI.text("{s}", .{label});
|
||||
for (0.., shop_items) |i, *shop_item| {
|
||||
for (0.., shop_items) |i, shop_item| {
|
||||
ImGUI.pushID(.{ .int = @intCast(i) });
|
||||
defer ImGUI.popID();
|
||||
|
||||
@ -1397,6 +1430,66 @@ fn showDebug(self: *App, plt: Platform.Frame) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn drawTree(self: *App, seed: u64, pos: Vec2) void {
|
||||
var prng = Prng.init(seed);
|
||||
const rng = prng.random();
|
||||
|
||||
Gfx.transformPush();
|
||||
defer Gfx.transformPop();
|
||||
|
||||
Gfx.transformTranslate(pos.sub(.init(terrain_tile_size.x/2, terrain_tile_size.y)));
|
||||
Gfx.transformScale(terrain_tile_size);
|
||||
|
||||
Gfx.transformTranslate(.init(rng.float(f32)-0.5, 0));
|
||||
|
||||
const tree_middle = &[_]Gfx.Sprite.Id{
|
||||
self.terrain_sheet.get(125, 41),
|
||||
self.terrain_sheet.get(125, 40),
|
||||
self.terrain_sheet.get(125, 39),
|
||||
};
|
||||
|
||||
const trunk_height = rng.uintAtMost(u32, 4) + 2;
|
||||
|
||||
Gfx.drawSprite(self.terrain_sheet.get(125, 42), .init(0, 0), .init(1, 1), .white);
|
||||
for (0..trunk_height) |i| {
|
||||
const sprite = tree_middle[rng.uintLessThan(u32, tree_middle.len)];
|
||||
var trunk_pos = Vec2.init(0, -@as(f32, @floatFromInt(i)));
|
||||
trunk_pos.x += (rng.float(f32)-0.5)*2 * 0.15;
|
||||
Gfx.drawSprite(sprite, trunk_pos, .init(1, 1), .white);
|
||||
}
|
||||
Gfx.transformTranslate(Vec2.initFromInt(u32, 0, trunk_height).multiplyScalar(-1));
|
||||
Gfx.drawSprite(
|
||||
self.terrain_sheet.get(125, 38),
|
||||
.init(0, 0),
|
||||
.init(1, 1),
|
||||
.white
|
||||
);
|
||||
|
||||
const inner_leaves = self.terrain_sheet.get(123, 42);
|
||||
const bottom_leaves = self.terrain_sheet.get(124, 39);
|
||||
const left_leaves = self.terrain_sheet.get(123, 38);
|
||||
const corner_leaves = self.terrain_sheet.get(123, 39);
|
||||
|
||||
Gfx.drawSprite(bottom_leaves, .init(0, -1), .init(1, 1), .white);
|
||||
Gfx.drawSprite(corner_leaves, .init(-1, -1), .init(1, 1), .white);
|
||||
Gfx.drawSprite(corner_leaves, .init(2, -1), .init(-1, 1), .white);
|
||||
|
||||
const leaves_height = rng.uintAtMost(u32, 3) + 1;
|
||||
|
||||
for (0..leaves_height) |i| {
|
||||
var base = Vec2.initFromInt(usize, 0, i).multiplyScalar(-1);
|
||||
base.x += (rng.float(f32)-0.5)*2 * 0.2;
|
||||
Gfx.drawSprite(inner_leaves, base.add(.init(0, -2)), .init(1, 1), .white);
|
||||
Gfx.drawSprite(left_leaves, base.add(.init(2, -2)), .init(-1, 1), .white);
|
||||
Gfx.drawSprite(left_leaves, base.add(.init(-1, -2)), .init(1, 1), .white);
|
||||
}
|
||||
Gfx.transformTranslate(Vec2.initFromInt(u32, 0, leaves_height).multiplyScalar(-1));
|
||||
|
||||
Gfx.drawSprite(bottom_leaves, .init(0, -1), .init(1, -1), .white);
|
||||
Gfx.drawSprite(corner_leaves, .init(-1, -1), .init(1, -1), .white);
|
||||
Gfx.drawSprite(corner_leaves, .init(2, -1), .init(-1, -1), .white);
|
||||
}
|
||||
|
||||
pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||
const input = plt.input;
|
||||
_ = input; // autofix
|
||||
@ -1456,7 +1549,7 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||
}
|
||||
|
||||
const wood_station_first_pos = -100;
|
||||
const wood_station_step = -50;
|
||||
const wood_station_step = -70;
|
||||
|
||||
if (station_count > self.upgrades.tree_station_count) {
|
||||
for (self.upgrades.tree_station_count..station_count) |i| {
|
||||
@ -1695,9 +1788,8 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||
continue;
|
||||
}
|
||||
|
||||
const tile_size = Vec2.init(32, 32);
|
||||
const tile_pos = Vec2.initFromInt(usize, x, y).add(.initFromInt(i32, terrain_origin_x, terrain_origin_y));
|
||||
Gfx.drawSprite(tile.sprite, tile_pos.multiply(tile_size), tile_size, .white);
|
||||
Gfx.drawSprite(tile.sprite, tile_pos.multiply(terrain_tile_size), terrain_tile_size, .white);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1707,8 +1799,7 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||
while (tree_iter.next()) |id| {
|
||||
const e = self.entities.getAssumeExists(id);
|
||||
|
||||
const tree_size = Vec2.init(40, 100);
|
||||
Gfx.drawRectangle(e.pos.sub(.init(tree_size.x/2, tree_size.y)), tree_size, .rgb(40, 200, 40));
|
||||
self.drawTree(e.tree_seed, e.pos);
|
||||
|
||||
const progress = @as(f32, @floatFromInt(e.tree_health)) / @as(f32, @floatFromInt(e.tree_max_health));
|
||||
drawProgressBar(progress, e.pos.add(.init(0, 20)), .init(40, 10), .rgb(0, 100, 20));
|
||||
@ -1788,9 +1879,7 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||
}
|
||||
}
|
||||
|
||||
if (e.type == .wood_station) {
|
||||
Gfx.drawRectangle(e.pos.sub(.init(5, 5)), .init(10, 10), .rgb(20, 200, 20));
|
||||
} else if (e.type == .burn_station) {
|
||||
if (e.type == .burn_station) {
|
||||
Gfx.drawRectangle(e.pos.sub(.init(5, 5)), .init(10, 10), .rgb(200, 20, 20));
|
||||
} else if (e.type == .minion) {
|
||||
Gfx.drawText(self.font, .{
|
||||
|
||||
@ -39,8 +39,8 @@ const State = struct {
|
||||
nearest_sampler: sg.Sampler,
|
||||
default_sampler: Sampler,
|
||||
|
||||
quads_buffer: [2048]Quad,
|
||||
quads: std.ArrayList(Quad),
|
||||
quads_buffer: [2048]VertexQuad,
|
||||
quads: std.ArrayList(VertexQuad),
|
||||
|
||||
clear_color: Color,
|
||||
|
||||
@ -126,7 +126,7 @@ pub fn init(gpa: std.mem.Allocator, logger: sg.Logger) !void {
|
||||
const max_quads = self.quads_buffer.len;
|
||||
|
||||
bindings.vertex_buffers[0] = sg.makeBuffer(.{
|
||||
.size = @sizeOf(Quad) * max_quads,
|
||||
.size = @sizeOf(VertexQuad) * max_quads,
|
||||
.usage = .{ .vertex_buffer = true, .stream_update = true },
|
||||
.label = "quad-vertices"
|
||||
});
|
||||
@ -543,42 +543,42 @@ pub fn drawRectangleOutline(pos: Vec2, size: Vec2, color: Color, width: f32, ali
|
||||
|
||||
drawSpriteQuad(
|
||||
self.default_sprite,
|
||||
.{
|
||||
.init(.{
|
||||
.init(outer_rect.right(), outer_rect.top()),
|
||||
.init(outer_rect.left(), outer_rect.top()),
|
||||
.init(inner_rect.right(), inner_rect.top()),
|
||||
.init(inner_rect.left(), inner_rect.top()),
|
||||
},
|
||||
}),
|
||||
color
|
||||
);
|
||||
drawSpriteQuad(
|
||||
self.default_sprite,
|
||||
.{
|
||||
.init(.{
|
||||
.init(outer_rect.right(), outer_rect.top()),
|
||||
.init(inner_rect.right(), inner_rect.top()),
|
||||
.init(outer_rect.right(), outer_rect.bottom()),
|
||||
.init(inner_rect.right(), inner_rect.bottom()),
|
||||
},
|
||||
}),
|
||||
color
|
||||
);
|
||||
drawSpriteQuad(
|
||||
self.default_sprite,
|
||||
.{
|
||||
.init(.{
|
||||
.init(outer_rect.left(), outer_rect.top()),
|
||||
.init(inner_rect.left(), inner_rect.top()),
|
||||
.init(outer_rect.left(), outer_rect.bottom()),
|
||||
.init(inner_rect.left(), inner_rect.bottom()),
|
||||
},
|
||||
}),
|
||||
color
|
||||
);
|
||||
drawSpriteQuad(
|
||||
self.default_sprite,
|
||||
.{
|
||||
.init(.{
|
||||
.init(outer_rect.right(), outer_rect.bottom()),
|
||||
.init(outer_rect.left(), outer_rect.bottom()),
|
||||
.init(inner_rect.right(), inner_rect.bottom()),
|
||||
.init(inner_rect.left(), inner_rect.bottom()),
|
||||
},
|
||||
}),
|
||||
color
|
||||
);
|
||||
}
|
||||
@ -595,7 +595,7 @@ pub fn drawLine(from: Vec2, to: Vec2, color: Color, width: f32) void {
|
||||
|
||||
drawSpriteQuad(
|
||||
self.default_sprite,
|
||||
.{ top_right, top_left, bottom_right, bottom_left },
|
||||
.init(.{ top_right, top_left, bottom_right, bottom_left }),
|
||||
color
|
||||
);
|
||||
}
|
||||
@ -755,7 +755,7 @@ pub fn setTexture(id: Texture.Id, texture_data: ImageData) void {
|
||||
}
|
||||
|
||||
pub fn drawTexture(id: Texture.Id, pos: Vec2, size: Vec2, color: Color) void {
|
||||
var quad: Quad = undefined;
|
||||
var quad: VertexQuad = undefined;
|
||||
quad.setColor(color);
|
||||
quad.setRect(.{ .pos = pos, .size = size });
|
||||
quad.setUVRect(.init(0, 0, 1, 1));
|
||||
@ -795,7 +795,7 @@ pub const Sampler = enum {
|
||||
const DrawOptions = struct {
|
||||
sampler: ?Sampler = null,
|
||||
texture: Texture.Id,
|
||||
quad: Quad
|
||||
quad: VertexQuad
|
||||
};
|
||||
|
||||
pub fn draw(opts: DrawOptions) void {
|
||||
@ -1180,15 +1180,15 @@ pub fn getSpriteUVRect(id: Sprite.Id) ?Rect {
|
||||
return uv_rect;
|
||||
}
|
||||
|
||||
fn drawSpriteQuad(id: Sprite.Id, points: [4]Vec2, color: Color) void {
|
||||
pub fn drawSpriteQuad(id: Sprite.Id, points: Quad, color: Color) void {
|
||||
const self = &g_state;
|
||||
|
||||
var quad: Quad = undefined;
|
||||
var quad: VertexQuad = undefined;
|
||||
quad.setColor(color);
|
||||
quad.vertices[0].position = points[0];
|
||||
quad.vertices[1].position = points[1];
|
||||
quad.vertices[2].position = points[2];
|
||||
quad.vertices[3].position = points[3];
|
||||
quad.vertices[0].position = points.positions[0];
|
||||
quad.vertices[1].position = points.positions[1];
|
||||
quad.vertices[2].position = points.positions[2];
|
||||
quad.vertices[3].position = points.positions[3];
|
||||
|
||||
var texture: ?Texture.Id = null;
|
||||
if (id != self.nil_sprite) {
|
||||
@ -1208,12 +1208,7 @@ fn drawSpriteQuad(id: Sprite.Id, points: [4]Vec2, color: Color) void {
|
||||
}
|
||||
|
||||
pub fn drawSprite(id: Sprite.Id, pos: Vec2, size: Vec2, color: Color) void {
|
||||
const rect = .{
|
||||
pos,
|
||||
pos.add(.init(size.x, 0)),
|
||||
pos.add(.init(0, size.y)),
|
||||
pos.add(size),
|
||||
};
|
||||
const rect = Quad.initRect(pos, size);
|
||||
drawSpriteQuad(id, rect, color);
|
||||
}
|
||||
|
||||
@ -2296,16 +2291,16 @@ pub const Vertex = extern struct {
|
||||
color: Vec4,
|
||||
};
|
||||
|
||||
pub const Quad = extern struct {
|
||||
pub const VertexQuad = extern struct {
|
||||
vertices: [4]Vertex,
|
||||
|
||||
pub fn init(vertices: [4]Vertex) Quad {
|
||||
return Quad{
|
||||
pub fn init(vertices: [4]Vertex) VertexQuad {
|
||||
return VertexQuad{
|
||||
.vertices = vertices
|
||||
};
|
||||
}
|
||||
|
||||
pub fn setColor(self: *Quad, color: Color) void {
|
||||
pub fn setColor(self: *VertexQuad, color: Color) void {
|
||||
for (&self.vertices) |*vertex| {
|
||||
vertex.color = Vec4{
|
||||
.x = color.r,
|
||||
@ -2316,7 +2311,7 @@ pub const Quad = extern struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setUVRect(self: *Quad, rect: Rect) void {
|
||||
pub fn setUVRect(self: *VertexQuad, rect: Rect) void {
|
||||
const pos = rect.pos;
|
||||
const size = rect.size;
|
||||
self.vertices[0].texcoord = pos;
|
||||
@ -2325,7 +2320,7 @@ pub const Quad = extern struct {
|
||||
self.vertices[3].texcoord = pos.add(size);
|
||||
}
|
||||
|
||||
pub fn setRect(self: *Quad, rect: Rect) void {
|
||||
pub fn setRect(self: *VertexQuad, rect: Rect) void {
|
||||
const pos = rect.pos;
|
||||
const size = rect.size;
|
||||
self.vertices[0].position = pos;
|
||||
@ -2335,6 +2330,39 @@ pub const Quad = extern struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const Quad = struct {
|
||||
positions: [4]Vec2,
|
||||
|
||||
pub fn init(positions: [4]Vec2) Quad {
|
||||
return Quad{
|
||||
.positions = positions
|
||||
};
|
||||
}
|
||||
|
||||
pub fn initRect(pos: Vec2, size: Vec2) Quad {
|
||||
return Quad{
|
||||
.positions = .{
|
||||
pos,
|
||||
pos.add(.init(size.x, 0)),
|
||||
pos.add(.init(0, size.y)),
|
||||
pos.add(size),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn rotate(self: *Quad, rad: f32, origin: Vec2) void {
|
||||
for (&self.positions) |*pos| {
|
||||
pos.* = pos.sub(origin).rotate(rad).add(origin);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn offset(self: *Quad, vec2: Vec2) void {
|
||||
for (&self.positions) |*pos| {
|
||||
pos.* = pos.add(vec2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const TransformFrame = struct {
|
||||
offset: Vec2,
|
||||
scale: Vec2,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user