diff --git a/engine/Makefile b/engine/Makefile index c552cc786..7d6d415b3 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -220,6 +220,7 @@ GLQUAKE_OBJS = \ gl_rsurf.o \ ltface.o \ gl_screen.o \ + gl_bloom.o \ gl_backend.o \ gl_shader.o \ gl_warp.o \ diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 67c6882b1..d5ba59249 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -369,6 +369,7 @@ presetinfo_t preset[] = {"r_nolerp", {"1", "1", "0", "0", "0"}}, {"r_nolightdir", {"1", "0", "0", "0", "0"}}, {"r_dynamic", {"0", "0", "1", "1", "1"}}, + {"r_bloom", {"0", "0", "0", "0", "1"}}, {"gl_flashblend", {"0", "1", "0", "1", "2"}}, {"gl_bump", {"0", "0", "0", "1", "1"}}, {"gl_specular", {"0", "0", "0", "1", "1"}}, diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 3e1a6ccfa..bb6cf9a0c 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -127,7 +127,7 @@ cvar_t gl_savecompressedtex = SCVAR("gl_savecompressedtex", "0"); extern cvar_t gl_dither; extern cvar_t gl_maxdist; extern cvar_t gl_mindist; -extern cvar_t gl_bloom; + cvar_t gl_detail = SCVARF("gl_detail", "0", CVAR_ARCHIVE); cvar_t gl_detailscale = SCVAR("gl_detailscale", "5"); @@ -311,8 +311,6 @@ void GLRenderer_Init(void) Cvar_Register (&r_shadow_glsl_offsetmapping_scale, GRAPHICALNICETIES); Cvar_Register (&r_shadow_glsl_offsetmapping_bias, GRAPHICALNICETIES); - Cvar_Register (&gl_bloom, GRAPHICALNICETIES); - Cvar_Register (&gl_contrast, GLRENDEREROPTIONS); #ifdef R_XFLIP Cvar_Register (&r_xflip, GLRENDEREROPTIONS); @@ -365,6 +363,8 @@ void GLRenderer_Init(void) Cvar_Register (&gl_blendsprites, GLRENDEREROPTIONS); Cvar_Register (&gl_mylumassuck, GLRENDEREROPTIONS); + + R_BloomRegister(); } #endif #if defined(SWQUAKE) diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 712db3672..256b5afa7 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -1253,8 +1253,12 @@ void CMod_LoadTexInfo (lump_t *l) //yes I know these load from the same place // out->texture = r_notexture_mip; // texture not found // out->flags = 0; } - if (gl_shadeq2.value) - out->texture->shader = R_RegisterCustom (name, NULL); + +#ifdef RGLQUAKE + if (qrenderer == QR_OPENGL) + if (gl_shadeq2.value) + out->texture->shader = R_RegisterCustom (name, NULL); +#endif Q_strncpyz(out->texture->name, in->texture, sizeof(out->texture->name)); #if !defined(SERVERONLY) && defined(RGLQUAKE) diff --git a/engine/ftequake/ftequake.dsp b/engine/ftequake/ftequake.dsp index 6c00ab8f4..1f0f7bdc1 100644 --- a/engine/ftequake/ftequake.dsp +++ b/engine/ftequake/ftequake.dsp @@ -3042,6 +3042,41 @@ SOURCE=..\gl\gl_backend.c # End Source File # Begin Source File +SOURCE=..\gl\gl_bloom.c + +!IF "$(CFG)" == "ftequake - Win32 Release" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\gl\gl_draw.c !IF "$(CFG)" == "ftequake - Win32 Release" diff --git a/engine/gl/gl_bloom.c b/engine/gl/gl_bloom.c new file mode 100644 index 000000000..3d6b81390 --- /dev/null +++ b/engine/gl/gl_bloom.c @@ -0,0 +1,592 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// r_bloom.c: 2D lighting post process effect + + +//http://www.quakesrc.org/forums/viewtopic.php?t=4340&start=0 + +#include "quakedef.h" +#include "glquake.h" + +extern vrect_t scr_vrect; + +/* +============================================================================== + + LIGHT BLOOMS + +============================================================================== +*/ + +static float Diamond8x[8][8] = { + 0.0f, 0.0f, 0.0f, 0.1f, 0.1f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.2f, 0.3f, 0.3f, 0.2f, 0.0f, 0.0f, + 0.0f, 0.2f, 0.4f, 0.6f, 0.6f, 0.4f, 0.2f, 0.0f, + 0.1f, 0.3f, 0.6f, 0.9f, 0.9f, 0.6f, 0.3f, 0.1f, + 0.1f, 0.3f, 0.6f, 0.9f, 0.9f, 0.6f, 0.3f, 0.1f, + 0.0f, 0.2f, 0.4f, 0.6f, 0.6f, 0.4f, 0.2f, 0.0f, + 0.0f, 0.0f, 0.2f, 0.3f, 0.3f, 0.2f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.1f, 0.1f, 0.0f, 0.0f, 0.0f }; + +static float Diamond6x[6][6] = { + 0.0f, 0.0f, 0.1f, 0.1f, 0.0f, 0.0f, + 0.0f, 0.3f, 0.5f, 0.5f, 0.3f, 0.0f, + 0.1f, 0.5f, 0.9f, 0.9f, 0.5f, 0.1f, + 0.1f, 0.5f, 0.9f, 0.9f, 0.5f, 0.1f, + 0.0f, 0.3f, 0.5f, 0.5f, 0.3f, 0.0f, + 0.0f, 0.0f, 0.1f, 0.1f, 0.0f, 0.0f }; + +static float Diamond4x[4][4] = { + 0.3f, 0.4f, 0.4f, 0.3f, + 0.4f, 0.9f, 0.9f, 0.4f, + 0.4f, 0.9f, 0.9f, 0.4f, + 0.3f, 0.4f, 0.4f, 0.3f }; + + +static int BLOOM_SIZE; + +cvar_t r_bloom = FCVAR("r_bloom", "gl_bloom", "0", 0); +cvar_t r_bloom_alpha = SCVAR("r_bloom_alpha", "0.5"); +cvar_t r_bloom_diamond_size = SCVAR("r_bloom_diamond_size", "8"); +cvar_t r_bloom_intensity = SCVAR("r_bloom_intensity", "1"); +cvar_t r_bloom_darken = SCVAR("r_bloom_darken", "3"); +cvar_t r_bloom_sample_size = SCVARF("r_bloom_sample_size", "256", CVAR_RENDERERLATCH); +cvar_t r_bloom_fast_sample = SCVARF("r_bloom_fast_sample", "0", CVAR_RENDERERLATCH); + +int r_bloomscreentexture; +int r_bloomeffecttexture; +int r_bloombackuptexture; +int r_bloomdownsamplingtexture; + +static int r_screendownsamplingtexture_size; +static int screen_texture_width, screen_texture_height; +static int r_screenbackuptexture_size; + +//current refdef size: +static int curView_x; +static int curView_y; +static int curView_width; +static int curView_height; + +//texture coordinates of screen data inside screentexture +static float screenText_tcw; +static float screenText_tch; + +static int sample_width; +static int sample_height; + +//texture coordinates of adjusted textures +static float sampleText_tcw; +static float sampleText_tch; + +//this macro is in sample size workspace coordinates +#define R_Bloom_SamplePass( xpos, ypos ) \ + qglBegin(GL_QUADS); \ + qglTexCoord2f( 0, sampleText_tch); \ + qglVertex2f( xpos, ypos); \ + qglTexCoord2f( 0, 0); \ + qglVertex2f( xpos, ypos+sample_height); \ + qglTexCoord2f( sampleText_tcw, 0); \ + qglVertex2f( xpos+sample_width, ypos+sample_height); \ + qglTexCoord2f( sampleText_tcw, sampleText_tch); \ + qglVertex2f( xpos+sample_width, ypos); \ + qglEnd(); + +#define R_Bloom_Quad( x, y, width, height, textwidth, textheight ) \ + qglBegin(GL_QUADS); \ + qglTexCoord2f( 0, textheight); \ + qglVertex2f( x, y); \ + qglTexCoord2f( 0, 0); \ + qglVertex2f( x, y+height); \ + qglTexCoord2f( textwidth, 0); \ + qglVertex2f( x+width, y+height); \ + qglTexCoord2f( textwidth, textheight); \ + qglVertex2f( x+width, y); \ + qglEnd(); + + + +/* +================= +R_Bloom_InitBackUpTexture +================= +*/ +void R_Bloom_InitBackUpTexture( int width, int height ) +{ + qbyte *data; + + data = Z_Malloc( width * height * 4 ); + + r_screenbackuptexture_size = width; + + r_bloombackuptexture = GL_LoadTexture("***r_bloombackuptexture***", width, height, data, false, false ); + + Z_Free ( data ); +} + +/* +================= +R_Bloom_InitEffectTexture +================= +*/ +void R_Bloom_InitEffectTexture( void ) +{ + qbyte *data; + float bloomsizecheck; + + if( r_bloom_sample_size.value < 32 ) + Cvar_SetValue (&r_bloom_sample_size, 32); + + //make sure bloom size is a power of 2 + BLOOM_SIZE = r_bloom_sample_size.value; + bloomsizecheck = (float)BLOOM_SIZE; + while(bloomsizecheck > 1.0f) bloomsizecheck /= 2.0f; + if( bloomsizecheck != 1.0f ) + { + BLOOM_SIZE = 32; + while( BLOOM_SIZE < r_bloom_sample_size.value ) + BLOOM_SIZE *= 2; + } + + //make sure bloom size doesn't have stupid values + if( BLOOM_SIZE > screen_texture_width || + BLOOM_SIZE > screen_texture_height ) + BLOOM_SIZE = min( screen_texture_width, screen_texture_height ); + + if( BLOOM_SIZE != r_bloom_sample_size.value ) + Cvar_SetValue (&r_bloom_sample_size, BLOOM_SIZE); + + data = Z_Malloc( BLOOM_SIZE * BLOOM_SIZE * 4 ); + + r_bloomeffecttexture = GL_LoadTexture("***r_bloomeffecttexture***", BLOOM_SIZE, BLOOM_SIZE, data, false, false ); + + Z_Free ( data ); +} + +/* +================= +R_Bloom_InitTextures +================= +*/ +void R_Bloom_InitTextures( void ) +{ + qbyte *data; + int size; + int maxtexsize; + + //find closer power of 2 to screen size + for (screen_texture_width = 1;screen_texture_width < glwidth;screen_texture_width *= 2); + for (screen_texture_height = 1;screen_texture_height < glheight;screen_texture_height *= 2); + + //disable blooms if we can't handle a texture of that size + qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize); + if( screen_texture_width > maxtexsize || + screen_texture_height > maxtexsize ) { + screen_texture_width = screen_texture_height = 0; + Cvar_SetValue (&r_bloom, 0); + Con_Printf( "WARNING: 'R_InitBloomScreenTexture' too high resolution for Light Bloom. Effect disabled\n" ); + return; + } + + //init the screen texture + size = screen_texture_width * screen_texture_height * 4; + data = Z_Malloc( size ); + memset( data, 255, size ); + r_bloomscreentexture = GL_LoadTexture("***r_bloomscreentexture***", screen_texture_width, screen_texture_height, data, false, false ); + Z_Free ( data ); + + + //validate bloom size and init the bloom effect texture + R_Bloom_InitEffectTexture (); + + //if screensize is more than 2x the bloom effect texture, set up for stepped downsampling + r_bloomdownsamplingtexture = 0; + r_screendownsamplingtexture_size = 0; + if( glwidth > (BLOOM_SIZE * 2) && !r_bloom_fast_sample.value ) + { + r_screendownsamplingtexture_size = (int)(BLOOM_SIZE * 2); + data = Z_Malloc( r_screendownsamplingtexture_size * r_screendownsamplingtexture_size * 4 ); + r_bloomdownsamplingtexture = GL_LoadTexture("***r_bloomdownsamplingtexture***", r_screendownsamplingtexture_size, r_screendownsamplingtexture_size, data, false, false ); + Z_Free ( data ); + } + + //Init the screen backup texture + if( r_screendownsamplingtexture_size ) + R_Bloom_InitBackUpTexture( r_screendownsamplingtexture_size, r_screendownsamplingtexture_size ); + else + R_Bloom_InitBackUpTexture( BLOOM_SIZE, BLOOM_SIZE ); +} + +void R_BloomRegister(void) +{ + Cvar_Register (&r_bloom, "bloom"); + Cvar_Register (&r_bloom_alpha, "bloom"); + Cvar_Register (&r_bloom_diamond_size, "bloom"); + Cvar_Register (&r_bloom_intensity, "bloom"); + Cvar_Register (&r_bloom_darken, "bloom"); + Cvar_Register (&r_bloom_sample_size, "bloom"); + Cvar_Register (&r_bloom_fast_sample, "bloom"); +} + +/* +================= +R_InitBloomTextures +================= +*/ +void R_InitBloomTextures( void ) +{ + BLOOM_SIZE = 0; + if( !r_bloom.value ) + return; + + R_Bloom_InitTextures (); +} + + +/* +================= +R_Bloom_DrawEffect +================= +*/ +void R_Bloom_DrawEffect( void ) +{ + GL_Bind(r_bloomeffecttexture); + qglEnable(GL_BLEND); + qglBlendFunc(GL_ONE, GL_ONE); + qglColor4f(r_bloom_alpha.value, r_bloom_alpha.value, r_bloom_alpha.value, 1.0f); + GL_TexEnv(GL_MODULATE); + qglBegin(GL_QUADS); + qglTexCoord2f( 0, sampleText_tch ); + qglVertex2f( curView_x, curView_y ); + qglTexCoord2f( 0, 0 ); + qglVertex2f( curView_x, curView_y + curView_height ); + qglTexCoord2f( sampleText_tcw, 0 ); + qglVertex2f( curView_x + curView_width, curView_y + curView_height ); + qglTexCoord2f( sampleText_tcw, sampleText_tch ); + qglVertex2f( curView_x + curView_width, curView_y ); + qglEnd(); + + qglDisable(GL_BLEND); +} + + +#if 0 +/* +================= +R_Bloom_GeneratexCross - alternative bluring method +================= +*/ +void R_Bloom_GeneratexCross( void ) +{ + int i; + static int BLOOM_BLUR_RADIUS = 8; + //static float BLOOM_BLUR_INTENSITY = 2.5f; + float BLOOM_BLUR_INTENSITY; + static float intensity; + static float range; + + //set up sample size workspace + qglViewport( 0, 0, sample_width, sample_height ); + qglMatrixMode( GL_PROJECTION ); + qglLoadIdentity (); + qglOrtho(0, sample_width, sample_height, 0, -10, 100); + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity (); + + //copy small scene into r_bloomeffecttexture + GL_Bind(0, r_bloomeffecttexture); + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, sample_width, sample_height); + + //start modifying the small scene corner + qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); + qglEnable(GL_BLEND); + + //darkening passes + if( r_bloom_darken.value ) + { + qglBlendFunc(GL_DST_COLOR, GL_ZERO); + GL_TexEnv(GL_MODULATE); + + for(i=0; iinteger ;i++) { + R_Bloom_SamplePass( 0, 0 ); + } + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, sample_width, sample_height); + } + + //bluring passes + if( BLOOM_BLUR_RADIUS ) { + + qglBlendFunc(GL_ONE, GL_ONE); + + range = (float)BLOOM_BLUR_RADIUS; + + BLOOM_BLUR_INTENSITY = r_bloom_intensity.value; + //diagonal-cross draw 4 passes to add initial smooth + qglColor4f( 0.5f, 0.5f, 0.5f, 1.0); + R_Bloom_SamplePass( 1, 1 ); + R_Bloom_SamplePass( -1, 1 ); + R_Bloom_SamplePass( -1, -1 ); + R_Bloom_SamplePass( 1, -1 ); + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, sample_width, sample_height); + + for(i=-(BLOOM_BLUR_RADIUS+1);i 7 || r_bloom_diamond_size.value <= 3) + { + if( r_bloom_diamond_size.value != 8 ) Cvar_SetValue( &r_bloom_diamond_size, 8 ); + + for(i=0; i 5 ) { + + if( r_bloom_diamond_size.value != 6 ) Cvar_SetValue(&r_bloom_diamond_size, 6 ); + + for(i=0; i 3 ) { + + if( r_bloom_diamond_size.value != 4 ) Cvar_SetValue(&r_bloom_diamond_size, 4 ); + + for(i=0; i scr_vrect.width ) { + sampleText_tcw = ((float)scr_vrect.width / (float)scr_vrect.height); + sampleText_tch = 1.0f; + } else { + sampleText_tcw = 1.0f; + sampleText_tch = ((float)scr_vrect.height / (float)scr_vrect.width); + } + sample_width = BLOOM_SIZE * sampleText_tcw; + sample_height = BLOOM_SIZE * sampleText_tch; + + //copy the screen space we'll use to work into the backup texture + GL_Bind(r_bloombackuptexture); + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, r_screenbackuptexture_size * sampleText_tcw, r_screenbackuptexture_size * sampleText_tch); + + //create the bloom image + R_Bloom_DownsampleView(); + R_Bloom_GeneratexDiamonds(); + //R_Bloom_GeneratexCross(); + + //restore the screen-backup to the screen + qglDisable(GL_BLEND); + GL_Bind(r_bloombackuptexture); + qglColor4f( 1, 1, 1, 1 ); + R_Bloom_Quad( 0, + glheight - (r_screenbackuptexture_size * sampleText_tch), + r_screenbackuptexture_size * sampleText_tcw, + r_screenbackuptexture_size * sampleText_tch, + sampleText_tcw, + sampleText_tch ); + + R_Bloom_DrawEffect(); + + + qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} \ No newline at end of file diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index f9cb8b535..85bafe1fa 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -127,7 +127,6 @@ cvar_t gl_dither = SCVAR("gl_dither", "1"); cvar_t gl_maxdist = SCVAR("gl_maxdist", "8192"); cvar_t gl_mindist = SCVARF("gl_mindist", "4", CVAR_CHEAT); //by setting to 64 or something, you can use this as a wallhack -cvar_t gl_bloom = SCVAR("gl_bloom", "0"); extern cvar_t gl_motionblur; extern cvar_t gl_motionblurscale; @@ -2224,6 +2223,8 @@ void GLR_RenderView (void) // render mirror view R_Mirror (); + R_BloomBlend(); + R_PolyBlend (); // glDisable(GL_FOG); @@ -2437,87 +2438,6 @@ void GLR_RenderView (void) qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } -/* - if (scenepp_bloom_program && gl_bloom.value) - { - float cs, ct; - int vwidth = 1, vheight = 1; - if (gl_config.arb_texture_non_power_of_two) - { //we can use any size, supposedly - vwidth = glwidth; - vheight = glheight; - } - else - { //limit the texture size to square and use padding. - while (vwidth < glwidth) - vwidth *= 2; - while (vheight < glheight) - vheight *= 2; - } - GL_Bind(scenepp_texture); - - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - cs = (float)glwidth / vwidth; - ct = (float)glheight / vheight; - - // go 2d - qglDisable (GL_DEPTH_TEST); - qglDisable (GL_CULL_FACE); - qglDisable (GL_ALPHA_TEST); - qglDisable (GL_BLEND); - - qglMatrixMode(GL_PROJECTION); - qglPushMatrix(); - qglLoadIdentity (); - qglOrtho (0, glwidth, 0, glheight, -99999, 99999); - qglMatrixMode(GL_MODELVIEW); - qglPushMatrix(); - qglLoadIdentity (); -//grab the scene - qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0); - GLSlang_UseProgram(scenepp_bloom_program1); -//regurgitate the scene, but darker - qglBegin(GL_QUADS); - qglTexCoord2f(0, 0); - qglVertex2f(0, 0); - qglTexCoord2f(cs, 0); - qglVertex2f(glwidth, 0); - qglTexCoord2f(cs, ct); - qglVertex2f(glwidth, glheight); - qglTexCoord2f(0, ct); - qglVertex2f(0, glheight); - qglEnd(); - - GL_Bind(scenepp_texture2); -//grab the dark scene - qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0); - GLSlang_UseProgram(scenepp_bloom_program2); -//smear it all over the place, on a +/-8 pixel basis. -//blend with the origional scene in the fragment program too. - GL_MBind(1, scenepp_texture); - qglBegin(GL_QUADS); - qglTexCoord2f(0, 0); - qglVertex2f(0, 0); - qglTexCoord2f(cs, 0); - qglVertex2f(glwidth, 0); - qglTexCoord2f(cs, ct); - qglVertex2f(glwidth, glheight); - qglTexCoord2f(0, ct); - qglVertex2f(0, glheight); - qglEnd(); - - GL_MBind(0, scenepp_texture); - - GLSlang_UseProgram(0); - - qglMatrixMode(GL_PROJECTION); - qglPopMatrix(); - qglMatrixMode(GL_MODELVIEW); - qglPopMatrix(); - } - */ } #endif diff --git a/engine/gl/gl_rmisc.c b/engine/gl/gl_rmisc.c index 5580289f6..639d6cebb 100644 --- a/engine/gl/gl_rmisc.c +++ b/engine/gl/gl_rmisc.c @@ -468,6 +468,8 @@ void GLR_ReInit (void) else normalisationCubeMap = 0; + R_InitBloomTextures(); + } /* typedef struct diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index f915ee4f7..f96c6eed5 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -19,6 +19,7 @@ void (APIENTRY *qglColor4ub) (GLubyte red, GLubyte green, GLubyte blue, GLubyte void (APIENTRY *qglColor4ubv) (const GLubyte *v); void (APIENTRY *qglColorMask) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void (APIENTRY *qglCopyTexImage2D) (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +void (APIENTRY *qglCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); void (APIENTRY *qglCullFace) (GLenum mode); void (APIENTRY *qglDepthFunc) (GLenum func); void (APIENTRY *qglDepthMask) (GLboolean flag); @@ -487,6 +488,7 @@ void GL_Init(void *(*getglfunction) (char *name)) qglColor4ubv = (void *)getglcore("glColor4ubv"); qglColorMask = (void *)getglcore("glColorMask"); qglCopyTexImage2D = (void *)getglcore("glCopyTexImage2D"); + qglCopyTexSubImage2D= (void *)getglcore("glCopyTexSubImage2D"); qglCullFace = (void *)getglcore("glCullFace"); qglDepthFunc = (void *)getglcore("glDepthFunc"); qglDepthMask = (void *)getglcore("glDepthMask");