Kaynağa Gözat

Fixing bugs in texture

Panagiotis Christopoulos Charitos 13 yıl önce
ebeveyn
işleme
06b7135ad3

+ 4 - 7
anki/gl/ShaderProgram.cpp

@@ -119,10 +119,7 @@ void ShaderProgramUniformVariable::set(const Texture& tex) const
 	ANKI_ASSERT(getGlDataType() == GL_SAMPLER_2D 
 		|| getGlDataType() == GL_SAMPLER_2D_SHADOW);
 	
-	if(tex.getUnit() == -1)
-	{
-		tex.bind();
-	}
+	tex.bind();
 	glUniform1i(getLocation(), tex.getUnit());
 }
 
@@ -144,7 +141,7 @@ const char* ShaderProgram::stdSourceCode =
 	"#pragma debug(on)\n";
 #endif
 
-ShaderProgram* ShaderProgram::currentProgram = nullptr;
+const ShaderProgram* ShaderProgram::currentProgram = nullptr;
 
 
 //==============================================================================
@@ -176,8 +173,8 @@ void ShaderProgram::create(const char* vertSource, const char* tcSource,
 
 	if(geomSource != nullptr)
 	{
-		geomShaderGlId = createAndCompileShader(geomSource, preprocSource.c_str(), 
-			GL_GEOMETRY_SHADER);
+		geomShaderGlId = createAndCompileShader(geomSource, 
+			preprocSource.c_str(), GL_GEOMETRY_SHADER);
 	}
 
 	ANKI_ASSERT(fragSource != nullptr);

+ 7 - 7
anki/gl/ShaderProgram.h

@@ -166,7 +166,7 @@ public:
 };
 
 
-/// Shader program resource
+/// Shader program object
 ///
 /// Shader program. Combines. Every shader program consist of one OpenGL ID, a 
 /// vector of uniform variables and a vector of attribute variables. Every 
@@ -242,7 +242,7 @@ public:
 		const char* transformFeedbackVaryings[]);
 
 	/// Bind the shader program
-	void bind()
+	void bind() const
 	{
 		ANKI_ASSERT(isInitialized());
 		if(currentProgram == nullptr || currentProgram != this)
@@ -263,7 +263,7 @@ public:
 		const char* varName) const;
 	/// @}
 
-	static ShaderProgram* getCurrentProgram()
+	static const ShaderProgram* getCurrentProgram()
 	{
 		return currentProgram;
 	}
@@ -283,7 +283,10 @@ private:
 		NameToAttribVarHashMap;
 
 	/// Is an optimization. it keeps the program that is now binded 
-	static ShaderProgram* currentProgram;
+	static const ShaderProgram* currentProgram;
+
+	/// Shader source that is used in ALL shader programs
+	static const char* stdSourceCode;
 
 	GLuint glId; ///< The OpenGL ID of the shader program
 	GLuint vertShaderGlId; ///< Vertex shader OpenGL id
@@ -292,9 +295,6 @@ private:
 	GLuint geomShaderGlId; ///< Geometry shader OpenGL id
 	GLuint fragShaderGlId; ///< Fragment shader OpenGL id
 
-	/// Shader source that is used in ALL shader programs
-	static const char* stdSourceCode;
-
 	/// @name Containers
 	/// @{
 	VariablesContainer vars; ///< All the vars. Does garbage collection

+ 31 - 11
anki/gl/Texture.cpp

@@ -16,7 +16,7 @@ TextureManager::TextureManager()
 {
 	GLint tmp;
 	glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &tmp);
-	units.resize(tmp, nullptr);
+	units.resize(tmp, Unit{nullptr, 0});
 	
 	activeUnit = -1;
 	mipmapping = true;
@@ -42,11 +42,19 @@ void TextureManager::activateUnit(uint unit)
 //==============================================================================
 uint TextureManager::choseUnit(Texture* tex)
 {
+	// Increase life for all
+	//
+	for(Unit& unit : units)
+	{
+		++unit.life;
+	}
+
 	// Already binded
 	//
 	if(tex->unit != -1)
 	{
-		ANKI_ASSERT(units[tex->unit] == tex);
+		ANKI_ASSERT(units[tex->unit].tex == tex);
+		units[tex->unit].life = 0;
 		return tex->unit;
 	}
 
@@ -54,19 +62,31 @@ uint TextureManager::choseUnit(Texture* tex)
 	//
 	for(uint i = 0; i < units.size(); i++)
 	{
-		if(units[i] == nullptr)
+		if(units[i].tex == nullptr)
 		{
-			units[i] = tex;
+			units[i].tex = tex;
+			units[i].life = 0;
 			return i;
 		}
 	}
 
-	// If all units occupied chose a random for now
+	// If all units occupied chose the older
 	//
-	int tmp = rand() % units.size();
-	units[tmp]->unit = -1;
-	units[tmp] = tex;
-	return tmp;
+
+	// Find the unit with the max life
+	uint umaxlife = 0;
+	for(uint i = 1; i < units.size(); ++i)
+	{
+		if(units[umaxlife].life < units[i].life)
+		{
+			umaxlife = i;
+		}
+	}
+
+	units[umaxlife].tex->unit = -1;
+	units[umaxlife].tex = tex;
+	units[umaxlife].life = 0;
+	return umaxlife;
 }
 
 
@@ -75,9 +95,9 @@ void TextureManager::textureDeleted(Texture* tex)
 {
 	for(auto it = units.begin(); it != units.end(); ++it)
 	{
-		if(*it == tex)
+		if(it->tex == tex)
 		{
-			*it = nullptr;
+			it->tex = nullptr;
 			return;
 		}
 	}

+ 10 - 1
anki/gl/Texture.h

@@ -69,8 +69,17 @@ public:
 	void textureDeleted(Texture* tex);
 
 private:
+	/// Texture unit representation
+	struct Unit
+	{
+		Texture* tex;
+		/// The bigger the life is the longer the @a tex has stayed witout bing 
+		/// binded
+		uint life; 
+	};
+
 	/// Texture units. The last is reserved and only used in Texture::create
-	std::vector<Texture*> units;
+	std::vector<Unit> units;
 	uint activeUnit;
 
 	/// @name Hints

+ 2 - 4
anki/renderer/Deformer.cpp

@@ -1,8 +1,8 @@
 #include "anki/renderer/Deformer.h"
-#include "anki/resource/ShaderProgram.h"
+#include "anki/resource/ShaderProgramResource.h"
 #include "anki/resource/Material.h"
 #include "anki/scene/SkinNode.h"
-#include "anki/renderer/MainRenderer.h"
+#include "anki/gl/GlStateMachine.h"
 
 
 namespace anki {
@@ -76,12 +76,10 @@ void Deformer::deform(SkinNode& skinNode, SkinPatchNode& node) const
 			SkinMesh::VBO_TF_TANGENTS)->getGlId());
 	}
 
-	//glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, this->Query);
 	glBeginTransformFeedback(GL_POINTS);
 		glDrawArrays(GL_POINTS, 0,
 			smp.getSkinMesh().getVerticesNumber(0));
 	glEndTransformFeedback();
-	//glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
 
 	GlStateMachineSingleton::get().disable(GL_RASTERIZER_DISCARD);
 }