// Draw all the sprites in this buff void ParticleBuff::renderAll() { // ready the very buffer buildVerts(); // Draw the parts glBindTexture( GL_TEXTURE_2D, m_texId ); glBindBuffer(GL_ARRAY_BUFFER, this->vbo() ); updateBuffer(); glEnableClientState( GL_VERTEX_ARRAY ); glVertexPointer( 2, GL_FLOAT, sizeof(PartiVert), 0 ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glTexCoordPointer( 2, GL_FLOAT, sizeof(PartiVert), (void*)(2*sizeof(GLfloat)) ); glEnableClientState( GL_COLOR_ARRAY ); glColorPointer( 4, GL_FLOAT, sizeof(PartiVert), (void*)(4*sizeof(GLfloat)) ); glDrawArrays( GL_TRIANGLES, 0, this->size() ); glDisableClientState( GL_TEXTURE_COORD_ARRAY ); glDisableClientState( GL_COLOR_ARRAY ); glDisableClientState( GL_VERTEX_ARRAY ); }
void MD5Model::animate(float dt) { // sanity check #1 if (currAnim < 0 || currAnim >= int(anims.size()) || !anims[currAnim]) throw Exception("MD5Model::animate(): currAnim is invalid"); Anim *anim = anims[currAnim]; // sanity check #2 if (currFrame < 0 || currFrame >= int(anim->numFrames)) throw Exception("MD5Model::animate(): currFrame is invalid"); // compute index of next frame int nextFrameIndex = currFrame >= anim->numFrames - 1 ? 0 : currFrame + 1; // update animation time animTime += dt*float(anim->frameRate); if (animTime > 1.0f) { while (animTime > 1.0f) animTime -= 1.0f; //setFrame(nextFrameIndex); currFrame = nextFrameIndex; nextFrameIndex = currFrame >= anim->numFrames - 1 ? 0 : currFrame + 1; } // make sure size of storage for interpolated frame is correct if (int(interpFrame.joints.size()) != numJoints) interpFrame.joints.resize(numJoints); ///// now interpolate between the two frames ///// Frame &frame = anim->frames[currFrame], &nextFrame = anim->frames[nextFrameIndex]; // interpolate between the joints of the current frame and those of the next // frame and store them in interpFrame for (int i = 0; i < numJoints; i++) { Joint &interpJoint = interpFrame.joints[i]; // linearly interpolate between joint positions float *pos1 = frame.joints[i].pos, *pos2 = nextFrame.joints[i].pos; interpJoint.pos[0] = pos1[0] + animTime*(pos2[0] - pos1[0]); interpJoint.pos[1] = pos1[1] + animTime*(pos2[1] - pos1[1]); interpJoint.pos[2] = pos1[2] + animTime*(pos2[2] - pos1[2]); interpJoint.quat = slerp(frame.joints[i].quat, nextFrame.joints[i].quat, animTime); } buildVerts(interpFrame); buildNormals(); calculateRenderData(); }
void MD5Model::loadMesh(const char *filename) { // sanity check if (!filename) throw Exception("MD5Model::loadMesh(): filename is NULL"); // attempt to open file for reading std::ifstream fin(filename, std::ifstream::in); // was open successful? if (!fin.is_open()) { std::string msg = std::string("MD5Model::loadMesh(): unable to open ") + std::string(filename) + std::string(" for reading"); throw Exception(msg); } // read in file version std::string str; getNextToken(fin, &str); // token must read "MD5Version" if (str != "MD5Version") throw Exception("MD5Model::loadMesh(): expected 'MD5Version'"); // get version # int ver = readInt(fin); // must be version 10 if (ver != 10) throw Exception("MD5Model::loadMesh(): MD5Version must be 10"); // clear any data before reading file clear(); // read in all of the MD5Model elements readElements(fin); // close input file (should be done destructor anyway...) fin.close(); // calculate vertex positions and normals from information in joints // 模型pose姿势中,多个骨骼节点初始位置+连续weight位置变换(骨骼节点开始的位置 + weightPos经过joint四元数旋转的位置)* 权重 的结果作为顶点的位置。 buildVerts(); // 直接叉乘,规范化,将单位面法向量作为每个顶点的法向量 buildNormals(); createRenderData(); }
void MD5Model::setFrame(int frameIndex) { // sanity check #1 if (anims.size() == 0 || currAnim < 0) throw Exception("MD5Model::setFrame(): no animation has beens set"); // sanity check #2 if (frameIndex < 0 || !anims[currAnim] || anims[currAnim]->numFrames <= 0 || anims[currAnim]->numFrames <= frameIndex) throw Exception("MD5Model::setFrame(): frame index is invalid"); buildVerts(anims[currAnim]->frames[frameIndex]); buildNormals(); calculateRenderData(); currFrame = frameIndex; animTime = 0.0f; }