1. Christian Fischer
  2. wiesel

Commits

Christian Fischer  committed e211de2

changed shader buffer handling to avoid table lookups

  • Participants
  • Parent commits cf838fe
  • Branches default

Comments (0)

Files changed (16)

File src/core/wiesel/video/render_context.cpp

View file
 RenderContext::RenderContext(Screen *screen) {
 	this->screen = screen;
 
-	// create default constant buffers
-	ShaderConstantBufferTemplate*	cb_tpl_modelview;
-	cb_tpl_modelview				= Shaders::instance()->getModelviewMatrixBufferTemplate();
-	this->cb_modelview				= new ShaderConstantBuffer(cb_tpl_modelview);
-	keep(this->cb_modelview);
-
-	ShaderConstantBufferTemplate*	cb_tpl_projection;
-	cb_tpl_projection				= Shaders::instance()->getProjectionMatrixBufferTemplate();
-	this->cb_projection				= new ShaderConstantBuffer(cb_tpl_projection);
-	keep(this->cb_projection);
-
 	return;
 }
 
 
 RenderContext::~RenderContext() {
-	release(cb_modelview);
-	release(cb_projection);
 	return;
 }

File src/core/wiesel/video/render_context.h

View file
 
 		/**
 		 * @brief Assigns a shader constant buffer to the current shader.
-		 * If there's no current shader, or the current shader does not use a buffer with the given name,
+		 * If there's no current shader, or the current shader does not use the given buffer template,
 		 * this function will do nothing.
-		 * @param name		Name to assign the buffer to.
-		 * @param buffer	The buffer which should be assigned to the shader.
+		 * @param buffer_template		The template of the buffer to be set.
+		 * @param buffer				The buffer which should be assigned to the shader.
 		 * @return \c true on success, \c false otherwise.
 		 */
-		virtual bool assignShaderConstantBuffer(const std::string &name, ShaderConstantBuffer *buffer) = 0;
+		virtual bool assignShaderConstantBuffer(const ShaderConstantBufferTemplate *buffer_template, ShaderConstantBuffer *buffer) = 0;
 
 		/**
 		 * @brief Set a texture for a specific texture unit.
 	protected:
 		Screen*			screen;
 		matrix4x4		projection;
-
-		ShaderConstantBuffer*		cb_modelview;
-		ShaderConstantBuffer*		cb_projection;
 	};
 
 }

File src/core/wiesel/video/shader.cpp

View file
 #include "video_driver.h"
 
 #include "wiesel/util/log.h"
+#include "shaders.h"
 #include <assert.h>
 #include <map>
 
 	constant_buffers.push_back(entry);
 	keep(entry.buffer_template);
 
+	// store special buffers
+	if (name == Shaders::CONSTANTBUFFER_PROJECTION_MATRIX) {
+		constant_buffer_template_projection = buffer_template;
+	}
+
+	if (name == Shaders::CONSTANTBUFFER_MODELVIEW_MATRIX) {
+		constant_buffer_template_modelview = buffer_template;
+	}
+
 	return true;
 }
 

File src/core/wiesel/video/shader.h

View file
 		 */
 		const ConstantBufferTplList *getConstantBufferTemplates() const;
 
+		/**
+		 * @brief Get the assigned ShaderConstantBufferTemplate for the shader's projection matrix, if any.
+		 */
+		inline ShaderConstantBufferTemplate* getProjectionMatrixConstantBufferTemplate() {
+			return constant_buffer_template_projection;
+		}
+
+		/**
+		 * @brief Get the assigned ShaderConstantBufferTemplate for the shader's modelview matrix, if any.
+		 */
+		inline ShaderConstantBufferTemplate* getModelviewMatrixConstantBufferTemplate() {
+			return constant_buffer_template_modelview;
+		}
+
 	// DeviceResource implementation
 	protected:
 		virtual bool doLoadContent();
 
 		/// A list of all constant buffers assigned to this shader.
 		ConstantBufferTplList		constant_buffers;
+
+	private:
+		ShaderConstantBufferTemplate*		constant_buffer_template_projection;
+		ShaderConstantBufferTemplate*		constant_buffer_template_modelview;
 	};
 
 
 	// setters
 	public:
 		/// assigns a constant buffer to the current shader instance.
-		virtual bool assignShaderConstantBuffer(const std::string &name, ShaderConstantBufferContent *buffer_content) = 0;
+		virtual bool assignShaderConstantBuffer(const ShaderConstantBufferTemplate *buffer_template, ShaderConstantBufferContent *buffer_content) = 0;
 
 	private:
 		Shader*		shader;

File src/core/wiesel/video/shader_constantbuffer.cpp

View file
 }
 
 
