122 lines
3.6 KiB
Zig
122 lines
3.6 KiB
Zig
const std = @import("std");
|
|
const glfw = @import("glfw");
|
|
const vk = @import("vulkan");
|
|
const Renderer = @import("Renderer.zig");
|
|
const Instance = @import("instance.zig").Instance;
|
|
|
|
// TODO memory
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
const allocator = gpa.allocator();
|
|
|
|
pub const Display = struct {
|
|
pub fn getWorkSize() !glfw.Window.Size {
|
|
try glfw.init(.{});
|
|
|
|
const monitor = try glfw.Monitor.getPrimary() orelse error.NoPrimaryMonitor;
|
|
const work_area = try monitor.getWorkarea();
|
|
|
|
if (work_area.width <= 0 or work_area.height <= 0) {
|
|
return error.WorkareaNotReady;
|
|
}
|
|
|
|
return glfw.Window.Size{
|
|
.width = work_area.width,
|
|
.height = work_area.height,
|
|
};
|
|
}
|
|
|
|
pub fn getFullSize() !glfw.Window.Size {
|
|
try glfw.init(.{});
|
|
|
|
const monitor = try glfw.Monitor.getPrimary() orelse error.NoPrimaryMonitor;
|
|
const modes = try monitor.getVideoModes(allocator);
|
|
defer allocator.free(modes);
|
|
if (modes.len <= 0) {
|
|
return error.NoModes;
|
|
}
|
|
|
|
var chosenArea: ?u32 = null;
|
|
var chosenMode: ?*const glfw.VideoMode = null;
|
|
for (modes) |mode| {
|
|
const area = mode.getWidth() * mode.getHeight();
|
|
if (area > chosenArea orelse 0) {
|
|
chosenArea = area;
|
|
chosenMode = &mode;
|
|
}
|
|
}
|
|
|
|
if (chosenArea == null) {
|
|
return error.NoModes;
|
|
}
|
|
|
|
return glfw.Window.Size{
|
|
.width = (chosenMode orelse unreachable).getWidth(),
|
|
.height = (chosenMode orelse unreachable).getHeight(),
|
|
};
|
|
}
|
|
|
|
pub fn getSize(fullscreen: bool) !glfw.Window.Size {
|
|
return if (fullscreen) try getFullSize() else try getWorkSize();
|
|
}
|
|
};
|
|
|
|
pub const Window = struct {
|
|
const Self = @This();
|
|
|
|
fullscreen: bool,
|
|
handle: glfw.Window,
|
|
size: glfw.Window.Size,
|
|
surface: vk.SurfaceKHR,
|
|
|
|
pub fn init(instance: *const Instance, title: [*:0]const u8, width: u32, height: u32, fullscreen: bool) !Self {
|
|
try glfw.init(.{});
|
|
const handle = try glfw.Window.create(width, height, title, try glfw.Monitor.getPrimary() orelse error.NoPrimaryMonitor, null, .{
|
|
.client_api = .no_api,
|
|
.srgb_capable = true,
|
|
.auto_iconify = !fullscreen,
|
|
.maximized = !fullscreen,
|
|
});
|
|
errdefer handle.destroy();
|
|
|
|
// TODO: input: register window
|
|
var surface: vk.SurfaceKHR = undefined;
|
|
_ = try glfw.createWindowSurface(instance.handle, handle, null, &surface);
|
|
|
|
return Self{
|
|
.fullscreen = fullscreen,
|
|
.handle = handle,
|
|
.size = try handle.getFramebufferSize(),
|
|
.surface = surface,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: *const Self, instance: *const Instance) void {
|
|
instance.dispatch.destroySurfaceKHR(instance.handle, self.surface, null);
|
|
self.handle.destroy();
|
|
}
|
|
|
|
pub fn updateSize(self: *Self) !bool {
|
|
const prevSize = self.size;
|
|
self.size = try self.handle.getFramebufferSize();
|
|
|
|
const changed = prevSize.width != self.size.width or prevSize.height != self.size.height;
|
|
return changed;
|
|
}
|
|
|
|
pub fn getPosition(self: *Self) !glfw.Pos {
|
|
return try self.handle.getPos();
|
|
}
|
|
|
|
pub fn setPosition(self: *Self, pos: glfw.Pos) !glfw.Pos {
|
|
return try self.handle.setPos(pos);
|
|
}
|
|
|
|
pub fn isOpen(self: *Self) !bool {
|
|
return try self.handle.shouldClose();
|
|
}
|
|
|
|
pub fn poll() !void {
|
|
return try glfw.pollEvents();
|
|
}
|
|
};
|