[quake3-bugzilla] [Bug 5422] New flare code and bloom patch
bugzilla-daemon at icculus.org
bugzilla-daemon at icculus.org
Mon Jan 23 08:58:25 EST 2012
https://bugzilla.icculus.org/show_bug.cgi?id=5422
--- Comment #1 from rambokalle at bin-wieder-da.de 2012-01-23 08:58:22 EST ---
Comment on attachment 3074
--> https://bugzilla.icculus.org/attachment.cgi?id=3074
new flare code and bloom patch
>Index: code/renderer/tr_local.h
>===================================================================
>--- code/renderer/tr_local.h (Revision 2216)
>+++ code/renderer/tr_local.h (Arbeitskopie)
>@@ -903,6 +903,8 @@
> qboolean projection2D; // if qtrue, drawstretchpic doesn't need to change modes
> byte color2D[4];
> qboolean vertexes2D; // shader needs to be finished
>+ qboolean doneBloom; // done bloom this frame
>+ qboolean doneSurfaces; // done any 3d surfaces already
> trRefEntity_t entity2D; // currentEntity will point at this when doing 2D rendering
> } backEndState_t;
>
>@@ -1147,6 +1149,10 @@
>
> extern cvar_t *r_marksOnTriangleMeshes;
>
>+extern cvar_t *r_lensReflection1;
>+extern cvar_t *r_lensReflection2;
>+extern cvar_t *r_lensReflectionBrightness;
>+
> //====================================================================
>
> float R_NoiseGet4f( float x, float y, float z, float t );
>@@ -1361,6 +1367,7 @@
>
> extern shaderCommands_t tess;
>
>+void RB_SetGL2D (void);
> void RB_BeginSurface(shader_t *shader, int fogNum );
> void RB_EndSurface(void);
> void RB_CheckOverflow( int verts, int indexes );
>@@ -1747,5 +1754,8 @@
> void R_DoneFreeType( void );
> void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font);
>
>+//Bloom Stuff
>+void R_BloomInit( void );
>+void R_BloomScreen( void );
>
> #endif //TR_LOCAL_H
>Index: code/renderer/tr_init.c
>===================================================================
>--- code/renderer/tr_init.c (Revision 2216)
>+++ code/renderer/tr_init.c (Arbeitskopie)
>@@ -168,6 +168,11 @@
> cvar_t *r_maxpolyverts;
> int max_polyverts;
>
>+// tcpp
>+cvar_t *r_lensReflection1;
>+cvar_t *r_lensReflection2;
>+cvar_t *r_lensReflectionBrightness;
>+
> /*
> ** InitOpenGL
> **
>@@ -1127,6 +1132,10 @@
> r_maxpolys = ri.Cvar_Get( "r_maxpolys", va("%d", MAX_POLYS), 0);
> r_maxpolyverts = ri.Cvar_Get( "r_maxpolyverts", va("%d", MAX_POLYVERTS), 0);
>
>+ r_lensReflection1 = ri.Cvar_Get( "r_lensReflection1", "0" , 0); // sharp reflection
>+ r_lensReflection2 = ri.Cvar_Get( "r_lensReflection2", "0" , 0); // fuzzy reflection
>+ r_lensReflectionBrightness = ri.Cvar_Get( "r_lensReflectionBrightness", "0.5" , 0);
>+
> // make sure all the commands added here are also
> // removed in R_Shutdown
> ri.Cmd_AddCommand( "imagelist", R_ImageList_f );
>@@ -1199,6 +1208,8 @@
> R_NoiseInit();
>
> R_Register();
>+
>+ R_BloomInit();
>
> max_polys = r_maxpolys->integer;
> if (max_polys < MAX_POLYS)
>Index: code/renderer/tr_flares.c
>===================================================================
>--- code/renderer/tr_flares.c (Revision 2216)
>+++ code/renderer/tr_flares.c (Arbeitskopie)
>@@ -313,6 +313,7 @@
> int iColor[3];
> float distance, intensity, factor;
> byte fogFactors[3] = {255, 255, 255};
>+ int ind=0;
>
> backEnd.pc.c_flareRenders++;
>
>@@ -420,6 +421,194 @@
> tess.indexes[tess.numIndexes++] = 2;
> tess.indexes[tess.numIndexes++] = 3;
>
>+ ind+=4;
>+
>+ // reflections -- tcpparena
>+
>+ if(r_lensReflection1->integer){
>+
>+ // renders sharp lens flare.
>+
>+ float cx, cy;
>+ float dx, dy;
>+ float size2;
>+ const float poses[]= {-.15f, 0.6f, -.1f, -.6f, -1.8f};
>+ const float sizes[]= {0.14f, 0.2f, 0.1f, 0.2f, 1.0f};
>+ int brightness1[]= {8,25, 40, 26, 10}; // red
>+ int brightness2[]= {15,23, 25, 30, 5}; // green
>+ int brightness3[]= {12,20, 30, 28, 10}; // blue
>+ const float r3_2=0.866025403784439f;
>+ int n;
>+ cx=backEnd.viewParms.viewportX+(backEnd.viewParms.viewportWidth>>1);
>+ cy=backEnd.viewParms.viewportY+(backEnd.viewParms.viewportHeight>>1);
>+ for(n=0;n<5;n++){
>+ dx=(f->windowX-cx)*poses[n]+cx;
>+ dy=(f->windowY-cy)*poses[n]+cy;
>+ size2=sizes[n]*backEnd.viewParms.viewportWidth*.25f;
>+
>+ brightness1[n]=(int)(brightness1[n]*r_lensReflectionBrightness->value);
>+ brightness2[n]=(int)(brightness2[n]*r_lensReflectionBrightness->value);
>+ brightness3[n]=(int)(brightness3[n]*r_lensReflectionBrightness->value);
>+
>+ tess.xyz[tess.numVertexes][0] = dx-size2;
>+ tess.xyz[tess.numVertexes][1] = dy;
>+ tess.texCoords[tess.numVertexes][0][0] = .5f;
>+ tess.texCoords[tess.numVertexes][0][1] = .5f;
>+ tess.vertexColors[tess.numVertexes][0] = (iColor[0]*brightness1[n])>>8;
>+ tess.vertexColors[tess.numVertexes][1] = (iColor[1]*brightness2[n])>>8;
>+ tess.vertexColors[tess.numVertexes][2] = (iColor[2]*brightness3[n])>>8;
>+ tess.vertexColors[tess.numVertexes][3] = 255;
>+ tess.numVertexes++;
>+
>+ tess.xyz[tess.numVertexes][0] = dx-size2*.5f;
>+ tess.xyz[tess.numVertexes][1] = dy-size2*r3_2;
>+ tess.texCoords[tess.numVertexes][0][0] = .5f;
>+ tess.texCoords[tess.numVertexes][0][1] = .5f;
>+ tess.vertexColors[tess.numVertexes][0] = (iColor[0]*brightness1[n])>>8;
>+ tess.vertexColors[tess.numVertexes][1] = (iColor[1]*brightness2[n])>>8;
>+ tess.vertexColors[tess.numVertexes][2] = (iColor[2]*brightness3[n])>>8;
>+ tess.vertexColors[tess.numVertexes][3] = 255;
>+ tess.numVertexes++;
>+
>+ tess.xyz[tess.numVertexes][0] = dx+size2*.5f;
>+ tess.xyz[tess.numVertexes][1] = dy-size2*r3_2;
>+ tess.texCoords[tess.numVertexes][0][0] = .5f;
>+ tess.texCoords[tess.numVertexes][0][1] = .5f;
>+ tess.vertexColors[tess.numVertexes][0] = (iColor[0]*brightness1[n])>>8;
>+ tess.vertexColors[tess.numVertexes][1] = (iColor[1]*brightness2[n])>>8;
>+ tess.vertexColors[tess.numVertexes][2] = (iColor[2]*brightness3[n])>>8;
>+ tess.vertexColors[tess.numVertexes][3] = 255;
>+ tess.numVertexes++;
>+
>+ tess.xyz[tess.numVertexes][0] = dx+size2;
>+ tess.xyz[tess.numVertexes][1] = dy;
>+ tess.texCoords[tess.numVertexes][0][0] = .5f;
>+ tess.texCoords[tess.numVertexes][0][1] = .5f;
>+ tess.vertexColors[tess.numVertexes][0] = (iColor[0]*brightness1[n])>>8;
>+ tess.vertexColors[tess.numVertexes][1] = (iColor[1]*brightness2[n])>>8;
>+ tess.vertexColors[tess.numVertexes][2] = (iColor[2]*brightness3[n])>>8;
>+ tess.vertexColors[tess.numVertexes][3] = 255;
>+ tess.numVertexes++;
>+
>+ tess.xyz[tess.numVertexes][0] = dx+size2*.5f;
>+ tess.xyz[tess.numVertexes][1] = dy+size2*r3_2;
>+ tess.texCoords[tess.numVertexes][0][0] = .5f;
>+ tess.texCoords[tess.numVertexes][0][1] = .5f;
>+ tess.vertexColors[tess.numVertexes][0] = (iColor[0]*brightness1[n])>>8;
>+ tess.vertexColors[tess.numVertexes][1] = (iColor[1]*brightness2[n])>>8;
>+ tess.vertexColors[tess.numVertexes][2] = (iColor[2]*brightness3[n])>>8;
>+ tess.vertexColors[tess.numVertexes][3] = 255;
>+ tess.numVertexes++;
>+
>+ tess.xyz[tess.numVertexes][0] = dx-size2*.5f;
>+ tess.xyz[tess.numVertexes][1] = dy+size2*r3_2;
>+ tess.texCoords[tess.numVertexes][0][0] = .5f;
>+ tess.texCoords[tess.numVertexes][0][1] = .5f;
>+ tess.vertexColors[tess.numVertexes][0] = (iColor[0]*brightness1[n])>>8;
>+ tess.vertexColors[tess.numVertexes][1] = (iColor[1]*brightness2[n])>>8;
>+ tess.vertexColors[tess.numVertexes][2] = (iColor[2]*brightness3[n])>>8;
>+ tess.vertexColors[tess.numVertexes][3] = 255;
>+ tess.numVertexes++;
>+
>+ tess.indexes[tess.numIndexes++] = 2+ind;
>+ tess.indexes[tess.numIndexes++] = 1+ind;
>+ tess.indexes[tess.numIndexes++] = 0+ind;
>+ tess.indexes[tess.numIndexes++] = 3+ind;
>+ tess.indexes[tess.numIndexes++] = 2+ind;
>+ tess.indexes[tess.numIndexes++] = 0+ind;
>+ tess.indexes[tess.numIndexes++] = 4+ind;
>+ tess.indexes[tess.numIndexes++] = 3+ind;
>+ tess.indexes[tess.numIndexes++] = 0+ind;
>+ tess.indexes[tess.numIndexes++] = 5+ind;
>+ tess.indexes[tess.numIndexes++] = 4+ind;
>+ tess.indexes[tess.numIndexes++] = 0+ind;
>+
>+ ind+=6;
>+
>+ }
>+ }
>+
>+ if(r_lensReflection2->integer){
>+
>+ // renders fuzzy lens flare.
>+
>+ float cx, cy;
>+ float dx, dy;
>+ float size2;
>+ const float poses[]= {1.7f, -0.2f};
>+ const float sizes[]= {1.2f, 0.2f};
>+ int brightness1[]= {25, 40}; // red
>+ int brightness2[]= {35, 10}; // green
>+ int brightness3[]= {30, 15}; // blue
>+ int n;
>+ cx=backEnd.viewParms.viewportX+(backEnd.viewParms.viewportWidth>>1);
>+ cy=backEnd.viewParms.viewportY+(backEnd.viewParms.viewportHeight>>1);
>+
>+
>+ for(n=0;n<2;n++){
>+ dx=(f->windowX-cx)*poses[n]+cx;
>+ dy=(f->windowY-cy)*poses[n]+cy;
>+ size2=sizes[n]*backEnd.viewParms.viewportWidth*.25f;
>+
>+ brightness1[n]=(int)(brightness1[n]*r_lensReflectionBrightness->value);
>+ brightness2[n]=(int)(brightness2[n]*r_lensReflectionBrightness->value);
>+ brightness3[n]=(int)(brightness3[n]*r_lensReflectionBrightness->value);
>+
>+ tess.xyz[tess.numVertexes][0] = dx-size2;
>+ tess.xyz[tess.numVertexes][1] = dy-size2;
>+ tess.texCoords[tess.numVertexes][0][0] = 0.f;
>+ tess.texCoords[tess.numVertexes][0][1] = 0.f;
>+ tess.vertexColors[tess.numVertexes][0] = (iColor[0]*brightness1[n])>>8;
>+ tess.vertexColors[tess.numVertexes][1] = (iColor[1]*brightness2[n])>>8;
>+ tess.vertexColors[tess.numVertexes][2] = (iColor[2]*brightness3[n])>>8;
>+ tess.vertexColors[tess.numVertexes][3] = 255;
>+ tess.numVertexes++;
>+
>+ tess.xyz[tess.numVertexes][0] = dx-size2;
>+ tess.xyz[tess.numVertexes][1] = dy+size2;
>+ tess.texCoords[tess.numVertexes][0][0] = 0.f;
>+ tess.texCoords[tess.numVertexes][0][1] = 1.f;
>+ tess.vertexColors[tess.numVertexes][0] = (iColor[0]*brightness1[n])>>8;
>+ tess.vertexColors[tess.numVertexes][1] = (iColor[1]*brightness2[n])>>8;
>+ tess.vertexColors[tess.numVertexes][2] = (iColor[2]*brightness3[n])>>8;
>+ tess.vertexColors[tess.numVertexes][3] = 255;
>+ tess.numVertexes++;
>+
>+ tess.xyz[tess.numVertexes][0] = dx+size2;
>+ tess.xyz[tess.numVertexes][1] = dy+size2;
>+ tess.texCoords[tess.numVertexes][0][0] = 1.f;
>+ tess.texCoords[tess.numVertexes][0][1] = 1.f;
>+ tess.vertexColors[tess.numVertexes][0] = (iColor[0]*brightness1[n])>>8;
>+ tess.vertexColors[tess.numVertexes][1] = (iColor[1]*brightness2[n])>>8;
>+ tess.vertexColors[tess.numVertexes][2] = (iColor[2]*brightness3[n])>>8;
>+ tess.vertexColors[tess.numVertexes][3] = 255;
>+ tess.numVertexes++;
>+
>+ tess.xyz[tess.numVertexes][0] = dx+size2;
>+ tess.xyz[tess.numVertexes][1] = dy-size2;
>+ tess.texCoords[tess.numVertexes][0][0] = 1.f;
>+ tess.texCoords[tess.numVertexes][0][1] = 0.f;
>+ tess.vertexColors[tess.numVertexes][0] = (iColor[0]*brightness1[n])>>8;
>+ tess.vertexColors[tess.numVertexes][1] = (iColor[1]*brightness2[n])>>8;
>+ tess.vertexColors[tess.numVertexes][2] = (iColor[2]*brightness3[n])>>8;
>+ tess.vertexColors[tess.numVertexes][3] = 255;
>+ tess.numVertexes++;
>+
>+ tess.indexes[tess.numIndexes++] = 0+ind;
>+ tess.indexes[tess.numIndexes++] = 1+ind;
>+ tess.indexes[tess.numIndexes++] = 2+ind;
>+ tess.indexes[tess.numIndexes++] = 0+ind;
>+ tess.indexes[tess.numIndexes++] = 2+ind;
>+ tess.indexes[tess.numIndexes++] = 3+ind;
>+
>+ ind+=4;
>+
>+
>+ }
>+ }
>+
>+
>+
> RB_EndSurface();
> }
>
>Index: code/renderer/tr_bloom.c
>===================================================================
>--- code/renderer/tr_bloom.c (Revision 0)
>+++ code/renderer/tr_bloom.c (Revision 0)
>@@ -0,0 +1,446 @@
>+/*
>+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.
>+
>+*/
>+// tr_bloom.c: 2D lighting post process effect
>+
>+#include "tr_local.h"
>+
>+
>+static cvar_t *r_bloom;
>+static cvar_t *r_bloom_sample_size;
>+static cvar_t *r_bloom_fast_sample;
>+static cvar_t *r_bloom_alpha;
>+static cvar_t *r_bloom_darken;
>+static cvar_t *r_bloom_intensity;
>+static cvar_t *r_bloom_diamond_size;
>+
>+/*
>+==============================================================================
>+
>+ 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 struct {
>+ struct {
>+ image_t *texture;
>+ int width, height;
>+ float readW, readH;
>+ } effect;
>+ struct {
>+ image_t *texture;
>+ int width, height;
>+ float readW, readH;
>+ } screen;
>+ struct {
>+ int width, height;
>+ } work;
>+ qboolean started;
>+} bloom;
>+
>+
>+static void ID_INLINE R_Bloom_Quad( int width, int height, float texX, float texY, float texWidth, float texHeight ) {
>+ int x = 0;
>+ int y = 0;
>+ x = 0;
>+ y += glConfig.vidHeight - height;
>+ width += x;
>+ height += y;
>+
>+ texWidth += texX;
>+ texHeight += texY;
>+
>+ qglBegin( GL_QUADS );
>+ qglTexCoord2f( texX, texHeight );
>+ qglVertex2f( x, y );
>+
>+ qglTexCoord2f( texX, texY );
>+ qglVertex2f( x, height );
>+
>+ qglTexCoord2f( texWidth, texY );
>+ qglVertex2f( width, height );
>+
>+ qglTexCoord2f( texWidth, texHeight );
>+ qglVertex2f( width, y );
>+ qglEnd ();
>+}
>+
>+
>+/*
>+=================
>+R_Bloom_InitTextures
>+=================
>+*/
>+static void R_Bloom_InitTextures( void )
>+{
>+ byte *data;
>+
>+ // find closer power of 2 to screen size
>+ for (bloom.screen.width = 1;bloom.screen.width< glConfig.vidWidth;bloom.screen.width *= 2);
>+ for (bloom.screen.height = 1;bloom.screen.height < glConfig.vidHeight;bloom.screen.height *= 2);
>+
>+ bloom.screen.readW = glConfig.vidWidth / (float)bloom.screen.width;
>+ bloom.screen.readH = glConfig.vidHeight / (float)bloom.screen.height;
>+
>+ // find closer power of 2 to effect size
>+ bloom.work.width = r_bloom_sample_size->integer;
>+ bloom.work.height = bloom.work.width * ( glConfig.vidWidth / glConfig.vidHeight );
>+
>+ for (bloom.effect.width = 1;bloom.effect.width < bloom.work.width;bloom.effect.width *= 2);
>+ for (bloom.effect.height = 1;bloom.effect.height < bloom.work.height;bloom.effect.height *= 2);
>+
>+ bloom.effect.readW = bloom.work.width / (float)bloom.effect.width;
>+ bloom.effect.readH = bloom.work.height / (float)bloom.effect.height;
>+
>+
>+ // disable blooms if we can't handle a texture of that size
>+ if( bloom.screen.width > glConfig.maxTextureSize ||
>+ bloom.screen.height > glConfig.maxTextureSize ||
>+ bloom.effect.width > glConfig.maxTextureSize ||
>+ bloom.effect.height > glConfig.maxTextureSize ||
>+ bloom.work.width > glConfig.vidWidth ||
>+ bloom.work.height > glConfig.vidHeight
>+ ) {
>+ ri.Cvar_Set( "r_bloom", "0" );
>+ Com_Printf( S_COLOR_YELLOW"WARNING: 'R_InitBloomTextures' too high resolution for light bloom, effect disabled\n" );
>+ return;
>+ }
>+
>+ data = ri.Hunk_AllocateTempMemory( bloom.screen.width * bloom.screen.height * 4 );
>+ Com_Memset( data, 0, bloom.screen.width * bloom.screen.height * 4 );
>+ bloom.screen.texture = R_CreateImage( "***bloom screen texture***", data, bloom.screen.width, bloom.screen.height, qfalse, qfalse, qfalse );
>+ ri.Hunk_FreeTempMemory( data );
>+
>+ data = ri.Hunk_AllocateTempMemory( bloom.effect.width * bloom.effect.height * 4 );
>+ Com_Memset( data, 0, bloom.effect.width * bloom.effect.height * 4 );
>+ bloom.effect.texture = R_CreateImage( "***bloom effect texture***", data, bloom.effect.width, bloom.effect.height, qfalse, qfalse, qfalse );
>+ ri.Hunk_FreeTempMemory( data );
>+ bloom.started = qtrue;
>+}
>+
>+/*
>+=================
>+R_InitBloomTextures
>+=================
>+*/
>+void R_InitBloomTextures( void )
>+{
>+ if( !r_bloom->integer )
>+ return;
>+ memset( &bloom, 0, sizeof( bloom ));
>+ R_Bloom_InitTextures ();
>+}
>+
>+/*
>+=================
>+R_Bloom_DrawEffect
>+=================
>+*/
>+static void R_Bloom_DrawEffect( void )
>+{
>+ GL_Bind( bloom.effect.texture );
>+ GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
>+ qglColor4f( r_bloom_alpha->value, r_bloom_alpha->value, r_bloom_alpha->value, 1.0f );
>+ R_Bloom_Quad( glConfig.vidWidth, glConfig.vidHeight, 0, 0, bloom.effect.readW, bloom.effect.readW );
>+}
>+
>+
>+/*
>+=================
>+R_Bloom_GeneratexDiamonds
>+=================
>+*/
>+static void R_Bloom_WarsowEffect( void )
>+{
>+ int i, j, k;
>+ float intensity, scale, *diamond;
>+
>+
>+ qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
>+ //Take the backup texture and downscale it
>+ GL_Bind( bloom.screen.texture );
>+ GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
>+ R_Bloom_Quad( bloom.work.width, bloom.work.height, 0, 0, bloom.screen.readW, bloom.screen.readH );
>+ //Copy downscaled framebuffer into a texture
>+ GL_Bind( bloom.effect.texture );
>+ qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, bloom.work.width, bloom.work.height );
>+ // darkening passes with repeated filter
>+ if( r_bloom_darken->integer ) {
>+ int i;
>+ GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO );
>+
>+ for( i = 0; i < r_bloom_darken->integer; i++ ) {
>+ R_Bloom_Quad( bloom.work.width, bloom.work.height,
>+ 0, 0,
>+ bloom.effect.readW, bloom.effect.readH );
>+ }
>+ qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, bloom.work.width, bloom.work.height );
>+ }
>+ /* Copy the result to the effect texture */
>+ GL_Bind( bloom.effect.texture );
>+ qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, bloom.work.width, bloom.work.height );
>+
>+ // bluring passes, warsow uses a repeated semi blend on a selectable diamond grid
>+ qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
>+ GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE_MINUS_SRC_COLOR );
>+ if( r_bloom_diamond_size->integer > 7 || r_bloom_diamond_size->integer <= 3 ) {
>+ if( r_bloom_diamond_size->integer != 8 )
>+ ri.Cvar_Set( "r_bloom_diamond_size", "8" );
>+ } else if( r_bloom_diamond_size->integer > 5 ) {
>+ if( r_bloom_diamond_size->integer != 6 )
>+ ri.Cvar_Set( "r_bloom_diamond_size", "6" );
>+ } else if( r_bloom_diamond_size->integer > 3 ) {
>+ if( r_bloom_diamond_size->integer != 4 )
>+ ri.Cvar_Set( "r_bloom_diamond_size", "4" );
>+ }
>+
>+ switch( r_bloom_diamond_size->integer ) {
>+ case 4:
>+ k = 2;
>+ diamond = &Diamond4x[0][0];
>+ scale = r_bloom_intensity->value * 0.8f;
>+ break;
>+ case 6:
>+ k = 3;
>+ diamond = &Diamond6x[0][0];
>+ scale = r_bloom_intensity->value * 0.5f;
>+ break;
>+ default:
>+// case 8:
>+ k = 4;
>+ diamond = &Diamond8x[0][0];
>+ scale = r_bloom_intensity->value * 0.3f;
>+ break;
>+ }
>+
>+ for( i = 0; i < r_bloom_diamond_size->integer; i++ ) {
>+ for( j = 0; j < r_bloom_diamond_size->integer; j++, diamond++ ) {
>+ float x, y;
>+ intensity = *diamond * scale;
>+ if( intensity < 0.01f )
>+ continue;
>+ qglColor4f( intensity, intensity, intensity, 1.0 );
>+ x = (i - k) * ( 2 / 640.0f ) * bloom.effect.readW;
>+ y = (j - k) * ( 2 / 480.0f ) * bloom.effect.readH;
>+
>+ R_Bloom_Quad( bloom.work.width, bloom.work.height, x, y, bloom.effect.readW, bloom.effect.readH );
>+ }
>+ }
>+ qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, bloom.work.width, bloom.work.height );
>+}
>+
>+/*
>+=================
>+R_Bloom_BackupScreen
>+Backup the full original screen to a texture for downscaling and later restoration
>+=================
>+*/
>+static void R_Bloom_BackupScreen( void ) {
>+ GL_Bind( bloom.screen.texture );
>+ qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight );
>+}
>+/*
>+=================
>+R_Bloom_RestoreScreen
>+Restore the temporary framebuffer section we used with the backup texture
>+=================
>+*/
>+static void R_Bloom_RestoreScreen( void ) {
>+ GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
>+ GL_Bind( bloom.screen.texture );
>+ qglColor4f( 1, 1, 1, 1 );
>+ R_Bloom_Quad( bloom.work.width, bloom.work.height, 0, 0,
>+ bloom.work.width / (float)bloom.screen.width,
>+ bloom.work.height / (float)bloom.screen.height );
>+}
>+
>+
>+/*
>+=================
>+R_Bloom_DownsampleView
>+Scale the copied screen back to the sample size used for subsequent passes
>+=================
>+*/
>+/*static void R_Bloom_DownsampleView( void )
>+{
>+ // TODO, Provide option to control the color strength here /
>+// qglColor4f( r_bloom_darken->value, r_bloom_darken->value, r_bloom_darken->value, 1.0f );
>+ qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
>+ GL_Bind( bloom.screen.texture );
>+ GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
>+ //Downscale it
>+ R_Bloom_Quad( bloom.work.width, bloom.work.height, 0, 0, bloom.screen.readW, bloom.screen.readH );
>+#if 1
>+ GL_Bind( bloom.effect.texture );
>+ qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, bloom.work.width, bloom.work.height );
>+ // darkening passes
>+ if( r_bloom_darken->integer ) {
>+ int i;
>+ GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO );
>+
>+ for( i = 0; i < r_bloom_darken->integer; i++ ) {
>+ R_Bloom_Quad( bloom.work.width, bloom.work.height,
>+ 0, 0,
>+ bloom.effect.readW, bloom.effect.readH );
>+ }
>+ qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, bloom.work.width, bloom.work.height );
>+ }
>+#endif
>+ // Copy the result to the effect texture /
>+ GL_Bind( bloom.effect.texture );
>+ qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, bloom.work.width, bloom.work.height );
>+}
>+
>+static void R_Bloom_CreateEffect( void ) {
>+ int dir, x;
>+ int range;
>+
>+ //First step will zero dst, rest will one add
>+ GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
>+// GL_Bind( bloom.screen.texture );
>+ GL_Bind( bloom.effect.texture );
>+ range = 4;
>+ for (dir = 0;dir < 2;dir++)
>+ {
>+ // blend on at multiple vertical offsets to achieve a vertical blur
>+ // TODO: do offset blends using GLSL
>+ for (x = -range;x <= range;x++)
>+ {
>+ float xoffset, yoffset, r;
>+ if (!dir){
>+ xoffset = 0;
>+ yoffset = x*1.5;
>+ } else {
>+ xoffset = x*1.5;
>+ yoffset = 0;
>+ }
>+ xoffset /= bloom.work.width;
>+ yoffset /= bloom.work.height;
>+ // this r value looks like a 'dot' particle, fading sharply to
>+ // black at the edges
>+ // (probably not realistic but looks good enough)
>+ //r = ((range*range+1)/((float)(x*x+1)))/(range*2+1);
>+ //r = (dir ? 1.0f : brighten)/(range*2+1);
>+ r = 2.0f /(range*2+1)*(1 - x*x/(float)(range*range));
>+// r *= r_bloom_darken->value;
>+ qglColor4f(r, r, r, 1);
>+ R_Bloom_Quad( bloom.work.width, bloom.work.height,
>+ xoffset, yoffset,
>+ bloom.effect.readW, bloom.effect.readH );
>+// bloom.screen.readW, bloom.screen.readH );
>+ GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
>+ }
>+ }
>+ GL_Bind( bloom.effect.texture );
>+ qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, bloom.work.width, bloom.work.height );
>+}*/
>+
>+/*
>+=================
>+R_BloomScreen
>+=================
>+*/
>+void R_BloomScreen( void )
>+{
>+ if( !r_bloom->integer )
>+ return;
>+ if ( backEnd.doneBloom )
>+ return;
>+ if ( !backEnd.doneSurfaces )
>+ return;
>+ backEnd.doneBloom = qtrue;
>+ if( !bloom.started ) {
>+ R_Bloom_InitTextures();
>+ if( !bloom.started )
>+ return;
>+ }
>+
>+ if ( !backEnd.projection2D )
>+ RB_SetGL2D();
>+#if 0
>+ // set up full screen workspace
>+ GL_TexEnv( GL_MODULATE );
>+ qglScissor( 0, 0, glConfig.vidWidth, glConfig.vidHeight );
>+ qglViewport( 0, 0, glConfig.vidWidth, glConfig.vidHeight );
>+ qglMatrixMode( GL_PROJECTION );
>+ qglLoadIdentity ();
>+ qglOrtho( 0, glConfig.vidWidth, glConfig.vidHeight, 0, 0, 1 );
>+ qglMatrixMode( GL_MODELVIEW );
>+ qglLoadIdentity ();
>+
>+ GL_Cull( CT_TWO_SIDED );
>+#endif
>+
>+ qglColor4f( 1, 1, 1, 1 );
>+
>+ //Backup the old screen in a texture
>+ R_Bloom_BackupScreen();
>+ // create the bloom texture using one of a few methods
>+ R_Bloom_WarsowEffect ();
>+// R_Bloom_CreateEffect();
>+ // restore the screen-backup to the screen
>+ R_Bloom_RestoreScreen();
>+ // Do the final pass using the bloom texture for the final effect
>+ R_Bloom_DrawEffect ();
>+}
>+
>+
>+void R_BloomInit( void ) {
>+ memset( &bloom, 0, sizeof( bloom ));
>+
>+ r_bloom = ri.Cvar_Get( "r_bloom", "0", CVAR_ARCHIVE );
>+ r_bloom_alpha = ri.Cvar_Get( "r_bloom_alpha", "0.3", CVAR_ARCHIVE );
>+ r_bloom_diamond_size = ri.Cvar_Get( "r_bloom_diamond_size", "8", CVAR_ARCHIVE );
>+ r_bloom_intensity = ri.Cvar_Get( "r_bloom_intensity", "1.3", CVAR_ARCHIVE );
>+ r_bloom_darken = ri.Cvar_Get( "r_bloom_darken", "4", CVAR_ARCHIVE );
>+ r_bloom_sample_size = ri.Cvar_Get( "r_bloom_sample_size", "256", CVAR_ARCHIVE|CVAR_LATCH );
>+ r_bloom_fast_sample = ri.Cvar_Get( "r_bloom_fast_sample", "0", CVAR_ARCHIVE|CVAR_LATCH );
>+}
>+
Index: code/renderer/tr_backend.c
>===================================================================
>--- code/renderer/tr_backend.c (Revision 2216)
>+++ code/renderer/tr_backend.c (Arbeitskopie)
>@@ -944,6 +944,8 @@
> backEnd.refdef = cmd->refdef;
> backEnd.viewParms = cmd->viewParms;
>
>+ //TODO Maybe check for rdf_noworld stuff but q3mme has full 3d ui
>+ backEnd.doneSurfaces = qtrue;
> RB_RenderDrawSurfList( cmd->drawSurfs, cmd->numDrawSurfs );
>
> return (const void *)(cmd + 1);
>@@ -1119,6 +1121,9 @@
>
> backEnd.projection2D = qfalse;
>
>+ backEnd.doneBloom = qfalse;
>+ backEnd.doneSurfaces = qfalse;
>+
> return (const void *)(cmd + 1);
> }
>
>@@ -1149,6 +1154,8 @@
> data = RB_SetColor( data );
> break;
> case RC_STRETCH_PIC:
>+ //Check if it's time for BLOOM!
>+ R_BloomScreen();
> data = RB_StretchPic( data );
> break;
> case RC_DRAW_SURFS:
>@@ -1158,6 +1165,8 @@
> data = RB_DrawBuffer( data );
> break;
> case RC_SWAP_BUFFERS:
>+ //Check if it's time for BLOOM!
>+ R_BloomScreen();
> data = RB_SwapBuffers( data );
> break;
> case RC_SCREENSHOT:
>Index: Makefile
>===================================================================
>--- Makefile (Revision 2216)
>+++ Makefile (Arbeitskopie)
>@@ -1450,6 +1450,7 @@
> Q3ROBJ = \
> $(B)/renderer/tr_animation.o \
> $(B)/renderer/tr_backend.o \
>+ $(B)/renderer/tr_bloom.o \
> $(B)/renderer/tr_bsp.o \
> $(B)/renderer/tr_cmds.o \
> $(B)/renderer/tr_curve.o \
--
Configure bugmail: https://bugzilla.icculus.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
More information about the quake3-bugzilla
mailing list