#include "ModelManager.h" #include "MeshManager.h" #include "ShaderManager.h" #include "Utilities/StringUtilities.h" #include "Utilities/Log.h" #include "tinyxml.h" #include "physfs.h" #include 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::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::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 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 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