get medium cards rendering
commit
15e1670ec3
|
@ -0,0 +1,2 @@
|
||||||
|
zig-out/
|
||||||
|
zig-cache/
|
|
@ -0,0 +1,55 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
// Although this function looks imperative, note that its job is to
|
||||||
|
// declaratively construct a build graph that will be executed by an external
|
||||||
|
// runner.
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
// Standard target options allows the person running `zig build` to choose
|
||||||
|
// what target to build for. Here we do not override the defaults, which
|
||||||
|
// means any target is allowed, and the default is native. Other options
|
||||||
|
// for restricting supported target set are available.
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
|
||||||
|
// Standard optimization options allow the person running `zig build` to select
|
||||||
|
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
|
||||||
|
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const seizer = b.dependency("seizer", .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "seizer-rummy",
|
||||||
|
.root_source_file = .{ .path = "src/main.zig" },
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
exe.root_module.addImport("seizer", seizer.module("seizer"));
|
||||||
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
const run_cmd = b.addRunArtifact(exe);
|
||||||
|
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);
|
||||||
|
|
||||||
|
const exe_unit_tests = b.addTest(.{
|
||||||
|
.root_source_file = .{ .path = "src/main.zig" },
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
||||||
|
|
||||||
|
// Similar to creating the run step earlier, this exposes a `test` step to
|
||||||
|
// the `zig build --help` menu, providing a way for the user to request
|
||||||
|
// running the unit tests.
|
||||||
|
const test_step = b.step("test", "Run unit tests");
|
||||||
|
test_step.dependOn(&run_exe_unit_tests.step);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
.{
|
||||||
|
.name = "seizer-rummy",
|
||||||
|
// This is a [Semantic Version](https://semver.org/).
|
||||||
|
// In a future version of Zig it will be used for package deduplication.
|
||||||
|
.version = "0.0.0",
|
||||||
|
|
||||||
|
// This field is optional.
|
||||||
|
// This is currently advisory only; Zig does not yet do anything
|
||||||
|
// with this value.
|
||||||
|
//.minimum_zig_version = "0.11.0",
|
||||||
|
|
||||||
|
// This field is optional.
|
||||||
|
// Each dependency must either provide a `url` and `hash`, or a `path`.
|
||||||
|
// `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
|
||||||
|
// Once all dependencies are fetched, `zig build` no longer requires
|
||||||
|
// internet connectivity.
|
||||||
|
.dependencies = .{
|
||||||
|
.seizer = .{
|
||||||
|
.url = "https://github.com/leroycep/seizer/archive/dd1f9f6c94e91edfd96f0075c5f5d33aa30758f4.tar.gz",
|
||||||
|
.hash = "122009caed9e40d713c847b24c2abf8540299e32fb5e77f73ab2acdf5c27bc3e4c90",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.paths = .{
|
||||||
|
// This makes *all* files, recursively, included in this package. It is generally
|
||||||
|
// better to explicitly list the files and directories instead, to insure that
|
||||||
|
// fetching from tarballs, file system paths, and version control all result
|
||||||
|
// in the same contents hash.
|
||||||
|
"",
|
||||||
|
// For example...
|
||||||
|
//"build.zig",
|
||||||
|
//"build.zig.zon",
|
||||||
|
//"src",
|
||||||
|
//"LICENSE",
|
||||||
|
//"README.md",
|
||||||
|
},
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,182 @@
|
||||||
|
var gl_binding: gl.Binding = undefined;
|
||||||
|
|
||||||
|
const Suit = enum(u2) {
|
||||||
|
clubs = 0b00,
|
||||||
|
spades = 0b01,
|
||||||
|
hearts = 0b10,
|
||||||
|
diamonds = 0b11,
|
||||||
|
|
||||||
|
pub fn color(this: @This()) u1 {
|
||||||
|
return (@intFromEnum(this) & 0b10) >> 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const Card = packed struct(u6) {
|
||||||
|
suit: Suit,
|
||||||
|
rank: u4,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A texture with a regular grid of sprites
|
||||||
|
const TileSheet = struct {
|
||||||
|
texture: seizer.Texture,
|
||||||
|
tile_size: [2]u32,
|
||||||
|
|
||||||
|
pub const InitOptions = struct {
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
image_file_contents: []const u8,
|
||||||
|
tile_size: [2]u32,
|
||||||
|
texture_options: seizer.Texture.InitFromFileOptions = .{},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(options: InitOptions) !@This() {
|
||||||
|
const texture = try seizer.Texture.initFromFileContents(
|
||||||
|
options.allocator,
|
||||||
|
options.image_file_contents,
|
||||||
|
options.texture_options,
|
||||||
|
);
|
||||||
|
return @This(){
|
||||||
|
.texture = texture,
|
||||||
|
.tile_size = options.tile_size,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(this: *@This()) void {
|
||||||
|
this.texture.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn renderTile(this: @This(), canvas: *seizer.Canvas, tile_id: u32, pos: [2]f32, options: struct {
|
||||||
|
size: ?[2]f32 = null,
|
||||||
|
}) void {
|
||||||
|
const texture_sizef = [2]f32{
|
||||||
|
@floatFromInt(this.texture.size[0]),
|
||||||
|
@floatFromInt(this.texture.size[1]),
|
||||||
|
};
|
||||||
|
const tile_sizef = [2]f32{
|
||||||
|
@floatFromInt(this.tile_size[0]),
|
||||||
|
@floatFromInt(this.tile_size[1]),
|
||||||
|
};
|
||||||
|
const size_in_tiles = [2]u32{
|
||||||
|
@as(u32, @intCast(this.texture.size[0])) / this.tile_size[0],
|
||||||
|
@as(u32, @intCast(this.texture.size[1])) / this.tile_size[1],
|
||||||
|
};
|
||||||
|
const pos_in_tiles = [2]u32{
|
||||||
|
tile_id % size_in_tiles[0],
|
||||||
|
tile_id / size_in_tiles[0],
|
||||||
|
};
|
||||||
|
const pos_in_tilesf = [2]f32{
|
||||||
|
@floatFromInt(pos_in_tiles[0]),
|
||||||
|
@floatFromInt(pos_in_tiles[1]),
|
||||||
|
};
|
||||||
|
const uv = seizer.geometry.AABB(f32){
|
||||||
|
.min = .{
|
||||||
|
(pos_in_tilesf[0] * tile_sizef[0]) / texture_sizef[0],
|
||||||
|
(pos_in_tilesf[1] * tile_sizef[1]) / texture_sizef[1],
|
||||||
|
},
|
||||||
|
.max = .{
|
||||||
|
((pos_in_tilesf[0] + 1) * tile_sizef[0]) / texture_sizef[0],
|
||||||
|
((pos_in_tilesf[1] + 1) * tile_sizef[1]) / texture_sizef[1],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
_ = canvas.printText(.{ 0, 0 }, "uv = {}", .{uv}, .{});
|
||||||
|
canvas.rect(pos, options.size orelse tile_sizef, .{
|
||||||
|
.texture = this.texture.glTexture,
|
||||||
|
.uv = uv,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// const cards_medium_spritesheet =
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
|
||||||
|
// GLFW setup
|
||||||
|
try seizer.backend.glfw.loadDynamicLibraries(gpa.allocator());
|
||||||
|
|
||||||
|
_ = seizer.backend.glfw.c.glfwSetErrorCallback(&seizer.backend.glfw.defaultErrorCallback);
|
||||||
|
|
||||||
|
const glfw_init_res = seizer.backend.glfw.c.glfwInit();
|
||||||
|
if (glfw_init_res != 1) {
|
||||||
|
std.debug.print("glfw init error: {}\n", .{glfw_init_res});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer seizer.backend.glfw.c.glfwTerminate();
|
||||||
|
|
||||||
|
seizer.backend.glfw.c.glfwWindowHint(seizer.backend.glfw.c.GLFW_OPENGL_DEBUG_CONTEXT, seizer.backend.glfw.c.GLFW_TRUE);
|
||||||
|
seizer.backend.glfw.c.glfwWindowHint(seizer.backend.glfw.c.GLFW_CLIENT_API, seizer.backend.glfw.c.GLFW_OPENGL_ES_API);
|
||||||
|
seizer.backend.glfw.c.glfwWindowHint(seizer.backend.glfw.c.GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
seizer.backend.glfw.c.glfwWindowHint(seizer.backend.glfw.c.GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
|
|
||||||
|
// Open window
|
||||||
|
const window = seizer.backend.glfw.c.glfwCreateWindow(720, 720, "Rummy", null, null) orelse return error.GlfwCreateWindow;
|
||||||
|
errdefer seizer.backend.glfw.c.glfwDestroyWindow(window);
|
||||||
|
|
||||||
|
seizer.backend.glfw.c.glfwMakeContextCurrent(window);
|
||||||
|
|
||||||
|
gl_binding.init(seizer.backend.glfw.GlBindingLoader);
|
||||||
|
gl.makeBindingCurrent(&gl_binding);
|
||||||
|
|
||||||
|
// Set up input callbacks
|
||||||
|
_ = seizer.backend.glfw.c.glfwSetFramebufferSizeCallback(window, &glfw_framebuffer_size_callback);
|
||||||
|
|
||||||
|
var card_tilemap = try TileSheet.init(.{
|
||||||
|
.allocator = gpa.allocator(),
|
||||||
|
.image_file_contents = @embedFile("./cardsMedium_tilemap.png"),
|
||||||
|
.tile_size = .{ 32, 32 },
|
||||||
|
.texture_options = .{
|
||||||
|
.min_filter = .nearest,
|
||||||
|
.mag_filter = .nearest,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
defer card_tilemap.deinit();
|
||||||
|
|
||||||
|
var canvas = try seizer.Canvas.init(gpa.allocator(), .{});
|
||||||
|
defer canvas.deinit(gpa.allocator());
|
||||||
|
|
||||||
|
while (seizer.backend.glfw.c.glfwWindowShouldClose(window) != seizer.backend.glfw.c.GLFW_TRUE) {
|
||||||
|
seizer.backend.glfw.c.glfwPollEvents();
|
||||||
|
|
||||||
|
gl.clearColor(0.7, 0.5, 0.5, 1.0);
|
||||||
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
var window_size: [2]c_int = undefined;
|
||||||
|
seizer.backend.glfw.c.glfwGetWindowSize(window, &window_size[0], &window_size[1]);
|
||||||
|
|
||||||
|
var framebuffer_size: [2]c_int = undefined;
|
||||||
|
seizer.backend.glfw.c.glfwGetFramebufferSize(window, &framebuffer_size[0], &framebuffer_size[1]);
|
||||||
|
|
||||||
|
canvas.begin(.{
|
||||||
|
.window_size = [2]f32{
|
||||||
|
@floatFromInt(window_size[0]),
|
||||||
|
@floatFromInt(window_size[1]),
|
||||||
|
},
|
||||||
|
.framebuffer_size = [2]f32{
|
||||||
|
@floatFromInt(framebuffer_size[0]),
|
||||||
|
@floatFromInt(framebuffer_size[1]),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
card_tilemap.renderTile(&canvas, 1, .{ 10, 10 }, .{});
|
||||||
|
// canvas.rect(.{ 10, 10 }, .{ @as(f32, @floatFromInt(card_tilemap.size[0])) / 15.0, @as(f32, @floatFromInt(card_tilemap.size[1])) / 10.0 }, .{
|
||||||
|
// .texture = card_tilemap.glTexture,
|
||||||
|
// .uv = .{ .min = .{ 0, 0 }, .max = .{ 1.0 / 15.0, 1.0 / 10.0 } },
|
||||||
|
// });
|
||||||
|
_ = canvas.writeText(.{ 50, 50 }, "Hello, world!", .{});
|
||||||
|
_ = canvas.printText(.{ 50, 100 }, "window_size = {}, {}\nframebuffer_size = {}, {}", .{ window_size[0], window_size[1], framebuffer_size[0], framebuffer_size[1] }, .{});
|
||||||
|
canvas.end();
|
||||||
|
|
||||||
|
seizer.backend.glfw.c.glfwSwapBuffers(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn glfw_framebuffer_size_callback(window: ?*seizer.backend.glfw.c.GLFWwindow, width: c_int, height: c_int) callconv(.C) void {
|
||||||
|
_ = window;
|
||||||
|
gl.viewport(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
@intCast(width),
|
||||||
|
@intCast(height),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const seizer = @import("seizer");
|
||||||
|
const gl = seizer.gl;
|
||||||
|
const std = @import("std");
|
Loading…
Reference in New Issue