Logo Search packages:      
Sourcecode: vegastrike version File versions  Download package

mesh_gfx.cpp

#include <algorithm>
#include "mesh.h"
#include "aux_texture.h"
#include "aux_logo.h"
#include "lin_time.h"
#include "configxml.h"
#include "vs_globals.h"
#include "cmd/nebula_generic.h"
#include "gfx/camera.h"
#include "gfx/animation.h"
#include "mesh_xml.h"
#if defined(CG_SUPPORT)
#include "gldrv/gl_light.h"
#include "cg_global.h"
#endif

extern vector<Logo*> undrawn_logos;
class OrigMeshContainer {
public:
  float d;
  Mesh * orig;
  OrigMeshContainer(){ orig=NULL; };
  OrigMeshContainer (Mesh * tmp, float d) {
    orig = tmp;
    this->d = d;
  }
  bool operator < (const OrigMeshContainer & b) const {
    if(orig->Decal[0]==NULL || b.orig->Decal[0]==NULL){
      cout << "DEcal is nulll" << endl;
      return b.orig->Decal[0]!=NULL;
    }
    return ((*orig->Decal[0]) < (*b.orig->Decal[0]));
  }
  bool operator == (const OrigMeshContainer &b) const {
    return (*orig->Decal[0])==*b.orig->Decal[0];
  }
};
class Meshvs_closer { 
public:
  Meshvs_closer () {}
  static bool FilterCompare (Mesh * a, Mesh * b) {
        if (a) {
              return a->getBlendDst()==ZERO;
        }
        return false;
  }
  ///approximate closness based on center o matrix (which is gonna be center for spheres and convex objects most likely)
  bool operator () (const OrigMeshContainer & a, const OrigMeshContainer & b) {
      float tmp = a.d-b.d;
      if (tmp*tmp<.001)
            return FilterCompare(a.orig,b.orig);
    //    return a.d+a.orig->rSize() > b.d+b.orig->rSize();//draw from outside in :-)
    return tmp>0.0;//draw from outside in :-)
  }
};

