blob: 5ccabd1f01b1bb4045c8eadfa496a93c372fbf13 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#pragma once
#include <gfx/llr/llr.h>
#include <gfx/sizes.h>
#include <math/mat4.h>
#include <math/vec3.h>
#include <stdbool.h>
#include <stddef.h>
typedef struct Geometry Geometry;
typedef struct GfxCore GfxCore;
typedef struct IBL IBL;
typedef struct Material Material;
typedef struct ShaderProgram ShaderProgram;
typedef struct Texture Texture;
/// Immediate mode renderer.
///
/// The renderer caches state changes in memory and only programs the underlying
/// shader program when a draw call is issued and if anything has changed. This
/// keeps the number of graphics API calls to a minimum, but requires tracking
/// state changes. The 'changed' booleans below fulfill this purpose, and
/// indicate whether a given state has changed since the last draw call.
///
/// The renderer must combine state changes accordingly. For example, if only
/// the lights have changed, then it is sufficient to update light uniforms in
/// the current shader program. On the other hand, if the shader program has
/// changed, then the renderer must reconfigure it from scratch and set light
/// uniforms, camera uniforms, etc.
///
/// Note that the shader program API has its own level of caching as well, so
/// reconfiguration at the level of the renderer does not result in the
/// worst-case set of graphics API calls.
///
/// Currently, the immediate mode renderer can only draw up to a maximum number
/// of primitives per frame. It does not adjust this number dynamically. Keeps
/// things simple while the extra complexity is not needed.
/// TODO: Flush the buffer when it reaches its maximum size to remove this
/// constraint.
typedef struct ImmRenderer {
GfxCore* gfxcore;
vec3 camera_position;
mat4 view; // Camera view matrix.
mat4 projection; // Camera projection matrix.
bool camera_changed; // Whether the camera parameters have changed.
// -------------------------------------------
// Immediate-mode rendering of scene elements.
IBL* ibl;
Texture* brdf_integration_map;
ShaderProgram* shader; // Active shader. Not owned.
bool shader_changed; // Whether the shader has changed.
// Lights are not const because environment lights store lazily-computed
// irradiance maps.
Light* lights[IMM_MAX_NUM_LIGHTS]; // Lights stack.
int num_lights; // Number of lights enabled at a given point in time. It
// points to one past the top of the stack.
bool lights_changed; // Whether the lights have changed.
bool skeleton_changed;
size_t num_joints;
mat4 joint_matrices[GFX_MAX_NUM_JOINTS];
// ---------------------------------------
// Immediate-mode rendering of primitives.
ShaderProgram* imm_shader; // Immediate-mode shader program for primitives.
Geometry* triangles;
size_t num_triangle_verts; // Number of triangle verts this frame.
// TODO: wireframe rendering.
struct {
bool wireframe : 1;
} flags;
vec3 triangle_verts[IMM_MAX_NUM_TRIANGLES * 3];
// -------------
// Matrix stack.
// The matrix stack contains pre-multiplied matrices.
// It is also never empty. The top of the stack is an identity matrix when the
// stack is "empty" from the user's perspective.
mat4 matrix_stack[IMM_MAX_NUM_MATRICES];
int stack_pointer; // Points to the top of the stack.
} ImmRenderer;
/// Create a new immediate mode renderer.
bool gfx_imm_make(ImmRenderer*, GfxCore*);
/// Destroy the immediate mode renderer.
void gfx_imm_destroy(ImmRenderer*);
/// Flush draw commands.
void gfx_imm_flush(ImmRenderer*);
|