instance_data(0),
instance_buffer(0),
vtx_setup(0),
+ matrix_location(-1),
matrix_offset(0)
{
+ const Technique *tech = object.get_technique();
+ const Technique::PassMap &passes = tech->get_passes();
+ for(Technique::PassMap::const_iterator i=passes.begin(); i!=passes.end(); ++i)
+ {
+ const Program *shprog = i->second.get_shader_program();
+ if(!shprog)
+ throw invalid_argument("InstanceArray::InstanceArray");
+
+ int loc = shprog->get_attribute_location("instance_transform");
+ if(matrix_location<0)
+ matrix_location = loc;
+ else if(loc!=matrix_location)
+ throw invalid_argument("InstanceArray::InstanceArray");
+ }
+
if(ARB_vertex_array_object && ARB_instanced_arrays && ARB_draw_instanced)
{
- instance_data = new VertexArray((ATTRIB4,12, ATTRIB4,13, ATTRIB4,14));
+ instance_data = new VertexArray((ATTRIB4,matrix_location, ATTRIB4,matrix_location+1, ATTRIB4,matrix_location+2));
const VertexFormat &fmt = instance_data->get_format();
- matrix_offset = fmt.offset(make_indexed_component(ATTRIB4, 12));
+ matrix_offset = fmt.offset(make_indexed_component(ATTRIB4, matrix_location));
instance_buffer = new Buffer(ARRAY_BUFFER);
instance_data->use_buffer(instance_buffer);
InstanceArray::~InstanceArray()
{
+ for(std::vector<ObjectInstance *>::iterator i=instances.begin(); i!=instances.end(); ++i)
+ delete *i;
delete vtx_setup;
delete instance_data;
delete instance_buffer;
if(instance_data)
{
if(instance_data->size()<instances.size())
+ {
instance_data->append();
+ unsigned req_size = instance_data->get_required_buffer_size();
+ if(instance_buffer->get_size()>0 && instance_buffer->get_size()<req_size)
+ {
+ delete instance_buffer;
+ instance_buffer = new Buffer(ARRAY_BUFFER);
+ instance_data->use_buffer(instance_buffer);
+ }
+ }
update_instance_matrix(instances.size()-1);
}
}
const Technique *tech = object.get_technique();
if(!tech)
throw logic_error("no technique");
- if(!tech->has_pass(tag))
+ const RenderPass *pass = tech->find_pass(tag);
+ if(!pass)
return;
- const RenderPass &pass = tech->get_pass(tag);
const Mesh *mesh = object.get_mesh();
mesh->get_vertices().refresh();
+ if(instance_buffer->get_size()==0)
+ instance_buffer->storage(instance_data->get_required_buffer_size());
instance_data->refresh();
Renderer::Push push(renderer);
- pass.apply(renderer);
+ pass->apply(renderer);
mesh->draw_instanced(renderer, *vtx_setup, instances.size());
}
else
for(vector<ObjectInstance *>::const_iterator i=instances.begin(); i!=instances.end(); ++i)
{
const Matrix &m = *(*i)->get_matrix();
- glVertexAttrib4f(12, m(0, 0), m(0, 1), m(0, 2), m(0, 3));
- glVertexAttrib4f(13, m(1, 0), m(1, 1), m(1, 2), m(1, 3));
- glVertexAttrib4f(14, m(2, 0), m(2, 1), m(2, 2), m(2, 3));
+ for(unsigned j=0; j<3; ++j)
+ glVertexAttrib4f(matrix_location+j, m(j, 0), m(j, 1), m(j, 2), m(j, 3));
(*i)->render(renderer, tag);
}
}