aboutsummaryrefslogtreecommitdiff
path: root/src/llr/llr_impl.h
blob: ada2d79d0dfafe683bf8f6f9d94a43a85041e557 (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
#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>
#include <stdint.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.
typedef struct LLR {
  GfxCore* gfxcore;

  union {
    struct {
      bool shader_changed   : 1; // Whether the shader has changed.
      bool camera_changed   : 1; // Whether the camera parameters have changed.
      bool lights_changed   : 1; // Whether the lights have changed.
      bool skeleton_changed : 1; // Whether the skeleton has changed.
      bool matrix_changed   : 1; // Whether the matrix stack has changed.
    };
    uint8_t changed_flags;
  };

  IBL*     ibl;
  Texture* brdf_integration_map;

  ShaderProgram* shader; // Active shader. Not owned.

  vec3 camera_position;
  mat4 camera_rotation;
  mat4 view;       // Camera view matrix.
  mat4 projection; // Camera projection matrix.
  R    fovy;       // Camera vertical field of view.
  R    aspect;     // Aspect ratio.

  // Lights are not const because environment lights store lazily-computed
  // irradiance maps.
  Light* lights[GFX_LLR_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.

  size_t num_joints;
  mat4   joint_matrices[GFX_MAX_NUM_JOINTS];

  // 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[GFX_LLR_MAX_NUM_MATRICES];
  int  stack_pointer; // Points to the top of the stack.
} LLR;

/// Create a new immediate mode renderer.
bool gfx_llr_make(LLR*, GfxCore*);

/// Destroy the immediate mode renderer.
void gfx_llr_destroy(LLR*);