⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pofobject.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
字号:
/* Copyright (C) Dan Ginsburg ang Dave Gosselin, 2001. 
 * All rights reserved worldwide.
 *
 * This software is provided "as is" without express or implied
 * warranties. You may freely copy and compile this source into
 * applications you distribute provided that the copyright text
 * below is included in the resulting source code, for example:
 * "Portions Copyright (C) Dan Ginsburg ang Dave Gosselin, 2001"
 */
//
//  pofObject.cpp
//    Evan Hart - ATI Research Inc.
//
//   This is the base class for gl-based pof objects.
//
/////////////////////////////////////////////////////////////////////

#include <string.h>
#include <gl/glut.h>

#include "pofObject.h"

#include "pof.h"

#include "glati.h"
#include "wglati.h"
#include "Extension.h"



vertexList::vertexList(){
  m_name=0;
  m_count=0;
  m_verts=NULL;
  m_vComponents=0;
  m_norms=0;
  m_texCoords=NULL;
  m_tComponents=NULL;
  m_tInstances=NULL;
  m_tSets=0;
  m_colors=NULL;
  m_cComponents=NULL;
  m_cInstances=NULL;
  m_cSets=0;
}

vertexList::~vertexList(){
  int ii;

  if (m_verts)
    delete []m_verts;

  for (ii=0;ii<m_tSets;ii++){
    if (m_texCoords[ii])
      delete []m_texCoords[ii];
  }

  if (m_texCoords)
    delete []m_texCoords;

  if (m_tComponents)
    delete []m_tComponents;

  if (m_tInstances)
    delete []m_tInstances;

  for (ii=0;ii<m_cSets;ii++){
    if (m_colors[ii])
      delete []m_colors[ii];
  }

  if (m_colors)
    delete []m_colors;

  if (m_cComponents)
    delete []m_cComponents;

  if (m_cInstances)
    delete []m_cInstances;

}

