const Engine = @This(); const std = @import("std"); const Recti = @import("geometry/Recti.zig"); const Matrix4f = @import("geometry/Matrix4f.zig"); const shaders = @import("shaders.zig"); const Texture = @import("Texture.zig"); const Sprite = @import("Sprite.zig"); const Layer = @import("Layer.zig"); const Color = @import("Color.zig"); const Scene = @import("Scene.zig"); const assets = @import("assets.zig"); const c = @cImport({ @cInclude("glad/glad.h"); @cInclude("GLFW/glfw3.h"); }); const HashMap = std.HashMap; // export const IGame = struct { // render: fn () void, // update: fn (f32) void, // }; current_scene: Scene, pub fn create(initial_scene: Scene) Engine { return .{ .current_scene = initial_scene }; } fn errorCallback(err: c_int, desc_c: [*c]const u8) callconv(.C) void { const desc: *const u8 = @ptrCast(desc_c); std.log.err("glfw error {x:0>8}: {s}", .{ err, desc }); } // export fn run(game: *const IGame) !void { pub fn run(self: *Engine) !void { // in case of errors, set callback early! // for some reason this returns an error function as well?? _ = c.glfwSetErrorCallback(errorCallback); // initialize glfw capabilities & cleanup if (c.glfwInit() != 1) { std.log.err("Failed to init glfw", .{}); return error.Initialization; } defer c.glfwTerminate(); // ensure glfw knows what we're about // c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MAJOR, 3); c.glfwDefaultWindowHints(); c.glfwWindowHint(c.GLFW_SAMPLES, 4); // c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MINOR, 3); // c.glfwWindowHint(c.GLFW_OPENGL_PROFILE, c.GLFW_OPENGL_CORE_PROFILE); // create the window & cleanup const window = c.glfwCreateWindow(640, 480, "My Title", null, null) orelse { std.log.err("Failed to open window", .{}); return error.Initialization; }; defer c.glfwDestroyWindow(window); // load opengl into the window c.glfwMakeContextCurrent(window); if (c.gladLoadGL() != 1) { std.log.err("Failed to load GL context", .{}); return error.Initialization; } // configure the context! c.glfwSwapInterval(1); // compile shaders... try shaders.load(); try assets.load(); const clearBrightness: f32 = 0.09; c.glClearColor(clearBrightness, clearBrightness, clearBrightness, 1.0); // c.glEnable(c.GL_MULTISAMPLE); c.glDisable(c.GL_MULTISAMPLE); c.glEnable(c.GL_BLEND); c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA); c.glEnable(c.GL_DEPTH_TEST); c.glDepthFunc(c.GL_LEQUAL); c.glDepthMask(c.GL_TRUE); var width: c_int = undefined; var height: c_int = undefined; c.glfwGetFramebufferSize(window, @ptrCast(&width), @ptrCast(&height)); const projection = Matrix4f.orthographic(0, @floatFromInt(width), @floatFromInt(height), 0, 0, 100); // run the main loop while (c.glfwWindowShouldClose(window) == 0) { shaders.set_projection_matrix(&projection); c.glClear(c.GL_COLOR_BUFFER_BIT | c.GL_DEPTH_BUFFER_BIT); self.current_scene.draw(); // game.render(); // game.update(1.0); c.glfwSwapBuffers(window); c.glfwPollEvents(); self.current_scene.update(0.0042); } }