+ShaderConstantBuffer *ShaderConstantBufferTemplate::getSharedBuffer() {
+	if (shared_buffer == NULL) {
+		shared_buffer = new ShaderConstantBuffer(this);
+	}
+
+	return shared_buffer;
+}
+
+
 
 
 
 
 
 
+bool ShaderConstantBuffer::setShaderValueAt(index_t index, int32_t i) {
+	return setShaderValueAt(index, TypeInt32, 1, &i);
+}
+
+bool ShaderConstantBuffer::setShaderValueAt(index_t index, float f) {
+	return setShaderValueAt(index, TypeFloat, 1, &f);
+}
+
+bool ShaderConstantBuffer::setShaderValueAt(index_t index, const vector2d &v) {
+	return setShaderValueAt(index, TypeVector2f, 1, (const float*)v);
+}
+
+bool ShaderConstantBuffer::setShaderValueAt(index_t index, const vector3d &v) {
+	return setShaderValueAt(index, TypeVector3f, 1, (const float*)v);
+}
+
+bool ShaderConstantBuffer::setShaderValueAt(index_t index, const matrix4x4 &m) {
+	return setShaderValueAt(index, TypeMatrix4x4f, 1, (const float*)m);
+}
+
+bool ShaderConstantBuffer::setShaderValueAt(index_t index, ValueType type, size_t elements, const void *pValue) {
+	assert(index >= 0);
+
+	if (getTemplate()) {
+		const ShaderConstantBufferTemplate::EntryList* entries = getTemplate()->getEntries();
+		assert(index < static_cast<index_t>(entries->size()));
+
+		return writeDataAtOffset(
+					(*entries)[index].offset,
+					pValue,
+					elements * getTypeSize(type)
+		);
+	}
+
+	return false;
+}
+
+
+
+
+ShaderConstantBuffer::index_t ShaderConstantBuffer::getShaderValueIndex(const std::string& name) const {
+	if (getTemplate()) {
+		for(index_t i=getTemplate()->getEntries()->size(); --i>=0;) {
+			if ((*(getTemplate()->getEntries()))[i].name == name) {
+				return i;
+			}
+		}
+	}
+
+	return -1;
+}
+
+
+
+const ShaderConstantBuffer::data_t ShaderConstantBuffer::getShaderDataPointer(const std::string &name, ValueType type, size_t elements) const {
+	if (getTemplate()) {
+		for(
+				ShaderConstantBufferTemplate::EntryList::const_iterator
+				it  = getTemplate()->getEntries()->begin();
+				it != getTemplate()->getEntries()->end();
+				it++
+		) {
+			if (it->name == name) {
+				assert(it->type == type);
+				assert(it->elements >= elements);
+
+				return data + it->offset;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+
+
 bool ShaderConstantBuffer::writeDataAtOffset(size_t offset, const void *pValue, size_t size) {
 	if (
 			getTemplate()

File src/core/wiesel/video/shader_constantbuffer.h

View file
 			return size;
 		}
 
+		/**
+		 * @brief Get or create a constant buffer, which can be used
+		 * shared between all instances of this template
+		 * @return
+		 */
+		ShaderConstantBuffer* getSharedBuffer();
+
 	private:
-		EntryList		entries;
-		size_t			size;
+		ref<ShaderConstantBuffer>		shared_buffer;
+		EntryList						entries;
+		size_t							size;
 	};
 
 
 	class WIESEL_CORE_EXPORT ShaderConstantBufferWriter : public virtual SharedObject
 	{
 	public:
+		/// pointer type
+		typedef unsigned char* data_t;
+
+	public:
 		ShaderConstantBufferWriter();
 
 		virtual ~ShaderConstantBufferWriter();
 
+	// setter (by name)
 	public:
 		/**
 		 * @brief Set an integer value for the current shader constant buffer.
 		 */
 		bool setShaderValue(const std::string &name, ValueType type, size_t elements, const void *pValue);
 
+	// overridables
+	public:
+		/**
+		 * @brief Get a pointer to the value of the given variable.
+		 * @param name		Name of the variable to get.
+		 * @param type		Type of the variables.
+		 * @param elements	Number of elements of this variable, when this variable is an array.
+		 * @return A pointer to the requested variable, or \c NULL, when the variable was not found
+		 *			or does not match the given types.
+		 */
+		virtual const data_t getShaderDataPointer(const std::string &name, ValueType type, size_t elements) const = 0;
+
 	/// overridables
 	protected:
 		/**
 			public ShaderConstantBufferWriter
 	{
 	public:
-		/// pointer type
-		typedef unsigned char* data_t;
-
 		/// type for the constant buffer version number
 		typedef uint16_t version_t;
 
+		/// type for indices of the values within this buffer
+		typedef signed int index_t;
+
 		ShaderConstantBuffer(ShaderConstantBufferTemplate *buffer_template);
 		virtual ~ShaderConstantBuffer();
 
 			return buffer_template;
 		}
 
+	// setter (by index))
+	public:
+		/**
+		 * @brief Set an integer value for the current shader constant buffer.
+		 * @param index		The index of the variable to set.
+		 * @param i			The integer value for the shader attribute.
+		 */
+		bool setShaderValueAt(index_t index, int32_t i);
+
+		/**
+		 * @brief Set a float value for the current shader constant buffer.
+		 * @param index		The index of the variable to set.
+		 * @param f			The float value for the shader attribute.
+		 */
+		bool setShaderValueAt(index_t index, float f);
+
+		/**
+		 * @brief Set a 2D-vector value for the current shader constant buffer.
+		 * @param index		The index of the variable to set.
+		 * @param v			The vector value for the shader attribute.
+		 */
+		bool setShaderValueAt(index_t index, const vector2d &v);
+
+		/**
+		 * @brief Set a 3D-vector value for the current shader constant buffer.
+		 * @param index		The index of the variable to set.
+		 * @param v			The vector value for the shader attribute.
+		 */
+		bool setShaderValueAt(index_t index, const vector3d &v);
+
+		/**
+		 * @brief Set a 4x4 matrix value for the current shader constant buffer.
+		 * @param index		The index of the variable to set.
+		 * @param m			The matrix value for the shader attribute.
+		 */
+		bool setShaderValueAt(index_t index, const matrix4x4 &m);
+
+		/**
+		 * @brief Set a single value of a shader constant buffer.
+		 * @param index		The index of the variable to set.
+		 * @param type		The value type.
+		 * @param elements	The number of elements of this value, to use an array of values.
+		 * @param pValue	Pointer to the value, which will be written into the constant buffer.
+		 */
+		bool setShaderValueAt(index_t index, ValueType type, size_t elements, const void *pValue);
+
 	// data access
 	public:
 		/**
+		 * @brief Get the index of a specific shader value.
+		 * @param name		Name of the variable to get.
+		 * @return The index of the requested variable or \c -1, when not found.
+		 */
+		index_t getShaderValueIndex(const std::string& name) const;
+
+		/**
 		 * @brief Writes raw data to a given offset.
 		 * The buffer needs to be large enough to store the whole data block,
 		 * otherwise the operation will fail.
 
 	// ShaderConstantBufferWriter
 	public:
+		virtual const data_t getShaderDataPointer(const std::string &name, ValueType type, size_t elements) const;
+
+	// ShaderConstantBufferWriter
+	protected:
 		virtual bool doSetShaderValue(const std::string &name, ValueType type, size_t elements, const void *pValue);
 
 	// DeviceResource implementation

File src/core/wiesel/video/shader_target.cpp

View file
 }
 
 
+const ShaderTarget::data_t ShaderTarget::getShaderDataPointer(const std::string& name, ValueType type, size_t elements) const {
+	for(BufferMap::const_iterator it=buffers.begin(); it!=buffers.end(); it++) {
+		data_t result = it->second->getShaderDataPointer(name, type, elements);
+
+		if (result) {
+			return result;
+		}
+	}
+
+	return NULL;
+}
+
 
 void ShaderTarget::applyShaderConfigTo(RenderContext* rc) {
 	rc->setShader(getShader());
 
-	for(BufferMap::iterator it=buffers.begin(); it!=buffers.end(); it++) {
-		rc->assignShaderConstantBuffer(it->first, it->second);
+	if (getShader()) {
+		for(BufferMap::iterator it=buffers.begin(); it!=buffers.end(); it++) {
+			ShaderConstantBufferTemplate *buffer_template = getShader()->findConstantBufferTemplate(it->first);
+
+			if (buffer_template) {
+				rc->assignShaderConstantBuffer(buffer_template, it->second);
+			}
+		}
 	}
 
 	return;

File src/core/wiesel/video/shader_target.h

View file
 		}
 
 	// ConstantBufferSetter
+	public:
+		virtual const data_t getShaderDataPointer(const std::string &name, ValueType type, size_t elements) const;
+
+	// ConstantBufferSetter
 	protected:
 		virtual bool doSetShaderValue(const std::string &name, ValueType type, size_t elements, const void *pValue);
 

File src/directx11/wiesel/dx11/video/dx11_render_context.cpp

View file
 	this->active_shader				= NULL;
 	this->active_shader_content		= NULL;
 
-	this->cb_modelview_content		= NULL;
-	this->cb_projection_content		= NULL;
-
 	return;
 }
 
 DirectX11RenderContext::~DirectX11RenderContext() {
 	releaseContext();
 
-	safe_release(cb_modelview_content);
-	safe_release(cb_projection_content);
-
 	return;
 }
 
 	blendFactor[3] = 0.0f;
 	d3d_device_context->OMSetBlendState(blendstate_enabled, blendFactor, 0xffffffff);
 
-	// prepare the default constant buffers
-	if(!cb_modelview->isLoaded()) {
-		cb_modelview->loadContentFrom(getScreen());
-	}
-
-	if(!cb_projection->isLoaded()) {
-		cb_projection->loadContentFrom(getScreen());
-	}
-
-	cb_modelview_content  = keep(dynamic_cast<Dx11ShaderConstantBufferContent*>(cb_modelview->getContent()));
-	cb_projection_content = keep(dynamic_cast<Dx11ShaderConstantBufferContent*>(cb_projection->getContent()));
-
 	return;
 }
 
 	setShader(NULL);
 	clearTextures();
 
-	// clear temporary members
-	safe_release(cb_modelview_content);
-	safe_release(cb_projection_content);
-
 	// display screen
 	if (vsync) {
 		swap_chain->Present(1, 0);
 
 
 void DirectX11RenderContext::setProjectionMatrix(const matrix4x4& matrix) {
-	assert(cb_projection);
-
 	this->projection = matrix;
-	this->cb_projection->setShaderValue(Shaders::UNIFORM_PROJECTION_MATRIX, this->projection);
-
-	if (active_shader_content) {
-		active_shader_content->assignShaderConstantBuffer(
-									Shaders::CONSTANTBUFFER_PROJECTION_MATRIX,
-									this->cb_projection_content
-		);
-	}
-
 	return;
 }
 
 
 void DirectX11RenderContext::setModelviewMatrix(const matrix4x4& matrix) {
-	assert(cb_modelview);
+	if (active_shader && active_shader_content) {
 
-	this->cb_modelview->setShaderValue(Shaders::UNIFORM_MODELVIEW_MATRIX, matrix);
+		// get the active shader's matrix buffer template
+		ShaderConstantBufferTemplate *modelview_buffer_template;
+		modelview_buffer_template = active_shader->getModelviewMatrixConstantBufferTemplate();
 
-	if (active_shader_content) {
-		active_shader_content->assignShaderConstantBuffer(
-									Shaders::CONSTANTBUFFER_MODELVIEW_MATRIX,
-									this->cb_modelview_content
-		);
+		if (modelview_buffer_template) {
+			// get the template's shared buffer
+			ShaderConstantBuffer *modelview_buffer = modelview_buffer_template->getSharedBuffer();
+
+			// update the modelview value
+			bool was_set = modelview_buffer->setShaderValueAt(0, matrix);
+			assert(was_set);
+
+			// get the buffer's content
+			ShaderConstantBufferContent *modelview_buffer_content = modelview_buffer->getContent();
+			if (modelview_buffer_content == NULL) {
+				modelview_buffer->loadContentFrom(getScreen());
+				modelview_buffer_content = modelview_buffer->getContent();
+				assert(modelview_buffer_content);
+			}
+
+			active_shader_content->assignShaderConstantBuffer(
+										modelview_buffer_template,
+										modelview_buffer_content
+			);
+		}
 	}
 
 	return;
 		if (active_shader_content) {
 			active_shader_content->bind(this);
 
-			// update projection matrix for the current shader
-			active_shader_content->assignShaderConstantBuffer(
-										Shaders::CONSTANTBUFFER_PROJECTION_MATRIX,
-										this->cb_projection_content
-			);
+			// get the shader's projection matrix buffer template
+			ShaderConstantBufferTemplate *projection_buffer_template;
+			projection_buffer_template = active_shader->getProjectionMatrixConstantBufferTemplate();
+
+			if (projection_buffer_template) {
+				// get the template's shared buffer
+				ShaderConstantBuffer *projection_buffer = projection_buffer_template->getSharedBuffer();
+
+				// get the data pointer
+				ShaderConstantBuffer::data_t projection_data_ptr = projection_buffer->getShaderDataPointer(
+													Shaders::UNIFORM_PROJECTION_MATRIX,
+													TypeMatrix4x4f,
+													1
+				);
+
+				// check if the projection matrix has changed
+				if (this->projection != *(reinterpret_cast<const matrix4x4*>(projection_data_ptr))) {
+					projection_buffer->setShaderValueAt(0, this->projection);
+				}
+
+				// get the buffer's content
+				ShaderConstantBufferContent *projection_buffer_content = projection_buffer->getContent();
+				if (projection_buffer_content == NULL) {
+					projection_buffer->loadContentFrom(getScreen());
+					projection_buffer_content = projection_buffer->getContent();
+					assert(projection_buffer_content);
+				}
+
+				// update projection matrix for the current shader
+				active_shader_content->assignShaderConstantBuffer(
+											projection_buffer_template,
+											projection_buffer_content
+				);
+			}
 		}
 		else {
 			d3d_device_context->VSSetShader(NULL, NULL, 0);
 }
 
 
-bool DirectX11RenderContext::assignShaderConstantBuffer(const std::string &name, wiesel::video::ShaderConstantBuffer *buffer) {
+bool DirectX11RenderContext::assignShaderConstantBuffer(const wiesel::video::ShaderConstantBufferTemplate *buffer_template, wiesel::video::ShaderConstantBuffer *buffer) {
 	if (active_shader_content) {
 		// load on demand
 		if(!buffer->isLoaded()) {
 			}
 		}
 
-		active_shader_content->assignShaderConstantBuffer(name, buffer->getContent());
+		active_shader_content->assignShaderConstantBuffer(buffer_template, buffer->getContent());
 	}
 
 	return false;

File src/directx11/wiesel/dx11/video/dx11_render_context.h

View file
 
 	public:
 		virtual void setShader(wiesel::video::Shader *shader);
-		virtual bool assignShaderConstantBuffer(const std::string &name, wiesel::video::ShaderConstantBuffer *buffer);
+		virtual bool assignShaderConstantBuffer(const wiesel::video::ShaderConstantBufferTemplate *buffer_template, wiesel::video::ShaderConstantBuffer *buffer);
 		virtual void setTexture(uint16_t index, wiesel::video::Texture *texture);
 		virtual void prepareTextureLayers(uint16_t layers);
 		virtual void clearTextures();
 		Dx11ShaderContent*						active_shader_content;
 		std::vector<wiesel::video::Texture*>	active_textures;
 		std::vector<Dx11TextureContent*		>	active_textures_content;
-
-		Dx11ShaderConstantBufferContent*		cb_modelview_content;
-		Dx11ShaderConstantBufferContent*		cb_projection_content;
 	};
 
 }

File src/directx11/wiesel/dx11/video/dx11_shader_content.cpp

View file
 }
 
 
-bool Dx11ShaderContent::assignShaderConstantBuffer(const std::string &name, ShaderConstantBufferContent *buffer_content) {
+bool Dx11ShaderContent::assignShaderConstantBuffer(const wiesel::video::ShaderConstantBufferTemplate *buffer_template, ShaderConstantBufferContent *buffer_content) {
 	Dx11ShaderConstantBufferContent *dx11_buffer_content = dynamic_cast<Dx11ShaderConstantBufferContent*>(buffer_content);
 
 	if (dx11_buffer_content) {
-		return assignShaderConstantBuffer(name, dx11_buffer_content);
+		return assignShaderConstantBuffer(buffer_template, dx11_buffer_content);
 	}
 
 	return false;
 }
 
 
-bool Dx11ShaderContent::assignShaderConstantBuffer(const std::string &name, Dx11ShaderConstantBufferContent *buffer_content) {
-	const ShaderConstantBufferTemplate *buffer_template = getShader()->findConstantBufferTemplate(name);
+bool Dx11ShaderContent::assignShaderConstantBuffer(const wiesel::video::ShaderConstantBufferTemplate *buffer_template, Dx11ShaderConstantBufferContent *buffer_content) {
 	if (buffer_template) {
 		ShaderConstantBuffer::version_t new_version = buffer_content->getShaderConstantBuffer()->getChangeVersion();
 		ShaderConstantBufferEntryMap::iterator entry = shader_constant_buffer_entries.find(buffer_template);

File src/directx11/wiesel/dx11/video/dx11_shader_content.h

View file
 
 	public:
 		/// assigns a constant buffer to the current shader instance.
-		virtual bool assignShaderConstantBuffer(const std::string &name, wiesel::video::ShaderConstantBufferContent *buffer_content);
+		virtual bool assignShaderConstantBuffer(const wiesel::video::ShaderConstantBufferTemplate *buffer_template, wiesel::video::ShaderConstantBufferContent *buffer_content);
 
 		/// assigns a constant buffer to the current shader instance.
-		bool assignShaderConstantBuffer(const std::string &name, Dx11ShaderConstantBufferContent *buffer_content);
+		bool assignShaderConstantBuffer(const wiesel::video::ShaderConstantBufferTemplate *buffer_template, Dx11ShaderConstantBufferContent *buffer_content);
 
 		/// bind this shader to the context
 		bool bind(DirectX11RenderContext *render_context);

File src/opengl/wiesel/video/gl/gl_render_context.cpp

View file
 	this->active_shader				= NULL;
 	this->active_shader_content		= NULL;
 
-	this->cb_modelview_content		= NULL;
-	this->cb_projection_content		= NULL;
-
 	return;
 }
 
 OpenGlRenderContext::~OpenGlRenderContext() {
 	releaseContext();
 
-	safe_release(cb_modelview_content);
-	safe_release(cb_projection_content);
-
 	return;
 }
 
 	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 	CHECK_GL_ERROR;
 
-	// prepare the default constant buffers
-	if(!cb_modelview->isLoaded()) {
-		cb_modelview->loadContentFrom(getScreen());
-	}
-
-	if(!cb_projection->isLoaded()) {
-		cb_projection->loadContentFrom(getScreen());
-	}
-
-	cb_modelview_content  = dynamic_cast<GlShaderConstantBufferContent*>(cb_modelview->getContent());
-	keep(cb_modelview_content);
-
-	cb_projection_content = dynamic_cast<GlShaderConstantBufferContent*>(cb_projection->getContent());
-	keep(cb_projection_content);
-
 	return;
 }
 
 	setShader(NULL);
 	clearTextures();
 
-	// clear temporary members
-	safe_release(cb_modelview_content);
-	safe_release(cb_projection_content);
-
 	return;
 }
 
 
 
 void OpenGlRenderContext::setProjectionMatrix(const matrix4x4& matrix) {
-	assert(cb_projection);
-
 	this->projection = matrix;
-	this->cb_projection->setShaderValue(Shaders::UNIFORM_PROJECTION_MATRIX, this->projection);
-
-	if (active_shader_content) {
-		active_shader_content->assignShaderConstantBuffer(
-									Shaders::CONSTANTBUFFER_PROJECTION_MATRIX,
-									this->cb_projection_content
-		);
-	}
-
-	return;
 }
 
 
 void OpenGlRenderContext::setModelviewMatrix(const matrix4x4& matrix) {
-	assert(cb_modelview);
+	if (active_shader && active_shader_content) {
 
-	this->cb_modelview->setShaderValue(Shaders::UNIFORM_MODELVIEW_MATRIX, matrix);
+		// get the active shader's matrix buffer template
+		ShaderConstantBufferTemplate *modelview_buffer_template = NULL;
+		modelview_buffer_template = active_shader->getModelviewMatrixConstantBufferTemplate();
 
-	if (active_shader_content) {
-		active_shader_content->assignShaderConstantBuffer(
-									Shaders::CONSTANTBUFFER_MODELVIEW_MATRIX,
-									this->cb_modelview_content
-		);
+		if (modelview_buffer_template) {
+			// get the template's shared buffer
+			ShaderConstantBuffer *modelview_buffer = modelview_buffer_template->getSharedBuffer();
+
+			// update the modelview value
+			bool was_set = modelview_buffer->setShaderValueAt(0, matrix);
+			assert(was_set);
+
+			// get the buffer's content
+			ShaderConstantBufferContent *modelview_buffer_content = modelview_buffer->getContent();
+			if (modelview_buffer_content == NULL) {
+				modelview_buffer->loadContentFrom(getScreen());
+				modelview_buffer_content = modelview_buffer->getContent();
+				assert(modelview_buffer_content);
+			}
+
+			active_shader_content->assignShaderConstantBuffer(
+										modelview_buffer_template,
+										modelview_buffer_content
+			);
+		}
 	}
 
 	return;
 		if (active_shader_content) {
 			glUseProgram(active_shader_content->getGlHandle());
 
-			// update projection matrix for the current shader
-			active_shader_content->assignShaderConstantBuffer(
-										Shaders::CONSTANTBUFFER_PROJECTION_MATRIX,
-										this->cb_projection_content
-			);
+			// get the shader's projection matrix buffer template
+			ShaderConstantBufferTemplate *projection_buffer_template;
+			projection_buffer_template = active_shader->getProjectionMatrixConstantBufferTemplate();
+
+			if (projection_buffer_template) {
+				// get the template's shared buffer
+				ShaderConstantBuffer *projection_buffer = projection_buffer_template->getSharedBuffer();
+
+				// get the data pointer
+				ShaderConstantBuffer::data_t projection_data_ptr = projection_buffer->getShaderDataPointer(
+													Shaders::UNIFORM_PROJECTION_MATRIX,
+													TypeMatrix4x4f,
+													1
+				);
+
+				// check if the projection matrix has changed
+				if (this->projection != *(reinterpret_cast<const matrix4x4*>(projection_data_ptr))) {
+					projection_buffer->setShaderValueAt(0, this->projection);
+				}
+
+				// get the buffer's content
+				ShaderConstantBufferContent *projection_buffer_content = projection_buffer->getContent();
+				if (projection_buffer_content == NULL) {
+					projection_buffer->loadContentFrom(getScreen());
+					projection_buffer_content = projection_buffer->getContent();
+					assert(projection_buffer_content);
+				}
+
+				// update projection matrix for the current shader
+				active_shader_content->assignShaderConstantBuffer(
+											projection_buffer_template,
+											projection_buffer_content
+				);
+			}
 		}
 		else {
 			glUseProgram(0);
 }
 
 
-bool OpenGlRenderContext::assignShaderConstantBuffer(const std::string &name, ShaderConstantBuffer *buffer) {
+bool OpenGlRenderContext::assignShaderConstantBuffer(const ShaderConstantBufferTemplate *buffer_template, ShaderConstantBuffer *buffer) {
 	if (active_shader_content) {
 		// load on demand
 		if (buffer->isLoaded() == false) {
 			}
 		}
 
-		return active_shader_content->assignShaderConstantBuffer(name, buffer->getContent());
+		return active_shader_content->assignShaderConstantBuffer(buffer_template, buffer->getContent());
 	}
 
 	return false;
 		if (texture) {
 			active_texture = keep(texture);
 
-			GlTextureContent *gl_texture_content = dynamic_cast<GlTextureContent*>(active_texture->getContent());
-			if (gl_texture_content) {
-				active_texture_content = keep(gl_texture_content);
-			}
+			active_texture_content = dynamic_cast<GlTextureContent*>(active_texture->getContent());
+		}
+
+		if (active_texture_content) {
+			keep(active_texture_content);
+
+			glActiveTexture(GL_TEXTURE0 + index);
+			glBindTexture(GL_TEXTURE_2D, active_texture_content->getGlHandle());
+		}
+		else {
+			glActiveTexture(GL_TEXTURE0 + index);
+			glBindTexture(GL_TEXTURE_2D, 0);
 		}
 
 		// write active textures into the texture list
 				if (texture_content && attr_vertex_texture != -1) {
 					assert(attr_vertex_texture  != -1);
 
-					glActiveTexture(GL_TEXTURE0 + i);
-					glBindTexture(GL_TEXTURE_2D, texture_content->getGlHandle());
+				//	glActiveTexture(GL_TEXTURE0 + i);
+				//	glBindTexture(GL_TEXTURE_2D, texture_content->getGlHandle());
 					glUniform1i(attr_vertex_texture, i);
 					CHECK_GL_ERROR;
 				}
 		}
 
 		if (vertex_buffer->hasNormals()) {
-			GLint attr_vertex_normals =active_shader_content->getAttribHandle(Shader::VertexNormal, 0);
+			GLint attr_vertex_normals = active_shader_content->getAttribHandle(Shader::VertexNormal, 0);
 			glDisableVertexAttribArray(attr_vertex_normals);
 		}
 

File src/opengl/wiesel/video/gl/gl_render_context.h

View file
 
 	public:
 		virtual void setShader(Shader *shader);
-		virtual bool assignShaderConstantBuffer(const std::string &name, ShaderConstantBuffer *buffer);
+		virtual bool assignShaderConstantBuffer(const ShaderConstantBufferTemplate *buffer_template, ShaderConstantBuffer *buffer);
 
 		virtual void setTexture(uint16_t index, Texture *texture);
 		virtual void prepareTextureLayers(uint16_t layers);
 		GlShaderContent*					active_shader_content;
 		std::vector<Texture*>				active_textures;
 		std::vector<GlTextureContent*>		active_textures_content;
-
-		GlShaderConstantBufferContent*		cb_modelview_content;
-		GlShaderConstantBufferContent*		cb_projection_content;
 	};
 
 }

File src/opengl/wiesel/video/gl/gl_shader_content.cpp

View file
 
 
 GLint GlShaderContent::getAttribHandle(Shader::Attribute attr, uint8_t index) const {
-	if (attribute_handles.size() >= attr && attribute_handles[attr].size() >= index) {
-		return attribute_handles[attr][index];
+	if (attribute_handles.size() >= attr) {
+		const AttributeHandlesByIndex* attrib_handles_by_index = &(attribute_handles[attr]);
+
+		if (attrib_handles_by_index->size() >= index) {
+			return (*attrib_handles_by_index)[index];
+		}
 	}
 
 	return -1;
 }
 
 
-bool GlShaderContent::assignShaderConstantBuffer(const std::string& name, ShaderConstantBufferContent* buffer_content) {
-	const ShaderConstantBufferTemplate *buffer_template = getShader()->findConstantBufferTemplate(name);
+bool GlShaderContent::assignShaderConstantBuffer(const ShaderConstantBufferTemplate *buffer_template, ShaderConstantBufferContent* buffer_content) {
 	if (buffer_template) {
 		ShaderConstantBuffer::version_t new_version = buffer_content->getShaderConstantBuffer()->getChangeVersion();
 		BufferEntryMap::iterator entry = buffer_entries.find(buffer_template);
 		if (entry == buffer_entries.end()) {
 			BufferEntry buffer_entry;
 			buffer_entry.buffer  = buffer_content->getShaderConstantBuffer();
-			buffer_entry.version = buffer_content->getShaderConstantBuffer()->getChangeVersion();
+			buffer_entry.version = 0;
+
+			// store uniform informations for each uniform, which belongs to this buffer
+			const ShaderConstantBufferTemplate::EntryList *entries = buffer_template->getEntries();
+			for(ShaderConstantBufferTemplate::EntryList::const_iterator it_unif=entries->begin(); it_unif!=entries->end(); it_unif++) {
+				std::map<std::string,GLint>::iterator it_handle = uniform_attributes.find(it_unif->name);
+
+				if (it_handle != uniform_attributes.end()) {
+					UniformEntry uniform_entry;
+					uniform_entry.entry  = &(*it_unif);
+					uniform_entry.handle = it_handle->second;
+					buffer_entry.buffer_uniforms.push_back(uniform_entry);
+				}
+			}
+
 			buffer_entries[buffer_template] = buffer_entry;
 
 			entry = buffer_entries.find(buffer_template);
 			entry->second.version = new_version;
 			entry->second.buffer  = buffer_content->getShaderConstantBuffer();
 
-			const ShaderConstantBufferTemplate::EntryList *entries = buffer_template->getEntries();
-			for(ShaderConstantBufferTemplate::EntryList::const_iterator it=entries->begin(); it!=entries->end(); it++) {
+			const UniformEntryList *uniform_entries = &(entry->second.buffer_uniforms);
+			for(UniformEntryList::const_iterator it=uniform_entries->begin(); it!=uniform_entries->end(); it++) {
 				bool success = setShaderValue(
-									it->name,
-									it->type,
-									it->elements,
-									buffer_content->getShaderConstantBuffer()->getDataPtr() + it->offset
+									it->handle,
+									it->entry->type,
+									it->entry->elements,
+									buffer_content->getShaderConstantBuffer()->getDataPtr() + it->entry->offset
 				);
 
 				assert(success);
 
 bool GlShaderContent::setShaderValue(const std::string &name, ValueType type, size_t elements, void *pValue) {
 	std::map<std::string,GLint>::iterator it = uniform_attributes.find(name);
+	if (it != uniform_attributes.end()) {
+		GLint attrib_handle = it->second;
+		return setShaderValue(attrib_handle, type, elements, pValue);
+	}
 
-	if (it != uniform_attributes.end() && it->second != -1) {
-		GLint attrib_handle = it->second;
+	return false;
+}
 
+bool GlShaderContent::setShaderValue(GLint attrib_handle, ValueType type, size_t elements, void *pValue) {
+	if (attrib_handle != -1) {
 		switch(type) {
 			case TypeInt32: {
 				if (elements == 1) {
 				glUniformMatrix4fv(attrib_handle, elements, false, reinterpret_cast<GLfloat*>(pValue));
 				break;
 			}
+
+			default: {
+				return false;
+			}
 		}
 
 		CHECK_GL_ERROR;

File src/opengl/wiesel/video/gl/gl_shader_content.h

View file
 		GLint getAttribHandle(Shader::Attribute attr, uint8_t index) const;
 
 		/// assigns a constant buffer to the current shader instance.
-		virtual bool assignShaderConstantBuffer(const std::string &name, ShaderConstantBufferContent *buffer_content);
+		virtual bool assignShaderConstantBuffer(const ShaderConstantBufferTemplate *buffer_template, ShaderConstantBufferContent *buffer_content);
+
+	protected:
+		/// set a uniform shader value
+		bool setShaderValue(const std::string &name, ValueType type, size_t elements, void *pValue);
 
 		/// set a uniform shader value
-		virtual bool setShaderValue(const std::string &name, ValueType type, size_t elements, void *pValue);
+		bool setShaderValue(GLint attrib_handle, ValueType type, size_t elements, void *pValue);
 
 	private:
+		struct UniformEntry {
+			const ShaderConstantBufferTemplate::Entry*	entry;
+			GLint										handle;
+		};
+
+		/// alias type for a list of uniform entries
+		typedef std::vector<UniformEntry>				UniformEntryList;
+
 		struct BufferEntry {
-			ShaderConstantBuffer*				buffer;
-			ShaderConstantBuffer::version_t		version;
+			ShaderConstantBuffer*						buffer;
+			ShaderConstantBuffer::version_t				version;
+
+			UniformEntryList							buffer_uniforms;
 		};
 
 		/// Alias type for an indiced list of attribute names