327 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			327 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "ModelManager.h"
 | |
| 
 | |
| #include "MeshManager.h"
 | |
| #include "ShaderManager.h"
 | |
| 
 | |
| #include "Utilities/StringUtilities.h"
 | |
| #include "Utilities/Log.h"
 | |
| 
 | |
| #include "tinyxml.h"
 | |
| #include "physfs.h"
 | |
| 
 | |
| #include <iostream>
 | |
| 
 | |
| using namespace std;
 | |
| 
 | |
| namespace BlueCore
 | |
| {
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| void Model::render(RenderDevice *device) const
 | |
| {
 | |
| //	ModelMesh->render();
 | |
| 
 | |
| 	glEnable(GL_LIGHTING);
 | |
| 	glDepthFunc ( GL_LEQUAL );
 | |
| 	glEnable ( GL_DEPTH_TEST );
 | |
| 	glDepthMask ( GL_TRUE );
 | |
| 
 | |
| 	 glEnableClientState (GL_VERTEX_ARRAY );
 | |
| 	 glEnableClientState (GL_TEXTURE_COORD_ARRAY );
 | |
| 	 glEnableClientState (GL_NORMAL_ARRAY );
 | |
| 
 | |
| 	 glMaterialfv (GL_FRONT, GL_SHININESS, &LitPass.Shininess);
 | |
| 	 glMaterialfv (GL_FRONT, GL_SPECULAR, ( GLfloat * ) &LitPass.Specular );
 | |
| 
 | |
| 	 // setup shader
 | |
| 	 if (LitPass.Program)
 | |
| 	 {
 | |
| 		 device->setShaderProgram(LitPass.Program);
 | |
| 
 | |
| 		 int textureId = 0;
 | |
| 		 
 | |
| 		 std::vector<Model::TextureUnit>::const_iterator titer;
 | |
| 		 for (titer = LitPass.Textures.begin(); titer != LitPass.Textures.end(); titer++)
 | |
| 		 {
 | |
| 			 device->setTexture(textureId, ( *titer ).mTexture );
 | |
| 			 device->setTexture(LitPass.Program, textureId, ( *titer ).mName);
 | |
| 			 textureId++;
 | |
| 		 }
 | |
| 
 | |
| 		 if (LitPass.Tangents)
 | |
| 		 {
 | |
| 			 //device->setTangentBuffer(LitPass.Program, &ModelMesh->TangentBuffer, "tangent");
 | |
| 			 //device->setTangentBuffer(LitPass.Program, &ModelMesh->BitangentBuffer, "bitangent");
 | |
| 		 }
 | |
| 		 
 | |
| 
 | |
| 	 }
 | |
| /*
 | |
| 	 else
 | |
| 	 {
 | |
| 		 int textureId = 0;
 | |
| 
 | |
| 		 std::vector<Model::TextureUnit>::iterator titer;
 | |
| 		 for (titer = pass.Textures.begin(); titer != pass.Textures.end(); titer++)
 | |
| 		 {
 | |
| 			 Renderer::getSingleton()->bindTexture(( *titer ).mTexture, textureId );
 | |
| 	 ShaderManager::getSingleton()->useTexture(pass.Program, textureId, ( *titer ).mName);
 | |
| 	 textureId++;
 | |
| 	 break;
 | |
| 	 }
 | |
| 	 }
 | |
| 	 // render subsets
 | |
| 	 SubsetVector::iterator iter;
 | |
| 	 for (iter = mesh->surface_subsets.begin(); iter
 | |
| 	 != mesh->surface_subsets.end(); iter++)
 | |
| 	 {
 | |
| 	 Subset subset = *iter;
 | |
| 	 mesh->index_buffer.draw(subset.first, subset.count);
 | |
| 	 }
 | |
| */
 | |
| 
 | |
| 	 ModelMesh->render();
 | |
| 
 | |
| 	device->setShaderProgram(0);
 | |
| 
 | |
| 	 glActiveTextureARB (GL_TEXTURE2_ARB );
 | |
| 	 glDisable (GL_TEXTURE_2D );
 | |
| 	 glActiveTextureARB (GL_TEXTURE1_ARB );
 | |
| 	 glDisable (GL_TEXTURE_2D );
 | |
| 	 glActiveTextureARB (GL_TEXTURE0_ARB );
 | |
| 	 glDisable (GL_TEXTURE_2D );
 | |
| 	
 | |
| 	/*	 
 | |
| 	 // cleanup
 | |
| 	 if (pass.Program && ShaderManager::getSingleton()->usingShaders() )
 | |
| 	 {
 | |
| 	 ShaderManager::getSingleton()->useShaderProgram( 0);
 | |
| 	 if (pass.Tangents)
 | |
| 	 {
 | |
| 	 ShaderManager::getSingleton()->disableTangentBuffer(pass.Program, "tangent");
 | |
| 	 ShaderManager::getSingleton()->disableTangentBuffer(pass.Program, "bitangent");
 | |
| 	 }
 | |
| 	 }
 | |
| 
 | |
| 
 | |
| 	 glPopMatrix();
 | |
| 
 | |
| 	 glActiveTextureARB (GL_TEXTURE2_ARB );
 | |
| 	 glDisable (GL_TEXTURE_2D );
 | |
| 	 glActiveTextureARB (GL_TEXTURE1_ARB );
 | |
| 	 glDisable (GL_TEXTURE_2D );
 | |
| 	 glActiveTextureARB (GL_TEXTURE0_ARB );
 | |
| 	 glDisable (GL_TEXTURE_2D );
 | |
| 	 */
 | |
| 	/*
 | |
| 	 glDisableClientState (GL_VERTEX_ARRAY );
 | |
| 	 glDisableClientState (GL_TEXTURE_COORD_ARRAY );
 | |
| 	 glDisableClientState (GL_NORMAL_ARRAY );
 | |
| 	 */
 | |
| 
 | |
| }
 | |
| //------------------------------------------------------------------------------
 | |
| ModelManager::ModelManager(TextureManager *texturemanager,
 | |
| 		ShaderManager* shadermanager, MeshManager* meshmanager) :
 | |
| 	_TextureManager(texturemanager), _ShaderManager(shadermanager),
 | |
| 			_MeshManager(meshmanager)
 | |
| {
 | |
| 	clog << ">>> ModelManager constructed ..."<< endline;
 | |
| }
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| ModelManager::~ModelManager()
 | |
| {
 | |
| 	clog << ">>> ModelManager destructed ..."<< endline;
 | |
| }
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| void ModelManager::parseRenderPassDefinition(
 | |
| 		Model::RenderPassDefinition &Definition,
 | |
| 		const TiXmlElement* DefinitionElement)
 | |
| {
 | |
| 
 | |
| 	const TiXmlElement * TextureElement =
 | |
| 			DefinitionElement->FirstChildElement("Texture");
 | |
| 
 | |
| 	while (TextureElement)
 | |
| 	{
 | |
| 		Model::TextureUnit unit;
 | |
| 		unit.mName = TextureElement->Attribute("name");
 | |
| 
 | |
| 		const char *file = TextureElement->Attribute("file");
 | |
| 
 | |
| 		if (file)
 | |
| 			unit.mTexture = _TextureManager->loadTexture(file);
 | |
| 		else
 | |
| 			unit.mTexture = 0;
 | |
| 
 | |
| 		Definition.Textures.push_back(unit);
 | |
| 
 | |
| 		TextureElement = TextureElement->NextSiblingElement("Texture");
 | |
| 	}
 | |
| 
 | |
| 	const TiXmlElement * ShaderElement =
 | |
| 			DefinitionElement->FirstChildElement("Shader");
 | |
| 
 | |
| 	if (ShaderElement)
 | |
| 	{
 | |
| 		Definition.Program
 | |
| 				= _ShaderManager->loadShaderProgram(ShaderElement->Attribute("name") );
 | |
| 
 | |
| 		const char *t = ShaderElement->Attribute("tangents");
 | |
| 		if (t && string("true") == t)
 | |
| 			Definition.Tangents = true;
 | |
| 		else
 | |
| 			Definition.Tangents = false;
 | |
| 	}
 | |
| 	else
 | |
| 		Definition.Program = 0;
 | |
| 
 | |
| 	const TiXmlElement * MaterialElement =
 | |
| 			DefinitionElement->FirstChildElement("Material");
 | |
| 
 | |
| 	if (MaterialElement)
 | |
| 	{
 | |
| 		double s;
 | |
| 		MaterialElement->QueryDoubleAttribute("shininess", &s);
 | |
| 		Definition.Shininess = s;
 | |
| 
 | |
| 		std::vector<std::string> components;
 | |
| 		explode(MaterialElement->Attribute("specular"), components);
 | |
| 
 | |
| 		for (unsigned int i = 0; i < components.size(); i++)
 | |
| 		{
 | |
| 			Definition.Specular[i] = atof(components[i].c_str() );
 | |
| 
 | |
| 			if (i == 3)
 | |
| 				break;
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	Definition.Enabled = true;
 | |
| }
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| Model *ModelManager::loadModel(const string &name)
 | |
| {
 | |
| 	// check if this model is already loaded
 | |
| 	ModelContainer::const_iterator result;
 | |
| 	result = _Models.find(name);
 | |
| 
 | |
| 	if (result != _Models.end() )
 | |
| 	{
 | |
| 		return result->second.pointer();
 | |
| 	}
 | |
| 
 | |
| 	string filename = name + ".model.xml";
 | |
| 	// load the document
 | |
| 	PHYSFS_file *file = PHYSFS_openRead(filename.c_str());
 | |
| 
 | |
| 	if ( !file)
 | |
| 	{
 | |
| 		clog << "!!! XML-File '"<< name << "' not found"<< endline;
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	unsigned int fileSize = PHYSFS_fileLength(file);
 | |
| 
 | |
| 	Buffer<char> buffer(fileSize);
 | |
| 
 | |
| 	PHYSFS_read(file, buffer.data(), 1, buffer.size() );
 | |
| 	buffer[buffer.count() - 1] = 0;
 | |
| 
 | |
| 	PHYSFS_close(file);
 | |
| 
 | |
| 	TiXmlDocument *document = new TiXmlDocument();
 | |
| 	document->Parse(buffer.data() );
 | |
| 
 | |
| 	if (document->Error() )
 | |
| 	{
 | |
| 		clog << "!!! Error loading XML-File'"<< name << "': ";
 | |
| 		clog << document->ErrorRow() << ","<< document->ErrorCol();
 | |
| 		clog << " "<< document->ErrorDesc() << endline;
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	Model *model = new Model();
 | |
| 
 | |
| 	if (document == 0)
 | |
| 	{
 | |
| 		clog << "!!! Model '"<< name << "' not found!"<< endline;
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	const TiXmlElement *model_element = document->FirstChildElement("Model");
 | |
| 
 | |
| 	if (model_element)
 | |
| 	{
 | |
| 		const TiXmlElement* MeshElement =
 | |
| 				model_element->FirstChildElement("Mesh");
 | |
| 
 | |
| 		if (MeshElement)
 | |
| 		{
 | |
| 			model->ModelMesh
 | |
| 					= _MeshManager->loadMesh(MeshElement->Attribute("file") );
 | |
| 		}
 | |
| 
 | |
| 		const TiXmlElement * ShadowMeshElement =
 | |
| 				model_element->FirstChildElement("ShadowMesh");
 | |
| 
 | |
| 		if (ShadowMeshElement)
 | |
| 		{
 | |
| 			model->ShadowMesh
 | |
| 					= _MeshManager->loadMesh(ShadowMeshElement->Attribute("file") );
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			model->ShadowMesh = 0;
 | |
| 		}
 | |
| 
 | |
| 		const TiXmlElement* definition_element;
 | |
| 
 | |
| 		definition_element
 | |
| 				= model_element->FirstChildElement("AmbientRenderPass");
 | |
| 		if (definition_element)
 | |
| 			parseRenderPassDefinition(model->AmbientPass, definition_element);
 | |
| 		else
 | |
| 			model->AmbientPass.Enabled = false;
 | |
| 
 | |
| 		definition_element = model_element->FirstChildElement("LitRenderPass");
 | |
| 		if (definition_element)
 | |
| 			parseRenderPassDefinition(model->LitPass, definition_element);
 | |
| 		else
 | |
| 			model->LitPass.Enabled = false;
 | |
| 
 | |
| 		definition_element
 | |
| 				= model_element->FirstChildElement("DefaultRenderPass");
 | |
| 		if (definition_element)
 | |
| 			parseRenderPassDefinition(model->DefaultPass, definition_element);
 | |
| 		else
 | |
| 			model->DefaultPass.Enabled = false;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	_Models[name] = model;
 | |
| 
 | |
| 	return model;
 | |
| }
 | |
| #if 0
 | |
| //------------------------------------------------------------------------------
 | |
| void ModelManager::unload()
 | |
| {
 | |
| 	ModelContainer::iterator iter;
 | |
| 
 | |
| 	for (iter = _Models.begin(); iter != _Models.end(); iter++)
 | |
| 	{
 | |
| 		clog << ">>> ModelManager: unload " << iter->first << endlog;
 | |
| 
 | |
| 		delete iter->second;
 | |
| 	}
 | |
| 
 | |
| 	_Models.clear();
 | |
| }
 | |
| #endif
 | |
| } // namespace BlueCore
 | 
