std::pair<ShaderID, bool> ResourceManagerImpl::find_shader(const std::string& name) { std::map<std::string, ShaderID>::const_iterator it = shader_lookup_.find(name); if(it == shader_lookup_.end()) { return std::make_pair(ShaderID(), false); } return std::make_pair((*it).second, true); }
uint32 Renderer_GL44::render_state_switch(RenderState& current, RenderCommand_GL44* commands, uint32 max_count) { auto batch_key = SortKey_GL44::Decode(commands->sort_key); auto cmd_data = static_cast<DefaultCommandData*>(commands->data); auto sk = batch_key.fields; auto& gd = m_geometry_data[cmd_data->geometry.value()]; auto& gcd = *m_geometry_config_data.data(gd.geometry_config_id.value()); auto& sd = m_shader_backend.m_shader_data[sk.material]; current.index_type = gcd.index_type; current.primitive_type = gcd.primitive; bool layout_changed = gcd.layout != current.vertex_layout; bool shader_changed = sk.material != current.shader.value(); bool buffer_changed = sk.buffer != (uint8)current.buffer; // compute size of next batch uint32 max_batch_size = std::min(max_count, sd.maximum_batch_size); uint32 batch_size = 1; auto batch_key_dm = batch_key; batch_key_dm.fields.depth = 0; for (uint32 i = 1; i < max_batch_size; i++) { // check if this draw call fits into the same draw batch auto current_key_dm = SortKey_GL44::Decode(commands[i].sort_key); current_key_dm.fields.depth = 0; if (current_key_dm.integer != batch_key_dm.integer) break; batch_size += 1; } // if the shader has changed if (shader_changed) { gl::use_program(sd.gl_program_id); current.shader = ShaderID(sk.material); m_shader_backend.m_iu_submission.set_shader(sd); } // instance uniform manager needs to know that a new batch begins m_shader_backend.m_iu_submission.batch_begin(batch_size); // if any of the two has changed we need to configure the mapping if (shader_changed || layout_changed) { for (uint32 i = 0; i < sd.vertex_attributes_count; i++) { auto& sh_att = sd.vertex_attributes[i]; auto vl_att_ptr = gcd.layout->find_attribute(sh_att.name); // TODO: faster? if (vl_att_ptr == nullptr) { LOG_WARNING("unmapped shader vertex property"); gl::disable_vertex_attribute(sh_att.location); continue; } auto& vl_att = *vl_att_ptr; gl::enable_vertex_attribute(sh_att.location); // floating point shader input if (sh_att.is_float_type) { gl::vertex_attrib_format( sh_att.location, vl_att.elements(), type_gl(vl_att.type()), type_normalize(vl_att.type()), vl_att.offset()); } // integer shader input else { gl::vertex_attrib_i_format( sh_att.location, vl_att.elements(), type_gl(vl_att.type()), vl_att.offset()); } gl::vertex_attrib_binding(sh_att.location, DEFAULT_BINDING_INDEX_GL); } } // if the buffer has changed if (buffer_changed || layout_changed) { uint32 gl_buffer = m_geom_buffer_gl_ids[(uint32)sk.buffer]; if (buffer_changed) { gl::bind_buffer(gl::BufferType::ElementArray, gl_buffer); current.buffer = (GeometryBufferType)sk.buffer; } gl::bind_vertex_buffer(DEFAULT_BINDING_INDEX_GL, gl_buffer, 0, gcd.layout->stride()); current.vertex_layout = gcd.layout; } // TODO minimize shader/layout state changes return batch_size; }