volviewer

Volumetric Data Toy Viewer
git clone anongit@rnpnr.xyz:volviewer.git
Log | Files | Refs | Feed | LICENSE

util.h (7616B)


      1 /* See LICENSE for license details. */
      2 #ifndef _UTIL_H_
      3 #define _UTIL_H_
      4 
      5 #include <stddef.h>
      6 #include <stdint.h>
      7 
      8 #ifndef asm
      9 #define asm __asm__
     10 #endif
     11 
     12 #ifndef typeof
     13 #define typeof __typeof__
     14 #endif
     15 
     16 #define alignof _Alignof
     17 
     18 #if COMPILER_CLANG || COMPILER_GCC
     19   #define force_inline inline __attribute__((always_inline))
     20   #define unreachable() __builtin_unreachable()
     21 #elif COMPILER_MSVC
     22   #define force_inline  __forceinline
     23   #define unreachable() __assume(0)
     24 #endif
     25 
     26 #if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS)
     27   #pragma section(".rdata$", read)
     28   #define read_only __declspec(allocate(".rdata$"))
     29 #elif COMPILER_CLANG
     30   #define read_only __attribute__((section(".rodata")))
     31 #elif COMPILER_GCC
     32   /* TODO(rnp): how do we do this with gcc, putting it in rodata causes warnings and writing to
     33    * it doesn't cause a fault */
     34   #define read_only
     35 #endif
     36 
     37 /* TODO(rnp): msvc probably won't build this but there are other things preventing that as well */
     38 #define sqrt_f32(a)     __builtin_sqrtf(a)
     39 #define atan2_f32(y, x) __builtin_atan2f(y, x)
     40 #define sin_f32(x)      __builtin_sinf(x)
     41 #define cos_f32(x)      __builtin_cosf(x)
     42 #define tan_f32(x)      __builtin_tanf(x)
     43 
     44 #if ARCH_ARM64
     45   /* TODO? debuggers just loop here forever and need a manual PC increment (step over) */
     46   #define debugbreak() asm volatile ("brk 0xf000")
     47 #elif ARCH_X64
     48   #define debugbreak() asm volatile ("int3; nop")
     49 #endif
     50 
     51 #ifdef _DEBUG
     52 	#ifdef OS_WINDOWS
     53 		#define DEBUG_EXPORT __declspec(dllexport)
     54 	#else
     55 		#define DEBUG_EXPORT
     56 	#endif
     57 	#define DEBUG_DECL(a) a
     58 	#define assert(c) do { if (!(c)) debugbreak(); } while (0)
     59 #else
     60 	#define DEBUG_EXPORT function
     61 	#define DEBUG_DECL(a)
     62 	#define assert(c)
     63 #endif
     64 
     65 #define InvalidCodePath assert(0)
     66 #define InvalidDefaultCase default: assert(0); break
     67 
     68 #define function      static
     69 #define global        static
     70 #define local_persist static
     71 
     72 #define static_assert _Static_assert
     73 
     74 /* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */
     75 #define str_(...) #__VA_ARGS__
     76 #define str(...) str_(__VA_ARGS__)
     77 
     78 #define countof(a)       (sizeof(a) / sizeof(*a))
     79 #define ARRAY_COUNT(a)   (sizeof(a) / sizeof(*a))
     80 #define ABS(x)           ((x) < 0 ? (-x) : (x))
     81 #define BETWEEN(x, a, b) ((x) >= (a) && (x) <= (b))
     82 #define CLAMP(x, a, b)   ((x) < (a) ? (a) : (x) > (b) ? (b) : (x))
     83 #define CLAMP01(x)       CLAMP(x, 0, 1)
     84 #define ISPOWEROF2(a)    (((a) & ((a) - 1)) == 0)
     85 #define MIN(a, b)        ((a) < (b) ? (a) : (b))
     86 #define MAX(a, b)        ((a) > (b) ? (a) : (b))
     87 #define ORONE(x)         ((x)? (x) : 1)
     88 #define SIGN(x)          ((x) < 0? -1 : 1)
     89 #define SWAP(a, b)       {typeof(a) __tmp = (a); (a) = (b); (b) = __tmp;}
     90 
     91 /* NOTE(rnp): no guarantees about actually getting an element */
     92 #define SLLPop(list)     list; list = list ? list->next : 0
     93 #define SLLPush(v, list) do { \
     94 	(v)->next = (list); \
     95 	(list)    = v;      \
     96 } while (0)
     97 
     98 #define DLLPushDown(v, list) do { \
     99 	(v)->next = (list);                   \
    100 	if ((v)->next) (v)->next->prev = (v); \
    101 	(list) = (v);                         \
    102 } while (0)
    103 
    104 #define DLLRemove(v) do { \
    105 	if ((v)->next) (v)->next->prev = (v)->prev; \
    106 	if ((v)->prev) (v)->prev->next = (v)->next; \
    107 } while (0)
    108 
    109 #define KB(a)            ((u64)(a) << 10ULL)
    110 #define MB(a)            ((u64)(a) << 20ULL)
    111 #define GB(a)            ((u64)(a) << 30ULL)
    112 
    113 #define I32_MAX          (0x7FFFFFFFL)
    114 #define U32_MAX          (0xFFFFFFFFUL)
    115 #define F32_INFINITY     (__builtin_inff())
    116 
    117 #define PI (3.14159265358979323846)
    118 
    119 #define INVALID_FILE (-1)
    120 
    121 typedef char      c8;
    122 typedef uint8_t   u8;
    123 typedef int16_t   s16;
    124 typedef uint16_t  u16;
    125 typedef int32_t   s32;
    126 typedef uint32_t  u32;
    127 typedef int64_t   s64;
    128 typedef uint64_t  u64;
    129 typedef uint32_t  b32;
    130 typedef float     f32;
    131 typedef double    f64;
    132 typedef ptrdiff_t sz;
    133 typedef size_t    uz;
    134 typedef ptrdiff_t sptr;
    135 typedef size_t    uptr;
    136 
    137 typedef struct { u8 *beg, *end; } Arena;
    138 
    139 typedef struct { sz len; u8 *data; } str8;
    140 #define str8(s) (str8){.len = ARRAY_COUNT(s) - 1, .data = (u8 *)s}
    141 
    142 typedef struct { sz len; u16 *data; } str16;
    143 
    144 typedef struct { u32 cp, consumed; } UnicodeDecode;
    145 
    146 typedef union {
    147 	struct { s32 x, y; };
    148 	struct { s32 w, h; };
    149 	s32 E[2];
    150 } sv2;
    151 
    152 typedef union {
    153 	struct { s32 x, y, z; };
    154 	struct { s32 w, h, d; };
    155 	sv2 xy;
    156 	s32 E[3];
    157 } sv3;
    158 
    159 typedef union {
    160 	struct { u32 x, y; };
    161 	struct { u32 w, h; };
    162 	u32 E[2];
    163 } uv2;
    164 
    165 typedef union {
    166 	struct { u32 x, y, z; };
    167 	struct { u32 w, h, d; };
    168 	uv2 xy;
    169 	u32 E[3];
    170 } uv3;
    171 
    172 typedef union {
    173 	struct { u32 x, y, z, w; };
    174 	struct { uv3 xyz; u32 _w; };
    175 	u32 E[4];
    176 } uv4;
    177 
    178 typedef union {
    179 	struct { f32 x, y; };
    180 	struct { f32 w, h; };
    181 	f32 E[2];
    182 } v2;
    183 
    184 typedef union {
    185 	struct { f32 x, y, z; };
    186 	struct { f32 w, h, d; };
    187 	f32 E[3];
    188 } v3;
    189 
    190 typedef union {
    191 	struct { f32 x, y, z, w; };
    192 	struct { f32 r, g, b, a; };
    193 	struct { v3 xyz; f32 _1; };
    194 	struct { f32 _2; v3 yzw; };
    195 	struct { v2 xy, zw; };
    196 	f32 E[4];
    197 } v4;
    198 
    199 #define XZ(v) (v2){.x = v.x, .y = v.z}
    200 #define YZ(v) (v2){.x = v.y, .y = v.z}
    201 #define XY(v) (v2){.x = v.x, .y = v.y}
    202 
    203 typedef union {
    204 	struct { v4 x, y, z, w; };
    205 	v4  c[4];
    206 	f32 E[16];
    207 } m4;
    208 
    209 typedef struct { v2 pos, size; } Rect;
    210 #define INVERTED_INFINITY_RECT (Rect){.pos  = {.x = -F32_INFINITY, .y = -F32_INFINITY}, \
    211                                       .size = {.x = -F32_INFINITY, .y = -F32_INFINITY}}
    212 
    213 typedef struct {
    214 	u8   *data;
    215 	u32   widx;
    216 	u32   cap;
    217 	b32   errors;
    218 } Stream;
    219 
    220 typedef struct OS OS;
    221 
    222 #define FILE_WATCH_CALLBACK_FN(name) b32 name(OS *os, str8 path, sptr user_data, Arena tmp)
    223 typedef FILE_WATCH_CALLBACK_FN(file_watch_callback);
    224 
    225 typedef struct {
    226 	sptr user_data;
    227 	u64  hash;
    228 	file_watch_callback *callback;
    229 } FileWatch;
    230 
    231 typedef struct {
    232 	u64       hash;
    233 	sptr      handle;
    234 	str8      name;
    235 
    236 	FileWatch *data;
    237 	sz         count;
    238 	sz         capacity;
    239 	Arena      buffer;
    240 } FileWatchDirectory;
    241 
    242 typedef struct {
    243 	FileWatchDirectory *data;
    244 	sz    count;
    245 	sz    capacity;
    246 	sptr  handle;
    247 } FileWatchContext;
    248 
    249 #define OS_ALLOC_ARENA_FN(name) Arena name(sz capacity)
    250 typedef OS_ALLOC_ARENA_FN(os_alloc_arena_fn);
    251 
    252 #define OS_ADD_FILE_WATCH_FN(name) void name(OS *os, Arena *a, str8 path, \
    253                                              file_watch_callback *callback, sptr user_data)
    254 typedef OS_ADD_FILE_WATCH_FN(os_add_file_watch_fn);
    255 
    256 #define OS_READ_WHOLE_FILE_FN(name) str8 name(Arena *arena, char *file)
    257 typedef OS_READ_WHOLE_FILE_FN(os_read_whole_file_fn);
    258 
    259 #define OS_WRITE_NEW_FILE_FN(name) b32 name(char *fname, str8 raw)
    260 typedef OS_WRITE_NEW_FILE_FN(os_write_new_file_fn);
    261 
    262 #define OS_WRITE_FILE_FN(name) b32 name(sptr file, str8 raw)
    263 typedef OS_WRITE_FILE_FN(os_write_file_fn);
    264 
    265 struct OS {
    266 	FileWatchContext file_watch_context;
    267 	sptr             context;
    268 	sptr             error_handle;
    269 };
    270 
    271 typedef struct {
    272 	u32 shader;
    273 	u32 vao;
    274 	u32 vbo;
    275 } RenderContext;
    276 
    277 typedef struct {
    278 	u32 fb;
    279 	u32 textures[2];
    280 	sv2 size;
    281 } RenderTarget;
    282 
    283 typedef struct {
    284 	sptr elements_offset;
    285 	s32  elements;
    286 	u32  buffer;
    287 	u32  vao;
    288 } RenderModel;
    289 
    290 typedef struct {
    291 	Arena arena;
    292 	OS    os;
    293 
    294 	RenderContext model_render_context;
    295 	RenderContext overlay_render_context;
    296 
    297 	RenderTarget multisample_target;
    298 	RenderTarget output_target;
    299 	RenderModel  unit_cube;
    300 
    301 	sv2 window_size;
    302 
    303 	b32 demo_mode;
    304 	f32 cycle_t;
    305 	f32 camera_angle;
    306 	f32 camera_fov;
    307 	f32 camera_radius;
    308 	v3  camera_position;
    309 
    310 	u32 output_frames_count;
    311 
    312 	f32 last_time;
    313 	b32 do_update;
    314 
    315 	b32 should_exit;
    316 
    317 	Arena video_arena;
    318 	sz    video_arena_offset;
    319 
    320 	void *window;
    321 } ViewerContext;
    322 
    323 #define LABEL_GL_OBJECT(type, id, s) {str8 _s = (s); glObjectLabel(type, id, _s.len, (c8 *)_s.data);}
    324 
    325 #include "util.c"
    326 
    327 #endif /* _UTIL_H_ */