void vertexList::loadVertices(POF* pof, unsigned int name){
  POFVertexChunk vChunk;
  POFNormalChunk nChunk;
  POFTexCoordChunk tChunk;
  POFColorChunk cChunk;
  unsigned int format, type;
  const void *data;
  float *tempDat;
  int ii,gg;

  m_name=name;
  
  //
  //load the vertex data
  //
  if (!(data=pofGetVertexList(pof,name,0,&vChunk)))
    return;

  format=vChunk.format & 0xffff;
  type=(vChunk.format & 0xffff0000) >> 16;

  if (type!=POF_FLOAT)
    return; //only handle floats

  switch (format){
    case POF_VERTEX_2:
      m_vComponents=2;
      break;
    case POF_VERTEX_3:
      m_vComponents=3;
      break;
    case POF_VERTEX_4:
      m_vComponents=4;
      break;
    default:
      return; //bad vertex data
  };

  m_count=vChunk.count;
  tempDat=(float *)data;
  m_verts=new float[m_count*m_vComponents];

  memcpy(m_verts,tempDat,sizeof(float)*m_count*m_vComponents);

  //
  //load the normal list
  //
  if (data=pofGetNormalList(pof,name,0,&nChunk)){

    format=nChunk.format & 0xffff;
    type=(nChunk.format & 0xffff0000) >> 16;

    if (type!=POF_FLOAT)
      goto END_NORMALS; //can't handle non-float normals

    if (format!=POF_NORMAL_3)
      goto END_NORMALS; //can only handle 3 component normals

    if (nChunk.count!=m_count)
      goto END_NORMALS; // # normals != # num vertices
    
    tempDat=(float *)data;
    m_norms=new float[m_count*3];
    memcpy(m_norms,tempDat,sizeof(float)*m_count*3);
END_NORMALS:;
  }

  //
  //load the texture coord list(s)
  //
  if (m_tSets=pofGetNumInstances(pof,POF_TYPE_TEX_COORD,name)){
    m_texCoords=new float* [m_tSets];
    m_tComponents=new int[m_tSets];
    m_tInstances=new unsigned int[m_tSets];

    for (ii=0; ii<m_tSets; ii++){
      m_texCoords[ii]=NULL;
      m_tComponents[ii]=0;
      m_tInstances[ii]=pofGetInstances(pof,POF_TYPE_TEX_COORD,name)[ii];

      data=pofGetTexCoordList(pof,name,m_tInstances[ii],&tChunk);
      
      if (!data)
        break;

      if (m_count!=tChunk.count)
        break;
      
      format=tChunk.format & 0xffff;
      type=(tChunk.format & 0xffff0000) >> 16;

      if (type!=POF_FLOAT)
        break; //can only handle float tex coords

      tempDat=(float *)data;

      switch (format){
        case POF_TEXCOORD_S:
          m_tComponents[ii]=1;
          m_texCoords[ii]=new float[m_count];
          memcpy(m_texCoords[ii],tempDat,sizeof(float)*m_count);
          break;
        case POF_TEXCOORD_ST:
          m_tComponents[ii]=2;
          m_texCoords[ii]=new float[m_count*2];
          memcpy(m_texCoords[ii],tempDat,sizeof(float)*m_count*2);
          break;
        case POF_TEXCOORD_STR:
          m_tComponents[ii]=3;
          m_texCoords[ii]=new float[m_count*3];
          memcpy(m_texCoords[ii],tempDat,sizeof(float)*m_count*3);
          break;
        case POF_TEXCOORD_STRQ:
          m_tComponents[ii]=4;
          m_texCoords[ii]=new float[m_count*4];
          memcpy(m_texCoords[ii],tempDat,sizeof(float)*m_count*4);
          break;
        case POF_TEXCOORD_STQ:
          m_tComponents[ii]=4;
          m_texCoords[ii]=new float[m_count*4];
          for (gg=0; gg<m_count; gg++){
            m_texCoords[ii][gg*4+0]=tempDat[gg*3+0];
            m_texCoords[ii][gg*4+1]=tempDat[gg*3+1];
            m_texCoords[ii][gg*4+2]=0.0f;
            m_texCoords[ii][gg*4+3]=tempDat[gg*3+2];
          }
          break;
      }

    }
  }

  //
  //load the color list(s)
  //
  if (m_cSets=pofGetNumInstances(pof,POF_TYPE_COLOR,name)){
    m_colors=new float* [m_cSets];
    m_cComponents=new int[m_cSets];
    m_cInstances=new unsigned int[m_cSets];

    for (ii=0; ii<m_cSets; ii++){
      m_colors[ii]=NULL;
      m_cComponents[ii]=0;
      m_cInstances[ii]=pofGetInstances(pof,POF_TYPE_COLOR,name)[ii];

      data=pofGetColorList(pof,name,m_cInstances[ii],&cChunk);
      
      if (!data)
        break;

      if (m_count!=cChunk.count)
        break;
      
      format=cChunk.format & 0xffff;
      type=(cChunk.format & 0xffff0000) >> 16;

      if (type!=POF_FLOAT)
        break; //can only handle float colors

      tempDat=(float *)data;

      switch (format){
        case POF_COLOR_RGB:
          m_cComponents[ii]=3;
          m_colors[ii]=new float[m_count*3];
          memcpy(m_colors[ii],tempDat,sizeof(float)*m_count*3);
          break;
        case POF_COLOR_RGBA:
          m_cComponents[ii]=4;
          m_colors[ii]=new float[m_count*4];
          memcpy(m_colors[ii],tempDat,sizeof(float)*m_count*4);
          break;
      }

    }
  }
  
}

int vertexList::getNumVertices(){
  return m_count;
}

float *vertexList::getTexCoords(unsigned int which){
  int ii;

  for (ii=0;ii<m_tSets;ii++){
    if (m_tInstances[ii]==which)
      break;
  }

  if (ii==m_tSets)
    return NULL;

  return m_texCoords[ii];
}

int vertexList::getNumTexCoordComponents(unsigned int which){
  int ii;

  for (ii=0;ii<m_tSets;ii++){
    if (m_tInstances[ii]==which)
      break;
  }

  if (ii==m_tSets)
    return 0;

  return m_tComponents[ii];
}

float *vertexList::getNormals(){
  return m_norms;
}

