#include "renderable.h"
#include "renderer.h"
#include "resourcemanager.h"
+#include "resources.h"
#include "sampler.h"
#include "texture.h"
#include "vertexarray.h"
namespace Msp {
namespace GL {
-Renderer::Renderer()
+Renderer::Renderer():
+ placeholder_texture(Resources::get_global().get<Texture>("_placeholder.png"))
{
state_stack.reserve(16);
shdata_stack.reserve(32);
}
void Renderer::set_texture(Tag tag, const Texture *tex, const Sampler *samp)
+{
+ set_texture(tag, tex, -1, samp);
+}
+
+void Renderer::set_texture(Tag tag, const Texture *tex, int level, const Sampler *samp)
{
State &state = get_state();
if(tex)
+ {
if(ResourceManager *res_mgr = tex->get_manager())
res_mgr->resource_used(*tex);
+ if(!tex->is_loaded())
+ tex = &placeholder_texture;
+ }
if(texture_stack.size()>state.texture_count)
{
bound_tex.tag = tag;
bound_tex.texture = tex;
bound_tex.sampler = samp;
+ bound_tex.level = level;
state.texture_count = texture_stack.size();
}
void Renderer::clear(const ClearValue *values)
{
- const State &state = get_state();
-
- pipeline_state.set_framebuffer(state.framebuffer);
- pipeline_state.set_viewport(state.viewport);
- pipeline_state.set_scissor(state.scissor);
+ apply_framebuffer();
commands.use_pipeline(&pipeline_state);
commands.clear(values);
}
void Renderer::draw(const Batch &batch)
{
apply_state();
- batch.refresh();
+ batch.refresh(frame_index);
pipeline_state.set_primitive_type(batch.get_type());
commands.use_pipeline(&pipeline_state);
commands.draw(batch);
void Renderer::draw_instanced(const Batch &batch, unsigned count)
{
apply_state();
- batch.refresh();
+ batch.refresh(frame_index);
pipeline_state.set_primitive_type(batch.get_type());
commands.use_pipeline(&pipeline_state);
commands.draw_instanced(batch, count);
commands.end_query(pool, index);
}
+void Renderer::apply_framebuffer()
+{
+ const State &state = get_state();
+
+ pipeline_state.set_framebuffer(state.framebuffer);
+ static const Rect default_rect = Rect::max();
+ pipeline_state.set_viewport(state.viewport ? *state.viewport : default_rect);
+ pipeline_state.set_scissor(state.scissor ? *state.scissor : default_rect);
+}
+
void Renderer::apply_state()
{
const State &state = get_state();
if(!state.shprog)
throw invalid_operation("Renderer::apply_state");
- pipeline_state.set_framebuffer(state.framebuffer);
- pipeline_state.set_viewport(state.viewport);
- pipeline_state.set_scissor(state.scissor);
+ apply_framebuffer();
bool shprog_changed = (state.shprog!=pipeline_state.get_shader_program());
pipeline_state.set_shader_program(state.shprog);
shdata_stack.erase(shdata_stack.begin()+state.shdata_count, shdata_stack.end());
for(const BoundProgramData &d: shdata_stack)
{
- d.shdata->apply(*state.shprog, pipeline_state);
+ d.shdata->apply(*state.shprog, pipeline_state, frame_index);
d.generation = d.shdata->get_generation();
}
changed &= ~SHADER_DATA;
if(state.vertex_setup)
{
if(const VertexArray *array = state.vertex_setup->get_vertex_array())
- array->refresh();
+ array->refresh(frame_index);
if(const VertexArray *array = state.vertex_setup->get_instance_array())
- array->refresh();
+ array->refresh(frame_index);
}
pipeline_state.set_vertex_setup(state.vertex_setup);
if(t.binding<0 || shprog_changed)
t.binding = state.shprog->get_uniform_binding(t.tag);
if(t.binding>=0)
- pipeline_state.set_texture(t.binding, t.texture, t.sampler);
+ pipeline_state.set_texture(t.binding, t.texture, t.level, t.sampler);
}
pipeline_state.set_depth_test(state.depth_test);