mtx_stack(*this),
changed(MATRIX),
matrices_loaded(false),
+ shdata_applied(0),
camera(c),
state_stack(1),
element_buffer(0)
state->shprog = p;
if(p && d)
add_shader_data(*d);
-
- /* Even if we have no new shdata, the existing ones need to be re-applied
- to the new program */
- shdata_changed = true;
}
void Renderer::add_shader_data(const ProgramData &d)
if(state_stack.size()==1)
throw stack_underflow("Renderer::pop_state");
+ const Lighting *old_lighting = state->lighting;
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());
mtx_stack.pop();
- changed |= MATRIX|SHADER_DATA;
+ changed |= MATRIX;
+ if(state->lighting!=old_lighting)
+ {
+ if(state->lighting)
+ state->lighting->update_shader_data(standard_shdata, state->lighting_matrix);
+ changed |= LIGHTING;
+ }
}
void Renderer::escape()
{
MatrixStack::modelview() = state->lighting_matrix;
state->lighting->bind();
- changed = (changed&~LIGHTING)|MATRIX;
+ changed = (changed&~LIGHTING)|LEGACY_MATRIX;
}
else
Lighting::unbind();
if(state->shprog)
{
+ bool shprog_changed = (state->shprog!=Program::current());
state->shprog->bind();
if(!legacy_bindings)
{
- const Matrix &m = mtx_stack.top();
- standard_shdata.uniform("eye_obj_matrix", mtx_stack.top());
- LinAl::SquareMatrix<float, 3> nm;
- for(unsigned i=0; i<3; ++i)
- for(unsigned j=0; j<3; ++j)
- nm(i, j) = m(i, j);
- nm = transpose(invert(nm));
- standard_shdata.uniform_matrix3("eye_obj_normal_matrix", &nm(0, 0));
+ if(changed&MODERN_MATRIX)
+ {
+ const Matrix &m = mtx_stack.top();
+ standard_shdata.uniform("eye_obj_matrix", mtx_stack.top());
+ LinAl::SquareMatrix<float, 3> nm;
+ for(unsigned i=0; i<3; ++i)
+ for(unsigned j=0; j<3; ++j)
+ nm(i, j) = m(i, j);
+ nm = transpose(invert(nm));
+ standard_shdata.uniform_matrix3("eye_obj_normal_matrix", &nm(0, 0));
+ changed &= ~MODERN_MATRIX;
+ }
+
if(state->material)
state->material->get_shader_data().apply();
standard_shdata.apply();
}
- if(changed&SHADER_DATA)
+ if((changed&SHADER_DATA) || shprog_changed)
{
- for(vector<const ProgramData *>::const_iterator i=shdata_stack.begin(); i!=shdata_stack.end(); ++i)
+ vector<const ProgramData *>::const_iterator i = shdata_stack.begin();
+ if(!shprog_changed)
+ i += shdata_applied;
+ for(; i!=shdata_stack.end(); ++i)
(*i)->apply();
changed &= ~SHADER_DATA;
+ shdata_applied = shdata_stack.size();
}
}
else
matrices_loaded = true;
}
- if(changed&MATRIX)
+ if(changed&LEGACY_MATRIX)
{
MatrixStack::modelview() = mtx_stack.top();
- changed &= ~MATRIX;
+ changed &= ~LEGACY_MATRIX;
}
}
}