1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
const c = @import("c.zig");
const std = @import("std");
const cfg = @import("config.zig");
const gl = @import("gl.zig");
pub const Output = struct {
update: fn (*Output, c.GLuint) bool,
destroy: fn (*Output) void,
fn init(update: fn (*Output, c.GLuint) bool, destroy: fn (*Output) void) Output {
return Output{
.update = update,
.destroy = destroy,
};
}
pub fn create(allocator: *std.mem.Allocator, config: cfg.OutputConfig, constants: *gl.Constants) *Output {
return switch (config.type) {
cfg.OutputType.window => WindowOutput.create(allocator, config, constants),
else => unreachable,
};
}
};
pub const WindowOutput = struct {
output: Output,
window: *c.GLFWwindow,
constants: *gl.Constants,
pub fn create(allocator: *std.mem.Allocator, config: cfg.OutputConfig, constants: *gl.Constants) *Output {
const self = allocator.create(WindowOutput) catch unreachable;
c.glfwDefaultWindowHints();
self.* = WindowOutput{
.constants = constants,
.output = Output.init(update, destroy),
.window = c.glfwCreateWindow(config.width, config.height, "glsl-view output", null, constants.main_window) orelse {
std.debug.panic("unable to create output window\n", .{});
},
};
c.glfwSetWindowUserPointer(self.*.window, @ptrCast(*c_void, self));
_ = c.glfwSetKeyCallback(self.*.window, keyCallback);
c.glfwMakeContextCurrent(self.*.window);
constants.normalizedQuad.bind(0);
return &self.*.output;
}
fn update(output: *Output, texture_id: c.GLuint) bool {
const self = @fieldParentPtr(WindowOutput, "output", output);
if (c.glfwWindowShouldClose(self.*.window) == c.GL_TRUE)
return true;
c.glfwMakeContextCurrent(self.*.window);
c.glClear(c.GL_COLOR_BUFFER_BIT);
c.glBindTexture(c.GL_TEXTURE_2D, texture_id);
c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4);
self.constants.textureShader.bind();
self.constants.normalizedQuad.draw();
c.glfwSwapBuffers(self.*.window);
return false;
}
fn destroy(output: *Output) void {
const self = @fieldParentPtr(WindowOutput, "output", output);
c.glfwDestroyWindow(self.*.window);
}
extern fn keyCallback(win: ?*c.GLFWwindow, key: c_int, scancode: c_int, action: c_int, mods: c_int) callconv(.C) void {
if (action != c.GLFW_PRESS) return;
const self = @ptrCast(*WindowOutput, @alignCast(@alignOf(WindowOutput), c.glfwGetWindowUserPointer(win).?));
std.debug.warn("key pressed: {}\n", .{ key });
switch (key) {
// c.GLFW_KEY_F => // toggle fullscreen
// c.GLFW_KEY_LEFT => // cycle through monitors
// c.GLFW_KEY_RIGHT => // cycle through monitors
else => {},
}
}
};
|