Panagiotis Christopoulos Charitos 15 éve
szülő
commit
a5dc9d3949
3 módosított fájl, 142 hozzáadás és 14 törlés
  1. 4 3
      src/Resources/Mesh.h
  2. 122 2
      src/Resources/Model.cpp
  3. 16 9
      src/Resources/Model.h

+ 4 - 3
src/Resources/Mesh.h

@@ -34,11 +34,12 @@ class Mesh: public Resource, public Object
 	public:
 		RsrcPtr<Material> material; ///< Required. If empty then mesh not renderable
 
-		/// Accessor to vao
+		/// @name Accessors
+		/// @{
 		const Vao* getVao() const {return mainVao;}
-
-		/// Accessor to depthVao
 		const Vao* getDepthVao() const {return depthVao;}
+		const Vbo* getVbo(Vbos id) const {return vbos[id];}
+		/// @}
 
 		/// Default constructor
 		Mesh(): Resource(RT_MESH), Object(NULL) {}

+ 122 - 2
src/Resources/Model.cpp

@@ -2,6 +2,11 @@
 #include "Parser.h"
 #include "Material.h"
 #include "Mesh.h"
+#include "SkelAnim.h"
+#include "MeshData.h"
+
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
 
 
 //======================================================================================================================
@@ -33,6 +38,7 @@ void Model::load(const char* filename)
 			{
 				scanner.getNextToken();
 
+				// }
 				if(token->getCode() == Scanner::TC_RBRACKET)
 				{
 					break;
@@ -48,6 +54,47 @@ void Model::load(const char* filename)
 			} // End for all subModels
 		}
 		//
+		// skeleton
+		//
+		if(Parser::isIdentifier(token, "skeleton"))
+		{
+			skeleton.loadRsrc(Parser::parseString(scanner).c_str());
+		}
+		//
+		// skelAnims
+		//
+		if(Parser::isIdentifier(token, "skelAnims"))
+		{
+			scanner.getNextToken();
+
+			// {
+			if(token->getCode() != Scanner::TC_LBRACKET)
+			{
+				throw PARSER_EXCEPTION_EXPECTED("{");
+			}
+
+			while(true)
+			{
+				scanner.getNextToken();
+
+				// }
+				if(token->getCode() != Scanner::TC_RBRACKET)
+				{
+					break;
+				}
+				else if(token->getCode() == Scanner::TC_STRING)
+				{
+					skelAnims.push_back(RsrcPtr<SkelAnim>());
+					skelAnims.back().loadRsrc(token->getValue().getString());
+				}
+				else
+				{
+					throw PARSER_EXCEPTION_EXPECTED("} or string");
+				}
+
+			}
+		}
+		//
 		// EOF
 		//
 		else if(token->getCode() == Scanner::TC_EOF)
@@ -62,6 +109,23 @@ void Model::load(const char* filename)
 			throw PARSER_EXCEPTION_UNEXPECTED();
 		}
 	} // end while
+
+	//
+	// Sanity checks
+	//
+	if(skelAnims.size() > 0 && skeleton.get() == NULL)
+	{
+		throw EXCEPTION("Model \"" + filename + "\": You have skeleton animations but no skeleton");
+	}
+
+	//
+	// Create VAOs
+	//
+	for(Vec<SubModel>::iterator it = subModels.begin(); it != subModels.end(); it++)
+	{
+		createVao(*it->material, *it->mesh, *it, it->normVao);
+		createVao(*it->dpMaterial, *it->mesh, *it, it->dpVao);
+	}
 }
 
 
@@ -93,6 +157,62 @@ void Model::parseSubModel(Scanner& scanner)
 	SubModel& subModel = subModels.back();
 
 	subModel.mesh.loadRsrc(mesh.c_str());
