www.pudn.com > RCApp-src.zip > MaterialManager.cpp
/* RedEye Project (http://members.ozemail.com.au/~ndmcevoy/) Copyright (C) 2003 Nick McEvoy This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ----------------------------------------------------------------- Commented for use with Doxygen (http://www.doxygen.org) ----------------------------------------------------------------- */ /*! \file MaterialManager.cpp * \brief Material manager. * * This file contains the material manager. */ // GLUT includes #include// RedEye includes #include "MaterialManager.h" #include "SoundManager.h" #include "Engine.h" //! The one and only instance reMaterialManager* reMaterialManager::mpInstance = NULL; #define DEFAULT_TEXTURE "textures/CandyStripe.rgb" #define NOCLAMP 0 #define UCLAMP 1 #define VCLAMP 2 #define UVCLAMP 3 // todo: to be replaced by reading material data from file struct Material { public: char* msFilename; int miClamp; bool mbTransparency; float mfAlphaRef; bool mbLighting; sgVec4 mfEmission; sgVec4 mfSpecular; float mfShininess; // ODE surface parameters dSurfaceParameters mSurface; }; // todo: to be replaced by reading material data from file Material materials[] = { { DEFAULT_TEXTURE, // DEFAULT ... DO NOT REMOVE !!! NOCLAMP, false, 0.0, true, 0, 0, 0, 1, 0, 0, 0, 1, 0, dContactBounce | dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM, dInfinity, 0, // mu, mu2 0.0, 0.0, // bounce, bounce_vel 0.8, 0.2, // soft_erp, soft_cfm 0.0, 0.0, // motion1, motion2 0.5, 0.5 // slip1, slip2 }, { "textures/Grass.bmp", NOCLAMP, false, 0.0, true, 0, 0, 0, 1, 0, 0, 0, 1, 0, dContactBounce | dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM, dInfinity, 0, // mu, mu2 0.0, 0.1, // bounce, bounce_vel 0.8, 0.2, // soft_erp, soft_cfm 0.0, 0.0, // motion1, motion2 0.5, 0.5 // slip1, slip2 }, { "textures/Ocean.rgb", NOCLAMP, true, 0.0, true, 0, 0, 0, 1, 1, 1, 1, 1, 5, dContactBounce | dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM, 0.1, 0, // mu, mu2 0.0, 0.0, // bounce, bounce_vel 0.4, 0.2, // soft_erp, soft_cfm 0.0, 0.0, // motion1, motion2 0.5, 0.5 // slip1, slip2 }, { "textures/Rock.bmp", NOCLAMP, false, 0.0, true, 0, 0, 0, 1, 0, 0, 0, 1, 0, dContactBounce | dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM, dInfinity, 0, // mu, mu2 0.0, 0.1, // bounce, bounce_vel 0.8, 0.2, // soft_erp, soft_cfm 0.0, 0.0, // motion1, motion2 0.8, 0.8 // slip1, slip2 }, { "textures/Sand.rgb", NOCLAMP, false, 0.0, true, 0, 0, 0, 1, 0, 0, 0, 1, 0, dContactBounce | dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM, dInfinity, 0, // mu, mu2 0.0, 0.1, // bounce, bounce_vel 0.8, 0.2, // soft_erp, soft_cfm 0.0, 0.0, // motion1, motion2 0.8, 0.8 // slip1, slip2 }, { "textures/TestTextureGrass.bmp", NOCLAMP, false, 0.0, true, 0, 0, 0, 1, 0, 0, 0, 1, 0, dContactBounce | dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM, 0.1, 0, // mu, mu2 0.0, 0.0, // bounce, bounce_vel 0.5, 0.2, // soft_erp, soft_cfm 0.0, 0.0, // motion1, motion2 0.5, 0.5 // slip1, slip2 }, { "textures/fuzzy.inta", UVCLAMP, true, 0.2, false, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, // ode flags 0, 0, // mu, mu2 0, 0, // bounce, bounce_vel 0, 0, // soft_erp, soft_cfm 0, 0, // motion1, motion2 0, 0 // slip1, slip2 }, }; static int miNumMaterials = sizeof(materials)/sizeof(Material); bool reCompareBaseFilename(const char* fname, const char* fname2) { int i; int iLen = strlen(fname); int iLen2 = strlen(fname2); const char* fnbase = NULL; const char* fnbase2 = NULL; for (i = iLen; i >= 0; i--) { if (fname[i] == '/') { fnbase = &fname[i+1]; break; } fnbase = &fname[i]; } for (i = iLen2; i >= 0; i--) { if (fname2[i] == '/') { fnbase2 = &fname2[i+1]; break; } fnbase2 = &fname2[i]; } if (strcmp(fnbase, fnbase2) == 0) return true; else return false; } ssgState* reGetAppState(char* fname) { return reGetMaterialManager()->GetAppState(fname); } reMaterial::reMaterial(int iIndex) { miIndex = iIndex; setExternalPropertyIndex(iIndex); if (materials[iIndex].msFilename[0] != '\0') { setTexture( materials[iIndex].msFilename, !(materials[iIndex].miClamp & UCLAMP), !(materials[iIndex].miClamp & VCLAMP)); enable(GL_TEXTURE_2D); } else disable(GL_TEXTURE_2D); if (materials[iIndex].mbLighting) enable(GL_LIGHTING); else disable(GL_LIGHTING); setShadeModel(GL_SMOOTH); enable(GL_COLOR_MATERIAL); enable(GL_CULL_FACE); setColourMaterial(GL_AMBIENT_AND_DIFFUSE); setMaterial(GL_EMISSION, 0, 0, 0, 1); setMaterial(GL_SPECULAR, 0, 0, 0, 1); setShininess(0); if (materials[iIndex].mbTransparency) { setTranslucent(); enable(GL_ALPHA_TEST); setAlphaClamp(materials[iIndex].mfAlphaRef); enable(GL_BLEND); } else { setOpaque(); disable(GL_BLEND); } } const char* reMaterial::GetFilename() { return materials[miIndex].msFilename; } void reMaterial::GetSurfaceParams(dSurfaceParameters& Surface) { Surface = materials[miIndex].mSurface; } reMaterialManager::reMaterialManager() : mMaterialList(false) { } reMaterialManager::~reMaterialManager() { DestroyDatabase(); mpInstance = NULL; } reMaterialManager* reMaterialManager::GetInstance() { if (mpInstance == NULL) { mpInstance = new reMaterialManager; } return mpInstance; } void reMaterialManager::CreateDatabase() { printf("reMaterialManager::CreateDatabase() - creating materials...\n"); // Set the state callback ssgSetAppStateCallback(reGetAppState); // todo: move materials to an xml file for (int i = 0; i < miNumMaterials; i++) { // Keep sound going reGetSoundManager()->Update(); // Create material reMaterial* pMaterial = new reMaterial(i); pMaterial->ref(); mMaterialList.AddTail(pMaterial); } // todo: read xml printf("reMaterialManager::CreateDatabase() - done\n"); } void reMaterialManager::DestroyDatabase() { printf("reMaterialManager::DestroyDatabase() - destroying materials...\n"); // Destroy materials LISTPOSITION pos = mMaterialList.GetHeadPosition(); while (pos) { reMaterial* pMaterial = mMaterialList.GetNext(pos); ssgDeRefDelete(pMaterial); } mMaterialList.RemoveAll(); printf("reMaterialManager::DestroyDatabase() - done\n"); } ssgSimpleState* reMaterialManager::GetSimpleState(char* fname) { ssgSimpleState* pState = (ssgSimpleState*)GetAppState(fname); if (!pState) { ulSetError(UL_WARNING, "reMaterialManager::GetSimpleState() Could not find texture %s.", fname); pState = (ssgSimpleState*)GetAppState(DEFAULT_TEXTURE); } return pState; } ssgState* reMaterialManager::GetAppState(char* fname) { LISTPOSITION pos = mMaterialList.GetHeadPosition(); while (pos) { reMaterial* pMaterial = mMaterialList.GetNext(pos); if (reCompareBaseFilename(pMaterial->GetFilename(), fname)) return pMaterial; // Found } return NULL; // Not found } bool reMaterialManager::GetSurfaceParams(int iIndex, dSurfaceParameters& Surface) { LISTPOSITION pos = mMaterialList.GetHeadPosition(); while (pos) { reMaterial* pMaterial = mMaterialList.GetNext(pos); if (pMaterial->GetIndex() == iIndex) { pMaterial->GetSurfaceParams(Surface); return true; // Found } } return false; // Not found }