typedef std::vector<OrigMeshContainer> OrigMeshVector;
#define NUM_PASSES 4
#define DAMAGE_PASS 2
const int UNDRAWN_MESHES_SIZE= NUM_MESH_SEQUENCE*NUM_PASSES;
OrigMeshVector undrawn_meshes[NUM_MESH_SEQUENCE][NUM_PASSES]; // lower priority means draw first
Texture * Mesh::TempGetTexture(MeshXML * xml, std::string filename, std::string factionname, GFXBOOL detail) const{
      static FILTER fil = XMLSupport::parse_bool(vs_config->getVariable("graphics","detail_texture_trilinear","true"))?TRILINEAR:MIPMAP;
      Texture * ret=NULL;
      string facplus = factionname+"_"+filename;
      if (filename.find(".ani")!=string::npos) {
          ret = new AnimatedTexture(facplus.c_str(),1,fil,detail);
            if (!ret->LoadSuccess()) {
                  delete ret;
                  ret = new AnimatedTexture(filename.c_str(),1,fil,detail);
                  if (!ret->LoadSuccess()) {
                        delete ret;
                        ret=NULL;
                  }else {
                        return ret;
                  }
            }else {
                  return ret;
            }
      }
      ret = new Texture (facplus.c_str(),1,fil,TEXTURE2D,TEXTURE_2D,GFXFALSE,65536,detail);
      if (!ret->LoadSuccess()) {
            delete ret;
            ret = new Texture (filename.c_str(),1,fil,TEXTURE2D,TEXTURE_2D,GFXFALSE,65536,detail);
      }
      return ret;
}
 int  Mesh::getNumTextureFrames() {
      if (Decal.size())
            if (Decal[0]) {
                  return Decal[0]->numFrames();
            }
      return 1;
}
double Mesh::getTextureCumulativeTime() {
      if (Decal.size())
            if (Decal[0]) {
                  return Decal[0]->curTime();
            }
      return 0;
}
float Mesh::getTextureFramesPerSecond(){
      if (Decal.size())
            if (Decal[0]) {
                  return Decal[0]->framesPerSecond();
            }
      return 0;
}
void Mesh::setTextureCumulativeTime(double d) {
      for (unsigned int i=0;i<Decal.size();++i) {
            if (Decal[i])
                  Decal[i]->setTime(d);
      }
}
Texture * Mesh::TempGetTexture (MeshXML * xml, int index, std::string factionname)const {
    Texture *tex=NULL;
    assert (index<(int)xml->decals.size());
    MeshXML::ZeTexture * zt = &(xml->decals[index]);
    if (zt->animated_name.length()) {
        string tempani = factionname+"_"+zt->animated_name;
        tex = new AnimatedTexture (tempani.c_str(),0,BILINEAR);
        if (!tex->LoadSuccess()) {
            delete tex;
            tex = new AnimatedTexture (zt->animated_name.c_str(),0,BILINEAR);
        }
    }else if (zt->decal_name.length()==0) {
        tex = NULL;
    } else {
        if (zt->alpha_name.length()==0) {
            string temptex = factionname+"_"+zt->decal_name;
            tex = new Texture(temptex.c_str(),0,MIPMAP,TEXTURE2D,TEXTURE_2D,(g_game.use_ship_textures||xml->force_texture)?GFXTRUE:GFXFALSE);
            if (!tex->LoadSuccess()) {
                delete tex;
                tex = new Texture(zt->decal_name.c_str(),0,MIPMAP,TEXTURE2D,TEXTURE_2D,(g_game.use_ship_textures||xml->force_texture)?GFXTRUE:GFXFALSE);
            }
        }else {
            string temptex = factionname+"_"+zt->decal_name;
            string tempalp = factionname+"_"+zt->alpha_name;
            tex = new Texture(temptex.c_str(), tempalp.c_str(),0,MIPMAP,TEXTURE2D,TEXTURE_2D,1,0,(g_game.use_ship_textures||xml->force_texture)?GFXTRUE:GFXFALSE);
            if (!tex->LoadSuccess()) {
                delete tex;
                tex = new Texture(zt->decal_name.c_str(), zt->alpha_name.c_str(),0,MIPMAP,TEXTURE2D,TEXTURE_2D,1,0,(g_game.use_ship_textures||xml->force_texture)?GFXTRUE:GFXFALSE);
            }

        }
    }
    return tex;
    
}
Texture * createTexture( const char * filename, int stage=0,enum FILTER f1= MIPMAP,enum TEXTURE_TARGET t0=TEXTURE2D,enum TEXTURE_IMAGE_TARGET t=TEXTURE_2D,unsigned char c=GFXFALSE,int i=65536)
{
      return new Texture( filename, stage, f1, t0, t, c, i);
}
Logo * createLogo(int numberlogos,Vector* center, Vector* normal, float* sizes, float* rotations, float offset, Texture * Dec, Vector *Ref)
{
      return new Logo(numberlogos,center,normal,sizes ,rotations, offset, Dec ,Ref);
}
Texture * createTexture( char const * ccc,char const * cc,int k= 0,enum FILTER f1= MIPMAP,enum TEXTURE_TARGET t0=TEXTURE2D,enum TEXTURE_IMAGE_TARGET t=TEXTURE_2D,float f=1,int j=0,unsigned char c=GFXFALSE,int i=65536)
{
      return new Texture( ccc, cc, k, f1, t0, t, f, j, c, i);
}
AnimatedTexture * createAnimatedTexture( char const * c,int i,enum FILTER f)
{
      return new AnimatedTexture( c, i, f);
}
extern Hashtable<std::string, std::vector <Mesh*>, 127> bfxmHashTable;
00167 Mesh::~Mesh()
{
      if(!orig||orig==this)
      {
        for (int j=0;j<NUM_MESH_SEQUENCE;j++) {
              for (int k=0;k<NUM_PASSES;++k) {
                    for (unsigned int i=0;i<undrawn_meshes[j][k].size();i++) {
                          if (undrawn_meshes[j][k][i].orig==this) {
                                undrawn_meshes[j][k].erase(undrawn_meshes[j][k].begin()+i);
                                i--;
                                VSFileSystem::vs_fprintf (stderr,"stale mesh found in draw queue--removed!\n");
                          }
                    }
              }
        }
        delete vlist;
        for (unsigned int i=0;i<Decal.size();i++) {
          if(Decal[i] != NULL) {
            delete Decal[i];
            Decal[i] = NULL;
          }
        }
        if (squadlogos!=NULL) {
          delete squadlogos;
          squadlogos= NULL;
        }
        if (forcelogos!=NULL) {
          delete forcelogos;
          forcelogos = NULL;
        }
        if (meshHashTable.Get(hash_name)==this){
          meshHashTable.Delete(hash_name);
        }
          vector <Mesh *>* hashers = bfxmHashTable.Get(hash_name);
          vector <Mesh *>::iterator finder;
          if (hashers) {
            for (int i=hashers->size()-1;i>=0;--i) {
              if ((*hashers)[i]==this) {
                hashers->erase (hashers->begin()+i);
                if (hashers->empty()) {
                  bfxmHashTable.Delete(hash_name);
                  delete hashers;
                }
              }
            }
          }
        if(draw_queue!=NULL)
          delete draw_queue;
      } else {
        orig->refcount--;
        //printf ("orig refcount: %d",refcount);
        if(orig->refcount == 0) {
          delete [] orig;           
        }
      }
}
00223 void Mesh::Draw(float lod, const Matrix &m, float toofar, int cloak, float nebdist,unsigned char hulldamage, bool renormalize) //short fix
{
  //  Vector pos (local_pos.Transform(m));
  MeshDrawContext c(m);
  UpdateFX(GetElapsedTime());
  c.SpecialFX = &LocalFX;
  c.damage=hulldamage;
  static float too_far_dist = XMLSupport::parse_float (vs_config->getVariable ("graphics","mesh_far_percent",".8"));
  //c.mesh_seq=((toofar+rSize()>too_far_dist*g_game.zfar)/*&&draw_sequence==0*/)?NUM_ZBUF_SEQ:draw_sequence;
  c.mesh_seq=((toofar+((getConvex()==1)?0:rSize())>too_far_dist*g_game.zfar)/*&&draw_sequence==0*/)?NUM_ZBUF_SEQ:draw_sequence;
  c.cloaked=MeshDrawContext::NONE;
  if (nebdist<0) {
    c.cloaked|=MeshDrawContext::FOG;
  }
  if (renormalize) {
        c.cloaked|=MeshDrawContext::RENORMALIZE;
  }
  if (cloak>=0) {
    c.cloaked|=MeshDrawContext::CLOAK;
    if ((cloak&0x1)) {
      c.cloaked |= MeshDrawContext::GLASSCLOAK;
      c.mesh_seq=MESH_SPECIAL_FX_ONLY;//draw near the end with lights
    } else {
      c.mesh_seq =2;
    }
    if (cloak<=2147483647/2) {
      c.cloaked|=MeshDrawContext::NEARINVIS;
    }
    float tmp = ((float)cloak)/2147483647;
    c.CloakFX.r = (c.cloaked&MeshDrawContext::GLASSCLOAK)?tmp:1;
    c.CloakFX.g = (c.cloaked&MeshDrawContext::GLASSCLOAK)?tmp:1;
    c.CloakFX.b = (c.cloaked&MeshDrawContext::GLASSCLOAK)?tmp:1;
    c.CloakFX.a = tmp;
    /*
    c.CloakNebFX.ambient[0]=((float)cloak)/2147483647;
    c.CloakNebFX.ag=((float)cloak)/2147483647;
    c.CloakNebFX.ab=((float)cloak)/2147483647;
    c.CloakNebFX.aa=((float)cloak)/2147483647;
    */
    ///all else == defaults, only ambient
  } 
  //  c.mat[12]=pos.i;
  //  c.mat[13]=pos.j;
  //  c.mat[14]=pos.k;//to translate to local_pos which is now obsolete!
  Mesh *origmesh = getLOD (lod);
  origmesh->draw_queue->push_back(c);
  if(!(origmesh->will_be_drawn&(1<<c.mesh_seq))) {
    origmesh->will_be_drawn |= (1<<c.mesh_seq);
    //    VSFileSystem::vs_fprintf (stderr,"origmesh %x",origmesh);
      for (unsigned int i=0;i<origmesh->Decal.size()&& i < NUM_PASSES;++i) {
            if (origmesh->Decal[i]) {
                  undrawn_meshes[c.mesh_seq][i].push_back(OrigMeshContainer(origmesh,toofar-rSize()));//FIXME will not work if many of hte same mesh are blocking each other
            }
      }
  }
  will_be_drawn |= (1<<c.mesh_seq);
}
00280 void Mesh::DrawNow(float lod,  bool centered, const Matrix &m, int cloak, float nebdist) { //short fix
  Mesh *o = getLOD (lod);
  //fixme: cloaking not delt with.... not needed for backgroudn anyway
  if (nebdist<0) {
    Nebula * t=_Universe->AccessCamera()->GetNebula();
    if (t) {
      t->SetFogState();
    }
  } else {
    GFXFogMode(FOG_OFF);
  }
  if (centered) {
    //    Matrix m1 (m);
    //Vector pos(_Universe->AccessCamera()->GetPosition().Transform(m1));
    //m1[12]=pos.i;
    //m1[13]=pos.j;
    //m1[14]=pos.k;
    GFXCenterCamera (true);
    GFXLoadMatrixModel (m);    
  } else {  
    if (o->draw_sequence!=MESH_SPECIAL_FX_ONLY) {
      GFXLoadIdentity(MODEL);
      GFXPickLights (Vector (m.p.i,m.p.j,m.p.k),rSize());
    }
    GFXLoadMatrixModel (m);
  } 
  vector <int> specialfxlight;
  unsigned int i;
  for ( i=0;i<LocalFX.size();i++) {
    int ligh;
    GFXCreateLight (ligh,(LocalFX)[i],true);
    specialfxlight.push_back(ligh);
  }
  GFXSelectMaterial(o->myMatNum);
  if (blendSrc!=SRCALPHA&&blendDst!=ZERO) 
    GFXDisable(DEPTHWRITE);
  GFXBlendMode(blendSrc, blendDst);
  if (o->Decal[0])
    o->Decal[0]->MakeActive();
  o->vlist->DrawOnce();
  if (centered) {
    GFXCenterCamera(false);
  }
  for ( i=0;i<specialfxlight.size();i++) {
    GFXDeleteLight (specialfxlight[i]);
  }
  if (cloak>=0&&cloak<2147483647) {
    GFXEnable (TEXTURE1);
  }
}
static GFXColor getMeshColor () {
   float color[4];
  vs_config->getColor ("unit", "ship_ambient",color);
  GFXColor tmp (color[0],color[1],color[2],color[3]);
  return tmp;
}
00336 void Mesh::ProcessZFarMeshes () {
  static GFXColor meshcolor (getMeshColor());
  GFXLightContextAmbient(meshcolor);
  _Universe->AccessCamera()->UpdateGFX (GFXFALSE, GFXFALSE);
  GFXEnable(LIGHTING);
  GFXEnable(CULLFACE);
  GFXDisable (DEPTHTEST);
  GFXDisable (DEPTHWRITE);
  ///sort meshes  
  //std::sort<OrigMeshVector::iterator,Meshvs_closer>(undrawn_meshes[NUM_ZBUF_SEQ].begin(),undrawn_meshes[NUM_ZBUF_SEQ].end(),Meshvs_closer());
  for (int k=0;k<NUM_PASSES;++k) {
        std::sort(undrawn_meshes[NUM_ZBUF_SEQ][k].begin(),undrawn_meshes[NUM_ZBUF_SEQ][k].end(),Meshvs_closer());
        
        for (OrigMeshVector::iterator i=undrawn_meshes[NUM_ZBUF_SEQ][k].begin();i!=undrawn_meshes[NUM_ZBUF_SEQ][k].end();i++) {
              i->orig->ProcessDrawQueue (k,NUM_ZBUF_SEQ);
              i->orig->will_be_drawn &= (~(1<<NUM_ZBUF_SEQ));//not accurate any more
        }
        undrawn_meshes[NUM_ZBUF_SEQ][k].clear();        
  }
  GFXFogMode(FOG_OFF);
  Animation::ProcessFarDrawQueue(-FLT_MAX);
  _Universe->AccessCamera()->UpdateGFX (GFXTRUE, GFXFALSE);
  GFXEnable (DEPTHTEST);
  GFXEnable (DEPTHWRITE);
}