-	subModel.mtl.loadRsrc(material.c_str());
-	subModel.dpMtl.loadRsrc(dpMaterial.c_str());
+	subModel.material.loadRsrc(material.c_str());
+	subModel.dpMaterial.loadRsrc(dpMaterial.c_str());
+}
+
+
+//======================================================================================================================
+// createVao                                                                                                           =
+//======================================================================================================================
+void Model::createVao(const Material& mtl, const Mesh& mesh, SubModel& subModel, Vao*& vao)
+{
+	vao = new Vao(&subModel);
+
+	if(mtl.getStdAttribVar(Material::SAV_POSITION) != NULL)
+	{
+		vao->attachArrayBufferVbo(*mesh.getVbo(Mesh::VBO_VERT_POSITIONS), *mtl.getStdAttribVar(Material::SAV_POSITION),
+		                          3, GL_FLOAT, GL_FALSE, 0, NULL);
+	}
+
+	if(mtl.getStdAttribVar(Material::SAV_NORMAL) != NULL)
+	{
+		vao->attachArrayBufferVbo(*mesh.getVbo(Mesh::VBO_VERT_NORMALS), *mtl.getStdAttribVar(Material::SAV_NORMAL),
+		                          3, GL_FLOAT, GL_FALSE, 0, NULL);
+	}
+
+	if(mtl.getStdAttribVar(Material::SAV_TANGENT) != NULL)
+	{
+		vao->attachArrayBufferVbo(*mesh.getVbo(Mesh::VBO_VERT_TANGENTS), *mtl.getStdAttribVar(Material::SAV_TANGENT),
+		                          4, GL_FLOAT, GL_FALSE, 0, NULL);
+	}
+
+	if(mtl.getStdAttribVar(Material::SAV_TEX_COORDS) != NULL)
+	{
+		vao->attachArrayBufferVbo(*mesh.getVbo(Mesh::VBO_TEX_COORDS), *mtl.getStdAttribVar(Material::SAV_TEX_COORDS),
+		                          2, GL_FLOAT, GL_FALSE, 0, NULL);
+	}
+
+	if(mtl.getStdAttribVar(Material::SAV_VERT_WEIGHT_BONES_NUM) != NULL)
+	{
+		vao->attachArrayBufferVbo(*mesh.getVbo(Mesh::VBO_VERT_WEIGHTS),
+		                          *mtl.getStdAttribVar(Material::SAV_VERT_WEIGHT_BONES_NUM), 1,
+		                          GL_FLOAT, GL_FALSE, sizeof(MeshData::VertexWeight), BUFFER_OFFSET(0));
+	}
+
+	if(mtl.getStdAttribVar(Material::SAV_VERT_WEIGHT_BONE_IDS) != NULL)
+	{
+		vao->attachArrayBufferVbo(*mesh.getVbo(Mesh::VBO_VERT_WEIGHTS),
+		                          *mtl.getStdAttribVar(Material::SAV_VERT_WEIGHT_BONE_IDS), 4,
+		                          GL_FLOAT, GL_FALSE, sizeof(MeshData::VertexWeight), BUFFER_OFFSET(4));
+	}
+
+	if(mtl.getStdAttribVar(Material::SAV_VERT_WEIGHT_WEIGHTS) != NULL)
+	{
+		vao->attachArrayBufferVbo(*mesh.getVbo(Mesh::VBO_VERT_WEIGHTS),
+		                          *mtl.getStdAttribVar(Material::SAV_VERT_WEIGHT_WEIGHTS), 4,
+		                          GL_FLOAT, GL_FALSE, sizeof(MeshData::VertexWeight), BUFFER_OFFSET(20));
+	}
+
+	vao->attachElementArrayBufferVbo(*mesh.getVbo(Mesh::VBO_VERT_INDECES));
 }

+ 16 - 9
src/Resources/Model.h

@@ -3,6 +3,7 @@
 
 #include "Resource.h"
 #include "RsrcPtr.h"
+#include "Object.h"
 
 
 class Mesh;
@@ -31,7 +32,7 @@ class Scanner;
 ///
 /// skeleton <string>
 ///
-/// stdAnims {
+/// skelAnims {
 /// 	<string>
 /// 	...
 /// 	<string>
@@ -41,24 +42,26 @@ class Model: public Resource
 {
 	public:
 		///
-		class SubModel
+		class SubModel: public Object
 		{
 			friend class Model;
 
 			public:
+				SubModel(): Object(NULL) {}
+
 				/// @name Accessors
 				/// @{
 				const Mesh& getMesh() const {return *mesh;}
-				const Material& getMtl() const {return *mtl;}
-				const Material& getDpMtl() const {return *dpMtl;}
+				const Material& getMaterial() const {return *material;}
+				const Material& getDpMaterial() const {return *dpMaterial;}
 				const Vao& getVao() const {return *normVao;}
 				const Vao& getDpVao() const {return *dpVao;}
 				/// @}
 
 			private:
 				RsrcPtr<Mesh> mesh; ///< The geometry
-				RsrcPtr<Material> mtl; ///< Material for MS ans BS
-				RsrcPtr<Material> dpMtl; ///< Material for depth passes
+				RsrcPtr<Material> material; ///< Material for MS ans BS
+				RsrcPtr<Material> dpMaterial; ///< Material for depth passes
 				Vao* normVao; ///< Normal VAO for MS ans BS
 				Vao* dpVao; ///< Depth pass VAO for SM and EarlyZ
 		};
@@ -68,11 +71,15 @@ class Model: public Resource
 		void load(const char* filename);
 
 	private:
-		Vec<SubModel> subModels;
-		RsrcPtr<Skeleton> skel; ///< The skeleton. It can be empty
-		Vec<RsrcPtr<SkelAnim> > sAnims; ///< The standard skeleton animations
+		Vec<SubModel> subModels; ///< The vector of submodels
+		RsrcPtr<Skeleton> skeleton; ///< The skeleton. It can be empty
+		Vec<RsrcPtr<SkelAnim> > skelAnims; ///< The standard skeleton animations
 
+		/// Parses a submodel from after the "subModel" until the closing bracket
 		void parseSubModel(Scanner& scanner);
+
+		/// Creates VAOs for an individual submodel
+		void createVao(const Material& mtl, const Mesh& mesh, SubModel& subModel, Vao*& vao);
 };