- Eye tracking

- GLSL Color control WIP
- 'crazy' lighitng WIP
- GLSL Motion blur WIP. Currently VRAM heavy
- Attempt at fallback shaders, which doesn't work right now.
This commit is contained in:
leilei-
2014-05-18 17:04:26 -04:00
parent 6eaf168ab7
commit 0f734a2ed2
32 changed files with 2321 additions and 55 deletions

View File

@@ -1301,6 +1301,7 @@ makedirs:
@if [ ! -d $(B)/renderergl2 ];then $(MKDIR) $(B)/renderergl2;fi
@if [ ! -d $(B)/renderergl2/glsl ];then $(MKDIR) $(B)/renderergl2/glsl;fi
@if [ ! -d $(B)/renderer_oa ];then $(MKDIR) $(B)/renderer_oa;fi
@if [ ! -d $(B)/renderer_oa/glsl ];then $(MKDIR) $(B)/renderer_oa/glsl;fi
@if [ ! -d $(B)/renderersoft ];then $(MKDIR) $(B)/renderersoft;fi
@if [ ! -d $(B)/ded ];then $(MKDIR) $(B)/ded;fi
@if [ ! -d $(B)/$(BASEGAME) ];then $(MKDIR) $(B)/$(BASEGAME);fi
@@ -1720,6 +1721,26 @@ Q3ROAOBJ = \
$(B)/renderergl1/sdl_gamma.o \
$(B)/renderergl1/sdl_glimp.o
Q3ROASTRINGOBJ = \
$(B)/renderer_oa/glsl/anime_fp.o \
$(B)/renderer_oa/glsl/anime_vp.o \
$(B)/renderer_oa/glsl/anime_film_fp.o \
$(B)/renderer_oa/glsl/anime_film_vp.o \
$(B)/renderer_oa/glsl/brightness_fp.o \
$(B)/renderer_oa/glsl/brightness_vp.o \
$(B)/renderer_oa/glsl/leifx_dither_fp.o \
$(B)/renderer_oa/glsl/leifx_dither_vp.o \
$(B)/renderer_oa/glsl/leifx_filter_fp.o \
$(B)/renderer_oa/glsl/leifx_filter_vp.o \
$(B)/renderer_oa/glsl/leifx_gamma_fp.o \
$(B)/renderer_oa/glsl/leifx_gamma_vp.o \
$(B)/renderer_oa/glsl/leifx_vgasignal_fp.o \
$(B)/renderer_oa/glsl/leifx_vgasignal_vp.o \
$(B)/renderer_oa/glsl/motionblur_accum_fp.o \
$(B)/renderer_oa/glsl/motionblur_accum_vp.o \
$(B)/renderer_oa/glsl/motionblur_post_fp.o \
$(B)/renderer_oa/glsl/motionblur_post_vp.o
Q3ROBJ = \
$(B)/renderergl1/tr_animation.o \
@@ -2149,9 +2170,9 @@ $(B)/renderer_opengl2_$(SHLIBNAME): $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ)
$(Q)$(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ) \
$(THREAD_LIBS) $(LIBSDLMAIN) $(RENDERER_LIBS) $(LIBS)
$(B)/renderer_openarena1_$(SHLIBNAME): $(Q3ROAOBJ) $(JPGOBJ)
$(B)/renderer_openarena1_$(SHLIBNAME): $(Q3ROAOBJ) $(Q3ROASTRINGOBJ) $(JPGOBJ)
$(echo_cmd) "LD $@"
$(Q)$(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(Q3ROAOBJ) $(JPGOBJ) \
$(Q)$(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(Q3ROASTRINGOBJ) $(Q3ROAOBJ) $(JPGOBJ) \
$(THREAD_LIBS) $(LIBSDLMAIN) $(RENDERER_LIBS) $(LIBS)
$(B)/renderer_software_$(SHLIBNAME): $(Q3RSOFTOBJ) $(JPGOBJ)
@@ -2161,10 +2182,10 @@ $(B)/renderer_software_$(SHLIBNAME): $(Q3RSOFTOBJ) $(JPGOBJ)
else
$(B)/$(CLIENTBIN)$(FULLBINEXT): $(Q3OBJ) $(Q3ROAOBJ) $(JPGOBJ) $(LIBSDLMAIN)
$(B)/$(CLIENTBIN)$(FULLBINEXT): $(Q3OBJ) $(Q3ROASTRINGOBJ) $(Q3ROAOBJ) $(JPGOBJ) $(LIBSDLMAIN)
$(echo_cmd) "LD $@"
$(Q)$(CC) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) \
-o $@ $(Q3OBJ) $(Q3ROAOBJ) $(JPGOBJ) \
-o $@ $(Q3OBJ) $(Q3ROASTRINGOBJ) $(Q3ROAOBJ) $(JPGOBJ) \
$(LIBSDLMAIN) $(CLIENT_LIBS) $(RENDERER_LIBS) $(LIBS)
$(B)/$(CLIENTBIN)_opengl2$(FULLBINEXT): $(Q3OBJ) $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ) $(LIBSDLMAIN)
@@ -2705,6 +2726,12 @@ $(B)/renderer_oa/%.o: $(ROADIR)/%.c
$(B)/renderer_oa/%.o: $(RCOMMONDIR)/%.c
$(DO_REF_CC)
$(B)/renderer_oa/glsl/%.c: $(ROADIR)/glsl/%.glsl
$(DO_REF_STR)
$(B)/renderer_oa/glsl/%.o: $(B)/renderer_oa/glsl/%.c
$(DO_REF_CC)
$(B)/renderersoft/%.o: $(CMDIR)/%.c
$(DO_REF_CC)
@@ -2848,7 +2875,7 @@ OBJ = $(Q3OBJ) $(Q3ROBJ) $(Q3R2OBJ) $(Q3ROAOBJ) $(Q3RSOFTOBJ) $(Q3DOBJ) $(JPGOBJ
$(MPGOBJ) $(Q3GOBJ) $(Q3CGOBJ) $(MPCGOBJ) $(Q3UIOBJ) $(MPUIOBJ) \
$(MPGVMOBJ) $(Q3GVMOBJ) $(Q3CGVMOBJ) $(MPCGVMOBJ) $(Q3UIVMOBJ) $(MPUIVMOBJ)
TOOLSOBJ = $(LBURGOBJ) $(Q3CPPOBJ) $(Q3RCCOBJ) $(Q3LCCOBJ) $(Q3ASMOBJ)
STRINGOBJ = $(Q3R2STRINGOBJ)
STRINGOBJ = $(Q3R2STRINGOBJ) $(Q3ROASTRINGOBJ)
copyfiles: release

View File

@@ -24,7 +24,7 @@ USE_CODEC_XMP=1
USE_CURL=0
# This doesn't work with OpenArena yet
BUILD_RENDERER_OPENGL2=1
BUILD_RENDERER_OPENGL2=0
# You can disable the renderer libraries and build in the OA renderer by default
USE_RENDERER_DLOPEN=1

View File

@@ -0,0 +1,186 @@
// Anime film video cassette shader
//
// Copyright (C) 2014 leilei
//
// 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.
uniform sampler2D u_Texture0;
varying vec2 texture_coordinate;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
#define PIXELWIDTH 2.96f
#define BLURAMOUNT 0.8f
float rand(float yeah){
vec2 hah;
float what = yeah;
float eh = texture_coordinate.x;
float ea = texture_coordinate.y;
hah.x = what + eh;
hah.y = what + ea;
return fract(sin(dot(hah.xy ,vec2(7445,7953))) * 45543.6353);
}
void main()
{
vec2 px; // shut
px.x = u_ScreenToNextPixelX;
px.y = u_ScreenToNextPixelY;
gl_FragColor = texture2D(u_Texture0, texture_coordinate);
vec2 chromar = texture_coordinate;
vec2 chromag = texture_coordinate;
vec2 chromab = texture_coordinate;
float lerma = gl_FragColor.rgb;
float larma = lerma * 5;
int errt;
float blendy; // to blend unblended with blend... trying to smooth the jag :(
float blenda;
vec4 smere;
vec4 blursum;
//
// Lame Chromatic stuff
//
vec2 resolution;
resolution.x = u_ScreenSizeX;
resolution.y = u_ScreenSizeY;
resolution.x = texture_coordinate.x;
resolution.y = texture_coordinate.y;
vec3 chromaoffset;
vec3 chromaoffsety;
vec3 chromatest;
vec2 chromanudge;
float signal = 0.5f;
float signaly = 0.5f;
float phosph = 50.0f;
vec3 fropsh;
fropsh.r = phosph * (gl_FragColor.r);
fropsh.g = phosph * (gl_FragColor.g);
fropsh.b = phosph * (gl_FragColor.b);
//
// Really cheesy barrel effect
//
// By the way, this is completely wrong and will mess up in higher resolutions.
// It's also slow as hell.
//
float chromabarrel = sin(resolution.x * 1.5) + 0.04f;
if (chromabarrel > 0.5) chromabarrel = chromabarrel * -1 + 1;
float chromabarrelx = sin(resolution.y * 1.5) + 0.04f;
if (chromabarrelx > 0.5) chromabarrelx = chromabarrelx * -1 + 1;
chromabarrel = pow (chromabarrel, 0.1f);
chromabarrelx = pow (chromabarrelx, 0.1f);
chromabarrel = pow(1 - chromabarrel, 1.5f);
chromabarrelx = pow(1 - chromabarrelx, 1.5f);
signal = chromabarrel * phosph;
signaly = chromabarrelx * phosph;
chromaoffset.r = px.x * (chromabarrel * fropsh.r);
chromaoffset.g = 0;
chromaoffset.b = px.x * ((chromabarrel * fropsh.b) * -1);
chromaoffsety.r = px.y * (chromabarrelx * fropsh.r);
chromaoffsety.g = 0;
chromaoffsety.b = px.y * ((chromabarrelx * fropsh.b) * -1);
vec2 chroar;
vec2 chroag;
vec2 chroab;
chroar.x = chromaoffset.r; chroar.y = chromaoffsety.r;
chroag.x = chromaoffset.g; chroag.y = chromaoffsety.g;
chroab.x = chromaoffset.b; chroab.y = chromaoffsety.b;
vec3 chroma4 = texture2D(u_Texture0, texture_coordinate+chroar);
vec3 chroma5 = texture2D(u_Texture0, texture_coordinate+chroag);
vec3 chroma6 = texture2D(u_Texture0, texture_coordinate+chroab);
chromatest.rgb = vec3(chroma4.r, chroma5.g, chroma6.b);
//
//
// Soft luminance blur from the analog quantization
// Also makes things look painterly and causes outlines to be softer
//
int ertdiv = 4;
for(errt=1; errt <28;errt+=ertdiv){
float blendfactor;
float yerp = 0.08f * errt * (larma * 0.6f + 0.03f);
vec4 pixel1 = texture2D(u_Texture0, texture_coordinate + vec2(px.x * yerp, px.y * yerp) );
vec4 pixel2 = texture2D(u_Texture0, texture_coordinate + vec2(-px.x * yerp, -px.y * yerp) );
vec4 pixel0 = texture2D(u_Texture0, texture_coordinate + vec2(0, 0) );
vec4 pixel3 = texture2D(u_Texture0, texture_coordinate + vec2(px.x * yerp, -px.y * yerp) );
vec4 pixel4 = texture2D(u_Texture0, texture_coordinate + vec2(-px.x * yerp, px.y * yerp) );
// chroma blur lol
vec4 rpixel1 = texture2D(u_Texture0, texture_coordinate + vec2(px.x * yerp, px.y * yerp) +chroar );
vec4 rpixel2 = texture2D(u_Texture0, texture_coordinate + vec2(-px.x * yerp, -px.y * yerp)+chroar );
vec4 rpixel0 = texture2D(u_Texture0, texture_coordinate + vec2(0, 0)+chroab );
vec4 rpixel3 = texture2D(u_Texture0, texture_coordinate + vec2(px.x * yerp, -px.y * yerp)+chroar );
vec4 rpixel4 = texture2D(u_Texture0, texture_coordinate + vec2(-px.x * yerp, px.y * yerp)+chroar );
vec4 bpixel1 = texture2D(u_Texture0, texture_coordinate + vec2(px.x * yerp, px.y * yerp)+chroab );
vec4 bpixel2 = texture2D(u_Texture0, texture_coordinate + vec2(-px.x * yerp, -px.y * yerp)+chroab );
vec4 bpixel0 = texture2D(u_Texture0, texture_coordinate + vec2(0, 0)+chroab );
vec4 bpixel3 = texture2D(u_Texture0, texture_coordinate + vec2(px.x * yerp, -px.y * yerp)+chroab );
vec4 bpixel4 = texture2D(u_Texture0, texture_coordinate + vec2(-px.x * yerp, px.y * yerp)+chroab );
pixel1.r = rpixel1.r;
pixel2.r = rpixel2.r;
pixel0.r = rpixel0.r;
pixel3.r = rpixel3.r;
pixel4.r = rpixel4.r;
pixel1.b = bpixel1.b;
pixel2.b = bpixel2.b;
pixel0.b = bpixel0.b;
pixel3.b = bpixel3.b;
pixel4.b = bpixel4.b;
blursum += ((pixel1 + pixel2) + (pixel3 + pixel4)) / 4;
}
float grane = rand(blursum.r + blursum.g + blursum.b / 3);
if (grane > 1.1f) grane = 1.1f;
if (grane < 0.88f) grane = 0.88f;
gl_FragColor.rgb = blursum / (errt / ertdiv) * grane;
}

View File

@@ -0,0 +1,20 @@
#version 120
varying vec2 texture_coordinate;
varying vec2 texture_coordinate2;
varying vec2 texture_coordinate3;
varying vec2 texture_coordinate4;
varying vec2 texture_coordinate5;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
varying float scale;
void main()
{
scale=0.7;
// Transforming The Vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Passing The Texture Coordinate Of Texture Unit 0 To The Fragment Shader
texture_coordinate = vec2(gl_MultiTexCoord0);
}

View File

@@ -0,0 +1,140 @@
/*
1980s japanimation ^_^
Copyright (C) 2014 leilei
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.
*/
uniform sampler2D u_Texture0;
uniform sampler2D u_Texture1;
uniform sampler2D u_Texture2;
uniform sampler2D u_Texture3;
uniform sampler2D u_Texture4;
uniform sampler2D u_Texture5;
uniform sampler2D u_Texture6;
varying vec2 texture_coordinate;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_Time;
#define color_enhance 1.3
#define color_saturation 1.5
// Edges
uniform sampler2D u_Texture7;
varying vec2 texture_coordinate2;
varying vec2 texture_coordinate3;
varying vec2 texture_coordinate4;
varying vec2 texture_coordinate5;
uniform float u_zFar;
#define USE_GRAIN = 0; // film grain effect
float LinearizeDepth(vec2 uv)
{
float n = 8.0; // camera z near
float f = u_zFar; // camera z far
float z = texture2D(u_Texture7, uv).a;
return (2.0 * n) / (f + n - z * (f - n));
}
float crosshatchtfable[16] = {
16,3,0,4,
16,4,0,3,
16,3,0,4,
16,4,0,3
};
float crosshatchtable[16] = {
0,5,16,9,
7,0,5,16,
16,7,0,5,
3,16,7,0
};
// for the spectrumish effect in the bloom
vec4 shinetable[16] = {
vec4(1.0f, 1.0f, 1.0f, 1),
vec4(1.0f, 1.0f, 1.0f, 1),
vec4(1.0f, 1.0f, 1.0f, 1),
vec4(0.9f, 1.0f, 1.0f, 1),
vec4(0.6f, 0.8f, 1.0f, 1),
vec4(0.3f, 0.5f, 1.0f, 1),
vec4(0.1f, 0.3f, 1.0f, 1),
vec4(0.1f, 0.4f, 0.7f, 1),
vec4(0.1f, 0.7f, 0.5f, 1),
vec4(0.1f, 1.0f, 0.2f, 1),
vec4(0.2f, 0.8f, 0.1f, 1),
vec4(0.5f, 0.5f, 0.07f, 1),
vec4(0.7f, 0.3f, 0.05f, 1),
vec4(1.0f, 0.0f, 0.0f, 1)
};
vec3 spectrumtable[4] = {
vec3(1.0f, 1.0f, 1.0f),
vec3(0.0f, 0.6f, 1.0f),
vec3(0.0f, 1.0f, 0.0f),
vec3(1.0f, 0.0f, 0.0f)
};
vec4 spectralfade(float faed) {
vec4 yeah;
float frade = faed;
frade = pow(faed, 0.2f);
vec3 spec0 = spectrumtable[0];
vec3 spec1 = spectrumtable[1];
vec3 spec2 = spectrumtable[2];
vec3 spec3 = spectrumtable[3];
//float sperc0 = * 0.25;
//yeah
if (frade < 0.25) yeah.rgb = spectrumtable[0];
else if (frade < 0.5) yeah.rgb = spectrumtable[1];
else if (frade < 0.75) yeah.rgb = spectrumtable[2];
else if (frade < 1.0) yeah.rgb = spectrumtable[3];
faed -= 0.3f;
if (faed < 0) faed = 0;
yeah.rgb = faed;
return yeah;
}
float rand(float yeah){
vec2 hah;
float what = yeah;
float eh = texture_coordinate.x;
float ea = texture_coordinate.y;
hah.x = what + eh;
hah.y = what + ea;
return fract(sin(dot(hah.xy ,vec2(7445,7953))) * 45543.6353);
}
void main()
{
// Sampling The Texture And Passing It To The Frame Buffer
gl_FragColor = texture2D(u_Texture0, texture_coordinate);
// Stubbed because I need to finish my shader.
}

View File

@@ -0,0 +1,34 @@
varying vec2 texture_coordinate;
varying vec2 texture_coordinate2;
varying vec2 texture_coordinate3;
varying vec2 texture_coordinate4;
varying vec2 texture_coordinate5;
varying float scale;
uniform float u_ScreenToNextPixelX;
uniform float u_Time;
uniform float u_ScreenToNextPixelY;
void main()
{
scale=116.0;
vec2 eh;
eh.x = u_ScreenToNextPixelX * scale;
eh.y = u_ScreenToNextPixelX * scale;
// Transforming The Vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Passing The Texture Coordinate Of Texture Unit 0 To The Fragment Shader
texture_coordinate = vec2(gl_MultiTexCoord0);
texture_coordinate2 = vec2(gl_MultiTexCoord0);
texture_coordinate2.x=texture_coordinate.x-0.003*eh.x;
texture_coordinate3 = vec2(gl_MultiTexCoord0);
texture_coordinate3.x=texture_coordinate.x+0.003*eh.x;
texture_coordinate4 = vec2(gl_MultiTexCoord0);
texture_coordinate4.y=texture_coordinate.y-0.003*eh.y;
texture_coordinate5 = vec2(gl_MultiTexCoord0);
texture_coordinate5.y=texture_coordinate.y+0.003*eh.y;
}

View File

@@ -0,0 +1,72 @@
// Color control shaders
//
// Copyright (C) 2013-2014 leilei
//
// 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.
uniform sampler2D u_Texture0;
varying vec2 texture_coordinate;
uniform float u_CC_Overbright;
uniform float u_CC_Brightness;
uniform float u_CC_Gamma;
uniform float u_CC_Contrast;
uniform float u_CC_Saturation;
float erroredtable[16] = {
14,4,15,1,
8,12,5,10,
15,2,14,3,
6,12,7,11
};
void main()
{
gl_FragColor = texture2D(u_Texture0, texture_coordinate);
// Dither setup...
vec4 OldColor; // compare differences for amplifying a correctional dither...
float OldCol = 2.0f / 255;
int ditdex = int(mod(gl_FragCoord.x, 4.0)) * 4 + int(mod(gl_FragCoord.y, 4.0)); // 4x4!
// looping through a lookup table matrix
vec3 color;
vec3 colord;
int coloredr;
int coloredg;
int coloredb;
color.r = 1;
color.g = 1;
color.b = 1;
int yeh = 0;
float ohyes;
for (yeh=ditdex; yeh<(ditdex+16); yeh++) ohyes = erroredtable[yeh-15];
ohyes = floor(ohyes) / 24;
OldColor = OldCol; // reset oldcolor
// Overbrights
gl_FragColor *= (u_CC_Overbright + 1);
OldColor *= (u_CC_Overbright + 1);
gl_FragColor.rgb += (ohyes * OldColor.rgb); // dither this stage
OldColor = OldCol; // reset oldcolor
// Gamma Correction
float gamma = u_CC_Gamma;
gl_FragColor.r = pow(gl_FragColor.r, 1.0 / gamma);
gl_FragColor.g = pow(gl_FragColor.g, 1.0 / gamma);
gl_FragColor.b = pow(gl_FragColor.b, 1.0 / gamma);
OldColor.r = pow(OldColor.r, 1.0 / gamma);
OldColor.g = pow(OldColor.g, 1.0 / gamma);
OldColor.b = pow(OldColor.b, 1.0 / gamma);
gl_FragColor.rgb += (ohyes * OldColor.rgb); // dither this stage
}

View File

@@ -0,0 +1,22 @@
varying vec2 texture_coordinate;
varying vec2 texture_coordinate2;
varying vec2 texture_coordinate3;
varying vec2 texture_coordinate4;
varying vec2 texture_coordinate5;
varying float scale;
uniform float u_CC_Overbright;
uniform float u_CC_Brightness;
uniform float u_CC_Gamma;
uniform float u_CC_Contrast;
uniform float u_CC_Saturation;
void main()
{
scale=0.7;
// Transforming The Vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Passing The Texture Coordinate Of Texture Unit 0 To The Fragment Shader
texture_coordinate = vec2(gl_MultiTexCoord0);
}

View File

@@ -0,0 +1,100 @@
// LeiFX shader - Pixel dithering and reduction process
//
// Copyright (C) 2013-2014 leilei
//
// 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.
uniform sampler2D u_Texture0;
varying vec2 texture_coordinate;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
// This table came from the wikipedia article about Ordered Dithering. NOT MAME. Just to clarify.
float erroredtable[16] = {
16,4,13,1,
8,12,5,9,
14,2,15,3,
6,10,7,11
};
void main()
{
// Sampling The Texture And Passing It To The Frame Buffer
gl_FragColor = texture2D(u_Texture0, texture_coordinate);
vec4 what;
what.x = 1; // shut
what.y = 1; // up
what.z = 1; // warnings
vec4 huh;
// *****************
// STAGE 0
// Grab our sampled pixels for processing......
// *****************
vec2 px; // shut
float egh = 1.0f;
px.x = u_ScreenToNextPixelX;
px.y = u_ScreenToNextPixelY;
vec4 pe1 = texture2D(u_Texture0, texture_coordinate); // first pixel...
// *****************
// STAGE 1
// Ordered dither with lookup table
// *****************
int ditdex = int(mod(gl_FragCoord.x, 4.0)) * 4 + int(mod(gl_FragCoord.y, 4.0)); // 4x4!
vec3 color;
vec3 colord;
int coloredr;
int coloredg;
int coloredb;
color.r = gl_FragColor.r * 255;
color.g = gl_FragColor.g * 255;
color.b = gl_FragColor.b * 255;
int yeh = 0;
float ohyes;
// looping through a lookup table matrix
for (yeh=ditdex; yeh<(ditdex+16); yeh++) ohyes = erroredtable[yeh-15];
//ohyes = pow(ohyes, 0.92f) - 3;
ohyes = floor(ohyes) - 6;
colord.r = color.r + ohyes;
colord.g = color.g + (ohyes / 2);
colord.b = color.b + ohyes;
if (color.r == 0) colord.r = 0;
if (color.g == 0) colord.g = 0;
if (color.b == 0) colord.b = 0;
//if (color.r < colord.r) pe1.r = colord.r / 255;
//if (color.g < colord.g) pe1.g = colord.g / 255;
//if (color.b < colord.b) pe1.b = colord.b / 255;
pe1.rgb = colord.rgb / 255;
// *****************
// STAGE 2
// Reduce color depth of sampled pixels....
// *****************
vec4 reduct; // 16 bits per pixel (5-6-5)
reduct.r = 64;
reduct.g = 128; // gotta be 16bpp for that green!
reduct.b = 64;
pe1 = pow(pe1, what); pe1 = pe1 * reduct; pe1 = floor(pe1); pe1 = pe1 / reduct; pe1 = pow(pe1, what);
gl_FragColor = pe1;
}

View File

@@ -0,0 +1,26 @@
varying vec2 texture_coordinate;
varying vec2 texture_coordinate2;
varying vec2 texture_coordinate3;
varying vec2 texture_coordinate4;
varying vec2 texture_coordinate5;
varying float scale;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
void main()
{
vec2 eh;
// Transforming The Vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Passing The Texture Coordinate Of Texture Unit 0 To The Fragment Shader
texture_coordinate = vec2(gl_MultiTexCoord0);
}

View File

@@ -0,0 +1,69 @@
// LeiFX shader - Pixel filtering process
//
// Copyright (C) 2013-2014 leilei
//
// 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.
uniform sampler2D u_Texture0;
varying vec2 texture_coordinate;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
#define PIXELWIDTH 0.66f
#define BLURAMOUNT 0.5f
void main()
{
vec2 px; // shut
px.x = u_ScreenToNextPixelX;
px.y = u_ScreenToNextPixelY;
// Sampling The Texture And Passing It To The Frame Buffer
gl_FragColor = texture2D(u_Texture0, texture_coordinate);
// A more direct port from the HLSL code i've written. Which rocks. Yeah.
float blendy; // to blend unblended with blend... trying to smooth the jag :(
float blenda;
float blendfactor;
vec4 pixel1 = texture2D(u_Texture0, texture_coordinate + vec2(px.x * PIXELWIDTH / 4, 0));
vec4 pixel2 = texture2D(u_Texture0, texture_coordinate + vec2(-px.x * PIXELWIDTH, 0));
vec4 pixel0 = texture2D(u_Texture0, texture_coordinate + vec2(0, 0));
vec4 pixelblend;
vec4 onee = 1; // because I can't just stick 1 in the GLSL dot function
float gary1 = dot(pixel1,onee);
float gary2 = dot(pixel2,onee);
float mean = 1.0;
mean = gary1 - gary2;
if (mean < 0) mean *= -1;
//if (mean > 1) mean = 1;
mean = pow(mean, BLURAMOUNT); // Adjust this value if you want to control the blur...
if (mean > 1) mean = 1;
{
// variably BLEND IT ALL TO H*CK!!!!
blendy = 1 - mean;
blenda = 1 - blendy;
pixel0 /= 3;
pixel1 /= 3;
pixel2 /= 3;
pixelblend.rgb = pixel0 + pixel1 + pixel2;
gl_FragColor.rgb = (pixelblend.rgb * blendy) + (gl_FragColor.rgb * blenda);
}
}

View File

@@ -0,0 +1,21 @@
#version 120
varying vec2 texture_coordinate;
varying vec2 texture_coordinate2;
varying vec2 texture_coordinate3;
varying vec2 texture_coordinate4;
varying vec2 texture_coordinate5;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
varying float scale;
void main()
{
scale=0.7;
// Transforming The Vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Passing The Texture Coordinate Of Texture Unit 0 To The Fragment Shader
texture_coordinate = vec2(gl_MultiTexCoord0);
}

View File

@@ -0,0 +1,32 @@
// LeiFX shader - Pixel filtering process
//
// Copyright (C) 2013-2014 leilei
//
// 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.
uniform sampler2D u_Texture0;
varying vec2 texture_coordinate;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
void main()
{
vec2 px; // shut
px.x = u_ScreenToNextPixelX;
px.y = u_ScreenToNextPixelX;
float gammaed = 0.09;
float leifx_linegamma = gammaed;
gl_FragColor = texture2D(u_Texture0, texture_coordinate);
float lines = mod(gl_FragCoord.y, 2.0);
if (lines < 1.0) leifx_linegamma = 0;
float leifx_gamma = 1.3 - gammaed + leifx_linegamma;
gl_FragColor.r = pow(gl_FragColor.r, 1.0 / leifx_gamma);
gl_FragColor.g = pow(gl_FragColor.g, 1.0 / leifx_gamma);
gl_FragColor.b = pow(gl_FragColor.b, 1.0 / leifx_gamma);
}

View File

@@ -0,0 +1,18 @@
#version 120
varying vec2 texture_coordinate;
varying vec2 texture_coordinate2;
varying vec2 texture_coordinate3;
varying vec2 texture_coordinate4;
varying vec2 texture_coordinate5;
varying float scale;
void main()
{
scale=0.7;
// Transforming The Vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Passing The Texture Coordinate Of Texture Unit 0 To The Fragment Shader
texture_coordinate = vec2(gl_MultiTexCoord0);
}

View File

@@ -0,0 +1,66 @@
uniform sampler2D u_Texture0;
varying vec2 texture_coordinate;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
// This is a simple shader that just blurs the whole picture with two given vectors, and scales its intensity
// based on the base res and the real resolution to imitate a degrading signal. Nothing really mindblowing other than to
// imitate the poor DACs of popular VGA cards that are not from a canadian company that specializes in image quality.
float BaseResX = 1024;
float BaseResY = 768;
float Blurs[3] = {1.6, 0.7, 0}; // to right and
int Passes = 12;
void main()
{
// Sampling The Texture And Passing It To The Frame Buffer
gl_FragColor = texture2D(u_Texture0, texture_coordinate);
vec4 what;
what.x = 1; // shut
what.y = 1; // up
what.z = 1; // warnings
vec4 huh;
vec2 px;
float egh = 1.0f / (BaseResX * u_ScreenToNextPixelX);
px.x = u_ScreenToNextPixelX;// * (BaseResX / u_ScreenSizeX);
px.y = u_ScreenToNextPixelY;// * (BaseResY / u_ScreenSizeY);
int passer;
float passy;
vec4 pe1 = texture2D(u_Texture0, texture_coordinate);
vec4 signal;
for (passer=0; passer<Passes; passer++)
{
passy = passer / Passes;
float prs = (float(passer) / float(Passes));
float shift1 = -px.x * (Blurs[0] *egh * prs);
vec2 texcoord = texture_coordinate - (vec2(shift1, 0) * 0.3) + (vec2(shift1, 0) * 1.2);
signal += texture2D(u_Texture0, texcoord) / Passes / 2;
}
for (passer=0; passer<Passes; passer++)
{
passy = passer / Passes;
float prs = (float(passer) / float(Passes));
float shift2 = -px.y * (Blurs[1] *egh * prs);
vec2 texcoord = texture_coordinate - (vec2(0, shift2)) * 0.5 + (vec2(0, shift2));
signal += texture2D(u_Texture0, texcoord) / Passes / 2;
}
gl_FragColor = signal;
}

View File

@@ -0,0 +1,26 @@
varying vec2 texture_coordinate;
varying vec2 texture_coordinate2;
varying vec2 texture_coordinate3;
varying vec2 texture_coordinate4;
varying vec2 texture_coordinate5;
varying float scale;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
void main()
{
vec2 eh;
// Transforming The Vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Passing The Texture Coordinate Of Texture Unit 0 To The Fragment Shader
texture_coordinate = vec2(gl_MultiTexCoord0);
}

View File

@@ -0,0 +1,54 @@
uniform sampler2D u_Texture0;
uniform sampler2D u_Texture1;
uniform sampler2D u_Texture2;
uniform sampler2D u_Texture3;
uniform sampler2D u_Texture4;
uniform sampler2D u_Texture5;
uniform sampler2D u_Texture6;
uniform sampler2D u_mpass1;
uniform sampler2D u_mpass2;
uniform sampler2D u_mpass3;
uniform sampler2D u_mpass4;
varying vec2 texture_coordinate;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
uniform float u_MotionBlurX;
uniform float u_MotionBlurY;
// This is a simple motion blur shader
float Blurs[3] = {17.6, 7.7, 0}; // to right and
int Passes = 32;
void main()
{
// Sampling The Texture And Passing It To The Frame Buffer
gl_FragColor = texture2D(u_Texture0, texture_coordinate);
// Actually....
vec4 m2 = texture2D(u_Texture2, texture_coordinate);
vec4 m3 = texture2D(u_Texture3, texture_coordinate);
vec4 m4 = texture2D(u_Texture4, texture_coordinate);
vec4 m5 = texture2D(u_Texture5, texture_coordinate);
vec4 m6 = texture2D(u_Texture6, texture_coordinate);
vec4 p1 = texture2D(u_mpass1, texture_coordinate);
vec4 blur = (m2 + m3 + m4 + m5 + m6) / 4;
vec4 parshes = p1;
gl_FragColor = blur;
}

View File

@@ -0,0 +1,27 @@
varying vec2 texture_coordinate;
varying vec2 texture_coordinate2;
varying vec2 texture_coordinate3;
varying vec2 texture_coordinate4;
varying vec2 texture_coordinate5;
varying float scale;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
uniform float u_MotionBlurX;
uniform float u_MotionBlurY;
void main()
{
vec2 eh;
// Transforming The Vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Passing The Texture Coordinate Of Texture Unit 0 To The Fragment Shader
texture_coordinate = vec2(gl_MultiTexCoord0);
}

View File

@@ -0,0 +1,57 @@
uniform sampler2D u_Texture0;
uniform sampler2D u_Texture1;
uniform sampler2D u_Texture2;
uniform sampler2D u_Texture3;
uniform sampler2D u_Texture4;
uniform sampler2D u_Texture5;
uniform sampler2D u_Texture6;
varying vec2 texture_coordinate;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
uniform float u_MotionBlurX;
uniform float u_MotionBlurY;
// This is a simple motion blur shader
float Blurs[3] = {17.6, 7.7, 0}; // to right and
int Passes = 32;
void main()
{
// Sampling The Texture And Passing It To The Frame Buffer
gl_FragColor = texture2D(u_Texture0, texture_coordinate);
// Actually....
// Blend x4 (60 = 240fps)
vec4 m2 = texture2D(u_mpass1, texture_coordinate);
vec4 m3 = texture2D(u_mpass2, texture_coordinate);
vec4 m4 = texture2D(u_mpass3, texture_coordinate);
vec4 m5 = texture2D(u_mpass4, texture_coordinate);
vec4 blur = (m2 + m3 + m4 + m5) / 4;
// Not yet implemented
/*
// Blend x3 (60 = 180fps)
vec4 m2 = texture2D(u_mpass1, texture_coordinate);
vec4 m3 = texture2D(u_mpass2, texture_coordinate);
vec4 m4 = texture2D(u_mpass3, texture_coordinate);
vec4 blur = (m2 + m3 + m4) / 3;
// Blend x2 (60 = 120fps)
vec4 m2 = texture2D(u_mpass1, texture_coordinate);
vec4 m3 = texture2D(u_mpass2, texture_coordinate);
vec4 blur = (m2 + m3) / 2;
*/
gl_FragColor = blur;
// gl_FragColor.b *= 3.1; // this is to check if my shader is working.
}

View File

@@ -0,0 +1,27 @@
varying vec2 texture_coordinate;
varying vec2 texture_coordinate2;
varying vec2 texture_coordinate3;
varying vec2 texture_coordinate4;
varying vec2 texture_coordinate5;
varying float scale;
uniform float u_ScreenToNextPixelX;
uniform float u_ScreenToNextPixelY;
uniform float u_ScreenSizeX;
uniform float u_ScreenSizeY;
uniform float u_MotionBlurX;
uniform float u_MotionBlurY;
void main()
{
vec2 eh;
// Transforming The Vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Passing The Texture Coordinate Of Texture Unit 0 To The Fragment Shader
texture_coordinate = vec2(gl_MultiTexCoord0);
}

View File

@@ -128,7 +128,36 @@ void GL_SelectTexture( int unit )
GLimp_LogComment( "glActiveTextureARB( GL_TEXTURE7_ARB )\n" );
qglClientActiveTextureARB( GL_TEXTURE7_ARB );
GLimp_LogComment( "glClientActiveTextureARB( GL_TEXTURE7_ARB )\n" );
} else {
}
else if ( unit == 11 )
{
qglActiveTextureARB( GL_TEXTURE11_ARB );
GLimp_LogComment( "glActiveTextureARB( GL_TEXTURE11_ARB )\n" );
qglClientActiveTextureARB( GL_TEXTURE11_ARB );
GLimp_LogComment( "glClientActiveTextureARB( GL_TEXTURE11_ARB )\n" );
}
else if ( unit == 12 )
{
qglActiveTextureARB( GL_TEXTURE12_ARB );
GLimp_LogComment( "glActiveTextureARB( GL_TEXTURE12_ARB )\n" );
qglClientActiveTextureARB( GL_TEXTURE12_ARB );
GLimp_LogComment( "glClientActiveTextureARB( GL_TEXTURE12_ARB )\n" );
}
else if ( unit == 13 )
{
qglActiveTextureARB( GL_TEXTURE13_ARB );
GLimp_LogComment( "glActiveTextureARB( GL_TEXTURE13_ARB )\n" );
qglClientActiveTextureARB( GL_TEXTURE13_ARB );
GLimp_LogComment( "glClientActiveTextureARB( GL_TEXTURE13_ARB )\n" );
}
else if ( unit == 14 )
{
qglActiveTextureARB( GL_TEXTURE14_ARB );
GLimp_LogComment( "glActiveTextureARB( GL_TEXTURE14_ARB )\n" );
qglClientActiveTextureARB( GL_TEXTURE14_ARB );
GLimp_LogComment( "glClientActiveTextureARB( GL_TEXTURE14_ARB )\n" );
}
else {
ri.Error( ERR_DROP, "GL_SelectTexture: unit = %i", unit );
}
@@ -1442,8 +1471,64 @@ extern cvar_t *r_slowness; // leilei - experimental variable slowness
extern cvar_t *r_slowness_cpu; // leilei - experimental variable slowness
extern cvar_t *r_slowness_gpu; // leilei - experimental variable slowness
// leilei - motion blur hack
float motiontime;
float motion_finished;
int motionframe;
int motionpasses;
int numofmotionpasses;
int inmotion;
int mblurred; // tells the renderer if we are rendering to a motion blur accum buffer instead of our drawing buffer
void R_MblurScreen( void );
void R_MblurScreenPost( void );
void RB_UpdateMotionBlur (void){
// leilei - motion blur hack
int e;
numofmotionpasses = 4;
motion_finished = (1000.0f / r_motionblur_fps->integer / 5 / numofmotionpasses);
/*
if (motionpasses > numofmotionpasses){
motionpasses = 0;
// inmotion = 0;
motionframe = 0;
// if (!backEnd.donemblur){
// R_MblurScreenPost();
// ri.Printf( PRINT_WARNING, "yae\n" );
// }
// return; // okay!
}
*/
if (motionpasses > numofmotionpasses){
motionpasses = 0;
}
if (motionframe > 5){
// do an accumulating post process
motionpasses += 1;
// R_MotionBlur_BackupScreen(10 + motionpasses);
R_MotionBlur_BackupScreen(11); // back it up in there...
motionframe = 1;
//return;
}
if (backEnd.refdef.time > motiontime){
R_MotionBlur_BackupScreen(motionframe); // back it up in there...
motionframe += 1;
R_MblurScreen();
motiontime = backEnd.refdef.time + motion_finished;
inmotion = 1;
}
else
inmotion = 0;
}
float mtime; // motion blur frame time
/*
=============
RB_SwapBuffers
@@ -1453,16 +1538,44 @@ RB_SwapBuffers
const void *RB_SwapBuffers( const void *data ) {
const swapBuffersCommand_t *cmd;
// finish any 2D drawing if needed
if ( tess.numIndexes ) {
RB_EndSurface();
}
if (r_motionblur->integer){
// if (backEnd.refdef.time > mtime && mblurred)
{
mtime = backEnd.refdef.time + (1000.0f / r_motionblur_fps->integer);
mblurred = 0;
RB_UpdateMotionBlur();
}
// else
// {
// mblurred = 1;
//// RB_UpdateMotionBlur();
//
// }
// if (mblurred)
// R_MblurScreen(); // don't update while in motion blur.
// if (!mblurred)
// R_MblurScreenPost();
}
// texture swapping test
if ( r_showImages->integer ) {
RB_ShowImages();
}
if (r_ext_vertex_shader->integer){ // leilei - leifx filters
R_LeiFXPostprocessDitherScreen();
R_LeiFXPostprocessFilterScreen();
@@ -1472,6 +1585,7 @@ const void *RB_SwapBuffers( const void *data ) {
R_BrightScreen(); // leilei - alternate brightness - do it here so we hit evereything
cmd = (const swapBuffersCommand_t *)data;
// we measure overdraw by reading back the stencil buffer and
@@ -1509,12 +1623,19 @@ const void *RB_SwapBuffers( const void *data ) {
backEnd.doneFilm = qfalse;
backEnd.doneleifx = qfalse;
backEnd.doneanime = qfalse;
backEnd.donemblur = qfalse;
backEnd.doneSurfaces = qfalse;
backEnd.doneSun = qfalse;
backEnd.doneSunFlare = qfalse;
// leilei - artificial slowness (mapper debug) - this might be windows only
#ifdef _WIN32
//if (r_motionblur->integer && !mblurred)
// Sleep(1000.0f / r_motionblur_fps->value);
if (r_slowness->integer > 2){
// Should be roughly equiv to a P2 300 at value 1.0 (target system)
float cpuspeed = r_slowness_cpu->value;
@@ -1538,6 +1659,8 @@ const void *RB_SwapBuffers( const void *data ) {
#endif
return (const void *)(cmd + 1);
}
@@ -1551,6 +1674,7 @@ void RB_ExecuteRenderCommands( const void *data ) {
t1 = ri.Milliseconds ();
while ( 1 ) {
data = PADP(data, sizeof(void *));
@@ -1604,4 +1728,6 @@ void RB_ExecuteRenderCommands( const void *data ) {
}
}
}

View File

@@ -35,7 +35,8 @@ static cvar_t *r_bloom_cascade_intensity;
static cvar_t *r_bloom_cascade_alpha;
static cvar_t *r_bloom_cascade_dry;
static cvar_t *r_bloom_dry;
extern cvar_t *r_overBrightBits;
extern cvar_t *r_gamma;
static cvar_t *r_bloom_reflection; // LEILEI
static cvar_t *r_bloom_sky_only; // LEILEI
cvar_t *r_film;
@@ -121,6 +122,55 @@ static struct {
struct {
int width, height;
} work;
// leilei - motion blur
struct {
image_t *texture;
int width, height;
float readW, readH;
} motion1;
struct {
image_t *texture;
int width, height;
float readW, readH;
} motion2;
struct {
image_t *texture;
int width, height;
float readW, readH;
} motion3;
struct {
image_t *texture;
int width, height;
float readW, readH;
} motion4;
struct {
image_t *texture;
int width, height;
float readW, readH;
} motion5;
struct {
image_t *texture;
int width, height;
float readW, readH;
} mpass1;
struct {
image_t *texture;
int width, height;
float readW, readH;
} mpass2;
struct {
image_t *texture;
int width, height;
float readW, readH;
} mpass3;
struct {
image_t *texture;
int width, height;
float readW, readH;
} mpass4;
qboolean started;
} postproc;
@@ -289,6 +339,22 @@ static void R_Postprocess_InitTextures( void )
postproc.screen.texture = R_CreateImage( "***postproc screen texture***", data, postproc.screen.width, postproc.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
ri.Hunk_FreeTempMemory( data );
// leilei - motion blur textures!
data = ri.Hunk_AllocateTempMemory( postproc.screen.width * postproc.screen.height * 4 );
Com_Memset( data, 0, postproc.screen.width * postproc.screen.height * 4 );
postproc.motion1.texture = R_CreateImage( "***motionblur1 texture***", data, postproc.screen.width, postproc.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
postproc.motion2.texture = R_CreateImage( "***motionblur2 texture***", data, postproc.screen.width, postproc.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
postproc.motion3.texture = R_CreateImage( "***motionblur3 texture***", data, postproc.screen.width, postproc.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
postproc.motion4.texture = R_CreateImage( "***motionblur4 texture***", data, postproc.screen.width, postproc.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
postproc.motion5.texture = R_CreateImage( "***motionblur5 texture***", data, postproc.screen.width, postproc.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
postproc.mpass1.texture = R_CreateImage( "***motionaccum1 texture***", data, postproc.screen.width, postproc.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
postproc.mpass2.texture = R_CreateImage( "***motionaccum1 texture***", data, postproc.screen.width, postproc.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
postproc.mpass3.texture = R_CreateImage( "***motionaccum1 texture***", data, postproc.screen.width, postproc.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
postproc.mpass4.texture = R_CreateImage( "***motionaccum1 texture***", data, postproc.screen.width, postproc.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
ri.Hunk_FreeTempMemory( data );
// GLSL Depth Buffer
data = ri.Hunk_AllocateTempMemory( postproc.screen.width * postproc.screen.height *4);
@@ -613,6 +679,23 @@ static void R_Postprocess_BackupScreen( void ) {
qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight );
}
// leilei - motion blur hack
void R_MotionBlur_BackupScreen(int which) {
if (which == 1){ GL_Bind( postproc.motion1.texture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight ); } // gather thee samples
if (which == 2){ GL_Bind( postproc.motion2.texture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight ); }
if (which == 3){ GL_Bind( postproc.motion3.texture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight ); }
if (which == 4){ GL_Bind( postproc.motion4.texture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight ); }
if (which == 5){ GL_Bind( postproc.motion5.texture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight ); }
if (which == 11){ GL_Bind( postproc.mpass1.texture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight ); } // to accum
if (which == 12){ GL_Bind( postproc.mpass1.texture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight ); } // to accum
if (which == 13){ GL_Bind( postproc.mpass1.texture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight ); } // to accum
if (which == 14){ GL_Bind( postproc.mpass1.texture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight ); } // to accum
if (which == 18){ GL_Bind( postproc.screen.texture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight ); } // to accum
}
/*
=================
@@ -654,6 +737,10 @@ static void R_Bloom_RestoreScreen_Postprocessed( void ) {
if (leifxmode == 3){ if (vertexShaders) R_GLSL_UseProgram(tr.leiFXFilterProgram); program=tr.programs[tr.leiFXFilterProgram];}
if (leifxmode == 888){ if (vertexShaders) R_GLSL_UseProgram(tr.animeProgram); program=tr.programs[tr.animeProgram];}
if (leifxmode == 999){ if (vertexShaders) R_GLSL_UseProgram(tr.animeFilmProgram); program=tr.programs[tr.animeFilmProgram];}
if (leifxmode == 777){ if (vertexShaders) R_GLSL_UseProgram(tr.motionBlurProgram); program=tr.programs[tr.motionBlurProgram];}
if (leifxmode == 778){ if (vertexShaders) R_GLSL_UseProgram(tr.motionBlurProgram); program=tr.programs[tr.motionBlurProgram];}
if (leifxmode == 779){ if (vertexShaders) R_GLSL_UseProgram(tr.motionBlurPostProgram); program=tr.programs[tr.motionBlurPostProgram];}
if (leifxmode == 666){ if (vertexShaders) R_GLSL_UseProgram(tr.BrightnessProgram); program=tr.programs[tr.BrightnessProgram];}
}
else
@@ -670,6 +757,18 @@ static void R_Bloom_RestoreScreen_Postprocessed( void ) {
if (program->u_ScreenToNextPixelY > -1) R_GLSL_SetUniform_u_ScreenToNextPixelY(program, (float)1.0/(float)glConfig.vidHeight);
// Brightness stuff
if (program->u_CC_Brightness > -1) R_GLSL_SetUniform_u_CC_Brightness(program, 1.0);
if (program->u_CC_Gamma > -1) R_GLSL_SetUniform_u_CC_Gamma(program, r_gamma->value);
if (program->u_CC_Overbright > -1) R_GLSL_SetUniform_u_CC_Overbright(program, r_overBrightBits->value);
if (program->u_CC_Saturation > -1) R_GLSL_SetUniform_u_CC_Saturation(program, 1.0);
if (program->u_CC_Contrast > -1) R_GLSL_SetUniform_u_CC_Contrast(program, 1.0);
if (program->u_zFar > -1) R_GLSL_SetUniform_u_zFar(program, tr.viewParms.zFar);
GL_SelectTexture(0);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
@@ -677,9 +776,42 @@ static void R_Bloom_RestoreScreen_Postprocessed( void ) {
GL_SelectTexture(7);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( postproc.depth.texture );
// motion blur crap
GL_SelectTexture(2);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( postproc.motion1.texture );
GL_SelectTexture(3);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( postproc.motion2.texture );
GL_SelectTexture(4);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( postproc.motion3.texture );
GL_SelectTexture(5);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( postproc.motion4.texture );
GL_SelectTexture(6);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( postproc.motion5.texture );
GL_SelectTexture(11);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( postproc.mpass1.texture );
GL_SelectTexture(12);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( postproc.mpass1.texture );
GL_SelectTexture(13);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( postproc.mpass1.texture );
GL_SelectTexture(14);
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( postproc.mpass1.texture );
qglColor4f( 1, 1, 1, 1 );
// if (leifxmode == 778)
// return;
R_Bloom_Quad( glConfig.vidWidth, glConfig.vidHeight, 0, 0,
postproc.screen.readW,postproc.screen.readH );
if (vertexShaders) R_GLSL_UseProgram(0);
GL_SelectTexture(0);
@@ -1035,6 +1167,64 @@ void R_AnimeScreen( void )
}
void R_MblurScreen( void )
{
if( !r_motionblur->integer)
return;
if ( backEnd.donemblur)
return;
if ( !backEnd.doneSurfaces )
return;
if( !postproc.started ) {
force32upload = 1;
R_Postprocess_InitTextures();
if( !postproc.started )
return;
}
if ( !backEnd.projection2D )
RB_SetGL2D();
force32upload = 1;
leifxmode = 777; // accumulate frames for the motion blur buffer
R_LeiFX_Stupid_Hack();
R_Postprocess_BackupScreen();
R_Bloom_RestoreScreen_Postprocessed();
force32upload = 0;
}
void R_MblurScreenPost( void )
{
if( !r_motionblur->integer)
return;
if ( !backEnd.doneSurfaces )
return;
if( !postproc.started ) {
force32upload = 1;
R_Postprocess_InitTextures();
if( !postproc.started )
return;
}
backEnd.donemblur = qtrue;
if ( !backEnd.projection2D )
RB_SetGL2D();
force32upload = 1;
leifxmode = 770; // accumulate frames for the motion blur buffer
R_LeiFX_Stupid_Hack();
// R_Postprocess_BackupScreen();
R_Bloom_RestoreScreen_Postprocessed();
force32upload = 0;
}
void R_BloomInit( void ) {
memset( &bloom, 0, sizeof( bloom ));
@@ -1104,7 +1294,7 @@ static void ID_INLINE R_Brighter_Quad( int width, int height, float texX, float
qglEnd ();
}
extern cvar_t *r_overBrightBits;
void R_BrightItUp (int dst, int src, float intensity)
{
@@ -1132,6 +1322,8 @@ void R_BrightScreen( void )
//if (!fakeit)
backEnd.doneAltBrightness = qtrue;
// Handle Overbrights first
int eh, ah;
if (r_overBrightBits->integer)
@@ -1140,14 +1332,33 @@ void R_BrightScreen( void )
ah = r_overBrightBits->integer;
if (ah < 1) ah = 1; if (ah > 2) ah = 2; // clamp so it never looks stupid
// Blend method
// do a loop for every overbright bit enabled
for (eh=0; eh<r_overBrightBits->integer; eh++){
if (r_alternateBrightness->integer == 1)
for (eh=0; eh<ah; eh++){
R_BrightItUp(GLS_SRCBLEND_DST_COLOR, GLS_DSTBLEND_ONE, 1.0f); }
}
if ( !backEnd.projection2D )
RB_SetGL2D();
// Fragment shader
if (r_alternateBrightness->integer == 2)
{
force32upload = 1;
leifxmode = 666;
R_LeiFX_Stupid_Hack();
R_Postprocess_BackupScreen();
R_Bloom_RestoreScreen_Postprocessed();
force32upload = 0;
}
}

View File

@@ -38,6 +38,7 @@ static byte *fileBase;
int c_subdivisions;
int c_gridVerts;
int ismaptexture;
//===============================================================================
@@ -287,6 +288,8 @@ static shader_t *ShaderForShaderNum( int shaderNum, int lightmapNum ) {
lightmapNum = LIGHTMAP_WHITEIMAGE;
}
ismaptexture = 1;
shader = R_FindShader( dsh->shader, lightmapNum, qtrue );
// if the shader had errors, just use default shader

View File

@@ -37,6 +37,8 @@ int palettedformat = GL_COLOR_INDEX8_EXT; // leilei - paletted texture support
static image_t* hashTable[FILE_HASH_SIZE];
extern int ismaptexture;
//
// leilei - paletted texture support START
//
@@ -508,6 +510,55 @@ void R_ImageList_f( void ) {
ri.Printf (PRINT_ALL, " %i total images\n\n", tr.numImages );
}
/*
===============
R_ImageListMapOnly_f
This version is used to make life easier to see which map textures are used
and also provide a bunch of lame zip commands to modularize maps better
(i.e. packing only used stuff by the *good* maps for releases)
===============
*/
void R_ImageListMapOnly_f( void ) {
int i;
int estTotalSize = 0;
for ( i = 0 ; i < tr.numImages ; i++ )
{
image_t *image = tr.images[i];
char *zipcommand = "zip -9 ";
char localName[ MAX_QPATH ];
char *sizeSuffix;
int estSize;
int displaySize;
estSize = image->uploadHeight * image->uploadWidth;
// mipmap adds about 50%
if (image->flags & IMGFLAG_MIPMAP)
estSize += estSize / 2;
sizeSuffix = "b ";
displaySize = estSize;
//if ( !strncmp( image->imgName, "textures", 8 ) ) {
if (image->maptexture){
COM_StripExtension( image->imgName, localName, MAX_QPATH );
ri.Printf(PRINT_ALL, "%s pak1-map-mapname.pk3 %s.*\n", zipcommand, localName);
}
}
// ri.Printf (PRINT_ALL, " ---------\n");
// ri.Printf (PRINT_ALL, " approx %i bytes\n", estTotalSize);
// ri.Printf (PRINT_ALL, " %i total images\n\n", tr.numImages );
}
//=======================================================================
/*
@@ -1817,6 +1868,10 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height,
GL_SelectTexture( 0 );
}
// leilei - map texture listing hack
image->maptexture = ismaptexture;
hash = generateHashValue(name);
image->next = hashTable[hash];
hashTable[hash] = image;
@@ -1983,6 +2038,8 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags )
image = R_CreateImage( ( char * ) name, pic, width, height, type, flags, 0 );
ri.Free( pic );
ismaptexture = 0;
return image;
}
@@ -2042,6 +2099,7 @@ image_t *R_FindImageFileIfItsThere( const char *name, imgType_t type, imgFlags_t
image = R_CreateImage( ( char * ) name, pic, width, height, type, flags, 0 );
ri.Free( pic );
ismaptexture = 0;
return image;
}
@@ -2225,7 +2283,7 @@ void R_CreateBuiltinImages( void ) {
// we use a solid white image instead of disabling texturing
Com_Memset( data, 255, sizeof( data ) );
ismaptexture = 0;
tr.whiteImage = R_CreateImage("*white", (byte *)data, 8, 8, IMGTYPE_COLORALPHA, IMGFLAG_NONE, 0);
// with overbright bits active, we need an image which is some fraction of full color,
@@ -2306,7 +2364,7 @@ void R_SetColorMappings( void ) {
g = r_gamma->value;
if (!r_alternateBrightness->integer) // leilei - don't do the shift to the brightness when we do alternate. This allows
if (r_alternateBrightness->integer != 1) // leilei - don't do the shift to the brightness when we do alternate. This allows
shift = tr.overbrightBits; // hardware gamma to work (if available) since we can't do alternate gamma via blends
else shift = 0; // don't
@@ -2334,7 +2392,7 @@ void R_SetColorMappings( void ) {
s_intensitytable[i] = j;
}
if ( glConfig.deviceSupportsGamma )
if ( glConfig.deviceSupportsGamma && r_alternateBrightness->integer != 2)
{
GLimp_SetGamma( s_gammatable, s_gammatable, s_gammatable );
}

View File

@@ -40,6 +40,8 @@ static void GfxInfo_f( void );
cvar_t *com_altivec;
#endif
cvar_t *r_shadeMode;
cvar_t *r_flareSize;
cvar_t *r_flareFade;
cvar_t *r_flareCoeff;
@@ -195,12 +197,39 @@ cvar_t *r_mockvr; // Leilei - for debugging PVR only!
cvar_t *r_leifx; // Leilei - leifx nostalgia filter
cvar_t *r_anime; // Leilei - anime filter
cvar_t *r_leidebug; // Leilei - debug
cvar_t *r_leidebugeye; // Leilei - eye debug
cvar_t *r_motionblur; // Leilei - motionblur
cvar_t *r_motionblur_fps; // Leilei - motionblur framerated
cvar_t *r_slowness; // Leilei - the cvar that slows everything down. use with caution.
cvar_t *r_slowness_cpu; // Leilei
cvar_t *r_slowness_gpu; // Leilei
// leilei - fallback shader hack
//extern const char *fallbackShader_anime_vp;
//extern const char *fallbackShader_anime_fp;
//extern const char *fallbackShader_anime_film_vp;
//extern const char *fallbackShader_anime_film_fp;
//extern const char *fallbackShader_brightness_vp;
//extern const char *fallbackShader_brightness_fp;
extern const char *fallbackShader_leifx_dither_vp;
extern const char *fallbackShader_leifx_dither_fp;
extern const char *fallbackShader_leifx_filter_vp;
extern const char *fallbackShader_leifx_filter_fp;
extern const char *fallbackShader_leifx_gamma_vp;
extern const char *fallbackShader_leifx_gamma_fp;
//extern const char *fallbackShader_leifx_vgasignal_vp;
//extern const char *fallbackShader_leifx_vgasignal_fp;
//extern const char *fallbackShader_motionblur_accum_vp;
//extern const char *fallbackShader_motionblur_accum_fp;
//extern const char *fallbackShader_motionblur_post_vp;
//extern const char *fallbackShader_motionblur_post_fp;
/*
** InitOpenGL
**
@@ -1155,6 +1184,8 @@ void R_Register( void )
r_lightmap = ri.Cvar_Get ("r_lightmap", "0", 0 );
r_portalOnly = ri.Cvar_Get ("r_portalOnly", "0", CVAR_CHEAT );
r_shadeMode = ri.Cvar_Get ("r_shadeMode", "0", CVAR_ARCHIVE);
r_flareSize = ri.Cvar_Get ("r_flareSize", "40", CVAR_CHEAT);
r_flareFade = ri.Cvar_Get ("r_flareFade", "7", CVAR_CHEAT);
r_flareCoeff = ri.Cvar_Get ("r_flareCoeff", FLARE_STDCOEFF, CVAR_CHEAT);
@@ -1212,8 +1243,12 @@ void R_Register( void )
r_mockvr = ri.Cvar_Get( "r_mockvr", "0" , CVAR_ARCHIVE | CVAR_CHEAT);
r_leifx = ri.Cvar_Get( "r_leifx", "0" , CVAR_ARCHIVE | CVAR_LATCH);
r_motionblur = ri.Cvar_Get( "r_motionblur", "0" , CVAR_ARCHIVE);
r_motionblur_fps = ri.Cvar_Get( "r_motionblur_fps", "60", 0);
r_anime = ri.Cvar_Get( "r_anime", "0" , CVAR_ARCHIVE | CVAR_LATCH);
r_leidebug = ri.Cvar_Get( "r_leidebug", "0" , CVAR_CHEAT);
r_leidebugeye = ri.Cvar_Get( "r_leidebugeye", "0" , CVAR_CHEAT);
r_slowness = ri.Cvar_Get( "r_slowness", "0" , CVAR_ARCHIVE); // it's 0 because you want it to be the fastest possible by default.
r_slowness_cpu = ri.Cvar_Get( "r_slowness_cpu", "300" , CVAR_ARCHIVE); // it's 0 because you want it to be the fastest possible by default.
r_slowness_gpu = ri.Cvar_Get( "r_slowness_gpu", "96" , CVAR_ARCHIVE); // it's 0 because you want it to be the fastest possible by default.
@@ -1225,12 +1260,14 @@ void R_Register( void )
ri.Cmd_AddCommand( "skinlist", R_SkinList_f );
ri.Cmd_AddCommand( "modellist", R_Modellist_f );
ri.Cmd_AddCommand( "modelist", R_ModeList_f );
ri.Cmd_AddCommand( "imagelistmaponly", R_ImageListMapOnly_f );
ri.Cmd_AddCommand( "screenshot", R_ScreenShot_f );
ri.Cmd_AddCommand( "screenshotJPEG", R_ScreenShotJPEG_f );
ri.Cmd_AddCommand( "gfxinfo", GfxInfo_f );
ri.Cmd_AddCommand( "minimize", GLimp_Minimize );
}
/*
* R_GLSL_AllocProgram
* Reserve memory for program
@@ -1275,6 +1312,12 @@ static glslProgram_t *R_GLSL_AllocProgram(void) {
program->u_ViewOrigin = -1;
program->u_Normal = -1;
program->u_mpass1 = -1;
program->u_mpass2 = -1;
program->u_mpass3 = -1;
program->u_mpass4 = -1;
tr.programs[tr.numPrograms] = program;
tr.numPrograms++;
@@ -1342,6 +1385,8 @@ void R_GLSL_Init(void) {
Q_strncpyz(programVertexObjects[0], "glsl/leifx_dither_vp.glsl", sizeof(programVertexObjects[0]));
Q_strncpyz(programFragmentObjects[0], "glsl/leifx_dither_fp.glsl", sizeof(programFragmentObjects[0]));
tr.leiFXDitherProgram = RE_GLSL_RegisterProgram("leifx_dither", (const char *)programVertexObjects, 1, (const char *)programFragmentObjects, 1);
// if (!tr.leiFXDitherProgram) // try fallback shader
//tr.leiFXDitherProgram = RE_GLSL_RegisterProgram("leifx_dither", (const char *)fallbackShader_leifx_dither_vp, 1, (const char *)fallbackShader_leifx_dither_fp, 1);
Q_strncpyz(programVertexObjects[0], "glsl/leifx_gamma_vp.glsl", sizeof(programVertexObjects[0]));
Q_strncpyz(programFragmentObjects[0], "glsl/leifx_gamma_fp.glsl", sizeof(programFragmentObjects[0]));
@@ -1351,7 +1396,17 @@ void R_GLSL_Init(void) {
Q_strncpyz(programFragmentObjects[0], "glsl/leifx_filter_fp.glsl", sizeof(programFragmentObjects[0]));
tr.leiFXFilterProgram = RE_GLSL_RegisterProgram("leifx_filter", (const char *)programVertexObjects, 1, (const char *)programFragmentObjects, 1);
Q_strncpyz(programVertexObjects[0], "glsl/motionblur_accum_vp.glsl", sizeof(programVertexObjects[0]));
Q_strncpyz(programFragmentObjects[0], "glsl/motionblur_accum_fp.glsl", sizeof(programFragmentObjects[0]));
tr.motionBlurProgram = RE_GLSL_RegisterProgram("motionblur_accum", (const char *)programVertexObjects, 1, (const char *)programFragmentObjects, 1);
Q_strncpyz(programVertexObjects[0], "glsl/motionblur_post_vp.glsl", sizeof(programVertexObjects[0]));
Q_strncpyz(programFragmentObjects[0], "glsl/motionblur_post_fp.glsl", sizeof(programFragmentObjects[0]));
tr.motionBlurPostProgram = RE_GLSL_RegisterProgram("motionblur_post", (const char *)programVertexObjects, 1, (const char *)programFragmentObjects, 1);
Q_strncpyz(programVertexObjects[0], "glsl/brightness_vp.glsl", sizeof(programVertexObjects[0]));
Q_strncpyz(programFragmentObjects[0], "glsl/brightness_fp.glsl", sizeof(programFragmentObjects[0]));
tr.BrightnessProgram = RE_GLSL_RegisterProgram("brightness", (const char *)programVertexObjects, 1, (const char *)programFragmentObjects, 1);
if (strcmp( (const char *)r_postprocess->string, "none" ))
{
@@ -1367,6 +1422,7 @@ void R_GLSL_Init(void) {
}
}
/*
===============
R_Init
@@ -1456,8 +1512,7 @@ void R_Init( void ) {
R_ModelInit();
R_InitFreeType();
err = qglGetError();
if ( err != GL_NO_ERROR )
ri.Printf (PRINT_ALL, "glGetError() = 0x%x\n", err);
@@ -1480,6 +1535,7 @@ void RE_Shutdown( qboolean destroyWindow ) {
ri.Cmd_RemoveCommand ("screenshotJPEG");
ri.Cmd_RemoveCommand ("screenshot");
ri.Cmd_RemoveCommand ("imagelist");
ri.Cmd_RemoveCommand ("imagelistmaponly");
ri.Cmd_RemoveCommand ("shaderlist");
ri.Cmd_RemoveCommand ("skinlist");
ri.Cmd_RemoveCommand ("gfxinfo");

View File

@@ -133,6 +133,9 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
vec3_t direction;
float totalFactor;
if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
// seperate lightOrigins are needed so an object that is
// sinking into the ground can still be lit, and so
@@ -145,6 +148,8 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin );
for ( i = 0 ; i < 3 ; i++ ) {
float v;
float vA, vB, vC, vD;
v = lightOrigin[i]*tr.world->lightGridInverseSize[i];
pos[i] = floor( v );
@@ -154,6 +159,9 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
} else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) {
pos[i] = tr.world->lightGridBounds[i] - 1;
}
}
VectorClear( ent->ambientLight );
@@ -240,6 +248,292 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight );
VectorNormalize2( direction, ent->lightDir );
}
static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
vec3_t lightOrigin;
int pos[3];
int i, j;
byte *gridData;
float frac[3];
int gridStep[3];
vec3_t direction;
float totalFactor;
byte *gridDataA;
float fracA[3];
float fracB[3];
float fracC[3];
float fracD[3];
int posA[3];
int posB[3];
int posC[3];
int posD[3];
vec3_t failed;
int lightdist = 128;
lightdist = r_leidebug->integer;
failed[0] = 666;
failed[1] = 666;
failed[2] = 666;
int failA, failB, failC, failD = 0;
vec3_t lightOriginA;
vec3_t lightOriginB;
vec3_t lightOriginC;
vec3_t lightOriginD;
vec3_t directionA;
vec3_t directionB;
vec3_t directionC;
vec3_t directionD;
qboolean shadey = qfalse;
//
// leilei - lighting hack
//
// Try to sample the lightgrid from four different positions
// so we can add in four more lights to the model
vec3_t dirr;
VectorSubtract( lightOrigin, backEnd.viewParms.or.origin, dirr );
//VectorCopy(backEnd.viewParms.or.orign, dirr);
VectorNormalize( dirr );
// VectorMA( lightOrigin, lightdist, dirr, lightOriginA );
// lightOriginA[0] = dirr[0] * lightdist;
// lightOriginA[1] = dirr[1] * lightdist;
// lightOriginA[2] = dirr[2] * lightdist;
// Reverse the light direction to check
VectorSubtract( ent->lightDir, lightOrigin, dirr );
VectorNormalize( dirr );
lightOriginA[0] = lightOrigin[0] - (dirr[0] * lightdist);
lightOriginA[1] = lightOrigin[1] - (dirr[1] * lightdist);
lightOriginA[2] = lightOrigin[2] - (dirr[2] * lightdist);
lightOriginB[0] = lightdist;
lightOriginB[1] = lightdist;
lightOriginC[2] = -lightdist;
lightOriginD[2] = lightdist;
if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
// seperate lightOrigins are needed so an object that is
// sinking into the ground can still be lit, and so
// multi-part models can be lit identically
VectorCopy( ent->e.lightingOrigin, lightOrigin );
} else {
VectorCopy( ent->e.origin, lightOrigin );
}
VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin );
//VectorAdd( lightOrigin, lightOriginA, lightOriginA );
VectorAdd( lightOrigin, lightOriginB, lightOriginB );
VectorAdd( lightOrigin, lightOriginC, lightOriginC );
VectorAdd( lightOrigin, lightOriginD, lightOriginD );
for ( i = 0 ; i < 3 ; i++ ) {
float v;
float vA, vB, vC, vD;
v = lightOrigin[i]*tr.world->lightGridInverseSize[i];
pos[i] = floor( v );
frac[i] = v - pos[i];
if ( pos[i] < 0 ) {
pos[i] = 0;
} else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) {
pos[i] = tr.world->lightGridBounds[i] - 1;
}
vA = lightOriginA[i]*tr.world->lightGridInverseSize[i];
posA[i] = floor( vA );
fracA[i] = vA - posA[i];
if ( posA[i] < 0 ) {
posA[i] = 0;
} else if ( posA[i] >= tr.world->lightGridBounds[i] - 1 ) {
posA[i] = tr.world->lightGridBounds[i] - 1;
}
vB = lightOriginB[i]*tr.world->lightGridInverseSize[i];
posB[i] = floor( vB );
fracB[i] = vB - posB[i];
if ( posB[i] < 0 ) {
posB[i] = 0;
} else if ( posB[i] >= tr.world->lightGridBounds[i] - 1 ) {
posB[i] = tr.world->lightGridBounds[i] - 1;
}
vC = lightOriginC[i]*tr.world->lightGridInverseSize[i];
posC[i] = floor( vC );
fracC[i] = vC - posC[i];
if ( posC[i] < 0 ) {
posC[i] = 0;
} else if ( posC[i] >= tr.world->lightGridBounds[i] - 1 ) {
posC[i] = tr.world->lightGridBounds[i] - 1;
}
vD = lightOriginD[i]*tr.world->lightGridInverseSize[i];
posD[i] = floor( vD );
fracD[i] = vD - posD[i];
if ( pos[i] < 0 ) {
posD[i] = 0;
} else if ( posD[i] >= tr.world->lightGridBounds[i] - 1 ) {
posD[i] = tr.world->lightGridBounds[i] - 1;
}
}
VectorClear( ent->ambientLight );
VectorClear( ent->directedLight );
VectorClear( ent->dynamicLight );
VectorClear( direction );
// leilei - lighting hack
VectorClear( ent->directedLightA );
assert( tr.world->lightGridData ); // NULL with -nolight maps
// trilerp the light value
gridStep[0] = 8;
gridStep[1] = 8 * tr.world->lightGridBounds[0];
gridStep[2] = 8 * tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1];
gridData = tr.world->lightGridData + pos[0] * gridStep[0]
+ pos[1] * gridStep[1] + pos[2] * gridStep[2];
gridDataA = tr.world->lightGridData + posA[0] * gridStep[0]
+ posA[1] * gridStep[1] + posA[2] * gridStep[2];
totalFactor = 0;
for ( i = 0 ; i < 8 ; i++ ) {
float factor;
float factorA;
float factorB;
float factorC;
float factorD;
byte *data;
byte *dataA;
int lat, lng;
vec3_t normal;
#if idppc
float d0, d1, d2, d3, d4, d5;
#endif
factor = 1.0;
factorA = 1.0;
factorB = 1.0;
factorC = 1.0;
factorD = 1.0;
data = gridData;
dataA = gridDataA;
for ( j = 0 ; j < 3 ; j++ ) {
if ( i & (1<<j) ) {
factor *= frac[j];
factorA *= fracA[j];
factorB *= fracB[j];
factorC *= fracC[j];
factorD *= fracD[j];
data += gridStep[j];
dataA += gridStep[j];
} else {
factor *= (1.0f - frac[j]);
factorA *= (1.0f - fracA[j]);
factorB *= (1.0f - fracB[j]);
factorC *= (1.0f - fracC[j]);
factorD *= (1.0f - fracD[j]);
}
}
if ( !(dataA[0]+dataA[1]+dataA[2]) ) {
failA = 1; // try to fallback on an actual light we have
}
if ( !(data[0]+data[1]+data[2]) ) {
continue; // ignore samples in walls
}
totalFactor += factor;
// idpcc stripped out for now as i can't test that.
ent->ambientLight[0] += factor * data[0];
ent->ambientLight[1] += factor * data[1];
ent->ambientLight[2] += factor * data[2];
ent->directedLight[0] += factor * data[3];
ent->directedLight[1] += factor * data[4];
ent->directedLight[2] += factor * data[5];
ent->directedLightA[0] += factorA * dataA[3];
ent->directedLightA[1] += factorA * dataA[4];
ent->directedLightA[2] += factorA * dataA[5];
lat = data[7];
lng = data[6];
lat *= (FUNCTABLE_SIZE/256);
lng *= (FUNCTABLE_SIZE/256);
// decode X as cos( lat ) * sin( long )
// decode Y as sin( lat ) * sin( long )
// decode Z as cos( long )
normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
VectorMA( direction, factor, normal, direction );
VectorMA( directionA, factorA, normal, directionA );
VectorMA( directionB, factorB, normal, directionB );
VectorMA( directionC, factorC, normal, directionC );
VectorMA( directionD, factorD, normal, directionD );
}
if ( totalFactor > 0 && totalFactor < 0.99 ) {
totalFactor = 1.0f / totalFactor;
VectorScale( ent->ambientLight, totalFactor, ent->ambientLight );
VectorScale( ent->directedLight, totalFactor, ent->directedLight );
VectorScale( ent->directedLightA, totalFactor, ent->directedLightA );
}
VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight );
VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight );
VectorNormalize2( direction, ent->lightDir );
VectorNormalize2( directionA, ent->lightDirA );
/* if (failA){
VectorCopy(failed, ent->lightDirA);
VectorCopy(failed, ent->directedLightA);
}
*/
}
@@ -294,11 +588,14 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
float d;
vec3_t lightDir;
vec3_t lightOrigin;
qboolean crazy;
// lighting calculations
if ( ent->lightingCalculated ) {
return;
}
if (r_shadeMode->integer == 6)
crazy =qtrue;
ent->lightingCalculated = qtrue;
//
@@ -316,6 +613,9 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
// if NOWORLDMODEL, only use dynamic lights (menu system, etc)
if ( !(refdef->rdflags & RDF_NOWORLDMODEL )
&& tr.world->lightGridData ) {
if (crazy)
R_SetupEntityLightingGrid_crazy( ent );
else
R_SetupEntityLightingGrid( ent );
} else {
ent->ambientLight[0] = ent->ambientLight[1] =

View File

@@ -69,6 +69,15 @@ typedef struct {
vec3_t directedLight;
vec3_t dynamicLight;
float lightDistance;
// leilei - better quality lighting hack
vec3_t directedLightA;
vec3_t lightDirA;
// leilei - eyes
vec3_t eyepos[2]; // looking from
} trRefEntity_t;
@@ -77,6 +86,8 @@ typedef struct {
vec3_t axis[3]; // orientation in world
vec3_t viewOrigin; // viewParms->or.origin in local coordinates
float modelMatrix[16];
vec3_t viewOriginOld; // leilei - motionBlur
vec3_t viewOriginOlder; // leilei - motionBlur
} orientationr_t;
//===============================================================================
@@ -184,6 +195,8 @@ typedef enum {
TCGEN_ENVIRONMENT_MAPPED,
TCGEN_ENVIRONMENT_CELSHADE_MAPPED,
TCGEN_ENVIRONMENT_CELSHADE_LEILEI, // leilei - cel hack
TCGEN_EYE_LEFT, // eyes
TCGEN_EYE_RIGHT, // eyes
TCGEN_FOG,
TCGEN_VECTOR // S and T from world coordinates
} texCoordGen_t;
@@ -280,7 +293,7 @@ typedef struct {
int alphahack;
} textureBundle_t;
#define NUM_TEXTURE_BUNDLES 8
#define NUM_TEXTURE_BUNDLES 16 // leilei - was 8, increased for motion blur
typedef struct {
qboolean active;
@@ -829,6 +842,30 @@ typedef struct {
GLfloat u_ScreenToNextPixelX;
GLfloat u_ScreenToNextPixelY;
GLfloat u_zFar;
// leilei - motion blur vars
GLfloat u_MotionBlurX;// OBSOLETE
GLfloat u_MotionBlurY;// OBSOLETE
GLint u_ViewMotion;// OBSOLETE
vec3_t v_ViewMotion;// OBSOLETE
GLint u_mpass1; // 1-5
GLint u_mpass2; // 6-10
GLint u_mpass3; // 11-15
GLint u_mpass4; // 16-20
// leilei - Color control
GLfloat u_CC_Brightness;
GLfloat u_CC_Contrast;
GLfloat u_CC_Saturation;
GLfloat u_CC_Overbright;
GLfloat u_CC_Gamma;
//End Postprocess Vars
@@ -985,6 +1022,7 @@ typedef struct {
qboolean doneFilm; // leilei - done film filtering this frame
qboolean doneSun; // leilei - done drawing a sun
qboolean doneSunFlare; // leilei - done drawing a sun flare
qboolean donemblur; // leilei - done motionblur this frame
qboolean doneSurfaces; // done any 3d surfaces already
trRefEntity_t entity2D; // currentEntity will point at this when doing 2D rendering
} backEndState_t;
@@ -1041,6 +1079,9 @@ typedef struct {
qhandle_t leiFXFilterProgram; // leilei
qhandle_t animeProgram; // leilei
qhandle_t animeFilmProgram; // leilei
qhandle_t motionBlurProgram; // leilei
qhandle_t motionBlurPostProgram; // leilei
qhandle_t BrightnessProgram; // leilei
int numPrograms;
glslProgram_t *programs[MAX_PROGRAMS];
@@ -1121,6 +1162,8 @@ extern char depthimage;
//
// cvars
//
extern cvar_t *r_shadeMode; // leilei - alternate shading modes
extern cvar_t *r_flareSize;
extern cvar_t *r_flareFade;
extern cvar_t *r_flareQuality;
@@ -1244,8 +1287,12 @@ extern cvar_t *r_alternateBrightness; // leilei - alternate brightness
extern cvar_t *r_leifx; // Leilei - leifx nostalgia filter
extern cvar_t *r_motionblur; // Leilei - motionblur
extern cvar_t *r_motionblur_fps; // Leilei - motionblur framerated
extern cvar_t *r_anime; // Leilei - anime filter
extern cvar_t *r_leidebug; // Leilei - debug only!
extern cvar_t *r_leidebugeye; // Leilei - debug only!
//====================================================================
@@ -1346,6 +1393,7 @@ void R_Init( void );
void R_SetColorMappings( void );
void R_GammaCorrect( byte *buffer, int bufSize );
void R_ImageListMapOnly_f( void ); // leilei - stuff hack
void R_ImageList_f( void );
void R_SkinList_f( void );
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=516
@@ -1724,6 +1772,46 @@ static ID_INLINE void R_GLSL_SetUniform_u_zFar(glslProgram_t *program, GLfloat v
qglUniform1fARB(program->u_zFar, value);
}
static ID_INLINE void R_GLSL_SetUniform_u_MotionBlurX(glslProgram_t *program, GLfloat value) {
qglUniform1fARB(program->u_MotionBlurX, value);
}
static ID_INLINE void R_GLSL_SetUniform_u_MotionBlurY(glslProgram_t *program, GLfloat value) {
qglUniform1fARB(program->u_MotionBlurY, value);
}
static ID_INLINE void R_GLSL_SetUniform_u_CC_Brightness(glslProgram_t *program, GLfloat value) {
qglUniform1fARB(program->u_CC_Brightness, value);
}
static ID_INLINE void R_GLSL_SetUniform_u_CC_Gamma(glslProgram_t *program, GLfloat value) {
qglUniform1fARB(program->u_CC_Gamma, value);
}
static ID_INLINE void R_GLSL_SetUniform_u_CC_Contrast(glslProgram_t *program, GLfloat value) {
qglUniform1fARB(program->u_CC_Contrast, value);
}
static ID_INLINE void R_GLSL_SetUniform_u_CC_Saturation(glslProgram_t *program, GLfloat value) {
qglUniform1fARB(program->u_CC_Saturation, value);
}
static ID_INLINE void R_GLSL_SetUniform_u_CC_Overbright(glslProgram_t *program, GLfloat value) {
qglUniform1fARB(program->u_CC_Overbright, value);
}
static ID_INLINE void R_GLSL_SetUniform_Mpass1(glslProgram_t *program, GLint value) {qglUniform1iARB(program->u_mpass1, value);}
static ID_INLINE void R_GLSL_SetUniform_Mpass2(glslProgram_t *program, GLint value) {qglUniform1iARB(program->u_mpass2, value);}
static ID_INLINE void R_GLSL_SetUniform_Mpass3(glslProgram_t *program, GLint value) {qglUniform1iARB(program->u_mpass3, value);}
static ID_INLINE void R_GLSL_SetUniform_Mpass4(glslProgram_t *program, GLint value) {qglUniform1iARB(program->u_mpass4, value);}
void R_GLSL_Init(void);
qhandle_t RE_GLSL_RegisterProgram(const char *name, const char *programVertexObjects, int numVertexObjects, const char *programFragmentObjects, int numFragmentObjects);
@@ -1882,6 +1970,7 @@ void RB_DeformTessGeometry( void );
void RB_CalcEnvironmentTexCoords( float *dstTexCoords );
void RB_CalcCelTexCoords( float *dstTexCoords ); // leilei - cel hack
void RB_CalcEnvironmentTexCoordsJO( float *dstTexCoords ); // leilei
void RB_CalcEyes( float *st, qboolean theothereye); // leilei - eyes
void RB_CalcEnvironmentCelShadeTexCoords( float *dstTexCoords );
void RB_CalcEnvironmentTexCoordsNew( float *dstTexCoords );
void RB_CalcEnvironmentTexCoordsHW(void);
@@ -2082,4 +2171,8 @@ void R_AltBrightnessInit( void );
void R_FilmScreen( void ); // leilei - film effect
extern int softwaremode;
extern int leifxmode;
void RB_UpdateMotionBlur (void);
void R_MotionBlur_BackupScreen(int which);
#endif //TR_LOCAL_H

View File

@@ -1162,6 +1162,12 @@ static void ComputeTexCoords( shaderStage_t *pStage ) {
case TCGEN_ENVIRONMENT_CELSHADE_LEILEI:
RB_CalcCelTexCoords( ( float * ) tess.svars.texcoords[b] );
break;
case TCGEN_EYE_LEFT:
RB_CalcEyes( ( float * ) tess.svars.texcoords[b], 1);
break;
case TCGEN_EYE_RIGHT:
RB_CalcEyes( ( float * ) tess.svars.texcoords[b] , 0 );
break;
case TCGEN_BAD:
return;
}
@@ -1368,6 +1374,11 @@ void GLSL_Feeder(shaderStage_t *pStage, shaderCommands_t *input)
R_BindAnimatedImage(&pStage->bundle[7]);
}
if (program->u_mpass1 > -1 && pStage->bundle[1].image[0]) { GL_SelectTexture(11); qglEnable(GL_TEXTURE_2D); R_BindAnimatedImage(&pStage->bundle[11]);}
if (program->u_mpass2 > -1 && pStage->bundle[1].image[0]) { GL_SelectTexture(12); qglEnable(GL_TEXTURE_2D); R_BindAnimatedImage(&pStage->bundle[12]);}
if (program->u_mpass3 > -1 && pStage->bundle[1].image[0]) { GL_SelectTexture(13); qglEnable(GL_TEXTURE_2D); R_BindAnimatedImage(&pStage->bundle[13]);}
if (program->u_mpass4 > -1 && pStage->bundle[1].image[0]) { GL_SelectTexture(14); qglEnable(GL_TEXTURE_2D); R_BindAnimatedImage(&pStage->bundle[14]);}
/* time */
if (program->u_Time > -1)
R_GLSL_SetUniform_Time(program, input->shaderTime);
@@ -1383,11 +1394,17 @@ void GLSL_Clean(void)
{
glslProgram_t *program;
program = tr.programs[glState.currentProgram];
if (program->u_mpass1 > -1) { GL_SelectTexture(11); qglDisable(GL_TEXTURE_2D); }
if (program->u_mpass2 > -1) { GL_SelectTexture(12); qglDisable(GL_TEXTURE_2D); }
if (program->u_mpass3 > -1) { GL_SelectTexture(13); qglDisable(GL_TEXTURE_2D); }
if (program->u_mpass4 > -1) { GL_SelectTexture(14); qglDisable(GL_TEXTURE_2D); }
/* disable texture unit 7 */
if (program->u_Texture7 > -1)
qglDisable(GL_TEXTURE_2D);
/* disable texture unit 6 */
if (program->u_Texture6 > -1) {
GL_SelectTexture(6);

View File

@@ -27,6 +27,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#endif
#define WAVEVALUE( table, base, amplitude, phase, freq ) ((base) + table[ ri.ftol( ( ( (phase) + tess.shaderTime * (freq) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * (amplitude))
static float *TableForFunc( genFunc_t func )
@@ -1084,22 +1088,8 @@ void RB_CalcCelTexCoords( float *st )
VectorCopy(backEnd.currentEntity->lightDir, lightdir);
VectorCopy(backEnd.currentEntity->directedLight, directedLight);
float light = (directedLight[0] + directedLight[1] + directedLight[2] / 3);
// if (light > 1)
// light = 1.0f;
//p = 0.9f - (light * 0.9f);
p = 1.0f - (light / 255);
// for (i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 )
// {
//
// d = DotProduct (normal, backEnd.currentEntity->lightDir);
// st[0] = normal[0]*d - backEnd.currentEntity->lightDir[0];
// st[1] = normal[1]*d - backEnd.currentEntity->lightDir[1];
// }
for (i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 )
{
VectorSubtract (backEnd.or.viewOrigin, v, viewer);
@@ -1111,9 +1101,6 @@ void RB_CalcCelTexCoords( float *st )
if (d < 0)d = 0;
if (l < 0)l = 0;
//if (d > 1)d = 1;
//if (l > 1)l = 1;
if (d < p)d = p;
if (l < p)l = p;
@@ -1122,11 +1109,6 @@ void RB_CalcCelTexCoords( float *st )
reflected[1] = normal[1]*1*(d+l) - (viewer[1] + lightdir[1] );
reflected[2] = normal[2]*1*(d+l) - (viewer[2] + lightdir[2] );
// reflected[0] = normal[0]*2*l - lightdir[0];
// reflected[1] = normal[1]*2*l - lightdir[1];
// reflected[2] = normal[2]*2*l - lightdir[2];
st[0] = 0.5 + reflected[1] * 0.5;
st[1] = 0.5 - reflected[2] * 0.5;
@@ -1515,6 +1497,108 @@ static void RB_CalcDiffuseColor_scalar( unsigned char *colors )
}
// leilei - use FIVE (!) lighting points. Very expensive!
static void RB_CalcDiffuseColor_crazy( unsigned char *colors )
{
int i, j, jA;
float *v, *normal;
float incoming, incomingA, incomingB, incomingC, incomingD;
trRefEntity_t *ent;
int ambientLightInt;
vec3_t ambientLight;
vec3_t lightDir, lightDirA;
vec3_t directedLight, directedLightA;
int numVertexes;
ent = backEnd.currentEntity;
ambientLightInt = ent->ambientLightInt;
VectorCopy( ent->ambientLight, ambientLight );
VectorCopy( ent->directedLight, directedLight );
VectorCopy( ent->lightDir, lightDir );
VectorCopy( ent->directedLightA, directedLightA );
VectorCopy( ent->lightDirA, lightDirA );
// Actually, in reality, I disabled B, C and D as I figured out a more sane way to do things.
/*
// debug light positions
{
vec3_t temp;
vec3_t temp2;
AnglesToAxis(lightDirA, temp);
AnglesToAxis(lightDir, temp2);
GL_Bind( tr.whiteImage );
qglColor3f (1,1,1);
qglDepthRange( 0, 0 ); // never occluded
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
qglBegin (GL_LINES);
qglVertex3fv (temp);
qglVertex3fv (temp2);
qglEnd ();
qglDepthRange( 0, 1 );
}
*/
if (lightDirA[0] == 666){
VectorCopy( ent->directedLight, directedLightA );
VectorCopy( ent->lightDir, lightDirA );
}
int eg;
for (eg=0; eg<3;eg++){
//ambientLight[eg] /= 3;
directedLight[eg] *= 0.5f;
directedLightA[eg] *= 0.5f;
}
v = tess.xyz[0];
normal = tess.normal[0];
numVertexes = tess.numVertexes;
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
incoming = DotProduct (normal, lightDir);
incomingA = DotProduct (normal, lightDirA);
if ( incomingA <= 0 ) { VectorCopy(directedLight, directedLightA); incomingA = incoming; }
if ( incoming <= 0 ) {
*(int *)&colors[i*4] = ambientLightInt;
continue;
}
j = ri.ftol(ambientLight[0] + (incoming * directedLight[0]));
jA = ri.ftol(ambientLight[0] + (incomingA * directedLightA[0]));
if ( j > 255 ) { j = 255; }
if ( jA > 255 ) { jA = 255; }
colors[i*4+0] = (j + jA) /2;
j = ri.ftol(ambientLight[1] + (incoming * directedLight[1]));
jA = ri.ftol(ambientLight[1] + (incomingA * directedLightA[1]));
if ( j > 255 ) {
j = 255;
}
if ( jA > 255 ) { jA = 255; }
colors[i*4+1] = (j + jA) /2;
j = ri.ftol(ambientLight[2] + (incoming * directedLight[2]));
jA = ri.ftol(ambientLight[2] + (incomingA * directedLightA[2]));
if ( j > 255 ) {
j = 255;
}
if ( jA > 255 ) { jA = 255; }
colors[i*4+2] = (j + jA) /2;
colors[i*4+3] = 255;
}
}
// leilei - some slower, but bolder way of lighting
// i sure hope gcc unrolls this.
static void RB_CalcDiffuseColor_alternative( unsigned char *colors )
@@ -1541,17 +1625,6 @@ static void RB_CalcDiffuseColor_alternative( unsigned char *colors )
VectorCopy( ent->lightDir, ambDir );
VectorCopy( lightOrigin, ambDir );
VectorNormalizeFast( ambDir );
// crappy sun shine effect
if(backEnd.doneSunFlare == qtrue)
{
VectorCopy( tr.sunDirection, ambDir );
ambientLight[0] = tr.sunLight[0];
ambientLight[1] = tr.sunLight[1];
ambientLight[2] = tr.sunLight[2];
VectorNormalizeFast( ambDir );
}
v = tess.xyz[0];
normal = tess.normal[0];
@@ -1563,7 +1636,7 @@ static void RB_CalcDiffuseColor_alternative( unsigned char *colors )
if (incoming < 0) incoming = 0;
if (incoming2 < 0) incoming2 *= -0.7; // invert for fake rim effect
if (incoming2 < 0.9f) incoming2 = 0.9f; // clamp out black
/*
// add specular to ambient incoming
{
@@ -1599,7 +1672,7 @@ static void RB_CalcDiffuseColor_alternative( unsigned char *colors )
}
incoming2 *= l;
*/
j = ri.ftol(ambientLight[0] * incoming2) + ri.ftol(incoming * directedLight[0]);
if ( j > 255 ) {
j = 255;
@@ -1622,6 +1695,106 @@ static void RB_CalcDiffuseColor_alternative( unsigned char *colors )
}
}
static void RB_CalcDiffuseColor_crazyew( unsigned char *colors )
{
int i, j;
float *v, *normal;
float incoming;
float incoming2;
trRefEntity_t *ent;
int ambientLightInt;
vec3_t ambientLight;
vec3_t ambDir;
vec3_t lightDir, lightDirA, lightDirB;
vec3_t directedLight, directedLightA;
int numVertexes;
ent = backEnd.currentEntity;
float ilength;
int d, l, b;
vec3_t viewer, reflected;
ambientLightInt = ent->ambientLightInt;
VectorCopy( ent->ambientLight, ambientLight );
VectorCopy( ent->directedLight, directedLight );
VectorCopy( ent->directedLightA, directedLightA );
VectorCopy( ent->lightDir, lightDir );
VectorCopy( ent->lightDirA, lightDirA );
//VectorCopy( lightOrigin, lightDirB );
VectorNormalizeFast( lightDirB );
v = tess.xyz[0];
normal = tess.normal[0];
numVertexes = tess.numVertexes;
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
incoming = DotProduct (normal, lightDir) * 0.8;
// incoming2 = DotProduct (normal, lightDirA) * 2;
if (incoming < 0) incoming = 0;
// if (incoming2 < 0) incoming2 *= -0.7; // invert for fake rim effect
// if (incoming2 < 0.9f) incoming2 = 0.9f; // clamp out black
// add specular to ambient incoming
{
VectorCopy( backEnd.currentEntity->lightDir, lightDir );
//ilength = Q_rsqrt( DotProduct( ambDir, ambDir ) );
VectorNormalizeFast( ambDir );
// calculate the specular color
d = DotProduct (normal, ambDir);
// d *= ilength;
// we don't optimize for the d < 0 case since this tends to
// cause visual artifacts such as faceted "snapping"
reflected[0] = normal[0]*2*d - lightDir[0];
reflected[1] = normal[1]*2*d - lightDir[1];
reflected[2] = normal[2]*2*d - lightDir[2];
VectorSubtract (backEnd.or.viewOrigin, v, viewer);
ilength = Q_rsqrt( DotProduct( viewer, viewer ) );
l = DotProduct (reflected, viewer);
l *= ilength;
if (l < 0) {
b = 0;
l = 0;
} else {
l = l*l;
l = l*l;
}
}
incoming2 += l;
j = ri.ftol(ambientLight[0]) + ri.ftol(incoming * directedLight[0]) + ri.ftol(incoming2 * directedLightA[0]);
if ( j > 255 ) {
j = 255;
}
colors[i*4+0] = j;
j = ri.ftol(ambientLight[1]) + ri.ftol(incoming * directedLight[1]) + ri.ftol(incoming2 * directedLightA[1]);
if ( j > 255 ) {
j = 255;
}
colors[i*4+1] = j;
j = ri.ftol(ambientLight[2]) + ri.ftol(incoming * directedLight[2]) + ri.ftol(incoming2 * directedLightA[2]);
if ( j > 255 ) {
j = 255;
}
colors[i*4+2] = j;
colors[i*4+3] = 255;
}
}
// simple faster one without a direction of any kind, should be similar to q2/hl
static void RB_CalcDiffuseColor_lame( unsigned char *colors )
{
@@ -1685,10 +1858,15 @@ void RB_CalcDiffuseColor( unsigned char *colors )
return;
}
#endif
RB_CalcDiffuseColor_scalar( colors );
//RB_CalcDiffuseColor_alternative( colors );
//RB_CalcDiffuseColor_lame( colors );
if (r_shadeMode->integer == 2)
RB_CalcDiffuseColor_alternative( colors );
else if (r_shadeMode->integer == 3)
RB_CalcDiffuseColor_lame( colors );
else if (r_shadeMode->integer == 6)
RB_CalcDiffuseColor_crazy( colors );
else
RB_CalcDiffuseColor_scalar( colors );
}
@@ -1869,3 +2047,163 @@ void RB_CalcFlatDirect( unsigned char *colors )
}
//
// EYES
//
vec3_t eyemin = { -12, -12, -8 }; // clamps
vec3_t eyemax = { 12, 12, 8 }; // clamps
/*
** RB_CalcEyes
*/
void RB_CalcEyes( float *st, qboolean theothereye)
{
int i;
float *v, *normal;
vec3_t viewer, reflected, eyepos, eyelook, stare;
float d, l, erp;
int idk;
vec3_t stareat, staree;
float dilation = 2;
VectorCopy(lightOrigin, staree);
VectorCopy(backEnd.or.viewOrigin, stareat);
// transform the direction to local space
// VectorNormalize( staree );
// stareat[0] = DotProduct( staree, backEnd.currentEntity->e.axis[0] );
// stareat[1] = DotProduct( staree, backEnd.currentEntity->e.axis[1] );
// stareat[2] = DotProduct( staree, backEnd.currentEntity->e.axis[2] );
// VectorNormalize( stareat );
v = tess.xyz[0];
normal = tess.normal[0];
//VectorCopy(lightOrigin, eyepos);
//normal = backEnd.currentEntity.eyepos[0];
VectorCopy(backEnd.currentEntity->e.eyepos[0], eyepos);
if (!theothereye){
eyepos[1] *= -1;
}
VectorCopy(backEnd.currentEntity->e.eyelook, stareat);
// We need to adjust the stareat vectors to local coordinates
vec3_t temp;
VectorSubtract( stareat, backEnd.currentEntity->e.origin, temp );
stareat[0] = DotProduct( temp, backEnd.currentEntity->e.axis[0] );
stareat[1] = DotProduct( temp, backEnd.currentEntity->e.axis[1] );
stareat[2] = DotProduct( temp, backEnd.currentEntity->e.axis[2] );
// debug light positions
if (r_leidebugeye->integer == 2)
{
vec3_t temp;
vec3_t temp2;
VectorCopy(eyepos, temp);
VectorCopy(backEnd.currentEntity->e.eyelook, temp2);
// VectorCopy(backEnd.currentEntity->e.eyelook, stareat);
ri.Printf( PRINT_WARNING, "EYES %f %f %f--\nVieworigin:%f %f %f \nEye look desired:%f %f %f\n", temp[0], temp[1], temp[2], backEnd.or.viewOrigin[0], backEnd.or.viewOrigin[1], backEnd.or.viewOrigin[2], stareat[0], stareat[1], stareat[2] );
VectorNormalize(temp2);
GL_Bind( tr.whiteImage );
qglColor3f (1,1,1);
qglDepthRange( 0, 0 ); // never occluded
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
qglBegin (GL_LINES);
qglVertex3fv (eyepos);
qglVertex3fv (stareat);
qglEnd ();
qglDepthRange( 0, 1 );
}
for (i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 )
{
float norm1, norm2;
// Base eye position
VectorSubtract (backEnd.or.viewOrigin, v, viewer);
//VectorSubtract (backEnd.currentEntity->e.eyepos[0], v, viewer);
VectorSubtract (eyepos, v, viewer);
VectorNormalizeFast (viewer);
d = DotProduct (normal, viewer);
d = d * 0.01f; // only have a slight normal
//d = r_leidebug->value;
//d = 1;
// Stuff to look at
//VectorSubtract (backEnd.currentEntity->e.eyelook, v, stare);
if (r_leidebugeye->integer==1)
VectorSubtract (backEnd.or.viewOrigin, v, stare);
else if (r_leidebugeye->integer==3)
VectorSubtract (stareat, v, stare);
VectorSubtract (stareat, v, stare);
VectorNormalizeFast (stare);
erp = DotProduct (normal, stare);
// Limit the eye's turning so it doesn't have dead eyes
for (idk=0;idk<3;idk++){
stare[idk] *= 22;
if (stare[idk] > eyemax[idk]) stare[idk] = eyemax[idk];
if (stare[idk] < eyemin[idk]) stare[idk] = eyemin[idk];
stare[idk] /= 22;
}
VectorAdd(viewer, stare, viewer);
reflected[0] = normal[0]*2*d - viewer[0];
reflected[1] = normal[1]*2*d - viewer[1];
reflected[2] = normal[2]*2*d - viewer[2];
st[0] = 0.5 + reflected[1] * 0.5;
st[1] = 0.5 - reflected[2] * 0.5;
}
}

