#include "glb_local.h" #include "renderer/qfx_library.h" #include "renderer/qfx_log.h" #include "renderer/qfx_settings.h" #include "renderer/qfx_opengl.h" #include "renderer/qfx_renderer.h" #include "renderer/qfx_shader.h" #include "renderer/qfx_glprogs.h" #include "script/centity.h" #include "script/cplayer.h" #include "script.h" #include "scriptmaster.h" #include "scripttimer.h" #include "script/vision.h" #include "img/IMAGE.h" #include "img/TORUS.h" #define WANT_OPENGL #include #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "glu32.lib") effect_t *effect_list[MAX_EFFECTS]; qboolean render_inited = false; GLuint m_pBloomBlurShader = 0; GLuint m_pBloomCombineShader = 0; GLuint m_pBloomDarkenShader = 0; GLuint m_uiBlurTexture = 0; GLuint m_uiDesaturationTexture = 0; GLuint m_uiInvertTexture = 0; GLuint m_uiDarkTexture = 0; GLuint m_uiLightTexture = 0; /*float vision_fadeTime = 0.0f; str vision_current; float vision_currentTime = 0.0f; float vision_currentTime2 = 0.0f;*/ cvar_t *r_debug; cvar_t *r_dof; cvar_t *r_texFilterAniso; cvar_t *r_tweakBlurX; cvar_t *r_tweakBlurY; cvar_t *r_tweakBlurPasses; cvar_t *r_glowEnable; cvar_t *r_glowQuality; cvar_t *r_glowSamples; cvar_t *r_ssao; cvar_t *r_autoluminance; cvar_t *r_fxaa; cvar_t *r_test_color; cvar_t *r_test_bump; // Vision variables // CANNOT BE MODIFIED FROM CONSOLE ! ScriptTimer m_blurTimer( TIMER_NORMAL ); ScriptTimer m_visionTimer( TIMER_GLIDE ); Container< VisionClass * > m_visionVar; VisionActivator r_anaglyphTweakEnable ( "r_anaglyphTweakEnable", "0" ); VisionActivator r_blur ( "r_blur", "1", NULL, &m_blurTimer ); VisionActivator r_distortionEnable ( "r_distortionEnable", "0" ); VisionActivator r_filmEnable ( "r_filmEnable", "0" ); VisionActivator r_glow ( "r_glow", "0" ); VisionVariable r_glowRadius0 ( "r_glowRadius0", "0.0000", &r_glow ); VisionVariable r_glowRadius1 ( "r_glowRadius1", "0.0000", &r_glow ); VisionVariable r_glowBloomCutoff ( "r_glowBloomCutoff", "0.0000", &r_glow ); VisionVariable r_glowBloomDesaturation ( "r_glowBloomDesaturation", "0.0000", &r_glow ); VisionVariable r_glowBloomIntensity0 ( "r_glowBloomIntensity0", "0.0000", &r_glow ); VisionVariable r_glowBloomIntensity1 ( "r_glowBloomIntensity1", "0.0000", &r_glow ); VisionVariable r_glowBloomStreakX ( "r_glowBloomStreakX", "0.0000", &r_glow ); VisionVariable r_glowBloomStreakY ( "r_glowBloomStreakY", "0.0000", &r_glow ); VisionVariable r_filmContrast ( "r_filmContrast", "1.0000 1.0000 1.0000", &r_filmEnable ); VisionVariable r_filmBleach ( "r_filmBleach", "0.0000 0.0000 0.0000", &r_filmEnable ); VisionVariable r_filmBrightness ( "r_filmBrightness", "0.0000", &r_filmEnable ); VisionVariable r_filmHue ( "r_filmHue", "0.0000 0.0000 0.0000", &r_filmEnable ); VisionVariable r_filmMidStart ( "r_filmMidStart", "0.2500", &r_filmEnable ); VisionVariable r_filmMidEnd ( "r_filmMidEnd", "0.7500", &r_filmEnable ); VisionVariable r_filmDarkTint ( "r_filmDarkTint", "1.0000 1.0000 1.0000", &r_filmEnable ); VisionVariable r_filmMidTint ( "r_filmMidTint", "1.0000 1.0000 1.0000", &r_filmEnable ); VisionVariable r_filmLightTint ( "r_filmLightTint", "1.0000 1.0000 1.0000", &r_filmEnable ); VisionVariable r_filmSaturation ( "r_filmSaturation", "1.0000 1.0000 1.0000", &r_filmEnable ); VisionVariable r_anaglyphAngleMult ( "r_anaglyphAngleMult", "0", &r_anaglyphTweakEnable ); VisionVariable r_anaglyphOffsetMult ( "r_anaglyphOffsetMult", "0", &r_anaglyphTweakEnable ); VisionVariable r_distortionRadius ( "r_distortionRadius", "1", &r_distortionEnable ); VisionVariable r_distortionScale ( "r_distortionScale", "0", &r_distortionEnable ); VisionVariable r_blurlevel ( "r_blurlevel", "0.0000", &r_blur ); /*float m_blur_level = 0.0f; float m_blur_currentlevel = 0.0f; float m_blur_startlevel = 0.0f; float m_blur_fadetime = 0.0f; float m_blur_currentTime = 0.0f;*/ #if 0 vvar_t r_glow; vvar_t r_glowRadius0; vvar_t r_glowRadius1; vvar_t r_glowBloomCutoff; vvar_t r_glowBloomDesaturation; vvar_t r_glowBloomIntensity0; vvar_t r_glowBloomIntensity1; vvar_t r_glowBloomStreakX; vvar_t r_glowBloomStreakY; vvar_t r_filmEnable; vvar_t r_filmContrast; vvar_t r_filmBrightness; vvar_t r_filmDesaturation; vvar_t r_filmSaturation; vvar_t r_filmHue; vvar_t r_filmBleach; vvar_t r_filmLightTint; vvar_t r_filmMidTint; vvar_t r_filmMidStart; vvar_t r_filmMidEnd; vvar_t r_filmDarkTint; vvar_t r_anaglyphTweakEnable; vvar_t r_anaglyphAngleMult; vvar_t r_anaglyphOffsetMult; vvar_t r_distortionEnable; vvar_t r_distortionRadius; vvar_t r_distortionScale; regVis_t vvars[] = { { &r_glow, "r_glow", "0" }, { &r_glowRadius0, "r_glowRadius0", "0" }, { &r_glowRadius1, "r_glowRadius1", "0" }, { &r_glowBloomCutoff, "r_glowBloomCutoff", "0" }, { &r_glowBloomDesaturation, "r_glowBloomDesaturation", "0" }, { &r_glowBloomIntensity0, "r_glowBloomIntensity0", "0" }, { &r_glowBloomIntensity1, "r_glowBloomIntensity1", "0" }, { &r_glowBloomStreakX, "r_glowBloomStreakX", "0" }, { &r_glowBloomStreakY, "r_glowBloomStreakY", "0" }, { &r_filmEnable, "r_filmEnable", "0" }, { &r_filmContrast, "r_filmContrast", "1.0" }, { &r_filmBrightness, "r_filmBrightness", "0.0" }, { &r_filmDesaturation, "r_filmDesaturation", "0.0" }, { &r_filmHue, "r_filmHue", "0 0 0" }, { &r_filmSaturation, "r_filmSaturation", "1 1 1" }, { &r_filmBleach, "r_filmBleach", "0 0 0" }, { &r_filmLightTint, "r_filmLightTint", "1 1 1" }, { &r_filmMidStart, "r_filmMidStart", "0.25" }, { &r_filmMidEnd, "r_filmMidEnd", "0.75" }, { &r_filmMidTint, "r_filmMidTint", "1 1 1" }, { &r_filmDarkTint, "r_filmDarkTint", "1 1 1" }, { &r_anaglyphTweakEnable, "r_anaglyphTweakEnable", "0" }, { &r_anaglyphAngleMult, "r_anaglyphAngleMult", "0" }, { &r_anaglyphOffsetMult, "r_anaglyphOffsetMult", "0" }, { &r_distortionEnable, "r_distortionEnable", "0" }, { &r_distortionRadius, "r_distortionRadius", "1" }, { &r_distortionScale, "r_distortionScale", "0" }, }; #endif regCvar_t r_cvars[] = { { &r_debug, "r_gfx_debug", "0", CVAR_ARCHIVE }, { &r_dof, "r_gfx_dof", "0", CVAR_ARCHIVE }, { &r_texFilterAniso, "r_gfx_texFilterAniso", "8", CVAR_ARCHIVE }, { &r_ssao, "r_gfx_ssao", "0", CVAR_ARCHIVE }, { &r_tweakBlurX, "r_gfx_tweakBlurX", "0", CVAR_ARCHIVE }, { &r_tweakBlurY, "r_gfx_tweakBlurY", "0", CVAR_ARCHIVE }, { &r_tweakBlurPasses, "r_gfx_tweakBlurPasses", "0", CVAR_ARCHIVE }, { &r_glowEnable, "r_gfx_glowEnable", "1", CVAR_ARCHIVE }, { &r_glowQuality, "r_gfx_glowQuality", "8", CVAR_ARCHIVE }, { &r_glowSamples, "r_gfx_glowSamples", "8", CVAR_ARCHIVE }, { &r_autoluminance, "r_gfx_autoluminance", "1", CVAR_ARCHIVE }, { &r_fxaa, "r_gfx_fxaa", "1", CVAR_ARCHIVE }, { &r_test_bump, "r_gfx_test_bump", "1", CVAR_ARCHIVE }, { &r_test_color, "r_gfx_test_color", "1", CVAR_ARCHIVE }, { NULL, NULL, NULL, NULL }, }; /* Renderer stuff */ GL_State_f GL_State = ( GL_State_f )0x00498A90; GL_Bind_f GL_Bind = ( GL_Bind_f )0x00498780; GL_Setup_f GL_Setup = ( GL_Setup_f )0x004B0FC0; typedef void( *R_Draw3D_f )( void ); R_Draw3D_f R_Draw3D_o; DWORD ** ppWhite = ( DWORD ** )0x01313D98; #define VISION_CVAR(name, default_value) name = cgi.Cvar_Get(#name, #default_value, CVAR_ROM) void WINAPI glnDrawElements( GLuint returnAddress, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices ); int R_CvarSize( void ) { return sizeof( r_cvars ) / sizeof( r_cvars[0] ); } void EmptyTexture( GLuint txtnumber ) { unsigned int* data; // Stored Data // Create Storage Space For Texture Data (128x128x4) data = (unsigned int*)new GLuint[ ( ( 512 * 512 )* 4 * sizeof(unsigned int) ) ]; memset( data, 0, ( ( 512 * 512 ) * 4 * sizeof(unsigned int) ) ); // Clear Storage Memory glBindTexture(GL_TEXTURE_2D, txtnumber); // Bind The Texture glTexImage2D( GL_TEXTURE_2D, 0, 4, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); // Build Texture Using Information In data glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); delete [] data; // Release data } void R_RenderScene( refDef_t *fd ); int spamtime = 0; int spamframetime = 0; int spamprevioustime = 0; //Our torus TORUS torus; //Normal map GLuint normalMap; //Decal texture GLuint decalTexture; //Normalisation cube map GLuint normalisationCubeMap; IMAGE normalMapImage; IMAGE decalImage; Vector worldLightPosition = Vector( 10.0f, 10.0f, 10.0f ); void RPrintf( int type, const char *fmt, ... ) { // Fix for this damn error spamming the console and sometimes this message eats more FPS than the model itself // This is a fix for CRAZY SERVER MODS in the map training // We leave at least 250 ms for this message if( _stricmp( "Exceeded MAX POLYS\n", fmt ) == 0 && spamtime <= 250 ) { // We have a custom frametime here because RPrintf can be called 10 times in a row spamframetime = cgi.Milliseconds() - spamprevioustime; spamprevioustime = cgi.Milliseconds(); spamtime += spamframetime; return; } else if( _stricmp( "Exceeded MAX POLYS\n", fmt ) == 0 && spamtime > 250 ) { spamtime = 0; } char buffer[4100]; va_list va; va_start( va, fmt ); vsprintf( buffer, fmt, va ); va_end( va ); ri.Printf( type, buffer ); } bool GenerateNormalisationCubeMap() { unsigned char * data = new unsigned char[ 32 * 32 * 3 ]; if( !data ) { printf( "Unable to allocate memory for texture data for cube map\n" ); return false; } //some useful variables int size = 32; float offset = 0.5f; float halfSize = 16.0f; Vector tempVector; unsigned char * bytePtr; //positive x bytePtr = data; for( int j = 0; jPrintf = RPrintf; //refexp->RenderScene = R_RenderScene; //R_Draw3D_o = ( R_Draw3D_f )detour_function( ( PBYTE )0x0049A590, ( PBYTE )R_Draw3D, 6 ); /*for( int i = 0; i < sizeof( vvars ) / sizeof( vvars[0] ); i++ ) { vvars[i].vvar->name = ( char * )vvars[i].name; R_ProcessVisionVar( vvars[i].name, vvars[i].value ); }*/ glGenTextures( 1, &m_pBloomBlurShader ); //EmptyTexture( m_pBloomBlurShader ); gl::CheckInit(); gl::InitializeExtensions(); QFXRenderer::Instance().InitializeGL(); glGenTextures( 1, &m_pBloomCombineShader ); glGenTextures( 1, &m_pBloomDarkenShader ); glGenTextures( 1, &m_uiBlurTexture ); glGenTextures( 1, &m_uiInvertTexture ); glGenTextures( 1, &m_uiDarkTexture ); glGenTextures( 1, &m_uiLightTexture ); render_inited = true; //refexp->DrawBox = DrawBox; //refimp->CM_EntityString = CM_EntityString; /* //Load identity modelview gl::qglMatrixMode( GL_MODELVIEW ); gl::qglLoadIdentity(); //Shading states gl::qglShadeModel( GL_SMOOTH ); gl::qglClearColor( 0.2f, 0.4f, 0.2f, 0.0f ); gl::qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); gl::qglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); //Depth states gl::qglClearDepth( 1.0f ); gl::qglDepthFunc( GL_LEQUAL ); gl::qglEnable( GL_DEPTH_TEST ); gl::qglEnable( GL_CULL_FACE ); //Load normal map normalMapImage.Load( "Normal map.bmp" ); normalMapImage.ExpandPalette(); //Convert normal map to texture gl::qglGenTextures( 1, &normalMap ); gl::qglBindTexture( GL_TEXTURE_2D, normalMap ); gl::qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, normalMapImage.width, normalMapImage.height, 0, normalMapImage.format, GL_UNSIGNED_BYTE, normalMapImage.data ); gl::qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); gl::qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); gl::qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); gl::qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); //Load decal image decalImage.Load( "decal.bmp" ); decalImage.ExpandPalette(); //Convert decal image to texture gl::qglGenTextures( 1, &decalTexture ); gl::qglBindTexture( GL_TEXTURE_2D, decalTexture ); gl::qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, decalImage.width, decalImage.height, 0, decalImage.format, GL_UNSIGNED_BYTE, decalImage.data ); gl::qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); gl::qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); gl::qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); gl::qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); //Create normalisation cube map gl::qglGenTextures( 1, &normalisationCubeMap ); gl::qglBindTexture( GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap ); GenerateNormalisationCubeMap(); gl::qglTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); gl::qglTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); gl::qglTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); gl::qglTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); gl::qglTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); */ } void R_Shutdown(void) { int i; refImport_t *refimp = ( refImport_t * )( 0x01313C80 ); refimp->Printf = ri.Printf; gl::Shutdown(); /* Revert to the original function */ /**exp_glBegin = (DWORD)orig_exp_glBegin; *exp_glDrawElements = (DWORD)orig_exp_glDrawElements; *exp_glViewport = (DWORD)orig_exp_glViewport;*/ detour_remove( R_Draw3D, R_Draw3D_o ); glDeleteTextures( 1, &m_pBloomBlurShader ); glDeleteTextures( 1, &m_pBloomCombineShader ); glDeleteTextures( 1, &m_pBloomDarkenShader ); glDeleteTextures( 1, &m_uiBlurTexture ); glDeleteTextures( 1, &m_uiInvertTexture ); glDeleteTextures( 1, &m_uiDarkTexture ); glDeleteTextures( 1, &m_uiLightTexture ); for( i = 0; i < MAX_EFFECTS; i++ ) { if( effect_list[ i ] == NULL ) continue; R_RemoveEffect( effect_list[ i ] ); } } void DrawBlur( float blur ); void DrawGBlur( int radius, float intensity, float cutoff, float desaturation ); void R_FadeOverTime(); void ProcessBloom( float radius ); void ViewOrtho(); void ViewPerspective(); void R_DrawModels() { refEntity_t ref; Entity *ent; for( int i = 0; i < s_entities.NumObjects(); i++ ) { ent = s_entities.ObjectAt( i + 1 ); if( !ent->modelhandle || ( ent->renderFx & RF_INVISIBLE ) ) { continue; } memset( &ref, 0, sizeof( refEntity_t ) ); if( ent->attached ) { orientation_t orient; memset( &orient, 0, sizeof( orientation_t ) ); ent->attached->GetTag( ent->attached_tagname, &orient ); if( ent->attached_use_angles ) { MatrixToEulerAngles( orient.axis, ent->angles ); } ent->origin = ent->attached->origin + orient.origin + ent->attached_offset; } VectorCopy( ent->origin, ref.lightingOrigin ); VectorCopy( ent->origin, ref.origin ); VectorCopy( ent->origin, ref.oldorigin ); //angles[ 1 ] += 90.f; //angles[ 2 ] += 90.f; AnglesToAxis( ent->angles, ref.axis ); ref.reType = RT_MODEL; ref.scale = ent->scale; ref.hModel = ent->modelhandle; ref.hOldModel = ent->modelhandle; ref.tiki = ent->tiki; ref.entityNumber = 2048; ref.actionWeight = 1.0f; for( int i = 0; i < ent->GetNumFrames(); i++ ) { frameInfo_t *frame = ent->GetFrameInfo( i ); ref.frameInfo[ i ].index = frame->index; ref.frameInfo[ i ].time = frame->time; ref.frameInfo[ i ].weight = frame->weight; } cge.CG_ProcessInitCommands( ent->tiki, &ref ); ref.renderfx = ent->renderFx; cgi.R_AddRefEntityToScene( &ref, 0 ); } } Entity *R_SpawnModel( const char *model, vec3_t origin, vec3_t angles ) { Entity *ent = new Entity; ent->setModel( model ); ent->setAngles( angles ); ent->setOrigin( origin ); //ent->renderFx = RF_ADDITIVEDLIGHT | RF_EXTRALIGHT | RF_LIGHTINGORIGIN | RF_SHADOW | RF_SHADOWPRECISE | RF_FIRST_PERSON; return ent; } int refEntityReadd = 0; int refSpriteReadd = 0; refEntity_t *refEntityList[ 1024 ]; refEntity_t *refSpriteList[ 1024 ]; model_t *models = ( model_t * )0x1314890; void refEntityAdd() { for( int i = 0; i < refSpriteReadd; i++ ) { refEntity_t *ent = refSpriteList[ i ]; cgi.R_AddRefSpriteToScene( ent ); free( ent ); refSpriteList[ i ] = NULL; } for( int i = 0; i < refEntityReadd; i++ ) { refEntity_t *ent = refEntityList[ i ]; model_t *pModel = &models[ ent->hModel ]; pModel->bmodel->haslightmap = false; cgi.R_AddRefEntityToScene( ent, ent->parentEntity ); free( ent ); refEntityList[ i ] = NULL; } refEntityReadd = 0; refSpriteReadd = 0; } void R_RenderScene( refDef_t *fd ) { GL_Setup(); GL_State( GLS_DEPTHMASK_TRUE ); R_DrawModels(); if( !r_anaglyph->integer && !r_anaglyphTweakEnable.isEnabled() ) { //QFXRenderer::Instance().PreRenderScene( fd ); cgi.R_RenderScene( fd ); //QFXRenderer::Instance().PostRenderScene(); GL_Setup(); GL_State( GLS_DEPTHMASK_TRUE ); R_Draw3D(); return; } glDrawBuffer( GL_BACK ); glReadBuffer( GL_BACK ); /* Clear things */ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); //glClear( GL_ACCUM_BUFFER_BIT ); glViewport( 0, 0, cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); glColorMask( GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE ); Vector angles; Vector leftvec; MatrixToEulerAngles( fd->viewAxis, angles ); AngleVectors( angles, NULL, leftvec, NULL ); Vector old_angles = angles; Vector old_origin = fd->viewOrg; /*if( r_anaglyph->integer ) { if( r_anaglyphAngleMult.value_current < 1.0f && ( r_anaglyphAngleMult.value >= 1.0f || !r_anaglyphTweakEnable.integer_target ) ) { r_anaglyphAngleMult.value_current = 1.0f; } if( r_anaglyphOffsetMult.value_current < 1.0f && ( r_anaglyphOffsetMult.value >= 1.0f || !r_anaglyphTweakEnable.integer_target ) ) { r_anaglyphOffsetMult.value_current = 1.0f; } }*/ if( r_anaglyphTweakEnable.isEnabled() ) { angles.y -= ( 1.0f * r_anaglyphAngleMult.floatValue() ); } else { angles.y -= 1.0f; } AnglesToAxis( angles, fd->viewAxis ); cgi.R_RenderScene( fd ); GL_Setup(); glFlush(); glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); glDrawBuffer( GL_BACK ); glClear( GL_DEPTH_BUFFER_BIT ); if( r_anaglyphTweakEnable.isEnabled() ) { fd->viewOrg[ 0 ] += leftvec[ 0 ] * ( 0.25f * r_anaglyphOffsetMult.floatValue() ); fd->viewOrg[ 2 ] -= ( 0.25f * r_anaglyphOffsetMult.floatValue() ); angles.y += ( 1.0f * r_anaglyphAngleMult.floatValue() ); } else { fd->viewOrg[ 0 ] += leftvec[ 0 ] * 0.25f; fd->viewOrg[ 2 ] -= 0.25f; angles.y += 1.0f; } AnglesToAxis( angles, fd->viewAxis ); glViewport( 0, 0, cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); glColorMask( GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE ); refEntityAdd(); cgi.R_RenderScene( fd ); GL_Setup(); glFlush(); glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); AnglesToAxis( old_angles, fd->viewAxis ); AnglesToAxis( old_angles, cg->refdef.viewAxis ); VectorCopy( old_origin, fd->viewOrg ); VectorCopy( old_origin, cg->refdef.viewOrg ); R_Draw3D(); } void R_Draw3D() { int blend_src = 0, blend_dst = 0; GLint viewport[4]; glHint( GL_GENERATE_MIPMAP_HINT, GL_NICEST ); glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); glHint( GL_POINT_SMOOTH_HINT, GL_NICEST ); glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST ); glHint( GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_NICEST ); #if 0 static float angle = 0.0f; angle += 0.1f; gl::qglRotatef( angle, 0.0f, 1.0f, 0.0f ); matrix_t inverseModelMatrix; gl::qglPushMatrix(); gl::qglLoadIdentity(); gl::qglRotatef( -angle, 0.0f, 1.0f, 0.0f ); gl::qglGetFloatv( GL_MODELVIEW_MATRIX, ( GLfloat * )inverseModelMatrix ); gl::qglPopMatrix(); vec4_t o; MatrixTransform4( inverseModelMatrix, worldLightPosition, o ); Vector objectLightPosition; if( o[ 3 ] == 0.0f || o[ 3 ] == 1.0f ) { objectLightPosition = Vector( o[ 0 ], o[ 1 ], o[ 2 ] ); } else { objectLightPosition = Vector( o[ 0 ] / o[ 3 ], o[ 1 ] / o[ 3 ], o[ 2 ] / o[ 3 ] ); } //Loop through vertices for( int i = 0; iinteger ) { //Bind normal map to texture unit 0 gl::qglBindTexture( GL_TEXTURE_2D, normalMap ); gl::qglEnable( GL_TEXTURE_2D ); //Bind normalisation cube map to texture unit 1 gl::qglActiveTextureARB( GL_TEXTURE1_ARB ); gl::qglBindTexture( GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap ); gl::qglEnable( GL_TEXTURE_CUBE_MAP_ARB ); gl::qglActiveTextureARB( GL_TEXTURE0_ARB ); //Send texture coords for normal map to unit 0 gl::qglTexCoordPointer( 2, GL_FLOAT, sizeof( TORUS_VERTEX ), &torus.vertices[ 0 ].s ); gl::qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); //Set vertex arrays for torus gl::qglVertexPointer( 3, GL_FLOAT, sizeof( TORUS_VERTEX ), &torus.vertices[ 0 ].position ); gl::qglEnableClientState( GL_VERTEX_ARRAY ); //Send tangent space light vectors for normalisation to unit 1 gl::qglClientActiveTextureARB( GL_TEXTURE1_ARB ); gl::qglTexCoordPointer( 3, GL_FLOAT, sizeof( TORUS_VERTEX ), &torus.vertices[ 0 ].tangentSpaceLight ); gl::qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); gl::qglClientActiveTextureARB( GL_TEXTURE0_ARB ); //Set up texture environment to do (tex0 dot tex1)*color gl::qglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); gl::qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); gl::qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE ); gl::qglActiveTextureARB( GL_TEXTURE1_ARB ); gl::qglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); gl::qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); gl::qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB ); gl::qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB ); gl::qglActiveTextureARB( GL_TEXTURE0_ARB ); //Draw torus gl::qglDrawElements( GL_TRIANGLES, torus.numIndices, GL_UNSIGNED_INT, torus.indices ); //Disable textures gl::qglDisable( GL_TEXTURE_2D ); gl::qglActiveTextureARB( GL_TEXTURE1_ARB ); gl::qglDisable( GL_TEXTURE_CUBE_MAP_ARB ); gl::qglActiveTextureARB( GL_TEXTURE0_ARB ); //disable vertex arrays gl::qglDisableClientState( GL_VERTEX_ARRAY ); gl::qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); gl::qglClientActiveTextureARB( GL_TEXTURE1_ARB ); gl::qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); gl::qglClientActiveTextureARB( GL_TEXTURE0_ARB ); //Return to standard modulate texenv gl::qglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); } if( r_test_bump->integer && r_test_color->integer ) { gl::qglBlendFunc( GL_DST_COLOR, GL_ZERO ); gl::qglEnable( GL_BLEND ); } if( r_test_color->integer ) { if( !r_test_bump->integer ) { gl::qglLightfv( GL_LIGHT1, GL_POSITION, ( const GLfloat * )&Quat( objectLightPosition ) ); gl::qglLightfv( GL_LIGHT1, GL_DIFFUSE, ( const GLfloat * )&Quat( 1.0f, 1.0f, 1.0f, 1.0f ) ); gl::qglLightfv( GL_LIGHT1, GL_AMBIENT, ( const GLfloat * )&Quat( 0.0f, 0.0f, 0.0f, 0.0f ) ); gl::qglLightModelfv( GL_LIGHT_MODEL_AMBIENT, ( const GLfloat * )&Quat( 0.0f, 0.0f, 0.0f, 0.0f ) ); gl::qglEnable( GL_LIGHT1 ); gl::qglEnable( GL_LIGHTING ); gl::qglMaterialfv( GL_FRONT, GL_DIFFUSE, ( const GLfloat * )&Quat( 1.0f, 1.0f, 1.0f, 1.0f ) ); } //Bind decal texture gl::qglBindTexture( GL_TEXTURE_2D, decalTexture ); gl::qglEnable( GL_TEXTURE_2D ); //Set vertex arrays for torus gl::qglVertexPointer( 3, GL_FLOAT, sizeof( TORUS_VERTEX ), &torus.vertices[ 0 ].position ); gl::qglEnableClientState( GL_VERTEX_ARRAY ); gl::qglNormalPointer( GL_FLOAT, sizeof( TORUS_VERTEX ), &torus.vertices[ 0 ].normal ); gl::qglEnableClientState( GL_NORMAL_ARRAY ); gl::qglTexCoordPointer( 2, GL_FLOAT, sizeof( TORUS_VERTEX ), &torus.vertices[ 0 ].s ); gl::qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); //Draw torus gl::qglDrawElements( GL_TRIANGLES, torus.numIndices, GL_UNSIGNED_INT, torus.indices ); //Disable texture gl::qglDisable( GL_TEXTURE_2D ); //disable vertex arrays gl::qglDisableClientState( GL_VERTEX_ARRAY ); gl::qglDisableClientState( GL_NORMAL_ARRAY ); gl::qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); } if( r_test_bump->integer && r_test_color->integer ) { gl::qglDisable( GL_BLEND ); } gl::qglFinish(); #endif QFXRenderer::Instance().GetVariables(); QFXRenderer::Instance().RenderGL(); // Post-processing effects are after Draw3D /*if( r_glow.integer ) { DrawGBlur( r_glowRadius0.value_current, r_glowBloomIntensity0.value_current, r_glowBloomCutoff.value_current, r_glowBloomDesaturation.value_current ); }*/ DrawBlur( r_blurlevel.floatValue() ); #if 0 ViewOrtho(); glDepthRange( 0.0f, 0.0f ); glGetIntegerv( GL_VIEWPORT, viewport ); glGetIntegerv( GL_BLEND_SRC, &blend_src ); glGetIntegerv( GL_BLEND_DST, &blend_dst ); if( r_filmEnable.isEnabled() ) { // This part is complex // It is doing a transition between inverted colors and normal colors /*if( r_filmInvert.integer ) { float invert_value = r_filmInvert.value_current; if( invert_value != r_filmInvert.value ) { glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA ); } else { glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ZERO ); } // Generate the invert texture glBindTexture( GL_TEXTURE_2D, m_uiInvertTexture ); glBegin( GL_QUADS ); glColor4f( 1.0f, 1.0f, 1.0f, 0.1f ); glVertex2f( -cgs->glConfig.vidWidth, -cgs->glConfig.vidHeight ); glVertex2f( cgs->glConfig.vidWidth, -cgs->glConfig.vidHeight ); glVertex2f( cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glVertex2f( -cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glEnd(); if( invert_value != r_filmInvert.value ) { glBindTexture( GL_TEXTURE_2D, m_uiInvertTexture ); glBegin( GL_QUADS ); glColor4f( 1.0f-invert_value, 1.0f-invert_value, 1.0f-invert_value, invert_value ); glVertex2f( -cgs->glConfig.vidWidth, -cgs->glConfig.vidHeight ); glVertex2f( cgs->glConfig.vidWidth, -cgs->glConfig.vidHeight ); glVertex2f( cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glVertex2f( -cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glEnd(); } }*/ //R_SetSceneColor( r_filmLightTint.vector_current, r_filmDarkTint.vector_current ); } //if( r_filmEnable.integer ) { // R_SetSceneColor( r_filmLightTint.vector ); //} /*memset( pixelData, 0, ( ( 512 * 512 ) * 4 * 4 ) ); glBindTexture( GL_TEXTURE_2D, m_pBloomBlurShader ); glTexImage2D( GL_TEXTURE_2D, 0, 4, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData ); glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 512, 512, 0 ); glClearColor( 0, 0, 0.5f, 0 ); // Bloom/Glow effects glViewport( 0, 0, 512, 512 ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); //glReadPixels( 0, 0, 512, 512, GL_RGBA, GL_UNSIGNED_BYTE, pixelData ); for( int i = 0; i < 512 * 512 ; i ++ ) { pixelData[i] = pixelData[i] / 64 * 64; } glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 512, 512, GL_RGBA, GL_UNSIGNED_BYTE, pixelData ); //glDrawPixels( 512, 512, GL_RGB, GL_UNSIGNED_BYTE, pixelData ); free( pixelData ); glViewport( viewport[0], viewport[1], viewport[2], viewport[3] ); glBlendFunc( GL_SRC_ALPHA, GL_ONE ); glBegin( GL_QUADS ); glVertex2f( -cgs->glConfig.vidWidth, -cgs->glConfig.vidHeight ); glVertex2f( cgs->glConfig.vidWidth, -cgs->glConfig.vidHeight ); glVertex2f( cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glVertex2f( -cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glEnd(); glFlush(); orig_wglSwapBuffers( NULL );*/ //glViewport( 0, 0, 512, 512 ); //glViewport( viewport[0], viewport[1], viewport[2], viewport[3] ); ViewPerspective(); // 64, 0.55f glDepthRange( 0.0f, 1.0f ); glBlendFunc( blend_src, blend_dst ); #endif for( int i = m_visionVar.NumObjects(); i > 0; i-- ) { VisionClass *variable = m_visionVar.ObjectAt( i ); if( !variable ) { continue; } variable->Think(); } //R_FadeOverTime(); //R_FadeBlurOverTime(); } void ViewOrtho() { glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); glOrtho( 0, cgs->glConfig.vidWidth , cgs->glConfig.vidHeight , 0, -1, 1 ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); } void ViewPerspective() { glPopMatrix(); glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); } void DrawBlur( float blur ) { if( blur <= 0.0f ) { return; } glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // Generate the blur texture glBindTexture( GL_TEXTURE_2D, m_uiBlurTexture ); glBegin( GL_QUADS ); glColor4f( 0.0f, 0.0f, 0.0f, 0.0f ); glVertex2f( ( GLfloat )-cgs->glConfig.vidWidth, ( GLfloat )-cgs->glConfig.vidHeight ); glVertex2f( ( GLfloat )cgs->glConfig.vidWidth, ( GLfloat )-cgs->glConfig.vidHeight ); glVertex2f( ( GLfloat )cgs->glConfig.vidWidth, ( GLfloat )cgs->glConfig.vidHeight ); glVertex2f( ( GLfloat )-cgs->glConfig.vidWidth, ( GLfloat )cgs->glConfig.vidHeight ); glEnd(); glAccum( GL_MULT, blur ); glAccum( GL_ACCUM, 1.0f - blur ); glAccum( GL_RETURN, 1.0f ); glFlush(); } void WINAPI glnDrawElements( GLuint returnAddress, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices ) { #if 0 int i; GLubyte colorR[5000]; GLubyte colorG[5000]; GLubyte colorB[5000]; char * lpCurrentShader = *( ( char ** ) 0x01313900 ); for ( i=0; i <= 4998; i = i+4 ) { colorR[i+0]=0xFF; colorR[i+1]=0x00; colorR[i+2]=0x00; colorR[i+3]=0xFF; colorG[i+0]=0x00; colorG[i+1]=0xFF; colorG[i+2]=0x00; colorG[i+3]=0xFF; colorB[i+0]=0x00; colorB[i+1]=0x00; colorB[i+2]=0xFF; colorB[i+3]=0xFF; } //if( returnAddress != ELM_FLAT ) //{ if( !strstr( lpCurrentShader, "DAK_pants_tan" ) && !strstr( lpCurrentShader, "DAK_private_tunic" ) && !strstr( lpCurrentShader, "c_DAK_private_tunic") && !strstr( lpCurrentShader, "facewrap" ) && !strstr( lpCurrentShader, "german-helmet_inside" ) && !strstr( lpCurrentShader, "dak_helmet" ) ) { return glDrawElements( mode, count, type, indices ); } glDisable( GL_TEXTURE_2D ); //glColorPointer( 4, GL_UNSIGNED_BYTE, 0, &colorG ); glDrawElements( mode, count, type, indices ); glColorPointer( 4, GL_UNSIGNED_BYTE, 0, &colorB ); glColorPointer( 4, GL_UNSIGNED_BYTE, 0, &colorG ); glEnable( GL_TEXTURE_2D ); //} #endif gl::qglDrawElements( mode, count, type, indices ); } void WINAPI glDrawElements_h( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices ) { gl::qglDrawElements( mode, count, type, indices ); } void WINAPI glTexCoordPointer_h( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ) { gl::qglTexCoordPointer( size, type, stride, pointer ); } void R_SetShader( int ent_num, const char * shader, qboolean fDefault ) { if( !fDefault ) { Entity *entity = CL_GetCEntity( ent_num ); if( entity == NULL ) { entity = new Entity; } // Assign the number entity->AssignNumber( ent_num ); entity->SetShader( shader ); } else { Entity *entity = CL_GetCEntity( ent_num ); if( entity != NULL ) { entity->SetShader( NULL ); } } } void R_AddRefEntityToScene( refEntity_t *ent, int parentEntityNumber ) { centity_t *cent = CL_GetEntity( ent->entityNumber ); Entity *entity = cent != NULL ? CL_GetCEntity( cent->currentState.number ) : NULL; if( entity != NULL && entity->fShader ) { // && ent->model != cg->playerFPSModelHandle && ent->entityNumber != cg->clientNum ) { ent->customShader = entity->customshader; } if( r_anaglyph->integer || r_anaglyphTweakEnable.isEnabled() ) { refEntity_t *newEnt = ( refEntity_t * )malloc( sizeof( refEntity_t ) ); memcpy( newEnt, ent, sizeof( refEntity_t ) ); refEntityList[ refEntityReadd ] = newEnt; refEntityReadd++; } cgi.R_AddRefEntityToScene( ent, parentEntityNumber ); } void R_AddRefSpriteToScene( refEntity_t *ent ) { if( r_anaglyph->integer || r_anaglyphTweakEnable.isEnabled() ) { refEntity_t *newEnt = ( refEntity_t * )malloc( sizeof( refEntity_t ) ); memcpy( newEnt, ent, sizeof( refEntity_t ) ); refSpriteList[ refSpriteReadd ] = newEnt; refSpriteReadd++; } cgi.R_AddRefSpriteToScene( ent ); } /*void WINAPI glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { orig_exp_glViewport(x, y, width, height); }*/ effect_t * R_GetEffectById(int ID) { return effect_list[ID]; } effect_t * R_GetEffectByName(const char * fxName) { int i; if(!R_IsEffect(fxName)) { cgi.DPrintf("R_GetEffectByName : unknown effect name %s\n", fxName); return NULL; } for(i=0;ieffectName) == 0) return effect_list[i]; } return NULL; } int R_GetEffectId(effect_t * effect) { int i; if(effect == NULL) return -1; for(i=0;ifadetime = fadetime; if(!bAddEffect) { effect->bRemove = true; } /* Remove effects that doesn't/can't fade */ if(effect->fadetime == 0) { if(!bAddEffect) R_RemoveEffect(effect); } else if(_strcmpi(effect->effectName, "invert") == 0) { if(!bAddEffect) R_RemoveEffect(effect); } if(bAddEffect == 2) { effect->intensity = intensity; effect->o_color[RED] = effect->t_color[RED]; effect->o_color[GREEN] = effect->t_color[GREEN]; effect->o_color[BLUE] = effect->t_color[BLUE]; effect->t_color[RED] = colors[RED]; effect->t_color[GREEN] = colors[GREEN]; effect->t_color[BLUE] = colors[BLUE]; memcpy(effect->param, parameters, sizeof(float)); } return; } bFound = false; /* Loop until we find a free spot in the used effects list */ for(i=0;ieffectName, fxName); effect->intensity = intensity; effect->color[RED]= 1.0f; effect->color[GREEN]= 1.0f; effect->color[BLUE]= 1.0f; effect->t_color[RED] = colors[RED]; effect->t_color[GREEN] = colors[GREEN]; effect->t_color[BLUE] = colors[BLUE]; effect->o_color[RED] = colors[RED]; effect->o_color[GREEN] = colors[GREEN]; effect->o_color[BLUE] = colors[BLUE]; effect->fadetime = fadetime; memcpy(effect->param, parameters, sizeof(float)); cgi.DPrintf("R_PostProcessEffect : effect '%s' (%p) added to the effect list (intensity=%f|red=%f|green=%f|blue=%f|param1=%f|param2=%f)\n", effect->effectName, effect, intensity, effect->t_color[RED], effect->t_color[GREEN], effect->t_color[BLUE], parameters[0], parameters[1]); /* Place the effect in the used effect list */ effect_list[i] = effect; } void R_ProcessEffectFade(effect_t * effect, int frametime) { float time; int reverted; if(effect == NULL) return; time = effect->fadetime * 1000.0f; /* Fade the RGB values over the specified time */ reverted = 0; if(!effect->bRemove) { if(effect->color[RED] > effect->t_color[RED]) effect->color[RED] -= (1.0f-effect->t_color[RED])/time * frametime; else if(effect->color[RED] < effect->t_color[RED]) effect->color[RED] += (effect->t_color[RED]-effect->o_color[RED])/time * frametime; if(effect->color[GREEN] > effect->t_color[GREEN]) effect->color[GREEN] -= (1.0f-effect->t_color[GREEN])/time * frametime; else if(effect->color[GREEN] < effect->t_color[GREEN]) effect->color[GREEN] += (effect->t_color[GREEN]-effect->o_color[GREEN])/time * frametime; if(effect->color[BLUE] > effect->t_color[BLUE]) effect->color[BLUE] -= (1.0f-effect->t_color[BLUE])/time * frametime; else if(effect->color[BLUE] < effect->t_color[BLUE]) effect->color[BLUE] += (effect->t_color[BLUE]-effect->o_color[BLUE])/time * frametime; } else { /* If the effect is being removed, increase all RGB values up to 1.0 */ effect->color[RED] += 1.0f/time * frametime; if(effect->color[RED] > 1.0f) { effect->color[RED] = 1.0f; reverted++; } effect->color[GREEN] += 1.0f/time * frametime; if(effect->color[GREEN] > 1.0f) { effect->color[GREEN] = 1.0f; reverted++; } effect->color[BLUE] += 1.0f/time * frametime; if(effect->color[BLUE] > 1.0f) { effect->color[BLUE] = 1.0f; reverted++; } /* If the effect did the transition (colors values are all 1.0) then we can now remove it */ if(reverted >= 3) R_RemoveEffect(effect); } } void R_ProcessEffectsFade(int frametime) { int i; /* Process the effects fading */ for(i=0;ibRemove = true; /* Remove the effect from the list */ if(index != -1) effect_list[index] = NULL; /* Just reallocate the effect name so that the debug message will show which effect * has been removed */ fxName = (char*)malloc(strlen(effect->effectName)); strcpy(fxName, effect->effectName); memset(effect, 0, sizeof(effect_t)); /* Free the effect from the memory */ free(effect); cgi.DPrintf("R_RemoveEffect : effect '%s' removed from the effect list\n", fxName); /* Free the effect name */ free(fxName); } #if 0 void R_SetSceneColor( vec3_t light, vec3_t dark ) { #if 0 GLfloat rgb[10010]; int i; /* Set the RGB array values */ for( i = 0; i <= 10007; i += 3 ) { rgb[i] = color[0]; rgb[i+1] = color[1]; rgb[i+2] = color[2]; } /* Apply the RGB values to the scene */ glEnable( GL_BLEND ); glColorPointer( 3, GL_FLOAT, 0, rgb ); #endif light[0] /= 2.0f; light[1] /= 2.0f; light[2] /= 2.0f; dark[0] /= 2.0f; dark[1] /= 2.0f; dark[2] /= 2.0f; GL_State( GLS_DEPTHMASK_TRUE ); glEnableClientState( GL_COLOR_ARRAY ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glEnable( GL_BLEND ); // Generate the light tint texture glBlendFunc( GL_DST_COLOR, GL_ONE ); glBindTexture( GL_TEXTURE_2D, m_uiLightTexture ); glBegin( GL_QUADS ); glColor3fv( light ); glVertex2f( -cgs->glConfig.vidWidth, -cgs->glConfig.vidHeight ); glVertex2f( cgs->glConfig.vidWidth, -cgs->glConfig.vidHeight ); glVertex2f( cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glVertex2f( -cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glEnd(); // Generate the dark tint texture glBlendFunc( GL_DST_COLOR, GL_ZERO ); glBindTexture( GL_TEXTURE_2D, m_uiDarkTexture ); glBegin( GL_QUADS ); glColor3fv( dark ); glVertex2f( -cgs->glConfig.vidWidth, -cgs->glConfig.vidHeight ); glVertex2f( cgs->glConfig.vidWidth, -cgs->glConfig.vidHeight ); glVertex2f( cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glVertex2f( -cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glEnd(); // Generate the desaturation texture GLint viewport[4]; int HEIGHT = cgs->glConfig.vidHeight; int WIDTH = cgs->glConfig.vidWidth; float biggest = 0.0f; for( int i = 0; i < 3; i++ ) { if( r_filmDesaturation.vector_current[i] > biggest ) { biggest = r_filmDesaturation.vector_current[i]; } } // Optimize performances /*if( biggest > 0.0f ) { glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glBindTexture( GL_TEXTURE_2D, m_uiDesaturationTexture ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE, 0, 0, cgs->glConfig.vidWidth, cgs->glConfig.vidHeight, 0 ); glColor4f( r_filmDesaturation.vector_current[0], r_filmDesaturation.vector_current[1], r_filmDesaturation.vector_current[2], biggest ); glBegin( GL_QUADS ); glTexCoord2f( 0, 1 ); glVertex2f( 0, 0 ); glTexCoord2f( 1, 1 ); glVertex2f( cgs->glConfig.vidWidth, 0 ); glTexCoord2f( 1, 0 ); glVertex2f( cgs->glConfig.vidWidth, cgs->glConfig.vidHeight ); glTexCoord2f( 0, 0 ); glVertex2f( 0, cgs->glConfig.vidHeight ); glEnd(); glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, cgs->glConfig.vidWidth, cgs->glConfig.vidHeight, 0 ); }*/ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glDisable( GL_BLEND ); } #endif void R_SetSkyColor( vec3_t color ) { glEnable( GL_BLEND ); glColor3f( color[0], color[1], color[2] ); } void R_SetSceneColor2(float intensity, vec3_t color) { glColor3ub((int)(color[0]*255.0f),(int)(color[1]*255.0f),(int)(color[2]*255.0f)); glVertex2f(-1,-1); glColor3ub((int)(color[0]*255.0f),(int)(color[1]*255.0f),(int)(color[2]*255.0f)); glVertex2f(1,-1); glColor3ub((int)(color[0]*255.0f),(int)(color[1]*255.0f),(int)(color[2]*255.0f)); glVertex2f(1,1); } /* vvar_t * R_GetVisionVar( const char * name, regVis_t **vis = NULL ) { for( int i = 0; i < sizeof( vvars ) / sizeof( vvars[0] ); i++ ) { if( _stricmp( vvars[i].name, name ) == 0 ) { if( vis != NULL ) { *vis = &vvars[i]; } return vvars[i].vvar; } } return NULL; } qboolean R_ProcessVisionVar( const char * variable, const char * value ) { vvar_t *var; const char *vec1, *vec2, *vec3; qboolean isVector = false; char buffer[MAX_STRINGTOKENS]; regVis_t *vis = NULL; if( value == NULL ) { return false; } var = R_GetVisionVar( variable, &vis ); if( var == NULL ) { return false; } strcpy( buffer, value ); vec1 = strtok( ( char * )buffer, " " ); if( vec1 != NULL && isdigit( vec1[0] ) ) { vec2 = strtok( NULL, " " ); if( vec2 != NULL && isdigit( vec2[0] ) ) { vec3 = strtok( NULL, " " ); if( vec3 != NULL && isdigit( vec3[0] ) ) { isVector = true; } } } if( !isVector ) { var->integer_target = atoi( value ); var->value = atof( value ); var->vector[0] = var->value; var->vector[1] = var->value; var->vector[2] = var->value; } else { // Cast values into vector var->vector[0] = atof( vec1 ); var->vector[1] = atof( vec2 ); var->vector[2] = atof( vec3 ); var->value = var->vector[0]; } if( !render_inited ) { VectorCopy( var->vector, var->vector_current ); VectorCopy( var->vector, var->vector_start ); var->value_current = var->value; var->value_start = var->value; var->integer = var->integer_target; } else { var->value_start = var->value_current; VectorCopy( var->vector_current, var->vector_start ); } var->bProcessed = true; return true; } */ char * R_LineParseComment( char * line ) { char * new_line = line; int i = 0; qboolean quotation = false; while( *new_line != '\n' && *new_line != '\0' ) { if( *new_line == '"' ) { quotation = true; } if( *new_line == '/' && *( new_line + 1 ) == '/' ) { if( i == 0 ) { *new_line = '\0'; } return new_line; } //if( *new_line == '\t' ) { // *new_line = ' '; //} if( *new_line == ' ' && !quotation ){ *new_line = '\t'; } new_line++; i++; } return line; } void R_ProcessBlur( float blur_level, float fade_time ) { /*m_blur_startlevel = m_blur_currentlevel; m_blur_level = blur_level; m_blur_fadetime = fade_time * 1000.0f; m_blur_currentTime = 0.0f;*/ m_blurTimer.SetTime( fade_time ); r_blurlevel.setFloatValue( blur_level ); } void R_ProcessVision( str vision_name, float fade_time, float phase, str type ) { Script m_visionScript; VisionClass *visionVariable; int warnings; str filename = type + "/" + vision_name + "." + type; m_visionTimer.SetTime( fade_time ); if( phase ) { m_visionTimer.SetPhase( phase ); } if( vision_name.icmp( vision_current ) == 0 ) { #ifdef DEBUG cgi.Printf( "DEBUG: Vision file '%s' was already processed!\n", filename.c_str() ); #endif return; } m_visionScript.LoadFile( filename ); if( !m_visionScript.isValid() ) { Com_Printf( "Couldn't find vision '%s'! Setting to the default vision\n", vision_name.c_str() ); filename = type + "/" + "default" + "." + type; m_visionScript.LoadFile( filename ); if( !m_visionScript.isValid() ) { Com_Printf( "Couldn't find the default vision!\n" ); return; } vision_name = "default"; } warnings = 0; while( m_visionScript.TokenAvailable( true ) ) { str variable = m_visionScript.GetToken( false ); str value = m_visionScript.GetString( false ); visionVariable = VisionClass::Get( variable ); if( visionVariable != NULL && visionVariable->GetType() == "vision" ) { visionVariable->setValue( value ); visionVariable->fProcessed = true; } else { cgi.Printf( "WARNING : unknown var '%s' in file '%s'\n", variable.c_str(), filename.c_str() ); warnings++; } } if( warnings ) { cgi.Printf( "Found %d warning(s) in file '%s'\n", warnings, filename.c_str() ); } for( int i = 0; i < m_visionVar.NumObjects(); i++ ) { visionVariable = m_visionVar[ i ]; if( visionVariable->GetType() != "vision" ) { continue; } if( !visionVariable->fProcessed || !visionVariable->isNewEnabled() ) { visionVariable->setValue( visionVariable->defaultValue() ); } visionVariable->fProcessed = false; } vision_current = vision_name; #ifdef DEBUG cgi.Printf( "DEBUG: Processed vision file '%s' with %d warning(s)\n", filename.c_str(), warnings ); #endif } #if 0 void R_ProcessVision( str vision_name, float fade_time ) { char *content = NULL; char **line = NULL; char *variable, *value, *pch; int i = 0, num_lines = 0; int errors = 0; int length = 0; VisionClass *var; if( strlen( vision_name ) >= 64 ) { cgi.Printf( "vision exceeded the maximum length!\n" ); return; } str filename = "vision/" + vision_name + ".vision"; if( vision_name.icmp( vision_current ) == 0 ) { #ifdef DEBUG cgi.Printf( "DEBUG: Vision file '%s' was already processed!\n", filename.c_str() ); #endif return; } length = cgi.FS_ReadFile( filename.c_str(), ( void ** )&content ); if( length < 0 ) { Com_Printf( "Couldn't find vision '%s'! Setting to the default vision\n", vision_name.c_str() ); length = cgi.FS_ReadFile( "vision/default.vision", ( void ** )&content ); if( length < 0 ) { Com_Printf( "Couldn't find the default vision!\n" ); return; } filename = "vision/default.vision"; vision_name = "default"; } //for( int i = 0; i < sizeof( vvars ) / sizeof( vvars[0] ); i++ ) { // vvars[i].vvar->bProcessed = false; //} pch = strtok( content, "\n" ); while( pch != NULL ) { line = ( char ** )realloc( line, sizeof( DWORD ) * ( i + 1 ) ); line[i] = R_LineParseComment( pch ); i++; num_lines++; pch = strtok( NULL, "\n" ); } i = 0; while( i < num_lines ) { value = NULL; // This means we're at a comment if( line[i][0] == '\0' ) { i++; continue; } variable = strtok( line[i], "\t" ); if( variable != NULL ) { value = strtok( NULL, "\t\"" ); } if( value != NULL ) { // Process a vision variable /*if( !R_ProcessVisionVar( variable, value ) ) { cgi.Printf( "WARNING : unknown var '%s' in file '%s'\n", variable, filename.c_str() ); errors++; }*/ var = VisionClass::Get( variable ); if( var != NULL && var->GetType() == "vision" ) { var->setValue( value ); var->fProcessed = true; } else { cgi.Printf( "WARNING : unknown var '%s' in file '%s'\n", variable, filename.c_str() ); errors++; } } i++; } if( errors ) { cgi.Printf( "Found %d warnings in file '%s'\n", errors, filename.c_str() ); } for( int i = 0; i < m_visionVar.NumObjects(); i++ ) { var = m_visionVar[ i ]; if( var->GetType() != "vision" ) { continue; } if( !var->fProcessed || !var->isNewEnabled() ) { var->setValue( var->defaultValue() ); } var->fProcessed = false; } /*for( int i = 0; i < sizeof( vvars ) / sizeof( vvars[0] ); i++ ) { // ALL variables must be processed if( !vvars[i].vvar->bProcessed ) { R_ProcessVisionVar( vvars[i].name, vvars[i].value ); } }*/ vision_current = vision_name; #ifdef DEBUG cgi.Printf( "DEBUG: Processed vision file '%s' with %d error(s)\n", filename.c_str(), errors ); #endif m_visionTimer.SetTime( fade_time ); } #endif // Vision class VisionClass *VisionClass::Get( str n ) { for( int i = 0; i < m_visionVar.NumObjects(); i++ ) { VisionClass *variable = m_visionVar[ i ]; if( variable->GetName().icmp( n ) == 0 ) { return variable; } } return NULL; } void VisionClass::VisionInit( const char *n, const char *v, ScriptTimer *globalTimer ) { name = n; defaultval = v; fProcessed = false; if( globalTimer == NULL ) { globalTimer = &m_visionTimer; } m_timer = globalTimer; m_visionVar.AddObject( this ); setValue( v ); } VisionClass::VisionClass() { value = 0.f; value_start = 0.f; value_target = 0.f; fProcessed = false; } VisionClass::VisionClass( const char *n, const char *v, ScriptTimer *globalTimer ) { VisionInit( n, v, globalTimer ); } void VisionClass::GlobalArchive( Archiver &arc ) { for( int i = 0; i < m_visionVar.NumObjects(); i++ ) { arc.ArchiveObject( m_visionVar[ i ] ); } } void VisionClass::Archive( Archiver &arc ) { Class::Archive( arc ); arc.ArchiveString( &string ); arc.ArchiveObject( m_timer ); arc.ArchiveFloat( &value ); arc.ArchiveFloat( &value_start ); arc.ArchiveFloat( &value_target ); arc.ArchiveBoolean( &fProcessed ); } str VisionClass::GetName() { return name; } str VisionClass::defaultValue() { return defaultval; } float VisionClass::floatValue() { return value; } str VisionClass::stringValue() { return string; } ScriptTimer *VisionClass::GetTimer() { return m_timer; } str VisionClass::GetType() { return ""; } qboolean VisionClass::isBasic() { return true; } qboolean VisionClass::isEnabled() { return true; } qboolean VisionClass::isNewEnabled() { return true; } void VisionClass::setFloatValue( float v ) { value_target = v; if( !render_inited ) { value = value_target; value_start = value_target; } else { value_start = value; } } void VisionClass::setValue( str v ) { float x; string = v; if( isdigit( *v ) ) { x = atof( v ); } else { x = 0.f; } value_target = x; if( !render_inited ) { value = value_target; value_start = value_target; } else { value_start = value; } } void VisionClass::Think() { if( !m_timer->isEnabled() ) { m_timer->Enable(); } value = m_timer->LerpValue( value_start, value_target ); } VisionActivator::VisionActivator( const char *n, const char *v, const char *t, ScriptTimer *globalTimer ) { VisionInit( n, v, globalTimer ); if( t == NULL ) { t = "none"; } vistype = t; } VisionActivator::VisionActivator() { } void VisionActivator::Archive( Archiver &arc ) { VisionClass::Archive( arc ); } str VisionActivator::GetType() { return vistype; } qboolean VisionActivator::isBasic() { return false; } qboolean VisionActivator::isEnabled() { return value > 0.0f || value_target > 0.0f; } qboolean VisionActivator::isNewEnabled() { return value_target > 0.0f; } void VisionActivator::setValue( str v ) { float floatvalue = ( float )atoi( v ); char newval[ MAX_STRING_TOKENS ]; sprintf( newval, "%f", floatvalue ); VisionClass::setValue( newval ); } VisionVariable::VisionVariable( const char *n, const char *v, VisionActivator *a ) { VisionInit( n, v, a->GetTimer() ); activator = a; } VisionVariable::VisionVariable() { } void VisionVariable::Archive( Archiver &arc ) { VisionClass::Archive( arc ); arc.ArchiveVector( &vector ); arc.ArchiveVector( &vector_start ); arc.ArchiveVector( &vector_target ); } VisionActivator *VisionVariable::GetActivator() { return activator; } ScriptTimer *VisionVariable::GetTimer() { return activator->GetTimer(); } str VisionVariable::GetType() { return activator->GetType(); } Vector VisionVariable::vectorValue() { return vector; } qboolean VisionVariable::isBasic() { return false; } qboolean VisionVariable::isEnabled() { if( !activator ) { return true; } return activator->isEnabled(); } qboolean VisionVariable::isNewEnabled() { if( !activator ) { return true; } return activator->isNewEnabled(); } void VisionVariable::setValue( str v ) { float x = 0.f, y = 0.f, z = 0.f; char buffer[ MAX_STRING_TOKENS ]; qboolean isVector; if( sscanf( v, "%f %f %f", &x, &y, &z ) == 3 ) { isVector = true; } else { isVector = false; } string = v; value_target = x; if( !isVector ) { vector_target = Vector( x, x, x ); } else { // Cast values into vector vector_target = Vector( x, y, z ); } if( !render_inited ) { vector = vector_target; vector_start = vector_target; value = value_target; value_start = value_target; } else { value_start = value; vector_start = vector; } } void VisionVariable::Think() { if( activator == NULL ) { return; } ScriptTimer *t = GetTimer(); if( !t->isEnabled() ) { t->Enable(); } vector = t->LerpValue( vector_start, vector_target ); value = t->LerpValue( value_start, value_target ); } CLASS_DECLARATION( Class, VisionActivator, NULL ) { { NULL, NULL } }; CLASS_DECLARATION( Class, VisionClass, NULL ) { { NULL, NULL } }; CLASS_DECLARATION( Class, VisionVariable, NULL ) { { NULL, NULL } };