diff options
| author | 3gg <3gg@shellblade.net> | 2025-06-27 10:18:39 -0700 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-06-27 10:18:39 -0700 |
| commit | bd57f345ed9dbed1d81683e48199626de2ea9044 (patch) | |
| tree | 4221f2f2a7ad2244d2e93052bd68187ec91b8ea9 /include | |
| parent | 9a82ce0083437a4f9f58108b2c23b957d2249ad8 (diff) | |
Restructure project
Diffstat (limited to 'include')
| -rw-r--r-- | include/gfx/asset.h | 99 | ||||
| -rw-r--r-- | include/gfx/core.h | 501 | ||||
| -rw-r--r-- | include/gfx/gfx.h | 31 | ||||
| -rw-r--r-- | include/gfx/renderer.h | 104 | ||||
| -rw-r--r-- | include/gfx/scene.h | 11 | ||||
| -rw-r--r-- | include/gfx/scene/animation.h | 142 | ||||
| -rw-r--r-- | include/gfx/scene/camera.h | 22 | ||||
| -rw-r--r-- | include/gfx/scene/light.h | 30 | ||||
| -rw-r--r-- | include/gfx/scene/material.h | 25 | ||||
| -rw-r--r-- | include/gfx/scene/mesh.h | 23 | ||||
| -rw-r--r-- | include/gfx/scene/model.h | 12 | ||||
| -rw-r--r-- | include/gfx/scene/node.h | 156 | ||||
| -rw-r--r-- | include/gfx/scene/object.h | 39 | ||||
| -rw-r--r-- | include/gfx/scene/scene.h | 21 | ||||
| -rw-r--r-- | include/gfx/sizes.h | 95 | ||||
| -rw-r--r-- | include/gfx/util/geometry.h | 13 | ||||
| -rw-r--r-- | include/gfx/util/ibl.h | 25 | ||||
| -rw-r--r-- | include/gfx/util/shader.h | 46 | ||||
| -rw-r--r-- | include/gfx/util/skyquad.h | 22 |
19 files changed, 1417 insertions, 0 deletions
diff --git a/include/gfx/asset.h b/include/gfx/asset.h new file mode 100644 index 0000000..caf40c1 --- /dev/null +++ b/include/gfx/asset.h | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /* Asset Management */ | ||
| 2 | #pragma once | ||
| 3 | |||
| 4 | #include <gfx/core.h> | ||
| 5 | |||
| 6 | #include <stddef.h> | ||
| 7 | |||
| 8 | typedef struct Gfx Gfx; | ||
| 9 | typedef struct Model Model; | ||
| 10 | typedef struct ShaderProgram ShaderProgram; | ||
| 11 | typedef struct Texture Texture; | ||
| 12 | |||
| 13 | /// Describes where the asset comes from. | ||
| 14 | typedef enum AssetOrigin { | ||
| 15 | AssetFromMemory, | ||
| 16 | AssetFromFile, | ||
| 17 | } AssetOrigin; | ||
| 18 | |||
| 19 | /// Describes a texture's colour space. | ||
| 20 | typedef enum TextureColourSpace { | ||
| 21 | sRGB, // The most likely default. | ||
| 22 | LinearColourSpace, | ||
| 23 | } TextureColourSpace; | ||
| 24 | |||
| 25 | /// Describes a command to load a texture. | ||
| 26 | typedef struct LoadTextureCmd { | ||
| 27 | AssetOrigin origin; | ||
| 28 | enum { LoadTexture, LoadCubemap } type; | ||
| 29 | TextureColourSpace colour_space; | ||
| 30 | TextureFiltering filtering; | ||
| 31 | TextureWrapping wrap; | ||
| 32 | bool mipmaps; | ||
| 33 | union { | ||
| 34 | // A single texture. | ||
| 35 | struct { | ||
| 36 | union { | ||
| 37 | struct { | ||
| 38 | mstring filepath; | ||
| 39 | }; | ||
| 40 | struct { | ||
| 41 | const void* data; | ||
| 42 | size_t size_bytes; | ||
| 43 | }; | ||
| 44 | }; | ||
| 45 | } texture; | ||
| 46 | // Cubemap texture. | ||
| 47 | struct { | ||
| 48 | union { | ||
| 49 | struct { | ||
| 50 | mstring filepath_pos_x; | ||
| 51 | mstring filepath_neg_x; | ||
| 52 | mstring filepath_pos_y; | ||
| 53 | mstring filepath_neg_y; | ||
| 54 | mstring filepath_pos_z; | ||
| 55 | mstring filepath_neg_z; | ||
| 56 | } filepaths; | ||
| 57 | struct { | ||
| 58 | const void* data_pos_x; | ||
| 59 | const void* data_neg_x; | ||
| 60 | const void* data_pos_y; | ||
| 61 | const void* data_neg_y; | ||
| 62 | const void* data_pos_z; | ||
| 63 | const void* data_neg_z; | ||
| 64 | } buffers; | ||
| 65 | }; | ||
| 66 | } cubemap; | ||
| 67 | } data; | ||
| 68 | } LoadTextureCmd; | ||
| 69 | |||
| 70 | /// Describes a command to load a model. | ||
| 71 | /// | ||
| 72 | /// |shader| is an optional shader program assigned to the loaded model objects. | ||
| 73 | /// If no shader is given, a Cook-Torrance shader based on the object's | ||
| 74 | /// characteristics (presence of normals, tangents, etc) is assigned. | ||
| 75 | typedef struct LoadModelCmd { | ||
| 76 | AssetOrigin origin; | ||
| 77 | union { | ||
| 78 | struct { | ||
| 79 | mstring filepath; | ||
| 80 | }; | ||
| 81 | struct { | ||
| 82 | const void* data; | ||
| 83 | size_t size_bytes; | ||
| 84 | }; | ||
| 85 | }; | ||
| 86 | ShaderProgram* shader; | ||
| 87 | } LoadModelCmd; | ||
| 88 | |||
| 89 | /// Load a model. | ||
| 90 | /// | ||
| 91 | /// For animated models, this function returns a (shallow) clone of the model | ||
| 92 | /// that is safe to mutate. For static models, this returns the original model | ||
| 93 | /// in the cache. | ||
| 94 | /// | ||
| 95 | /// Currently only supports the GLTF format. | ||
| 96 | Model* gfx_load_model(Gfx*, const LoadModelCmd*); | ||
| 97 | |||
| 98 | /// Load a texture. | ||
| 99 | const Texture* gfx_load_texture(Gfx*, const LoadTextureCmd*); | ||
diff --git a/include/gfx/core.h b/include/gfx/core.h new file mode 100644 index 0000000..44509c9 --- /dev/null +++ b/include/gfx/core.h | |||
| @@ -0,0 +1,501 @@ | |||
| 1 | /// Render Backend. | ||
| 2 | /// | ||
| 3 | /// The Render Backend creates and owns graphics objects and performs low-level | ||
| 4 | /// rendering operations. | ||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "sizes.h" | ||
| 8 | |||
| 9 | #include <math/aabb3.h> | ||
| 10 | #include <math/fwd.h> | ||
| 11 | #include <math/mat4.h> | ||
| 12 | #include <math/vec4.h> | ||
| 13 | |||
| 14 | #include <cstring.h> | ||
| 15 | |||
| 16 | #include <stddef.h> | ||
| 17 | #include <stdint.h> | ||
| 18 | |||
| 19 | // Implementation objects. | ||
| 20 | typedef struct Buffer Buffer; | ||
| 21 | typedef struct FrameBuffer FrameBuffer; | ||
| 22 | typedef struct Geometry Geometry; | ||
| 23 | typedef struct GfxCore GfxCore; | ||
| 24 | typedef struct RenderBuffer RenderBuffer; | ||
| 25 | typedef struct Shader Shader; | ||
| 26 | typedef struct ShaderProgram ShaderProgram; | ||
| 27 | typedef struct Texture Texture; | ||
| 28 | |||
| 29 | /// Data type for vertex indices. | ||
| 30 | /// Might need U32 for bigger models. | ||
| 31 | typedef uint8_t VertexIndex8; | ||
| 32 | typedef uint16_t VertexIndex16; | ||
| 33 | typedef uint16_t VertexCount; | ||
| 34 | |||
| 35 | /// Geometry drawing modes. | ||
| 36 | typedef enum PrimitiveType { | ||
| 37 | Triangles, | ||
| 38 | TriangleFan, | ||
| 39 | TriangleStrip | ||
| 40 | } PrimitiveType; | ||
| 41 | |||
| 42 | /// Buffer usage. | ||
| 43 | typedef enum BufferUsage { BufferStatic, BufferDynamic } BufferUsage; | ||
| 44 | |||
| 45 | /// Buffer type. | ||
| 46 | typedef enum BufferType { | ||
| 47 | BufferUntyped, | ||
| 48 | Buffer2d, | ||
| 49 | Buffer3d, | ||
| 50 | Buffer4d, | ||
| 51 | BufferFloat, | ||
| 52 | BufferU8, | ||
| 53 | BufferU16 | ||
| 54 | } BufferType; | ||
| 55 | |||
| 56 | /// Buffer data descriptor. | ||
| 57 | typedef struct BufferDataDesc { | ||
| 58 | union { | ||
| 59 | const void* data; | ||
| 60 | const vec2* vec2s; | ||
| 61 | const vec3* vec3s; | ||
| 62 | const float* floats; | ||
| 63 | const uint8_t* u8s; | ||
| 64 | const uint16_t* u16s; | ||
| 65 | }; | ||
| 66 | size_t count; | ||
| 67 | } BufferDataDesc; | ||
| 68 | |||
| 69 | /// Buffer descriptor. | ||
| 70 | /// | ||
| 71 | /// 'count' is the number of elements in the array. For untyped buffers, this is | ||
| 72 | /// the size in bytes of the 'data' array. For other types, it is the number of | ||
| 73 | /// vec2s, vec3s, etc. in the corresponding array. | ||
| 74 | /// | ||
| 75 | /// The data pointers can also be null. In such a case, a buffer of the given | ||
| 76 | /// size is created with its contents uninitialized. | ||
| 77 | /// | ||
| 78 | /// TODO: Think about typed buffers (Buffer, Buffer2d, Buffer3d, BufferU8, etc). | ||
| 79 | /// Typed buffers don't work well with interleaved vertex attributes. Not sure | ||
| 80 | /// this is really worth it. | ||
| 81 | typedef struct BufferDesc { | ||
| 82 | BufferUsage usage; | ||
| 83 | BufferType type; | ||
| 84 | BufferDataDesc data; | ||
| 85 | } BufferDesc; | ||
| 86 | |||
| 87 | /// A buffer view for vertex data (attributes or indices). | ||
| 88 | /// Either 'data' or 'buffer' must be set. | ||
| 89 | #define MAKE_BUFFER_VIEW(NAME, TYPE) \ | ||
| 90 | typedef struct NAME { \ | ||
| 91 | const TYPE* data; \ | ||
| 92 | Buffer* buffer; \ | ||
| 93 | size_t offset_bytes; \ | ||
| 94 | size_t size_bytes; \ | ||
| 95 | size_t stride_bytes; \ | ||
| 96 | } NAME; | ||
| 97 | |||
| 98 | /// A buffer view for untyped data. | ||
| 99 | MAKE_BUFFER_VIEW(BufferView, void) | ||
| 100 | |||
| 101 | /// A buffer view for 2D vectors. | ||
| 102 | MAKE_BUFFER_VIEW(BufferView2d, vec2) | ||
| 103 | |||
| 104 | /// A buffer view for 3D vectors. | ||
| 105 | MAKE_BUFFER_VIEW(BufferView3d, vec3) | ||
| 106 | |||
| 107 | /// A buffer view for 4D vectors. | ||
| 108 | MAKE_BUFFER_VIEW(BufferView4d, vec4) | ||
| 109 | |||
| 110 | /// A buffer view for floats. | ||
| 111 | MAKE_BUFFER_VIEW(BufferViewFloat, float) | ||
| 112 | |||
| 113 | /// A buffer view for 8-bit unsigned integers. | ||
| 114 | MAKE_BUFFER_VIEW(BufferViewU8, uint8_t) | ||
| 115 | |||
| 116 | /// A buffer view for 16-bit unsigned integers. | ||
| 117 | MAKE_BUFFER_VIEW(BufferViewU16, uint16_t) | ||
| 118 | |||
| 119 | /// A buffer view for 8-bit vertex indices. | ||
| 120 | MAKE_BUFFER_VIEW(BufferViewIdx8, uint16_t) | ||
| 121 | |||
| 122 | /// A buffer view for 16-bit vertex indices. | ||
| 123 | MAKE_BUFFER_VIEW(BufferViewIdx16, uint16_t) | ||
| 124 | |||
| 125 | /// Describes a piece of geometry. | ||
| 126 | /// | ||
| 127 | /// Buffer views may point to either already-existing GPU buffers or to data in | ||
| 128 | /// host memory. | ||
| 129 | /// | ||
| 130 | /// If the buffer views do not already point to GPU buffers, GPU buffers are | ||
| 131 | /// created for the geometry. The 'buffer_usage' field specifies the usage for | ||
| 132 | /// the created buffers. Use BufferStatic for static geometry and BufferDynamic | ||
| 133 | /// for dynamic geometry. | ||
| 134 | /// | ||
| 135 | /// Currently we support only up to 16-bit vertex indices. Might have to change | ||
| 136 | /// this to support a larger variety of 3D models. | ||
| 137 | typedef struct GeometryDesc { | ||
| 138 | BufferView2d positions2d; | ||
| 139 | BufferView3d positions3d; | ||
| 140 | BufferView3d normals; | ||
| 141 | BufferView4d tangents; | ||
| 142 | BufferView2d texcoords; | ||
| 143 | struct { | ||
| 144 | BufferViewU8 u8; | ||
| 145 | BufferViewU16 u16; | ||
| 146 | } joints; // uvec4. | ||
| 147 | struct { | ||
| 148 | BufferViewFloat floats; | ||
| 149 | BufferViewU8 u8; | ||
| 150 | BufferViewU16 u16; | ||
| 151 | } weights; // vec4 or uvec4. | ||
| 152 | BufferViewIdx8 indices8; | ||
| 153 | BufferViewIdx16 indices16; | ||
| 154 | VertexCount num_verts; | ||
| 155 | size_t num_indices; | ||
| 156 | PrimitiveType type; | ||
| 157 | BufferUsage buffer_usage; | ||
| 158 | aabb3 aabb; | ||
| 159 | } GeometryDesc; | ||
| 160 | |||
| 161 | /// Shader compiler define. | ||
| 162 | typedef struct ShaderCompilerDefine { | ||
| 163 | sstring name; | ||
| 164 | sstring value; | ||
| 165 | } ShaderCompilerDefine; | ||
| 166 | |||
| 167 | /// Shader types. | ||
| 168 | typedef enum { VertexShader, FragmentShader } ShaderType; | ||
| 169 | |||
| 170 | /// Describes a shader. | ||
| 171 | typedef struct ShaderDesc { | ||
| 172 | ShaderType type; | ||
| 173 | const char* code; | ||
| 174 | ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES]; | ||
| 175 | size_t num_defines; | ||
| 176 | } ShaderDesc; | ||
| 177 | |||
| 178 | /// Describes a shader program. | ||
| 179 | typedef struct ShaderProgramDesc { | ||
| 180 | const Shader* vertex_shader; | ||
| 181 | const Shader* fragment_shader; | ||
| 182 | } ShaderProgramDesc; | ||
| 183 | |||
| 184 | /// Shader uniform type. | ||
| 185 | typedef enum { | ||
| 186 | UniformFloat, | ||
| 187 | UniformMat4, | ||
| 188 | UniformTexture, | ||
| 189 | UniformVec3, | ||
| 190 | UniformVec4, | ||
| 191 | UniformMat4Array | ||
| 192 | } UniformType; | ||
| 193 | |||
| 194 | /// Shader uniform. | ||
| 195 | /// | ||
| 196 | /// For uniform arrays, the client must ensure that the array is still valid by | ||
| 197 | /// the time the uniform data is passed to the GPU. | ||
| 198 | typedef struct ShaderUniform { | ||
| 199 | sstring name; | ||
| 200 | UniformType type; | ||
| 201 | union { | ||
| 202 | const Texture* texture; | ||
| 203 | mat4 mat4; | ||
| 204 | vec3 vec3; | ||
| 205 | vec4 vec4; | ||
| 206 | float scalar; | ||
| 207 | struct { | ||
| 208 | size_t count; | ||
| 209 | union { | ||
| 210 | const mat4* values; | ||
| 211 | }; | ||
| 212 | } array; | ||
| 213 | } value; | ||
| 214 | } ShaderUniform; | ||
| 215 | |||
| 216 | /// Texture dimension. | ||
| 217 | typedef enum { Texture2D, TextureCubeMap } TextureDimension; | ||
| 218 | |||
| 219 | /// Texture data format. | ||
| 220 | typedef enum { | ||
| 221 | TextureDepth, | ||
| 222 | TextureRG16, | ||
| 223 | TextureRG16F, | ||
| 224 | TextureRGB8, | ||
| 225 | TextureR11G11B10F, | ||
| 226 | TextureRGBA8, | ||
| 227 | TextureSRGB8, | ||
| 228 | TextureSRGBA8 | ||
| 229 | } TextureFormat; | ||
| 230 | |||
| 231 | /// Texture filtering. | ||
| 232 | typedef enum { NearestFiltering, LinearFiltering } TextureFiltering; | ||
| 233 | |||
| 234 | /// Texture wrap mode. | ||
| 235 | typedef enum { Repeat, ClampToEdge } TextureWrapping; | ||
| 236 | |||
| 237 | /// Cubemap faces. | ||
| 238 | typedef enum { | ||
| 239 | CubemapFacePosX, | ||
| 240 | CubemapFaceNegX, | ||
| 241 | CubemapFacePosY, | ||
| 242 | CubemapFaceNegY, | ||
| 243 | CubemapFacePosZ, | ||
| 244 | CubemapFaceNegZ | ||
| 245 | } CubemapFace; | ||
| 246 | |||
| 247 | /// Texture data descriptor. | ||
| 248 | typedef struct TextureDataDesc { | ||
| 249 | union { | ||
| 250 | const void* pixels; | ||
| 251 | struct { | ||
| 252 | const void* pixels_pos_x; | ||
| 253 | const void* pixels_neg_x; | ||
| 254 | const void* pixels_pos_y; | ||
| 255 | const void* pixels_neg_y; | ||
| 256 | const void* pixels_pos_z; | ||
| 257 | const void* pixels_neg_z; | ||
| 258 | } cubemap; | ||
| 259 | }; | ||
| 260 | } TextureDataDesc; | ||
| 261 | |||
| 262 | /// Describes a texture. | ||
| 263 | typedef struct TextureDesc { | ||
| 264 | int width; | ||
| 265 | int height; | ||
| 266 | int depth; // Not used until 3D textures are exposed. | ||
| 267 | TextureDimension dimension; | ||
| 268 | TextureFormat format; | ||
| 269 | TextureFiltering filtering; | ||
| 270 | TextureWrapping wrap; | ||
| 271 | bool mipmaps; | ||
| 272 | TextureDataDesc data; | ||
| 273 | } TextureDesc; | ||
| 274 | |||
| 275 | /// Describes a renderbuffer. | ||
| 276 | typedef struct RenderBufferDesc { | ||
| 277 | int width; | ||
| 278 | int height; | ||
| 279 | TextureFormat texture_format; | ||
| 280 | } RenderBufferDesc; | ||
| 281 | |||
| 282 | /// Framebuffer attachment type. | ||
| 283 | typedef enum FrameBufferAttachmentType { | ||
| 284 | FrameBufferNoAttachment, | ||
| 285 | FrameBufferTexture, | ||
| 286 | FrameBufferCubemapTexture, | ||
| 287 | FrameBufferRenderBuffer | ||
| 288 | } FrameBufferAttachmentType; | ||
| 289 | |||
| 290 | /// Describes a framebuffer attachment. | ||
| 291 | typedef struct FrameBufferAttachment { | ||
| 292 | FrameBufferAttachmentType type; | ||
| 293 | union { | ||
| 294 | struct { | ||
| 295 | Texture* texture; | ||
| 296 | int mip_level; | ||
| 297 | } texture; | ||
| 298 | struct { | ||
| 299 | Texture* texture; | ||
| 300 | int mip_level; | ||
| 301 | CubemapFace face; | ||
| 302 | } cubemap; | ||
| 303 | RenderBuffer* renderbuffer; | ||
| 304 | }; | ||
| 305 | } FrameBufferAttachment; | ||
| 306 | |||
| 307 | /// Describes a framebuffer. | ||
| 308 | typedef struct FrameBufferDesc { | ||
| 309 | FrameBufferAttachment colour; | ||
| 310 | FrameBufferAttachment depth; | ||
| 311 | } FrameBufferDesc; | ||
| 312 | |||
| 313 | // ----------------------------------------------------------------------------- | ||
| 314 | // Render commands. | ||
| 315 | // ----------------------------------------------------------------------------- | ||
| 316 | |||
| 317 | /// Start a new frame. | ||
| 318 | void gfx_start_frame(GfxCore*); | ||
| 319 | |||
| 320 | /// End a frame. | ||
| 321 | void gfx_end_frame(GfxCore*); | ||
| 322 | |||
| 323 | /// Set the render backend's viewport dimensions. | ||
| 324 | void gfx_set_viewport(GfxCore*, int x, int y, int width, int height); | ||
| 325 | |||
| 326 | /// Get the render backend's viewport dimensions. | ||
| 327 | void gfx_get_viewport(GfxCore*, int* x, int* y, int* width, int* height); | ||
| 328 | |||
| 329 | /// Clear the viewport. | ||
| 330 | void gfx_clear(GfxCore*, vec4 colour); | ||
| 331 | |||
| 332 | /// Set blending state. | ||
| 333 | void gfx_set_blending(GfxCore*, bool enable); | ||
| 334 | |||
| 335 | /// Set depth mask. | ||
| 336 | void gfx_set_depth_mask(GfxCore*, bool enable); | ||
| 337 | |||
| 338 | /// Set cull mode. | ||
| 339 | void gfx_set_culling(GfxCore*, bool enable); | ||
| 340 | |||
| 341 | /// Set polygon offset. | ||
| 342 | void gfx_set_polygon_offset(GfxCore*, float scale, float bias); | ||
| 343 | |||
| 344 | /// Reset the polygon offset. | ||
| 345 | void gfx_reset_polygon_offset(GfxCore*); | ||
| 346 | |||
| 347 | // ----------------------------------------------------------------------------- | ||
| 348 | // Buffers. | ||
| 349 | // ----------------------------------------------------------------------------- | ||
| 350 | |||
| 351 | /// Create a buffer from raw data. | ||
| 352 | Buffer* gfx_make_buffer(GfxCore*, const BufferDesc*); | ||
| 353 | |||
| 354 | /// Destroy the buffer. | ||
| 355 | void gfx_destroy_buffer(GfxCore*, Buffer**); | ||
| 356 | |||
| 357 | /// Update the buffer's data. | ||
| 358 | void gfx_update_buffer(Buffer*, const BufferDataDesc*); | ||
| 359 | |||
| 360 | // ----------------------------------------------------------------------------- | ||
| 361 | // Geometry. | ||
| 362 | // ----------------------------------------------------------------------------- | ||
| 363 | |||
| 364 | /// Create geometry. | ||
| 365 | Geometry* gfx_make_geometry(GfxCore*, const GeometryDesc*); | ||
| 366 | |||
| 367 | /// Destroy the geometry. | ||
| 368 | void gfx_destroy_geometry(GfxCore*, Geometry**); | ||
| 369 | |||
| 370 | /// Upload new vertex data for the geometry. | ||
| 371 | /// | ||
| 372 | /// This is similar to gfx_make_geometry(), but the geometry need not be | ||
| 373 | /// entirely specified. | ||
| 374 | /// | ||
| 375 | /// Only the vertex attributes, vertex count, and index count set in the | ||
| 376 | /// descriptor are updated. Index data, primitive type, and other properties of | ||
| 377 | /// the geometry are not updated. | ||
| 378 | /// | ||
| 379 | /// New data must be given as arrays in host memory. That is, the buffer views | ||
| 380 | /// in the descriptor must point to CPU arrays, not GPU buffers. | ||
| 381 | /// | ||
| 382 | /// Note that the descriptor cannot specify a larger vertex or index count than | ||
| 383 | /// what the geometry was created with. If the geometry size or any other | ||
| 384 | /// attribute not handled by this update function needs to be changed, then a | ||
| 385 | /// new geometry must be created. | ||
| 386 | void gfx_update_geometry(Geometry*, const GeometryDesc*); | ||
| 387 | |||
| 388 | /// Render the geometry. | ||
| 389 | void gfx_render_geometry(const Geometry*); | ||
| 390 | |||
| 391 | /// Return the geometry's bounding box. | ||
| 392 | aabb3 gfx_get_geometry_aabb(const Geometry*); | ||
| 393 | |||
| 394 | // ----------------------------------------------------------------------------- | ||
| 395 | // Textures. | ||
| 396 | // ----------------------------------------------------------------------------- | ||
| 397 | |||
| 398 | /// Create a texture. | ||
| 399 | Texture* gfx_make_texture(GfxCore*, const TextureDesc*); | ||
| 400 | |||
| 401 | /// Destroy the texture. | ||
| 402 | void gfx_destroy_texture(GfxCore*, Texture**); | ||
| 403 | |||
| 404 | /// Update the texture. | ||
| 405 | void gfx_update_texture(Texture*, const TextureDataDesc*); | ||
| 406 | |||
| 407 | // ----------------------------------------------------------------------------- | ||
| 408 | // Renderbuffers. | ||
| 409 | // ----------------------------------------------------------------------------- | ||
| 410 | |||
| 411 | /// Create a renderbuffer. | ||
| 412 | RenderBuffer* gfx_make_renderbuffer(GfxCore*, const RenderBufferDesc*); | ||
| 413 | |||
| 414 | /// Destroy the renderbuffer. | ||
| 415 | void gfx_destroy_renderbuffer(GfxCore*, RenderBuffer**); | ||
| 416 | |||
| 417 | // ----------------------------------------------------------------------------- | ||
| 418 | // Framebuffers. | ||
| 419 | // ----------------------------------------------------------------------------- | ||
| 420 | |||
| 421 | /// Create a framebuffer. | ||
| 422 | FrameBuffer* gfx_make_framebuffer(GfxCore*, const FrameBufferDesc*); | ||
| 423 | |||
| 424 | /// Destroy the framebuffer. | ||
| 425 | void gfx_destroy_framebuffer(GfxCore*, FrameBuffer**); | ||
| 426 | |||
| 427 | /// Attach a colour buffer to the framebuffer. | ||
| 428 | bool gfx_framebuffer_attach_colour(FrameBuffer*, const FrameBufferAttachment*); | ||
| 429 | |||
| 430 | /// Attach a depth buffer to the framebuffer. | ||
| 431 | bool gfx_framebuffer_attach_depth(FrameBuffer*, const FrameBufferAttachment*); | ||
| 432 | |||
| 433 | /// Activate the framebuffer. | ||
| 434 | /// Subsequent draw calls write to this framebuffer. | ||
| 435 | void gfx_activate_framebuffer(const FrameBuffer*); | ||
| 436 | |||
| 437 | /// Deactivate the framebuffer. | ||
| 438 | /// Subsequent draw calls write to the default framebuffer. | ||
| 439 | void gfx_deactivate_framebuffer(const FrameBuffer*); | ||
| 440 | |||
| 441 | /// Set the framebuffer's viewport. | ||
| 442 | /// This function should be called every time the framebuffer is activated. | ||
| 443 | void gfx_framebuffer_set_viewport( | ||
| 444 | FrameBuffer*, int x, int y, int width, int height); | ||
| 445 | |||
| 446 | // ----------------------------------------------------------------------------- | ||
| 447 | // Shaders. | ||
| 448 | // ----------------------------------------------------------------------------- | ||
| 449 | |||
| 450 | /// Create a shader. | ||
| 451 | Shader* gfx_make_shader(GfxCore*, const ShaderDesc*); | ||
| 452 | |||
| 453 | /// Destroy the shader. | ||
| 454 | void gfx_destroy_shader(GfxCore*, Shader**); | ||
| 455 | |||
| 456 | /// Create a shader program. | ||
| 457 | ShaderProgram* gfx_make_shader_program(GfxCore*, const ShaderProgramDesc*); | ||
| 458 | |||
| 459 | /// Destroy the shader program. | ||
| 460 | void gfx_destroy_shader_program(GfxCore*, ShaderProgram**); | ||
| 461 | |||
| 462 | /// Activate the shader program. | ||
| 463 | void gfx_activate_shader_program(const ShaderProgram*); | ||
| 464 | |||
| 465 | /// Deactivate the shader program. | ||
| 466 | void gfx_deactivate_shader_program(const ShaderProgram*); | ||
| 467 | |||
| 468 | /// Apply the shader program's uniform variables. | ||
| 469 | /// | ||
| 470 | /// Calls to gfx_set_XYZ_uniform save the values of the uniform variables in the | ||
| 471 | /// graphics library. By calling this function, those values are passed on to | ||
| 472 | /// the graphics driver for rendering. | ||
| 473 | /// | ||
| 474 | /// This function should be called after setting all of the uniform variables | ||
| 475 | /// and prior to issuing a draw call. | ||
| 476 | void gfx_apply_uniforms(const ShaderProgram*); | ||
| 477 | |||
| 478 | /// Set the texture uniform. | ||
| 479 | /// Has no effect if the shader does not contain the given uniform. | ||
| 480 | void gfx_set_texture_uniform(ShaderProgram*, const char* name, const Texture*); | ||
| 481 | |||
| 482 | /// Set the matrix uniform. | ||
| 483 | /// Has no effect if the shader does not contain the given uniform. | ||
| 484 | void gfx_set_mat4_uniform(ShaderProgram*, const char* name, const mat4*); | ||
| 485 | |||
| 486 | /// Set the vec3 uniform. | ||
| 487 | /// Has no effect if the shader does not contain the given uniform. | ||
| 488 | void gfx_set_vec3_uniform(ShaderProgram*, const char* name, vec3); | ||
| 489 | |||
| 490 | /// Set the vec4 uniform. | ||
| 491 | /// Has no effect if the shader does not contain the given uniform. | ||
| 492 | void gfx_set_vec4_uniform(ShaderProgram*, const char* name, vec4); | ||
| 493 | |||
| 494 | /// Set the float uniform. | ||
| 495 | /// Has no effect if the shader does not contain the given uniform. | ||
| 496 | void gfx_set_float_uniform(ShaderProgram*, const char* name, float value); | ||
| 497 | |||
| 498 | /// Set the matrix array uniform. | ||
| 499 | /// Has no effect if the shader does not contain the given uniform. | ||
| 500 | void gfx_set_mat4_array_uniform( | ||
| 501 | ShaderProgram*, const char* name, const mat4*, size_t count); | ||
diff --git a/include/gfx/gfx.h b/include/gfx/gfx.h new file mode 100644 index 0000000..7c670a5 --- /dev/null +++ b/include/gfx/gfx.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | typedef struct AssetCache AssetCache; | ||
| 4 | typedef struct GfxCore GfxCore; | ||
| 5 | typedef struct ImmRenderer ImmRenderer; | ||
| 6 | typedef struct Renderer Renderer; | ||
| 7 | |||
| 8 | typedef struct Gfx Gfx; | ||
| 9 | |||
| 10 | /// Create a new graphics system, | ||
| 11 | Gfx* gfx_init(void); | ||
| 12 | |||
| 13 | /// Destroy the graphics system. | ||
| 14 | void gfx_destroy(Gfx**); | ||
| 15 | |||
| 16 | /// Get the render backend. | ||
| 17 | GfxCore* gfx_get_core(Gfx*); | ||
| 18 | |||
| 19 | /// Get the renderer. | ||
| 20 | Renderer* gfx_get_renderer(Gfx*); | ||
| 21 | |||
| 22 | /// Get the immediate mode renderer. | ||
| 23 | ImmRenderer* gfx_get_imm_renderer(Gfx*); | ||
| 24 | |||
| 25 | /// Get the asset cache. | ||
| 26 | AssetCache* gfx_get_asset_cache(Gfx*); | ||
| 27 | |||
| 28 | /// Remove unused resources from the scene (meshes, materials). | ||
| 29 | /// TODO: need to think about the interface for scene_purge(). Maybe this | ||
| 30 | /// should be gfx_purge() and take a list of Scenes? | ||
| 31 | // void gfx_purge(Scene*); | ||
diff --git a/include/gfx/renderer.h b/include/gfx/renderer.h new file mode 100644 index 0000000..2a4ada1 --- /dev/null +++ b/include/gfx/renderer.h | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <math/aabb2.h> | ||
| 4 | #include <math/aabb3.h> | ||
| 5 | #include <math/camera.h> | ||
| 6 | #include <math/defs.h> | ||
| 7 | #include <math/mat4.h> | ||
| 8 | #include <math/vec3.h> | ||
| 9 | #include <math/vec4.h> | ||
| 10 | |||
| 11 | typedef struct GfxCore GfxCore; | ||
| 12 | typedef struct Scene Scene; | ||
| 13 | typedef struct SceneCamera SceneCamera; | ||
| 14 | |||
| 15 | typedef struct ImmRenderer ImmRenderer; | ||
| 16 | typedef struct Renderer Renderer; | ||
| 17 | |||
| 18 | // ----------------------------------------------------------------------------- | ||
| 19 | // Main Renderer. | ||
| 20 | // ----------------------------------------------------------------------------- | ||
| 21 | |||
| 22 | typedef enum RenderSceneMode { | ||
| 23 | RenderDefault, | ||
| 24 | RenderDebug, | ||
| 25 | RenderNormals, | ||
| 26 | RenderNormalMappedNormals, | ||
| 27 | RenderTangents | ||
| 28 | } RenderSceneMode; | ||
| 29 | |||
| 30 | typedef struct RenderSceneParams { | ||
| 31 | RenderSceneMode mode; | ||
| 32 | const Scene* scene; | ||
| 33 | const SceneCamera* camera; | ||
| 34 | } RenderSceneParams; | ||
| 35 | |||
| 36 | /// Render the scene. | ||
| 37 | void gfx_render_scene(Renderer*, const RenderSceneParams*); | ||
| 38 | |||
| 39 | /// Update the scene. | ||
| 40 | void gfx_update(Scene*, const SceneCamera*, R t); | ||
| 41 | |||
| 42 | // ----------------------------------------------------------------------------- | ||
| 43 | // Immediate Mode Renderer. | ||
| 44 | // ----------------------------------------------------------------------------- | ||
| 45 | |||
| 46 | /// Prepare the graphics systems for immediate-mode rendering. | ||
| 47 | /// | ||
| 48 | /// Call this before issuing any immediate-mode rendering draws. | ||
| 49 | void gfx_imm_start(ImmRenderer*); | ||
| 50 | |||
| 51 | /// End immediate mode rendering. | ||
| 52 | /// | ||
| 53 | /// Call this after issuing immediate-mode rendering draws and before swapping | ||
| 54 | /// buffers. | ||
| 55 | void gfx_imm_end(ImmRenderer*); | ||
| 56 | |||
| 57 | /// Draw a set of triangles. | ||
| 58 | void gfx_imm_draw_triangles(ImmRenderer*, const vec3[], size_t num_triangles); | ||
| 59 | |||
| 60 | /// Draw a triangle. | ||
| 61 | void gfx_imm_draw_triangle(ImmRenderer*, const vec3[3]); | ||
| 62 | |||
| 63 | /// Draw a bounding box. | ||
| 64 | void gfx_imm_draw_aabb2(ImmRenderer*, aabb2); | ||
| 65 | |||
| 66 | /// Draw a bounding box. | ||
| 67 | void gfx_imm_draw_aabb3(ImmRenderer*, aabb3); | ||
| 68 | |||
| 69 | /// Draw a box. | ||
| 70 | /// | ||
| 71 | /// The vertices must be given in the following order: | ||
| 72 | /// | ||
| 73 | /// 7 ----- 6 | ||
| 74 | /// / /| | ||
| 75 | /// 3 ----- 2 | | ||
| 76 | /// | | | | ||
| 77 | /// | 4 ----- 5 | ||
| 78 | /// |/ |/ | ||
| 79 | /// 0 ----- 1 | ||
| 80 | void gfx_imm_draw_box3(ImmRenderer* renderer, const vec3 vertices[8]); | ||
| 81 | |||
| 82 | /// Set the camera. | ||
| 83 | void gfx_imm_set_camera(ImmRenderer*, const Camera*); | ||
| 84 | |||
| 85 | /// Load an identity model matrix. Clears the matrix stack. | ||
| 86 | void gfx_imm_load_identity(ImmRenderer* renderer); | ||
| 87 | |||
| 88 | /// Push the given matrix to the matrix stack. | ||
| 89 | void gfx_imm_push_matrix(ImmRenderer* renderer, const mat4* matrix); | ||
| 90 | |||
| 91 | /// Pop the top of the matrix stack. | ||
| 92 | void gfx_imm_pop_matrix(ImmRenderer* renderer); | ||
| 93 | |||
| 94 | /// Push a translation matrix to the matrix stack. | ||
| 95 | void gfx_imm_translate(ImmRenderer* renderer, vec3 offset); | ||
| 96 | |||
| 97 | /// Set the model matrix. Clears the matrix stack. | ||
| 98 | void gfx_imm_set_model_matrix(ImmRenderer*, const mat4*); | ||
| 99 | |||
| 100 | /// Set the view-projection matrix. | ||
| 101 | void gfx_imm_set_view_projection_matrix(ImmRenderer*, const mat4*); | ||
| 102 | |||
| 103 | /// Set the render colour. | ||
| 104 | void gfx_imm_set_colour(ImmRenderer*, vec4 colour); | ||
diff --git a/include/gfx/scene.h b/include/gfx/scene.h new file mode 100644 index 0000000..abcaa70 --- /dev/null +++ b/include/gfx/scene.h | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <gfx/scene/animation.h> | ||
| 4 | #include <gfx/scene/camera.h> | ||
| 5 | #include <gfx/scene/light.h> | ||
| 6 | #include <gfx/scene/material.h> | ||
| 7 | #include <gfx/scene/mesh.h> | ||
| 8 | #include <gfx/scene/model.h> | ||
| 9 | #include <gfx/scene/node.h> | ||
| 10 | #include <gfx/scene/object.h> | ||
| 11 | #include <gfx/scene/scene.h> | ||
diff --git a/include/gfx/scene/animation.h b/include/gfx/scene/animation.h new file mode 100644 index 0000000..d95b895 --- /dev/null +++ b/include/gfx/scene/animation.h | |||
| @@ -0,0 +1,142 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "node.h" | ||
| 4 | #include "object.h" | ||
| 5 | #include <gfx/sizes.h> | ||
| 6 | |||
| 7 | #include <cstring.h> | ||
| 8 | #include <math/aabb3.h> | ||
| 9 | #include <math/defs.h> | ||
| 10 | #include <math/mat4.h> | ||
| 11 | #include <math/quat.h> | ||
| 12 | #include <math/vec3.h> | ||
| 13 | |||
| 14 | #include <stdbool.h> | ||
| 15 | #include <stddef.h> | ||
| 16 | #include <stdint.h> | ||
| 17 | |||
| 18 | typedef struct Buffer Buffer; | ||
| 19 | typedef struct SceneNode SceneNode; | ||
| 20 | |||
| 21 | typedef struct Anima Anima; | ||
| 22 | typedef struct Joint Joint; | ||
| 23 | typedef struct Skeleton Skeleton; | ||
| 24 | |||
| 25 | /// Index type used to store relative indices into arrays. | ||
| 26 | typedef uint16_t joint_idx; | ||
| 27 | |||
| 28 | /// Index value denoting no index. | ||
| 29 | static const joint_idx INDEX_NONE = (joint_idx)-1; | ||
| 30 | |||
| 31 | typedef struct Box { | ||
| 32 | vec3 vertices[8]; | ||
| 33 | } Box; | ||
| 34 | |||
| 35 | /// Joint descriptor. | ||
| 36 | typedef struct JointDesc { | ||
| 37 | joint_idx parent; /// Parent Joint; index into Anima's joints. | ||
| 38 | mat4 inv_bind_matrix; /// Transforms the mesh into the joint's local space. | ||
| 39 | aabb3 box; /// Bounding box. | ||
| 40 | } JointDesc; | ||
| 41 | |||
| 42 | /// Skeleton descriptor. | ||
| 43 | typedef struct SkeletonDesc { | ||
| 44 | size_t num_joints; | ||
| 45 | joint_idx joints[GFX_MAX_NUM_JOINTS]; /// Indices into Anima's joints array. | ||
| 46 | } SkeletonDesc; | ||
| 47 | |||
| 48 | /// Animation interpolation mode. | ||
| 49 | typedef enum AnimationInterpolation { | ||
| 50 | StepInterpolation, | ||
| 51 | LinearInterpolation, | ||
| 52 | CubicSplineInterpolation | ||
| 53 | } AnimationInterpolation; | ||
| 54 | |||
| 55 | /// The kind of transformation applied by a Channel. | ||
| 56 | typedef enum ChannelType { | ||
| 57 | RotationChannel, | ||
| 58 | ScaleChannel, | ||
| 59 | TranslationChannel, | ||
| 60 | WeightsChannel | ||
| 61 | } ChannelType; | ||
| 62 | |||
| 63 | /// Animation keyframe descriptor. | ||
| 64 | /// | ||
| 65 | /// The arrays should have as many entries as 'num_joints' in the SkeletonDesc. | ||
| 66 | typedef struct KeyframeDesc { | ||
| 67 | R time; // Start time in [0, end animation time] | ||
| 68 | union { | ||
| 69 | vec3 translation; | ||
| 70 | quat rotation; | ||
| 71 | }; | ||
| 72 | } KeyframeDesc; | ||
| 73 | |||
| 74 | /// Animation channel descriptor. | ||
| 75 | typedef struct ChannelDesc { | ||
| 76 | joint_idx target; /// Index into Anima's joints array. | ||
| 77 | ChannelType type; | ||
| 78 | AnimationInterpolation interpolation; | ||
| 79 | size_t num_keyframes; | ||
| 80 | KeyframeDesc keyframes[GFX_MAX_NUM_KEYFRAMES]; | ||
| 81 | } ChannelDesc; | ||
| 82 | |||
| 83 | /// Animation descriptor. | ||
| 84 | typedef struct AnimationDesc { | ||
| 85 | // TODO: Store a name hash for faster comparisons. | ||
| 86 | sstring name; // Animation name. Required for playback. | ||
| 87 | size_t num_channels; // Number of channels. | ||
| 88 | ChannelDesc channels[GFX_MAX_NUM_CHANNELS]; | ||
| 89 | } AnimationDesc; | ||
| 90 | |||
| 91 | /// Anima object descriptor. | ||
| 92 | /// | ||
| 93 | /// The last joint of the joints array at index 'num_joints - 1' must be the | ||
| 94 | /// root of all skeletons; specifically, the root of all joints that otherwise | ||
| 95 | /// would have no parent (a skeleton need not have its own root and can be a set | ||
| 96 | /// of disjoint node hierarchies). | ||
| 97 | typedef struct AnimaDesc { | ||
| 98 | size_t num_skeletons; | ||
| 99 | size_t num_animations; | ||
| 100 | size_t num_joints; | ||
| 101 | SkeletonDesc skeletons[GFX_MAX_NUM_SKELETONS]; | ||
| 102 | AnimationDesc animations[GFX_MAX_NUM_ANIMATIONS]; | ||
| 103 | JointDesc joints[GFX_MAX_NUM_JOINTS]; | ||
| 104 | } AnimaDesc; | ||
| 105 | |||
| 106 | /// Animation play settings. | ||
| 107 | typedef struct AnimationPlaySettings { | ||
| 108 | const char* name; // Animation name. | ||
| 109 | bool loop; // Whether to loop the animation or just play once. | ||
| 110 | // TODO: Add animation speed. | ||
| 111 | } AnimationPlaySettings; | ||
| 112 | |||
| 113 | /// Create an anima object. | ||
| 114 | Anima* gfx_make_anima(const AnimaDesc*); | ||
| 115 | |||
| 116 | /// Destroy the anima. | ||
| 117 | void gfx_destroy_anima(Anima**); | ||
| 118 | |||
| 119 | /// Play an animation (sets the current animation). | ||
| 120 | bool gfx_play_animation(Anima*, const AnimationPlaySettings*); | ||
| 121 | |||
| 122 | /// Update the current animation. | ||
| 123 | void gfx_update_animation(Anima*, R t); | ||
| 124 | |||
| 125 | /// Stop the current animation. | ||
| 126 | void gfx_stop_animation(Anima*); | ||
| 127 | |||
| 128 | /// Return the anima's ith skeleton. | ||
| 129 | const Skeleton* gfx_get_anima_skeleton(const Anima* anima, size_t i); | ||
| 130 | |||
| 131 | /// Return the number of joints in the skeleton. | ||
| 132 | size_t gfx_get_skeleton_num_joints(const Skeleton*); | ||
| 133 | |||
| 134 | /// Return true if the skeleton's ith joint has a bounding box. | ||
| 135 | /// | ||
| 136 | /// IK joints that do not directly transform vertices have no bounding box. | ||
| 137 | bool gfx_joint_has_box(const Anima*, const Skeleton*, size_t joint); | ||
| 138 | |||
| 139 | /// Return the bounding box of the skeleton's ith joint. | ||
| 140 | /// | ||
| 141 | /// IK joints that do not directly transform vertices have no box. | ||
| 142 | Box gfx_get_joint_box(const Anima*, const Skeleton*, size_t joint); | ||
diff --git a/include/gfx/scene/camera.h b/include/gfx/scene/camera.h new file mode 100644 index 0000000..99d83fe --- /dev/null +++ b/include/gfx/scene/camera.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <math/fwd.h> | ||
| 4 | |||
| 5 | typedef struct SceneNode SceneNode; | ||
| 6 | |||
| 7 | typedef struct SceneCamera SceneCamera; | ||
| 8 | |||
| 9 | /// Create a new camera. | ||
| 10 | SceneCamera* gfx_make_camera(); | ||
| 11 | |||
| 12 | /// Destroy the camera. | ||
| 13 | /// | ||
| 14 | /// The camera is conveniently removed from the scene graph and its parent scene | ||
| 15 | /// node is destroyed. | ||
| 16 | void gfx_destroy_camera(SceneCamera**); | ||
| 17 | |||
| 18 | /// Set the scene camera's math camera. | ||
| 19 | void gfx_set_camera_camera(SceneCamera* scene_camera, Camera* camera); | ||
| 20 | |||
| 21 | /// Get the scene camera's math camera. | ||
| 22 | Camera* gfx_get_camera_camera(SceneCamera*); | ||
diff --git a/include/gfx/scene/light.h b/include/gfx/scene/light.h new file mode 100644 index 0000000..132e344 --- /dev/null +++ b/include/gfx/scene/light.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | typedef struct Texture Texture; | ||
| 4 | |||
| 5 | typedef struct Light Light; | ||
| 6 | |||
| 7 | /// Light type. | ||
| 8 | typedef enum LightType { EnvironmentLightType } LightType; | ||
| 9 | |||
| 10 | /// Describes an environment light. | ||
| 11 | typedef struct EnvironmentLightDesc { | ||
| 12 | const Texture* environment_map; | ||
| 13 | } EnvironmentLightDesc; | ||
| 14 | |||
| 15 | /// Describes a light. | ||
| 16 | typedef struct LightDesc { | ||
| 17 | LightType type; | ||
| 18 | union { | ||
| 19 | EnvironmentLightDesc environment; | ||
| 20 | } light; | ||
| 21 | } LightDesc; | ||
| 22 | |||
| 23 | /// Create a light. | ||
| 24 | Light* gfx_make_light(const LightDesc*); | ||
| 25 | |||
| 26 | /// Destroy the light. | ||
| 27 | /// | ||
| 28 | /// The light is conveniently removed from the scene graph and its parent scene | ||
| 29 | /// node is destroyed. | ||
| 30 | void gfx_destroy_light(Light**); | ||
diff --git a/include/gfx/scene/material.h b/include/gfx/scene/material.h new file mode 100644 index 0000000..bca664e --- /dev/null +++ b/include/gfx/scene/material.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <gfx/core.h> | ||
| 4 | #include <gfx/sizes.h> | ||
| 5 | |||
| 6 | typedef struct Material Material; | ||
| 7 | |||
| 8 | /// Describes a material. | ||
| 9 | /// | ||
| 10 | /// A material holds a shader program and a set of shader-specific uniform | ||
| 11 | /// variables. Two materials can share the same shader, but shader parameters | ||
| 12 | /// generally give two materials a different appearance. | ||
| 13 | typedef struct MaterialDesc { | ||
| 14 | ShaderUniform uniforms[GFX_MAX_UNIFORMS_PER_MATERIAL]; | ||
| 15 | int num_uniforms; | ||
| 16 | } MaterialDesc; | ||
| 17 | |||
| 18 | /// Create a material. | ||
| 19 | Material* gfx_make_material(const MaterialDesc*); | ||
| 20 | |||
| 21 | /// Destroy the material. | ||
| 22 | /// | ||
| 23 | /// The caller must make sure that no Mesh points to the given Material. | ||
| 24 | /// For a safe purge of unused resources, see scene_purge(). | ||
| 25 | void gfx_destroy_material(Material**); | ||
diff --git a/include/gfx/scene/mesh.h b/include/gfx/scene/mesh.h new file mode 100644 index 0000000..0d3b4d4 --- /dev/null +++ b/include/gfx/scene/mesh.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | typedef struct Geometry Geometry; | ||
| 4 | typedef struct Material Material; | ||
| 5 | typedef struct ShaderProgram ShaderProgram; | ||
| 6 | |||
| 7 | typedef struct Mesh Mesh; | ||
| 8 | |||
| 9 | /// Describes a mesh. | ||
| 10 | typedef struct MeshDesc { | ||
| 11 | const Geometry* geometry; | ||
| 12 | const Material* material; | ||
| 13 | ShaderProgram* shader; | ||
| 14 | } MeshDesc; | ||
| 15 | |||
| 16 | /// Create a mesh. | ||
| 17 | Mesh* gfx_make_mesh(const MeshDesc*); | ||
| 18 | |||
| 19 | /// Destroy the mesh. | ||
| 20 | /// | ||
| 21 | /// The caller must make sure that no SceneObject points to the given Mesh. | ||
| 22 | /// For a safe purge of unused resources, see scene_purge(). | ||
| 23 | void gfx_destroy_mesh(Mesh**); | ||
diff --git a/include/gfx/scene/model.h b/include/gfx/scene/model.h new file mode 100644 index 0000000..42f85d4 --- /dev/null +++ b/include/gfx/scene/model.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | typedef struct Anima Anima; | ||
| 4 | typedef struct Model Model; | ||
| 5 | typedef struct SceneNode SceneNode; | ||
| 6 | |||
| 7 | /// Return the model's anima, or null if the model is not animated. | ||
| 8 | Anima* gfx_get_model_anima(Model*); | ||
| 9 | |||
| 10 | /// Return the model's root node. | ||
| 11 | const SceneNode* gfx_get_model_root(const Model*); | ||
| 12 | SceneNode* gfx_get_model_root_mut(Model*); | ||
diff --git a/include/gfx/scene/node.h b/include/gfx/scene/node.h new file mode 100644 index 0000000..a2c2836 --- /dev/null +++ b/include/gfx/scene/node.h | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "animation.h" | ||
| 4 | |||
| 5 | #include <math/fwd.h> | ||
| 6 | #include <math/mat4.h> | ||
| 7 | |||
| 8 | #include <stdint.h> | ||
| 9 | |||
| 10 | typedef struct Anima Anima; | ||
| 11 | typedef struct Light Light; | ||
| 12 | typedef struct Model Model; | ||
| 13 | typedef struct SceneCamera SceneCamera; | ||
| 14 | typedef struct SceneObject SceneObject; | ||
| 15 | |||
| 16 | /// Scene node type. | ||
| 17 | typedef enum NodeType { | ||
| 18 | LogicalNode, | ||
| 19 | AnimaNode, | ||
| 20 | CameraNode, | ||
| 21 | LightNode, | ||
| 22 | ModelNode, | ||
| 23 | ObjectNode, | ||
| 24 | } NodeType; | ||
| 25 | |||
| 26 | /// A node in the scene graph. | ||
| 27 | /// | ||
| 28 | /// Scene nodes take ownership of the object they are associated with (Camera, | ||
| 29 | /// Light, SceneObject, etc), as well as of child nodes. | ||
| 30 | typedef struct SceneNode SceneNode; | ||
| 31 | |||
| 32 | // ----------------------------------------------------------------------------- | ||
| 33 | // Constructors and destructor. | ||
| 34 | // ----------------------------------------------------------------------------- | ||
| 35 | |||
| 36 | /// Create a new scene node. | ||
| 37 | /// | ||
| 38 | /// This node does not contain any camera, light, object, etc. and exists simply | ||
| 39 | /// as a logical and spatial construct. | ||
| 40 | SceneNode* gfx_make_node(); | ||
| 41 | |||
| 42 | /// Create an anima node. | ||
| 43 | SceneNode* gfx_make_anima_node(Anima*); | ||
| 44 | |||
| 45 | /// Create a new camera node. | ||
| 46 | SceneNode* gfx_make_camera_node(SceneCamera*); | ||
| 47 | |||
| 48 | /// Create a new light node. | ||
| 49 | SceneNode* gfx_make_light_node(Light*); | ||
| 50 | |||
| 51 | /// Create a new model node. | ||
| 52 | SceneNode* gfx_make_model_node(Model*); | ||
| 53 | |||
| 54 | /// Create a new object node. | ||
| 55 | SceneNode* gfx_make_object_node(SceneObject*); | ||
| 56 | |||
| 57 | /// Make the node an anima node. | ||
| 58 | void gfx_construct_anima_node(SceneNode*, Anima*); | ||
| 59 | |||
| 60 | /// Make the node a camera node. | ||
| 61 | void gfx_construct_camera_node(SceneNode*, SceneCamera*); | ||
| 62 | |||
| 63 | /// Make the node a light node. | ||
| 64 | void gfx_construct_light_node(SceneNode*, Light*); | ||
| 65 | |||
| 66 | /// Make the node a model node. | ||
| 67 | void gfx_construct_model_node(SceneNode*, Model*); | ||
| 68 | |||
| 69 | /// Make the node an object node. | ||
| 70 | void gfx_construct_object_node(SceneNode*, SceneObject*); | ||
| 71 | |||
| 72 | /// Recursively destroy the scene node and its children. | ||
| 73 | /// | ||
| 74 | /// The scene node and its children are removed from the scene graph. | ||
| 75 | /// | ||
| 76 | /// Node resources -- cameras, lights, objects, etc. -- are also destroyed. | ||
| 77 | void gfx_destroy_node(SceneNode**); | ||
| 78 | |||
| 79 | // ----------------------------------------------------------------------------- | ||
| 80 | // Getters. | ||
| 81 | // ----------------------------------------------------------------------------- | ||
| 82 | |||
| 83 | /// Get the node's type. | ||
| 84 | NodeType gfx_get_node_type(const SceneNode*); | ||
| 85 | |||
| 86 | /// Get the node's anima. | ||
| 87 | /// | ||
| 88 | /// The node must be of type AnimaNode. | ||
| 89 | const Anima* gfx_get_node_anima(const SceneNode*); | ||
| 90 | Anima* gfx_get_node_anima_mut(SceneNode*); | ||
| 91 | |||
| 92 | /// Get the node's camera. | ||
| 93 | /// | ||
| 94 | /// The node must be of type CameraNode. | ||
| 95 | const SceneCamera* gfx_get_node_camera(const SceneNode* node); | ||
| 96 | SceneCamera* gfx_get_node_camera_mut(SceneNode* node); | ||
| 97 | |||
| 98 | /// Get the node's light. | ||
| 99 | /// | ||
| 100 | /// The node must be of type LightNode. | ||
| 101 | const Light* gfx_get_node_light(const SceneNode*); | ||
| 102 | Light* gfx_get_node_light_mut(SceneNode*); | ||
| 103 | |||
| 104 | /// Get the node's model. | ||
| 105 | /// | ||
| 106 | /// The node must be of type ModelNode. | ||
| 107 | const Model* gfx_get_node_model(const SceneNode*); | ||
| 108 | Model* gfx_get_node_model_mut(SceneNode*); | ||
| 109 | |||
| 110 | /// Get the node's scene object. | ||
| 111 | /// | ||
| 112 | /// The node must be of type ObjectNode. | ||
| 113 | const SceneObject* gfx_get_node_object(const SceneNode*); | ||
| 114 | SceneObject* gfx_get_node_object_mut(SceneNode*); | ||
| 115 | |||
| 116 | /// Get the node's parent. | ||
| 117 | const SceneNode* gfx_get_node_parent(const SceneNode*); | ||
| 118 | SceneNode* gfx_get_node_parent_mut(SceneNode*); | ||
| 119 | |||
| 120 | /// Get the node's first child. | ||
| 121 | const SceneNode* gfx_get_node_child(const SceneNode*); | ||
| 122 | SceneNode* gfx_get_node_child_mut(SceneNode*); | ||
| 123 | |||
| 124 | /// Get the node's immediate sibling. | ||
| 125 | const SceneNode* gfx_get_node_sibling(const SceneNode*); | ||
| 126 | SceneNode* gfx_get_node_sibling_mut(SceneNode*); | ||
| 127 | |||
| 128 | /// Get the node's (local) transform. | ||
| 129 | mat4 gfx_get_node_transform(const SceneNode*); | ||
| 130 | |||
| 131 | /// Get the node's global transform. | ||
| 132 | mat4 gfx_get_node_global_transform(const SceneNode*); | ||
| 133 | |||
| 134 | // ----------------------------------------------------------------------------- | ||
| 135 | // Setters. | ||
| 136 | // ----------------------------------------------------------------------------- | ||
| 137 | |||
| 138 | /// Set the node's parent. | ||
| 139 | /// | ||
| 140 | /// Pass in null to unwire from the existing parent, if one exists. | ||
| 141 | void gfx_set_node_parent(SceneNode*, SceneNode* parent_node); | ||
| 142 | |||
| 143 | /// Set the node's (local) transform. | ||
| 144 | void gfx_set_node_transform(SceneNode*, const mat4* transform); | ||
| 145 | |||
| 146 | /// Set the node's position. | ||
| 147 | void gfx_set_node_position(SceneNode*, const vec3* position); | ||
| 148 | |||
| 149 | /// Set the node's rotation. | ||
| 150 | void gfx_set_node_rotation(SceneNode*, const quat* rotation); | ||
| 151 | |||
| 152 | /// Set the node's rotation. | ||
| 153 | void gfx_set_node_rotation_mat(SceneNode*, const mat4* rotation); | ||
| 154 | |||
| 155 | /// Log the node's hierarchy. | ||
| 156 | void gfx_log_node_hierarchy(const SceneNode*); | ||
diff --git a/include/gfx/scene/object.h b/include/gfx/scene/object.h new file mode 100644 index 0000000..7579d29 --- /dev/null +++ b/include/gfx/scene/object.h | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <gfx/sizes.h> | ||
| 4 | |||
| 5 | #include <math/fwd.h> | ||
| 6 | |||
| 7 | #include <math/aabb3.h> | ||
| 8 | |||
| 9 | typedef struct Mesh Mesh; | ||
| 10 | typedef struct SceneNode SceneNode; | ||
| 11 | typedef struct Skeleton Skeleton; | ||
| 12 | |||
| 13 | typedef struct SceneObject SceneObject; | ||
| 14 | |||
| 15 | typedef struct ObjectDesc { | ||
| 16 | size_t num_meshes; | ||
| 17 | Mesh* meshes[GFX_MAX_NUM_MESHES]; | ||
| 18 | } ObjectDesc; | ||
| 19 | |||
| 20 | /// Create a new object. | ||
| 21 | SceneObject* gfx_make_object(const ObjectDesc*); | ||
| 22 | |||
| 23 | /// Destroy the object. | ||
| 24 | /// | ||
| 25 | /// The object is conveniently removed from the scene graph and its parent scene | ||
| 26 | /// node is destroyed. | ||
| 27 | void gfx_destroy_object(SceneObject**); | ||
| 28 | |||
| 29 | /// Set the object's skeleton. | ||
| 30 | void gfx_set_object_skeleton(SceneObject*, const Skeleton*); | ||
| 31 | |||
| 32 | /// Get the object's skeleton. | ||
| 33 | /// Return null if the object has no skeleton. | ||
| 34 | const Skeleton* gfx_get_object_skeleton(const SceneObject*); | ||
| 35 | |||
| 36 | /// Gets the object's bounding box. | ||
| 37 | /// | ||
| 38 | /// The object's bounding box is the bounding box of its mesh geometries. | ||
| 39 | aabb3 gfx_get_object_aabb(const SceneObject*); | ||
diff --git a/include/gfx/scene/scene.h b/include/gfx/scene/scene.h new file mode 100644 index 0000000..0d96210 --- /dev/null +++ b/include/gfx/scene/scene.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <math/defs.h> | ||
| 4 | #include <math/fwd.h> | ||
| 5 | |||
| 6 | typedef struct SceneNode SceneNode; | ||
| 7 | |||
| 8 | typedef struct Scene Scene; | ||
| 9 | |||
| 10 | /// Create a new scene. | ||
| 11 | Scene* gfx_make_scene(void); | ||
| 12 | |||
| 13 | /// Destroy the scene. | ||
| 14 | /// | ||
| 15 | /// This function destroys the scene and all objects that it owns (scene | ||
| 16 | /// objects, cameras, lights, etc), but not objects that could be shared with | ||
| 17 | /// other scenes (meshes, materials, etc). | ||
| 18 | void gfx_destroy_scene(Scene**); | ||
| 19 | |||
| 20 | /// Get the scene's root node. | ||
| 21 | SceneNode* gfx_get_scene_root(Scene*); | ||
diff --git a/include/gfx/sizes.h b/include/gfx/sizes.h new file mode 100644 index 0000000..076113c --- /dev/null +++ b/include/gfx/sizes.h | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | /// Size constants used throughout the library. | ||
| 2 | #pragma once | ||
| 3 | |||
| 4 | // Scene. | ||
| 5 | |||
| 6 | /// Maximum number of cameras per scene. | ||
| 7 | #define GFX_MAX_NUM_CAMERAS 16 | ||
| 8 | |||
| 9 | /// Maximum number of lights. | ||
| 10 | #define GFX_MAX_NUM_LIGHTS 1024 | ||
| 11 | |||
| 12 | /// Maximum number of materials. | ||
| 13 | #define GFX_MAX_NUM_MATERIALS 1024 | ||
| 14 | |||
| 15 | /// Maximum number of meshes. | ||
| 16 | #define GFX_MAX_NUM_MESHES 1024 | ||
| 17 | |||
| 18 | /// Maximum number of mesh links. | ||
| 19 | #define GFX_MAX_NUM_MESH_LINKS 1024 | ||
| 20 | |||
| 21 | /// Maximum number of models. | ||
| 22 | #define GFX_MAX_NUM_MODELS 64 | ||
| 23 | |||
| 24 | /// Maximum number of joints per skeleton. | ||
| 25 | #define GFX_MAX_NUM_JOINTS 96 | ||
| 26 | |||
| 27 | /// Maximum number of keyframes per channel. | ||
| 28 | #define GFX_MAX_NUM_KEYFRAMES 32 | ||
| 29 | |||
| 30 | /// Maximum number of channels per animation. | ||
| 31 | #define GFX_MAX_NUM_CHANNELS 128 | ||
| 32 | |||
| 33 | /// Maximum number of skeletons. | ||
| 34 | #define GFX_MAX_NUM_SKELETONS 128 | ||
| 35 | |||
| 36 | /// Maximum number of animations. | ||
| 37 | #define GFX_MAX_NUM_ANIMATIONS 128 | ||
| 38 | |||
| 39 | /// Maximum number of animas. | ||
| 40 | #define GFX_MAX_NUM_ANIMAS 128 | ||
| 41 | |||
| 42 | /// Maximum number of nodes per scene. | ||
| 43 | #define GFX_MAX_NUM_NODES 1024 | ||
| 44 | |||
| 45 | /// Maximum number of objects per scene. | ||
| 46 | #define GFX_MAX_NUM_OBJECTS 1024 | ||
| 47 | |||
| 48 | /// Maximum number of uniforms in a Material. | ||
| 49 | #define GFX_MAX_UNIFORMS_PER_MATERIAL 18 | ||
| 50 | |||
| 51 | // Render. | ||
| 52 | |||
| 53 | /// Maximum number of buffers per renderer. | ||
| 54 | #define GFX_MAX_NUM_BUFFERS 1024 | ||
| 55 | |||
| 56 | /// Maximum number of framebuffers per renderer. | ||
| 57 | #define GFX_MAX_NUM_FRAMEBUFFERS 32 | ||
| 58 | |||
| 59 | /// Maximum number of geometries per renderer. | ||
| 60 | #define GFX_MAX_NUM_GEOMETRIES 1024 | ||
| 61 | |||
| 62 | /// Maximum number of renderbuffers per renderer. | ||
| 63 | #define GFX_MAX_NUM_RENDERBUFFERS (GFX_MAX_NUM_FRAMEBUFFERS * 2) | ||
| 64 | |||
| 65 | /// Maximum number of shader programs per renderer. | ||
| 66 | #define GFX_MAX_NUM_SHADER_PROGRAMS 128 | ||
| 67 | |||
| 68 | /// Maximum number of shaders per renderer. | ||
| 69 | #define GFX_MAX_NUM_SHADERS (GFX_MAX_NUM_SHADER_PROGRAMS * 2) | ||
| 70 | |||
| 71 | /// Maximum number of textures per renderer. | ||
| 72 | #define GFX_MAX_NUM_TEXTURES 1024 | ||
| 73 | |||
| 74 | /// Maximum number of uniforms in a ShaderProgram. | ||
| 75 | #define GFX_MAX_UNIFORMS_PER_SHADER (GFX_MAX_UNIFORMS_PER_MATERIAL + 8) | ||
| 76 | |||
| 77 | /// Maximum number of compiler defines in a Shader. | ||
| 78 | #define GFX_MAX_SHADER_COMPILER_DEFINES 16 | ||
| 79 | |||
| 80 | // Renderer. | ||
| 81 | |||
| 82 | /// Maximum number of triangles that the immediate-mode renderer can draw in a | ||
| 83 | /// frame. | ||
| 84 | #define IMM_MAX_NUM_TRIANGLES 1024 | ||
| 85 | |||
| 86 | /// Maximum number of matrices in the immediate-mode renderer's matrix stack. | ||
| 87 | #define IMM_MAX_NUM_MATRICES 32 | ||
| 88 | |||
| 89 | // Asset Manager. | ||
| 90 | |||
| 91 | #define GFX_MAX_NUM_ASSETS 1024 | ||
| 92 | |||
| 93 | // Gfx. | ||
| 94 | |||
| 95 | #define GFX_MAX_NUM_SCENES 4 | ||
diff --git a/include/gfx/util/geometry.h b/include/gfx/util/geometry.h new file mode 100644 index 0000000..a962291 --- /dev/null +++ b/include/gfx/util/geometry.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /// Functions to construct geometry procedurally. | ||
| 2 | #pragma once | ||
| 3 | |||
| 4 | #include <gfx/core.h> | ||
| 5 | |||
| 6 | #include <math/vec2.h> | ||
| 7 | #include <math/vec3.h> | ||
| 8 | |||
| 9 | /// Construct a quad with positions in the range [-1, 1]^2. | ||
| 10 | Geometry* gfx_make_quad_11(GfxCore*); | ||
| 11 | |||
| 12 | /// Construct a quad with positions in the range [0, 1]^2. | ||
| 13 | Geometry* gfx_make_quad_01(GfxCore*); | ||
diff --git a/include/gfx/util/ibl.h b/include/gfx/util/ibl.h new file mode 100644 index 0000000..6e39180 --- /dev/null +++ b/include/gfx/util/ibl.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /// Functions for image-based lighting. | ||
| 2 | #pragma once | ||
| 3 | |||
| 4 | typedef struct IBL IBL; | ||
| 5 | |||
| 6 | typedef struct GfxCore GfxCore; | ||
| 7 | typedef struct Texture Texture; | ||
| 8 | |||
| 9 | /// Create an environment map filterer for IBL. | ||
| 10 | IBL* gfx_make_ibl(GfxCore*); | ||
| 11 | |||
| 12 | /// Destroy the environment map filterer. | ||
| 13 | void gfx_destroy_ibl(GfxCore*, IBL**); | ||
| 14 | |||
| 15 | /// Create a BRDF integration map for IBL. | ||
| 16 | Texture* gfx_make_brdf_integration_map(IBL*, GfxCore*, int width, int height); | ||
| 17 | |||
| 18 | /// Create an irradiance map (cubemap) from an environment map for IBL. | ||
| 19 | Texture* gfx_make_irradiance_map( | ||
| 20 | IBL*, GfxCore*, const Texture* environment_map, int width, int height); | ||
| 21 | |||
| 22 | /// Create a prefiltered environment map (cubemap) for IBL. | ||
| 23 | Texture* gfx_make_prefiltered_environment_map( | ||
| 24 | IBL*, GfxCore*, const Texture* environment_map, int width, int height, | ||
| 25 | int* max_mip_level); | ||
diff --git a/include/gfx/util/shader.h b/include/gfx/util/shader.h new file mode 100644 index 0000000..bd058f4 --- /dev/null +++ b/include/gfx/util/shader.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /// A variety of shaders included for convenience. | ||
| 2 | #pragma once | ||
| 3 | |||
| 4 | #include <stddef.h> | ||
| 5 | |||
| 6 | typedef struct GfxCore GfxCore; | ||
| 7 | typedef struct ShaderCompilerDefine ShaderCompilerDefine; | ||
| 8 | typedef struct ShaderProgram ShaderProgram; | ||
| 9 | |||
| 10 | /// Create a BRDF integration map shader. | ||
| 11 | ShaderProgram* gfx_make_brdf_integration_map_shader(GfxCore*); | ||
| 12 | |||
| 13 | /// Create a Cook-Torrance shader. | ||
| 14 | ShaderProgram* gfx_make_cook_torrance_shader(GfxCore*); | ||
| 15 | |||
| 16 | /// Create a Cook-Torrance shader with additional shader compiler defines. | ||
| 17 | /// This function can be used to create shader permutations. | ||
| 18 | ShaderProgram* gfx_make_cook_torrance_shader_perm( | ||
| 19 | GfxCore*, const ShaderCompilerDefine*, size_t num_defines); | ||
| 20 | |||
| 21 | /// Create a 3D debugging shader. | ||
| 22 | ShaderProgram* gfx_make_debug3d_shader(GfxCore*); | ||
| 23 | |||
| 24 | /// Create a shader for drawing in immediate mode. | ||
| 25 | ShaderProgram* gfx_make_immediate_mode_shader(GfxCore*); | ||
| 26 | |||
| 27 | /// Create a shader for computing irradiance maps from cube maps. | ||
| 28 | ShaderProgram* gfx_make_irradiance_map_shader(GfxCore*); | ||
| 29 | |||
| 30 | /// Create a shader for computing prefiltered environment maps from cube maps. | ||
| 31 | ShaderProgram* gfx_make_prefiltered_environment_map_shader(GfxCore*); | ||
| 32 | |||
| 33 | /// Create a skyquad shader. | ||
| 34 | ShaderProgram* gfx_make_skyquad_shader(GfxCore*); | ||
| 35 | |||
| 36 | /// Create a shader to view normal-mapped normals. | ||
| 37 | ShaderProgram* gfx_make_view_normal_mapped_normals_shader(GfxCore*); | ||
| 38 | |||
| 39 | /// Create a shader to view vertex normals. | ||
| 40 | ShaderProgram* gfx_make_view_normals_shader(GfxCore*); | ||
| 41 | |||
| 42 | /// Create a shader to view vertex tangents. | ||
| 43 | ShaderProgram* gfx_make_view_tangents_shader(GfxCore*); | ||
| 44 | |||
| 45 | /// Create a shader to view textures. | ||
| 46 | ShaderProgram* gfx_make_view_texture_shader(GfxCore*); | ||
diff --git a/include/gfx/util/skyquad.h b/include/gfx/util/skyquad.h new file mode 100644 index 0000000..2b3fe17 --- /dev/null +++ b/include/gfx/util/skyquad.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /// A skyquad is like a skybox but with a single quad. | ||
| 2 | #pragma once | ||
| 3 | |||
| 4 | typedef struct GfxCore GfxCore; | ||
| 5 | typedef struct Scene Scene; | ||
| 6 | typedef struct SceneNode SceneNode; | ||
| 7 | typedef struct SceneObject SceneObject; | ||
| 8 | typedef struct Texture Texture; | ||
| 9 | |||
| 10 | /// Create a skyquad. | ||
| 11 | SceneObject* gfx_make_skyquad(GfxCore*, const Texture*); | ||
| 12 | |||
| 13 | /// Set up a skyquad in the scene. | ||
| 14 | /// | ||
| 15 | /// This function adds two scene nodes under the given root node: | ||
| 16 | /// - An object node to render the skyquad in the background. | ||
| 17 | /// - A light node to light up other objects with the skyquad. | ||
| 18 | /// | ||
| 19 | /// Return the light node under which objects affected by the light can be | ||
| 20 | /// rooted. | ||
| 21 | SceneNode* gfx_setup_skyquad( | ||
| 22 | GfxCore*, SceneNode* root, const Texture* environment_map); | ||