View File

@@ -128,6 +128,13 @@ static glslProgram_t *R_GLSL_AllocProgram(void) {
program->u_ScreenToNextPixelX = -1;
program->u_ScreenToNextPixelY = -1;
program->u_zFar = -1;
program->u_MotionBlurX = -1;
program->u_MotionBlurY = -1;
program->u_CC_Brightness = -1;
program->u_CC_Gamma = -1;
program->u_CC_Overbright = -1;
program->u_CC_Contrast = -1;
program->u_CC_Saturation = -1;
tr.programs[tr.numPrograms] = program;
tr.numPrograms++;
@@ -183,6 +190,20 @@ static void R_GLSL_ParseProgram(glslProgram_t *program, char *_text) {
program->u_ScreenToNextPixelY = qglGetUniformLocationARB(program->program, "u_ScreenToNextPixelY");
} else if (!Q_stricmp(token, "u_zFar;")) {
program->u_zFar = qglGetUniformLocationARB(program->program, "u_zFar");
} else if (!Q_stricmp(token, "u_MotionBlurX;")) {
program->u_MotionBlurX = qglGetUniformLocationARB(program->program, "u_MotionBlurX");
} else if (!Q_stricmp(token, "u_MotionBlurY;")) {
program->u_MotionBlurY = qglGetUniformLocationARB(program->program, "u_MotionBlurY");
} else if (!Q_stricmp(token, "u_CC_Brightness;")) {
program->u_CC_Brightness = qglGetUniformLocationARB(program->program, "u_CC_Brightness");
} else if (!Q_stricmp(token, "u_CC_Overbright;")) {
program->u_CC_Overbright = qglGetUniformLocationARB(program->program, "u_CC_Overbright");
} else if (!Q_stricmp(token, "u_CC_Gamma;")) {
program->u_CC_Gamma = qglGetUniformLocationARB(program->program, "u_CC_Gamma");
} else if (!Q_stricmp(token, "u_CC_Contrast;")) {
program->u_CC_Contrast = qglGetUniformLocationARB(program->program, "u_CC_Contrast");
} else if (!Q_stricmp(token, "u_CC_Saturation;")) {
program->u_CC_Saturation = qglGetUniformLocationARB(program->program, "u_CC_Saturation");
} else {
ri.Printf(PRINT_WARNING, "WARNING: uniform float %s unrecognized in program %s\n", token, program->name);
}
@@ -2615,6 +2636,14 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
{
stage->bundle[0].tcGen = TCGEN_ENVIRONMENT_CELSHADE_LEILEI;
}
else if ( !Q_stricmp( token, "eyeleft" ) ) // leilei - eye tracking
{
stage->bundle[0].tcGen = TCGEN_EYE_LEFT;
}
else if ( !Q_stricmp( token, "eyeright" ) ) // leilei - eye tracking
{
stage->bundle[0].tcGen = TCGEN_EYE_RIGHT;
}
else if ( !Q_stricmp( token, "lightmap" ) )
{
stage->bundle[0].tcGen = TCGEN_LIGHTMAP;
@@ -2729,6 +2758,7 @@ deformVertexes projectionShadow
deformVertexes autoSprite
deformVertexes autoSprite2
deformVertexes text[0-7]
deformVertexes tessie // leilei
===============
*/
static void ParseDeform( char **text ) {
@@ -2755,6 +2785,7 @@ static void ParseDeform( char **text ) {
return;
}
if ( !Q_stricmp( token, "autosprite" ) ) {
ds->deformation = DEFORM_AUTOSPRITE;
return;

View File

@@ -62,6 +62,8 @@ typedef struct image_s {
imgFlags_t flags;
struct image_s* next;
qboolean maptexture; // leilei - map texture listing hack
} image_t;
// any change in the LIGHTMAP_* defines here MUST be reflected in

View File

@@ -116,6 +116,13 @@ typedef struct {
// extra sprite information
float radius;
float rotation;
// leilei - eyes
vec3_t eyepos[2]; // looking from
vec3_t eyelook; // looking from
} refEntity_t;