libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
glutils.h
Go to the documentation of this file.
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license in the file COPYING
10 * or http://www.opensource.org/licenses/CDDL-1.0.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file COPYING.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2023 Saso Kiselkov. All rights reserved.
24 */
34#ifndef _ACF_UTILS_GLUTILS_H_
35#define _ACF_UTILS_GLUTILS_H_
36
37#include <stdio.h>
38
39#include "assert.h"
40#include "geom.h"
41#include "glew.h"
42#include "glutils_zink.h"
43#include "log.h"
44#include "safe_alloc.h"
45#include "sysmacros.h"
46
47#include <cglm/cglm.h>
48
49#ifdef __cplusplus
50extern "C" {
51#endif
52
53#ifdef __AVX__
54#define MAT4_ALLOC_ALIGN 32
55#else
56#define MAT4_ALLOC_ALIGN 16
57#endif
58
79typedef struct {
80 GLuint vao;
81 GLuint vbo;
82 GLuint ibo;
83 bool_t setup;
84 size_t num_vtx;
86
98typedef struct {
99 GLuint vao;
100 GLuint vbo;
101 bool_t setup;
102 size_t num_vtx;
104
105typedef struct glutils_cache_s glutils_cache_t;
106
115typedef void (*glutils_texsz_enum_cb_t)(const char *token, int64_t bytes,
116 void *userinfo);
117
118API_EXPORT void glutils_sys_init(void);
119
120API_EXPORT void glutils_disable_all_client_state(void);
121API_EXPORT void glutils_disable_all_vtx_attrs(void);
122
123API_EXPORT GLuint glutils_make_quads_IBO(size_t num_vtx);
124
132static inline bool_t
134{
135 ASSERT(quads != NULL);
136 return (quads->vbo != 0);
137}
138
144#define glutils_init_2D_quads(__quads, __p, __t, __num_pts) \
145 glutils_init_2D_quads_impl((__quads), log_basename(__FILE__), \
146 __LINE__, (__p), (__t), (__num_pts))
147API_EXPORT void glutils_init_2D_quads_impl(glutils_quads_t *quads,
148 const char *filename, int line, const vect2_t *p, const vect2_t *t,
149 size_t num_pts);
150
152#define glutils_update_2D_quads(__quads, __p, __t, __num_pts) \
153 glutils_update_2D_quads_impl((__quads), log_basename(__FILE__), \
154 __LINE__, (__p), (__t), (__num_pts))
155API_EXPORT void glutils_update_2D_quads_impl(glutils_quads_t *quads,
156 const char *filename, int line, const vect2_t *p, const vect2_t *t,
157 size_t num_pts);
170#define glutils_init_3D_quads(__quads, __p, __t, __num_pts) \
171 glutils_init_3D_quads_impl((__quads), log_basename(__FILE__), \
172 __LINE__, (__p), (__t), (__num_pts))
173API_EXPORT void glutils_init_3D_quads_impl(glutils_quads_t *quads,
174 const char *filename, int line, const vect3_t *p, const vect2_t *t,
175 size_t num_pts);
183#define glutils_update_3D_quads(__quads, __p, __t, __num_pts) \
184 glutils_update_3D_quads_impl((__quads), log_basename(__FILE__), \
185 __LINE__, (__p), (__t), (__num_pts))
186API_EXPORT void glutils_update_3D_quads_impl(glutils_quads_t *quads,
187 const char *filename, int line, const vect3_t *p, const vect2_t *t,
188 size_t num_pts);
189
190API_EXPORT void glutils_destroy_quads(glutils_quads_t *quads);
191API_EXPORT void glutils_draw_quads(glutils_quads_t *quads, GLint prog);
209#define glutils_init_3D_lines(__lines, __p, __num_pts) \
210 glutils_init_3D_lines_impl((__lines), log_basename(__FILE__), \
211 __LINE__, (__p), (__num_pts))
212API_EXPORT void glutils_init_3D_lines_impl(glutils_lines_t *lines,
213 const char *filename, int line, const vect3_t *p, size_t num_pts);
214
215API_EXPORT void glutils_destroy_lines(glutils_lines_t *lines);
216API_EXPORT void glutils_draw_lines(glutils_lines_t *lines, GLint prog);
217
218/*
219 * glutils cache is a generic quads/lines object cache.
220 */
221API_EXPORT glutils_cache_t *glutils_cache_new(size_t cap_bytes);
222API_EXPORT void glutils_cache_destroy(glutils_cache_t *cache);
224 glutils_cache_t *cache, const vect2_t *p, const vect2_t *t, size_t num_pts);
226 glutils_cache_t *cache, const vect3_t *p, const vect2_t *t, size_t num_pts);
228 glutils_cache_t *cache, const vect3_t *p, size_t num_pts);
229
230API_EXPORT void glutils_vp2pvm(GLfloat pvm[16]);
231
232#define GLUTILS_VALIDATE_INDICES(indices, num_idx, num_vtx) \
233 do { \
234 for (unsigned i = 0; i < (num_idx); i++) { \
235 VERIFY_MSG((indices)[i] < (num_vtx), "invalid index " \
236 "specification encountered, index %d (value %d) " \
237 "is outside of vertex range %d", i, (indices)[i], \
238 (num_vtx)); \
239 } \
240 } while (0)
241
296#define TEXSZ_MK_TOKEN(name) \
297 static const char *__texsz_token_ ## name = #name
303#define TEXSZ_DECL_TOKEN_GLOB(name) \
304 extern const char *__texsz_token_ ## name
310#define TEXSZ_DEF_TOKEN_GLOB(name) \
311 const char *__texsz_token_ ## name = #name
326#define TEXSZ_ALLOC(__token_id, __format, __type, __w, __h) \
327 TEXSZ_ALLOC_INSTANCE(__token_id, NULL, NULL, -1, (__format), \
328 (__type), (__w), (__h))
334#define TEXSZ_FREE(__token_id, __format, __type, __w, __h) \
335 TEXSZ_FREE_INSTANCE(__token_id, NULL, (__format), \
336 (__type), (__w), (__h))
361#define TEXSZ_ALLOC_INSTANCE(__token_id, __instance, __filename, __line, \
362 __format, __type, __w, __h) \
363 glutils_texsz_alloc(__texsz_token_ ## __token_id, (__instance), \
364 (__filename), (__line), (__format), (__type), (__w), (__h))
373#define TEXSZ_FREE_INSTANCE(__token_id, __instance, __format, __type, \
374 __w, __h) \
375 glutils_texsz_free(__texsz_token_ ## __token_id, (__instance), \
376 (__format), (__type), (__w), (__h))
383#define TEXSZ_ALLOC_BYTES(__token_id, __bytes) \
384 TEXSZ_ALLOC_BYTES_INSTANCE(__token_id, NULL, NULL, -1, (__bytes))
390#define TEXSZ_FREE_BYTES(__token_id, __bytes) \
391 TEXSZ_FREE_BYTES_INSTANCE(__token_id, NULL, (__bytes))
398#define TEXSZ_ALLOC_BYTES_INSTANCE(__token_id, __instance, __filename, \
399 __line, __bytes) \
400 glutils_texsz_alloc_bytes(__texsz_token_ ## __token_id, (__instance), \
401 (__filename), (__line), (__bytes))
408#define TEXSZ_FREE_BYTES_INSTANCE(__token_id, __instance, __bytes) \
409 glutils_texsz_free_bytes(__texsz_token_ ## __token_id, (__instance), \
410 (__bytes))
411
412API_EXPORT void glutils_texsz_init(void);
413API_EXPORT void glutils_texsz_fini(void);
414API_EXPORT void glutils_texsz_alloc(const char *token, const void *instance,
415 const char *filename, int line, GLenum format, GLenum type,
416 unsigned w, unsigned h);
417API_EXPORT void glutils_texsz_free(const char *token, const void *instance,
418 GLenum format, GLenum type, unsigned w, unsigned h);
419API_EXPORT void glutils_texsz_alloc_bytes(const char *token,
420 const void *instance, const char *filename, int line, int64_t bytes);
421API_EXPORT void glutils_texsz_free_bytes(const char *token,
422 const void *instance, int64_t bytes);
423
424API_EXPORT uint64_t glutils_texsz_get(void);
425API_EXPORT void glutils_texsz_enum(glutils_texsz_enum_cb_t cb, void *userinfo);
426
434#define IF_TEXSZ(__xxx) \
435 do { \
436 if (glutils_texsz_inited()) { \
437 __xxx; \
438 } \
439 } while (0)
440API_EXPORT bool_t glutils_texsz_inited(void);
441
442#ifndef _LACF_RENDER_DEBUG
450#define _LACF_RENDER_DEBUG 0
451#endif
452
493#if _LACF_RENDER_DEBUG
494#define GLUTILS_ASSERT_NO_ERROR() VERIFY3U(glGetError(), ==, GL_NO_ERROR)
495#define GLUTILS_ASSERT(_x_) VERIFY(_x_)
496#define GLUTILS_ASSERT_MSG(_x_, ...) VERIFY(_x_, __VA_ARGS__)
497#define GLUTILS_ASSERT3S(_x_, _y_, _z_) VERIFY3S(_x_, _y_, _z_)
498#define GLUTILS_ASSERT3U(_x_, _y_, _z_) VERIFY3U(_x_, _y_, _z_)
499#define GLUTILS_ASSERT3P(_x_, _y_, _z_) VERIFY3P(_x_, _y_, _z_)
500#define GLUTILS_RESET_ERRORS() glutils_reset_errors()
501#else /* !_LACF_RENDER_DEBUG */
502#define GLUTILS_ASSERT_NO_ERROR()
503#define GLUTILS_ASSERT(_x_)
504#define GLUTILS_ASSERT_MSG(_x_, ...)
505#define GLUTILS_ASSERT3S(_x_, _y_, _z_)
506#define GLUTILS_ASSERT3U(_x_, _y_, _z_)
507#define GLUTILS_ASSERT3P(_x_, _y_, _z_)
508#define GLUTILS_RESET_ERRORS()
509#endif /* !_LACF_RENDER_DEBUG */
510
511API_EXPORT bool_t glutils_nsight_debugger_present(void);
512
517static inline void
519{
520 while (glGetError() != GL_NO_ERROR)
521 ;
522}
523
551/*
552 * MacOS doesn't support OpenGL 4.3.
553 */
554#if _LACF_RENDER_DEBUG && !APL
555
556PRINTF_ATTR(2) static inline void
557glutils_debug_push(GLuint msgid, const char *format, ...)
558{
559 char buf_stack[128];
560 int len;
561 va_list ap;
562
563 va_start(ap, format);
564 len = vsnprintf(buf_stack, sizeof (buf_stack), format, ap);
565 va_end(ap);
566
567 if (len >= (int)sizeof (buf_stack)) {
568 char *buf_heap = (char *)safe_malloc(len + 1);
569
570 va_start(ap, format);
571 vsnprintf(buf_heap, len + 1, format, ap);
572 va_end(ap);
573
574 glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, msgid, len,
575 buf_heap);
576
577 free(buf_heap);
578 } else {
579 glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, msgid, len,
580 buf_stack);
581 }
582}
583
584static inline void
586{
587 glPopDebugGroup();
588}
589
590#else /* !_LACF_RENDER_DEBUG || APL */
591
592ALWAYS_INLINE_ATTR PRINTF_ATTR(2) static inline void
593glutils_debug_push(GLuint msgid, const char *format, ...)
594{
595 LACF_UNUSED(msgid);
596 LACF_UNUSED(format);
597 /* no-op */
598}
599
600ALWAYS_INLINE_ATTR static inline void
602{
603 /* no-op */
604}
605
606#endif /* !_LACF_RENDER_DEBUG || APL */
607
608typedef struct glutils_nl_s glutils_nl_t;
609
610API_EXPORT glutils_nl_t *glutils_nl_alloc_2D(const vec2 *pts, size_t num_pts);
611API_EXPORT glutils_nl_t *glutils_nl_alloc_3D(const vec3 *pts, size_t num_pts);
612API_EXPORT void glutils_nl_free(glutils_nl_t *nl);
613API_EXPORT void glutils_nl_draw(glutils_nl_t *nl, float width, GLuint prog);
614
630static inline void
631glutils_enable_vtx_attr_ptr(GLint index, GLint size, GLenum type,
632 GLboolean normalized, size_t stride, size_t offset)
633{
634 if (index != -1) {
635 glEnableVertexAttribArray(index);
636 glVertexAttribPointer(index, size, type, normalized,
637 stride, (void *)offset);
638 }
639}
640
648static inline void
650{
651 if (index != -1)
652 glDisableVertexAttribArray(index);
653}
654
655API_EXPORT bool_t glutils_png2gltexfmt(int png_color_type, int png_bit_depth,
656 GLint *int_fmt, GLint *fmt, GLint *type);
657
658#ifdef __cplusplus
659}
660#endif
661
662#endif /* _ACF_UTILS_GLUTILS_H_ */
#define ASSERT(x)
Definition assert.h:208
void glutils_nl_draw(glutils_nl_t *nl, float width, GLuint prog)
Definition glutils.c:1333
static void glutils_reset_errors(void)
Definition glutils.h:518
void glutils_texsz_init(void)
Definition glutils.c:814
static void glutils_disable_vtx_attr_ptr(GLint index)
Definition glutils.h:649
uint64_t glutils_texsz_get(void)
Definition glutils.c:1039
void glutils_draw_lines(glutils_lines_t *lines, GLint prog)
Definition glutils.c:727
glutils_nl_t * glutils_nl_alloc_3D(const vec3 *pts, size_t num_pts)
Definition glutils.c:1179
void glutils_texsz_alloc(const char *token, const void *instance, const char *filename, int line, GLenum format, GLenum type, unsigned w, unsigned h)
Definition glutils.c:984
bool_t glutils_nsight_debugger_present(void)
Definition glutils.c:1076
void glutils_sys_init(void)
Definition glutils.c:108
glutils_nl_t * glutils_nl_alloc_2D(const vec2 *pts, size_t num_pts)
Definition glutils.c:1144
void glutils_update_3D_quads_impl(glutils_quads_t *quads, const char *filename, int line, const vect3_t *p, const vect2_t *t, size_t num_pts)
Definition glutils.c:270
void glutils_init_3D_quads_impl(glutils_quads_t *quads, const char *filename, int line, const vect3_t *p, const vect2_t *t, size_t num_pts)
Definition glutils.c:239
bool_t glutils_texsz_inited(void)
Definition glutils.c:1066
void glutils_init_2D_quads_impl(glutils_quads_t *quads, const char *filename, int line, const vect2_t *p, const vect2_t *t, size_t num_pts)
Definition glutils.c:209
void glutils_destroy_lines(glutils_lines_t *lines)
Definition glutils.c:742
void glutils_cache_destroy(glutils_cache_t *cache)
Definition glutils.c:484
static void glutils_debug_pop(void)
Definition glutils.h:601
static void glutils_debug_push(GLuint msgid, const char *format,...)
Definition glutils.h:593
void glutils_init_3D_lines_impl(glutils_lines_t *lines, const char *filename, int line, const vect3_t *p, size_t num_pts)
Definition glutils.c:666
void glutils_disable_all_vtx_attrs(void)
Definition glutils.c:158
void glutils_destroy_quads(glutils_quads_t *quads)
Definition glutils.c:313
glutils_quads_t * glutils_cache_get_2D_quads(glutils_cache_t *cache, const vect2_t *p, const vect2_t *t, size_t num_pts)
Definition glutils.c:613
static bool_t glutils_quads_inited(const glutils_quads_t *quads)
Definition glutils.h:133
glutils_lines_t * glutils_cache_get_3D_lines(glutils_cache_t *cache, const vect3_t *p, size_t num_pts)
Definition glutils.c:652
void(* glutils_texsz_enum_cb_t)(const char *token, int64_t bytes, void *userinfo)
Definition glutils.h:115
void glutils_update_2D_quads_impl(glutils_quads_t *quads, const char *filename, int line, const vect2_t *p, const vect2_t *t, size_t num_pts)
Definition glutils.c:225
glutils_quads_t * glutils_cache_get_3D_quads(glutils_cache_t *cache, const vect3_t *p, const vect2_t *t, size_t num_pts)
Definition glutils.c:638
GLuint glutils_make_quads_IBO(size_t num_vtx)
Definition glutils.c:176
static void glutils_enable_vtx_attr_ptr(GLint index, GLint size, GLenum type, GLboolean normalized, size_t stride, size_t offset)
Definition glutils.h:631
void glutils_draw_quads(glutils_quads_t *quads, GLint prog)
Definition glutils.c:387
void glutils_disable_all_client_state(void)
Definition glutils.c:128
bool_t glutils_png2gltexfmt(int png_color_type, int png_bit_depth, GLint *int_fmt, GLint *fmt, GLint *type)
Definition glutils.c:1416
void glutils_texsz_fini(void)
Definition glutils.c:833
void glutils_texsz_enum(glutils_texsz_enum_cb_t cb, void *userinfo)
Definition glutils.c:1052
void glutils_texsz_alloc_bytes(const char *token, const void *instance, const char *filename, int line, int64_t bytes)
Definition glutils.c:1014
glutils_cache_t * glutils_cache_new(size_t cap_bytes)
Definition glutils.c:440
void glutils_texsz_free_bytes(const char *token, const void *instance, int64_t bytes)
Definition glutils.c:1028
void glutils_texsz_free(const char *token, const void *instance, GLenum format, GLenum type, unsigned w, unsigned h)
Definition glutils.c:1000
void glutils_vp2pvm(GLfloat pvm[16])
Definition glutils.c:762
void glutils_nl_free(glutils_nl_t *nl)
Definition glutils.c:1241
static void * safe_malloc(size_t size)
Definition safe_alloc.h:56
Definition geom.h:89