namespace Msp {
namespace GL {
+/**
+A helper class for single-point binding. Provides tracking of the currently
+bound object.
+*/
template<typename T>
class Bindable
{
/**
Effects are used to wrap other renderables and give them additional visual
-properties.
+properties. An Effect's render method should set up the necessary state, call
+the wrapped Renderable's render method, and clean up after itself.
*/
class Effect: public Renderable
{
class Buffer;
class Renderer;
+/**
+Raw mesh data, consisting of a VertexArray and one or more Batches. Though a
+Mesh can draw itself, it's usually used as part of Renderables rather than on
+its own.
+*/
class Mesh
{
friend class MeshBuilder;
class Texture;
/**
-Stores a Mesh together with a Technique to determine its appearance.
+Combines a Mesh with a Technique to give it an appearance. The Technique will
+define which render passes the Object supports.
-It is possible to use a single Object for rendering multiple identical or
-similar objects. See class ObjectInstance.
+In many cases, it's desirable to include multiple copies of an Object in a
+Scene, with different model matrices. ObjectInstances can be used to alter the
+rendering of an object on a per-instance basis.
*/
class Object: public Renderable
{
void set_technique(const Technique *);
const Technique *get_technique() const { return technique.get(); }
- /**
- Renders the object. A tag can be provided to render a non-default pass.
- */
virtual void render(const Tag &tag = Tag()) const;
virtual void render(Renderer &, const Tag & = Tag()) const;
- /**
- Renders the object with an instance. The instance's hook functions are
- called before and after drawing the mesh. A tag may also be given to render
- a non-default pass.
- */
+ /** Renders an instance of the object. The instance's hook functions are
+ called before and after drawing the mesh. */
virtual void render(Renderer &, const ObjectInstance &, const Tag & = Tag()) const;
private:
class ProgramData;
/**
-Represents a single instance of an Object. An application can derive another
-class from this and overload the hook functions to specify location and other
-instance-specific parameters for the rendered objects.
+Represents a single instance of an Object. A derived class can overload the
+hook functions to specify a model matrix and other instance-specific parameters
+for the rendered objects.
+
+ObjectInstances can benefit from being put in an InstanceScene, which will
+render all instances of the same object consecutively.
*/
class ObjectInstance: public Renderable
{
class Lighting;
class PostProcessor;
+/**
+Encapsulates all of the information used to produce a complete image in the
+framebuffer. This is the highest level rendering class, combining Renderables
+with a camera, lights and some other influential objects.
+
+A Pipeline is also a Renderable itself. Externally, it only exposes the
+default pass. Internally, it can hold any number of passes, which are invoked
+in sequence when rendering the default pass is requested. Each pass can have a
+Lighting, a DepthTest and a Blend to control how it is rendered.
+
+A Pipeline's render method should normally be called without a Renderer; it
+will create one itself, using the camera specified for the Pipeline. If a
+Renderer is passed, its camera will be used instead.
+
+Renderables are rendered in the order they were added to the Pipeline. While
+it's possible to remove renderables as well, using a Scene is recommended if
+frequent add/remove operations are needed.
+
+Pipelines may have post-processors to apply full-screen effects. Framebuffer
+objects are automatically used to pass render results to the post-processors.
+High dynamic range and multisample rendering can also be used.
+*/
class Pipeline: public Renderable
{
public:
virtual void render(const Texture2D &color, const Texture2D &depth) = 0;
protected:
- /** Returns a vertex shader suitable for rendering a fullscreen quad. Input
- vertices are assumed to be in normalized device coordinates; no transform is
- done. The shader provides a varying vec2 texcoord for fragment a shader to
- access textures. */
+ /** Returns a vertex shader suitable for rendering a full-screen quad.
+ Input vertices are assumed to be in normalized device coordinates; no
+ transform is performed. The shader provides a varying vec2 texcoord for
+ a fragment shader to access textures. */
static Shader &get_fullscreen_vertex_shader();
/** Returns a mesh consisting of a single quad, covering the entire screen.
UniformMap::iterator i = uniforms.find(name);
if(i!=uniforms.end())
{
+ /* UniformBlock does not copy the uniforms, so existing blocks will be
+ left with stale pointers. This is not a problem as long as no one stores
+ pointers to the blocks and expects them to stay valid. */
delete i->second;
i->second = uni;
changes = VALUES_CHANGED;
class Vector4;
/**
-Stores uniform variables for a shader program.
+Stores uniform variables for shader programs. The uniforms are stored in a
+program-independent way, and UniformBlocks are created to match the uniform
+layouts of different programs. If multiple programs have the same layout, the
+same block is used for them.
+
+The class is optimized for an access pattern where the set of uniforms and
+programs stays constants, with only the values changing.
*/
class ProgramData
{
void find_uniforms_for_block(Block &, const Program::UniformBlockInfo &) const;
UniformBlock *create_block(const Program::UniformBlockInfo &) const;
const UniformBlock *get_block(const Program &, const Program::UniformBlockInfo *) const;
+
public:
- const UniformBlock *get_block(const Program &, const std::string &) const;
+ /** Returns a UniformBlock matching the program's layout. If name is empty,
+ uniforms for the default uniform block (outside any uniform block
+ declarations) are returned. */
+ const UniformBlock *get_block(const Program &prog, const std::string &name) const;
+ /// Creates blocks for the currently bound program and applies them.
void apply() const;
};
/**
Base class for renderable objects. All Renderables must support rendering with
a Renderer, and may optionally provide support for standalone rendering.
+
+The render methods take a Tag to identify a render pass. It is most commonly
+used together with Techniques and Pipelines to implement multipass rendering.
*/
class Renderable
{
public:
virtual ~Renderable() { }
- /** Returns a key used for grouping Renderables in an InstanceScene. */
+ /** Returns a key used for grouping Renderables in an InstanceScene. The
+ returned value is treated as opaque. */
virtual long get_instance_key() const { return 0; }
+ /** Renders the renderable without a renderer. This can be convenient in
+ some simple cases, but most renderables don't need to implement this
+ method. */
virtual void render(const Tag & = Tag()) const;
+
+ /** Renders the renderable. Implementors should take care to return the
+ renderer to the state it was in, for example by using Renderer::Push. */
virtual void render(Renderer &, const Tag & = Tag()) const = 0;
};
will often be more efficient. This is especially true for ObjectInstances.
The Renderer works by deferring GL state changes until something is actually
-being drawn. This avoids many unnecessary GL calls. */
+being drawn. This avoids many unnecessary GL calls if consecutive renderables
+use the same resources.
+*/
class Renderer
{
public:
void push_state();
void pop_state();
- /** Prepares for temporarily bypassing the Renderer. */
+ /** Prepares for temporarily bypassing the Renderer by synchronizing the
+ current state with GL. No additional call is necessary to resume using the
+ Renderer. */
void escape();
void draw(const Batch &);
namespace Msp {
namespace GL {
+/**
+Provides transparent string-to-hash conversion for faster comparison. An empty
+string is guaranteed to have an id of 0.
+*/
struct Tag
{
unsigned id;
class Vector3;
class Vector4;
+/**
+Stores uniforms with a specific layout. Both named and default uniform blocks
+are supported.
+*/
class UniformBlock: public Bufferable
{
private: