git.s-ol.nu zig-imgui / 82c6a2b
add openGL3 impl (still failing) s-ol 30 days ago
2 changed file(s) with 451 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
1 const c = @import("c.zig");
2 const mem = @import("std").mem;
3 const math = @import("std").math;
4 const debug = @import("std").debug;
5 const builtin = @import("builtin");
6
7 const OpenGLHasDrawWithBaseVertex = @hasField(c, "IMGUI_IMPL_OPENGL_ES2") or
8 @hasField(c, "IMGUI_IMPL_OPENGL_ES3");
9
10 // OpenGL Data
11 var g_GlslVersionString_buf : [32]u8 = undefined;
12 var g_GlslVersionString : []u8 = g_GlslVersionString_buf[0..0];
13
14 var g_FontTexture : c.GLuint = 0;
15 var g_ShaderHandle : c.GLuint = 0;
16 var g_VertHandle : c.GLuint = 0;
17 var g_FragHandle: c.GLuint = 0;
18 var g_AttribLocationTex : c.GLint = 0;
19 var g_AttribLocationProjMtx : c.GLint = 0;
20 var g_AttribLocationVtxPos : c.GLint = 0;
21 var g_AttribLocationVtxUV : c.GLint = 0;
22 var g_AttribLocationVtxColor : c.GLint = 0;
23 var g_VboHandle : c.GLuint = 0;
24 var g_ElementsHandle : c.GLuint = 0;
25
26 pub fn Init() void {
27 const io = c.igGetIO();
28 io.*.BackendRendererName = c"imgui_impl_gl3.zig";
29 if (OpenGLHasDrawWithBaseVertex)
30 io.*.BackendFlags |= @enumToInt(c.ImGuiBackendFlags_RendererHasVtxOffset);
31 // @TODO: Viewports
32 // io.*.BackendFlags |= @enumToInt(c.ImGuiBackendFlags_RendererHasViewports);
33
34 // @TODO: GLSL versions?
35 // g_GlslVersionString = g_GlslVersionString_buf[0..glsl_version.len];
36 // mem.copy(u8, g_GlslVersionString, glsl_version);
37
38 // @FIXME: just for testing:
39 var tex : c.GLint = undefined;
40 c.glGetIntegerv(c.GL_TEXTURE_BINDING_2D, &tex);
41
42 // @TODO: Viewports
43 // if (io.*.ConfigFlags & @enumToInt(c.ImGuiConfigFlags_ViewportsEnable) != 0)
44 // InitPlatformInterface();
45 }
46
47 pub fn Shutdown() void {
48 // ImGui_ImplOpenGL3_ShutdownPlatformInterface();
49 DestroyDeviceObjects();
50 }
51
52 pub fn NewFrame() !void {
53 if (g_ShaderHandle == 0)
54 try CreateDeviceObjects();
55 }
56
57 fn CreateDeviceObjects() !void {
58 // back up GL state
59 var last_texture : c.GLint = undefined;
60 var last_array_buffer : c.GLint = undefined;
61 var last_vertex_array : c.GLint = undefined;
62
63 c.glGetIntegerv(c.GL_TEXTURE_BINDING_2D, &last_texture);
64 defer c.glBindTexture(c.GL_TEXTURE_2D, @intCast(c.GLuint, last_texture));
65
66 c.glGetIntegerv(c.GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
67 c.glBindBuffer(c.GL_ARRAY_BUFFER, @intCast(c.GLuint, last_array_buffer));
68
69 if (!@hasField(c, "IMGUI_IMPL_OPENGL_ES2"))
70 c.glGetIntegerv(c.GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
71 defer if (!@hasField(c, "IMGUI_IMPL_OPENGL_ES2"))
72 c.glBindVertexArray(@intCast(c.GLuint, last_vertex_array));
73
74 // @TODO: GLSL versions?
75 const vertex_shader_glsl : [*]const c.GLchar =
76 c\\#version 150
77 c\\uniform mat4 ProjMtx;
78 c\\in vec2 Position;
79 c\\in vec2 UV;
80 c\\in vec4 Color;
81 c\\out vec2 Frag_UV;
82 c\\out vec4 Frag_Color;
83 c\\void main()
84 c\\{
85 c\\ Frag_UV = UV;
86 c\\ Frag_Color = Color;
87 c\\ gl_Position = ProjMtx * vec4(Position.xy, 0, 1);
88 c\\}
89 ;
90
91 const fragment_shader_glsl : [*]const c.GLchar =
92 c\\#version 150
93 c\\uniform sampler2D Texture;
94 c\\in vec2 Frag_UV;
95 c\\in vec4 Frag_Color;
96 c\\out vec4 Out_Color;
97 c\\void main()
98 c\\{
99 c\\ Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
100 c\\}
101 ;
102
103 // Create shaders / programs
104 g_VertHandle = c.glCreateShader(c.GL_VERTEX_SHADER);
105 c.glShaderSource(g_VertHandle, 1, &vertex_shader_glsl, null);
106 c.glCompileShader(g_VertHandle);
107 try CheckThing(.Shader, g_VertHandle, "vertex shader");
108
109 g_FragHandle = c.glCreateShader(c.GL_FRAGMENT_SHADER);
110 c.glShaderSource(g_FragHandle, 1, &fragment_shader_glsl, null);
111 c.glCompileShader(g_FragHandle);
112 try CheckThing(.Shader, g_FragHandle, "fragment shader");
113
114 g_ShaderHandle = c.glCreateProgram();
115 c.glAttachShader(g_ShaderHandle, g_VertHandle);
116 c.glAttachShader(g_ShaderHandle, g_FragHandle);
117 c.glLinkProgram(g_ShaderHandle);
118 try CheckThing(.Program, g_ShaderHandle, "shader program");
119
120 g_AttribLocationTex = c.glGetUniformLocation(g_ShaderHandle, c"Texture");
121 g_AttribLocationProjMtx = c.glGetUniformLocation(g_ShaderHandle, c"ProjMtx");
122 g_AttribLocationVtxPos = c.glGetAttribLocation(g_ShaderHandle, c"Position");
123 g_AttribLocationVtxUV = c.glGetAttribLocation(g_ShaderHandle, c"UV");
124 g_AttribLocationVtxColor = c.glGetAttribLocation(g_ShaderHandle, c"Color");
125
126 // Create buffers
127 c.glGenBuffers(1, &g_VboHandle);
128 c.glGenBuffers(1, &g_ElementsHandle);
129
130 CreateFontsTexture();
131 }
132
133
134 const CheckableThing = enum {
135 Shader,
136 Program,
137 };
138 fn CheckThing(comptime thingType: CheckableThing, handle: c.GLuint, desc: []const u8) !void {
139 var status : c.GLint = undefined;
140 var log_length : c.GLint = undefined;
141 const getInfoLogFunc = switch (thingType) {
142 .Shader => blk: {
143 c.glGetShaderiv(handle, c.GL_COMPILE_STATUS, &status);
144 c.glGetShaderiv(handle, c.GL_INFO_LOG_LENGTH, &log_length);
145 break :blk c.glGetShaderInfoLog;
146 },
147 .Program => blk: {
148 c.glGetProgramiv(handle, c.GL_LINK_STATUS, &status);
149 c.glGetProgramiv(handle, c.GL_INFO_LOG_LENGTH, &log_length);
150 break :blk c.glGetProgramInfoLog;
151 },
152 };
153
154 if (log_length > 1)
155 {
156 var buf : [1024]u8 = undefined;
157 var length : c.GLsizei = undefined;
158 getInfoLogFunc(handle, buf.len, &length, &buf[0]);
159 debug.warn("{}\n", buf[0..@intCast(usize, length)]);
160 }
161
162 if (@intCast(c.GLboolean, status) == c.GL_FALSE) {
163 debug.warn("ERROR: CreateDeviceObjects: failed to compile/link {}! (with GLSL '{}')\n", desc, g_GlslVersionString);
164 return error.ShaderLinkError;
165 }
166 }
167
168 fn DestroyDeviceObjects() void {
169 if (g_VboHandle != 0) {
170 c.glDeleteBuffers(1, &g_VboHandle);
171 g_VboHandle = 0;
172 }
173
174 if (g_ElementsHandle != 0) {
175 c.glDeleteBuffers(1, &g_ElementsHandle);
176 g_ElementsHandle = 0;
177 }
178
179 if (g_ShaderHandle != 0 and g_VertHandle != 0)
180 c.glDetachShader(g_ShaderHandle, g_VertHandle);
181
182 if (g_ShaderHandle != 0 and g_FragHandle != 0)
183 c.glDetachShader(g_ShaderHandle, g_FragHandle);
184
185 if (g_VertHandle != 0) {
186 c.glDeleteShader(g_VertHandle);
187 g_VertHandle = 0;
188 }
189
190 if (g_FragHandle != 0) {
191 c.glDeleteShader(g_FragHandle);
192 g_FragHandle = 0;
193 }
194
195 if (g_ShaderHandle != 0) {
196 c.glDeleteProgram(g_ShaderHandle);
197 g_ShaderHandle = 0;
198 }
199
200 DestroyFontsTexture();
201 }
202
203 fn CreateFontsTexture() void {
204 const io = c.igGetIO();
205
206 // Get current font image data
207 var width : c_int = undefined;
208 var height : c_int = undefined;
209 var pixels : [*c]u8 = undefined;
210 c.ImFontAtlas_GetTexDataAsRGBA32(io.*.Fonts, &pixels, &width, &height, null);
211
212 // backup & restore state
213 var last_texture : c.GLint = undefined;
214 c.glGetIntegerv(c.GL_TEXTURE_BINDING_2D, &last_texture);
215 defer c.glBindTexture(c.GL_TEXTURE_2D, @intCast(c.GLuint, last_texture));
216
217 // Upload texture to graphics system
218 c.glGenTextures(1, &g_FontTexture);
219 c.glBindTexture(c.GL_TEXTURE_2D, g_FontTexture);
220 c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MIN_FILTER, c.GL_LINEAR);
221 c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MAG_FILTER, c.GL_LINEAR);
222 if (@hasField(c, "GL_UNPACK_ROW_LENGTH"))
223 c.glPixelStorei(c.GL_UNPACK_ROW_LENGTH, 0);
224 c.glTexImage2D(c.GL_TEXTURE_2D, 0, c.GL_RGBA, width, height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, pixels);
225
226 // Store texture ID
227 io.*.Fonts.*.TexID = @intToPtr(c.ImTextureID, g_FontTexture);
228 }
229
230 fn DestroyFontsTexture() void {
231 if (g_FontTexture == 0)
232 return;
233
234 const io = c.igGetIO();
235 c.glDeleteTextures(1, &g_FontTexture);
236 io.*.Fonts.*.TexID = @intToPtr(c.ImTextureID, 0);
237 g_FontTexture = 0;
238 }
239
240 pub fn RenderDrawData(draw_data : *c.ImDrawData) void {
241 // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
242 const fb_width = @floatToInt(i32, draw_data.*.DisplaySize.x * draw_data.*.FramebufferScale.x);
243 const fb_height = @floatToInt(i32, draw_data.*.DisplaySize.y * draw_data.*.FramebufferScale.y);
244 if (fb_width <= 0 or fb_height <= 0)
245 return;
246
247 // Backup GL state
248 var last_program : c.GLint = undefined;
249 var last_texture : c.GLint = undefined;
250 var last_sampler : c.GLint = undefined;
251 var last_array_buffer : c.GLint = undefined;
252 var last_vertex_array_object : c.GLint = undefined;
253 var last_polygon_mode : [2]c.GLint = undefined;
254 var last_viewport : [4]c.GLint = undefined;
255 var last_scissor_box : [4]c.GLint = undefined;
256 var last_blend_src_rgb : c.GLint = undefined;
257 var last_blend_dst_rgb : c.GLint = undefined;
258 var last_blend_src_alpha : c.GLint = undefined;
259 var last_blend_dst_alpha : c.GLint = undefined;
260 var last_blend_equation_rgb : c.GLint = undefined;
261 var last_blend_equation_alpha : c.GLint = undefined;
262 var clip_origin_lower_left : bool = true;
263 var last_clip_origin : c.GLint = 0;
264 var last_active_texture : c.GLint = undefined;
265
266 c.glGetIntegerv(c.GL_ACTIVE_TEXTURE, &last_active_texture);
267 c.glActiveTexture(c.GL_TEXTURE0);
268 c.glGetIntegerv(c.GL_CURRENT_PROGRAM, &last_program);
269 c.glGetIntegerv(c.GL_TEXTURE_BINDING_2D, &last_texture);
270 if (@hasField(c, "GL_SAMPLER_BINDING"))
271 c.glGetIntegerv(c.GL_SAMPLER_BINDING, &last_sampler);
272 c.glGetIntegerv(c.GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
273 if (!@hasField(c, "IMGUI_IMPL_OPENc.GL_ES2"))
274 c.glGetIntegerv(c.GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object);
275 if (@hasField(c, "GL_POLYGON_MODE"))
276 c.glGetIntegerv(c.GL_POLYGON_MODE, last_polygon_mode);
277 c.glGetIntegerv(c.GL_VIEWPORT, &last_viewport[0]);
278 c.glGetIntegerv(c.GL_SCISSOR_BOX, &last_scissor_box[0]);
279 c.glGetIntegerv(c.GL_BLEND_SRC_RGB, &last_blend_src_rgb);
280 c.glGetIntegerv(c.GL_BLEND_DST_RGB, &last_blend_dst_rgb);
281 c.glGetIntegerv(c.GL_BLEND_SRC_ALPHA, &last_blend_src_alpha);
282 c.glGetIntegerv(c.GL_BLEND_DST_ALPHA, &last_blend_dst_alpha);
283 c.glGetIntegerv(c.GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb);
284 c.glGetIntegerv(c.GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha);
285 var last_enable_blend : c.GLboolean = c.glIsEnabled(c.GL_BLEND);
286 var last_enable_cull_face : c.GLboolean = c.glIsEnabled(c.GL_CULL_FACE);
287 var last_enable_depth_test : c.GLboolean = c.glIsEnabled(c.GL_DEPTH_TEST);
288 var last_enable_scissor_test : c.GLboolean = c.glIsEnabled(c.GL_SCISSOR_TEST);
289 if (@hasField(c, "GL_CLIP_ORIGIN") and builtin.os != builtin.Os.osx) {
290 // Support for GL 4.5's glClipControl(GL_UPPER_LEFT)
291 c.glGetIntegerv(c.GL_CLIP_ORIGIN, &last_clip_origin);
292 if (last_clip_origin == c.GL_UPPER_LEFT)
293 clip_origin_lower_left = false;
294 }
295
296 defer {
297 // Restore modified GL state
298 c.glUseProgram(@intCast(c.GLuint, last_program));
299 c.glBindTexture(c.GL_TEXTURE_2D, @intCast(c.GLuint, last_texture));
300 if (@hasField(c, "GL_SAMPLER_BINDING"))
301 c.glBindSampler(0, @intCast(c.GLuint, last_sampler));
302 c.glActiveTexture(@intCast(c.GLuint, last_active_texture));
303 if (!@hasField(c, "IMGUI_IMPL_OPENGL_ES2"))
304 c.glBindVertexArray(@intCast(c.GLuint, last_vertex_array_object));
305 c.glBindBuffer(c.GL_ARRAY_BUFFER, @intCast(c.GLuint, last_array_buffer));
306 c.glBlendEquationSeparate(@intCast(c.GLuint, last_blend_equation_rgb), @intCast(c.GLuint, last_blend_equation_alpha));
307 c.glBlendFuncSeparate(@intCast(c.GLuint, last_blend_src_rgb),
308 @intCast(c.GLuint, last_blend_dst_rgb),
309 @intCast(c.GLuint, last_blend_src_alpha),
310 @intCast(c.GLuint, last_blend_dst_alpha));
311 if (last_enable_blend == c.GL_TRUE) { c.glEnable(c.GL_BLEND); }
312 else { c.glDisable(c.GL_BLEND); }
313 if (last_enable_cull_face == c.GL_TRUE) { c.glEnable(c.GL_CULL_FACE); }
314 else { c.glDisable(c.GL_CULL_FACE); }
315 if (last_enable_depth_test == c.GL_TRUE) { c.glEnable(c.GL_DEPTH_TEST); }
316 else { c.glDisable(c.GL_DEPTH_TEST); }
317 if (last_enable_scissor_test == c.GL_TRUE) { c.glEnable(c.GL_SCISSOR_TEST); }
318 else { c.glDisable(c.GL_SCISSOR_TEST); }
319 if (@hasField(c, "GL_POLYGON_MODE"))
320 c.glPolygonMode(c.GL_FRONT_AND_BACK, @intCast(c.GLenum, last_polygon_mode[0]));
321 c.glViewport(last_viewport[0], last_viewport[1], @intCast(c.GLsizei, last_viewport[2]), @intCast(c.GLsizei, last_viewport[3]));
322 c.glScissor(last_scissor_box[0], last_scissor_box[1], @intCast(c.GLsizei, last_scissor_box[2]), @intCast(c.GLsizei, last_scissor_box[3]));
323 }
324
325 // Setup desired GL state
326 // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
327 // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
328 var vertex_array_object : c.GLuint = 0;
329 if (!@hasField(c, "IMGUI_IMPL_OPENGL_ES2"))
330 c.glGenVertexArrays(1, &vertex_array_object);
331 defer if (!@hasField(c, "IMGUI_IMPL_OPENGL_ES2"))
332 c.glDeleteVertexArrays(1, &vertex_array_object);
333
334 SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
335
336 // Will project scissor/clipping rectangles into framebuffer space
337 const clip_off = draw_data.*.DisplayPos; // (0,0) unless using multi-viewports
338 const clip_scale = draw_data.*.FramebufferScale; // (1,1) unless using retina display which are often (2,2)
339
340 // Render command lists
341 var n : usize = 0;
342 while (n < @intCast(usize, draw_data.*.CmdListsCount)) : (n += 1) {
343 const cmd_list = draw_data.*.CmdLists[n];
344
345 // Upload vertex/index buffers
346 c.glBufferData(c.GL_ARRAY_BUFFER, cmd_list.*.VtxBuffer.Size * @sizeOf(c.ImDrawVert), @ptrCast(?*c.GLvoid, cmd_list.*.VtxBuffer.Data), c.GL_STREAM_DRAW);
347 c.glBufferData(c.GL_ELEMENT_ARRAY_BUFFER, cmd_list.*.IdxBuffer.Size * @sizeOf(c.ImDrawIdx), @ptrCast(*c.GLvoid, cmd_list.*.IdxBuffer.Data), c.GL_STREAM_DRAW);
348
349 var cmd_i : usize = 0;
350 while (cmd_i < @intCast(usize, cmd_list.*.CmdBuffer.Size)) : (cmd_i += 1) {
351 const pcmd = &cmd_list.*.CmdBuffer.Data[cmd_i];
352
353 if (pcmd.*.UserCallback != null) {
354 // User callback, registered via ImDrawList::AddCallback()
355 // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
356 const ImDrawCallback_ResetRenderState = @intToPtr(c.ImDrawCallback, math.maxInt(usize));
357 if (pcmd.*.UserCallback == ImDrawCallback_ResetRenderState) {
358 SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
359 } else {
360 if (pcmd.*.UserCallback) |callback| {
361 callback(cmd_list, pcmd);
362 } else {
363 unreachable;
364 }
365 }
366 } else {
367 // Project scissor/clipping rectangles into framebuffer space
368 var clip_rect : c.ImVec4 = undefined;
369 clip_rect.x = (pcmd.*.ClipRect.x - clip_off.x) * clip_scale.x;
370 clip_rect.y = (pcmd.*.ClipRect.y - clip_off.y) * clip_scale.y;
371 clip_rect.z = (pcmd.*.ClipRect.z - clip_off.x) * clip_scale.x;
372 clip_rect.w = (pcmd.*.ClipRect.w - clip_off.y) * clip_scale.y;
373
374 if (clip_rect.x < @intToFloat(f32, fb_width) and clip_rect.y < @intToFloat(f32, fb_height)
375 and clip_rect.z >= 0.0 and clip_rect.w >= 0.0) {
376 // Apply scissor/clipping rectangle
377 if (clip_origin_lower_left) {
378 c.glScissor(@floatToInt(c.GLint, clip_rect.x), fb_height - @floatToInt(c.GLint, clip_rect.w),
379 @floatToInt(c.GLint, clip_rect.z - clip_rect.x), @floatToInt(c.GLint, clip_rect.w - clip_rect.y));
380 } else {
381 // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
382 c.glScissor(@floatToInt(c.GLint, clip_rect.x), @floatToInt(c.GLint, clip_rect.y),
383 @floatToInt(c.GLint, clip_rect.z), @floatToInt(c.GLint, clip_rect.w));
384 }
385
386 // Bind texture, Draw
387 c.glBindTexture(c.GL_TEXTURE_2D, @intCast(c.GLuint, @ptrToInt(pcmd.*.TextureId)));
388 const drawIndexSize = @sizeOf(c.ImDrawIdx);
389 const drawIndexType = if (drawIndexSize == 2) c.GL_UNSIGNED_SHORT else c.GL_UNSIGNED_INT;
390 const offset = @intToPtr(?*c.GLvoid, pcmd.*.IdxOffset * drawIndexSize);
391 if (@hasField(c, "IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX")) {
392 c.glDrawElementsBaseVertex(c.GL_TRIANGLES, @intCast(c.GLsizei, pcmd.*.ElemCount), drawIndexType, offset, @intCast(c.GLint, pcmd.*.VtxOffset));
393 } else {
394 c.glDrawElements(c.GL_TRIANGLES, @intCast(c.GLsizei, pcmd.*.ElemCount), drawIndexType, offset);
395 }
396 }
397 }
398 }
399 }
400 }
401
402 fn SetupRenderState(draw_data: *c.ImDrawData, fb_width: i32, fb_height: i32, vertex_array_object: c.GLuint) void {
403 // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
404 c.glEnable(c.GL_BLEND);
405 c.glBlendEquation(c.GL_FUNC_ADD);
406 c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
407 c.glDisable(c.GL_CULL_FACE);
408 c.glDisable(c.GL_DEPTH_TEST);
409 c.glEnable(c.GL_SCISSOR_TEST);
410 if (@hasField(c, "GL_POLYGON_MODE"))
411 c.glPolygonMode(c.GL_FRONT_AND_BACK, c.GL_FILL);
412
413 // Setup viewport, orthographic projection matrix
414 // Our visible imgui space lies from draw_data.*.DisplayPos (top left) to draw_data.*.DisplayPos+data_data.*.DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
415 c.glViewport(0, 0, @intCast(c.GLsizei, fb_width), @intCast(c.GLsizei, fb_height));
416 const L = draw_data.*.DisplayPos.x;
417 const R = draw_data.*.DisplayPos.x + draw_data.*.DisplaySize.x;
418 const T = draw_data.*.DisplayPos.y;
419 const B = draw_data.*.DisplayPos.y + draw_data.*.DisplaySize.y;
420 const ortho_projection = [4][4]f32{
421 [_]f32{ 2.0/(R-L), 0.0, 0.0, 0.0 },
422 [_]f32{ 0.0, 2.0/(T-B), 0.0, 0.0 },
423 [_]f32{ 0.0, 0.0, -1.0, 0.0 },
424 [_]f32{ (R+L)/(L-R), (T+B)/(B-T), 0.0, 1.0 },
425 };
426 c.glUniform1i(g_AttribLocationTex, 0);
427 c.glUniformMatrix4fv(g_AttribLocationProjMtx, 1, c.GL_FALSE, &ortho_projection[0][0]);
428 if (@hasField(c, "GL_SAMPLER_BINDING"))
429 c.glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
430
431 if (!@hasField(c, "IMGUI_IMPL_OPENGL_ES2"))
432 c.glBindVertexArray(vertex_array_object);
433
434 // Bind vertex/index buffers and setup attributes for ImDrawVert
435 c.glBindBuffer(c.GL_ARRAY_BUFFER, g_VboHandle);
436 c.glBindBuffer(c.GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
437 c.glEnableVertexAttribArray(@intCast(c.GLuint, g_AttribLocationVtxPos));
438 c.glEnableVertexAttribArray(@intCast(c.GLuint, g_AttribLocationVtxUV));
439 c.glEnableVertexAttribArray(@intCast(c.GLuint, g_AttribLocationVtxColor));
440 c.glVertexAttribPointer(@intCast(c.GLuint, g_AttribLocationVtxPos), 2, c.GL_FLOAT, c.GL_FALSE, @sizeOf(c.ImDrawVert), @intToPtr(?*c.GLvoid, @byteOffsetOf(c.ImDrawVert, "pos")));
441 c.glVertexAttribPointer(@intCast(c.GLuint, g_AttribLocationVtxUV), 2, c.GL_FLOAT, c.GL_FALSE, @sizeOf(c.ImDrawVert), @intToPtr(?*c.GLvoid, @byteOffsetOf(c.ImDrawVert, "uv")));
442 c.glVertexAttribPointer(@intCast(c.GLuint, g_AttribLocationVtxColor), 4, c.GL_UNSIGNED_BYTE, c.GL_TRUE, @sizeOf(c.ImDrawVert), @intToPtr(?*c.GLvoid, @byteOffsetOf(c.ImDrawVert, "col")));
443 }
22 const std = @import("std");
33 const panic = std.debug.panic;
44 const glfw_impl = @import("glfw_impl.zig");
5 const gl3_impl = @import("gl3_impl.zig");
56
67 extern fn errorCallback(err: c_int, description: [*c]const u8) void {
78 panic("Error: {}\n", description);
910
1011 var window: *c.GLFWwindow = undefined;
1112
12 pub fn main() void {
13 pub fn main() !void {
1314 _ = c.glfwSetErrorCallback(errorCallback);
1415
1516 if (c.glfwInit() == c.GL_FALSE) {
4243
4344 const io = c.igGetIO();
4445 io.*.ConfigFlags |= @enumToInt(c.ImGuiConfigFlags_NavEnableKeyboard);
45 io.*.ConfigFlags |= @enumToInt(c.ImGuiConfigFlags_DockingEnable);
46 io.*.ConfigFlags |= @enumToInt(c.ImGuiConfigFlags_ViewportsEnable);
46 // io.*.ConfigFlags |= @enumToInt(c.ImGuiConfigFlags_DockingEnable);
47 // io.*.ConfigFlags |= @enumToInt(c.ImGuiConfigFlags_ViewportsEnable);
4748
4849 const style = c.igGetStyle();
4950 c.igStyleColorsDark(style);
5657 glfw_impl.Init(window, true, glfw_impl.ClientApi.OpenGL);
5758 defer glfw_impl.Shutdown();
5859
59 // ImGui_ImplOpenGL3_Init(glsl_version);
60 gl3_impl.Init(); // #version 150
61 defer gl3_impl.Shutdown();
6062
6163 const start_time = c.glfwGetTime();
6264 var prev_time = start_time;
6466 while (c.glfwWindowShouldClose(window) == c.GL_FALSE) {
6567 c.glfwPollEvents();
6668
69 try gl3_impl.NewFrame();
6770 glfw_impl.NewFrame();
68 // gl3_impl.NewFrame();
6971 c.igNewFrame();
7072
7173 // main part
7880 c.glViewport(0, 0, w, h);
7981 c.glClearColor(0.0, 0.0, 0.0, 0.0);
8082 c.glClear(c.GL_COLOR_BUFFER_BIT);
81 // gl3_impl.RenderDrawData(c.igGetDrawData());
83 gl3_impl.RenderDrawData(c.igGetDrawData());
8284
8385 // const now_time = c.glfwGetTime();
8486 // const elapsed = now_time - prev_time;