1 /*
2 * This software is licensed under the terms of the MIT License.
3 * See COPYING for further information.
4 * ---
5 * Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
6 * Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
7 */
8
9 #ifndef IGUARD_renderer_api_h
10 #define IGUARD_renderer_api_h
11
12 #include "taisei.h"
13
14 #include "util.h"
15 #include "util/pixmap.h"
16 #include "color.h"
17 #include "common/shaderlib/shaderlib.h"
18 #include "resource/resource.h"
19
20 typedef struct Texture Texture;
21 typedef struct Framebuffer Framebuffer;
22 typedef struct VertexBuffer VertexBuffer;
23 typedef struct VertexArray VertexArray;
24 typedef struct IndexBuffer IndexBuffer;
25 typedef struct ShaderObject ShaderObject;
26 typedef struct ShaderProgram ShaderProgram;
27 typedef struct Sprite Sprite;
28 typedef struct Model Model;
29
30 enum {
31 R_DEBUG_LABEL_SIZE = 128,
32 R_NUM_SPRITE_AUX_TEXTURES = 3,
33 };
34
35 typedef enum RendererFeature {
36 RFEAT_DRAW_INSTANCED,
37 RFEAT_DRAW_INSTANCED_BASE_INSTANCE,
38 RFEAT_DEPTH_TEXTURE,
39 RFEAT_FRAMEBUFFER_MULTIPLE_OUTPUTS,
40 RFEAT_TEXTURE_BOTTOMLEFT_ORIGIN,
41
42 NUM_RFEATS,
43 } RendererFeature;
44
45 typedef uint_fast8_t r_feature_bits_t;
46
47 typedef enum RendererCapability {
48 RCAP_DEPTH_TEST,
49 RCAP_DEPTH_WRITE,
50 RCAP_CULL_FACE,
51
52 NUM_RCAPS
53 } RendererCapability;
54
55 typedef uint_fast8_t r_capability_bits_t;
56
57 typedef enum TextureType {
58 // NOTE: whichever is placed first here is considered the "default" where applicable.
59 TEX_TYPE_RGBA_8,
60 TEX_TYPE_RGB_8,
61 TEX_TYPE_RG_8,
62 TEX_TYPE_R_8,
63
64 TEX_TYPE_RGBA_16,
65 TEX_TYPE_RGB_16,
66 TEX_TYPE_RG_16,
67 TEX_TYPE_R_16,
68
69 TEX_TYPE_RGBA_16_FLOAT,
70 TEX_TYPE_RGB_16_FLOAT,
71 TEX_TYPE_RG_16_FLOAT,
72 TEX_TYPE_R_16_FLOAT,
73
74 TEX_TYPE_RGBA_32_FLOAT,
75 TEX_TYPE_RGB_32_FLOAT,
76 TEX_TYPE_RG_32_FLOAT,
77 TEX_TYPE_R_32_FLOAT,
78
79 TEX_TYPE_DEPTH_8,
80 TEX_TYPE_DEPTH_16,
81 TEX_TYPE_DEPTH_24,
82 TEX_TYPE_DEPTH_32,
83 TEX_TYPE_DEPTH_16_FLOAT,
84 TEX_TYPE_DEPTH_32_FLOAT,
85
86 TEX_TYPE_RGBA = TEX_TYPE_RGBA_8,
87 TEX_TYPE_RGB = TEX_TYPE_RGB_8,
88 TEX_TYPE_RG = TEX_TYPE_RG_8,
89 TEX_TYPE_R = TEX_TYPE_R_8,
90 TEX_TYPE_DEPTH = TEX_TYPE_DEPTH_8,
91 } TextureType;
92
93 typedef enum TextureFilterMode {
94 // NOTE: whichever is placed first here is considered the "default" where applicable.
95 TEX_FILTER_LINEAR,
96 TEX_FILTER_LINEAR_MIPMAP_NEAREST,
97 TEX_FILTER_LINEAR_MIPMAP_LINEAR,
98 TEX_FILTER_NEAREST,
99 TEX_FILTER_NEAREST_MIPMAP_NEAREST,
100 TEX_FILTER_NEAREST_MIPMAP_LINEAR,
101 } TextureFilterMode;
102
103 typedef enum TextureWrapMode {
104 // NOTE: whichever is placed first here is considered the "default" where applicable.
105 TEX_WRAP_REPEAT,
106 TEX_WRAP_MIRROR,
107 TEX_WRAP_CLAMP,
108 } TextureWrapMode;
109
110 typedef enum TextureMipmapMode {
111 TEX_MIPMAP_MANUAL,
112 TEX_MIPMAP_AUTO,
113 } TextureMipmapMode;
114
115 enum {
116 TEX_ANISOTROPY_DEFAULT = 1,
117 // TEX_MIPMAPS_MAX = ((uint)(-1)),
118 // pedantic out-of-range warning
119 #define TEX_MIPMAPS_MAX ((uint)(-1))
120 };
121
122 typedef struct TextureParams {
123 uint width;
124 uint height;
125 TextureType type;
126
127 struct {
128 TextureFilterMode mag;
129 TextureFilterMode min;
130 } filter;
131
132 struct {
133 TextureWrapMode s;
134 TextureWrapMode t;
135 } wrap;
136
137 uint anisotropy;
138 uint mipmaps;
139 TextureMipmapMode mipmap_mode;
140 bool stream;
141 } attr_designated_init TextureParams;
142
143 typedef enum FramebufferAttachment {
144 FRAMEBUFFER_ATTACH_DEPTH,
145 FRAMEBUFFER_ATTACH_COLOR0,
146 FRAMEBUFFER_ATTACH_COLOR1,
147 FRAMEBUFFER_ATTACH_COLOR2,
148 FRAMEBUFFER_ATTACH_COLOR3,
149
150 FRAMEBUFFER_MAX_COLOR_ATTACHMENTS = 4,
151 FRAMEBUFFER_MAX_ATTACHMENTS = FRAMEBUFFER_ATTACH_COLOR0 + FRAMEBUFFER_MAX_COLOR_ATTACHMENTS,
152 } FramebufferAttachment;
153
154 typedef enum Primitive {
155 PRIM_POINTS,
156 PRIM_LINE_STRIP,
157 PRIM_LINE_LOOP,
158 PRIM_LINES,
159 PRIM_TRIANGLE_STRIP,
160 PRIM_TRIANGLES,
161 } Primitive;
162
163 typedef enum VertexAttribType {
164 VA_FLOAT,
165 VA_BYTE,
166 VA_UBYTE,
167 VA_SHORT,
168 VA_USHORT,
169 VA_INT,
170 VA_UINT,
171 } VertexAttribType;
172
173 typedef struct VertexAttribTypeInfo {
174 size_t size;
175 size_t alignment;
176 } VertexAttribTypeInfo;
177
178 typedef enum VertexAttribConversion {
179 VA_CONVERT_FLOAT,
180 VA_CONVERT_FLOAT_NORMALIZED,
181 VA_CONVERT_INT,
182 } VertexAttribConversion;
183
184 typedef struct VertexAttribSpec {
185 uint8_t elements;
186 VertexAttribType type;
187 VertexAttribConversion coversion;
188 uint divisor;
189 } VertexAttribSpec;
190
191 typedef struct VertexAttribFormat {
192 VertexAttribSpec spec;
193 size_t stride;
194 size_t offset;
195 uint attachment;
196 } VertexAttribFormat;
197
198 typedef struct GenericModelVertex {
199 float position[3];
200 float normal[3];
201
202 struct {
203 float s;
204 float t;
205 } uv;
206 } GenericModelVertex;
207
208 typedef enum UniformType {
209 UNIFORM_FLOAT,
210 UNIFORM_VEC2,
211 UNIFORM_VEC3,
212 UNIFORM_VEC4,
213 UNIFORM_INT,
214 UNIFORM_IVEC2,
215 UNIFORM_IVEC3,
216 UNIFORM_IVEC4,
217 UNIFORM_SAMPLER,
218 UNIFORM_MAT3,
219 UNIFORM_MAT4,
220 UNIFORM_UNKNOWN,
221 } UniformType;
222
223 typedef struct UniformTypeInfo {
224 // Refers to vector elements, not array elements.
225 uint8_t elements;
226 uint8_t element_size;
227 } UniformTypeInfo;
228
229 typedef struct Uniform Uniform;
230
231 typedef enum ClearBufferFlags {
232 CLEAR_COLOR = (1 << 0),
233 CLEAR_DEPTH = (1 << 1),
234
235 CLEAR_ALL = CLEAR_COLOR | CLEAR_DEPTH,
236 } ClearBufferFlags;
237
238 // Blend modes API based on the SDL one.
239
240 typedef enum BlendModeComponent {
241 BLENDCOMP_COLOR_OP = 0x00,
242 BLENDCOMP_SRC_COLOR = 0x04,
243 BLENDCOMP_DST_COLOR = 0x08,
244 BLENDCOMP_ALPHA_OP = 0x10,
245 BLENDCOMP_SRC_ALPHA = 0x14,
246 BLENDCOMP_DST_ALPHA = 0x18,
247 } BlendModeComponent;
248
249 #define BLENDMODE_COMPOSE(src_color, dst_color, color_op, src_alpha, dst_alpha, alpha_op) \
250 ( \
251 ((uint32_t) color_op << BLENDCOMP_COLOR_OP ) | \
252 ((uint32_t) src_color << BLENDCOMP_SRC_COLOR) | \
253 ((uint32_t) dst_color << BLENDCOMP_DST_COLOR) | \
254 ((uint32_t) alpha_op << BLENDCOMP_ALPHA_OP ) | \
255 ((uint32_t) src_alpha << BLENDCOMP_SRC_ALPHA) | \
256 ((uint32_t) dst_alpha << BLENDCOMP_DST_ALPHA) \
257 )
258
259 #define BLENDMODE_COMPONENT(mode, comp) \
260 (((uint32_t) mode >> (uint32_t) comp) & 0xF)
261
262 typedef enum BlendOp {
263 BLENDOP_ADD = 0x1, // dst + src
264 BLENDOP_SUB = 0x2, // dst - src
265 BLENDOP_REV_SUB = 0x3, // src - dst
266 BLENDOP_MIN = 0x4, // min(dst, src)
267 BLENDOP_MAX = 0x5, // max(dst, src)
268 } BlendOp;
269
270 typedef enum BlendFactor {
271 BLENDFACTOR_ZERO = 0x1, // 0, 0, 0, 0
272 BLENDFACTOR_ONE = 0x2, // 1, 1, 1, 1
273 BLENDFACTOR_SRC_COLOR = 0x3, // srcR, srcG, srcB, srcA
274 BLENDFACTOR_INV_SRC_COLOR = 0x4, // 1-srcR, 1-srcG, 1-srcB, 1-srcA
275 BLENDFACTOR_SRC_ALPHA = 0x5, // srcA, srcA, srcA, srcA
276 BLENDFACTOR_INV_SRC_ALPHA = 0x6, // 1-srcA, 1-srcA, 1-srcA, 1-srcA
277 BLENDFACTOR_DST_COLOR = 0x7, // dstR, dstG, dstB, dstA
278 BLENDFACTOR_INV_DST_COLOR = 0x8, // 1-dstR, 1-dstG, 1-dstB, 1-dstA
279 BLENDFACTOR_DST_ALPHA = 0x9, // dstA, dstA, dstA, dstA
280 BLENDFACTOR_INV_DST_ALPHA = 0xA, // 1-dstA, 1-dstA, 1-dstA, 1-dstA
281 } BlendFactor;
282
283 typedef enum BlendMode {
284 BLEND_NONE = BLENDMODE_COMPOSE(
285 BLENDFACTOR_ONE, BLENDFACTOR_ZERO, BLENDOP_ADD,
286 BLENDFACTOR_ONE, BLENDFACTOR_ZERO, BLENDOP_ADD
287 ),
288
289 BLEND_ALPHA = BLENDMODE_COMPOSE(
290 BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_INV_SRC_ALPHA, BLENDOP_ADD,
291 BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA, BLENDOP_ADD
292 ),
293
294 BLEND_PREMUL_ALPHA = BLENDMODE_COMPOSE(
295 BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA, BLENDOP_ADD,
296 BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA, BLENDOP_ADD
297 ),
298
299 _BLEND_ADD = BLENDMODE_COMPOSE(
300 BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE, BLENDOP_ADD,
301 BLENDFACTOR_ZERO, BLENDFACTOR_ONE, BLENDOP_ADD
302 ),
303
304 BLEND_SUB = BLENDMODE_COMPOSE(
305 BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE, BLENDOP_REV_SUB,
306 BLENDFACTOR_ZERO, BLENDFACTOR_ONE, BLENDOP_REV_SUB
307 ),
308
309 BLEND_MOD = BLENDMODE_COMPOSE(
310 BLENDFACTOR_ZERO, BLENDFACTOR_SRC_COLOR, BLENDOP_ADD,
311 BLENDFACTOR_ZERO, BLENDFACTOR_ONE, BLENDOP_ADD
312 ),
313 } BlendMode;
314
315 attr_deprecated("Use BLEND_PREMUL_ALPHA and a color with alpha == 0 instead")
316 static const BlendMode BLEND_ADD = _BLEND_ADD;
317
318 typedef struct UnpackedBlendModePart {
319 BlendOp op;
320 BlendFactor src;
321 BlendFactor dst;
322 } UnpackedBlendModePart;
323
324 typedef struct UnpackedBlendMode {
325 UnpackedBlendModePart color;
326 UnpackedBlendModePart alpha;
327 } UnpackedBlendMode;
328
329 typedef enum CullFaceMode {
330 CULL_FRONT = 0x1,
331 CULL_BACK = 0x2,
332 CULL_BOTH = CULL_FRONT | CULL_BACK,
333 } CullFaceMode;
334
335 typedef enum DepthTestFunc {
336 DEPTH_NEVER,
337 DEPTH_ALWAYS,
338 DEPTH_EQUAL,
339 DEPTH_NOTEQUAL,
340 DEPTH_LESS,
341 DEPTH_LEQUAL,
342 DEPTH_GREATER,
343 DEPTH_GEQUAL,
344 } DepthTestFunc;
345
346 typedef enum VsyncMode {
347 VSYNC_NONE,
348 VSYNC_NORMAL,
349 VSYNC_ADAPTIVE,
350 } VsyncMode;
351
352 typedef union ShaderCustomParams {
353 float vector[4];
354 Color color;
355 } ShaderCustomParams;
356
357 typedef struct SpriteStateParams {
358 Texture *primary_texture;
359 Texture *aux_textures[R_NUM_SPRITE_AUX_TEXTURES];
360 BlendMode blend;
361 ShaderProgram *shader;
362 } SpriteStateParams;
363
364 typedef struct SpriteScaleParams {
365 union {
366 float x;
367 float both;
368 };
369
370 float y;
371 } SpriteScaleParams;
372
373 typedef struct SpriteRotationParams {
374 vec3 vector;
375 float angle;
376 } SpriteRotationParams;
377
378 typedef struct SpriteFlipParams {
379 unsigned char x : 1;
380 unsigned char y : 1;
381 } SpriteFlipParams;
382
383 typedef struct SpriteParams {
384 const char *sprite;
385 Sprite *sprite_ptr;
386
387 const char *shader;
388 ShaderProgram *shader_ptr;
389
390 Texture *aux_textures[R_NUM_SPRITE_AUX_TEXTURES];
391 const Color *color;
392 const ShaderCustomParams *shader_params;
393
394 BlendMode blend;
395
396 FloatOffset pos;
397 SpriteScaleParams scale;
398 SpriteRotationParams rotation;
399 SpriteFlipParams flip;
400 } SpriteParams;
401
402 // Matches vertex buffer layout
403 typedef struct SpriteInstanceAttribs {
404 mat4 mv_transform;
405 mat4 tex_transform;
406
407 union {
408 FloatRect texrect;
409 vec4 texrect_vec4;
410 };
411
412 Color rgba;
413 FloatExtent sprite_size;
414 ShaderCustomParams custom;
415
416 // offsetof(end_of_fields) == size without padding.
417 char end_of_fields;
418 } SpriteInstanceAttribs;
419
420 /*
421 * Creates an SDL window with proper flags, and, if needed, sets up a rendering context associated with it.
422 * Must be called before anything else.
423 */
424
425 SDL_Window* r_create_window(const char *title, int x, int y, int w, int h, uint32_t flags)
426 attr_nonnull(1) attr_nodiscard;
427
428 /*
429 * TODO: Document these, and put them in an order that makes a little bit of sense.
430 */
431
432 void r_init(void);
433 void r_post_init(void);
434 void r_shutdown(void);
435 const char *r_backend_name(void);
436
437 r_feature_bits_t r_features(void);
438
439 r_capability_bits_t r_capabilities_current(void);
440 void r_capabilities(r_capability_bits_t newcaps);
441
442 void r_capability(RendererCapability cap, bool value);
443 bool r_capability_current(RendererCapability cap);
444
445 void r_color4(float r, float g, float b, float a);
446 const Color* r_color_current(void);
447
448 void r_blend(BlendMode mode);
449 BlendMode r_blend_current(void);
450
451 void r_cull(CullFaceMode mode);
452 CullFaceMode r_cull_current(void);
453
454 void r_depth_func(DepthTestFunc func);
455 DepthTestFunc r_depth_func_current(void);
456
457 bool r_shader_language_supported(const ShaderLangInfo *lang, ShaderLangInfo *out_alternative) attr_nonnull(1);
458
459 ShaderObject* r_shader_object_compile(ShaderSource *source) attr_nonnull(1);
460 void r_shader_object_destroy(ShaderObject *shobj) attr_nonnull(1);
461 void r_shader_object_set_debug_label(ShaderObject *shobj, const char *label) attr_nonnull(1);
462 const char* r_shader_object_get_debug_label(ShaderObject *shobj) attr_nonnull(1);
463
464 ShaderProgram* r_shader_program_link(uint num_objects, ShaderObject *shobjs[num_objects]) attr_nonnull(2);
465 void r_shader_program_destroy(ShaderProgram *prog);
466 void r_shader_program_set_debug_label(ShaderProgram *prog, const char *label) attr_nonnull(1);
467 const char* r_shader_program_get_debug_label(ShaderProgram *prog) attr_nonnull(1);
468
469 void r_shader_ptr(ShaderProgram *prog) attr_nonnull(1);
470 ShaderProgram* r_shader_current(void) attr_returns_nonnull;
471
472 Uniform* _r_shader_uniform(ShaderProgram *prog, const char *uniform_name, hash_t uniform_name_hash) attr_nonnull(1, 2);
473 UniformType r_uniform_type(Uniform *uniform);
474 void r_uniform_ptr_unsafe(Uniform *uniform, uint offset, uint count, void *data);
475
476 #define _R_UNIFORM_GENERIC(suffix, uniform, ...) (_Generic((uniform), \
477 char* : _r_uniform_##suffix, \
478 const char* : _r_uniform_##suffix, \
479 Uniform* : _r_uniform_ptr_##suffix \
480 ))(uniform, __VA_ARGS__)
481
482 void _r_uniform_ptr_float(Uniform *uniform, float value);
483 void _r_uniform_float(const char *uniform, float value) attr_nonnull(1);
484 #define r_uniform_float(uniform, ...) _R_UNIFORM_GENERIC(float, uniform, __VA_ARGS__)
485
486 void _r_uniform_ptr_float_array(Uniform *uniform, uint offset, uint count, float elements[count]) attr_nonnull(4);
487 void _r_uniform_float_array(const char *uniform, uint offset, uint count, float elements[count]) attr_nonnull(1, 4);
488 #define r_uniform_float_array(uniform, ...) _R_UNIFORM_GENERIC(float_array, uniform, __VA_ARGS__)
489
490 void _r_uniform_ptr_vec2(Uniform *uniform, float x, float y) attr_nonnull(1);
491 void _r_uniform_vec2(const char *uniform, float x, float y) attr_nonnull(1);
492 #define r_uniform_vec2(uniform, ...) _R_UNIFORM_GENERIC(vec2, uniform, __VA_ARGS__)
493
494 void _r_uniform_ptr_vec2_vec(Uniform *uniform, vec2_noalign value) attr_nonnull(2);
495 void _r_uniform_vec2_vec(const char *uniform, vec2_noalign value) attr_nonnull(1, 2);
496 #define r_uniform_vec2_vec(uniform, ...) _R_UNIFORM_GENERIC(vec2_vec, uniform, __VA_ARGS__)
497
498 void _r_uniform_ptr_vec2_complex(Uniform *uniform, cmplx value);
499 void _r_uniform_vec2_complex(const char *uniform, cmplx value) attr_nonnull(1);
500 #define r_uniform_vec2_complex(uniform, ...) _R_UNIFORM_GENERIC(vec2_complex, uniform, __VA_ARGS__)
501
502 void _r_uniform_ptr_vec2_array(Uniform *uniform, uint offset, uint count, vec2_noalign elements[count]) attr_nonnull(4);
503 void _r_uniform_vec2_array(const char *uniform, uint offset, uint count, vec2_noalign elements[count]) attr_nonnull(1, 4);
504 #define r_uniform_vec2_array(uniform, ...) _R_UNIFORM_GENERIC(vec2_array, uniform, __VA_ARGS__)
505
506 void _r_uniform_ptr_vec2_array_complex(Uniform *uniform, uint offset, uint count, cmplx elements[count]) attr_nonnull(4);
507 void _r_uniform_vec2_array_complex(const char *uniform, uint offset, uint count, cmplx elements[count]) attr_nonnull(1, 4);
508 #define r_uniform_vec2_array_complex(uniform, ...) _R_UNIFORM_GENERIC(vec2_array_complex, uniform, __VA_ARGS__)
509
510 void _r_uniform_ptr_vec3(Uniform *uniform, float x, float y, float z);
511 void _r_uniform_vec3(const char *uniform, float x, float y, float z) attr_nonnull(1);
512 #define r_uniform_vec3(uniform, ...) _R_UNIFORM_GENERIC(vec3, uniform, __VA_ARGS__)
513
514 void _r_uniform_ptr_vec3_vec(Uniform *uniform, vec3_noalign value) attr_nonnull(2);
515 void _r_uniform_vec3_vec(const char *uniform, vec3_noalign value) attr_nonnull(1, 2);
516 #define r_uniform_vec3_vec(uniform, ...) _R_UNIFORM_GENERIC(vec3_vec, uniform, __VA_ARGS__)
517
518 void _r_uniform_ptr_vec3_rgb(Uniform *uniform, const Color *rgb) attr_nonnull(2);
519 void _r_uniform_vec3_rgb(const char *uniform, const Color *rgb) attr_nonnull(1, 2);
520 #define r_uniform_vec3_rgb(uniform, ...) _R_UNIFORM_GENERIC(vec3_rgb, uniform, __VA_ARGS__)
521
522 void _r_uniform_ptr_vec3_array(Uniform *uniform, uint offset, uint count, vec3_noalign elements[count]) attr_nonnull(4);
523 void _r_uniform_vec3_array(const char *uniform, uint offset, uint count, vec3_noalign elements[count]) attr_nonnull(1, 4);
524 #define r_uniform_vec3_array(uniform, ...) _R_UNIFORM_GENERIC(vec3_array, uniform, __VA_ARGS__)
525
526 void _r_uniform_ptr_vec4(Uniform *uniform, float x, float y, float z, float w);
527 void _r_uniform_vec4(const char *uniform, float x, float y, float z, float w) attr_nonnull(1);
528 #define r_uniform_vec4(uniform, ...) _R_UNIFORM_GENERIC(vec4, uniform, __VA_ARGS__)
529
530 void _r_uniform_ptr_vec4_vec(Uniform *uniform, vec4_noalign value) attr_nonnull(2);
531 void _r_uniform_vec4_vec(const char *uniform, vec4_noalign value) attr_nonnull(1, 2);
532 #define r_uniform_vec4_vec(uniform, ...) _R_UNIFORM_GENERIC(vec4_vec, uniform, __VA_ARGS__)
533
534 void _r_uniform_ptr_vec4_rgba(Uniform *uniform, const Color *rgba) attr_nonnull(2);
535 void _r_uniform_vec4_rgba(const char *uniform, const Color *rgba) attr_nonnull(1, 2);
536 #define r_uniform_vec4_rgba(uniform, ...) _R_UNIFORM_GENERIC(vec4_rgba, uniform, __VA_ARGS__)
537
538 void _r_uniform_ptr_vec4_array(Uniform *uniform, uint offset, uint count, vec4_noalign elements[count]) attr_nonnull(4);
539 void _r_uniform_vec4_array(const char *uniform, uint offset, uint count, vec4_noalign elements[count]) attr_nonnull(1, 4);
540 #define r_uniform_vec4_array(uniform, ...) _R_UNIFORM_GENERIC(vec4_array, uniform, __VA_ARGS__)
541
542 void _r_uniform_ptr_mat3(Uniform *uniform, mat3_noalign value) attr_nonnull(2);
543 void _r_uniform_mat3(const char *uniform, mat3_noalign value) attr_nonnull(1, 2);
544 #define r_uniform_mat3(uniform, ...) _R_UNIFORM_GENERIC(mat3, uniform, __VA_ARGS__)
545
546 void _r_uniform_ptr_mat3_array(Uniform *uniform, uint offset, uint count, mat3_noalign elements[count]) attr_nonnull(4);
547 void _r_uniform_mat3_array(const char *uniform, uint offset, uint count, mat3_noalign elements[count]) attr_nonnull(1, 4);
548 #define r_uniform_mat3_array(uniform, ...) _R_UNIFORM_GENERIC(mat3_array, uniform, __VA_ARGS__)
549
550 void _r_uniform_ptr_mat4(Uniform *uniform, mat4_noalign value) attr_nonnull(2);
551 void _r_uniform_mat4(const char *uniform, mat4_noalign value) attr_nonnull(1, 2);
552 #define r_uniform_mat4(uniform, ...) _R_UNIFORM_GENERIC(mat4, uniform, __VA_ARGS__)
553
554 void _r_uniform_ptr_mat4_array(Uniform *uniform, uint offset, uint count, mat4_noalign elements[count]) attr_nonnull(4);
555 void _r_uniform_mat4_array(const char *uniform, uint offset, uint count, mat4_noalign elements[count]) attr_nonnull(1, 4);
556 #define r_uniform_mat4_array(uniform, ...) _R_UNIFORM_GENERIC(mat4_array, uniform, __VA_ARGS__)
557
558 void _r_uniform_ptr_int(Uniform *uniform, int value);
559 void _r_uniform_int(const char *uniform, int value) attr_nonnull(1);
560 #define r_uniform_int(uniform, ...) _R_UNIFORM_GENERIC(int, uniform, __VA_ARGS__)
561
562 void _r_uniform_ptr_int_array(Uniform *uniform, uint offset, uint count, int elements[count]) attr_nonnull(4);
563 void _r_uniform_int_array(const char *uniform, uint offset, uint count, int elements[count]) attr_nonnull(1, 4);
564 #define r_uniform_int_array(uniform, ...) _R_UNIFORM_GENERIC(int_array, uniform, __VA_ARGS__)
565
566 void _r_uniform_ptr_ivec2(Uniform *uniform, int x, int y);
567 void _r_uniform_ivec2(const char *uniform, int x, int y) attr_nonnull(1);
568 #define r_uniform_ivec2(uniform, ...) _R_UNIFORM_GENERIC(ivec2, uniform, __VA_ARGS__)
569
570 void _r_uniform_ptr_ivec2_vec(Uniform *uniform, ivec2_noalign value) attr_nonnull(2);
571 void _r_uniform_ivec2_vec(const char *uniform, ivec2_noalign value) attr_nonnull(1, 2);
572 #define r_uniform_ivec2_vec(uniform, ...) _R_UNIFORM_GENERIC(ivec2_vec, uniform, __VA_ARGS__)
573
574 void _r_uniform_ptr_ivec2_array(Uniform *uniform, uint offset, uint count, ivec2_noalign elements[count]) attr_nonnull(4);
575 void _r_uniform_ivec2_array(const char *uniform, uint offset, uint count, ivec2_noalign elements[count]) attr_nonnull(1, 4);
576 #define r_uniform_ivec2_array(uniform, ...) _R_UNIFORM_GENERIC(ivec2_array, uniform, __VA_ARGS__)
577
578 void _r_uniform_ptr_ivec3(Uniform *uniform, int x, int y, int z);
579 void _r_uniform_ivec3(const char *uniform, int x, int y, int z) attr_nonnull(1);
580 #define r_uniform_ivec3(uniform, ...) _R_UNIFORM_GENERIC(ivec3, uniform, __VA_ARGS__)
581
582 void _r_uniform_ptr_ivec3_vec(Uniform *uniform, ivec3_noalign value) attr_nonnull(2);
583 void _r_uniform_ivec3_vec(const char *uniform, ivec3_noalign value) attr_nonnull(1, 2);
584 #define r_uniform_ivec3_vec(uniform, ...) _R_UNIFORM_GENERIC(ivec3_vec, uniform, __VA_ARGS__)
585
586 void _r_uniform_ptr_ivec3_array(Uniform *uniform, uint offset, uint count, ivec3_noalign elements[count]) attr_nonnull(4);
587 void _r_uniform_ivec3_array(const char *uniform, uint offset, uint count, ivec3_noalign elements[count]) attr_nonnull(1, 4);
588 #define r_uniform_ivec3_array(uniform, ...) _R_UNIFORM_GENERIC(ivec3_array, uniform, __VA_ARGS__)
589
590 void _r_uniform_ptr_ivec4(Uniform *uniform, int x, int y, int z, int w);
591 void _r_uniform_ivec4(const char *uniform, int x, int y, int z, int w) attr_nonnull(1);
592 #define r_uniform_ivec4(uniform, ...) _R_UNIFORM_GENERIC(ivec4, uniform, __VA_ARGS__)
593
594 void _r_uniform_ptr_ivec4_vec(Uniform *uniform, ivec4_noalign value) attr_nonnull(2);
595 void _r_uniform_ivec4_vec(const char *uniform, ivec4_noalign value) attr_nonnull(1, 2);
596 #define r_uniform_ivec4_vec(uniform, ...) _R_UNIFORM_GENERIC(ivec4_vec, uniform, __VA_ARGS__)
597
598 void _r_uniform_ptr_ivec4_array(Uniform *uniform, uint offset, uint count, ivec4_noalign elements[count]) attr_nonnull(4);
599 void _r_uniform_ivec4_array(const char *uniform, uint offset, uint count, ivec4_noalign elements[count]) attr_nonnull(1, 4);
600 #define r_uniform_ivec4_array(uniform, ...) _R_UNIFORM_GENERIC(ivec4_array, uniform, __VA_ARGS__)
601
602 void _r_uniform_ptr_sampler_ptr(Uniform *uniform, Texture *tex) attr_nonnull(2);
603 void _r_uniform_sampler_ptr(const char *uniform, Texture *tex) attr_nonnull(1, 2);
604 void _r_uniform_ptr_sampler(Uniform *uniform, const char *tex) attr_nonnull(2);
605 void _r_uniform_sampler(const char *uniform, const char *tex) attr_nonnull(1, 2);
606 #define r_uniform_sampler(uniform, tex) (_Generic((uniform), \
607 char* : _Generic((tex), \
608 char* : _r_uniform_sampler, \
609 const char* : _r_uniform_sampler, \
610 Texture* : _r_uniform_sampler_ptr \
611 ), \
612 const char* : _Generic((tex), \
613 char* : _r_uniform_sampler, \
614 const char* : _r_uniform_sampler, \
615 Texture* : _r_uniform_sampler_ptr \
616 ), \
617 Uniform* : _Generic((tex), \
618 char* : _r_uniform_ptr_sampler, \
619 const char* : _r_uniform_ptr_sampler, \
620 Texture* : _r_uniform_ptr_sampler_ptr \
621 ) \
622 ))(uniform, tex)
623
624 void _r_uniform_ptr_sampler_array_ptr(Uniform *uniform, uint offset, uint count, Texture *values[count]) attr_nonnull(4);
625 void _r_uniform_sampler_array_ptr(const char *uniform, uint offset, uint count, Texture *values[count]) attr_nonnull(1, 4);
626 void _r_uniform_ptr_sampler_array(Uniform *uniform, uint offset, uint count, const char *values[count]) attr_nonnull(4);
627 void _r_uniform_sampler_array(const char *uniform, uint offset, uint count, const char *values[count]) attr_nonnull(4);
628 #define r_uniform_sampler_array(uniform, offset, count, values) (_Generic(uniform, \
629 char* : _Generic((values), \
630 char** : _r_uniform_sampler_array, \
631 Texture** : _r_uniform_sampler_array_ptr \
632 ), \
633 const char* : _Generic((values), \
634 char** : _r_uniform_sampler_array, \
635 Texture** : _r_uniform_sampler_array_ptr \
636 ), \
637 Uniform* : _Generic((values), \
638 char** : _r_uniform_ptr_sampler_array, \
639 Texture** : _r_uniform_ptr_sampler_array_ptr \
640 ) \
641 ))(uniform, offset, count, values)
642
643 void r_draw(VertexArray *varr, Primitive prim, uint firstvert, uint count, uint instances, uint base_instance);
644 void r_draw_indexed(VertexArray *varr, Primitive prim, uint firstidx, uint count, uint instances, uint base_instance);
645
646 Texture* r_texture_create(const TextureParams *params) attr_nonnull(1);
647 void r_texture_get_size(Texture *tex, uint mipmap, uint *width, uint *height) attr_nonnull(1);
648 uint r_texture_get_width(Texture *tex, uint mipmap) attr_nonnull(1);
649 uint r_texture_get_height(Texture *tex, uint mipmap) attr_nonnull(1);
650 void r_texture_get_params(Texture *tex, TextureParams *params) attr_nonnull(1, 2);
651 const char* r_texture_get_debug_label(Texture *tex) attr_nonnull(1);
652 void r_texture_set_debug_label(Texture *tex, const char *label) attr_nonnull(1);
653 void r_texture_set_filter(Texture *tex, TextureFilterMode fmin, TextureFilterMode fmag) attr_nonnull(1);
654 void r_texture_set_wrap(Texture *tex, TextureWrapMode ws, TextureWrapMode wt) attr_nonnull(1);
655 void r_texture_fill(Texture *tex, uint mipmap, const Pixmap *image_data) attr_nonnull(1, 3);
656 void r_texture_fill_region(Texture *tex, uint mipmap, uint x, uint y, const Pixmap *image_data) attr_nonnull(1, 5);
657 void r_texture_invalidate(Texture *tex) attr_nonnull(1);
658 void r_texture_clear(Texture *tex, const Color *clr) attr_nonnull(1, 2);
659 void r_texture_destroy(Texture *tex) attr_nonnull(1);
660
661 Framebuffer* r_framebuffer_create(void);
662 const char* r_framebuffer_get_debug_label(Framebuffer *fb) attr_nonnull(1);
663 void r_framebuffer_set_debug_label(Framebuffer *fb, const char* label) attr_nonnull(1);
664 void r_framebuffer_attach(Framebuffer *fb, Texture *tex, uint mipmap, FramebufferAttachment attachment) attr_nonnull(1);
665 Texture* r_framebuffer_get_attachment(Framebuffer *fb, FramebufferAttachment attachment) attr_nonnull(1);
666 uint r_framebuffer_get_attachment_mipmap(Framebuffer *fb, FramebufferAttachment attachment) attr_nonnull(1);
667 void r_framebuffer_viewport(Framebuffer *fb, float x, float y, float w, float h);
668 void r_framebuffer_viewport_rect(Framebuffer *fb, FloatRect viewport);
669 void r_framebuffer_viewport_current(Framebuffer *fb, FloatRect *viewport) attr_nonnull(2);
670 void r_framebuffer_destroy(Framebuffer *fb) attr_nonnull(1);
671 void r_framebuffer_clear(Framebuffer *fb, ClearBufferFlags flags, const Color *colorval, float depthval);
672 IntExtent r_framebuffer_get_size(Framebuffer *fb);
673
674 void r_framebuffer(Framebuffer *fb);
675 Framebuffer* r_framebuffer_current(void);
676
677 VertexBuffer* r_vertex_buffer_create(size_t capacity, void *data);
678 const char* r_vertex_buffer_get_debug_label(VertexBuffer *vbuf) attr_nonnull(1);
679 void r_vertex_buffer_set_debug_label(VertexBuffer *vbuf, const char* label) attr_nonnull(1);
680 void r_vertex_buffer_destroy(VertexBuffer *vbuf) attr_nonnull(1);
681 void r_vertex_buffer_invalidate(VertexBuffer *vbuf) attr_nonnull(1);
682 SDL_RWops* r_vertex_buffer_get_stream(VertexBuffer *vbuf) attr_nonnull(1);
683
684 IndexBuffer* r_index_buffer_create(size_t max_elements);
685 size_t r_index_buffer_get_capacity(IndexBuffer *ibuf) attr_nonnull(1);
686 const char* r_index_buffer_get_debug_label(IndexBuffer *ibuf) attr_nonnull(1);
687 void r_index_buffer_set_debug_label(IndexBuffer *ibuf, const char *label) attr_nonnull(1);
688 void r_index_buffer_set_offset(IndexBuffer *ibuf, size_t offset) attr_nonnull(1);
689 size_t r_index_buffer_get_offset(IndexBuffer *ibuf) attr_nonnull(1);
690 void r_index_buffer_add_indices(IndexBuffer *ibuf, uint index_ofs, size_t num_indices, uint indices[num_indices]) attr_nonnull(1, 4);
691 void r_index_buffer_destroy(IndexBuffer *ibuf) attr_nonnull(1);
692
693 VertexArray* r_vertex_array_create(void);
694 const char* r_vertex_array_get_debug_label(VertexArray *varr) attr_nonnull(1);
695 void r_vertex_array_set_debug_label(VertexArray *varr, const char* label) attr_nonnull(1);
696 void r_vertex_array_destroy(VertexArray *varr) attr_nonnull(1);
697 void r_vertex_array_attach_vertex_buffer(VertexArray *varr, VertexBuffer *vbuf, uint attachment) attr_nonnull(1, 2);
698 VertexBuffer* r_vertex_array_get_vertex_attachment(VertexArray *varr, uint attachment) attr_nonnull(1);
699 void r_vertex_array_attach_index_buffer(VertexArray *varr, IndexBuffer *ibuf) attr_nonnull(1);
700 IndexBuffer* r_vertex_array_get_index_attachment(VertexArray *varr) attr_nonnull(1);
701 void r_vertex_array_layout(VertexArray *varr, uint nattribs, VertexAttribFormat attribs[nattribs]) attr_nonnull(1, 3);
702
703 void r_model_add_static(Model *out_mdl, Primitive prim, size_t num_vertices, GenericModelVertex vertices[num_vertices], uint indices[num_vertices]);
704
705 void r_vsync(VsyncMode mode);
706 VsyncMode r_vsync_current(void);
707
708 void r_swap(SDL_Window *window);
709
710 bool r_screenshot(Pixmap *dest) attr_nodiscard attr_nonnull(1);
711
712 void r_mat_mv_push(void);
713 void r_mat_mv_push_premade(mat4 mat);
714 void r_mat_mv_push_identity(void);
715 void r_mat_mv_pop(void);
716 void r_mat_mv(mat4 mat);
717 void r_mat_mv_current(mat4 out_mat);
718 mat4 *r_mat_mv_current_ptr(void);
719 void r_mat_mv_identity(void);
720 void r_mat_mv_translate_v(vec3 v);
721 void r_mat_mv_rotate_v(float angle, vec3 v);
722 void r_mat_mv_scale_v(vec3 v);
723
724 void r_mat_proj_push(void);
725 void r_mat_proj_push_premade(mat4 mat);
726 void r_mat_proj_push_identity(void);
727 void r_mat_proj_push_ortho_ex(float left, float right, float bottom, float top, float near, float far);
728 void r_mat_proj_push_ortho(float width, float height);
729 void r_mat_proj_push_perspective(float angle, float aspect, float near, float far);
730 void r_mat_proj_pop(void);
731 void r_mat_proj(mat4 mat);
732 void r_mat_proj_current(mat4 out_mat);
733 mat4 *r_mat_proj_current_ptr(void);
734 void r_mat_proj_identity(void);
735 void r_mat_proj_translate_v(vec3 v);
736 void r_mat_proj_rotate_v(float angle, vec3 v);
737 void r_mat_proj_scale_v(vec3 v);
738 void r_mat_proj_ortho(float left, float right, float bottom, float top, float near, float far);
739 void r_mat_proj_perspective(float angle, float aspect, float near, float far);
740
741 void r_mat_tex_push(void);
742 void r_mat_tex_push_premade(mat4 mat);
743 void r_mat_tex_push_identity(void);
744 void r_mat_tex_pop(void);
745 void r_mat_tex(mat4 mat);
746 void r_mat_tex_current(mat4 out_mat);
747 mat4 *r_mat_tex_current_ptr(void);
748 void r_mat_tex_identity(void);
749 void r_mat_tex_translate_v(vec3 v);
750 void r_mat_tex_rotate_v(float angle, vec3 v);
751 void r_mat_tex_scale_v(vec3 v);
752
753 void r_shader_standard(void);
754 void r_shader_standard_notex(void);
755
756 VertexBuffer* r_vertex_buffer_static_models(void) attr_returns_nonnull;
757 VertexArray* r_vertex_array_static_models(void) attr_returns_nonnull;
758
759 void r_state_push(void);
760 void r_state_pop(void);
761
762 void r_draw_quad(void);
763 void r_draw_quad_instanced(uint instances);
764 void r_draw_model_ptr(Model *model, uint instances, uint base_instance) attr_nonnull(1);
765 void r_draw_sprite(const SpriteParams *params) attr_nonnull(1);
766
767 void r_sprite_batch_prepare_state(const SpriteStateParams *stp);
768 void r_sprite_batch_add_instance(const SpriteInstanceAttribs *attribs);
769
770 void r_flush_sprites(void);
771
772 BlendMode r_blend_compose(
773 BlendFactor src_color, BlendFactor dst_color, BlendOp color_op,
774 BlendFactor src_alpha, BlendFactor dst_alpha, BlendOp alpha_op
775 );
776
777 uint32_t r_blend_component(BlendMode mode, BlendModeComponent component);
778 void r_blend_unpack(BlendMode mode, UnpackedBlendMode *dest) attr_nonnull(2);
779
780 const UniformTypeInfo* r_uniform_type_info(UniformType type) attr_returns_nonnull;
781 const VertexAttribTypeInfo* r_vertex_attrib_type_info(VertexAttribType type);
782
783 VertexAttribFormat* r_vertex_attrib_format_interleaved(
784 size_t nattribs,
785 VertexAttribSpec specs[nattribs],
786 VertexAttribFormat formats[nattribs],
787 uint attachment
788 ) attr_nonnull(2, 3);
789
790 /*
791 * Small convenience wrappers
792 */
793
794 INLINE
r_enable(RendererCapability cap)795 void r_enable(RendererCapability cap) {
796 r_capability(cap, true);
797 }
798
799 INLINE
r_disable(RendererCapability cap)800 void r_disable(RendererCapability cap) {
801 r_capability(cap, false);
802 }
803
804 INLINE
r_shader_get(const char * name)805 ShaderProgram* r_shader_get(const char *name) {
806 return get_resource_data(RES_SHADER_PROGRAM, name, RESF_DEFAULT | RESF_UNSAFE);
807 }
808
809 INLINE
r_shader_get_optional(const char * name)810 ShaderProgram* r_shader_get_optional(const char *name) {
811 return get_resource_data(RES_SHADER_PROGRAM, name, RESF_OPTIONAL | RESF_UNSAFE);
812 }
813
814 INLINE
r_texture_get(const char * name)815 Texture* r_texture_get(const char *name) {
816 return get_resource_data(RES_TEXTURE, name, RESF_DEFAULT | RESF_UNSAFE);
817 }
818
819 #pragma GCC diagnostic push
820 #pragma GCC diagnostic ignored "-Wdeprecated"
821
r_mat_mv_translate(float x,float y,float z)822 INLINE void r_mat_mv_translate(float x, float y, float z) { r_mat_mv_translate_v((vec3) { x, y, z }); }
r_mat_proj_translate(float x,float y,float z)823 INLINE void r_mat_proj_translate(float x, float y, float z) { r_mat_proj_translate_v((vec3) { x, y, z }); }
r_mat_tex_translate(float x,float y,float z)824 INLINE void r_mat_tex_translate(float x, float y, float z) { r_mat_tex_translate_v((vec3) { x, y, z }); }
825
r_mat_mv_rotate(float angle,float nx,float ny,float nz)826 INLINE void r_mat_mv_rotate(float angle, float nx, float ny, float nz) { r_mat_mv_rotate_v(angle, (vec3) { nx, ny, nz }); }
r_mat_proj_rotate(float angle,float nx,float ny,float nz)827 INLINE void r_mat_proj_rotate(float angle, float nx, float ny, float nz) { r_mat_proj_rotate_v(angle, (vec3) { nx, ny, nz }); }
r_mat_tex_rotate(float angle,float nx,float ny,float nz)828 INLINE void r_mat_tex_rotate(float angle, float nx, float ny, float nz) { r_mat_tex_rotate_v(angle, (vec3) { nx, ny, nz }); }
829
r_mat_mv_scale(float sx,float sy,float sz)830 INLINE void r_mat_mv_scale(float sx, float sy, float sz) { r_mat_mv_scale_v((vec3) { sx, sy, sz }); }
r_mat_proj_scale(float sx,float sy,float sz)831 INLINE void r_mat_proj_scale(float sx, float sy, float sz) { r_mat_proj_scale_v((vec3) { sx, sy, sz }); }
r_mat_tex_scale(float sx,float sy,float sz)832 INLINE void r_mat_tex_scale(float sx, float sy, float sz) { r_mat_tex_scale_v((vec3) { sx, sy, sz }); }
833
834 #pragma GCC diagnostic pop
835
836 INLINE
r_color(const Color * c)837 void r_color(const Color *c) {
838 r_color4(c->r, c->g, c->b, c->a);
839 }
840
841 INLINE
r_color3(float r,float g,float b)842 void r_color3(float r, float g, float b) {
843 r_color4(r, g, b, 1.0);
844 }
845
846 INLINE attr_nonnull(1)
r_shader(const char * prog)847 void r_shader(const char *prog) {
848 r_shader_ptr(r_shader_get(prog));
849 }
850
851 INLINE
r_shader_uniform(ShaderProgram * prog,const char * name)852 Uniform* r_shader_uniform(ShaderProgram *prog, const char *name) {
853 return _r_shader_uniform(prog, name, ht_str2ptr_hash(name));
854 }
855
856 INLINE
r_shader_current_uniform(const char * name)857 Uniform* r_shader_current_uniform(const char *name) {
858 return r_shader_uniform(r_shader_current(), name);
859 }
860
861 INLINE
r_clear(ClearBufferFlags flags,const Color * colorval,float depthval)862 void r_clear(ClearBufferFlags flags, const Color *colorval, float depthval) {
863 r_framebuffer_clear(r_framebuffer_current(), flags, colorval, depthval);
864 }
865
866 INLINE attr_nonnull(1)
r_draw_model(const char * model)867 void r_draw_model(const char *model) {
868 r_draw_model_ptr(get_resource_data(RES_MODEL, model, RESF_UNSAFE), 0, 0);
869 }
870
871 INLINE attr_nonnull(1)
r_draw_model_instanced(const char * model,uint instances,uint base_instance)872 void r_draw_model_instanced(const char *model, uint instances, uint base_instance) {
873 r_draw_model_ptr(get_resource_data(RES_MODEL, model, RESF_UNSAFE), instances, base_instance);
874 }
875
876 INLINE
r_capability_bit(RendererCapability cap)877 r_capability_bits_t r_capability_bit(RendererCapability cap) {
878 r_capability_bits_t idx = cap;
879 assert(idx < NUM_RCAPS);
880 return (1 << idx);
881 }
882
883 INLINE
r_feature_bit(RendererFeature feat)884 r_feature_bits_t r_feature_bit(RendererFeature feat) {
885 r_feature_bits_t idx = feat;
886 assert(idx < NUM_RFEATS);
887 return (1 << idx);
888 }
889
890 INLINE
r_supports(RendererFeature feature)891 bool r_supports(RendererFeature feature) {
892 return r_features() & r_feature_bit(feature);
893 }
894
895 #endif // IGUARD_renderer_api_h
896