const GFXMaterial &Mesh::GetMaterial () {
   return GFXGetMaterial (myMatNum);
}

00366 void Mesh::ProcessUndrawnMeshes(bool pushSpecialEffects) {
  static GFXColor meshcolor (getMeshColor());
  GFXLightContextAmbient(meshcolor);
  GFXEnable(DEPTHWRITE);
  GFXEnable(DEPTHTEST);
  GFXEnable(LIGHTING);
  GFXEnable(CULLFACE);

  for(int a=0; a<NUM_ZBUF_SEQ; a++) {
    if (a==MESH_SPECIAL_FX_ONLY) {
      
      GFXPushGlobalEffects();
      GFXDisable(DEPTHWRITE);
    } else {
    }
      for (int k=0;k<NUM_PASSES;++k) {
    if (!undrawn_meshes[a][k].empty()) {  
      std::sort(undrawn_meshes[a][k].begin(),undrawn_meshes[a][k].end());//sort by texture address
      undrawn_meshes[a][k].back().orig->vlist->LoadDrawState();
    }
    while(!undrawn_meshes[a][k].empty()) {
      Mesh *m = undrawn_meshes[a][k].back().orig;
      undrawn_meshes[a][k].pop_back();
      m->ProcessDrawQueue(k,a);
      m->will_be_drawn &= (~(1<<a));//not accurate any more
    }
      }
    if (a==MESH_SPECIAL_FX_ONLY) {
      if (!pushSpecialEffects) {
      GFXPopGlobalEffects();
      }
      GFXEnable(DEPTHWRITE);
    }
  
    while(undrawn_logos.size()) {
      Logo *l = undrawn_logos.back();
      undrawn_logos.pop_back();
      l->ProcessDrawQueue();
      l->will_be_drawn = false;
    }
  }
}
void Mesh::RestoreCullFace (int whichdrawqueue) {
  if (blendDst!=ZERO &&whichdrawqueue!=NUM_ZBUF_SEQ||getCullFaceForcedOff()) {
    if (blendSrc!=SRCALPHA) {
      GFXEnable (CULLFACE);
    }
  }
}
00415 void Mesh::SelectCullFace (int whichdrawqueue) {
  if (whichdrawqueue==NUM_ZBUF_SEQ) {
    GFXEnable(CULLFACE);
  }else {
    if (getCullFaceForcedOn()) {
      GFXEnable(CULLFACE);
    }else if (getCullFaceForcedOff()) {
      GFXDisable(CULLFACE);
    }
  }
  if (blendDst!=ZERO&&whichdrawqueue!=NUM_ZBUF_SEQ) {
    //    
    GFXDisable(DEPTHWRITE);
    if (blendSrc!=SRCALPHA||getCullFaceForcedOff()) {
      GFXDisable(CULLFACE);
    }
  }
  
}
void SetupCloakState (char cloaked,const GFXColor & CloakFX, vector <int> &specialfxlight, unsigned char hulldamage,unsigned int matnum) {
    if (cloaked&MeshDrawContext::CLOAK) {
        GFXPushBlendMode ();
            GFXDisable(CULLFACE);
/**/
            GFXEnable(LIGHTING);
            GFXEnable(TEXTURE0);
            GFXEnable(TEXTURE1);
            
/**/
        if (cloaked&MeshDrawContext::GLASSCLOAK) {
            GFXDisable (TEXTURE1);
            int ligh;
            GFXCreateLight (ligh,GFXLight (true,GFXColor(0,0,0,1),GFXColor (0,0,0,1),GFXColor (0,0,0,1),CloakFX,GFXColor(1,0,0)),true);
            specialfxlight.push_back (ligh);
            GFXBlendMode (ONE,ONE);
            GFXSelectMaterialHighlights(matnum,
                                        GFXColor(1,1,1,1),
                                        GFXColor(1,1,1,1),
                                        GFXColor(1,1,1,1),
                                        CloakFX);
        }else {
                  GFXEnable(TEXTURE1);
            if (cloaked&MeshDrawContext::NEARINVIS) {      
                //NOT sure I like teh jump this produces    GFXDisable (TEXTURE1);
            }
            GFXBlendMode (SRCALPHA, INVSRCALPHA);
            GFXColorMaterial (AMBIENT|DIFFUSE);

                  if (hulldamage) {
                        GFXColor4f(CloakFX.r,CloakFX.g,CloakFX.b,CloakFX.a*hulldamage/255);
                  }else
                        GFXColorf(CloakFX);
        }

#if defined(CG_SUPPORT)
            cgGLSetParameter2f(cloak_cg->VecBlendParams, 0.0f, CloakFX.a);
            cgGLEnableProfile(cloak_cg->vertexProfile);
#endif

    }else if (hulldamage) {
            //ok now we go in and do the dirtying
            GFXColorMaterial (AMBIENT|DIFFUSE);
            GFXColor4f(1,1,1,hulldamage/255.);
      }

}
static void RestoreCloakState (char cloaked, bool envMap,unsigned char damage) {
    if (cloaked&MeshDrawContext::CLOAK) {
        GFXColorMaterial (0);
        if (envMap)
            GFXEnable (TEXTURE1);
        GFXPopBlendMode ();
#if defined(CG_SUPPORT)
           cgGLDisableProfile(cloak_cg->vertexProfile);
#endif
    }
      if (damage) {
            GFXColorMaterial(0);
      }
}
static void SetupFogState (char cloaked) {
    if (cloaked&MeshDrawContext::FOG) {
        Nebula *t=_Universe->AccessCamera()->GetNebula();
        if (t) {
            t->SetFogState();
        }
    } else {
        GFXFogMode (FOG_OFF);
    }    
}
bool SetupSpecMapFirstPass (vector <Texture *> &decal, unsigned int mat, bool envMap,float polygon_offset,Texture *detailTexture,const vector<Vector> &detailPlanes) {
      if (polygon_offset){
            float a,b;
            GFXGetPolygonOffset(&a,&b);
            GFXPolygonOffset (a, b-polygon_offset);
      }
    bool retval=false;
      int detailoffset=2;
    if (decal.size()>1) {
        if (decal[1]) {
                  detailoffset=1;
            GFXSelectMaterialHighlights(mat,
                                        GFXColor(1,1,1,1),
                                        GFXColor(1,1,1,1),
                                        GFXColor(0,0,0,0),
                                        GFXColor(0,0,0,0));
            retval=true;
            if (envMap&&detailTexture==NULL)
                GFXDisable(TEXTURE1);
            if (decal[0])
                decal[0]->MakeActive();
            }
      }
      if (detailTexture) {
                  for (unsigned int i=1;i<detailPlanes.size();i+=2) {
                        int stage = (i/2)+detailoffset;
                        GFXActiveTexture(stage);
                        GFXTextureEnv(stage,GFXADDSIGNEDTEXTURE);
                        /* 
                        glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
                        glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_PREVIOUS);
                        glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB,GL_TEXTURE);
                        glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_ADD_SIGNED);
                        */
                        const float params[4]={detailPlanes[i-1].i,detailPlanes[i-1].j,detailPlanes[i-1].k,0};
                        const float paramt[4]={detailPlanes[i].i,detailPlanes[i].j,detailPlanes[i].k,0};
                        GFXTextureCoordGenMode(OBJECT_LINEAR_GEN,params,paramt);
                        detailTexture->MakeActive(stage);
                        GFXToggleTexture(true,stage); 
                        
                        
                  }
      }
      
    return retval;
}
void RestoreFirstPassState(Texture * detailTexture, const vector<Vector> & detailPlanes ) {
      if (detailTexture) {
            static float tempo[4]={1,0,0,0};
            GFXActiveTexture(1);
            GFXTextureEnv(1,GFXADDTEXTURE);           
            GFXTextureCoordGenMode(SPHERE_MAP_GEN,tempo,tempo);
            _Universe->activeStarSystem()->activateLightMap();
            unsigned int sizeplus1=detailPlanes.size()/2+1;
            for (unsigned int i=1;i<sizeplus1;i++) {
                  GFXToggleTexture(false,i+1);//turn off high detial tex
            }
      }
}
void SetupSpecMapSecondPass(Texture * decal,unsigned int mat,BLENDFUNC blendsrc, bool envMap, const GFXColor &cloakFX, float polygon_offset) {
      GFXPushBlendMode();                 
    GFXSelectMaterialHighlights(mat,
                                GFXColor(0,0,0,0),
                                GFXColor(0,0,0,0),
                        cloakFX,
                                (envMap&&GFXMultiTexAvailable())?GFXColor (1,1,1,1):GFXColor(0,0,0,0));
    GFXBlendMode (ONE,ONE);
    decal->MakeActive();
    float a,b;
    GFXGetPolygonOffset(&a,&b);
    GFXPolygonOffset (a, b-1-polygon_offset);
    GFXDisable(DEPTHWRITE);
    if (envMap){
      GFXActiveTexture(1);
      GFXTextureEnv(1,GFXMODULATETEXTURE); 
      GFXEnable(TEXTURE1);
    }
    else {
      GFXSetSeparateSpecularColor(GFXFALSE);
      GFXTextureEnv(0,GFXMODULATETEXTURE); 
      GFXEnable(TEXTURE0);
      GFXActiveTexture(1);
      GFXDisable(TEXTURE1);

    }
}
void SetupGlowMapFourthPass(Texture * decal,unsigned int mat,BLENDFUNC blendsrc, const GFXColor &cloakFX, float polygon_offset) {
      GFXPushBlendMode();                 
    GFXSelectMaterialHighlights(mat,
                                GFXColor(0,0,0,0),
                                GFXColor(0,0,0,0),
                                                GFXColor(0,0,0,0),
                                cloakFX);
    GFXBlendMode (blendsrc,ONE);
    decal->MakeActive();
    float a,b;
    GFXGetPolygonOffset(&a,&b);
    GFXPolygonOffset (a, b-2-polygon_offset);
    GFXDisable(DEPTHWRITE);
      GFXDisable(TEXTURE1);
}
extern void GFXSelectMaterialAlpha(const unsigned int, float);
void SetupDamageMapThirdPass(Texture * decal,unsigned int mat, float polygon_offset) {
      GFXPushBlendMode();                 
    GFXBlendMode (SRCALPHA,INVSRCALPHA);
    decal->MakeActive();
    float a,b;
    GFXGetPolygonOffset(&a,&b);
    GFXPolygonOffset (a, b-DAMAGE_PASS-polygon_offset);
    GFXDisable(DEPTHWRITE);
      GFXDisable(TEXTURE1);
}

