#include <set>
#include <vector>
#include "commands.h"
+#include "cullface.h"
#include "matrix.h"
#include "programdata.h"
#include "renderer_backend.h"
namespace GL {
class Batch;
+class Blend;
class Buffer;
class Camera;
union ClearValue;
+class DepthTest;
class Material;
class Mesh;
class Lighting;
class Program;
class QueryPool;
+struct Rect;
class Renderable;
class Sampler;
+class StencilTest;
class Texture;
class VertexSetup;
};
private:
- struct BoundTexture
+ struct SampledTexture
{
- Tag tag;
- mutable int binding = -1;
const Texture *texture = 0;
const Sampler *sampler = 0;
int level = -1;
+
+ SampledTexture() = default;
+ SampledTexture(const Texture *t, const Sampler *s, int l): texture(t), sampler(s), level(l) { }
+
+ bool operator==(const SampledTexture &o) const { return texture==o.texture && sampler==o.sampler && level==o.level; }
+ };
+
+ template<typename T>
+ struct BoundResource
+ {
+ Tag tag;
+ mutable int binding = -1;
int replaced = -1;
+ T resource;
};
struct BoundProgramData
struct State
{
+ std::uintptr_t pipeline_key = 0;
const Camera *camera = 0;
Matrix model_matrix;
const Framebuffer *framebuffer = 0;
enum ChangeMask
{
+ PIPELINE_KEY = 1,
MATRIX = 2,
+ CAMERA = 4,
SHADER_DATA = 16
};
State *current_state = 0;
ProgramData standard_shdata;
std::vector<BoundProgramData> shdata_stack;
- std::vector<BoundTexture> texture_stack;
+ std::vector<BoundResource<SampledTexture>> texture_stack;
+ const Texture &placeholder_texture;
+ const Sampler &default_sampler;
+ PipelineState *last_pipeline = 0;
Commands commands;
+ static const Tag world_obj_matrix_tag;
+ static const Tag world_obj_normal_matrix_tag;
+
public:
Renderer();
void push_state();
/** Restores a previously saved state. Must be matched with an earlier
- push_state call. */
+ push_state() call. */
void pop_state();
private:
State &get_state() const;
public:
+ void set_pipeline_key(std::uintptr_t);
+ void set_pipeline_key(const void *p) { set_pipeline_key(reinterpret_cast<uintptr_t>(p)); }
+
+ template<typename T>
+ void set_pipeline_key(std::uintptr_t k, T d)
+ { set_pipeline_key(k^(static_cast<uintptr_t>(d)<<((sizeof(std::uintptr_t)-sizeof(T))*std::numeric_limits<char>::digits))); }
+
+ template<typename T>
+ void set_pipeline_key(const void *p, T d) { set_pipeline_key(reinterpret_cast<uintptr_t>(p), d); }
+
/** Sets the camera to render from. The model matrix is reset to identity. */
void set_camera(const Camera &);
void set_texture(Tag, const Texture *, const Sampler * = 0);
void set_texture(Tag, const Texture *, int, const Sampler * = 0);
+ void set_storage_texture(Tag, const Texture *);
private:
+ template<typename T>
+ static void set_resource(std::vector<BoundResource<T>> &, unsigned &, Tag, const T &);
+
void flush_shader_data();
- void flush_textures();
+
+ template<typename T>
+ static void flush_resources(std::vector<BoundResource<T>> &, unsigned &);
public:
void set_vertex_setup(const VertexSetup *);
/** Draws a batch of primitives. A shader must be active. */
void draw(const Batch &);
- /** Draws multiple instances of a batch of primitives. A shader must be active. */
+ /** Draws multiple instances of a batch of primitives. A shader must be
+ active. */
void draw_instanced(const Batch &, unsigned);
+private:
+ void apply_batch(const Batch &);
+
+public:
+ /** Dispatches a compute operation. */
+ void dispatch(unsigned, unsigned = 1, unsigned = 1);
+
/** Resolves multisample attachments from the active framebuffer into
- target. */
- void resolve_multisample(Framebuffer &target);
+ their corresponding resolve attachments. */
+ void resolve_multisample();
void begin_query(const QueryPool &, unsigned);
void end_query(const QueryPool &, unsigned);
private:
+ PipelineState &get_pipeline_state();
+ void apply_framebuffer();
void apply_state();
};