float *vertexList::getVertices(){
  return m_verts;
}

float *vertexList::getColors(unsigned int which){
  int ii;

  for (ii=0;ii<m_cSets;ii++){
    if (m_cInstances[ii]==which)
      break;
  }

  if (ii==m_cSets)
    return NULL;

  return m_colors[ii];
}

int vertexList::getNumColorComponents(unsigned int which){
  int ii;

  for (ii=0;ii<m_cSets;ii++){
    if (m_cInstances[ii]==which)
      break;
  }

  if (ii==m_cSets)
    return 0;

  return m_cComponents[ii];
}


faceSet::faceSet(){
  m_name=0;
  m_indices=NULL;
  m_count=0;
  m_vtx=NULL;
  m_coordSet=0;
}

faceSet::~faceSet(){
  if (m_indices)
    delete []m_indices;
}

void faceSet::loadFaceSet(POF* pof, unsigned int name){
  POFFaceChunk fChunk;
  const void *data;
  unsigned int *tempDat;

  if (data=pofGetFaceList(pof,name,&fChunk)){
    m_count=fChunk.count;
    m_coordSet=fChunk.coordSet;

    m_indices=new unsigned int[m_count*3];
    tempDat=(unsigned int *)data;

    memcpy(m_indices,tempDat,sizeof(unsigned int)*m_count*3);
  }
}

unsigned int* faceSet::getIndices(){
  return m_indices;
}

int faceSet::getNumFaces(){
  return m_count;
}

unsigned int faceSet::getCoordSet(){
  return m_coordSet;
}

vertexList *faceSet::getVertexList(){
  return m_vtx;
}

void faceSet::setVertexList(vertexList *v){
  m_vtx=v;
}



pofObject::pofObject(){
  m_faces=NULL;
  m_verts=NULL;
  m_numObjects=0;
  m_numLists=0;
  m_hasBBox=false;
  m_hasNumPolys=false;
}

pofObject::~pofObject(){
  
  while (m_numObjects)
    delete m_faces[--m_numObjects];

  while (m_numLists)
    delete m_verts[--m_numLists];

  delete []m_faces;
  delete []m_verts;
}

void pofObject::loadObject(char *fn){
  POF *pof;
  int ii,gg;
  faceSet **tempf;
  vertexList **tempv;

  pof=pofOpen(fn,POF_MODE_READ);

  for (ii=0;ii<pofGetNumObjects(pof,POF_TYPE_FACE);ii++){
    if (!(m_numObjects%5)){
      tempf=new faceSet*[m_numObjects+5];
      memcpy(tempf,m_faces,sizeof(faceSet*)*m_numObjects);
      delete []m_faces;
      m_faces=tempf;
    }
    m_faces[m_numObjects]=new faceSet();
    m_faces[m_numObjects]->loadFaceSet(pof,pofGetObjectNames(pof,POF_TYPE_FACE)[ii]);

    for (gg=0;gg<m_numLists;gg++){
      if (m_faces[m_numObjects]->m_coordSet==m_verts[gg]->m_name)
        break;
    }

    if (gg==m_numLists){
      if (!(m_numLists%5)){
        tempv=new vertexList* [m_numLists+5];
        memcpy(tempv,m_verts,sizeof(vertexList*)*m_numLists);
        delete []m_verts;
        m_verts=tempv;
      }
      m_verts[m_numLists]=new vertexList();
      m_verts[m_numLists]->loadVertices(pof,m_faces[m_numObjects]->m_coordSet);
      m_faces[m_numObjects]->m_vtx=m_verts[m_numLists];
      m_numLists++;
    }
    else
      m_faces[m_numObjects]->m_vtx=m_verts[gg];

    m_numObjects++;
  }
  pofClose(pof);
}