void RestoreGlowMapState(bool write_to_depthmap, float polygonoffset,float NOT_USED_BUT_BY_HELPER=3) { 
  float a,b;
    GFXGetPolygonOffset(&a,&b);
    GFXPolygonOffset (a, b+polygonoffset+NOT_USED_BUT_BY_HELPER);
      static bool force_write_to_depthmap=XMLSupport::parse_bool (vs_config->getVariable("graphics","force_glowmap_restore_write_to_depthmap","true"));
      if (force_write_to_depthmap||write_to_depthmap) {
            GFXEnable(DEPTHWRITE);
      }
      GFXEnable(TEXTURE1);
      GFXPopBlendMode();                        
}
void RestoreDamageMapState(bool write_to_depthmap, float polygonoffset) {
      RestoreGlowMapState(write_to_depthmap,polygonoffset,DAMAGE_PASS);
}
void RestoreSpecMapState(bool envMap, bool write_to_depthmap, float polygonoffset) { 
  float a,b;
    GFXGetPolygonOffset(&a,&b);
    GFXPolygonOffset (a, b+1+polygonoffset);
    if (envMap) {
      GFXActiveTexture(1);
      GFXTextureEnv(1,GFXADDTEXTURE); //restore modulate
    }else {
       static bool separatespec = XMLSupport::parse_bool (vs_config->getVariable ("graphics","separatespecularcolor","false"))?GFXTRUE:GFXFALSE;
       GFXSetSeparateSpecularColor(separatespec);
    }
    if (write_to_depthmap) {
        GFXEnable(DEPTHWRITE);
    }
      GFXPopBlendMode();      
}
00648 void Mesh::ProcessDrawQueue(int whichpass,int whichdrawqueue) {
  //  assert(draw_queue->size());
      if (whichpass>=(int)Decal.size()) {
            VSFileSystem::vs_fprintf (stderr,"Fatal error: drawing ship that has a nonexistant tex");
            return;
      }
      if (Decal[whichpass]==NULL) {
            VSFileSystem::vs_fprintf (stderr,"Less Fatal error: drawing ship that has a nonexistant tex");
            return;
      }

  if (draw_queue->empty()) {
    VSFileSystem::vs_fprintf (stderr,"cloaking queues issue! Report to hellcatv@hotmail.com\nn%d\n%s",whichdrawqueue,hash_name.c_str());
    return;
  }
  bool damagepassabort=false;
  bool last_pass = whichpass+1>=Decal.size();
  vector<MeshDrawContext> tmp_draw_queue;
  if (last_pass)
        tmp_draw_queue.reserve(draw_queue->size());
  if (whichpass==DAMAGE_PASS) {
        damagepassabort=true;
        vector<MeshDrawContext>::iterator i = draw_queue->begin();
        for (;i!=draw_queue->end();++i) {
              if ((*i).mesh_seq!=whichdrawqueue) {
                    tmp_draw_queue.push_back(*i);
              }else {
                    if ((*i).damage!=0){
                          damagepassabort=false;
                    }
              }
        }
  }
  if (!damagepassabort) {
        tmp_draw_queue.clear();
  if (whichdrawqueue==NUM_ZBUF_SEQ) {
        for (unsigned int i=0;i<draw_queue->size();i++) {
            MeshDrawContext * c = &((*draw_queue)[i]);
          if (c->mesh_seq==whichdrawqueue) {
            Animation::ProcessFarDrawQueue ((_Universe->AccessCamera()->GetPosition()-c->mat.p).Magnitude()/*+this->radialSize*/);        
            }
        }
      GFXEnable(LIGHTING);
  }

  if (getLighting()) {
    GFXSelectMaterial(myMatNum);
    GFXEnable (LIGHTING);
  }else {
    GFXDisable (LIGHTING);
    GFXColor4f(1,1,1,1);
  }
  bool write_to_depthmap=!(blendDst!=ZERO&&whichdrawqueue!=NUM_ZBUF_SEQ);
  if (!write_to_depthmap) {
    GFXDisable(DEPTHWRITE);
  }
  SelectCullFace(whichdrawqueue);
  GFXBlendMode(blendSrc, blendDst);
  GFXEnable(TEXTURE0);
  if(Decal[0])
    Decal[0]->MakeActive();
  GFXSelectTexcoordSet(0, 0);
  if(getEnvMap()) {
    GFXEnable(TEXTURE1);
    _Universe->activateLightMap();
    GFXSelectTexcoordSet(1, 1);
  } else {
    GFXDisable(TEXTURE1);
  }

#if defined(CG_SUPPORT)
  cgGLBindProgram(cloak_cg->vertexProgram);

 cgGLSetStateMatrixParameter(cloak_cg->ModelViewProj, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
 cgGLSetStateMatrixParameter(cloak_cg->ModelViewIT, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE_TRANSPOSE);
 cgGLSetStateMatrixParameter(cloak_cg->ModelView, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY );
 cgGLSetParameter4f(cloak_cg->MaterialDiffuse, this->GetMaterial().dr,  this->GetMaterial().dg, this->GetMaterial().db, this->GetMaterial().da);
 cgGLSetParameter4f(cloak_cg->MaterialAmbient, this->GetMaterial().ar, this->GetMaterial().ag, this->GetMaterial().ab, this->GetMaterial().aa);
 cgGLSetParameter4f(cloak_cg->MaterialSpecular, this->GetMaterial().sr, this->GetMaterial().sg, this->GetMaterial().sb, this->GetMaterial().sa);
 cgGLSetParameter4f(cloak_cg->MaterialEmissive, this->GetMaterial().er, this->GetMaterial().eg, this->GetMaterial().eb, this->GetMaterial().ea);

 cgGLSetParameter3f(cloak_cg->VecEye, _Universe->AccessCamera()->GetPosition().i, _Universe->AccessCamera()->GetPosition().j, _Universe->AccessCamera()->GetPosition().k);
 cgGLSetParameter3f(cloak_cg->VecCenter,this->Position().i, this->Position().j, this->Position().k);

 cgGLSetParameter3f(cloak_cg->VecPower, this->GetMaterial().power, 0.0f, 0.0f);
 cgGLSetParameter3f(cloak_cg->VecLightDir, 0.0f, 1.0f, 1.0f);

  cgGLSetOptimalOptions(cloak_cg->vertexProfile);
#endif

  vlist->BeginDrawState();    

  switch (whichpass) {
  case 0:
        SetupSpecMapFirstPass (Decal,myMatNum,getEnvMap(),polygon_offset,detailTexture,detailPlanes);
        break;
  case 1:
        
        SetupSpecMapSecondPass(Decal[whichpass],myMatNum,blendSrc,getEnvMap(), GFXColor(1,1,1,1),polygon_offset);
        break;
  case 3:
        SetupGlowMapFourthPass (Decal[whichpass],myMatNum,ONE,GFXColor(1,1,1,1),polygon_offset);
        break;
  case DAMAGE_PASS:
        SetupDamageMapThirdPass(Decal[whichpass],myMatNum,polygon_offset);
        break;
  }
  for(unsigned int draw_queue_index=0;draw_queue_index<draw_queue->size();++draw_queue_index) {   
    MeshDrawContext &c =(*draw_queue)[draw_queue_index];
    if (c.mesh_seq!=whichdrawqueue) {
            if (last_pass) {
                  tmp_draw_queue.push_back (c);
            }
            continue;
    }
      if (c.damage==0&&whichpass==DAMAGE_PASS)
            continue;
      if ((c.cloaked&MeshDrawContext::CLOAK)&&whichpass!=0)
            continue;
    if (whichdrawqueue!=MESH_SPECIAL_FX_ONLY) {
      GFXLoadIdentity(MODEL);
      GFXPickLights (Vector (c.mat.p.i,c.mat.p.j,c.mat.p.k),rSize());
    }
    vector <int> specialfxlight;
    GFXLoadMatrixModel ( c.mat);
      unsigned char damaged=((whichpass==DAMAGE_PASS)?c.damage:0);
    SetupCloakState (c.cloaked,c.CloakFX,specialfxlight,damaged,myMatNum);

    unsigned int i;
    for ( i=0;i<c.SpecialFX->size();i++) {
      int ligh;
      GFXCreateLight (ligh,(*c.SpecialFX)[i],true);
      specialfxlight.push_back(ligh);
    }
    SetupFogState(c.cloaked);
      if (c.cloaked&MeshDrawContext::RENORMALIZE)
            glEnable(GL_NORMALIZE);

    vlist->Draw();

      if (c.cloaked&MeshDrawContext::RENORMALIZE)
            glDisable(GL_NORMALIZE);
      
    for ( i=0;i<specialfxlight.size();i++) {
      GFXDeleteLight (specialfxlight[i]);
    }
    RestoreCloakState(c.cloaked,getEnvMap(),damaged);

    
    if(0!=forcelogos&&!(c.cloaked&MeshDrawContext::NEARINVIS)) {
      forcelogos->Draw(c.mat);
    }
    if (0!=squadlogos&&!(c.cloaked&MeshDrawContext::NEARINVIS)){
      squadlogos->Draw(c.mat);
    }
  }
  vlist->EndDrawState();

      switch(whichpass) {
      case 0:
            RestoreFirstPassState(detailTexture,detailPlanes);
            break;
      case 1:
            RestoreSpecMapState(getEnvMap(),write_to_depthmap,polygon_offset);
            break;
      case 3:
            RestoreGlowMapState(write_to_depthmap,polygon_offset);
            break;
      case DAMAGE_PASS:
            RestoreDamageMapState(write_to_depthmap,polygon_offset);//nothin
            break;
      }  
  if (!getLighting()) {
    GFXEnable(LIGHTING);
  }
  if (!write_to_depthmap) {
    GFXEnable(DEPTHWRITE);//risky--for instance logos might be fubar!
  }
  RestoreCullFace(whichdrawqueue);
  
  }
  if (last_pass) {
        *draw_queue=tmp_draw_queue;
  }
}
00833 void Mesh::CreateLogos(MeshXML * xml , int faction, Flightgroup * fg) {
  numforcelogo=numsquadlogo =0;
  unsigned int index;
  for (index=0;index<xml->logos.size();index++) {
    if (xml->logos[index].type==0)
      numforcelogo++;
    if (xml->logos[index].type==1)
      numsquadlogo++;
  }
  unsigned int nfl=numforcelogo;
  Logo ** tmplogo=NULL;
  Texture * Dec=NULL;
  for (index=0,nfl=numforcelogo,tmplogo=&forcelogos,Dec=FactionUtil::getForceLogo(faction);index<2;index++,nfl=numsquadlogo,tmplogo=&squadlogos,Dec=(fg==NULL?FactionUtil::getSquadLogo(faction):fg->squadLogo)) {
    if (Dec==NULL) {
      Dec = FactionUtil::getSquadLogo(faction);
    }
    if (nfl==0)
      continue;
    Vector *PolyNormal = new Vector [nfl];
    Vector *center = new Vector [nfl];
    float *sizes = new float [nfl];
    float *rotations = new float [nfl];
    float *offset = new float [nfl];
    Vector *Ref = new Vector [nfl];
    Vector norm1,norm2,norm;
    int ri=0;
    float totoffset=0;
    for (unsigned int ind=0;ind<xml->logos.size();ind++) {
      if (xml->logos[ind].type==index) {
      float weight=0;
      norm1.Set(0,1,0);
      norm2.Set(1,0,0);
      if (xml->logos[ind].refpnt.size()>2) {
        if (xml->logos[ind].refpnt[0]<xml->vertices.size()&&
            xml->logos[ind].refpnt[0]>=0&&
            xml->logos[ind].refpnt[1]<xml->vertices.size()&&
            xml->logos[ind].refpnt[1]>=0&&
            xml->logos[ind].refpnt[2]<xml->vertices.size()&&
            xml->logos[ind].refpnt[2]>=0) {           
          norm2=Vector (xml->vertices[xml->logos[ind].refpnt[1]].x-
                    xml->vertices[xml->logos[ind].refpnt[0]].x,
                    xml->vertices[xml->logos[ind].refpnt[1]].y-
                    xml->vertices[xml->logos[ind].refpnt[0]].y,
                    xml->vertices[xml->logos[ind].refpnt[1]].z-
                    xml->vertices[xml->logos[ind].refpnt[0]].z);
          norm1=Vector (xml->vertices[xml->logos[ind].refpnt[2]].x-
                    xml->vertices[xml->logos[ind].refpnt[0]].x,
                    xml->vertices[xml->logos[ind].refpnt[2]].y-
                    xml->vertices[xml->logos[ind].refpnt[0]].y,
                    xml->vertices[xml->logos[ind].refpnt[2]].z-
                    xml->vertices[xml->logos[ind].refpnt[0]].z);
        }
      }
      CrossProduct (norm2,norm1,norm);
      
      Normalize(norm);//norm is our normal vect, norm1 is our reference vect
      Vector Cent(0,0,0);
      for (unsigned int rj=0;rj<xml->logos[ind].refpnt.size();rj++) {
        weight+=xml->logos[ind].refweight[rj];
        Cent += Vector (xml->vertices[xml->logos[ind].refpnt[rj]].x*xml->logos[ind].refweight[rj],
                    xml->vertices[xml->logos[ind].refpnt[rj]].y*xml->logos[ind].refweight[rj],
                    xml->vertices[xml->logos[ind].refpnt[rj]].z*xml->logos[ind].refweight[rj]);
      }     
      if (weight!=0) {
        Cent.i/=weight;
        Cent.j/=weight;
        Cent.k/=weight;
      }
      //Cent.i-=x_center;
      //Cent.j-=y_center;
      //Cent.k-=z_center;
      Ref[ri]=norm2;
      PolyNormal[ri]=norm;
      center[ri] = Cent;
      sizes[ri]=xml->logos[ind].size*xml->scale.k;
      rotations[ri]=xml->logos[ind].rotate;
      offset[ri]=xml->logos[ind].offset;
      totoffset+=offset[ri];
      ri++;
      }
    }
    totoffset/=nfl;
    *tmplogo= new Logo (nfl,center,PolyNormal,sizes,rotations, totoffset,Dec,Ref);
    delete [] Ref;
    delete []PolyNormal;
    delete []center;
    delete [] sizes;
    delete [] rotations;
    delete [] offset;
  }
}


Generated by  Doxygen 1.6.0   Back to index