15 #if defined (CG_SUPPORT)
22 #include <sys/types.h>
42 explicit Exception(
const std::string &message ) : _message( message ) {}
44 virtual const char *
what()
const throw ()
46 return _message.c_str();
75 assert( passno < orig->technique->getNumPasses() );
82 this->
program = pass.getCompiledProgram();
91 assert( this->passno == passno );
92 assert( this->
sequence == pass.sequence );
95 #define SLESSX( a, b ) \
96 do {if ( !( (a) == (b) ) ) return ( (a) < (b) ); \
100 #define PLESSX( a, b ) \
101 do {SLESSX( bool(a), bool(b) ); if ( bool(a) ) SLESSX( *a, *b ); \
105 #define SLESS( f ) SLESSX( f, b.f )
107 #define PLESS( f ) PLESSX( f, b.f )
161 return !(*
this <
b) && !(b < *
this);
176 const std::vector< MeshDrawContext > &
queue;
183 return (
queue[a].mat.p-
ctr).MagnitudeSquared() > (
queue[
b].mat.p-
ctr).MagnitudeSquared();
189 #define NUM_PASSES (4)
190 #define BASE_PASS (0)
191 #define ENVSPEC_PASS (1)
192 #define DAMAGE_PASS (2)
193 #define GLOW_PASS (3)
195 #define ENVSPEC_TEX (1)
196 #define DAMAGE_TEX (2)
198 #define NORMAL_TEX (4)
205 Texture* Mesh::TempGetTexture(
MeshXML *xml, std::string filename, std::string factionname,
GFXBOOL detail )
const
209 static bool factionalize_textures =
211 string faction_prefix = ( factionalize_textures ? (factionname+
"_") :
string() );
213 string facplus = faction_prefix+filename;
214 if (filename.find(
".ani" ) != string::npos) {
241 return Decal[0]->numFrames();
249 return Decal[0]->curTime();
257 return Decal[0]->framesPerSecond();
263 for (
unsigned int i = 0;
i <
Decal.size(); ++
i)
265 Decal[i]->setTime( d );
270 static bool factionalize_textures =
272 string faction_prefix = ( factionalize_textures ? (factionname+
"_") :
string() );
274 assert( index < (
int) xml->
decals.size() );
276 if ( zt->animated_name.length() ) {
283 }
else if (zt->decal_name.length() == 0) {
286 if (zt->alpha_name.length() == 0) {
287 string temptex = faction_prefix+zt->decal_name;
300 string temptex = faction_prefix+zt->decal_name;
301 string tempalp = faction_prefix+zt->alpha_name;
324 return new Texture( filename, stage, f1,
t0, t,
c,
i );
336 return new Logo( numberlogos, center, normal, sizes, rotations, offset, Dec, Ref );
364 if (it->orig ==
this) {
369 for (
unsigned int i = 0;
i <
Decal.size();
i++)
384 vector< Mesh* > *hashers = bfxmHashTable.
Get(
hash_name );
385 vector< Mesh* >::iterator finder;
387 for (
int i = hashers->size()-1;
i >= 0; --
i)
388 if ( (*hashers)[
i] == this ) {
389 hashers->erase( hashers->begin()+
i );
390 if ( hashers->empty() ) {
406 void Mesh::Draw(
float lod,
const Matrix &m,
float toofar,
int cloak,
float nebdist,
unsigned char hulldamage,
bool renormalize,
const MeshFX*mfx )
409 if (origmesh->
rSize() > 0) {
434 if (cloak <= 2147483647/2)
436 float tmp = ( (
float) cloak )/2147483647;
456 for (
int passno = 0, npasses = origmesh->
technique->getNumPasses(); passno < npasses; ++passno)
493 static vector< int >specialfxlight;
496 for (i = 0; i <
LocalFX.size(); i++) {
499 specialfxlight.push_back( ligh );
506 o->
Decal[0]->MakeActive();
513 for (i = 0; i < specialfxlight.size(); i++)
515 if (cloak >= 0 && cloak < 2147483647)
553 template <
typename T >
556 return !( ( (min1 < min2) == (max1 < min2) )
557 && ( (min1 < max2) == (max1 < max2) )
558 && ( (min1 < min2) == (min1 < max2) ) );
585 if (!pushSpecialEffects)
623 vector< int > &specialfxlight,
624 unsigned char hulldamage,
625 unsigned int matnum )
641 1 ),
GFXColor( 0, 0, 0, 1 ),
GFXColor( 0, 0, 0, 1 ), CloakFX,
GFXColor( 1,
645 specialfxlight.push_back( ligh );
660 GFXColor4f( CloakFX.
r, CloakFX.
g, CloakFX.
b, CloakFX.
a*hulldamage/255 );
664 }
else if (hulldamage) {
678 #if defined (CG_SUPPORT)
679 cgGLDisableProfile( cloak_cg->vertexProfile );
701 float polygon_offset,
703 const vector< Vector > &detailPlanes,
709 static bool separatespec =
714 if (polygon_offset) {
729 skip_glowpass =
false;
730 size_t detailoffset = 2;
731 if ( !nomultienv && (decalSize > 1) && (decal[1]) ) {
739 if (envMap && detailTexture == NULL) {
745 skip_glowpass =
true;
754 }
else if (decalSize && decal[0]) {
761 for (
unsigned int i = 1;
i < detailPlanes.size();
i += 2) {
762 int stage = (
i/2)+detailoffset;
763 const float params[4] = {detailPlanes[
i-1].i, detailPlanes[
i-1].j, detailPlanes[
i-1].k, 0};
764 const float paramt[4] = {detailPlanes[
i].i, detailPlanes[
i].j, detailPlanes[
i].k, 0};
775 const vector< Vector > &detailPlanes,
776 bool skipped_glowpass,
781 if (detailTexture || skipped_glowpass) {
782 static float tempo[4] = {1, 0, 0, 0};
786 unsigned int sizeplus1 = detailPlanes.size()/2+1;
787 for (
unsigned int i = 1;
i < sizeplus1;
i++)
794 assert( passno >= 0 && passno <= 2 );
812 if ( decal && ( (passno == 0) || (passno == 2) ) ) {
815 }
else if (passno == 1) {
827 static bool separatespec =
843 float polygon_offset )
881 float polygon_offset )
918 static bool force_write_to_depthmap =
920 if (force_write_to_depthmap || write_to_depthmap)
946 static bool separatespec =
951 if (write_to_depthmap)
962 ProcessShaderDrawQueue( whichpass, whichdrawqueue, zsort, sortctr );
964 ProcessFixedDrawQueue( whichpass, whichdrawqueue, zsort, sortctr );
987 tu.
texture->MakeActive( targetIndex );
990 default:
throw Exception(
"Texture Unit for technique of unhandled kind" );
1005 default:
throw Exception(
"Texture Unit for technique of unhandled kind" );
1014 "Environment Texture Unit for technique must be a cube map" );
1019 "Environment Texture Unit for technique must be a 2D spheremap" );
1026 "Detail Texture Unit for technique must be 2D" );
1030 activateTextureUnit( tu,
true );
1032 "Texture Unit for technique requested a missing texture (detail default given that cannot be found)" );
1035 if ( ( sourceIndex < static_cast<int>(
Decal.size()) ) &&
Decal[sourceIndex] )
1037 Decal[sourceIndex]->MakeActive( targetIndex );
1039 activateTextureUnit( tu,
true );
1041 "Texture Unit for technique requested a missing texture (decal default given that cannot be found)" );
1055 default:
throw Exception(
"Texture Unit for technique of unhandled kind" );
1191 void Mesh::ProcessShaderDrawQueue(
size_t whichpass,
int whichdrawqueue,
bool zsort,
const QVector &sortctr )
1227 float zero[4] = {0, 0, 0, 0};
1228 float envmaprgba[4] = {1, 1, 1, 0};
1229 float noenvmaprgba[4] = {0.5, 0.5, 0.5, 1.0};
1231 vector< MeshDrawContext > &cur_draw_queue =
draw_queue[whichdrawqueue];
1242 int activeLightsArrayParam = -1;
1243 int apparentLightSizeArrayParam = -1;
1244 int numLightsParam = -1;
1266 numLightsParam = sp.
id;
1269 activeLightsArrayParam = sp.
id;
1272 apparentLightSizeArrayParam = sp.
id;
1293 activateTextureUnit( tu );
1313 static std::vector< int >indices;
1315 indices.resize( cur_draw_queue.size() );
1316 for (
int i = 0, n = cur_draw_queue.size();
i < n; ++
i)
1318 std::sort( indices.begin(), indices.end(),
1322 for (
int i = 0, n = cur_draw_queue.size();
i < n; ++
i) {
1326 static vector< int >
lights;
1329 if (c.
mesh_seq == whichdrawqueue) {
1338 size_t fxLightsBase = lights.size();
1339 for (
size_t i = 0;
i < c.
SpecialFX->size();
i++) {
1343 lights.push_back( light );
1349 lights.push_back( light );
1355 bool popGlobals =
false;
1357 int maxlights = lights.size();
1364 int npasslights = 0;
1365 for (
size_t iter = 0, lightnum = 0, nlights = lights.size();
1366 (iter < maxiter) && ( (pass.
perLightIteration == 0 && lightnum == 0) || (lightnum < nlights) );
1367 ++iter, lightnum += npasslights)
1370 npasslights =
std::max( 0,
std::min(
int(nlights) -
int(lightnum),
int(maxlights) ) );
1387 if (lightnum == 0) {
1396 activeLightsArrayParam,
1397 apparentLightSizeArrayParam,
1399 lights.begin() + lightnum,
1400 lights.begin() + lightnum + npasslights );
1440 for (; fxLightsBase < lights.size(); ++fxLightsBase)
1442 size_t lastPass =
technique->getNumPasses();
1465 #define GETDECAL( pass ) ( (Decal[pass]) )
1466 #define HASDECAL( pass ) ( ( (NUM_PASSES > pass) && Decal[pass] ) )
1467 #define SAFEDECAL( pass ) ( (HASDECAL( pass ) ? Decal[pass] : black) )
1469 void Mesh::ProcessFixedDrawQueue(
size_t techpass,
int whichdrawqueue,
bool zsort,
const QVector &sortctr )
1499 memset( Decal, 0,
sizeof (Decal) );
1544 std::vector< MeshDrawContext > &cur_draw_queue =
draw_queue[whichdrawqueue];
1545 if ( cur_draw_queue.empty() ) {
1546 static bool thiserrdone =
false;
1558 while ( (DecalSize > 0) &&
HASDECAL( DecalSize-1 ) )
1564 bool last_pass = !DecalSize;
1596 && ( (mat.
sr != 0) || (mat.
sg != 0)
1597 || (mat.
sb != 0) ) )
1599 bool skipglowpass =
false;
1600 bool nomultienv =
false;
1601 int nomultienv_passno = 0;
1608 nomultienv_passno = 0;
1610 nomultienv_passno = 1;
1614 while ( ( nomultienv && (whichpass ==
ENVSPEC_PASS) ) || !whichpass || (whichpass < DecalSize) ) {
1615 if ( !(nomultienv_passno >= 0 && nomultienv_passno <= 2) ) {
1616 static int errcount = 0;
1622 if ( (whichpass ==
GLOW_PASS) && skipglowpass ) {
1651 static std::vector< int >indices;
1653 indices.resize( cur_draw_queue.size() );
1654 for (
int i = 0, n = cur_draw_queue.size();
i < n; ++
i)
1656 std::sort( indices.begin(), indices.end(),
1660 for (
int i = 0, n = cur_draw_queue.size();
i < n; ++
i) {
1664 static vector< int >specialfxlight;
1677 specialfxlight.clear();
1681 for (
unsigned int j = 0;
j < c.
SpecialFX->size();
j++) {
1684 specialfxlight.push_back( ligh );
1689 specialfxlight.push_back( ligh );
1693 glEnable( GL_NORMALIZE );
1696 glDisable( GL_NORMALIZE );
1697 for (
unsigned int j = 0;
j < specialfxlight.size();
j++)
1731 if ( (nomultienv && whichpass == ENVSPEC_PASS) ||
HASDECAL( whichpass ) )
1736 if (whichpass == ENVSPEC_PASS) {
1742 }
else if ( DecalSize > (whichpass =
DAMAGE_PASS) ) {
1743 if (
HASDECAL( whichpass ) )
break;
1746 nomultienv_passno++;
1753 if ( DecalSize > (whichpass =
GLOW_PASS) )
1777 for (index = 0; index < xml->
logos.size(); index++) {
1778 if (xml->
logos[index].type == 0)
1780 if (xml->
logos[index].type == 1)
1784 Logo **tmplogo = NULL;
1796 float *sizes =
new float[nfl];
1797 float *rotations =
new float[nfl];
1798 float *offset =
new float[nfl];
1800 Vector norm1, norm2, norm;
1802 float totoffset = 0;
1803 for (
unsigned int ind = 0; ind < xml->
logos.size(); ind++)
1804 if (xml->
logos[ind].type == index) {
1806 norm1.Set( 0, 1, 0 );
1807 norm2.Set( 1, 0, 0 );
1808 if (xml->
logos[ind].refpnt.size() > 2) {
1809 if ( xml->
logos[ind].refpnt[0] < static_cast<int>(xml->
vertices.size())
1810 && xml->
logos[ind].refpnt[0] >= 0
1811 && xml->
logos[ind].refpnt[1] < static_cast<int>(xml->
vertices.size())
1812 && xml->
logos[ind].refpnt[1] >= 0
1813 && xml->
logos[ind].refpnt[2] < static_cast<int>(xml->
vertices.size())
1814 && xml->
logos[ind].refpnt[2] >= 0) {
1829 CrossProduct( norm2, norm1, norm );
1833 for (
unsigned int rj = 0; rj < xml->
logos[ind].refpnt.size(); rj++) {
1834 weight += xml->
logos[ind].refweight[rj];
1848 PolyNormal[ri] = norm;
1850 sizes[ri] = xml->
logos[ind].size*xml->
scale.k;
1851 rotations[ri] = xml->
logos[ind].rotate;
1852 offset[ri] = xml->
logos[ind].offset;
1853 totoffset += offset[ri];
1857 *tmplogo =
new Logo( nfl, center, PolyNormal, sizes, rotations, totoffset, Dec, Ref );
1859 delete[] PolyNormal;
1869 if ( xmltechnique.empty() ) {
1875 static string shader_technique =
vs_config->
getVariable(
"graphics",
"default_full_technique",
"mac" );
1877 static string shader_technique =
vs_config->
getVariable(
"graphics",
"default_full_technique",
"default" );
1879 effective = shader_technique;
1881 static string fixed_technique =
vs_config->
getVariable(
"graphics",
"default_simple_technique",
"fixed_simple" );
1882 effective = fixed_technique;