-
Notifications
You must be signed in to change notification settings - Fork 21
/
example_glfw.zig
129 lines (104 loc) · 4.02 KB
/
example_glfw.zig
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
const std = @import("std");
const builtin = @import("builtin");
const c = @cImport({
@cInclude("glad/glad.h");
@cInclude("GLFW/glfw3.h");
});
const Demo = @import("demo.zig");
const PerfGraph = @import("perf.zig");
const nvg = @import("nanovg");
var blowup: bool = false;
var screenshot: bool = false;
var premult: bool = false;
fn keyCallback(window: ?*c.GLFWwindow, key: c_int, scancode: c_int, action: c_int, mods: c_int) callconv(.C) void {
_ = scancode;
_ = mods;
if (key == c.GLFW_KEY_ESCAPE and action == c.GLFW_PRESS)
c.glfwSetWindowShouldClose(window, c.GL_TRUE);
if (key == c.GLFW_KEY_SPACE and action == c.GLFW_PRESS)
blowup = !blowup;
if (key == c.GLFW_KEY_S and action == c.GLFW_PRESS)
screenshot = true;
if (key == c.GLFW_KEY_P and action == c.GLFW_PRESS)
premult = !premult;
}
pub fn main() !void {
var window: ?*c.GLFWwindow = null;
var prevt: f64 = 0;
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = if (builtin.mode == .Debug) gpa.allocator() else std.heap.c_allocator;
if (c.glfwInit() == c.GLFW_FALSE) {
return error.GLFWInitFailed;
}
defer c.glfwTerminate();
c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MAJOR, 2);
c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MINOR, 0);
c.glfwWindowHint(c.GLFW_SAMPLES, 4);
const monitor = c.glfwGetPrimaryMonitor();
var scale: f32 = 1;
if (!builtin.target.isDarwin()) {
c.glfwGetMonitorContentScale(monitor, &scale, null);
}
window = c.glfwCreateWindow(@as(i32, @intFromFloat(scale * 1000)), @as(i32, @intFromFloat(scale * 600)), "NanoVG", null, null);
if (window == null) {
return error.GLFWInitFailed;
}
defer c.glfwDestroyWindow(window);
_ = c.glfwSetKeyCallback(window, keyCallback);
c.glfwMakeContextCurrent(window);
if (c.gladLoadGL() == 0) {
return error.GLADInitFailed;
}
var vg = try nvg.gl.init(allocator, .{
.debug = true,
});
defer vg.deinit();
var demo: Demo = undefined;
demo.load(vg);
defer demo.free(vg);
var fps = PerfGraph.init(.fps, "Frame Time");
c.glfwSwapInterval(0);
c.glfwSetTime(0);
prevt = c.glfwGetTime();
while (c.glfwWindowShouldClose(window) == c.GLFW_FALSE) {
const t = c.glfwGetTime();
const dt = t - prevt;
prevt = t;
fps.update(@floatCast(dt));
var mx: f64 = undefined;
var my: f64 = undefined;
c.glfwGetCursorPos(window, &mx, &my);
mx /= scale;
my /= scale;
var win_width: i32 = undefined;
var win_height: i32 = undefined;
c.glfwGetWindowSize(window, &win_width, &win_height);
win_width = @intFromFloat(@as(f32, @floatFromInt(win_width)) / scale);
win_height = @intFromFloat(@as(f32, @floatFromInt(win_height)) / scale);
var fb_width: i32 = undefined;
var fb_height: i32 = undefined;
c.glfwGetFramebufferSize(window, &fb_width, &fb_height);
// Calculate pixel ratio for hi-dpi devices.
const pxRatio = @as(f32, @floatFromInt(fb_width)) / @as(f32, @floatFromInt(win_width));
// Update and render
c.glViewport(0, 0, fb_width, fb_height);
if (premult) {
c.glClearColor(0, 0, 0, 0);
} else {
c.glClearColor(0.3, 0.3, 0.32, 1.0);
}
c.glClear(c.GL_COLOR_BUFFER_BIT | c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT);
vg.beginFrame(@floatFromInt(win_width), @floatFromInt(win_height), pxRatio);
demo.draw(vg, @floatCast(mx), @floatCast(my), @floatFromInt(win_width), @floatFromInt(win_height), @floatCast(t), blowup);
fps.draw(vg, 5, 5);
vg.endFrame();
if (screenshot) {
screenshot = false;
const data = try Demo.saveScreenshot(allocator, fb_width, fb_height, premult);
defer allocator.free(data);
try std.fs.cwd().writeFile(.{ .sub_path = "dump.png", .data = data });
}
c.glfwSwapBuffers(window);
c.glfwPollEvents();
}
}