void pofObject::getBBox(float *bbox){
  vertexList *v;
  int ii,gg,hh;

  if (!m_hasBBox){
    m_bBox[0]=100000.0f;
    m_bBox[1]=100000.0f;
    m_bBox[2]=100000.0f;
    m_bBox[3]=-100000.0f;
    m_bBox[4]=-100000.0f;
    m_bBox[5]=-100000.0f;
    for (ii=0;ii<m_numLists;ii++){
      v=m_verts[ii];
      for (gg=0;gg<v->m_count;gg++){
        for (hh=0;hh<v->m_vComponents;hh++){
          if (m_bBox[hh]>v->m_verts[gg*v->m_vComponents+hh])
            m_bBox[hh]=v->m_verts[gg*v->m_vComponents+hh];
          if (m_bBox[hh+3]<v->m_verts[gg*v->m_vComponents+hh])
            m_bBox[hh+3]=v->m_verts[gg*v->m_vComponents+hh];
        }
      }
    }
  }
  m_hasBBox=true;
  memcpy(bbox,m_bBox,sizeof(float)*6);
}

int pofObject::numPolygons(){
  int ii;

  if (!m_hasNumPolys){
    m_numPolys=0;
    for (ii=0;ii<m_numObjects;ii++){
      m_numPolys+=m_faces[ii]->getNumFaces();
    }
    m_hasNumPolys=true;
  }

  return m_numPolys;
}

void pofObject::renderObject(){
  int ii;
  vertexList *v;
  float *tex;

  glEnableClientState(GL_VERTEX_ARRAY);

  for (ii=0;ii<m_numObjects;ii++){
    v=m_faces[ii]->getVertexList();
    glVertexPointer(v->m_vComponents,GL_FLOAT,0,v->m_verts);
    if (v->m_norms){
      glEnableClientState(GL_NORMAL_ARRAY);
      glNormalPointer(GL_FLOAT,0,v->m_norms);
    }
    if (v->m_cSets){
      glEnableClientState(GL_COLOR_ARRAY);
      glColorPointer(v->m_cComponents[0],GL_FLOAT,0,v->m_colors[0]);
    }
    if (tex=v->getTexCoords(POF_TCI_BASE)){
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
      glTexCoordPointer(v->getNumTexCoordComponents(POF_TCI_BASE),GL_FLOAT,
                        0,tex);
    }
    //    glLockArraysEXT(0,v->m_count);
    glDrawElements(GL_TRIANGLES,m_faces[ii]->m_count*3,GL_UNSIGNED_INT,m_faces[ii]->m_indices);
    //    glUnlockArraysEXT();
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  }

  glDisableClientState(GL_VERTEX_ARRAY);
}

void pofObject::renderVectors(){
  float *vtx;
  float *nrm;
  float *tan;
  float *binorm;
  vertexList *v;
  int ii,gg;

  for (ii=0;ii<m_numObjects;ii++){
    v=m_faces[ii]->m_vtx;
    vtx=v->getVertices();
    nrm=v->getNormals();
    tan=v->getTexCoords(POF_TCI_TAN0);
    binorm=v->getTexCoords(POF_TCI_BINORM0);
    if (nrm){
      glColor3f(1.0f,0.0f,0.0f);
      glBegin(GL_LINES);
      for (gg=0;gg<v->getNumVertices();gg++){
        glVertex3fv(&vtx[gg*3]);
        glVertex3f(vtx[gg*3+0]+nrm[gg*3+0], vtx[gg*3+1]+nrm[gg*3+1],
                   vtx[gg*3+2]+nrm[gg*3+2]);
      }
      glEnd();
    }
    if (tan){
      glColor3f(0.0f,0.0f,1.0f);
      glBegin(GL_LINES);
      for (gg=0;gg<v->getNumVertices();gg++){
        glVertex3fv(&vtx[gg*3]);
        glVertex3f(vtx[gg*3+0]+tan[gg*3+0], vtx[gg*3+1]+tan[gg*3+1],
                   vtx[gg*3+2]+tan[gg*3+2]);
      }
      glEnd();
    }
    if (binorm){
      glColor3f(0.0f,1.0f,0.0f);
      glBegin(GL_LINES);
      for (gg=0;gg<v->getNumVertices();gg++){
        glVertex3fv(&vtx[gg*3]);
        glVertex3f(vtx[gg*3+0]+binorm[gg*3+0], vtx[gg*3+1]+binorm[gg*3+1],
                   vtx[gg*3+2]+binorm[gg*3+2]);
      }
      glEnd();
    }
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -