00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00100
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
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
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
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
00197
00198 int frame = model_->getStartFrame();
00199 if (mesh->getReferencesBones())
00200 {
00201
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
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
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
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 }