ModelRendererMesh.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <graph/ModelRendererMesh.h>
00022 #include <graph/OptionsDisplay.h>
00023 #include <graph/TextureStore.h>
00024 #include <3dsparse/ModelMaths.h>
00025 #include <GLEXT/GLGlobalState.h>
00026 #include <GLEXT/GLStateExtension.h>
00027 #include <GLEXT/GLTexture.h>
00028 #include <GLEXT/GLInfo.h>
00029 
00030 ModelRendererMesh::ModelRendererMesh(Model *model) : 
00031         model_(model)
00032 {
00033         setup();
00034 }
00035 
00036 ModelRendererMesh::~ModelRendererMesh()
00037 {
00038         while (!boneTypes_.empty())
00039         {
00040                 BoneType *type = boneTypes_.back();
00041                 boneTypes_.pop_back();
00042                 delete type;
00043         }
00044         while (!meshInfos_.empty())
00045         {
00046                 MeshInfo info = meshInfos_.back();
00047                 meshInfos_.pop_back();
00048 
00049                 while (!info.frameInfos_.empty())
00050                 {
00051                         MeshFrameInfo frameInfo = info.frameInfos_.back();
00052                         info.frameInfos_.pop_back();
00053                         if (frameInfo.displayList != 0)
00054                         {
00055                                 glDeleteLists(frameInfo.displayList, 1);
00056                         }
00057                 }
00058         }
00059 }
00060 
00061 void ModelRendererMesh::setup()
00062 {
00063         std::vector<BoneType *> &baseTypes = model_->getBaseBoneTypes();
00064         std::vector<BoneType *>::iterator itor;
00065         for (itor = baseTypes.begin();
00066                 itor != baseTypes.end();
00067                 itor++)
00068         {
00069                 boneTypes_.push_back(new BoneType(*(*itor)));
00070         }
00071 
00072         MeshInfo info;
00073         MeshFrameInfo frameInfo;
00074         for (int f=0; f<=model_->getTotalFrames(); f++)
00075         {
00076                 info.frameInfos_.push_back(frameInfo);
00077         }
00078         
00079         for (unsigned int m=0; m<model_->getMeshes().size(); m++)
00080         {
00081                 meshInfos_.push_back(info);
00082         }
00083 }
00084 
00085 void ModelRendererMesh::drawBottomAligned(float currentFrame, 
00086         float distance, float fade, bool setState)
00087 {
00088         glPushMatrix();
00089                 glTranslatef(0.0f, 0.0f, -model_->getMin()[2]);
00090                 draw(currentFrame, distance, fade, setState);
00091         glPopMatrix();
00092 }
00093 
00094 void ModelRendererMesh::draw(float currentFrame, 
00095         float distance, float fade, bool setState)
00096 {
00097         GLGlobalState globalState(GLState::BLEND_ON | GLState::ALPHATEST_ON);
00098 
00099         // Set transparency on
00100         // Fade the model (make it transparent)
00101         bool useBlendColor = (GLStateExtension::hasBlendColor() && fade < 1.0f);
00102         if (useBlendColor)
00103         {
00104                 fade = MIN(1.0f, MAX(fade, 0.2f));
00105                 glBlendColorEXT(0.0f, 0.0f, 0.0f, fade);
00106                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA_EXT);
00107         }
00108 
00109         // Draw the model
00110         for (unsigned int m=0; m<model_->getMeshes().size(); m++)
00111         {
00112                 Mesh *mesh = model_->getMeshes()[m];
00113                 drawMesh(m, mesh, currentFrame, setState);
00114         }
00115 
00116         // Turn off fading
00117         if (useBlendColor)
00118         {
00119                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00120         }
00121 }
00122 
00123 void ModelRendererMesh::drawMesh(unsigned int m, Mesh *mesh, float currentFrame, bool setState)
00124 {
00125         MeshInfo &meshInfo = meshInfos_[m];
00126 
00127         bool vertexLighting = OptionsDisplay::instance()->getNoModelLighting();
00128         bool useTextures =
00129                 (!OptionsDisplay::instance()->getNoSkins() &&
00130                 mesh->getTextureName()[0]);
00131         unsigned state = 0;
00132         
00133         //if (setState)
00134         {
00135                 if (useTextures)
00136                 {
00137                         state |= GLState::TEXTURE_ON;
00138                         if (!meshInfo.texture)
00139                         {
00140                                 meshInfo.texture = 
00141                                         TextureStore::instance()->loadTexture(
00142                                                 mesh->getTextureName(), mesh->getATextureName());
00143                         }
00144                         if (meshInfo.texture) meshInfo.texture->draw();
00145                         
00146                         if (mesh->getSphereMap())
00147                         {
00148                                 state |= GLState::NORMALIZE_ON;
00149 
00150                                 glEnable(GL_TEXTURE_GEN_S);                                             
00151                                 glEnable(GL_TEXTURE_GEN_T);     
00152                                 glEnable(GL_TEXTURE_GEN_R);
00153                                 glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
00154                                 glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
00155                                 glTexGenf(GL_R, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
00156                         }
00157                 }
00158                 else
00159                 {
00160                         state |= GLState::TEXTURE_OFF;
00161                 }
00162 
00163                 if (!vertexLighting)
00164                 {
00165                         state |= 
00166                                 GLState::NORMALIZE_ON | 
00167                                 GLState::LIGHTING_ON | 
00168                                 GLState::LIGHT1_ON;
00169 
00170                         if (useTextures)
00171                         {
00172                                 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mesh->getAmbientColor());
00173                                 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mesh->getDiffuseColor());
00174                                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mesh->getSpecularColor());
00175                                 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mesh->getEmissiveColor());
00176                                 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mesh->getShininessColor());
00177                         }
00178                         else
00179                         {
00180                                 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mesh->getAmbientNoTexColor());
00181                                 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mesh->getDiffuseNoTexColor());
00182                                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mesh->getSpecularNoTexColor());
00183                                 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mesh->getEmissiveNoTexColor());
00184                                 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mesh->getShininessColor());
00185                         }
00186                 }
00187                 else
00188                 {
00189                         state |= 
00190                                 GLState::NORMALIZE_OFF | 
00191                                 GLState::LIGHTING_OFF | 
00192                                 GLState::LIGHT1_OFF;
00193                 }
00194         }
00195 
00196         // Get the current frame for the animation
00197         // If we have no bones, when we only have one frame
00198         int frame = model_->getStartFrame();
00199         if (mesh->getReferencesBones())
00200         {
00201                 // If we have bones, make sure the frame falls within the accepted bounds
00202                 if (model_->getTotalFrames() > 1)
00203                 {
00204                         frame = ((unsigned int)(currentFrame)) % model_->getTotalFrames();
00205                         if (frame < 0) frame = 0;
00206                 }
00207         }
00208 
00209         GLGlobalState globalState(state);
00210 
00211         {
00212                 int frameNo = frame;
00213                 DIALOG_ASSERT(frameNo >= 0 && frameNo < (int) meshInfo.frameInfos_.size());
00214                 
00215                 unsigned int lastState = meshInfo.frameInfos_[frameNo].lastCachedState;
00216                 unsigned int displayList = meshInfo.frameInfos_[frameNo].displayList;
00217                 if (lastState != state)
00218                 {
00219                         if (displayList != 0)
00220                         {
00221                                 glDeleteLists(displayList, 1);
00222                                 displayList = 0;
00223                         }
00224                         meshInfo.frameInfos_[frameNo].lastCachedState = state;
00225                 }
00226 
00227                 if (!displayList)
00228                 {
00229                         glNewList(displayList = glGenLists(1), GL_COMPILE);
00230                                 drawVerts(m, mesh, vertexLighting, frame);
00231                         glEndList();
00232 
00233                         meshInfo.frameInfos_[frameNo].displayList = displayList;
00234                 }
00235 
00236                 glCallList(displayList);
00237                 GLInfo::addNoTriangles((int) mesh->getFaces().size());
00238         }
00239 
00240         if (useTextures)
00241         {
00242                 if (mesh->getSphereMap())
00243                 {
00244                         glDisable(GL_TEXTURE_GEN_S);                                            
00245                         glDisable(GL_TEXTURE_GEN_T);    
00246                         glDisable(GL_TEXTURE_GEN_R);
00247                 }
00248         }
00249 }
00250 
00251 void ModelRendererMesh::drawVerts(unsigned int m, Mesh *mesh, bool vertexLighting, int frame)
00252 {
00253         // Move the bones into position
00254         for (unsigned int b=0; b<boneTypes_.size(); b++)
00255         {
00256                 Bone *bone = model_->getBones()[b];
00257                 BoneType *type = boneTypes_[b];
00258 
00259                 unsigned int posKeys = bone->getPositionKeys().size();
00260                 unsigned int rotKeys = bone->getRotationKeys().size();
00261                 if (posKeys == 0 && rotKeys == 0)
00262                 {
00263                         memcpy(type->final_, type->absolute_, sizeof(BoneMatrixType));
00264                         continue;
00265                 }
00266 
00267                 BoneMatrixType m;
00268                 bone->getRotationAtTime(float(frame), m);
00269                                 
00270                 Vector &pos = bone->getPositionAtTime(float(frame));
00271                 m[0][3] = pos[0];
00272                 m[1][3] = pos[1];
00273                 m[2][3] = pos[2];
00274 
00275                 ModelMaths::concatTransforms(type->relative_, m, type->relativeFinal_);
00276                 if (type->parent_ == -1)
00277                 {
00278                         memcpy(type->final_, type->relativeFinal_, sizeof(BoneMatrixType));
00279                 }
00280                 else
00281                 {
00282                         BoneType *parent = boneTypes_[type->parent_];
00283                         ModelMaths::concatTransforms(parent->final_, type->relativeFinal_, type->final_);
00284                 }
00285         }
00286 
00287         // Draw the vertices
00288         Vector vec;
00289         glBegin(GL_TRIANGLES);
00290 
00291         int faceVerts[3];
00292         
00293         std::vector<Face *>::iterator itor;
00294         for (itor = mesh->getFaces().begin();
00295                 itor != mesh->getFaces().end();
00296                 itor++)
00297         {
00298                 Face *face = *itor;
00299 
00300                 for (int i=0; i<3; i++)
00301                 {
00302                         int index = face->v[i];
00303                         faceVerts[i] = index;
00304                 }
00305                 
00306                 if (faceVerts[0] != faceVerts[1] &&
00307                         faceVerts[1] != faceVerts[2] &&
00308                         faceVerts[0] != faceVerts[2])
00309                 {
00310                         GLInfo::addNoTriangles(1);
00311                         for (int i=0; i<3; i++)
00312                         {
00313                                 Vertex *vertex = mesh->getVertex(faceVerts[i]);
00314 
00315                                 if (vertexLighting)
00316                                 {
00317                                         if (GLState::getState() & GLState::TEXTURE_OFF) 
00318                                         {
00319                                                 glColor3f(
00320                                                         mesh->getDiffuseNoTexColor()[0] * vertex->lightintense[0],
00321                                                         mesh->getDiffuseNoTexColor()[1] * vertex->lightintense[1],
00322                                                         mesh->getDiffuseNoTexColor()[2] * vertex->lightintense[2]);
00323                                         }
00324                                         else
00325                                         {
00326                                                 glColor3fv(vertex->lightintense);
00327                                         }
00328                                 }
00329 
00330                                 glTexCoord2f(face->tcoord[i][0], face->tcoord[i][1]);
00331                                 glNormal3fv(face->normal[i]);
00332 
00333                                 if (vertex->boneIndex != -1)
00334                                 {
00335                                         BoneType *type = boneTypes_[vertex->boneIndex];
00336 
00337                                         // Note: Translation of MS to S3D coords
00338                                         Vector newPos, newVec;
00339                                         newPos[0] = vertex->position[0];
00340                                         newPos[1] = vertex->position[2];
00341                                         newPos[2] = vertex->position[1];
00342 
00343                                         ModelMaths::vectorRotate(newPos, type->final_, newVec);
00344                                         vec[0] = newVec[0];
00345                                         vec[1] = newVec[2];
00346                                         vec[2] = newVec[1];
00347 
00348                                         vec[0] += type->final_[0][3] + vertexTranslation_[0];
00349                                         vec[1] += type->final_[2][3] + vertexTranslation_[1];
00350                                         vec[2] += type->final_[1][3] + vertexTranslation_[2];
00351                                         
00352                                 }
00353                                 else
00354                                 {
00355                                         vec[0] = vertex->position[0] + vertexTranslation_[0];
00356                                         vec[1] = vertex->position[1] + vertexTranslation_[1];
00357                                         vec[2] = vertex->position[2] + vertexTranslation_[2];
00358                                 }
00359 
00360                                 glVertex3fv(vec);
00361                         }
00362                 }
00363         }
00364         glEnd();
00365 }

Generated on Mon Feb 16 15:14:46 2009 for Scorched3D by  doxygen 1.5.3