forked from vv/efemra
1
0
Fork 0
efemra/src/rendering/vulkan/display.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();
}
};