X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=plugins%2Fentity%2Flight.cpp;h=b447628f0f80930add66ab5fa3a1b90ab2566aad;hb=830125fad042fad35dc029b6eb57c8156ad7e176;hp=d1a30e14a3c6e8cc8ed7f283051f65137770ad92;hpb=515673c08f8718a237e90c2130a1f5294f966d6a;p=xonotic%2Fnetradiant.git diff --git a/plugins/entity/light.cpp b/plugins/entity/light.cpp index d1a30e14..b447628f 100644 --- a/plugins/entity/light.cpp +++ b/plugins/entity/light.cpp @@ -3,534 +3,533 @@ #include "entity.h" #include "light.h" -void DrawSphere(vec3_t center, float radius, int sides, int nGLState) -{ - int i, j; - float dt = (float) (2 * Q_PI / (float) sides); - float dp = (float) (Q_PI / (float) sides); - float t, p; - vec3_t v; - - if (radius <= 0) - return; - - g_QglTable.m_pfn_qglBegin(GL_TRIANGLES); - for (i = 0; i <= sides - 1; i++) { - for (j = 0; j <= sides - 2; j++) { - t = i * dt; - p = (float) ((j * dp) - (Q_PI / 2)); - - VectorPolar(v, radius, t, p); - VectorAdd(v, center, v); - g_QglTable.m_pfn_qglVertex3fv(v); - - VectorPolar(v, radius, t, p + dp); - VectorAdd(v, center, v); - g_QglTable.m_pfn_qglVertex3fv(v); - - VectorPolar(v, radius, t + dt, p + dp); - VectorAdd(v, center, v); - g_QglTable.m_pfn_qglVertex3fv(v); - - VectorPolar(v, radius, t, p); - VectorAdd(v, center, v); - g_QglTable.m_pfn_qglVertex3fv(v); - - VectorPolar(v, radius, t + dt, p + dp); - VectorAdd(v, center, v); - g_QglTable.m_pfn_qglVertex3fv(v); - - VectorPolar(v, radius, t + dt, p); - VectorAdd(v, center, v); - g_QglTable.m_pfn_qglVertex3fv(v); - } - } - - p = (float) ((sides - 1) * dp - (Q_PI / 2)); - for (i = 0; i <= sides - 1; i++) { - t = i * dt; - - VectorPolar(v, radius, t, p); - VectorAdd(v, center, v); - g_QglTable.m_pfn_qglVertex3fv(v); - - VectorPolar(v, radius, t + dt, p + dp); - VectorAdd(v, center, v); - g_QglTable.m_pfn_qglVertex3fv(v); - - VectorPolar(v, radius, t + dt, p); - VectorAdd(v, center, v); - g_QglTable.m_pfn_qglVertex3fv(v); - } - g_QglTable.m_pfn_qglEnd(); +void DrawSphere( vec3_t center, float radius, int sides, int nGLState ){ + int i, j; + float dt = (float) ( 2 * Q_PI / (float) sides ); + float dp = (float) ( Q_PI / (float) sides ); + float t, p; + vec3_t v; + + if ( radius <= 0 ) { + return; + } + + g_QglTable.m_pfn_qglBegin( GL_TRIANGLES ); + for ( i = 0; i <= sides - 1; i++ ) { + for ( j = 0; j <= sides - 2; j++ ) { + t = i * dt; + p = (float) ( ( j * dp ) - ( Q_PI / 2 ) ); + + VectorPolar( v, radius, t, p ); + VectorAdd( v, center, v ); + g_QglTable.m_pfn_qglVertex3fv( v ); + + VectorPolar( v, radius, t, p + dp ); + VectorAdd( v, center, v ); + g_QglTable.m_pfn_qglVertex3fv( v ); + + VectorPolar( v, radius, t + dt, p + dp ); + VectorAdd( v, center, v ); + g_QglTable.m_pfn_qglVertex3fv( v ); + + VectorPolar( v, radius, t, p ); + VectorAdd( v, center, v ); + g_QglTable.m_pfn_qglVertex3fv( v ); + + VectorPolar( v, radius, t + dt, p + dp ); + VectorAdd( v, center, v ); + g_QglTable.m_pfn_qglVertex3fv( v ); + + VectorPolar( v, radius, t + dt, p ); + VectorAdd( v, center, v ); + g_QglTable.m_pfn_qglVertex3fv( v ); + } + } + + p = (float) ( ( sides - 1 ) * dp - ( Q_PI / 2 ) ); + for ( i = 0; i <= sides - 1; i++ ) { + t = i * dt; + + VectorPolar( v, radius, t, p ); + VectorAdd( v, center, v ); + g_QglTable.m_pfn_qglVertex3fv( v ); + + VectorPolar( v, radius, t + dt, p + dp ); + VectorAdd( v, center, v ); + g_QglTable.m_pfn_qglVertex3fv( v ); + + VectorPolar( v, radius, t + dt, p ); + VectorAdd( v, center, v ); + g_QglTable.m_pfn_qglVertex3fv( v ); + } + g_QglTable.m_pfn_qglEnd(); } -#define LIGHT_ATTEN_LINEAR 1 -#define LIGHT_ATTEN_ANGLE 2 -#define LIGHT_ATTEN_DISTANCE 4 - -#define LIGHT_Q3A_DEFAULT (LIGHT_ATTEN_ANGLE | LIGHT_ATTEN_DISTANCE) -#define LIGHT_WOLF_DEFAULT (LIGHT_ATTEN_LINEAR | LIGHT_ATTEN_DISTANCE) - -float CalculateEnvelopeForLight(entity_t * e, float fFalloffTolerance) -{ - float fEnvelope = 0.f; - int iSpawnFlags = atoi(ValueForKey(e, "spawnflags")); - int iLightFlags = 0; - float fFade = 1.f; - float fIntensity, fPhotons; - float fScale; - const char *gameFile = g_FuncTable.m_pfnGetGameFile(); - - // These variables are tweakable on the q3map2 console, setting to q3map2 - // default here as there is no way to find out what the user actually uses - // right now. Maybe move them to worldspawn? - float fPointScale = 7500.f; - float fLinearScale = 1.f / 8000.f; - //float fFalloffTolerance = 1.f; // Need it as parameter - - // Arnout: HACK for per-game radii - really need to move this to a per-game module? - if( !strcmp( gameFile, "wolf.game" ) || !strcmp( gameFile, "et.game" ) ) { - // Spawnflags : - // 1: nonlinear - // 2: angle - - // set default flags - iLightFlags = LIGHT_WOLF_DEFAULT; - - // inverse distance squared attenuation? - if (iSpawnFlags & 1) { - iLightFlags &= ~LIGHT_ATTEN_LINEAR; - iLightFlags |= LIGHT_ATTEN_ANGLE; - } - // angle attenuate - if (iSpawnFlags & 2) - iLightFlags |= LIGHT_ATTEN_ANGLE; - } else { - // Spawnflags : - // 1: linear - // 2: no angle - - // set default flags - iLightFlags = LIGHT_Q3A_DEFAULT; - - // linear attenuation? - if (iSpawnFlags & 1) { - iLightFlags |= LIGHT_ATTEN_LINEAR; - iLightFlags &= ~LIGHT_ATTEN_ANGLE; - } - // no angle attenuate? - if (iSpawnFlags & 2) - iLightFlags &= ~LIGHT_ATTEN_ANGLE; - } - - // set fade key (from wolf) - if (iLightFlags & LIGHT_ATTEN_LINEAR) { - fFade = FloatForKey(e, "fade"); - if (fFade <= 0.f) - fFade = 1.f; - } - // set light intensity - fIntensity = FloatForKey(e, "_light"); - if (fIntensity == 0.f) - fIntensity = FloatForKey(e, "light"); - if (fIntensity == 0.f) - fIntensity = 300.f; - - // set light scale (sof2) - fScale = FloatForKey(e, "scale"); - if (fScale <= 0.f) - fScale = 1.f; - fIntensity *= fScale; - - // amount of photons - fPhotons = fIntensity * fPointScale; - - // calculate envelope - - // solve distance for non-distance lights - if (!(iLightFlags & LIGHT_ATTEN_DISTANCE)) - //!\todo (spog) can't access global objects in a module - globals are EVIL - solution: API for querying global settings. - fEnvelope = 131072/*g_MaxWorldCoord * 2.f*/; - // solve distance for linear lights - else if (iLightFlags & LIGHT_ATTEN_LINEAR) - fEnvelope = ((fPhotons * fLinearScale) - fFalloffTolerance) / fFade; - // solve for inverse square falloff - else - fEnvelope = sqrt(fPhotons / fFalloffTolerance) /* + fRadius */ ; // Arnout radius is always 0, only for area lights - - return fEnvelope; +#define LIGHT_ATTEN_LINEAR 1 +#define LIGHT_ATTEN_ANGLE 2 +#define LIGHT_ATTEN_DISTANCE 4 + +#define LIGHT_Q3A_DEFAULT ( LIGHT_ATTEN_ANGLE | LIGHT_ATTEN_DISTANCE ) +#define LIGHT_WOLF_DEFAULT ( LIGHT_ATTEN_LINEAR | LIGHT_ATTEN_DISTANCE ) + +float CalculateEnvelopeForLight( entity_t * e, float fFalloffTolerance ){ + float fEnvelope = 0.f; + int iSpawnFlags = atoi( ValueForKey( e, "spawnflags" ) ); + int iLightFlags = 0; + float fFade = 1.f; + float fIntensity, fPhotons; + float fScale; + const char *gameFile = g_FuncTable.m_pfnGetGameFile(); + + // These variables are tweakable on the q3map2 console, setting to q3map2 + // default here as there is no way to find out what the user actually uses + // right now. Maybe move them to worldspawn? + float fPointScale = 7500.f; + float fLinearScale = 1.f / 8000.f; + //float fFalloffTolerance = 1.f; // Need it as parameter + + // Arnout: HACK for per-game radii - really need to move this to a per-game module? + if ( !strcmp( gameFile, "wolf.game" ) || !strcmp( gameFile, "et.game" ) ) { + // Spawnflags : + // 1: nonlinear + // 2: angle + + // set default flags + iLightFlags = LIGHT_WOLF_DEFAULT; + + // inverse distance squared attenuation? + if ( iSpawnFlags & 1 ) { + iLightFlags &= ~LIGHT_ATTEN_LINEAR; + iLightFlags |= LIGHT_ATTEN_ANGLE; + } + // angle attenuate + if ( iSpawnFlags & 2 ) { + iLightFlags |= LIGHT_ATTEN_ANGLE; + } + } + else { + // Spawnflags : + // 1: linear + // 2: no angle + + // set default flags + iLightFlags = LIGHT_Q3A_DEFAULT; + + // linear attenuation? + if ( iSpawnFlags & 1 ) { + iLightFlags |= LIGHT_ATTEN_LINEAR; + iLightFlags &= ~LIGHT_ATTEN_ANGLE; + } + // no angle attenuate? + if ( iSpawnFlags & 2 ) { + iLightFlags &= ~LIGHT_ATTEN_ANGLE; + } + } + + // set fade key (from wolf) + if ( iLightFlags & LIGHT_ATTEN_LINEAR ) { + fFade = FloatForKey( e, "fade" ); + if ( fFade <= 0.f ) { + fFade = 1.f; + } + } + // set light intensity + fIntensity = FloatForKey( e, "_light" ); + if ( fIntensity == 0.f ) { + fIntensity = FloatForKey( e, "light" ); + } + if ( fIntensity == 0.f ) { + fIntensity = 300.f; + } + + // set light scale (sof2) + fScale = FloatForKey( e, "scale" ); + if ( fScale <= 0.f ) { + fScale = 1.f; + } + fIntensity *= fScale; + + // amount of photons + fPhotons = fIntensity * fPointScale; + + // calculate envelope + + // solve distance for non-distance lights + if ( !( iLightFlags & LIGHT_ATTEN_DISTANCE ) ) { + //!\todo (spog) can't access global objects in a module - globals are EVIL - solution: API for querying global settings. + fEnvelope = 131072 /*g_MaxWorldCoord * 2.f*/; + } + // solve distance for linear lights + else if ( iLightFlags & LIGHT_ATTEN_LINEAR ) { + fEnvelope = ( ( fPhotons * fLinearScale ) - fFalloffTolerance ) / fFade; + } + // solve for inverse square falloff + else{ + fEnvelope = sqrt( fPhotons / fFalloffTolerance ) /* + fRadius */ ; // Arnout radius is always 0, only for area lights + + } + return fEnvelope; } -float CalculateLightRadius(entity_t * e, bool outer) -{ - float fEnvelope = 0.f; - int iSpawnFlags = atoi(ValueForKey(e, "spawnflags")); - float fIntensity; - float fScale; - const char *gameFile = g_FuncTable.m_pfnGetGameFile(); - - fIntensity = FloatForKey(e, "light"); - if (fIntensity == 0.f) - fIntensity = 300.f; - - // Arnout: HACK for per-game radii - really need to move this to a per-game module - if( !strcmp( gameFile, "sof2.game" ) || !strcmp( gameFile, "jk2.game" ) || !strcmp( gameFile, "ja.game" )) { - // Spawnflags : - // 1: linear - // 2: noincidence - - if (!outer) { - if (iSpawnFlags & 2) - fIntensity *= .9f; - else - fIntensity *= .25f; - } - // set light scale (sof2) - fScale = FloatForKey(e, "scale"); - if (fScale <= 0.f) - fScale = 1.f; - fIntensity *= fScale; - - fEnvelope = fIntensity; - } else { - float fPointScale = 7500.f; - - if (outer) - fEnvelope = sqrt(fIntensity * fPointScale / 48.f); - else - fEnvelope = sqrt(fIntensity * fPointScale / 255.f); - } - - return fEnvelope; +float CalculateLightRadius( entity_t * e, bool outer ){ + float fEnvelope = 0.f; + int iSpawnFlags = atoi( ValueForKey( e, "spawnflags" ) ); + float fIntensity; + float fScale; + const char *gameFile = g_FuncTable.m_pfnGetGameFile(); + + fIntensity = FloatForKey( e, "light" ); + if ( fIntensity == 0.f ) { + fIntensity = 300.f; + } + + // Arnout: HACK for per-game radii - really need to move this to a per-game module + if ( !strcmp( gameFile, "sof2.game" ) || !strcmp( gameFile, "jk2.game" ) || !strcmp( gameFile, "ja.game" ) ) { + // Spawnflags : + // 1: linear + // 2: noincidence + + if ( !outer ) { + if ( iSpawnFlags & 2 ) { + fIntensity *= .9f; + } + else{ + fIntensity *= .25f; + } + } + // set light scale (sof2) + fScale = FloatForKey( e, "scale" ); + if ( fScale <= 0.f ) { + fScale = 1.f; + } + fIntensity *= fScale; + + fEnvelope = fIntensity; + } + else { + float fPointScale = 7500.f; + + if ( outer ) { + fEnvelope = sqrt( fIntensity * fPointScale / 48.f ); + } + else{ + fEnvelope = sqrt( fIntensity * fPointScale / 255.f ); + } + } + + return fEnvelope; } -void Light_OnIntensityChanged(entity_t* e) -{ - e->fLightEnvelope1[0] = CalculateEnvelopeForLight(e, 1.f); - e->fLightEnvelope1[1] = CalculateEnvelopeForLight(e, 48.f); - e->fLightEnvelope1[2] = CalculateEnvelopeForLight(e, 255.f); +void Light_OnIntensityChanged( entity_t* e ){ + e->fLightEnvelope1[0] = CalculateEnvelopeForLight( e, 1.f ); + e->fLightEnvelope1[1] = CalculateEnvelopeForLight( e, 48.f ); + e->fLightEnvelope1[2] = CalculateEnvelopeForLight( e, 255.f ); - e->fLightEnvelope2[0] = CalculateLightRadius(e, TRUE); - e->fLightEnvelope2[1] = CalculateLightRadius(e, FALSE); + e->fLightEnvelope2[0] = CalculateLightRadius( e, TRUE ); + e->fLightEnvelope2[1] = CalculateLightRadius( e, FALSE ); } -void Light_OnKeyValueChanged(entity_t *e, const char *key, const char* value) -{ - if(strcmp(key,"_color") == 0) - { - if (sscanf(ValueForKey(e, "_color"),"%f %f %f", - &e->color[0], &e->color[1], &e->color[2]) != 3) - VectorSet(e->color, 1, 1, 1); - } - else if(strcmp(key,"spawnflags") == 0 || - strcmp(key,"fade") == 0 || - strcmp(key,"_light") == 0 || - strcmp(key,"light") == 0 || - strcmp(key,"scale") == 0) - { - Light_OnIntensityChanged(e); - } +void Light_OnKeyValueChanged( entity_t *e, const char *key, const char* value ){ + if ( strcmp( key,"_color" ) == 0 ) { + if ( sscanf( ValueForKey( e, "_color" ),"%f %f %f", + &e->color[0], &e->color[1], &e->color[2] ) != 3 ) { + VectorSet( e->color, 1, 1, 1 ); + } + } + else if ( strcmp( key,"spawnflags" ) == 0 || + strcmp( key,"fade" ) == 0 || + strcmp( key,"_light" ) == 0 || + strcmp( key,"light" ) == 0 || + strcmp( key,"scale" ) == 0 ) { + Light_OnIntensityChanged( e ); + } } -bool Entity_IsLight(entity_t *e) -{ - return e->eclass != NULL && e->eclass->nShowFlags & ECLASS_LIGHT;//strncmp(ValueforKey(e, "classname"), "light") == 0 +bool Entity_IsLight( entity_t *e ){ + return e->eclass != NULL && e->eclass->nShowFlags & ECLASS_LIGHT; //strncmp(ValueforKey(e, "classname"), "light") == 0 } -static void DrawLightSphere(entity_t * e, int nGLState, int pref) -{ - const char *target = ValueForKey(e, "target"); - bool bIsSpotLight = !!target[0]; - //!\todo Write an API for modules to register preference settings, and make this preference module-specific. - // int nPasses = pref == 1 ? 3 : 2; - - g_QglTable.m_pfn_qglPushAttrib(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - g_QglTable.m_pfn_qglDepthMask(GL_FALSE); - g_QglTable.m_pfn_qglEnable(GL_BLEND); - g_QglTable.m_pfn_qglBlendFunc(GL_ONE, GL_ONE); - - // Arnout: TODO: spotlight rendering - if (!(bIsSpotLight)) - { - switch(pref) - { - case 1: - g_QglTable.m_pfn_qglColor3f(e->color[0] * .05f, - e->color[1] * .05f, - e->color[2] * .05f); - DrawSphere(e->origin, e->fLightEnvelope1[0], 16, nGLState); - DrawSphere(e->origin, e->fLightEnvelope1[1], 16, nGLState); - DrawSphere(e->origin, e->fLightEnvelope1[2], 16, nGLState); - break; - case 2: - g_QglTable.m_pfn_qglColor3f(e->color[0] * .15f * .95f, - e->color[1] * .15f * .95f, - e->color[2] * .15f * .95f); - DrawSphere(e->origin, e->fLightEnvelope2[0], 16, nGLState); - DrawSphere(e->origin, e->fLightEnvelope2[1], 16, nGLState); - break; - - } - } - - g_QglTable.m_pfn_qglPopAttrib(); +static void DrawLightSphere( entity_t * e, int nGLState, int pref ){ + const char *target = ValueForKey( e, "target" ); + bool bIsSpotLight = !!target[0]; + //!\todo Write an API for modules to register preference settings, and make this preference module-specific. + // int nPasses = pref == 1 ? 3 : 2; + + g_QglTable.m_pfn_qglPushAttrib( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); + g_QglTable.m_pfn_qglDepthMask( GL_FALSE ); + g_QglTable.m_pfn_qglEnable( GL_BLEND ); + g_QglTable.m_pfn_qglBlendFunc( GL_ONE, GL_ONE ); + + // Arnout: TODO: spotlight rendering + if ( !( bIsSpotLight ) ) { + switch ( pref ) + { + case 1: + g_QglTable.m_pfn_qglColor3f( e->color[0] * .05f, + e->color[1] * .05f, + e->color[2] * .05f ); + DrawSphere( e->origin, e->fLightEnvelope1[0], 16, nGLState ); + DrawSphere( e->origin, e->fLightEnvelope1[1], 16, nGLState ); + DrawSphere( e->origin, e->fLightEnvelope1[2], 16, nGLState ); + break; + case 2: + g_QglTable.m_pfn_qglColor3f( e->color[0] * .15f * .95f, + e->color[1] * .15f * .95f, + e->color[2] * .15f * .95f ); + DrawSphere( e->origin, e->fLightEnvelope2[0], 16, nGLState ); + DrawSphere( e->origin, e->fLightEnvelope2[1], 16, nGLState ); + break; + + } + } + + g_QglTable.m_pfn_qglPopAttrib(); } float F = 0.70710678f; // North, East, South, West vec3_t normals[8] = { { 0, F, F }, { F, 0, F }, { 0,-F, F }, {-F, 0, F }, - { 0, F,-F }, { F, 0,-F }, { 0,-F,-F }, {-F, 0,-F } }; + { 0, F,-F }, { F, 0,-F }, { 0,-F,-F }, {-F, 0,-F } }; unsigned short indices[24] = { 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 2, - 1, 2, 5, 1, 5, 4, 1, 4, 3, 1, 3, 2 }; + 1, 2, 5, 1, 5, 4, 1, 4, 3, 1, 3, 2 }; -void DrawLight(entity_t* e, int nGLState, int pref, int nViewType) -{ +void DrawLight( entity_t* e, int nGLState, int pref, int nViewType ){ // int i; - // top, bottom, tleft, tright, bright, bleft - vec3_t points[6]; - vec3_t vMid, vMin, vMax; - VectorAdd(e->origin, e->eclass->mins, vMin); - VectorAdd(e->origin, e->eclass->maxs, vMax); - vMid[0] = (vMin[0] + vMax[0]) * 0.5; - vMid[1] = (vMin[1] + vMax[1]) * 0.5; - vMid[2] = (vMin[2] + vMax[2]) * 0.5; - - VectorSet(points[0], vMid[0], vMid[1], vMax[2]); - VectorSet(points[1], vMid[0], vMid[1], vMin[2]); - VectorSet(points[2], vMin[0], vMax[1], vMid[2]); - VectorSet(points[3], vMax[0], vMax[1], vMid[2]); - VectorSet(points[4], vMax[0], vMin[1], vMid[2]); - VectorSet(points[5], vMin[0], vMin[1], vMid[2]); - - if (nGLState & DRAW_GL_LIGHTING)// && g_PrefsDlg.m_bGLLighting) - { - g_QglTable.m_pfn_qglBegin(GL_TRIANGLES);// NOTE: comment to use gl_triangle_fan instead - //g_QglTable.m_pfn_qglBegin(GL_TRIANGLE_FAN); - g_QglTable.m_pfn_qglVertex3fv(points[0]); - g_QglTable.m_pfn_qglVertex3fv(points[2]); - g_QglTable.m_pfn_qglNormal3fv(normals[0]); - g_QglTable.m_pfn_qglVertex3fv(points[3]); - - g_QglTable.m_pfn_qglVertex3fv(points[0]);// - g_QglTable.m_pfn_qglVertex3fv(points[3]);// - g_QglTable.m_pfn_qglNormal3fv(normals[1]); - g_QglTable.m_pfn_qglVertex3fv(points[4]); - - g_QglTable.m_pfn_qglVertex3fv(points[0]);// - g_QglTable.m_pfn_qglVertex3fv(points[4]);// - g_QglTable.m_pfn_qglNormal3fv(normals[2]); - g_QglTable.m_pfn_qglVertex3fv(points[5]); - - g_QglTable.m_pfn_qglVertex3fv(points[0]);// - g_QglTable.m_pfn_qglVertex3fv(points[5]);// - g_QglTable.m_pfn_qglNormal3fv(normals[3]); - g_QglTable.m_pfn_qglVertex3fv(points[2]); - - //g_QglTable.m_pfn_qglEnd(); - //g_QglTable.m_pfn_qglBegin(GL_TRIANGLE_FAN); - - g_QglTable.m_pfn_qglVertex3fv(points[1]); - g_QglTable.m_pfn_qglVertex3fv(points[2]); - g_QglTable.m_pfn_qglNormal3fv(normals[7]); - g_QglTable.m_pfn_qglVertex3fv(points[5]); - - g_QglTable.m_pfn_qglVertex3fv(points[1]);// - g_QglTable.m_pfn_qglVertex3fv(points[5]);// - g_QglTable.m_pfn_qglNormal3fv(normals[6]); - g_QglTable.m_pfn_qglVertex3fv(points[4]); - - g_QglTable.m_pfn_qglVertex3fv(points[1]);// - g_QglTable.m_pfn_qglVertex3fv(points[4]);// - g_QglTable.m_pfn_qglNormal3fv(normals[5]); - g_QglTable.m_pfn_qglVertex3fv(points[3]); - - g_QglTable.m_pfn_qglVertex3fv(points[1]);// - g_QglTable.m_pfn_qglVertex3fv(points[3]);// - g_QglTable.m_pfn_qglNormal3fv(normals[4]); - g_QglTable.m_pfn_qglVertex3fv(points[2]); - - g_QglTable.m_pfn_qglEnd(); - } - else if (nGLState & DRAW_GL_FILL) - { - vec3_t colors[4]; - VectorScale(e->color, 0.95, colors[0]); - VectorScale(colors[0], 0.95, colors[1]); - VectorScale(colors[1], 0.95, colors[2]); - VectorScale(colors[2], 0.95, colors[3]); - g_QglTable.m_pfn_qglBegin(GL_TRIANGLES);// NOTE: comment to use gl_triangle_fan instead - //g_QglTable.m_pfn_qglBegin(GL_TRIANGLE_FAN); - g_QglTable.m_pfn_qglColor3fv(colors[0]); - g_QglTable.m_pfn_qglVertex3fv(points[0]); - g_QglTable.m_pfn_qglVertex3fv(points[2]); - g_QglTable.m_pfn_qglVertex3fv(points[3]); - - g_QglTable.m_pfn_qglColor3fv(colors[1]); - g_QglTable.m_pfn_qglVertex3fv(points[0]);// - g_QglTable.m_pfn_qglVertex3fv(points[3]);// - g_QglTable.m_pfn_qglVertex3fv(points[4]); - - g_QglTable.m_pfn_qglColor3fv(colors[2]); - g_QglTable.m_pfn_qglVertex3fv(points[0]);// - g_QglTable.m_pfn_qglVertex3fv(points[4]);// - g_QglTable.m_pfn_qglVertex3fv(points[5]); - - g_QglTable.m_pfn_qglColor3fv(colors[3]); - g_QglTable.m_pfn_qglVertex3fv(points[0]);// - g_QglTable.m_pfn_qglVertex3fv(points[5]);// - g_QglTable.m_pfn_qglVertex3fv(points[2]); - - //g_QglTable.m_pfn_qglEnd(); - //g_QglTable.m_pfn_qglBegin(GL_TRIANGLE_FAN); - - g_QglTable.m_pfn_qglColor3fv(colors[0]); - g_QglTable.m_pfn_qglVertex3fv(points[1]); - g_QglTable.m_pfn_qglVertex3fv(points[2]); - g_QglTable.m_pfn_qglVertex3fv(points[5]); - - g_QglTable.m_pfn_qglColor3fv(colors[1]); - g_QglTable.m_pfn_qglVertex3fv(points[1]);// - g_QglTable.m_pfn_qglVertex3fv(points[5]);// - g_QglTable.m_pfn_qglVertex3fv(points[4]); - - g_QglTable.m_pfn_qglColor3fv(colors[2]); - g_QglTable.m_pfn_qglVertex3fv(points[1]);// - g_QglTable.m_pfn_qglVertex3fv(points[4]);// - g_QglTable.m_pfn_qglVertex3fv(points[3]); - - g_QglTable.m_pfn_qglColor3fv(colors[3]); - g_QglTable.m_pfn_qglVertex3fv(points[1]);// - g_QglTable.m_pfn_qglVertex3fv(points[3]);// - g_QglTable.m_pfn_qglVertex3fv(points[2]); - - g_QglTable.m_pfn_qglEnd(); - } - else - { - g_QglTable.m_pfn_qglVertexPointer(3, GL_FLOAT, 0, points); - g_QglTable.m_pfn_qglDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, indices); - } - - - // NOTE: prolly not relevant until some time.. - // check for DOOM lights - if (strlen(ValueForKey(e, "light_right")) > 0) { - vec3_t vRight, vUp, vTarget, vTemp; - GetVectorForKey (e, "light_right", vRight); - GetVectorForKey (e, "light_up", vUp); - GetVectorForKey (e, "light_target", vTarget); - - g_QglTable.m_pfn_qglColor3f(0, 1, 0); - g_QglTable.m_pfn_qglBegin(GL_LINE_LOOP); - VectorAdd(vTarget, e->origin, vTemp); - VectorAdd(vTemp, vRight, vTemp); - VectorAdd(vTemp, vUp, vTemp); - g_QglTable.m_pfn_qglVertex3fv(e->origin); - g_QglTable.m_pfn_qglVertex3fv(vTemp); - VectorAdd(vTarget, e->origin, vTemp); - VectorAdd(vTemp, vUp, vTemp); - VectorSubtract(vTemp, vRight, vTemp); - g_QglTable.m_pfn_qglVertex3fv(e->origin); - g_QglTable.m_pfn_qglVertex3fv(vTemp); - VectorAdd(vTarget, e->origin, vTemp); - VectorAdd(vTemp, vRight, vTemp); - VectorSubtract(vTemp, vUp, vTemp); - g_QglTable.m_pfn_qglVertex3fv(e->origin); - g_QglTable.m_pfn_qglVertex3fv(vTemp); - VectorAdd(vTarget, e->origin, vTemp); - VectorSubtract(vTemp, vUp, vTemp); - VectorSubtract(vTemp, vRight, vTemp); - g_QglTable.m_pfn_qglVertex3fv(e->origin); - g_QglTable.m_pfn_qglVertex3fv(vTemp); - g_QglTable.m_pfn_qglEnd(); - - } - - if(nGLState & DRAW_GL_FILL) - { - DrawLightSphere(e, nGLState, pref); - } - else - { - // Arnout: FIXME: clean this up a bit - // now draw lighting radius stuff... - if (pref) - { - bool bDrawSpotlightArc = false; - int nPasses = pref == 1 ? 3 : 2; - - const char *target = ValueForKey(e, "target"); - bool bIsSpotLight = !!target[0]; - - /*!\todo Spotlight.. - if (bIsSpotLight) - { - // find the origin of the target... - entity_t *e = FindEntity("targetname", target); - - if (e) - bDrawSpotlightArc = true; - } - */ - - g_QglTable.m_pfn_qglPushAttrib(GL_LINE_BIT); - g_QglTable.m_pfn_qglLineStipple(8, 0xAAAA); - g_QglTable.m_pfn_qglEnable(GL_LINE_STIPPLE); - - float* envelope = (pref == 1) ? e->fLightEnvelope1 : e->fLightEnvelope2; - for (int iPass = 0; iPass < nPasses; iPass++) - { - float fRadius = envelope[iPass]; - - g_QglTable.m_pfn_qglBegin(GL_LINE_LOOP); - - if (bIsSpotLight) - { - if (bDrawSpotlightArc) - { - // I give up on this, it's beyond me - } - } - else - { - if (fRadius > 0) - { - int i; - float ds, dc; - - for (i = 0; i <= 24; i++) - { - ds = sin((i * 2 * Q_PI) / 24); - dc = cos((i * 2 * Q_PI) / 24); - - switch (nViewType) - { - case 2: - g_QglTable.m_pfn_qglVertex3f(e->origin[0] + fRadius * dc, - e->origin[1] + fRadius * ds, - e->origin[2]); - break; - case 1: - g_QglTable.m_pfn_qglVertex3f(e->origin[0] + fRadius * dc, - e->origin[1], - e->origin[2] + fRadius * ds); - break; - case 0: - g_QglTable.m_pfn_qglVertex3f(e->origin[0], - e->origin[1] + fRadius * dc, - e->origin[2] + fRadius * ds); - break; - } - } - } - } - g_QglTable.m_pfn_qglEnd(); - } - g_QglTable.m_pfn_qglPopAttrib(); - } - } + // top, bottom, tleft, tright, bright, bleft + vec3_t points[6]; + vec3_t vMid, vMin, vMax; + VectorAdd( e->origin, e->eclass->mins, vMin ); + VectorAdd( e->origin, e->eclass->maxs, vMax ); + vMid[0] = ( vMin[0] + vMax[0] ) * 0.5; + vMid[1] = ( vMin[1] + vMax[1] ) * 0.5; + vMid[2] = ( vMin[2] + vMax[2] ) * 0.5; + + VectorSet( points[0], vMid[0], vMid[1], vMax[2] ); + VectorSet( points[1], vMid[0], vMid[1], vMin[2] ); + VectorSet( points[2], vMin[0], vMax[1], vMid[2] ); + VectorSet( points[3], vMax[0], vMax[1], vMid[2] ); + VectorSet( points[4], vMax[0], vMin[1], vMid[2] ); + VectorSet( points[5], vMin[0], vMin[1], vMid[2] ); + + if ( nGLState & DRAW_GL_LIGHTING ) { // && g_PrefsDlg.m_bGLLighting) + g_QglTable.m_pfn_qglBegin( GL_TRIANGLES ); // NOTE: comment to use gl_triangle_fan instead + //g_QglTable.m_pfn_qglBegin(GL_TRIANGLE_FAN); + g_QglTable.m_pfn_qglVertex3fv( points[0] ); + g_QglTable.m_pfn_qglVertex3fv( points[2] ); + g_QglTable.m_pfn_qglNormal3fv( normals[0] ); + g_QglTable.m_pfn_qglVertex3fv( points[3] ); + + g_QglTable.m_pfn_qglVertex3fv( points[0] ); // + g_QglTable.m_pfn_qglVertex3fv( points[3] ); // + g_QglTable.m_pfn_qglNormal3fv( normals[1] ); + g_QglTable.m_pfn_qglVertex3fv( points[4] ); + + g_QglTable.m_pfn_qglVertex3fv( points[0] ); // + g_QglTable.m_pfn_qglVertex3fv( points[4] ); // + g_QglTable.m_pfn_qglNormal3fv( normals[2] ); + g_QglTable.m_pfn_qglVertex3fv( points[5] ); + + g_QglTable.m_pfn_qglVertex3fv( points[0] ); // + g_QglTable.m_pfn_qglVertex3fv( points[5] ); // + g_QglTable.m_pfn_qglNormal3fv( normals[3] ); + g_QglTable.m_pfn_qglVertex3fv( points[2] ); + + //g_QglTable.m_pfn_qglEnd(); + //g_QglTable.m_pfn_qglBegin(GL_TRIANGLE_FAN); + + g_QglTable.m_pfn_qglVertex3fv( points[1] ); + g_QglTable.m_pfn_qglVertex3fv( points[2] ); + g_QglTable.m_pfn_qglNormal3fv( normals[7] ); + g_QglTable.m_pfn_qglVertex3fv( points[5] ); + + g_QglTable.m_pfn_qglVertex3fv( points[1] ); // + g_QglTable.m_pfn_qglVertex3fv( points[5] ); // + g_QglTable.m_pfn_qglNormal3fv( normals[6] ); + g_QglTable.m_pfn_qglVertex3fv( points[4] ); + + g_QglTable.m_pfn_qglVertex3fv( points[1] ); // + g_QglTable.m_pfn_qglVertex3fv( points[4] ); // + g_QglTable.m_pfn_qglNormal3fv( normals[5] ); + g_QglTable.m_pfn_qglVertex3fv( points[3] ); + + g_QglTable.m_pfn_qglVertex3fv( points[1] ); // + g_QglTable.m_pfn_qglVertex3fv( points[3] ); // + g_QglTable.m_pfn_qglNormal3fv( normals[4] ); + g_QglTable.m_pfn_qglVertex3fv( points[2] ); + + g_QglTable.m_pfn_qglEnd(); + } + else if ( nGLState & DRAW_GL_FILL ) { + vec3_t colors[4]; + VectorScale( e->color, 0.95, colors[0] ); + VectorScale( colors[0], 0.95, colors[1] ); + VectorScale( colors[1], 0.95, colors[2] ); + VectorScale( colors[2], 0.95, colors[3] ); + g_QglTable.m_pfn_qglBegin( GL_TRIANGLES ); // NOTE: comment to use gl_triangle_fan instead + //g_QglTable.m_pfn_qglBegin(GL_TRIANGLE_FAN); + g_QglTable.m_pfn_qglColor3fv( colors[0] ); + g_QglTable.m_pfn_qglVertex3fv( points[0] ); + g_QglTable.m_pfn_qglVertex3fv( points[2] ); + g_QglTable.m_pfn_qglVertex3fv( points[3] ); + + g_QglTable.m_pfn_qglColor3fv( colors[1] ); + g_QglTable.m_pfn_qglVertex3fv( points[0] ); // + g_QglTable.m_pfn_qglVertex3fv( points[3] ); // + g_QglTable.m_pfn_qglVertex3fv( points[4] ); + + g_QglTable.m_pfn_qglColor3fv( colors[2] ); + g_QglTable.m_pfn_qglVertex3fv( points[0] ); // + g_QglTable.m_pfn_qglVertex3fv( points[4] ); // + g_QglTable.m_pfn_qglVertex3fv( points[5] ); + + g_QglTable.m_pfn_qglColor3fv( colors[3] ); + g_QglTable.m_pfn_qglVertex3fv( points[0] ); // + g_QglTable.m_pfn_qglVertex3fv( points[5] ); // + g_QglTable.m_pfn_qglVertex3fv( points[2] ); + + //g_QglTable.m_pfn_qglEnd(); + //g_QglTable.m_pfn_qglBegin(GL_TRIANGLE_FAN); + + g_QglTable.m_pfn_qglColor3fv( colors[0] ); + g_QglTable.m_pfn_qglVertex3fv( points[1] ); + g_QglTable.m_pfn_qglVertex3fv( points[2] ); + g_QglTable.m_pfn_qglVertex3fv( points[5] ); + + g_QglTable.m_pfn_qglColor3fv( colors[1] ); + g_QglTable.m_pfn_qglVertex3fv( points[1] ); // + g_QglTable.m_pfn_qglVertex3fv( points[5] ); // + g_QglTable.m_pfn_qglVertex3fv( points[4] ); + + g_QglTable.m_pfn_qglColor3fv( colors[2] ); + g_QglTable.m_pfn_qglVertex3fv( points[1] ); // + g_QglTable.m_pfn_qglVertex3fv( points[4] ); // + g_QglTable.m_pfn_qglVertex3fv( points[3] ); + + g_QglTable.m_pfn_qglColor3fv( colors[3] ); + g_QglTable.m_pfn_qglVertex3fv( points[1] ); // + g_QglTable.m_pfn_qglVertex3fv( points[3] ); // + g_QglTable.m_pfn_qglVertex3fv( points[2] ); + + g_QglTable.m_pfn_qglEnd(); + } + else + { + g_QglTable.m_pfn_qglVertexPointer( 3, GL_FLOAT, 0, points ); + g_QglTable.m_pfn_qglDrawElements( GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, indices ); + } + + + // NOTE: prolly not relevant until some time.. + // check for DOOM lights + if ( strlen( ValueForKey( e, "light_right" ) ) > 0 ) { + vec3_t vRight, vUp, vTarget, vTemp; + GetVectorForKey( e, "light_right", vRight ); + GetVectorForKey( e, "light_up", vUp ); + GetVectorForKey( e, "light_target", vTarget ); + + g_QglTable.m_pfn_qglColor3f( 0, 1, 0 ); + g_QglTable.m_pfn_qglBegin( GL_LINE_LOOP ); + VectorAdd( vTarget, e->origin, vTemp ); + VectorAdd( vTemp, vRight, vTemp ); + VectorAdd( vTemp, vUp, vTemp ); + g_QglTable.m_pfn_qglVertex3fv( e->origin ); + g_QglTable.m_pfn_qglVertex3fv( vTemp ); + VectorAdd( vTarget, e->origin, vTemp ); + VectorAdd( vTemp, vUp, vTemp ); + VectorSubtract( vTemp, vRight, vTemp ); + g_QglTable.m_pfn_qglVertex3fv( e->origin ); + g_QglTable.m_pfn_qglVertex3fv( vTemp ); + VectorAdd( vTarget, e->origin, vTemp ); + VectorAdd( vTemp, vRight, vTemp ); + VectorSubtract( vTemp, vUp, vTemp ); + g_QglTable.m_pfn_qglVertex3fv( e->origin ); + g_QglTable.m_pfn_qglVertex3fv( vTemp ); + VectorAdd( vTarget, e->origin, vTemp ); + VectorSubtract( vTemp, vUp, vTemp ); + VectorSubtract( vTemp, vRight, vTemp ); + g_QglTable.m_pfn_qglVertex3fv( e->origin ); + g_QglTable.m_pfn_qglVertex3fv( vTemp ); + g_QglTable.m_pfn_qglEnd(); + + } + + if ( nGLState & DRAW_GL_FILL ) { + DrawLightSphere( e, nGLState, pref ); + } + else + { + // Arnout: FIXME: clean this up a bit + // now draw lighting radius stuff... + if ( pref ) { + bool bDrawSpotlightArc = false; + int nPasses = pref == 1 ? 3 : 2; + + const char *target = ValueForKey( e, "target" ); + bool bIsSpotLight = !!target[0]; + + /*!\todo Spotlight.. + if (bIsSpotLight) + { + // find the origin of the target... + entity_t *e = FindEntity("targetname", target); + + if (e) + bDrawSpotlightArc = true; + } + */ + + g_QglTable.m_pfn_qglPushAttrib( GL_LINE_BIT ); + g_QglTable.m_pfn_qglLineStipple( 8, 0xAAAA ); + g_QglTable.m_pfn_qglEnable( GL_LINE_STIPPLE ); + + float* envelope = ( pref == 1 ) ? e->fLightEnvelope1 : e->fLightEnvelope2; + for ( int iPass = 0; iPass < nPasses; iPass++ ) + { + float fRadius = envelope[iPass]; + + g_QglTable.m_pfn_qglBegin( GL_LINE_LOOP ); + + if ( bIsSpotLight ) { + if ( bDrawSpotlightArc ) { + // I give up on this, it's beyond me + } + } + else + { + if ( fRadius > 0 ) { + int i; + float ds, dc; + + for ( i = 0; i <= 24; i++ ) + { + ds = sin( ( i * 2 * Q_PI ) / 24 ); + dc = cos( ( i * 2 * Q_PI ) / 24 ); + + switch ( nViewType ) + { + case 2: + g_QglTable.m_pfn_qglVertex3f( e->origin[0] + fRadius * dc, + e->origin[1] + fRadius * ds, + e->origin[2] ); + break; + case 1: + g_QglTable.m_pfn_qglVertex3f( e->origin[0] + fRadius * dc, + e->origin[1], + e->origin[2] + fRadius * ds ); + break; + case 0: + g_QglTable.m_pfn_qglVertex3f( e->origin[0], + e->origin[1] + fRadius * dc, + e->origin[2] + fRadius * ds ); + break; + } + } + } + } + g_QglTable.m_pfn_qglEnd(); + } + g_QglTable.m_pfn_qglPopAttrib(); + } + } } - -