Panagiotis Christopoulos Charitos 14 лет назад
Родитель
Сommit
6f73bfd376

+ 5 - 8
anki/resource/MaterialVariable.cpp

@@ -24,11 +24,9 @@ MaterialVariable::MaterialVariable(
 	const char* shaderProgVarName,
 	const PassLevelToShaderProgramHashMap& sProgs,
 	const std::string& val)
-	: type(T_USER)
+	: initialized(true)
 {
 	init(shaderProgVarName, sProgs);
-	ANKI_ASSERT(getShaderProgramVariableType() ==
-		ShaderProgramVariable::T_UNIFORM);
 	data = TextureResourcePointer();
 	boost::get<TextureResourcePointer>(data).load(val.c_str());
 }
@@ -40,18 +38,17 @@ void MaterialVariable::init(const char* shaderProgVarName,
 {
 	oneSProgVar = NULL;
 
+	// For all sprogs
 	PassLevelToShaderProgramHashMap::const_iterator it = sProgs.begin();
 	for(; it != sProgs.end(); ++it)
 	{
 		const ShaderProgram& sProg = *(it->second);
 		const PassLevelKey& key = it->first;
 
-		if(sProg.variableExists(shaderProgVarName))
+		if(sProg.uniformVariableExists(shaderProgVarName))
 		{
-			const ShaderProgramVariable& sProgVar =
-				sProg.getVariableByName(shaderProgVarName);
-
-			ANKI_ASSERT(sProgVar.getType() == ShaderProgramVariable::T_UNIFORM);
+			const ShaderProgramUniformVariable& sProgVar =
+				sProg.findUniformVariableByName(shaderProgVarName);
 
 			sProgVars[key] = &sProgVar;
 

+ 21 - 30
anki/resource/MaterialVariable.h

@@ -1,7 +1,7 @@
 #ifndef ANKI_RESOURCE_MATERIAL_VARIABLE_H
 #define ANKI_RESOURCE_MATERIAL_VARIABLE_H
 
-#include "anki/resource/ShaderProgramVariable.h"
+#include "anki/resource/ShaderProgramUniformVariable.h"
 #include "anki/resource/MaterialCommon.h"
 #include "anki/math/Math.h"
 #include "anki/resource/Resource.h"
@@ -20,29 +20,28 @@ namespace anki {
 class MaterialVariable
 {
 public:
-	/// The type
-	enum Type
-	{
-		T_USER,
-		T_BUILDIN
-	};
-
 	/// The data union (limited to a few types at the moment)
 	typedef boost::variant<float, Vec2, Vec3, Vec4, Mat3,
 		Mat4, TextureResourcePointer> Variant;
 
 	/// Given a pair of pass and level it returns a pointer to a
-	/// shader program variable. The pointer may be null
-	typedef PassLevelHashMap<const ShaderProgramVariable*>::Type
-		PassLevelToShaderProgramVariableHashMap;
+	/// shader program uniform variable. The pointer may be null
+	typedef PassLevelHashMap<const ShaderProgramUniformVariable*>::Type
+		PassLevelToShaderProgramUniformVariableHashMap;
 
 	/// @name Constructors & destructor
 	/// @{
 
 	/// For build-ins
+	template<typename Type>
 	MaterialVariable(
 		const char* shaderProgVarName,
-		const PassLevelToShaderProgramHashMap& sProgs);
+		const PassLevelToShaderProgramHashMap& sProgs)
+		: initialized(false)
+	{
+		init(shaderProgVarName, sProgs);
+		data = Type();
+	}
 
 	/// For user defined
 	template<typename Type>
@@ -50,33 +49,26 @@ public:
 		const char* shaderProgVarName,
 		const PassLevelToShaderProgramHashMap& sProgs,
 		const Type& val)
+		: initialized(true)
 	{
 		init(shaderProgVarName, sProgs);
-		ANKI_ASSERT(getShaderProgramVariableType() ==
-			ShaderProgramVariable::T_UNIFORM);
 		data = val;
 	}
 	/// @}
 		
 	/// @name Accessors
 	/// @{
-	Type getType() const
-	{
-		return type;
-	}
-
 	const Variant& getVariant() const
 	{
 		return data;
 	}
 
 	/// XXX
-	const ShaderProgramVariable& getShaderProgramVariable(
+	const ShaderProgramUniformVariable& getShaderProgramUniformVariable(
 		const PassLevelKey& key) const
 	{
 		ANKI_ASSERT(inPass(key));
-		const ShaderProgramVariable* var =
-			sProgVars.at(key);
+		const ShaderProgramUniformVariable* var = sProgVars.at(key);
 		return *var;
 	}
 
@@ -99,21 +91,20 @@ public:
 		return oneSProgVar->getName();
 	}
 
-	/// Get the type of all the shader program variables
-	ShaderProgramVariable::Type getShaderProgramVariableType() const
+	bool getInitialized() const
 	{
-		return oneSProgVar->getType();
+		return initialized;
 	}
 	/// @}
 
 private:
-	Type type;
-	PassLevelToShaderProgramVariableHashMap sProgVars;
+	bool initialized;
+	PassLevelToShaderProgramUniformVariableHashMap sProgVars;
 	Variant data;
 
 	/// Keep one ShaderProgramVariable here for easy access of the common
 	/// variable stuff like name or GL data type etc
-	const ShaderProgramVariable* oneSProgVar;
+	const ShaderProgramUniformVariable* oneSProgVar;
 
 	/// Common constructor code
 	void init(const char* shaderProgVarName,
@@ -121,9 +112,9 @@ private:
 };
 
 
-/// Declaration for specialized (string)
+/// Declaration for specialized XXX
 template<>
-MaterialVariable::MaterialVariable<std::string>(
+MaterialVariable::MaterialVariable(
 	const char* shaderProgVarName,
 	const PassLevelToShaderProgramHashMap& sProgs,
 	const std::string& val);

+ 32 - 63
anki/resource/ShaderProgram.cpp

@@ -17,15 +17,12 @@
 namespace anki {
 
 
+//==============================================================================
+
 #define SHADER_PROGRAM_EXCEPTION(x) ANKI_EXCEPTION( \
 	"Shader program \"" + rsrcFilename + \
 	"\": " + x)
 
-
-//==============================================================================
-// Statics                                                                     =
-//==============================================================================
-
 const char* ShaderProgram::stdSourceCode =
 	"#version 330 core\n"
 	//"precision lowp float;\n"
@@ -38,8 +35,6 @@ const char* ShaderProgram::stdSourceCode =
 #endif
 
 
-//==============================================================================
-// Destructor                                                                  =
 //==============================================================================
 ShaderProgram::~ShaderProgram()
 {
@@ -47,8 +42,6 @@ ShaderProgram::~ShaderProgram()
 }
 
 
-//==============================================================================
-// createAndCompileShader                                                      =
 //==============================================================================
 uint ShaderProgram::createAndCompileShader(const char* sourceCode,
 	const char* preproc, int type) const
@@ -105,8 +98,6 @@ uint ShaderProgram::createAndCompileShader(const char* sourceCode,
 }
 
 
-//==============================================================================
-// link                                                                        =
 //==============================================================================
 void ShaderProgram::link() const
 {
@@ -133,8 +124,6 @@ void ShaderProgram::link() const
 }
 
 
-//==============================================================================
-// getUniAndAttribVars                                                         =
 //==============================================================================
 void ShaderProgram::getUniAndAttribVars()
 {
@@ -144,7 +133,6 @@ void ShaderProgram::getUniAndAttribVars()
 	GLint size;
 	GLenum type;
 
-
 	// attrib locations
 	glGetProgramiv(glId, GL_ACTIVE_ATTRIBUTES, &num);
 	for(int i = 0; i < num; i++) // loop all attributes
@@ -165,12 +153,13 @@ void ShaderProgram::getUniAndAttribVars()
 
 		ShaderProgramAttributeVariable* var =
 			new ShaderProgramAttributeVariable(loc, &name_[0], type, *this);
+
 		vars.push_back(var);
+		attribs.push_back(var);
 		nameToVar[var->getName().c_str()] = var;
 		nameToAttribVar[var->getName().c_str()] = var;
 	}
 
-
 	// uni locations
 	glGetProgramiv(glId, GL_ACTIVE_UNIFORMS, &num);
 	for(int i = 0; i < num; i++) // loop all uniforms
@@ -191,20 +180,20 @@ void ShaderProgram::getUniAndAttribVars()
 
 		ShaderProgramUniformVariable* var =
 			new ShaderProgramUniformVariable(loc, &name_[0], type, *this);
+
 		vars.push_back(var);
+		unis.push_back(var);
 		nameToVar[var->getName().c_str()] = var;
 		nameToUniVar[var->getName().c_str()] = var;
 	}
 }
 
 
-//==============================================================================
-// load                                                                        =
 //==============================================================================
 void ShaderProgram::load(const char* filename)
 {
 	rsrcFilename = filename;
-	ANKI_ASSERT(glId == std::numeric_limits<uint>::max());
+	ANKI_ASSERT(!isInitialized());
 
 	ShaderProgramPrePreprocessor pars(filename);
 
@@ -251,86 +240,74 @@ void ShaderProgram::load(const char* filename)
 
 
 //==============================================================================
-// getVariableByName                                                           =
-//==============================================================================
-const ShaderProgramVariable& ShaderProgram::getVariableByName(
+const ShaderProgramVariable& ShaderProgram::findVariableByName(
 	const char* name) const
 {
-	VarsHashMap::const_iterator it = nameToVar.find(name);
+	NameToVarHashMap::const_iterator it = nameToVar.find(name);
 	if(it == nameToVar.end())
 	{
-		throw SHADER_PROGRAM_EXCEPTION("Cannot get variable: " + name);
+		throw SHADER_PROGRAM_EXCEPTION("Cannot find variable: " + name);
 	}
 	return *(it->second);
 }
 
 
 //==============================================================================
-// getAttributeVariableByName                                                  =
-//==============================================================================
-const ShaderProgramAttributeVariable& ShaderProgram::getAttributeVariableByName(
-	const char* name) const
+const ShaderProgramAttributeVariable&
+	ShaderProgram::findAttributeVariableByName(const char* name) const
 {
-	AttribVarsHashMap::const_iterator it = nameToAttribVar.find(name);
+	NameToAttribVarHashMap::const_iterator it = nameToAttribVar.find(name);
 	if(it == nameToAttribVar.end())
 	{
-		throw SHADER_PROGRAM_EXCEPTION("Cannot get attribute loc: " + name);
+		throw SHADER_PROGRAM_EXCEPTION("Cannot find attribute loc: " + name);
 	}
 	return *(it->second);
 }
 
 
 //==============================================================================
-// getUniformVariableByName                                                    =
-//==============================================================================
-const ShaderProgramUniformVariable& ShaderProgram::getUniformVariableByName(
+const ShaderProgramUniformVariable& ShaderProgram::findUniformVariableByName(
 	const char* name) const
 {
-	UniVarsHashMap::const_iterator it = nameToUniVar.find(name);
+	NameToUniVarHashMap::const_iterator it = nameToUniVar.find(name);
 	if(it == nameToUniVar.end())
 	{
-		throw SHADER_PROGRAM_EXCEPTION("Cannot get uniform loc: " + name);
+		throw SHADER_PROGRAM_EXCEPTION("Cannot find uniform loc: " + name);
 	}
 	return *(it->second);
 }
 
 
-//==============================================================================
-// variableExists                                                              =
 //==============================================================================
 bool ShaderProgram::variableExists(const char* name) const
 {
-	VarsHashMap::const_iterator it = nameToVar.find(name);
+	NameToVarHashMap::const_iterator it = nameToVar.find(name);
 	return it != nameToVar.end();
 }
 
 
-//==============================================================================
-// uniformVariableExists                                                       =
 //==============================================================================
 bool ShaderProgram::uniformVariableExists(const char* name) const
 {
-	UniVarsHashMap::const_iterator it = nameToUniVar.find(name);
+	NameToUniVarHashMap::const_iterator it = nameToUniVar.find(name);
 	return it != nameToUniVar.end();
 }
 
 
-//==============================================================================
-// attributeVariableExists                                                     =
 //==============================================================================
 bool ShaderProgram::attributeVariableExists(const char* name) const
 {
-	AttribVarsHashMap::const_iterator it = nameToAttribVar.find(name);
+	NameToAttribVarHashMap::const_iterator it = nameToAttribVar.find(name);
 	return it != nameToAttribVar.end();
 }
 
 
-//==============================================================================
-// createSrcCodeToCache                                                        =
 //==============================================================================
 std::string ShaderProgram::createSrcCodeToCache(const char* sProgFPathName,
 	const char* preAppendedSrcCode)
 {
+	using namespace boost::filesystem;
+
 	if(strlen(preAppendedSrcCode) < 1)
 	{
 		return sProgFPathName;
@@ -342,12 +319,10 @@ std::string ShaderProgram::createSrcCodeToCache(const char* sProgFPathName,
 	std::string suffix = boost::lexical_cast<std::string>(h);
 
 	//
-	boost::filesystem::path newfPathName =
-		AppSingleton::get().getCachePath() /
-		(boost::filesystem::path(sProgFPathName).filename().string()
-			+ "." + suffix);
+	path newfPathName = AppSingleton::get().getCachePath() /
+		(path(sProgFPathName).filename().string() + "." + suffix);
 
-	if(boost::filesystem::exists(newfPathName))
+	if(exists(newfPathName))
 	{
 		return newfPathName.string();
 	}
@@ -369,28 +344,22 @@ std::string ShaderProgram::createSrcCodeToCache(const char* sProgFPathName,
 
 
 //==============================================================================
-// getShaderInfoString                                                         =
-//==============================================================================
-std::string ShaderProgram::getShaderInfoString() const
+std::ostream& operator<<(std::ostream& s, const ShaderProgram& x)
 {
-	std::stringstream ss;
-
-	ss << "Variables:\n";
-	BOOST_FOREACH(const ShaderProgramVariable& var, vars)
+	s << "Variables:\n";
+	BOOST_FOREACH(const ShaderProgramVariable& var, x.getVariables())
 	{
-		ss << var.getName() << " " << var.getLocation() << " ";
+		s << var.getName() << " " << var.getLocation() << " ";
 		if(var.getType() == ShaderProgramVariable::T_ATTRIBUTE)
 		{
-			ss << "attribute";
+			s << "attribute";
 		}
 		else
 		{
-			ss << "uniform";
+			s << "uniform";
 		}
-		ss << std::endl;
 	}
-
-	return ss.str();
+	return s;
 }
 
 

+ 66 - 50
anki/resource/ShaderProgram.h

@@ -1,5 +1,5 @@
-#ifndef ANKI_RESOURCE_SHADER_PROGRAM_SHADER_PROGRAM_H
-#define ANKI_RESOURCE_SHADER_PROGRAM_SHADER_PROGRAM_H
+#ifndef ANKI_RESOURCE_SHADER_PROGRAM_H
+#define ANKI_RESOURCE_SHADER_PROGRAM_H
 
 #include "anki/util/ConstCharPtrHashMap.h"
 #include "anki/util/Assert.h"
@@ -9,52 +9,79 @@
 #include "anki/core/Globals.h"
 #include <boost/ptr_container/ptr_vector.hpp>
 #include <GL/glew.h>
-#include <limits>
 #include <vector>
+#include <boost/noncopyable.hpp>
 
 
 namespace anki {
 
 
-/// Shader program @ref Resource
+/// Shader program resource
 ///
 /// Shader program. Combines a fragment and a vertex shader. Every shader
 /// program consist of one OpenGL ID, a vector of uniform variables and a
 /// vector of attribute variables. Every variable is a struct that contains
 /// the variable's name, location, OpenGL data type and if it is a uniform or
 /// an attribute var.
-class ShaderProgram
+class ShaderProgram: public boost::noncopyable
 {
 public:
-	ShaderProgram();
+	typedef boost::ptr_vector<ShaderProgramVariable> VariablesContainer;
+	typedef std::vector<ShaderProgramUniformVariable*>
+		UniformVariablesContainer;
+	typedef std::vector<ShaderProgramAttributeVariable*>
+		AttributeVariablesContainer;
+
+	ShaderProgram()
+		: glId(UNINITIALIZED_ID)
+	{}
+
 	~ShaderProgram();
 
 	/// @name Accessors
 	/// @{
-	GLuint getGlId() const;
+	GLuint getGlId() const
+	{
+		ANKI_ASSERT(isInitialized());
+		return glId;
+	}
 
-	const boost::ptr_vector<ShaderProgramVariable>& getVariables() const
+	/// Get all variables container
+	const VariablesContainer& getVariables() const
 	{
 		return vars;
 	}
+
+	const UniformVariablesContainer& getUniformVariables() const
+	{
+		return unis;
+	}
+
+	const AttributeVariablesContainer& getAttributeVariables() const
+	{
+		return attribs;
+	}
 	/// @}
 
 	/// Resource load
 	void load(const char* filename);
 
 	/// Bind the shader program
-	void bind() const;
+	void bind() const
+	{
+		ANKI_ASSERT(isInitialized());
+		GlStateMachineSingleton::get().useShaderProg(glId);
+	}
 
-	/// @name Variable getters
+	/// @name Variable finders
 	/// Used to find and return the variable. They throw exception if
 	/// variable not found so ask if the variable with that name exists
 	/// prior using any of these
 	/// @{
-	const ShaderProgramVariable& getVariableByName(
+	const ShaderProgramVariable& findVariableByName(const char* varName) const;
+	const ShaderProgramUniformVariable& findUniformVariableByName(
 		const char* varName) const;
-	const ShaderProgramUniformVariable& getUniformVariableByName(
-		const char* varName) const;
-	const ShaderProgramAttributeVariable& getAttributeVariableByName(
+	const ShaderProgramAttributeVariable& findAttributeVariableByName(
 		const char* varName) const;
 	/// @}
 
@@ -76,30 +103,33 @@ public:
 	static std::string createSrcCodeToCache(const char* sProgFPathName,
 		const char* preAppendedSrcCode);
 
-	/// For debuging
-	std::string getShaderInfoString() const;
-
 	/// For sorting
 	bool operator<(const ShaderProgram& b) const
 	{
 		return glId < b.glId;
 	}
 
+	/// For debugging
+	friend std::ostream& operator<<(std::ostream& s,
+		const ShaderProgram& x);
+
 private:
-	/// XXX
-	typedef ConstCharPtrHashMap<ShaderProgramVariable*>::Type VarsHashMap;
+	typedef ConstCharPtrHashMap<ShaderProgramVariable*>::Type
+		NameToVarHashMap;
 
-	/// XXX
 	typedef ConstCharPtrHashMap<ShaderProgramUniformVariable*>::Type
-		UniVarsHashMap;
+		NameToUniVarHashMap;
 
-	/// XXX
 	typedef ConstCharPtrHashMap<ShaderProgramAttributeVariable*>::Type
-		AttribVarsHashMap;
+		NameToAttribVarHashMap;
+
+	static const GLuint UNINITIALIZED_ID = -1;
 
 	std::string rsrcFilename;
 	GLuint glId; ///< The OpenGL ID of the shader program
 	GLuint vertShaderGlId; ///< Vertex shader OpenGL id
+	GLuint tcShaderGlId; ///< Tessellation control shader OpenGL id
+	GLuint teShaderGlId; ///< Tessellation eval shader OpenGL id
 	GLuint geomShaderGlId; ///< Geometry shader OpenGL id
 	GLuint fragShaderGlId; ///< Fragment shader OpenGL id
 
@@ -108,10 +138,13 @@ private:
 
 	/// @name Containers
 	/// @{
-	boost::ptr_vector<ShaderProgramVariable> vars; ///< All the vars
-	VarsHashMap nameToVar; ///< Variable searching
-	UniVarsHashMap nameToUniVar; ///< Uniform searching
-	AttribVarsHashMap nameToAttribVar; ///< Attribute searching
+	VariablesContainer vars; ///< All the vars. Does garbage collection
+	UniformVariablesContainer unis;
+	AttributeVariablesContainer attribs;
+
+	NameToVarHashMap nameToVar; ///< Variable searching
+	NameToUniVarHashMap nameToUniVar; ///< Uniform searching
+	NameToAttribVarHashMap nameToAttribVar; ///< Attribute searching
 	/// @}
 
 	/// Query the driver to get the vars. After the linking of the shader
@@ -127,30 +160,13 @@ private:
 	/// Link the shader program
 	/// @exception Exception
 	void link() const;
-}; 
-
-
-//==============================================================================
-// Inlines                                                                     =
-//==============================================================================
-
-inline ShaderProgram::ShaderProgram()
-	: glId(std::numeric_limits<uint>::max())
-{}
-
 
-inline GLuint ShaderProgram::getGlId() const
-{
-	ANKI_ASSERT(glId != std::numeric_limits<uint>::max());
-	return glId;
-}
-
-
-inline void ShaderProgram::bind() const
-{
-	ANKI_ASSERT(glId != std::numeric_limits<uint>::max());
-	GlStateMachineSingleton::get().useShaderProg(glId);
-}
+	/// Returns true if the class points to a valid GL ID
+	bool isInitialized() const
+	{
+		return glId != UNINITIALIZED_ID;
+	}
+}; 
 
 
 } // end namespace

+ 0 - 10
anki/util/HighRezTimer.cpp

@@ -6,8 +6,6 @@
 namespace anki {
 
 
-//==============================================================================
-// Constructor                                                                 =
 //==============================================================================
 HighRezTimer::HighRezTimer():
 	startTime(0.0),
@@ -15,8 +13,6 @@ HighRezTimer::HighRezTimer():
 {}
 
 
-//==============================================================================
-// start                                                                       =
 //==============================================================================
 void HighRezTimer::start()
 {
@@ -27,8 +23,6 @@ void HighRezTimer::start()
 }
 
 
-//==============================================================================
-// stop                                                                        =
 //==============================================================================
 void HighRezTimer::stop()
 {
@@ -38,8 +32,6 @@ void HighRezTimer::stop()
 }
 
 
-//==============================================================================
-// getElapsedTime                                                              =
 //==============================================================================
 HighRezTimer::Scalar HighRezTimer::getElapsedTime() const
 {
@@ -54,8 +46,6 @@ HighRezTimer::Scalar HighRezTimer::getElapsedTime() const
 }
 
 
-//==============================================================================
-// getCrntTime                                                                 =
 //==============================================================================
 HighRezTimer::Scalar HighRezTimer::getCrntTime()
 {

+ 16 - 16
anki/util/HighRezTimer.h

@@ -10,28 +10,28 @@ namespace anki {
 /// High resolution timer. All time in seconds
 class HighRezTimer
 {
-	public:
-		/// The type that the timer manipulates the results
-		typedef double Scalar;
+public:
+	/// The type that the timer manipulates the results
+	typedef double Scalar;
 
-		HighRezTimer();
+	HighRezTimer();
 
-		/// Start the timer
-		void start();
+	/// Start the timer
+	void start();
 
-		/// Stop the timer
-		void stop();
+	/// Stop the timer
+	void stop();
 
-		/// Get the time elapsed between start and stop (if its stopped) or 
-		/// between start and the current time
-		Scalar getElapsedTime() const;
+	/// Get the time elapsed between start and stop (if its stopped) or
+	/// between start and the current time
+	Scalar getElapsedTime() const;
 
-		/// Get the current date's seconds
-		static Scalar getCrntTime();
+	/// Get the current date's seconds
+	static Scalar getCrntTime();
 
-	private:
-		Scalar startTime;
-		Scalar stopTime;
+private:
+	Scalar startTime;
+	Scalar stopTime;
 };