This way, the correct size for the buffer can be determined right away,
rather than each block resizing it in turn. Binding the buffer before
applying the blocks also avoids some thrashing.
throw invalid_operation("ProgramData::apply");
const Program::UniformBlockMap &prog_blocks = prog->get_uniform_blocks();
throw invalid_operation("ProgramData::apply");
const Program::UniformBlockMap &prog_blocks = prog->get_uniform_blocks();
- for(Program::UniformBlockMap::const_iterator i=prog_blocks.begin(); i!=prog_blocks.end(); ++i)
+ if(!prog_blocks.empty())
- const UniformBlock &block = get_block(*prog, &i->second);
- block.apply(i->second.bind_point);
+ typedef pair<const UniformBlock *, unsigned> ApplyBlock;
+ list<ApplyBlock> apply_blocks;
+ for(Program::UniformBlockMap::const_iterator i=prog_blocks.begin(); i!=prog_blocks.end(); ++i)
+ {
+ const UniformBlock &block = get_block(*prog, &i->second);
+ apply_blocks.push_back(make_pair(&block, i->second.bind_point));
+ }
+
+ if(buffer)
+ buffer->bind();
+
+ for(list<ApplyBlock>::const_iterator i=apply_blocks.begin(); i!=apply_blocks.end(); ++i)
+ i->first->apply(i->second);
}
const UniformBlock &block = get_block(*prog, 0);
}
const UniformBlock &block = get_block(*prog, 0);