[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