Since later shdata can override values from earlier ones, the stack must
be replayed even if items are only removed. However we can detect if the
exact same items are added back as might happen when multiple objects
using the same technique are rendered in succession.
Renderer::Renderer(const Camera *c):
changed(0),
matrices_loaded(false),
Renderer::Renderer(const Camera *c):
changed(0),
matrices_loaded(false),
state_stack(1)
{
state_stack.reserve(16);
state_stack(1)
{
state_stack.reserve(16);
void Renderer::add_shader_data(const ProgramData &d)
{
void Renderer::add_shader_data(const ProgramData &d)
{
- shdata_stack.push_back(&d);
- state->shdata_count = shdata_stack.size();
- changed |= SHADER_DATA;
+ if(state->shdata_count<shdata_stack.size() && shdata_stack[state->shdata_count]==&d)
+ ++state->shdata_count;
+ else
+ {
+ if(shdata_stack.size()>state->shdata_count)
+ shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
+ shdata_stack.push_back(&d);
+ state->shdata_count = shdata_stack.size();
+ changed |= SHADER_DATA;
+ }
}
void Renderer::set_mesh(const Mesh *m)
}
void Renderer::set_mesh(const Mesh *m)
const Clipping *old_clipping = state->clipping;
state_stack.pop_back();
state = &state_stack.back();
const Clipping *old_clipping = state->clipping;
state_stack.pop_back();
state = &state_stack.back();
- if(shdata_stack.size()>state->shdata_count)
- {
- shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
- changed |= SHADER_DATA;
- }
- shdata_applied = min<unsigned>(shdata_applied, shdata_stack.size());
changed |= MATRIX;
bool camera_changed = (state->camera!=old_camera);
if(camera_changed)
changed |= MATRIX;
bool camera_changed = (state->camera!=old_camera);
if(camera_changed)
- if((changed&SHADER_DATA) || shprog_changed)
+ bool extra_shdata = (shdata_stack.size()>state->shdata_count);
+
+ if((changed&SHADER_DATA) || shprog_changed || extra_shdata)
- vector<const ProgramData *>::const_iterator i = shdata_stack.begin();
- if(!shprog_changed)
- i += shdata_applied;
- for(; i!=shdata_stack.end(); ++i)
+ if(extra_shdata)
+ shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
+ for(vector<const ProgramData *>::const_iterator i=shdata_stack.begin(); i!=shdata_stack.end(); ++i)
(*i)->apply();
changed &= ~SHADER_DATA;
(*i)->apply();
changed &= ~SHADER_DATA;
- shdata_applied = shdata_stack.size();
unsigned char changed;
bool matrices_loaded;
unsigned char changed;
bool matrices_loaded;
- unsigned shdata_applied;
std::vector<State> state_stack;
State *state;
ProgramData standard_shdata;
std::vector<State> state_stack;
State *state;
ProgramData standard_shdata;