6.3Implementation 89
class State
{
public:
const Matrix44& GetModel() const;
void SetModel(const Matrix44& value);
const Matrix44& GetView() const;
void SetView(const Matrix44& value);
const Matrix44& GetProjection() const;
void SetProjection(const Matrix44& value);
const Matrix44& GetModelView() const;
const Matrix44& GetModelViewProjection() const;
};
Listing 6.2. Minimal interface for state used to automatically set engine uniforms.
formations, operator overloads, and a method called Pointer() that gives us di-
rect access to the matrix’s elements for making OpenGL calls.
By encapsulating the state required for engine uniforms in a class, different
instances of the class can be passed to different draw methods. This is less error
prone than setting some subset of global states between draw calls, which was
required with GLSL built-in uniforms. An engine can even take this one step fur-
ther and define separate scene state and object state classes. For example, the
view and projection matrices from our
State class may be part of the scene state,
and the model matrix would be part of the object state. With this separation, an
engine can then pass the scene state to all objects, which then issue draw com-
mands using the scene state and their own state. For conciseness, we only use one
state class in this chapter.
6.3Implementation
To implement this framework, we build on the shader program and uniform ab-
stractions discussed in the previous chapter. In particular, we require a
Uniform
class that encapsulates a
4
matrix uniform (mat4). We also need a Shader-
Program
class that represents an OpenGL shader program and contains the pro-
gram’s uniforms in a
std::map, like the following:
std::map<std::string, Uniform *> m_uniformMap;