From 95c340b91529e0c390ead69ec798f085e2a4b1e7 Mon Sep 17 00:00:00 2001 From: Dendy Date: Mon, 25 Jul 2022 15:32:25 +0200 Subject: [PATCH] Implement main game rendering WIP --- .gitmodules | 3 ++ build.zig | 1 + lib/zlm | 1 + src/Action.zig | 7 +-- src/Game.zig | 22 ++++----- src/Game/Cell.zig | 2 +- src/Game/Piece.zig | 2 +- src/Game/Renderer.zig | 110 +++++++++++++----------------------------- src/Renderer.zig | 58 ++++++++++++++++------ src/Timer.zig | 6 +-- src/color.zig | 22 ++++----- src/main.zig | 10 ++-- src/shaders/vector.vs | 4 +- 13 files changed, 119 insertions(+), 129 deletions(-) create mode 160000 lib/zlm diff --git a/.gitmodules b/.gitmodules index ec33071..ec2a81d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/zgl"] path = lib/zgl url = https://github.com/ziglibs/zgl +[submodule "lib/zlm"] + path = lib/zlm + url = https://github.com/ziglibs/zlm diff --git a/build.zig b/build.zig index d774945..9e48054 100644 --- a/build.zig +++ b/build.zig @@ -18,6 +18,7 @@ pub fn build(b: *std.build.Builder) void { sdk.link(exe, .dynamic); exe.addPackagePath("zgl", "lib/zgl/zgl.zig"); + exe.addPackagePath("zlm", "lib/zlm/zlm.zig"); exe.addPackage(sdk.getWrapperPackage("sdl2")); exe.linkSystemLibrary("gl"); diff --git a/lib/zlm b/lib/zlm new file mode 160000 index 0000000..e9da7f0 --- /dev/null +++ b/lib/zlm @@ -0,0 +1 @@ +Subproject commit e9da7f084055eb3fab0454ef4d5db0a103ff96df diff --git a/src/Action.zig b/src/Action.zig index e57319f..6e22729 100644 --- a/src/Action.zig +++ b/src/Action.zig @@ -1,13 +1,14 @@ const Self = @This(); +const SDL = @import("sdl2"); activate: bool = false, holding: bool = false, -code: u8, // SDL Keycode +scancode: SDL.Scancode, // SDL Keycode callback: *const anyopaque, // MUST be a function with void return -pub fn init(code: u8, callback: *const anyopaque) Self { +pub fn init(scancode: SDL.Scancode, callback: *const anyopaque) Self { return Self{ - .code = code, + .scancode = scancode, .callback = callback, }; } diff --git a/src/Game.zig b/src/Game.zig index 57d7a77..070c06c 100644 --- a/src/Game.zig +++ b/src/Game.zig @@ -37,13 +37,13 @@ piece: Piece, shadow: Piece, action_list: [7]Action = .{ - Action.init(SDL.SDL_SCANCODE_D, actionRight), // Right - Action.init(SDL.SDL_SCANCODE_A, actionLeft), // Left - Action.init(SDL.SDL_SCANCODE_S, actionDown), // Down - Action.init(SDL.SDL_SCANCODE_W, actionHard), // Instant Drop - Action.init(SDL.SDL_SCANCODE_SPACE, actionSwap), // Swap Piece - Action.init(SDL.SDL_SCANCODE_RIGHT, actionRotR), // Rotate - Action.init(SDL.SDL_SCANCODE_LEFT, actionRotL), // Rotate + Action.init(SDL.Scancode.d, actionRight), // Right + Action.init(SDL.Scancode.a, actionLeft), // Left + Action.init(SDL.Scancode.s, actionDown), // Down + Action.init(SDL.Scancode.w, actionHard), // Instant Drop + Action.init(SDL.Scancode.space, actionSwap), // Swap Piece + Action.init(SDL.Scancode.right, actionRotR), // Rotate + Action.init(SDL.Scancode.left, actionRotL), // Rotate }, timer_down: Timer, @@ -53,7 +53,7 @@ timer_right_arr: Timer, timer_right_das: Timer, timer_gravity: Timer, -pub fn init(renderer: *SDL.SDL_Renderer) Self { +pub fn init(renderer: Renderer.Renderer) Self { var ret = Self{ .grid = Grid.init(), @@ -164,14 +164,14 @@ pub fn tick(self: *Self) State { } // KEY EVENTS - var key_state = SDL.SDL_GetKeyboardState(null); + var key_state = SDL.getKeyboardState(); for (self.action_list) |*action| { - if (key_state[action.*.code] == 1 and !action.*.holding) { + if (key_state.isPressed(action.*.scancode) and !action.*.holding) { action.*.holding = true; action.*.activate = true; } - if (key_state[action.*.code] == 0) { + if (!key_state.isPressed(action.*.scancode)) { action.*.holding = false; } diff --git a/src/Game/Cell.zig b/src/Game/Cell.zig index 14d60da..04c6135 100644 --- a/src/Game/Cell.zig +++ b/src/Game/Cell.zig @@ -6,7 +6,7 @@ const Color = @import("../color.zig"); const Self = @This(); free: bool, -color: SDL.SDL_Color, +color: SDL.Color, pub fn init() Self { return Self{ diff --git a/src/Game/Piece.zig b/src/Game/Piece.zig index 05cba27..36f4022 100644 --- a/src/Game/Piece.zig +++ b/src/Game/Piece.zig @@ -51,7 +51,7 @@ dropped: bool = false, swapped: bool = false, piece_type: Type, -color: SDL.SDL_Color, +color: SDL.Color, pub fn init(piece_type: Type) Self { return Self{ diff --git a/src/Game/Renderer.zig b/src/Game/Renderer.zig index aa63254..5f5395e 100644 --- a/src/Game/Renderer.zig +++ b/src/Game/Renderer.zig @@ -4,27 +4,23 @@ const Game = @import("../Game.zig"); const Bag = @import("Bag.zig"); const Grid = @import("Grid.zig"); const Piece = @import("Piece.zig"); +pub const Renderer = @import("../Renderer.zig"); const color = @import("../color.zig"); const Self = @This(); -renderer: *SDL.SDL_Renderer, +renderer: Renderer, grid_cell_size: i32, grid_pos_x: i32, grid_pos_y: i32, -pub fn init(renderer: *SDL.SDL_Renderer) Self { - // Calculate positions - var aux_w: i32 = undefined; - var aux_h: i32 = undefined; +pub fn init(renderer: Renderer) Self { + var wsize = renderer.getOutputSize(); - // TODO: have in mind the return value - _ = SDL.SDL_GetRendererOutputSize(renderer, &aux_w, &aux_h); - - const grid_cell_size = @divFloor(@minimum(aux_w, aux_h), 32); - const grid_pos_x = @divFloor(aux_w, 2) - (grid_cell_size * @divFloor(Grid.ncolumns, 2)); - const grid_pos_y = @divFloor(aux_h, 2) - (grid_cell_size * @divFloor(Grid.nrows + Grid.buffer, 2)); + const grid_cell_size = @divFloor(@minimum(wsize.width, wsize.height), 32); + const grid_pos_x = @divFloor(wsize.width, 2) - (grid_cell_size * @divFloor(Grid.ncolumns, 2)); + const grid_pos_y = @divFloor(wsize.height, 2) - (grid_cell_size * @divFloor(Grid.nrows + Grid.buffer, 2)); return Self{ .renderer = renderer, .grid_pos_x = grid_pos_x, @@ -36,16 +32,7 @@ pub fn init(renderer: *SDL.SDL_Renderer) Self { pub fn renderBag(self: *Self, game: Game) void { const pos_x = self.grid_pos_x + ((Grid.ncolumns + 1) * self.grid_cell_size); const pos_y = self.grid_pos_y + (Grid.buffer * self.grid_cell_size); - const cell_size = self.grid_cell_size; - var rect = SDL.SDL_Rect{ - .x = pos_x, - .y = pos_y, - .w = cell_size, - .h = cell_size, - }; - - //var trans: u8 = 0; var r: u8 = 0; var g: u8 = 0; var b: u8 = 0; @@ -69,13 +56,13 @@ pub fn renderBag(self: *Self, game: Game) void { a = 50; } - rect.x = pos_x + @intCast(i32, x) * cell_size; - rect.y = pos_y + (@intCast(i32, y) + @intCast(i32, i * piece.structure.len)) * cell_size; + const new_x = pos_x + @intCast(i32, x) * self.grid_cell_size; + const new_y = pos_y + (@intCast(i32, y) + @intCast(i32, i * piece.structure.len)) * self.grid_cell_size; - _ = SDL.SDL_SetRenderDrawColor(self.renderer, r, g, b, a); - _ = SDL.SDL_RenderFillRect(self.renderer, &rect); - _ = SDL.SDL_SetRenderDrawColor(self.renderer, r -| 30, g -| 30, b -| 30, a); - _ = SDL.SDL_RenderDrawRect(self.renderer, &rect); + self.renderer.setColor(r, g, b, a); + self.renderer.fillRectangle(new_x, new_y, self.grid_cell_size, self.grid_cell_size); + self.renderer.setColor(r -| 30, g -| 30, b -| 30, a); + self.renderer.drawRectangle(new_x, new_y, self.grid_cell_size, self.grid_cell_size); } } } @@ -85,16 +72,7 @@ pub fn renderBag(self: *Self, game: Game) void { pub fn renderHeld(self: *Self, game: Game) void { const pos_x = self.grid_pos_x - (5 * self.grid_cell_size); const pos_y = self.grid_pos_y + (Grid.buffer * self.grid_cell_size); - const cell_size = self.grid_cell_size; - var rect = SDL.SDL_Rect{ - .x = pos_x, - .y = pos_y, - .w = cell_size, - .h = cell_size, - }; - - //var trans: u8 = 0; var r: u8 = 0; var g: u8 = 0; var b: u8 = 0; @@ -117,13 +95,13 @@ pub fn renderHeld(self: *Self, game: Game) void { a = 50; } - rect.x = pos_x + @intCast(i32, x) * cell_size; - rect.y = pos_y + @intCast(i32, y) * cell_size; + const new_x = pos_x + @intCast(i32, x) * self.grid_cell_size; + const new_y = pos_y + @intCast(i32, y) * self.grid_cell_size; - _ = SDL.SDL_SetRenderDrawColor(self.renderer, r, g, b, a); - _ = SDL.SDL_RenderFillRect(self.renderer, &rect); - _ = SDL.SDL_SetRenderDrawColor(self.renderer, r -| 30, g -| 30, b -| 30, a); - _ = SDL.SDL_RenderDrawRect(self.renderer, &rect); + self.renderer.setColor(r, g, b, a); + self.renderer.fillRectangle(new_x, new_y, self.grid_cell_size, self.grid_cell_size); + self.renderer.setColor(r -| 30, g -| 30, b -| 30, a); + self.renderer.drawRectangle(new_x, new_y, self.grid_cell_size, self.grid_cell_size); } } } @@ -138,19 +116,8 @@ pub fn render(self: *Self, game: Game) void { } pub fn renderPiece(self: *Self, piece: Piece) void { - - const cell_size = self.grid_cell_size; const pos_x = self.grid_pos_x; const pos_y = self.grid_pos_y; - const renderer = self.renderer; - - - var rect = SDL.SDL_Rect{ - .x = pos_x, - .y = pos_y, - .w = cell_size, - .h = cell_size, - }; for (piece.structure) |_, y| { for (piece.structure[y]) |_, x| { @@ -164,34 +131,23 @@ pub fn renderPiece(self: *Self, piece: Piece) void { var b = piece.color.b; var a = piece.color.a; - rect.x = pos_x + (@intCast(i32, x) + piece.col) * cell_size; - rect.y = pos_y + (@intCast(i32, y) + piece.row) * cell_size; + const new_x = pos_x + (@intCast(i32, x) + piece.col) * self.grid_cell_size; + const new_y = pos_y + (@intCast(i32, y) + piece.row) * self.grid_cell_size; - _ = SDL.SDL_SetRenderDrawColor(renderer, r, g, b, a); - _ = SDL.SDL_RenderFillRect(renderer, &rect); - _ = SDL.SDL_SetRenderDrawColor(renderer, r -| 30, g -| 30, b -| 30, a +| 30); - _ = SDL.SDL_RenderDrawRect(renderer, &rect); + self.renderer.setColor(r, g, b, a); + self.renderer.fillRectangle(new_x, new_y, self.grid_cell_size, self.grid_cell_size); + self.renderer.setColor(r -| 30, g -| 30, b -| 30, a); + self.renderer.drawRectangle(new_x, new_y, self.grid_cell_size, self.grid_cell_size); } } } pub fn renderGrid(self: *Self, grid: Grid) void { - - const cell_size = self.grid_cell_size; const pos_x = self.grid_pos_x; const pos_y = self.grid_pos_y; - const renderer = self.renderer; + const lg = color.light_grey; - var rect = SDL.SDL_Rect{ - .x = pos_x, - .y = pos_y, - .w = cell_size, - .h = cell_size, - }; - - const buffer = Grid.buffer; - - var visible = grid.cells[buffer..]; + var visible = grid.cells[Grid.buffer..]; for (visible) |_, y| { for (visible[y]) |_, x| { var r = visible[y][x].color.r; @@ -199,13 +155,13 @@ pub fn renderGrid(self: *Self, grid: Grid) void { var b = visible[y][x].color.b; var a = visible[y][x].color.a; - rect.x = pos_x + @intCast(i32, x) * cell_size; - rect.y = pos_y + (@intCast(i32, y) + buffer) * cell_size; + const new_x = pos_x + @intCast(i32, x) * self.grid_cell_size; + const new_y = pos_y + (@intCast(i32, y) + Grid.buffer) * self.grid_cell_size; - _ = SDL.SDL_SetRenderDrawColor(renderer, r, g, b, a); - _ = SDL.SDL_RenderFillRect(renderer, &rect); - _ = SDL.SDL_SetRenderDrawColor(renderer, color.light_grey.r, color.light_grey.g, color.light_grey.b, color.light_grey.a); - _ = SDL.SDL_RenderDrawRect(renderer, &rect); + self.renderer.setColor(r, g, b, a); + self.renderer.fillRectangle(new_x, new_y, self.grid_cell_size, self.grid_cell_size); + self.renderer.setColor(lg.r, lg.g, lg.b, lg.a); + self.renderer.drawRectangle(new_x, new_y, self.grid_cell_size, self.grid_cell_size); } } } diff --git a/src/Renderer.zig b/src/Renderer.zig index 88b0941..1650595 100644 --- a/src/Renderer.zig +++ b/src/Renderer.zig @@ -1,6 +1,8 @@ const std = @import("std"); const sdl = @import("sdl2"); +const zlm = @import("zlm"); const gl = @import("zgl"); +const m = zlm.SpecializeOn(f32); const Self = @This(); @@ -16,6 +18,8 @@ pub fn init() !Self { // Set OpenGL version try sdl.gl.setAttribute(.{ .context_major_version = 3 }); try sdl.gl.setAttribute(.{ .context_minor_version = 3 }); + try sdl.gl.setAttribute(.{ .multisamplebuffers = true }); + try sdl.gl.setAttribute(.{ .multisamplesamples = 4 }); const window = try sdl.createWindow( "USG", @@ -28,6 +32,7 @@ pub fn init() !Self { const ctx = try sdl.gl.createContext(window); + var mvp_loc: u32 = undefined; var color_loc: u32 = undefined; const program = gl.Program.create(); { @@ -44,10 +49,19 @@ pub fn init() !Self { program.attach(fs); defer program.detach(fs); program.link(); + mvp_loc = program.uniformLocation("mvp").?; color_loc = program.uniformLocation("color").?; } program.use(); + var wsize = window.getSize(); + var xunit = @intToFloat(f32, wsize.width); + var yunit = @intToFloat(f32, wsize.height); + + const ortho = m.Mat4.createOrthogonal(0.0, xunit, yunit, 0.0, 0.0, 100.0); + + gl.uniformMatrix4fv(mvp_loc, false, &.{ ortho.fields }); + var vertex_array = gl.VertexArray.gen(); vertex_array.bind(); @@ -77,7 +91,7 @@ pub fn deinit(self: Self) void { sdl.gl.deleteContext(self.context); } -pub fn setColor(self: *Self, r: u8, g: u32, b: u32, a: u32) void { +pub fn setColor(self: *Self, r: u8, g: i32, b: i32, a: i32) void { self.*.color = .{ @intToFloat(f32, r)/255.0, @intToFloat(f32, g)/255.0, @@ -86,24 +100,29 @@ pub fn setColor(self: *Self, r: u8, g: u32, b: u32, a: u32) void { }; } -pub fn drawRectangle(self: *Self, x: u32, y: u32, w: u32, h: u32) void { - var wsize = self.window.getSize(); +pub fn drawRectangle(self: *Self, x: i32, y: i32, w: i32, h: i32) void { + _ = self; + _ = x; + _ = y; + _ = w; + _ = h; +} - var xunit = 2 / @intToFloat(f32, wsize.width); - var yunit = 2 / @intToFloat(f32, wsize.height); - - var xf = @intToFloat(f32, x) * xunit - 1; - var yf = 1 - @intToFloat(f32, y) * yunit; - var wf = @intToFloat(f32, w) * xunit; - var hf = @intToFloat(f32, h) * yunit; +pub fn fillRectangle(self: *Self, x: i32, y: i32, w: i32, h: i32) void { + var xf = @intToFloat(f32, x); + var yf = @intToFloat(f32, y); + var wf = @intToFloat(f32, w); + var hf = @intToFloat(f32, h); gl.enableVertexAttribArray(0); gl.vertexAttribPointer(0, 3, .float, false, 0, 0); - std.debug.print("{} {}\n", .{ xf, yf }); const vertex_buffer = [_]f32{ - xf, yf, 0.0, - xf + wf, yf, 0.0, + xf, yf , 0.0, + xf + wf, yf , 0.0, + xf, yf + hf, 0.0, + xf + wf, yf + hf, 0.0, + xf + wf, yf , 0.0, xf, yf + hf, 0.0, }; @@ -111,9 +130,16 @@ pub fn drawRectangle(self: *Self, x: u32, y: u32, w: u32, h: u32) void { gl.uniform4fv(self.color_loc, &.{ self.color }); gl.drawArrays(.triangles, 0, 3); + gl.drawArrays(.triangles, 3, 6); gl.disableVertexAttribArray(0); - - _ = xf; - _ = yf; +} + +pub const OutputSize = struct { width: c_int, height: c_int }; +pub fn getOutputSize(self: Self) OutputSize { + var wsize = self.window.getSize(); + return OutputSize{ + .width = wsize.width, + .height = wsize.height, + }; } diff --git a/src/Timer.zig b/src/Timer.zig index 039dec8..fe0b7db 100644 --- a/src/Timer.zig +++ b/src/Timer.zig @@ -19,7 +19,7 @@ pub fn init(target: u64) Self { pub fn start(self: *Self) void { self.started = true; self.progress = 0; - self.initial = SDL.SDL_GetTicks64(); + self.initial = SDL.getTicks64(); } pub fn unstop (self: *Self) void { @@ -29,7 +29,7 @@ pub fn unstop (self: *Self) void { pub fn finished(self: *Self) bool { if (self.started) { - self.progress = SDL.SDL_GetTicks64() - self.initial; + self.progress = SDL.getTicks64() - self.initial; if (self.progress >= self.target) { return true; } else return false; @@ -40,7 +40,7 @@ pub fn finished(self: *Self) bool { pub fn reset(self: *Self) void { self.progress = 0; - self.initial = SDL.SDL_GetTicks64(); + self.initial = SDL.getTicks64(); } pub fn stop(self: *Self) void { diff --git a/src/color.zig b/src/color.zig index 850c243..2185cb8 100644 --- a/src/color.zig +++ b/src/color.zig @@ -1,66 +1,66 @@ const SDL = @import("sdl2"); -pub const yellow = SDL.SDL_Color{ +pub const yellow = SDL.Color{ .r = 232, .g = 216, .b = 165, .a = 255, }; -pub const brown = SDL.SDL_Color{ +pub const brown = SDL.Color{ .r = 180, .g = 130, .b = 90, .a = 255, }; -pub const cyan = SDL.SDL_Color{ +pub const cyan = SDL.Color{ .r = 138, .g = 167, .b = 172, .a = 255, }; -pub const orange = SDL.SDL_Color{ +pub const orange = SDL.Color{ .r = 222, .g = 154, .b = 40, .a = 255, }; -pub const blue = SDL.SDL_Color{ +pub const blue = SDL.Color{ .r = 112, .g = 123, .b = 136, .a = 255, }; -pub const green = SDL.SDL_Color{ +pub const green = SDL.Color{ .r = 142, .g = 146, .b = 87, .a = 255, }; -pub const red = SDL.SDL_Color{ +pub const red = SDL.Color{ .r = 229, .g = 93, .b = 77, .a = 255, }; -pub const purple = SDL.SDL_Color{ +pub const purple = SDL.Color{ .r = 180, .g = 171, .b = 189, .a = 255, }; -pub const pink = SDL.SDL_Color{ +pub const pink = SDL.Color{ .r = 230, .g = 115, .b = 170, .a = 255, }; -pub const dark_grey = SDL.SDL_Color{ +pub const dark_grey = SDL.Color{ .r = 40, .g = 40, .b = 40, .a = 255, }; -pub const light_grey = SDL.SDL_Color{ +pub const light_grey = SDL.Color{ .r = 80, .g = 80, .b = 80, diff --git a/src/main.zig b/src/main.zig index f4efe64..8a6ab03 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,8 +1,8 @@ const std = @import("std"); -const sdl = @import("sdl2"); +const SDL = @import("sdl2"); const Renderer = @import("Renderer.zig"); -//const Game = @import("Game.zig"); +const Game = @import("Game.zig"); //const MainMenu = @import("MainMenu.zig"); //const State = @import("flow.zig").State; @@ -12,14 +12,14 @@ pub fn main() !void { defer renderer.deinit(); //var main_menu = MainMenu.init(); - //var game = Game.init(renderer); + var game = Game.init(renderer); //var current_state: State = main_menu.state; //_ = SDL.IMG_Init(SDL.IMG_INIT_JPG); mainLoop: while (true) { - while (sdl.pollEvent()) |ev| { + while (SDL.pollEvent()) |ev| { switch (ev) { .quit => break :mainLoop, else => {}, @@ -31,6 +31,8 @@ pub fn main() !void { renderer.render(); + _ = game.tick(); + //current_state = switch (current_state) { //.main_menu => main_menu.tick(), //.game => game.tick(), diff --git a/src/shaders/vector.vs b/src/shaders/vector.vs index cb16d4d..c02f467 100644 --- a/src/shaders/vector.vs +++ b/src/shaders/vector.vs @@ -1,8 +1,8 @@ #version 330 core +uniform mat4 mvp; layout(location = 0) in vec3 vertexPosition_modelspace; void main() { - gl_Position.xyz = vertexPosition_modelspace; - gl_Position.w = 1.0; + gl_Position = mvp * vec4(vertexPosition_modelspace, 1); }