From: Mikko Rasa Date: Sat, 14 Apr 2018 22:13:56 +0000 (+0300) Subject: Use different heuristics for applying shader data X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=5b71f1bf0d152486c0f6fe03c853992c57530369;p=libs%2Fgl.git Use different heuristics for applying shader data 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. --- diff --git a/source/renderer.cpp b/source/renderer.cpp index c3a6923f..76ac5846 100644 --- a/source/renderer.cpp +++ b/source/renderer.cpp @@ -24,7 +24,6 @@ namespace GL { Renderer::Renderer(const Camera *c): changed(0), matrices_loaded(false), - shdata_applied(0), state_stack(1) { state_stack.reserve(16); @@ -125,9 +124,16 @@ void Renderer::set_shader_program(const Program *p, 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_countshdata_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) @@ -161,12 +167,6 @@ void Renderer::pop_state() 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(shdata_applied, shdata_stack.size()); changed |= MATRIX; bool camera_changed = (state->camera!=old_camera); if(camera_changed) @@ -343,15 +343,15 @@ void Renderer::apply_state() } } - 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_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_iterator i=shdata_stack.begin(); i!=shdata_stack.end(); ++i) (*i)->apply(); changed &= ~SHADER_DATA; - shdata_applied = shdata_stack.size(); } } else diff --git a/source/renderer.h b/source/renderer.h index 79557eab..af4bd65b 100644 --- a/source/renderer.h +++ b/source/renderer.h @@ -98,7 +98,6 @@ private: unsigned char changed; bool matrices_loaded; - unsigned shdata_applied; std::vector state_stack; State *state; ProgramData standard_shdata;