From 5b71f1bf0d152486c0f6fe03c853992c57530369 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 15 Apr 2018 01:13:56 +0300 Subject: [PATCH] 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. --- source/renderer.cpp | 32 ++++++++++++++++---------------- source/renderer.h | 1 - 2 files changed, 16 insertions(+), 17 deletions(-) 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; -- 2.43.0