2008-01-16 11:45:17 +00:00
|
|
|
#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
|
|
|
|
{
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2008-01-17 16:42:24 +00:00
|
|
|
void Model::render(RenderDevice *device) const
|
2008-01-16 11:45:17 +00:00
|
|
|
{
|
2008-01-24 22:16:53 +00:00
|
|
|
// ModelMesh->render();
|
|
|
|
|
2008-01-20 10:16:37 +00:00
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
glDepthFunc ( GL_LEQUAL );
|
|
|
|
glEnable ( GL_DEPTH_TEST );
|
|
|
|
glDepthMask ( GL_TRUE );
|
2008-01-24 22:16:53 +00:00
|
|
|
|
2008-01-16 11:45:17 +00:00
|
|
|
glEnableClientState (GL_VERTEX_ARRAY );
|
|
|
|
glEnableClientState (GL_TEXTURE_COORD_ARRAY );
|
|
|
|
glEnableClientState (GL_NORMAL_ARRAY );
|
|
|
|
|
2008-01-24 22:16:53 +00:00
|
|
|
glMaterialfv (GL_FRONT, GL_SHININESS, &LitPass.Shininess);
|
|
|
|
glMaterialfv (GL_FRONT, GL_SPECULAR, ( GLfloat * ) &LitPass.Specular );
|
2008-01-16 11:45:17 +00:00
|
|
|
|
|
|
|
// setup shader
|
2008-01-24 22:16:53 +00:00
|
|
|
if (LitPass.Program)
|
2008-01-16 11:45:17 +00:00
|
|
|
{
|
2008-01-24 22:16:53 +00:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2008-01-16 11:45:17 +00:00
|
|
|
|
|
|
|
}
|
2008-01-24 22:16:53 +00:00
|
|
|
/*
|
2008-01-16 11:45:17 +00:00
|
|
|
else
|
|
|
|
{
|
2008-01-24 22:16:53 +00:00
|
|
|
int textureId = 0;
|
2008-01-16 11:45:17 +00:00
|
|
|
|
2008-01-24 22:16:53 +00:00
|
|
|
std::vector<Model::TextureUnit>::iterator titer;
|
|
|
|
for (titer = pass.Textures.begin(); titer != pass.Textures.end(); titer++)
|
|
|
|
{
|
|
|
|
Renderer::getSingleton()->bindTexture(( *titer ).mTexture, textureId );
|
2008-01-16 11:45:17 +00:00
|
|
|
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);
|
|
|
|
}
|
2008-01-24 22:16:53 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
ModelMesh->render();
|
2008-01-16 11:45:17 +00:00
|
|
|
|
2008-01-24 22:16:53 +00:00
|
|
|
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 );
|
|
|
|
|
|
|
|
/*
|
2008-01-16 11:45:17 +00:00
|
|
|
// 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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-01-24 22:16:53 +00:00
|
|
|
|
2008-01-16 11:45:17 +00:00
|
|
|
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)
|
|
|
|
{
|
2008-01-24 22:16:53 +00:00
|
|
|
clog << ">>> ModelManager constructed ..."<< endline;
|
2008-01-16 11:45:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
ModelManager::~ModelManager()
|
|
|
|
{
|
2008-01-24 22:16:53 +00:00
|
|
|
clog << ">>> ModelManager destructed ..."<< endline;
|
2008-01-16 11:45:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
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() )
|
|
|
|
{
|
2008-01-17 16:42:24 +00:00
|
|
|
return result->second.pointer();
|
2008-01-16 11:45:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|