#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 ); 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::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::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 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