forked from fabioarnold/nanovg-zig
-
Notifications
You must be signed in to change notification settings - Fork 1
/
example_glfw.zig
131 lines (106 loc) · 3.98 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
130
131
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 = gpa.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);
const monitor = c.glfwGetPrimaryMonitor();
var scale: f32 = 1;
if (!builtin.target.isDarwin()) {
c.glfwGetMonitorContentScale(monitor, &scale, null);
}
window = c.glfwCreateWindow(@floatToInt(i32, scale * 1000), @floatToInt(i32, 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, .{
.antialias = true,
.stencil_strokes = false,
.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(f32, 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 = @floatToInt(i32, @intToFloat(f32, win_width) / scale);
win_height = @floatToInt(i32, @intToFloat(f32, 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 = @intToFloat(f32, fb_width) / @intToFloat(f32, 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);
_ = dt;
vg.beginFrame(@intToFloat(f32, win_width), @intToFloat(f32, win_height), pxRatio);
demo.draw(vg, @floatCast(f32, mx), @floatCast(f32, my), @intToFloat(f32, win_width), @intToFloat(f32, win_height), @floatCast(f32, 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("dump.png", data);
}
c.glfwSwapBuffers(window);
c.glfwPollEvents();
}
}