Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
	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;
	}