summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/Camera.cpp5
-rw-r--r--src/core/Game.cpp4
-rw-r--r--src/core/config.h1
-rw-r--r--src/core/re3.cpp11
-rw-r--r--src/extras/postfx.cpp516
-rw-r--r--src/extras/postfx.h45
-rw-r--r--src/extras/shaders/Makefile16
-rw-r--r--src/extras/shaders/colourfilterVC.frag28
-rw-r--r--src/extras/shaders/colourfilterVC_PS.csobin0 -> 648 bytes
-rw-r--r--src/extras/shaders/colourfilterVC_PS.hlsl23
-rw-r--r--src/extras/shaders/colourfilterVC_PS.inc56
-rw-r--r--src/extras/shaders/colourfilterVC_fs_gl3.inc30
-rw-r--r--src/extras/shaders/contrast.frag18
-rw-r--r--src/extras/shaders/contrastPS.csobin0 -> 344 bytes
-rw-r--r--src/extras/shaders/contrastPS.hlsl21
-rw-r--r--src/extras/shaders/contrastPS.inc31
-rw-r--r--src/extras/shaders/contrast_fs_gl3.inc20
-rw-r--r--src/extras/shaders/im2d.vert21
-rw-r--r--src/extras/shaders/im2d_gl3.inc23
-rw-r--r--src/extras/shaders/make.cmd3
-rw-r--r--src/extras/shaders/makeinc.sh5
-rw-r--r--src/peds/Ped.cpp1
-rw-r--r--src/render/MBlur.cpp32
-rw-r--r--src/rw/Lights.cpp11
24 files changed, 909 insertions, 12 deletions
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 2f977a20..df778815 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -514,7 +514,12 @@ CCamera::Process(void)
int tableIndex = (int)(DEGTORAD(DrunkAngle)/TWOPI * CParticle::SIN_COS_TABLE_SIZE) & CParticle::SIN_COS_TABLE_SIZE-1;
DrunkAngle += 5.0f;
+#ifndef FIX_BUGS
+ // This just messes up interpolation, probably not what they intended
+ // and multiplying the interpolated FOV is also a bit extreme
+ // so let's not do any of this nonsense
Cams[ActiveCam].FOV *= (1.0f + CMBlur::Drunkness);
+#endif
CamSource.x += -0.02f*CMBlur::Drunkness * CParticle::m_CosTable[tableIndex];
CamSource.y += -0.02f*CMBlur::Drunkness * CParticle::m_SinTable[tableIndex];
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 7b113d89..ce2194a0 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -90,6 +90,7 @@
#include "debugmenu.h"
#include "Ropes.h"
#include "WindModifiers.h"
+#include "postfx.h"
eLevelName CGame::currLevel;
int32 CGame::currArea;
@@ -152,6 +153,9 @@ CGame::InitialiseOnceBeforeRW(void)
CFileMgr::Initialise();
CdStreamInit(MAX_CDCHANNELS);
ValidateVersion();
+#ifdef EXTENDED_COLOURFILTER
+ CPostFX::InitOnce();
+#endif
return true;
}
diff --git a/src/core/config.h b/src/core/config.h
index 469f9017..eadbc307 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -225,6 +225,7 @@ enum Config {
//#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
//#define USE_TEXTURE_POOL
#define CUTSCENE_BORDERS_SWITCH
+//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
// Water & Particle
#define PC_PARTICLE
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 9d10193d..34fbb428 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -33,6 +33,8 @@
#include "WaterLevel.h"
#include "main.h"
#include "Script.h"
+#include "MBlur.h"
+#include "postfx.h"
#ifndef _WIN32
#include "assert.h"
@@ -515,6 +517,15 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Render", "Frame limiter", &FrontEndMenuManager.m_PrefsFrameLimiter, nil);
DebugMenuAddVarBool8("Render", "VSynch", &FrontEndMenuManager.m_PrefsVsync, nil);
DebugMenuAddVar("Render", "Max FPS", &RsGlobal.maxFPS, nil, 1, 1, 1000, nil);
+#ifdef EXTENDED_COLOURFILTER
+ static const char *filternames[] = { "None", "Simple", "Normal", "Mobile" };
+ e = DebugMenuAddVar("Render", "Colourfilter", &CPostFX::EffectSwitch, nil, 1, CPostFX::POSTFX_OFF, CPostFX::POSTFX_MOBILE, filternames);
+ DebugMenuEntrySetWrap(e, true);
+ DebugMenuAddVar("Render", "Intensity", &CPostFX::Intensity, nil, 0.05f, 0, 10.0f);
+ DebugMenuAddVarBool8("Render", "Blur", &CPostFX::BlurOn, nil);
+ DebugMenuAddVarBool8("Render", "Motion Blur", &CPostFX::MotionBlurOn, nil);
+#endif
+ DebugMenuAddVar("Render", "Drunkness", &CMBlur::Drunkness, nil, 0.05f, 0, 1.0f);
DebugMenuAddVarBool8("Render", "Occlusion debug", &bDisplayOccDebugStuff, nil);
DebugMenuAddVarBool8("Render", "Show Ped Paths", &gbShowPedPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Paths", &gbShowCarPaths, nil);
diff --git a/src/extras/postfx.cpp b/src/extras/postfx.cpp
new file mode 100644
index 00000000..e8cd4bc4
--- /dev/null
+++ b/src/extras/postfx.cpp
@@ -0,0 +1,516 @@
+#define WITHWINDOWS
+#define WITH_D3D
+#include "common.h"
+
+#ifdef EXTENDED_COLOURFILTER
+
+#ifndef LIBRW
+#error "Need librw for EXTENDED_COLOURFILTER"
+#endif
+
+#include "RwHelper.h"
+#include "Camera.h"
+#include "MBlur.h"
+#include "postfx.h"
+
+RwRaster *CPostFX::pFrontBuffer;
+RwRaster *CPostFX::pBackBuffer;
+bool CPostFX::bJustInitialised;
+int CPostFX::EffectSwitch = POSTFX_NORMAL;
+bool CPostFX::BlurOn = false;
+bool CPostFX::MotionBlurOn = false;
+
+static RwIm2DVertex Vertex[4];
+static RwIm2DVertex Vertex2[4];
+static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
+
+#ifdef RW_D3D9
+void *colourfilterVC_PS;
+void *contrast_PS;
+#endif
+#ifdef RW_OPENGL
+int32 u_blurcolor;
+int32 u_contrastAdd;
+int32 u_contrastMult;
+rw::gl3::Shader *colourFilterVC;
+rw::gl3::Shader *contrast;
+#endif
+
+void
+CPostFX::InitOnce(void)
+{
+#ifdef RW_OPENGL
+ u_blurcolor = rw::gl3::registerUniform("u_blurcolor");
+ u_contrastAdd = rw::gl3::registerUniform("u_contrastAdd");
+ u_contrastMult = rw::gl3::registerUniform("u_contrastMult");
+#endif
+}
+
+void
+CPostFX::Open(RwCamera *cam)
+{
+ uint32 width = Pow(2.0f, int32(log2(RwRasterGetWidth (RwCameraGetRaster(cam))))+1);
+ uint32 height = Pow(2.0f, int32(log2(RwRasterGetHeight(RwCameraGetRaster(cam))))+1);
+ uint32 depth = RwRasterGetDepth(RwCameraGetRaster(cam));
+ pFrontBuffer = RwRasterCreate(width, height, depth, rwRASTERTYPECAMERATEXTURE);
+ pBackBuffer = RwRasterCreate(width, height, depth, rwRASTERTYPECAMERATEXTURE);
+ bJustInitialised = true;
+
+ float zero, xmax, ymax;
+
+ if(RwRasterGetDepth(RwCameraGetRaster(cam)) == 16){
+ zero = HALFPX;
+ xmax = width + HALFPX;
+ ymax = height + HALFPX;
+ }else{
+ zero = -HALFPX;
+ xmax = width - HALFPX;
+ ymax = height - HALFPX;
+ }
+
+ RwIm2DVertexSetScreenX(&Vertex[0], zero);
+ RwIm2DVertexSetScreenY(&Vertex[0], zero);
+ RwIm2DVertexSetScreenZ(&Vertex[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[0], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[0], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex[1], zero);
+ RwIm2DVertexSetScreenY(&Vertex[1], ymax);
+ RwIm2DVertexSetScreenZ(&Vertex[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[1], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[1], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[1], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[1], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex[2], xmax);
+ RwIm2DVertexSetScreenY(&Vertex[2], ymax);
+ RwIm2DVertexSetScreenZ(&Vertex[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[2], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[2], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex[3], xmax);
+ RwIm2DVertexSetScreenY(&Vertex[3], zero);
+ RwIm2DVertexSetScreenZ(&Vertex[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[3], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[3], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255);
+
+
+ RwIm2DVertexSetScreenX(&Vertex2[0], zero + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[0], zero + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[0], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[0], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[1], 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[1], ymax + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[1], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[1], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[1], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[1], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[2], xmax + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[2], ymax + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[2], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[2], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[3], xmax + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[3], zero + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[3], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[3], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], 255, 255, 255, 255);
+
+
+#ifdef RW_D3D9
+#include "shaders/colourfilterVC_PS.inc"
+ colourfilterVC_PS = rw::d3d::createPixelShader(colourfilterVC_PS_cso);
+#include "shaders/contrastPS.inc"
+ contrast_PS = rw::d3d::createPixelShader(contrastPS_cso);
+#endif
+#ifdef RW_OPENGL
+ using namespace rw::gl3;
+// AllocConsole();
+// freopen("CONIN$", "r", stdin);
+// freopen("CONOUT$", "w", stdout);
+// freopen("CONOUT$", "w", stderr);
+
+
+ {
+#ifdef RW_GLES2
+#include "gl2_shaders/im2d_gl2.inc"
+#include "gl2_shaders/colourfilterVC_fs_gl2.inc"
+#else
+#include "shaders/im2d_gl3.inc"
+#include "shaders/colourfilterVC_fs_gl3.inc"
+#endif
+ const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, colourfilterVC_frag_src, nil };
+ colourFilterVC = Shader::create(vs, fs);
+ assert(colourFilterVC);
+ }
+
+ {
+#ifdef RW_GLES2
+#include "gl2_shaders/im2d_gl2.inc"
+#include "gl2_shaders/contrast_fs_gl2.inc"
+#else
+#include "shaders/im2d_gl3.inc"
+#include "shaders/contrast_fs_gl3.inc"
+ const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, contrast_frag_src, nil };
+ contrast = Shader::create(vs, fs);
+ assert(contrast);
+#endif
+ }
+
+#endif
+}
+
+void
+CPostFX::Close(void)
+{
+ if(pFrontBuffer){
+ RwRasterDestroy(pFrontBuffer);
+ pFrontBuffer = nil;
+ }
+ if(pBackBuffer){
+ RwRasterDestroy(pBackBuffer);
+ pBackBuffer = nil;
+ }
+#ifdef RW_D3D9
+ if(colourfilterVC_PS){
+ rw::d3d::destroyPixelShader(colourfilterVC_PS);
+ colourfilterVC_PS = nil;
+ }
+ if(contrast_PS){
+ rw::d3d::destroyPixelShader(contrast_PS);
+ contrast_PS = nil;
+ }
+#endif
+#ifdef RW_OPENGL
+ if(colourFilterVC){
+ colourFilterVC->destroy();
+ colourFilterVC = nil;
+ }
+ if(contrast){
+ contrast->destroy();
+ contrast = nil;
+ }
+#endif
+}
+
+void
+CPostFX::RenderOverlayBlur(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
+{
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, pFrontBuffer);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r*2, g*2, b*2, 30);
+
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, BlurOn ? Vertex2 : Vertex, 4, Index, 6);
+
+
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
+
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, BlurOn ? Vertex2 : Vertex, 4, Index, 6);
+}
+
+void
+CPostFX::RenderOverlaySniper(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
+{
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, pFrontBuffer);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, 80);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+}
+
+float CPostFX::Intensity = 1.0f;
+
+void
+CPostFX::RenderOverlayShader(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
+{
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, pBackBuffer);
+
+ if(EffectSwitch == POSTFX_MOBILE){
+ float mult[3], add[3];
+ mult[0] = (r-64)/256.0f + 1.4f;
+ mult[1] = (g-64)/256.0f + 1.4f;
+ mult[2] = (b-64)/256.0f + 1.4f;
+ add[0] = r/1536.f - 0.05f;
+ add[1] = g/1536.f - 0.05f;
+ add[2] = b/1536.f - 0.05f;
+#ifdef RW_D3D9
+ rw::d3d::d3ddevice->SetPixelShaderConstantF(10, mult, 1);
+ rw::d3d::d3ddevice->SetPixelShaderConstantF(11, add, 1);
+
+ rw::d3d::im2dOverridePS = contrast_PS;
+#endif
+#ifdef RW_OPENGL
+ rw::gl3::im2dOverrideShader = contrast;
+ contrast->use();
+ glUniform3fv(contrast->uniformLocations[u_contrastMult], 1, mult);
+ glUniform3fv(contrast->uniformLocations[u_contrastAdd], 1, add);
+#endif
+ }else{
+ float f = Intensity;
+ float blurcolors[4];
+ blurcolors[0] = r*f/255.0f;
+ blurcolors[1] = g*f/255.0f;
+ blurcolors[2] = b*f/255.0f;
+ blurcolors[3] = 30/255.0f;
+#ifdef RW_D3D9
+ rw::d3d::d3ddevice->SetPixelShaderConstantF(10, blurcolors, 1);
+
+/*
+ float blurcolors[NUMAVERAGE*4];
+ int j = Next;
+ for(int i = NUMAVERAGE-1; i >= 0; i--){
+ j = (j+NUMAVERAGE-1)%NUMAVERAGE;
+// blurcolors[i*4+0] = PrevRed[j]/255.0f;
+// blurcolors[i*4+1] = PrevGreen[j]/255.0f;
+// blurcolors[i*4+2] = PrevBlue[j]/255.0f;
+// blurcolors[i*4+3] = Intensity/255.0f;
+
+ blurcolors[i*4+0] = r/255.0f;
+ blurcolors[i*4+1] = g/255.0f;
+ blurcolors[i*4+2] = b/255.0f;
+ blurcolors[i*4+3] = Intensity/255.0f;
+ }
+ rw::d3d::d3ddevice->SetPixelShaderConstantF(15, blurcolors, NUMAVERAGE);
+*/
+
+ rw::d3d::im2dOverridePS = colourfilterVC_PS;
+#endif
+#ifdef RW_OPENGL
+ rw::gl3::im2dOverrideShader = colourFilterVC;
+ colourFilterVC->use();
+ glUniform4fv(colourFilterVC->uniformLocations[u_blurcolor], 1, blurcolors);
+#endif
+ }
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+#ifdef RW_D3D9
+ rw::d3d::im2dOverridePS = nil;
+#endif
+#ifdef RW_OPENGL
+ rw::gl3::im2dOverrideShader = nil;
+#endif
+}
+
+void
+CPostFX::RenderMotionBlur(RwCamera *cam, uint32 blur)
+{
+ if(blur == 0)
+ return;
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, pFrontBuffer);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, blur);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, blur);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, blur);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, blur);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+}
+
+bool
+CPostFX::NeedBackBuffer(void)
+{
+ // Current frame -- needed for non-blur effect
+ switch(EffectSwitch){
+ case POSTFX_OFF:
+ case POSTFX_SIMPLE:
+ // no actual rendering here
+ return false;
+ case POSTFX_NORMAL:
+ if(MotionBlurOn)
+ return false;
+ else
+ return true;
+ case POSTFX_MOBILE:
+ return true;
+ }
+ return false;
+}
+
+bool
+CPostFX::NeedFrontBuffer(int32 type)
+{
+ // Last frame -- needed for motion blur
+ if(CMBlur::Drunkness > 0.0f)
+ return true;
+ if(type == MOTION_BLUR_SNIPER)
+ return true;
+
+ switch(EffectSwitch){
+ case POSTFX_OFF:
+ case POSTFX_SIMPLE:
+ // no actual rendering here
+ return false;
+ case POSTFX_NORMAL:
+ if(MotionBlurOn)
+ return true;
+ else
+ return false;
+ case POSTFX_MOBILE:
+ return false;
+ }
+ return false;
+}
+
+void
+CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha)
+{
+ if(pFrontBuffer == nil)
+ Open(cam);
+ assert(pFrontBuffer);
+ assert(pBackBuffer);
+
+ if(type == MOTION_BLUR_LIGHT_SCENE){
+ SmoothColor(red, green, blue, blur);
+ red = AvgRed;
+ green = AvgGreen;
+ blue = AvgBlue;
+ blur = AvgAlpha;
+ }
+
+ if(NeedBackBuffer()){
+ RwRasterPushContext(pBackBuffer);
+ RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
+ RwRasterPopContext();
+ }
+
+ DefinedState();
+
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+
+ if(type == MOTION_BLUR_SNIPER){
+ if(!bJustInitialised)
+ RenderOverlaySniper(cam, red, green, blue, blur);
+ }else switch(EffectSwitch){
+ case POSTFX_OFF:
+ case POSTFX_SIMPLE:
+ // no actual rendering here
+ break;
+ case POSTFX_NORMAL:
+ if(MotionBlurOn){
+ if(!bJustInitialised)
+ RenderOverlayBlur(cam, red, green, blue, blur);
+ }else{
+ RenderOverlayShader(cam, red, green, blue, blur);
+ }
+ break;
+ case POSTFX_MOBILE:
+ RenderOverlayShader(cam, red, green, blue, blur);
+ break;
+ }
+
+ if(!bJustInitialised)
+ RenderMotionBlur(cam, 175.0f * CMBlur::Drunkness);
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ if(NeedFrontBuffer(type)){
+ RwRasterPushContext(pFrontBuffer);
+ RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
+ RwRasterPopContext();
+ bJustInitialised = false;
+ }else
+ bJustInitialised = true;
+}
+
+int CPostFX::PrevRed[NUMAVERAGE], CPostFX::AvgRed;
+int CPostFX::PrevGreen[NUMAVERAGE], CPostFX::AvgGreen;
+int CPostFX::PrevBlue[NUMAVERAGE], CPostFX::AvgBlue;
+int CPostFX::PrevAlpha[NUMAVERAGE], CPostFX::AvgAlpha;
+int CPostFX::Next;
+int CPostFX::NumValues;
+
+// This is rather annoying...the blur color can flicker slightly
+// which becomes very visible when amplified by the shader
+void
+CPostFX::SmoothColor(uint32 red, uint32 green, uint32 blue, uint32 alpha)
+{
+ PrevRed[Next] = red;
+ PrevGreen[Next] = green;
+ PrevBlue[Next] = blue;
+ PrevAlpha[Next] = alpha;
+ Next = (Next+1) % NUMAVERAGE;
+ NumValues = Min(NumValues+1, NUMAVERAGE);
+
+ AvgRed = 0;
+ AvgGreen = 0;
+ AvgBlue = 0;
+ AvgAlpha = 0;
+ for(int i = 0; i < NumValues; i++){
+ AvgRed += PrevRed[i];
+ AvgGreen += PrevGreen[i];
+ AvgBlue += PrevBlue[i];
+ AvgAlpha += PrevAlpha[i];
+ }
+ AvgRed /= NumValues;
+ AvgGreen /= NumValues;
+ AvgBlue /= NumValues;
+ AvgAlpha /= NumValues;
+}
+
+#endif
diff --git a/src/extras/postfx.h b/src/extras/postfx.h
new file mode 100644
index 00000000..ace2e4a8
--- /dev/null
+++ b/src/extras/postfx.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#ifdef EXTENDED_COLOURFILTER
+
+class CPostFX
+{
+public:
+ enum {
+ POSTFX_OFF,
+ POSTFX_SIMPLE,
+ POSTFX_NORMAL,
+ POSTFX_MOBILE
+ };
+ static RwRaster *pFrontBuffer;
+ static RwRaster *pBackBuffer;
+ static bool bJustInitialised;
+ static int EffectSwitch;
+ static bool BlurOn; // or use CMblur for that?
+ static bool MotionBlurOn; // or use CMblur for that?
+ static float Intensity;
+
+ // smooth blur color
+ enum { NUMAVERAGE = 20 };
+ static int PrevRed[NUMAVERAGE], AvgRed;
+ static int PrevGreen[NUMAVERAGE], AvgGreen;
+ static int PrevBlue[NUMAVERAGE], AvgBlue;
+ static int PrevAlpha[NUMAVERAGE], AvgAlpha;
+ static int Next;
+ static int NumValues;
+
+ static void InitOnce(void);
+ static void Open(RwCamera *cam);
+ static void Close(void);
+ static void RenderOverlayBlur(RwCamera *cam, int32 r, int32 g, int32 b, int32 a);
+ static void RenderOverlaySniper(RwCamera *cam, int32 r, int32 g, int32 b, int32 a);
+ static void RenderOverlayShader(RwCamera *cam, int32 r, int32 g, int32 b, int32 a);
+ static void RenderMotionBlur(RwCamera *cam, uint32 blur);
+ static void Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha);
+ static void SmoothColor(uint32 red, uint32 green, uint32 blue, uint32 alpha);
+ static bool NeedBackBuffer(void);
+ static bool NeedFrontBuffer(int32 type);
+ static bool UseBlurColours(void) { return EffectSwitch != POSTFX_SIMPLE; }
+};
+
+#endif
diff --git a/src/extras/shaders/Makefile b/src/extras/shaders/Makefile
new file mode 100644
index 00000000..effb6afc
--- /dev/null
+++ b/src/extras/shaders/Makefile
@@ -0,0 +1,16 @@
+all: im2d_gl3.inc colourfilterVC_fs_gl3.inc contrast_fs_gl3.inc
+
+im2d_gl3.inc: im2d.vert
+ (echo 'const char *im2d_vert_src =';\
+ sed 's/..*/"&\\n"/' im2d.vert;\
+ echo ';') >im2d_gl3.inc
+
+colourfilterVC_fs_gl3.inc: colourfilterVC.frag
+ (echo 'const char *colourfilterVC_frag_src =';\
+ sed 's/..*/"&\\n"/' colourfilterVC.frag;\
+ echo ';') >colourfilterVC_fs_gl3.inc
+
+contrast_fs_gl3.inc: contrast.frag
+ (echo 'const char *contrast_frag_src =';\
+ sed 's/..*/"&\\n"/' contrast.frag;\
+ echo ';') >contrast_fs_gl3.inc
diff --git a/src/extras/shaders/colourfilterVC.frag b/src/extras/shaders/colourfilterVC.frag
new file mode 100644
index 00000000..e19a8600
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC.frag
@@ -0,0 +1,28 @@
+uniform sampler2D tex0;
+uniform vec4 u_blurcolor;
+
+in vec4 v_color;
+in vec2 v_tex0;
+in float v_fog;
+
+out vec4 color;
+
+void
+main(void)
+{
+ float a = u_blurcolor.a;
+
+ vec4 doublec = clamp(u_blurcolor*2, 0.0, 1.0);
+ vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ vec4 prev = dst;
+ for(int i = 0; i < 5; i++){
+// vec4 doublec = clamp(u_blurcolor*2, 0.0, 1.0);
+ vec4 tmp = dst*(1.0-a) + prev*doublec*a;
+ tmp += prev*u_blurcolor;
+ tmp += prev*u_blurcolor;
+ prev = clamp(tmp, 0.0, 1.0);
+ }
+ color.rgb = prev.rgb;
+ color.a = 1.0f;
+}
+
diff --git a/src/extras/shaders/colourfilterVC_PS.cso b/src/extras/shaders/colourfilterVC_PS.cso
new file mode 100644
index 00000000..4b0e9f3f
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC_PS.cso
Binary files differ
diff --git a/src/extras/shaders/colourfilterVC_PS.hlsl b/src/extras/shaders/colourfilterVC_PS.hlsl
new file mode 100644
index 00000000..1e62950b
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC_PS.hlsl
@@ -0,0 +1,23 @@
+sampler2D tex : register(s0);
+float4 blurcol : register(c10);
+
+//float4 blurcols[10] : register(c15);
+
+
+float4 main(in float2 texcoord : TEXCOORD0) : COLOR0
+{
+ float a = blurcol.a;
+
+ float4 doublec = saturate(blurcol*2);
+ float4 dst = tex2D(tex, texcoord.xy);
+ float4 prev = dst;
+ for(int i = 0; i < 5; i++){
+// float4 doublec = saturate(blurcol*2);
+ float4 tmp = dst*(1-a) + prev*doublec*a;
+ tmp += prev*blurcol;
+ tmp += prev*blurcol;
+ prev = saturate(tmp);
+ }
+ prev.a = 1.0f;
+ return prev;
+}
diff --git a/src/extras/shaders/colourfilterVC_PS.inc b/src/extras/shaders/colourfilterVC_PS.inc
new file mode 100644
index 00000000..daa18360
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC_PS.inc
@@ -0,0 +1,56 @@
+static unsigned char colourfilterVC_PS_cso[] = {
+ 0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x2b, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
+ 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x70, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x00,
+ 0x01, 0x00, 0x2a, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x75, 0x72,
+ 0x63, 0x6f, 0x6c, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00,
+ 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d,
+ 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29,
+ 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72,
+ 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e,
+ 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00,
+ 0x51, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0xb0,
+ 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x00, 0x08, 0x0f, 0xa0,
+ 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xb0,
+ 0x00, 0x08, 0xe4, 0xa0, 0x02, 0x00, 0x00, 0x03, 0x01, 0x00, 0x17, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x0a, 0x00, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x03,
+ 0x02, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x12, 0x00, 0x00, 0x04, 0x03, 0x00, 0x07, 0x80, 0x0a, 0x00, 0xff, 0xa0,
+ 0x02, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x02, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x0a, 0x00, 0xe4, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x04, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x04, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x04, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x04, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x04, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x04, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x03, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x01, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x55, 0xa0, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/colourfilterVC_fs_gl3.inc b/src/extras/shaders/colourfilterVC_fs_gl3.inc
new file mode 100644
index 00000000..acb9b15c
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC_fs_gl3.inc
@@ -0,0 +1,30 @@
+const char *colourfilterVC_frag_src =
+"uniform sampler2D tex0;\n"
+"uniform vec4 u_blurcolor;\n"
+
+"in vec4 v_color;\n"
+"in vec2 v_tex0;\n"
+"in float v_fog;\n"
+
+"out vec4 color;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" float a = u_blurcolor.a;\n"
+
+" vec4 doublec = clamp(u_blurcolor*2, 0.0, 1.0);\n"
+" vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" vec4 prev = dst;\n"
+" for(int i = 0; i < 5; i++){\n"
+"// vec4 doublec = clamp(u_blurcolor*2, 0.0, 1.0);\n"
+" vec4 tmp = dst*(1.0-a) + prev*doublec*a;\n"
+" tmp += prev*u_blurcolor;\n"
+" tmp += prev*u_blurcolor;\n"
+" prev = clamp(tmp, 0.0, 1.0);\n"
+" }\n"
+" color.rgb = prev.rgb;\n"
+" color.a = 1.0f;\n"
+"}\n"
+
+;
diff --git a/src/extras/shaders/contrast.frag b/src/extras/shaders/contrast.frag
new file mode 100644
index 00000000..d6dec478
--- /dev/null
+++ b/src/extras/shaders/contrast.frag
@@ -0,0 +1,18 @@
+uniform sampler2D tex0;
+uniform vec3 u_contrastAdd;
+uniform vec3 u_contrastMult;
+
+in vec4 v_color;
+in vec2 v_tex0;
+in float v_fog;
+
+out vec4 color;
+
+void
+main(void)
+{
+ vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ color.rgb = dst.rgb*u_contrastMult + u_contrastAdd;
+ color.a = 1.0f;
+}
+
diff --git a/src/extras/shaders/contrastPS.cso b/src/extras/shaders/contrastPS.cso
new file mode 100644
index 00000000..a87c48d7
--- /dev/null
+++ b/src/extras/shaders/contrastPS.cso
Binary files differ
diff --git a/src/extras/shaders/contrastPS.hlsl b/src/extras/shaders/contrastPS.hlsl
new file mode 100644
index 00000000..a1de1d81
--- /dev/null
+++ b/src/extras/shaders/contrastPS.hlsl
@@ -0,0 +1,21 @@
+struct PS_INPUT
+{
+ float4 position : POSITION;
+ float3 texcoord0 : TEXCOORD0;
+ float4 color : COLOR0;
+};
+
+uniform float3 contrastMult : register(c10);
+uniform float3 contrastAdd : register(c11);
+
+sampler2D tex : register(s0);
+
+float4
+main(PS_INPUT In) : COLOR
+{
+ float4 dst = tex2D(tex, In.texcoord0.xy);
+
+ dst.rgb = dst.rgb*contrastMult + contrastAdd;
+ dst.a = 1.0;
+ return dst;
+}
diff --git a/src/extras/shaders/contrastPS.inc b/src/extras/shaders/contrastPS.inc
new file mode 100644
index 00000000..5386792f
--- /dev/null
+++ b/src/extras/shaders/contrastPS.inc
@@ -0,0 +1,31 @@
+static unsigned char contrastPS_cso[] = {
+ 0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x35, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
+ 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x98, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0b, 0x00,
+ 0x01, 0x00, 0x2e, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x2a, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x88, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74,
+ 0x41, 0x64, 0x64, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x74,
+ 0x72, 0x61, 0x73, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x00, 0x74, 0x65, 0x78,
+ 0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x32,
+ 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
+ 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68,
+ 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
+ 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33,
+ 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0xa0,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
+ 0x00, 0x08, 0x0f, 0xa0, 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x00, 0x00, 0xe4, 0xb0, 0x00, 0x08, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02,
+ 0x01, 0x00, 0x07, 0x80, 0x0a, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x0b, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/contrast_fs_gl3.inc b/src/extras/shaders/contrast_fs_gl3.inc
new file mode 100644
index 00000000..58aaf079
--- /dev/null
+++ b/src/extras/shaders/contrast_fs_gl3.inc
@@ -0,0 +1,20 @@
+const char *contrast_frag_src =
+"uniform sampler2D tex0;\n"
+"uniform vec3 u_contrastAdd;\n"
+"uniform vec3 u_contrastMult;\n"
+
+"in vec4 v_color;\n"
+"in vec2 v_tex0;\n"
+"in float v_fog;\n"
+
+"out vec4 color;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" color.rgb = dst.rgb*u_contrastMult + u_contrastAdd;\n"
+" color.a = 1.0f;\n"
+"}\n"
+
+;
diff --git a/src/extras/shaders/im2d.vert b/src/extras/shaders/im2d.vert
new file mode 100644
index 00000000..241593b1
--- /dev/null
+++ b/src/extras/shaders/im2d.vert
@@ -0,0 +1,21 @@
+uniform vec4 u_xform;
+
+layout(location = 0) in vec4 in_pos;
+layout(location = 2) in vec4 in_color;
+layout(location = 3) in vec2 in_tex0;
+
+out vec4 v_color;
+out vec2 v_tex0;
+out float v_fog;
+
+void
+main(void)
+{
+ gl_Position = in_pos;
+ gl_Position.w = 1.0;
+ gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;
+ v_fog = DoFog(gl_Position.z);
+ gl_Position.xyz *= gl_Position.w;
+ v_color = in_color;
+ v_tex0 = in_tex0;
+}
diff --git a/src/extras/shaders/im2d_gl3.inc b/src/extras/shaders/im2d_gl3.inc
new file mode 100644
index 00000000..68341b39
--- /dev/null
+++ b/src/extras/shaders/im2d_gl3.inc
@@ -0,0 +1,23 @@
+const char *im2d_vert_src =
+"uniform vec4 u_xform;\n"
+
+"layout(location = 0) in vec4 in_pos;\n"
+"layout(location = 2) in vec4 in_color;\n"
+"layout(location = 3) in vec2 in_tex0;\n"
+
+"out vec4 v_color;\n"
+"out vec2 v_tex0;\n"
+"out float v_fog;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" gl_Position = in_pos;\n"
+" gl_Position.w = 1.0;\n"
+" gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;\n"
+" v_fog = DoFog(gl_Position.z);\n"
+" gl_Position.xyz *= gl_Position.w;\n"
+" v_color = in_color;\n"
+" v_tex0 = in_tex0;\n"
+"}\n"
+;
diff --git a/src/extras/shaders/make.cmd b/src/extras/shaders/make.cmd
new file mode 100644
index 00000000..8404ac6c
--- /dev/null
+++ b/src/extras/shaders/make.cmd
@@ -0,0 +1,3 @@
+@echo off
+for %%f in (*PS.hlsl) do "%DXSDK_DIR%\Utilities\bin\x86\fxc.exe" /T ps_2_0 /nologo /E main /Fo %%~nf.cso %%f
+for %%f in (*VS.hlsl) do "%DXSDK_DIR%\Utilities\bin\x86\fxc.exe" /T vs_2_0 /nologo /E main /Fo %%~nf.cso %%f
diff --git a/src/extras/shaders/makeinc.sh b/src/extras/shaders/makeinc.sh
new file mode 100644
index 00000000..a649af33
--- /dev/null
+++ b/src/extras/shaders/makeinc.sh
@@ -0,0 +1,5 @@
+#!sh
+for i in *cso; do
+ (echo -n 'static '
+ xxd -i $i | grep -v '_len = ') > ${i%cso}inc
+done
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index a1c03024..26c91abb 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -2798,6 +2798,7 @@ CPed::SetModelIndex(uint32 mi)
{
m_pRTShadow = new CCutsceneShadow;
m_pRTShadow->Create(m_rwObject, 10, 1, 1, 1);
+ //m_pRTShadow->Create(m_rwObject, 8, 0, 0, 0);
}
#endif
}
diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp
index 4c805d25..08298a1f 100644
--- a/src/render/MBlur.cpp
+++ b/src/render/MBlur.cpp
@@ -11,6 +11,7 @@
#include "Camera.h"
#include "MBlur.h"
#include "Timer.h"
+#include "postfx.h"
// Originally taken from RW example 'mblur'
@@ -30,6 +31,10 @@ extern "C" D3DCAPS8 _RwD3D8DeviceCaps;
RwBool
CMBlur::MotionBlurOpen(RwCamera *cam)
{
+#ifdef EXTENDED_COLOURFILTER
+ CPostFX::Open(cam);
+ return TRUE;
+#else
#ifdef GTA_PS2
RwRect rect = {0, 0, 0, 0};
@@ -130,18 +135,22 @@ CMBlur::MotionBlurOpen(RwCamera *cam)
return TRUE;
#endif
+#endif
}
RwBool
CMBlur::MotionBlurClose(void)
{
+#ifdef EXTENDED_COLOURFILTER
+ CPostFX::Close();
+#else
if(pFrontBuffer){
RwRasterDestroy(pFrontBuffer);
pFrontBuffer = nil;
return TRUE;
}
-
+#endif
return FALSE;
}
@@ -197,8 +206,8 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255);
- RwIm2DVertexSetScreenX(&Vertex2[0], zero);
- RwIm2DVertexSetScreenY(&Vertex2[0], zero);
+ RwIm2DVertexSetScreenX(&Vertex2[0], zero + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[0], zero + 2.0f);
RwIm2DVertexSetScreenZ(&Vertex2[0], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&Vertex2[0], RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetRecipCameraZ(&Vertex2[0], 1.0f/RwCameraGetNearClipPlane(cam));
@@ -206,8 +215,8 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
RwIm2DVertexSetV(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetIntRGBA(&Vertex2[0], 255, 255, 255, 255);
- RwIm2DVertexSetScreenX(&Vertex2[1], zero);
- RwIm2DVertexSetScreenY(&Vertex2[1], ymax);
+ RwIm2DVertexSetScreenX(&Vertex2[1], 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[1], ymax + 2.0f);
RwIm2DVertexSetScreenZ(&Vertex2[1], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&Vertex2[1], RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetRecipCameraZ(&Vertex2[1], 1.0f/RwCameraGetNearClipPlane(cam));
@@ -215,8 +224,8 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
RwIm2DVertexSetV(&Vertex2[1], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetIntRGBA(&Vertex2[1], 255, 255, 255, 255);
- RwIm2DVertexSetScreenX(&Vertex2[2], xmax);
- RwIm2DVertexSetScreenY(&Vertex2[2], ymax);
+ RwIm2DVertexSetScreenX(&Vertex2[2], xmax + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[2], ymax + 2.0f);
RwIm2DVertexSetScreenZ(&Vertex2[2], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&Vertex2[2], RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetRecipCameraZ(&Vertex2[2], 1.0f/RwCameraGetNearClipPlane(cam));
@@ -224,20 +233,22 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
RwIm2DVertexSetV(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetIntRGBA(&Vertex2[2], 255, 255, 255, 255);
- RwIm2DVertexSetScreenX(&Vertex2[3], xmax);
- RwIm2DVertexSetScreenY(&Vertex2[3], zero);
+ RwIm2DVertexSetScreenX(&Vertex2[3], xmax + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[3], zero + 2.0f);
RwIm2DVertexSetScreenZ(&Vertex2[3], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&Vertex2[3], RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetRecipCameraZ(&Vertex2[3], 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetU(&Vertex2[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetV(&Vertex2[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetIntRGBA(&Vertex2[3], 255, 255, 255, 255);
-
}
void
CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha)
{
+#ifdef EXTENDED_COLOURFILTER
+ CPostFX::Render(cam, red, green, blue, blur, type, bluralpha);
+#else
RwRGBA color = { (RwUInt8)red, (RwUInt8)green, (RwUInt8)blue, (RwUInt8)blur };
#ifdef GTA_PS2
if( pFrontBuffer )
@@ -253,6 +264,7 @@ CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, u
RwRasterPopContext();
}
#endif
+#endif
}
static uint8 DrunkBlurRed = 128;
diff --git a/src/rw/Lights.cpp b/src/rw/Lights.cpp
index cd45b81f..c5038232 100644
--- a/src/rw/Lights.cpp
+++ b/src/rw/Lights.cpp
@@ -23,6 +23,13 @@ RwRGBAReal DirectionalLightColourForFrame;
RwRGBAReal AmbientLightColour;
RwRGBAReal DirectionalLightColour;
+#ifdef EXTENDED_COLOURFILTER
+#include "postfx.h"
+#define USEBLURCOLORS CPostFX::UseBlurColours()
+#else
+#define USEBLURCOLORS CMBlur::BlurOn
+#endif
+
//--MIAMI: done
void
SetLightsWithTimeOfDayColour(RpWorld *)
@@ -31,7 +38,7 @@ SetLightsWithTimeOfDayColour(RpWorld *)
RwMatrix mat;
if(pAmbient){
- if(CMBlur::BlurOn){
+ if(USEBLURCOLORS){
AmbientLightColourForFrame.red = CTimeCycle::GetAmbientRed_Bl() * CCoronas::LightsMult;
AmbientLightColourForFrame.green = CTimeCycle::GetAmbientGreen_Bl() * CCoronas::LightsMult;
AmbientLightColourForFrame.blue = CTimeCycle::GetAmbientBlue_Bl() * CCoronas::LightsMult;
@@ -41,7 +48,7 @@ SetLightsWithTimeOfDayColour(RpWorld *)
AmbientLightColourForFrame.blue = CTimeCycle::GetAmbientBlue() * CCoronas::LightsMult;
}
- if(CMBlur::BlurOn){
+ if(USEBLURCOLORS){
AmbientLightColourForFrame_PedsCarsAndObjects.red = CTimeCycle::GetAmbientRed_Obj_Bl() * CCoronas::LightsMult;
AmbientLightColourForFrame_PedsCarsAndObjects.green = CTimeCycle::GetAmbientGreen_Obj_Bl() * CCoronas::LightsMult;
AmbientLightColourForFrame_PedsCarsAndObjects.blue = CTimeCycle::GetAmbientBlue_Obj_Bl() * CCoronas::LightsMult;