bluecore/engine/ModelManager.cpp
2008-01-17 16:42:24 +00:00

323 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 );
glMatrixMode (GL_MODELVIEW );
glPushMatrix();
Matrix4x4 m(_AbsoluteRotation, _AbsoluteTranslation);
glMultMatrixd ( ( GLdouble * ) &m.m );
mesh->vertex_buffer.bind();
mesh->index_buffer.bind();
*/
/*
glMaterialfv (GL_FRONT, GL_SHININESS, &pass.Shininess);
glMaterialfv (GL_FRONT, GL_SPECULAR, ( GLfloat * ) &pass.Specular );
// setup shader
if (pass.Program && ShaderManager::getSingleton()->usingShaders() )
{
ShaderManager::getSingleton()->useShaderProgram(pass.Program);
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++;
}
if (pass.Tangents)
{
ShaderManager::getSingleton()->useTangentBuffer(pass.Program, &mesh->tangent_buffer, "tangent");
ShaderManager::getSingleton()->useTangentBuffer(pass.Program, &mesh->bitangent_buffer,
"bitangent");
}
}
else
{
glActiveTextureARB (GL_TEXTURE2_ARB );
glDisable (GL_TEXTURE_2D );
glActiveTextureARB (GL_TEXTURE1_ARB );
glDisable (GL_TEXTURE_2D );
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);
}
// 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)
{
}
//------------------------------------------------------------------------------
ModelManager::~ModelManager()
{
}
//------------------------------------------------------------------------------
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