1753 lines
62 KiB
C++
1753 lines
62 KiB
C++
/*
|
|
=======================================================================
|
|
FILE : GLScreenRender.cpp
|
|
DESC : screen renderer
|
|
PROJ : Crytek Engine
|
|
CODER: Tiago Sousa
|
|
|
|
Last Update: 18/11/2003
|
|
|
|
Todo:
|
|
- Clean up code
|
|
- Remove redundant data/tests
|
|
=======================================================================
|
|
*/
|
|
|
|
#include "RenderPCH.h"
|
|
#include "GL_Renderer.h"
|
|
#include "I3dengine.h"
|
|
|
|
// tiago: added
|
|
#include "GLCGPShader.h"
|
|
#include "GLCGVProgram.h"
|
|
#include "../Common/RendElements/CREScreenCommon.h"
|
|
|
|
// check shader presence
|
|
#define CHECK_SHADER(s, msg)\
|
|
if(!(s))\
|
|
{\
|
|
if (gRenDev->m_LogFile)\
|
|
{\
|
|
gRenDev->Logv(SRendItem::m_RecurseLevel, "ERROR! %s program not present !\n", msg);\
|
|
}\
|
|
return 0;\
|
|
}\
|
|
|
|
// log helper
|
|
#define LOG_EFFECT(msg)\
|
|
if (gRenDev->m_LogFile)\
|
|
{\
|
|
gRenDev->Logv(SRendItem::m_RecurseLevel, msg);\
|
|
}\
|
|
|
|
// ====================================================================
|
|
// compute scaled texture coordinates for texel-to-pixel correct output
|
|
|
|
#define TEXEL_TO_SCREEN(size) \
|
|
((size)==0)? 0.0f: 0.5f/((float)(size))
|
|
|
|
// ===============================================================
|
|
// SetTexture - sets texture stage
|
|
|
|
inline void SetTexture(CGLRenderer *pRenderer, STexPic *pTex, int iStage, int iMinFilter, int iMagFilter, bool bClamp)
|
|
{
|
|
pRenderer->EF_SelectTMU(iStage);
|
|
if(pTex)
|
|
{
|
|
pTex->m_RefTex.m_MinFilter=iMinFilter;
|
|
pTex->m_RefTex.m_MagFilter=iMagFilter;
|
|
pTex->m_RefTex.bRepeats=(!bClamp);
|
|
pTex->Set();
|
|
|
|
GLenum iTextureMode = pTex->m_TargetType;
|
|
glTexParameteri(iTextureMode, GL_TEXTURE_MIN_FILTER, iMinFilter);
|
|
glTexParameteri(iTextureMode, GL_TEXTURE_MAG_FILTER, iMagFilter);
|
|
|
|
if(!pTex->m_RefTex.bRepeats)
|
|
{
|
|
glTexParameteri(iTextureMode, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(iTextureMode, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pRenderer->SetTexture(0);
|
|
}
|
|
}
|
|
|
|
// =================================================================================
|
|
// CopyScreenToTexture - copy screen into texture (note: this assumes texture is screen sized)
|
|
|
|
inline void CopyScreenToTexture(CGLRenderer *pRenderer, STexPic *pTex)
|
|
{
|
|
// copy to previous frame buffer texture
|
|
SetTexture(pRenderer, pTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
glCopyTexSubImage2D(pTex->m_TargetType, 0, 0, 0, 0, 0, pTex->m_Width, pTex->m_Height);
|
|
|
|
/*{
|
|
byte *pDst = new byte [pTex->m_Width*pTex->m_Height*4];
|
|
glGetTexImage(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, GL_UNSIGNED_BYTE, pDst);
|
|
|
|
WriteJPG(pDst, pTex->m_Width, pTex->m_Height, "Screen.jpg");
|
|
delete [] pDst;
|
|
}*/
|
|
}
|
|
|
|
// ===============================================================
|
|
// CreateRenderTarget - texture targets creation helper
|
|
// Last Update: 28/05/2003
|
|
|
|
bool CreateRenderTarget(CGLRenderer *pRenderer, STexPic *&pTex, int iWidth, int iHeight, bool bUseAlpha, bool bLockable)
|
|
{
|
|
// check if parameters are valid
|
|
if(!pRenderer || !pTex || !iWidth || !iHeight)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// recreate texture when necessary
|
|
if(pTex->m_Width!=iWidth || pTex->m_Height!=iHeight)
|
|
{
|
|
pTex->m_Flags&= ~FT_ALLOCATED;
|
|
}
|
|
|
|
GLenum srcFormat=(bUseAlpha)?GL_RGBA : GL_RGB;
|
|
GLenum dstFormat=(bUseAlpha)?GL_RGBA8 : GL_RGB8;
|
|
|
|
// if not created yet, create texture
|
|
if (!(pTex->m_Flags & FT_ALLOCATED))
|
|
{
|
|
// set texture flags
|
|
pTex->m_Flags |= FT_ALLOCATED;
|
|
pTex->m_Flags2 |= FT2_RECTANGLE;
|
|
pTex->m_TargetType = GL_TEXTURE_RECTANGLE_NV;
|
|
|
|
pTex->m_Width = iWidth;
|
|
pTex->m_Height = iHeight;
|
|
pRenderer->m_TexMan->SetTexture(pTex->m_Bind, eTT_Rectangle);
|
|
glTexImage2D(pTex->m_TargetType, 0, dstFormat, iWidth, iHeight, 0, srcFormat, GL_UNSIGNED_BYTE, 0);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// ===============================================================
|
|
// BlurTextureHw - blur texture in hardware
|
|
// Last Update: 30/07/2003
|
|
// Todo: add diferent blur types/optimize also
|
|
// Notes: only rectangular texture supported
|
|
|
|
bool BlurTextureHw(CScreenVars *pVars, CGLRenderer *pRenderer, STexPic *&pTex, int iBlurType, int iBlurAmount, bool bDefineRT, bool bRestoreRT)
|
|
{
|
|
// make sure data ok
|
|
if(!pRenderer || !pTex)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
LOG_EFFECT("*** Begin texture bluring process... ***\n")
|
|
|
|
// get vertex/fragment program
|
|
CCGVProgram_GL *vpBlur=(CCGVProgram_GL *) pVars->m_pVPBlur;
|
|
CCGPShader_GL *fpBlur;
|
|
if (pTex->m_TargetType == GL_TEXTURE_RECTANGLE_NV)
|
|
fpBlur=(CCGPShader_GL *) pVars->m_pRCBlurRECT;
|
|
else
|
|
fpBlur=(CCGPShader_GL *) pVars->m_pRCBlur;
|
|
CHECK_SHADER(vpBlur, "Blur vertex")
|
|
CHECK_SHADER(fpBlur, "Blur fragment")
|
|
|
|
// get current viewport
|
|
int iTmpX, iTmpY, iTempWidth, iTempHeight;
|
|
gRenDev->GetViewport(&iTmpX, &iTmpY, &iTempWidth, &iTempHeight);
|
|
|
|
// resize screen to fit texture
|
|
gRenDev->SetViewport( 0, 0, pTex->m_Width, pTex->m_Height );
|
|
|
|
// blur texture
|
|
|
|
// setup texture offsets, for texture neighboors sampling
|
|
float s1=1.0f;///((float)pTex->m_Width);
|
|
float t1=1.0f;///((float)pTex->m_Height);
|
|
float s_off=s1*0.5f;
|
|
float t_off=t1*0.5f;
|
|
|
|
float pfOffset0[]={ s1*0.5f, t1, 0.0f, 0.0f};
|
|
float pfOffset1[]={ -s1, t1*0.5f, 0.0f, 0.0f};
|
|
float pfOffset2[]={-s1*0.5f, -t1, 0.0f, 0.0f};
|
|
float pfOffset3[]={ s1, -t1*0.5f, 0.0f, 0.0f};
|
|
|
|
// render quad
|
|
SetTexture(pRenderer, pTex, 0, GL_LINEAR, GL_LINEAR, 1);
|
|
SetTexture(pRenderer, pTex, 1, GL_LINEAR, GL_LINEAR, 1);
|
|
SetTexture(pRenderer, pTex, 2, GL_LINEAR, GL_LINEAR, 1);
|
|
SetTexture(pRenderer, pTex, 3, GL_LINEAR, GL_LINEAR, 1);
|
|
|
|
// set current vertex/fragment program
|
|
vpBlur->mfSet(true, 0);
|
|
fpBlur->mfSet(true, 0);
|
|
pRenderer->EF_CommitVS();
|
|
pRenderer->EF_CommitPS();
|
|
|
|
// set vertex program consts
|
|
|
|
// set texture coordinates, displacement offsets
|
|
vpBlur->mfParameter4f("Offset0", pfOffset0);
|
|
vpBlur->mfParameter4f("Offset1", pfOffset1);
|
|
vpBlur->mfParameter4f("Offset2", pfOffset2);
|
|
vpBlur->mfParameter4f("Offset3", pfOffset3);
|
|
|
|
|
|
// setup screen aligned quad
|
|
struct_VERTEX_FORMAT_P3F_TEX2F pScreenBlur[] =
|
|
{
|
|
Vec3(1, 1, 0), (float)pTex->m_Width+s_off, 0,
|
|
Vec3(1, 0, 0), (float)pTex->m_Width+s_off, (float)pTex->m_Height+t_off,
|
|
Vec3(0, 1, 0), 0, 0,
|
|
Vec3(0, 0, 0), 0, (float)pTex->m_Height+t_off,
|
|
};
|
|
|
|
// blur texture
|
|
if(iBlurType==0) // simple box blur
|
|
{
|
|
for(int iBlurPasses=0; iBlurPasses< iBlurAmount; iBlurPasses++)
|
|
{
|
|
// set texture coordinates scale (needed for rectangular textures in gl ..)
|
|
float pfScale[]={ 1, 1, 1.0f, 1.0f } ; //iBlurPasses};
|
|
vpBlur->mfParameter4f("vTexCoordScale", pfScale);
|
|
|
|
// render screen aligned quad...
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenBlur,VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
CopyScreenToTexture(pRenderer, pTex);
|
|
}
|
|
}
|
|
|
|
vpBlur->mfSet(false, 0);
|
|
fpBlur->mfSet(false, 0);
|
|
|
|
pRenderer->EF_SelectTMU(1);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(2);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(3);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(0);
|
|
|
|
// restore previous viewport
|
|
gRenDev->SetViewport( 0, 0, iTempWidth, iTempHeight);
|
|
|
|
LOG_EFFECT("*** End texture bluring process... ***\n")
|
|
return 1;
|
|
}
|
|
|
|
// =========================================================================
|
|
// ResizeTextureHw - resize a texture in hardware, using bilinear resampling
|
|
bool ResizeTextureHw(CScreenVars *pVars, CGLRenderer *pRenderer, STexPic *&pSrc, STexPic *&pDst)
|
|
{
|
|
// make sure data ok
|
|
if(!pRenderer || !pSrc || !pDst || !pVars)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
LOG_EFFECT("*** Begin texture resampling process... ***\n")
|
|
|
|
// get vertex/fragment program
|
|
CCGVProgram_GL *vpBlur=(CCGVProgram_GL *) pVars->m_pVPBlur;
|
|
CCGPShader_GL *fpBlur;
|
|
if (pSrc->m_TargetType == GL_TEXTURE_RECTANGLE_NV)
|
|
fpBlur=(CCGPShader_GL *) pVars->m_pRCBlurRECT;
|
|
else
|
|
fpBlur=(CCGPShader_GL *) pVars->m_pRCBlur;
|
|
|
|
gRenDev->SetViewport( 0, 0, pDst->m_Width, pDst->m_Height );
|
|
|
|
// set current vertex/fragment program
|
|
vpBlur->mfSet(true, 0);
|
|
fpBlur->mfSet(true, 0);
|
|
pRenderer->EF_CommitVS();
|
|
pRenderer->EF_CommitPS();
|
|
|
|
// setup texture offsets, for texture neighboors sampling
|
|
float s1=1.0f;
|
|
float t1=1.0f;
|
|
float s_off=s1*0.5f;
|
|
float t_off=t1*0.5f;
|
|
|
|
float pfOffset0[]={ s1*0.5f, t1, 0.0f, 0.0f};
|
|
float pfOffset1[]={ -s1, t1*0.5f, 0.0f, 0.0f};
|
|
float pfOffset2[]={-s1*0.5f, -t1, 0.0f, 0.0f};
|
|
float pfOffset3[]={ s1, -t1*0.5f, 0.0f, 0.0f};
|
|
|
|
// render quad
|
|
SetTexture(pRenderer, pSrc, 0, GL_LINEAR, GL_LINEAR, 1);
|
|
SetTexture(pRenderer, pSrc, 1, GL_LINEAR, GL_LINEAR, 1);
|
|
SetTexture(pRenderer, pSrc, 2, GL_LINEAR, GL_LINEAR, 1);
|
|
SetTexture(pRenderer, pSrc, 3, GL_LINEAR, GL_LINEAR, 1);
|
|
|
|
// set current vertex/fragment program
|
|
vpBlur->mfSet(true, NULL);
|
|
fpBlur->mfSet(true, NULL);
|
|
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
|
|
// set vertex program consts
|
|
vpBlur->mfParameter4f("Offset0", pfOffset0);
|
|
vpBlur->mfParameter4f("Offset1", pfOffset1);
|
|
vpBlur->mfParameter4f("Offset2", pfOffset2);
|
|
vpBlur->mfParameter4f("Offset3", pfOffset3);
|
|
|
|
// setup screen aligned quad
|
|
struct_VERTEX_FORMAT_P3F_TEX2F pScreenBlur[] =
|
|
{
|
|
Vec3(1, 1, 0), (float)pSrc->m_Width, 0,
|
|
Vec3(1, 0, 0), (float)pSrc->m_Width, (float)pSrc->m_Height,
|
|
Vec3(0, 1, 0), 0, 0,
|
|
Vec3(0, 0, 0), 0, (float)pSrc->m_Height,
|
|
};
|
|
|
|
// resample texture
|
|
// set texture coordinates scale (needed for rectangular textures in gl ..)
|
|
float pfScale[]={ 1, 1, 1.0f, 0};
|
|
vpBlur->mfParameter4f("vTexCoordScale", pfScale);
|
|
|
|
// render screen aligned quad...
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenBlur,VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
CopyScreenToTexture(pRenderer, pDst);
|
|
|
|
vpBlur->mfSet(false, 0);
|
|
fpBlur->mfSet(false, 0);
|
|
|
|
pRenderer->EF_SelectTMU(1);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(2);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(3);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(0);
|
|
|
|
LOG_EFFECT("*** End texture resampling process... ***\n")
|
|
return 1;
|
|
}
|
|
|
|
// flashbang helper (remove this, not necessary, use simple lerp)
|
|
inline float InterpolateCubic(float fCp1, float fCp2, float fCp3, float fCp4, float fTime)
|
|
{
|
|
float fTimeSquare = fTime*fTime;
|
|
return (((-fCp1 * 2.0f) + (fCp2 * 5.0f) - (fCp3 * 4) + fCp4) / 6.0f) * fTimeSquare * fTime +
|
|
(fCp1 + fCp3 - (2.0f * fCp2)) * fTimeSquare + (((-4.0f * fCp1) + fCp2 + (fCp3 * 4.0f) - fCp4) / 6.0f) * fTime + fCp2;
|
|
}
|
|
|
|
// =============================================================
|
|
// Render screen post-processing effects for low-spec machines..
|
|
// Tiago - Do not alter anything without consulting me
|
|
// Last Update: 04/12/2003
|
|
|
|
bool CREScreenProcess:: mfDrawLowSpec(SShader *ef, SShaderPass *sfm)
|
|
{
|
|
// MUST RESET TO DEFAULT
|
|
gRenDev->ResetToDefault();
|
|
|
|
// get data
|
|
ITimer *pTimer=iSystem->GetITimer();
|
|
CGLRenderer *pRenderer = gcpOGL;
|
|
int iTempX, iTempY, iWidth, iHeight;
|
|
gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight);
|
|
|
|
// setup shared renderstate
|
|
gRenDev->Set2DMode(true, 1, 1);
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
|
|
// add texel displacement adjustment
|
|
float fSoff=0.5f/(float)iWidth;
|
|
float fToff=0.5f/(float)iHeight;
|
|
|
|
// setup shared screen aligned quad
|
|
struct_VERTEX_FORMAT_P3F_TEX2F pScreenQuad[] =
|
|
{
|
|
Vec3(0, 0, 0), fSoff, fToff,
|
|
Vec3(0, 1, 0), fSoff, 1+fToff,
|
|
Vec3(1, 0, 0), 1+ fSoff, fToff,
|
|
Vec3(1, 1, 0), 1+ fSoff, 1+fToff,
|
|
};
|
|
|
|
// Cryvision
|
|
if(m_pVars->m_iNightVisionActive)
|
|
{
|
|
// some bug in set material color, lets pass color trough vertices instead ...
|
|
gRenDev->SetMaterialColor(0.4f, 0.5f, 0.6f, 1.0f);
|
|
|
|
static float fNoise=0;
|
|
fNoise+=(pTimer->GetFrameTime())*20.0f;
|
|
if(fNoise>2.0f)
|
|
{
|
|
fNoise=0.0f;
|
|
}
|
|
|
|
// setup shared screen aligned quad
|
|
struct_VERTEX_FORMAT_P3F_TEX2F pScrQuad[] =
|
|
{
|
|
Vec3(0, 0, 0), 0, fNoise,
|
|
Vec3(0, 1, 0), 0, 2+fNoise,
|
|
Vec3(1, 0, 0), 2, 0+fNoise,
|
|
Vec3(1, 1, 0), 2, 2+fNoise,
|
|
};
|
|
|
|
// bright color a bit ..
|
|
gRenDev->SetMaterialColor(0.0f, 0.2f, 0.3f, 1.0f);
|
|
STexPic *pWhiteTex = gRenDev->m_TexMan->m_Text_White;
|
|
SetTexture(pRenderer, pWhiteTex, 0, GL_LINEAR, GL_LINEAR, 0);
|
|
|
|
gRenDev->SetState(GS_BLSRC_ONE | GS_BLDST_ONE | GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScrQuad,VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
|
|
// set color..
|
|
STexPic *pScreenNoiseTex = gRenDev->m_TexMan->m_Text_ScreenNoise;
|
|
SetTexture(pRenderer, pScreenNoiseTex, 0, GL_LINEAR, GL_LINEAR, 0);
|
|
|
|
gRenDev->SetMaterialColor(0.4f, 0.6f, 0.8f, 1.0f);
|
|
gRenDev->SetState(GS_BLSRC_DSTCOL | GS_BLDST_SRCCOL | GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScrQuad,VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
|
|
gRenDev->Set2DMode(false, 1, 1);
|
|
gRenDev->ResetToDefault();
|
|
}
|
|
|
|
// ==============================================================================================
|
|
// FlashBang - grenade flashbang fx
|
|
if(m_pVars->m_bFlashBangActive)
|
|
{
|
|
LOG_EFFECT("*** Begin FlashBang... ***\n");
|
|
|
|
// render flashbang flash
|
|
STexPic *pFlashBangFlash = gRenDev->m_TexMan->m_Text_FlashBangFlash;
|
|
|
|
// get flashbang properties
|
|
float fPosX, fPosY, fSizeX, fSizeY;
|
|
fPosX=m_pVars->m_fFlashBangFlashPosX;
|
|
fPosY=m_pVars->m_fFlashBangFlashPosY;
|
|
fSizeX=m_pVars->m_fFlashBangFlashSizeX;
|
|
fSizeY=m_pVars->m_fFlashBangFlashSizeY;
|
|
|
|
float fBrightness=1.0f;
|
|
fBrightness=InterpolateCubic(0.0f, .0f, 1.0f, .5f, m_pVars->m_fFlashBangTimeOut);
|
|
|
|
// set render states
|
|
gRenDev->SetState(GS_BLSRC_ONE | GS_BLDST_ONE | GS_NODEPTHTEST);
|
|
gRenDev->SetMaterialColor(fBrightness, fBrightness, fBrightness, 1);
|
|
STexPic *pWhiteTex = gRenDev->m_TexMan->m_Text_White;
|
|
SetTexture(pRenderer, pWhiteTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenQuad,VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
// sincronize
|
|
float fTimeScale=1.0f;
|
|
if(m_pVars->m_fFlashBangTimeScale)
|
|
{
|
|
fTimeScale=1.0f/m_pVars->m_fFlashBangTimeScale;
|
|
}
|
|
|
|
m_pVars->m_fFlashBangTimeOut-=fTimeScale*pTimer->GetFrameTime();
|
|
|
|
// reset animation
|
|
if(m_pVars->m_fFlashBangTimeOut<=0.01f)
|
|
{
|
|
m_pVars->m_bFlashBangActive=0;
|
|
m_pVars->m_fFlashBangTimeOut=1.0f;
|
|
}
|
|
|
|
LOG_EFFECT("*** End FlashBang... ***\n");
|
|
}
|
|
|
|
// ===================================================
|
|
// Fade Fx - simple fade between screen and some color
|
|
|
|
if(m_pVars->m_bFadeActive)
|
|
{
|
|
gRenDev->ResetToDefault();
|
|
LOG_EFFECT("*** Begin screen fade process... ***\n")
|
|
|
|
float fStep, fSign=(m_pVars->m_fFadeTime<0.0f)? -1.0f: 1.0f;
|
|
|
|
// interpolate values
|
|
if(m_pVars->m_fFadeCurrPreTime>=m_pVars->m_fFadePreTime)
|
|
{
|
|
m_pVars->m_fFadeCurrTime-= pTimer->GetFrameTime();
|
|
// fade its only disabled in 'fade in' case, in fade out case, user should disable it
|
|
if(m_pVars->m_fFadeCurrTime<0.0f)
|
|
{
|
|
m_pVars->m_fFadeCurrTime=0.0f;
|
|
m_pVars->m_fFadePreTime=0.0f;
|
|
m_pVars->m_bFadeActive=0;
|
|
m_pVars->m_fFadeCurrPreTime=0.0f;
|
|
}
|
|
}
|
|
|
|
fStep=m_pVars->m_fFadeCurrTime/fabsf(m_pVars->m_fFadeTime);
|
|
|
|
if(fSign>0.0f)
|
|
{
|
|
fStep=1.0f-fStep;
|
|
}
|
|
|
|
// count 'pre-fade' frame number
|
|
m_pVars->m_fFadeCurrPreTime+=1.0f;
|
|
|
|
m_pVars->m_pFadeCurrColor.set(m_pVars->m_pFadeColor.r, m_pVars->m_pFadeColor.g, m_pVars->m_pFadeColor.b, fStep);
|
|
|
|
// copy fade amount
|
|
CRenderer::CV_r_fadeamount=1-fStep;
|
|
if(!m_pVars->m_bFadeActive)
|
|
{
|
|
CRenderer::CV_r_fadeamount=1.0f;
|
|
}
|
|
|
|
// set render states
|
|
gRenDev->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
|
|
|
|
// some bug in set material color, lets pass color trough vertices instead ...
|
|
gRenDev->SetMaterialColor(m_pVars->m_pFadeCurrColor.r, m_pVars->m_pFadeCurrColor.g, m_pVars->m_pFadeCurrColor.b, m_pVars->m_pFadeCurrColor.a);
|
|
|
|
STexPic *pWhiteTex = gRenDev->m_TexMan->m_Text_White;
|
|
SetTexture(pRenderer, pWhiteTex, 0, GL_LINEAR, GL_LINEAR, 1);
|
|
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenQuad,VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
LOG_EFFECT("*** End screen fade process... ***\n")
|
|
}
|
|
|
|
gRenDev->Set2DMode(false, 1, 1);
|
|
gRenDev->ResetToDefault();
|
|
|
|
return 1;
|
|
}
|
|
|
|
// =============================================================
|
|
// Returns closest power of 2 texture size
|
|
inline int GetClosestPow2Size(int size)
|
|
{
|
|
// clamp maximum texture size to 512
|
|
if(size>=512)
|
|
{
|
|
return 512;
|
|
}
|
|
if(size>=256)
|
|
{
|
|
return 256;
|
|
}
|
|
if(size>=128)
|
|
{
|
|
return 128;
|
|
}
|
|
if(size>=64)
|
|
{
|
|
return 64;
|
|
}
|
|
if(size>=32)
|
|
{
|
|
return 32;
|
|
}
|
|
if(size>=16)
|
|
{
|
|
return 16;
|
|
}
|
|
if(size>=8)
|
|
{
|
|
return 8;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
// =============================================================
|
|
// Render screen post-processing effects
|
|
// Tiago - Do not alter anything without consulting me
|
|
// Last Update: 17/09/2003
|
|
|
|
bool CREScreenProcess::mfDraw(SShader *ef, SShaderPass *sfm)
|
|
{
|
|
// make sure everything's ok..
|
|
if(!gRenDev || !ef || !sfm)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
FRAME_PROFILER( "ScreenRender:mfDraw",iSystem,PROFILE_GAME );
|
|
|
|
// get cryvision state
|
|
m_pVars->m_iNightVisionActive=CRenderer::CV_r_cryvision;
|
|
|
|
if(CRenderer::CV_r_disable_sfx==1)
|
|
{
|
|
CRenderer::CV_r_maxtexlod_bias=0.0f;
|
|
}
|
|
else
|
|
{
|
|
if(m_pVars->m_bCartoonActive)
|
|
{
|
|
CRenderer::CV_r_maxtexlod_bias=-1.5f;
|
|
}
|
|
else
|
|
{
|
|
CRenderer::CV_r_maxtexlod_bias=0.0f;
|
|
}
|
|
}
|
|
|
|
// get renderer
|
|
CGLRenderer *pRenderer = gcpOGL;
|
|
|
|
// no support for rectangular textures and pixel shaders, just process low-spec screen effects
|
|
if ((!SUPPORTS_GL_NV_texture_rectangle && !SUPPORTS_GL_EXT_texture_rectangle) || !(pRenderer->GetFeatures() & RFT_HW_TS) || CRenderer::CV_r_disable_sfx)
|
|
{
|
|
mfDrawLowSpec(ef, sfm);
|
|
return 0;
|
|
}
|
|
|
|
// make sure every state ok..
|
|
gRenDev->ResetToDefault();
|
|
|
|
// force no wireframe
|
|
pRenderer->SetPolygonMode(R_SOLID_MODE);
|
|
|
|
ITimer *pTimer=iSystem->GetITimer();
|
|
|
|
// get shared screen image
|
|
STexPic *pScreenTex=gRenDev->m_TexMan->m_Text_ScreenMap;
|
|
int iTempX, iTempY, iWidth, iHeight;
|
|
gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight);
|
|
|
|
// update screen texture..
|
|
LOG_EFFECT("*** Begin updating screen texture... ***\n")
|
|
gRenDev->SetViewport(0, 0, iWidth, iHeight);
|
|
|
|
// create necessary textures at once
|
|
CreateRenderTarget(pRenderer, pScreenTex, iWidth, iHeight, 1, 0);
|
|
CreateRenderTarget(pRenderer, gRenDev->m_TexMan->m_Text_PrevScreenMap, iWidth, iHeight, 0, 0);
|
|
CreateRenderTarget(pRenderer, gRenDev->m_TexMan->m_Text_ScreenLowMap, GetClosestPow2Size(iWidth/4), GetClosestPow2Size(iWidth/4), 0, 0);
|
|
CreateRenderTarget(pRenderer, gRenDev->m_TexMan->m_Text_Glare, GetClosestPow2Size(iWidth/8), GetClosestPow2Size(iWidth/8), 0, 0);
|
|
CreateRenderTarget(pRenderer, gRenDev->m_TexMan->m_Text_FlashBangMap, GetClosestPow2Size(iWidth/8), GetClosestPow2Size(iWidth/8), 0, 0);
|
|
CreateRenderTarget(pRenderer, gRenDev->m_TexMan->m_Text_ScreenAvg1x1, 2, 2, 0, 0);
|
|
CreateRenderTarget(pRenderer, gRenDev->m_TexMan->m_Text_ScreenLuminosityMap, 1, 1, 0, 0);
|
|
|
|
// add texel displacement adjustment
|
|
float fSoff=0.5f/(float)iWidth;
|
|
float fToff=0.5f/(float)iHeight;
|
|
|
|
// update screen texture..
|
|
CopyScreenToTexture(pRenderer, pScreenTex);
|
|
|
|
LOG_EFFECT("*** End updating screen texture... ***\n")
|
|
|
|
// setup shared screen aligned quad
|
|
struct_VERTEX_FORMAT_P3F_TEX2F pScreenQuad[] =
|
|
{
|
|
Vec3(1, 1, 0), 1, 0,
|
|
Vec3(1, 0, 0), 1, 1,
|
|
Vec3(0, 1, 0), 0, 0,
|
|
Vec3(0, 0, 0), 0, 1,
|
|
};
|
|
|
|
// setup shared screen sized aligned quad
|
|
struct_VERTEX_FORMAT_P3F_TEX2F pScreenSizeQuad[] =
|
|
{
|
|
Vec3(1, 1, 0), (float)pScreenTex->m_Width, 0,
|
|
Vec3(1, 0, 0), (float)pScreenTex->m_Width, (float)pScreenTex->m_Height,
|
|
Vec3(0, 1, 0), 0, 0,
|
|
Vec3(0, 0, 0), 0, (float)pScreenTex->m_Height,
|
|
};
|
|
|
|
// setup shared renderstate
|
|
//gRenDev->SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0);
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
gRenDev->Set2DMode(true, 1, 1);
|
|
|
|
// ==============================================================================================
|
|
// any effect requires screen low res image version ?
|
|
if((m_pVars->m_bBlurActive || m_pVars->m_bGlareActive) && !m_pVars->m_bCartoonActive) // && !m_pVars->m_iNightVisionActive)// || m_pVars->m_bNightVisionActive
|
|
{
|
|
STexPic *pScreenLow = gRenDev->m_TexMan->m_Text_ScreenLowMap,
|
|
*pScreenAvg = gRenDev->m_TexMan->m_Text_ScreenAvg1x1;
|
|
// update screen texture..
|
|
LOG_EFFECT("*** Begin updating screen mip maps textures... ***\n")
|
|
|
|
// resize textures using bilinear resampling
|
|
ResizeTextureHw(m_pVars, pRenderer, pScreenTex, pScreenLow);
|
|
|
|
// only glare requires all mip maps levels
|
|
if(m_pVars->m_bGlareActive && !m_pVars->m_bBlurActive && !m_pVars->m_iNightVisionActive)
|
|
{
|
|
ResizeTextureHw(m_pVars, pRenderer, pScreenLow, pScreenAvg);
|
|
}
|
|
LOG_EFFECT("*** End updating screen mip maps textures... ***\n")
|
|
}
|
|
|
|
// ==============================================================================================
|
|
// Glare/Nightvision - Glare fx and Nightvision w/ glare
|
|
// TODO: add multiple glare type filters
|
|
|
|
if((m_pVars->m_iNightVisionActive && m_pVars->m_bCartoonActive) || (m_pVars->m_bGlareActive && !m_pVars->m_bCartoonActive) || m_pVars->m_iNightVisionActive)
|
|
{
|
|
LOG_EFFECT("*** Begin glare... ***\n");
|
|
|
|
pRenderer->EF_SelectTMU(1);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(2);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(3);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(0);
|
|
|
|
// compute screen luminosity if necessary
|
|
if(!m_pVars->m_iNightVisionActive)
|
|
{
|
|
// get data
|
|
CREGlare *pRE = gRenDev->m_RP.m_pREGlare;
|
|
STexPic *pTex = gRenDev->m_TexMan->m_Text_Glare,
|
|
*pScreenLuminosityTex = gRenDev->m_TexMan->m_Text_ScreenLuminosityMap,
|
|
*pScreenLow = gRenDev->m_TexMan->m_Text_ScreenLowMap,
|
|
*pScreenAvg = gRenDev->m_TexMan->m_Text_ScreenAvg1x1;
|
|
|
|
// get vertex/fragment programs
|
|
CCGPShader_GL *fpGlareAmount=(CCGPShader_GL *) m_pVars->m_pRCGlareAmountMap;
|
|
CCGPShader_GL *fpGlareMap=(CCGPShader_GL *) m_pVars->m_pRCGlareMap;
|
|
CHECK_SHADER(fpGlareAmount, "GlareAmount vertex")
|
|
CHECK_SHADER(fpGlareMap, "GlareMap fragment")
|
|
|
|
CCGVProgram_GL *vpGlare=(CCGVProgram_GL *) m_pVars->m_pVPGlare;
|
|
CCGPShader_GL *fpGlare=(CCGPShader_GL *) m_pVars->m_pRCGlare;
|
|
CCGPShader_GL *fpRenderModeCold=(CCGPShader_GL *) m_pVars->m_pRCRenderModeCold;
|
|
CHECK_SHADER(vpGlare, "Glare vertex")
|
|
CHECK_SHADER(fpGlare, "Glare fragment")
|
|
CHECK_SHADER(fpRenderModeCold, "RenderModeCold fragment")
|
|
|
|
gRenDev->SetMaterialColor(1,1,1,1);
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
gRenDev->SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0);
|
|
|
|
// get average screen luminosity
|
|
gRenDev->SetViewport( 0, 0, iWidth, iHeight);
|
|
|
|
// clamp...
|
|
int iGlareQuality=CRenderer::CV_r_glarequality;
|
|
if(iGlareQuality>3)
|
|
{
|
|
iGlareQuality=3;
|
|
}
|
|
else
|
|
if(iGlareQuality<0)
|
|
{
|
|
iGlareQuality=0;
|
|
}
|
|
|
|
// ---------------------------------
|
|
// compute screen luminosity texture
|
|
// ---------------------------------
|
|
{
|
|
// set constants
|
|
float fLastGlareAmount=0;
|
|
static float fFrameCounter=0;
|
|
|
|
// slowdown transition ..
|
|
if(fFrameCounter>=CRenderer::CV_r_glaretransition/(pTimer->GetFrameTime()*125.0f+0.001f))
|
|
{
|
|
// get average screen luminosity
|
|
gRenDev->SetViewport( 0, 0, pScreenLuminosityTex->m_Width, pScreenLuminosityTex->m_Height);
|
|
|
|
// set pixel/vertex programs
|
|
vpGlare->mfSet(true, 0);
|
|
fpGlareAmount->mfSet(true, 0);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// set texture coordinates scale (needed for rectangular textures in gl ..)
|
|
float pfTexel01[4]= { (float)pScreenAvg->m_Width, (float)pScreenAvg->m_Height, -0.5f, -0.5f};
|
|
vpGlare->mfParameter4f("vTexCoordScale01", pfTexel01);
|
|
float pfTexel02[4]= { (float)pScreenAvg->m_Width, (float)pScreenAvg->m_Height, -0.5f, 0.5f};
|
|
vpGlare->mfParameter4f("vTexCoordScale02", pfTexel02);
|
|
float pfTexel03[4]= { (float)pScreenAvg->m_Width, (float)pScreenAvg->m_Height, 0.5f, -0.5f};
|
|
vpGlare->mfParameter4f("vTexCoordScale03", pfTexel03);
|
|
float pfTexel04[4]= { (float)pScreenAvg->m_Width, (float)pScreenAvg->m_Height, 0.5f, 0.5f};
|
|
vpGlare->mfParameter4f("vTexCoordScale04", pfTexel04);
|
|
|
|
fLastGlareAmount=0.0025f*pTimer->GetFrameTime()*1000.0f;
|
|
fFrameCounter=0;
|
|
// set screen texture/state
|
|
SetTexture(pRenderer, pScreenAvg, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pScreenAvg, 1, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pScreenAvg, 2, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pScreenAvg, 3, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
float pGlare[]= { 1, 1, 1, fLastGlareAmount};
|
|
fpGlareAmount->mfParameter4f("Glare", pGlare);
|
|
|
|
// use motion blur to lerp between brightness values
|
|
gRenDev->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenQuad, VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
// copy screen
|
|
CopyScreenToTexture(pRenderer, pScreenLuminosityTex);
|
|
|
|
// reset state
|
|
vpGlare->mfSet(false, 0);
|
|
fpGlareAmount->mfSet(false, 0);
|
|
}
|
|
else
|
|
{
|
|
// no need for processing, just keep old luminosity texture
|
|
}
|
|
|
|
fFrameCounter+=(float) 1.0f;
|
|
}
|
|
|
|
// cold render mode ? then must apply unsharp filter on screen texture
|
|
if(CRenderer::CV_r_rendermode==3)
|
|
{
|
|
// ---------------------------------------------------
|
|
// First must create blured texture for unsharp filter
|
|
// Notes: possible optimization, create an low-res
|
|
// screen always, for sharing with other effects
|
|
// ---------------------------------------------------
|
|
|
|
//BlurTextureHw(m_pVars, pRenderer, pScreenLow, 0, 2, 0, 0);
|
|
|
|
|
|
// --------------------------------------
|
|
// apply unsharp filter on screen texture
|
|
// --------------------------------------
|
|
|
|
// set current rendertarget
|
|
gRenDev->SetViewport( 0, 0, pScreenTex->m_Width, pScreenTex->m_Height);
|
|
|
|
// set pixel/vertex programs
|
|
vpGlare->mfSet(true, 0);
|
|
fpRenderModeCold->mfSet(true, 0);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
float pfScale01[]={ (float) pScreenTex->m_Width, (float) pScreenTex->m_Height, 0, 0};
|
|
vpGlare->mfParameter4f("vTexCoordScale01", pfScale01);
|
|
float pfBluredSize[4]={ (float) pScreenLow->m_Width, (float) pScreenLow->m_Height, 0, 0};
|
|
vpGlare->mfParameter4f("vTexCoordScale02", pfBluredSize);
|
|
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pScreenLow, 1, GL_LINEAR, GL_LINEAR, 1);
|
|
|
|
// render quad
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenQuad, VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
fpGlare->mfSet(false, 0);
|
|
fpRenderModeCold->mfSet(false, 0);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// copy framebuffer into texture
|
|
CopyScreenToTexture(pRenderer, pScreenTex);
|
|
}
|
|
|
|
// ------------------
|
|
// generate glare map
|
|
// ------------------
|
|
// if not reset to default, for some reason texture coordinates get wrong
|
|
gRenDev->ResetToDefault();
|
|
gRenDev->SetViewport( 0, 0, pTex->m_Width, pTex->m_Height);
|
|
|
|
// set fragment program
|
|
vpGlare->mfSet(true, 0);
|
|
fpGlareMap->mfSet(true, 0);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// set default image enhancing values
|
|
float pGlareMapConsts[]= { 0.2f, 0.2f, 0.2f, 1.0f };
|
|
float pSaturationConsts[]= { 0.0f, 0.0f, 0.0f, 0.2f };
|
|
float pContrastConsts[]= { 0.0f, 0.0f, 0.85f, 0.15f };
|
|
|
|
// is this really necessary... ?
|
|
if(CRenderer::CV_r_rendermode==1) // normal render mode
|
|
{
|
|
// adjust glare properties
|
|
if(CRenderer::CV_r_glare==2) // outdoor position ?
|
|
{
|
|
// threshold
|
|
pGlareMapConsts[0]= 0.2f;
|
|
pGlareMapConsts[1]= 0.2f;
|
|
pGlareMapConsts[2]= 0.2f;
|
|
// glare amount
|
|
pGlareMapConsts[3]= 0.5f;
|
|
}
|
|
else
|
|
if(CRenderer::CV_r_glare==3) // indoor position ?
|
|
{
|
|
// threshold
|
|
pGlareMapConsts[0]= 0.25f;
|
|
pGlareMapConsts[1]= 0.25f;
|
|
pGlareMapConsts[2]= 0.25f;
|
|
// glare amount
|
|
pGlareMapConsts[3]= 0.8f;
|
|
}
|
|
|
|
// set saturation amount
|
|
pSaturationConsts[3]=0.2f;
|
|
|
|
// set contrast amount
|
|
pContrastConsts[2]= 0.05f;
|
|
pContrastConsts[3]= 0.95f;
|
|
}
|
|
else
|
|
if(CRenderer::CV_r_rendermode==2) // paradisiacal render mode
|
|
{
|
|
// adjust glare properties
|
|
if(CRenderer::CV_r_glare==2) // outdoor position ?
|
|
{
|
|
// threshold
|
|
pGlareMapConsts[0]= 0.2f;
|
|
pGlareMapConsts[1]= 0.2f;
|
|
pGlareMapConsts[2]= 0.2f;
|
|
// glare amount
|
|
pGlareMapConsts[3]= 1.0f;
|
|
}
|
|
else
|
|
if(CRenderer::CV_r_glare==3) // indoor position ?
|
|
{
|
|
// threshold
|
|
pGlareMapConsts[0]= 0.1f;
|
|
pGlareMapConsts[1]= 0.1f;
|
|
pGlareMapConsts[2]= 0.1f;
|
|
// glare amount
|
|
pGlareMapConsts[3]= 0.8f;
|
|
}
|
|
|
|
// set saturation amount
|
|
pSaturationConsts[3]=0.1f;
|
|
|
|
// set contrast amount
|
|
pContrastConsts[2]= 0.05f;
|
|
pContrastConsts[3]= 0.95f;
|
|
}
|
|
else
|
|
if(CRenderer::CV_r_rendermode==3) // cold reality render mode
|
|
{
|
|
// adjust glare properties
|
|
if(CRenderer::CV_r_glare==2) // outdoor position ?
|
|
{
|
|
// threshold
|
|
pGlareMapConsts[0]= 0.2f;
|
|
pGlareMapConsts[1]= 0.2f;
|
|
pGlareMapConsts[2]= 0.2f;
|
|
// glare amount
|
|
pGlareMapConsts[3]= 0.5f;
|
|
}
|
|
else
|
|
if(CRenderer::CV_r_glare==3) // indoor position ?
|
|
{
|
|
// threshold
|
|
pGlareMapConsts[0]= 0.1f;
|
|
pGlareMapConsts[1]= 0.1f;
|
|
pGlareMapConsts[2]= 0.1f;
|
|
// glare amount
|
|
pGlareMapConsts[3]= 0.65f;
|
|
}
|
|
|
|
// set saturation amount
|
|
pSaturationConsts[3]=0.425f;
|
|
|
|
// set contrast amount
|
|
pContrastConsts[2]= 0.0f;
|
|
pContrastConsts[3]= 1.0f;
|
|
}
|
|
|
|
// glare vars
|
|
|
|
// make smooth transition
|
|
float fAdjustStep=pTimer->GetFrameTime();
|
|
m_pVars->m_pCurrGlareMapConst.r=CLAMP(m_pVars->m_pCurrGlareMapConst.r+(pGlareMapConsts[0]-m_pVars->m_pCurrGlareMapConst.r)*fAdjustStep, 0.0f, 1.0f);
|
|
m_pVars->m_pCurrGlareMapConst.g=CLAMP(m_pVars->m_pCurrGlareMapConst.g+(pGlareMapConsts[1]-m_pVars->m_pCurrGlareMapConst.g)*fAdjustStep, 0.0f, 1.0f);
|
|
m_pVars->m_pCurrGlareMapConst.b=CLAMP(m_pVars->m_pCurrGlareMapConst.b+(pGlareMapConsts[2]-m_pVars->m_pCurrGlareMapConst.b)*fAdjustStep, 0.0f, 1.0f);
|
|
m_pVars->m_pCurrGlareMapConst.a=CLAMP(m_pVars->m_pCurrGlareMapConst.a+(pGlareMapConsts[3]-m_pVars->m_pCurrGlareMapConst.a)*fAdjustStep, 0.0f, 1.0f);
|
|
m_pVars->m_pCurrSaturation.a=CLAMP(m_pVars->m_pCurrSaturation.a+(pSaturationConsts[3]-m_pVars->m_pCurrSaturation.a)*fAdjustStep, 0.0f, 1.0f);
|
|
m_pVars->m_pCurrContrast.b=CLAMP(m_pVars->m_pCurrContrast.b+(pContrastConsts[2]-m_pVars->m_pCurrContrast.b)*fAdjustStep, 0.0f, 1.0f);
|
|
m_pVars->m_pCurrContrast.a=CLAMP(m_pVars->m_pCurrContrast.a+(pContrastConsts[3]-m_pVars->m_pCurrContrast.a)*fAdjustStep, 0.0f, 1.0f);
|
|
|
|
// pass constants (note: i negated values from here, since cg generates wrong instructions)
|
|
float pNegCurrGlareMapConst[]={ -m_pVars->m_pCurrGlareMapConst.r, -m_pVars->m_pCurrGlareMapConst.g, -m_pVars->m_pCurrGlareMapConst.b, m_pVars->m_pCurrGlareMapConst.a};
|
|
fpGlareMap->mfParameter4f("vGlare", pNegCurrGlareMapConst);
|
|
|
|
float pfBluredSize[4]={ (float)pScreenLow->m_Width, (float) pScreenLow->m_Height, 0, 0};
|
|
vpGlare->mfParameter4f("vTexCoordScale01", pfBluredSize);
|
|
float pfLumSize[4]={ (float)pScreenLuminosityTex->m_Width, (float)pScreenLuminosityTex->m_Height, 0, 0};
|
|
vpGlare->mfParameter4f("vTexCoordScale02", pfLumSize);
|
|
|
|
// use first mip map
|
|
SetTexture(pRenderer, pScreenLow, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pScreenLuminosityTex, 1, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenQuad,VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
fpGlareMap->mfSet(false, 0);
|
|
vpGlare->mfSet(false, 0);
|
|
|
|
// get lowres screen texture
|
|
CopyScreenToTexture(pRenderer, pTex);
|
|
|
|
// blur texture
|
|
if(CRenderer::CV_r_rendermode!=3)
|
|
{
|
|
gRenDev->SetViewport( 0, 0, pScreenTex->m_Width, pScreenTex->m_Height);
|
|
BlurTextureHw(m_pVars, pRenderer, pTex, 0, iGlareQuality*4, 0, 0);
|
|
}
|
|
|
|
// if not reset to default, for some reason texture coordinates get wrong
|
|
gRenDev->ResetToDefault();
|
|
|
|
// add glare to screen
|
|
gRenDev->SetViewport(0, 0, pScreenTex->m_Width, pScreenTex->m_Height);
|
|
|
|
// ----------------------------------------
|
|
// apply glare in image and post-process it
|
|
// ----------------------------------------
|
|
{
|
|
// set pixel/vertex programs
|
|
vpGlare->mfSet(true, 0);
|
|
fpGlare->mfSet(true, 0);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// due to cg bug, need to pass 2 diferent constants..
|
|
float pCurrContrast01[]= { 0.0f, 0.0f, 0.0f, m_pVars->m_pCurrContrast.b };
|
|
float pCurrContrast02[]= { 0.0f, 0.0f, 0.0f, m_pVars->m_pCurrContrast.a };
|
|
// set pixel program constants
|
|
fpGlare->mfParameter4f("vSaturationAmount", pSaturationConsts);
|
|
fpGlare->mfParameter4f("vConstrastAmount", pCurrContrast01);
|
|
fpGlare->mfParameter4f("vConstrastAmount02", pCurrContrast02);
|
|
|
|
// set texture coordinates scale (needed for rectangular textures in gl ..)
|
|
float pfTexel01[4]={ (float)pScreenTex->m_Width, (float)pScreenTex->m_Height, 0, 0};
|
|
vpGlare->mfParameter4f("vTexCoordScale01", pfTexel01);
|
|
float pfTexel02[4]={ (float)pTex->m_Width, (float)pTex->m_Height, 0, 0};
|
|
vpGlare->mfParameter4f("vTexCoordScale02", pfTexel02);
|
|
float pfTexel03[4]= { 1, 1, 0, 0};
|
|
vpGlare->mfParameter4f("vTexCoordScale03", pfTexel03);
|
|
|
|
// set screen, glare map and glare adjustment texture
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pTex, 1, GL_LINEAR, GL_LINEAR, 1);
|
|
|
|
// render quad
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenQuad, VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
if(m_pVars->m_bFlashBangActive || m_pVars->m_bCartoonActive || m_pVars->m_bBlurActive)
|
|
CopyScreenToTexture(pRenderer, pScreenTex);
|
|
|
|
fpGlare->mfSet(false, 0);
|
|
vpGlare->mfSet(false, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// make sure, stuff is disabled (can be enabled by menu options or console vars)
|
|
if(m_pVars->m_pCVStencilShadows->GetIVal())
|
|
{
|
|
m_pVars->m_iPrevStencilShadows=m_pVars->m_pCVStencilShadows->GetIVal();
|
|
m_pVars->m_pCVStencilShadows->Set(0);
|
|
}
|
|
|
|
if(m_pVars->m_pCVShadowMaps->GetIVal())
|
|
{
|
|
m_pVars->m_iPrevShadowMaps=m_pVars->m_pCVShadowMaps->GetIVal();
|
|
m_pVars->m_pCVShadowMaps->Set(0);
|
|
}
|
|
|
|
if(m_pVars->m_pCVVolFog->GetIVal())
|
|
{
|
|
m_pVars->m_iPrevVolFog=m_pVars->m_pCVVolFog->GetIVal();
|
|
m_pVars->m_pCVVolFog->Set(0);
|
|
}
|
|
|
|
// ------------------
|
|
// process cry-vision
|
|
// ------------------
|
|
|
|
LOG_EFFECT("*** Begin Cryvision... ***\n");
|
|
// get data
|
|
STexPic *pTex = gRenDev->m_TexMan->m_Text_Glare,
|
|
*pScreenLow = gRenDev->m_TexMan->m_Text_ScreenLowMap,
|
|
*pHeatTexture = gRenDev->m_TexMan->m_Text_ScreenLowMap;
|
|
|
|
// get vertex/fragment programs
|
|
CCGPShader_GL *fpGlareMap=(CCGPShader_GL *) m_pVars->m_pRCGlareMap;
|
|
|
|
CCGVProgram_GL *vpGlare=(CCGVProgram_GL *) m_pVars->m_pVPGlare;
|
|
CCGPShader_GL *fpGlare=(CCGPShader_GL *) m_pVars->m_pRCGlare;
|
|
|
|
CCGVProgram_GL *vpNightGlare=(CCGVProgram_GL *) m_pVars->m_pVPNightVision;
|
|
CCGPShader_GL *fpNightGlare=(CCGPShader_GL *) m_pVars->m_pRCNightVision;
|
|
|
|
CCGPShader_GL *fpHeatSource=(CCGPShader_GL *) m_pVars->m_pRCHeatVision;
|
|
CCGPShader_GL *fpHeatSourceDecode=(CCGPShader_GL *) m_pVars->m_pRCHeatSourceDecode;
|
|
|
|
gRenDev->SetViewport(0, 0, iWidth, iHeight);
|
|
gRenDev->SetMaterialColor(1,1,1,1);
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
|
|
// ---------------------------------
|
|
// get heat mask from screen texture
|
|
// ---------------------------------
|
|
{
|
|
gRenDev->SetViewport(0, 0, pHeatTexture->m_Width, pHeatTexture->m_Height);
|
|
|
|
// set pixel/vertex programs
|
|
vpNightGlare->mfSet(true, 0);
|
|
fpHeatSource->mfSet(true, 0);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// set texture coordinates scale (needed for rectangular textures in gl ..)
|
|
float pfScale01[4]={ (float)pScreenTex->m_Width, (float)pScreenTex->m_Height, 1, 1};
|
|
vpNightGlare->mfParameter4f("vTexCoordScale01", pfScale01);
|
|
float pfScale02[4]={ (float)pScreenTex->m_Width, (float)pScreenTex->m_Height, 1, 1};
|
|
vpNightGlare->mfParameter4f("vTexCoordScale02", pfScale02);
|
|
float pfScalePal[4]= { 1, 1, 0, 0};
|
|
vpNightGlare->mfParameter4f("vTexCoordScale03", pfScalePal);
|
|
float pfParams[]= { 1, 1, 0, 0};
|
|
vpNightGlare->mfParameter4f("fNoiseParams", pfParams);
|
|
|
|
float fMotionBlurAmount=75.0f*pTimer->GetFrameTime();
|
|
if(fMotionBlurAmount>1) fMotionBlurAmount=1;
|
|
|
|
float pfHeatParams[]= { 1, 1, 1, fMotionBlurAmount};
|
|
fpHeatSource->mfParameter4f("vHeatConstants", pfHeatParams);
|
|
|
|
// setup texture stages/states
|
|
STexPic *pPaleteTex = gRenDev->m_TexMan->m_Text_HeatPalete;
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pScreenTex, 1, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pPaleteTex, 2, GL_NEAREST, GL_NEAREST, 1);
|
|
// render quad (note: use alpha blending to add motion blur on heat sources )
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenQuad, VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
// copy screen texture
|
|
CopyScreenToTexture(pRenderer, pHeatTexture);
|
|
|
|
vpNightGlare->mfSet(false, 0);
|
|
fpHeatSource->mfSet(false, 0);
|
|
|
|
// blur texture
|
|
BlurTextureHw(m_pVars, pRenderer, pHeatTexture, 0, 3, 0, 0);
|
|
}
|
|
|
|
// ------------------------------------
|
|
// delete heat mask from screen texture
|
|
// ---------------------------------
|
|
// if not reset to default, for some reason texture coordinates get wrong
|
|
gRenDev->ResetToDefault();
|
|
|
|
{
|
|
gRenDev->SetViewport(0, 0, iWidth, iHeight);
|
|
|
|
// setup texture stages/states
|
|
STexPic *pPaleteTex = gRenDev->m_TexMan->m_Text_HeatPalete;
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pScreenTex, 1, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pPaleteTex, 2, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
// set pixel/vertex programs
|
|
vpNightGlare->mfSet(true, 0);
|
|
fpHeatSourceDecode->mfSet(true, 0);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// set texture coordinates scale (needed for rectangular textures in gl ..)
|
|
float pfScale01[4]={ (float)pScreenTex->m_Width, (float)pScreenTex->m_Height, 1, 1};
|
|
vpNightGlare->mfParameter4f("vTexCoordScale01", pfScale01);
|
|
float pfScale02[4]={ (float)pScreenTex->m_Width, (float)pScreenTex->m_Height, 1, 1};
|
|
vpNightGlare->mfParameter4f("vTexCoordScale02", pfScale02);
|
|
float pfScalePal[4]= { 1, 1, 0, 0};
|
|
vpNightGlare->mfParameter4f("vTexCoordScale03", pfScalePal);
|
|
float pfParams[]= { 1, 1, 0, 0};
|
|
vpNightGlare->mfParameter4f("fNoiseParams", pfParams);
|
|
|
|
// render quad, use alpha blending to add motion blur on heat sources
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenQuad, VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
// copy screen texture
|
|
CopyScreenToTexture(pRenderer, pScreenTex);
|
|
|
|
vpNightGlare->mfSet(false, 0);
|
|
fpHeatSourceDecode->mfSet(false, 0);
|
|
}
|
|
|
|
// ------------------
|
|
// generate glare map
|
|
// ------------------
|
|
// if not reset to default, for some reason texture coordinates get wrong
|
|
gRenDev->ResetToDefault();
|
|
gRenDev->SetViewport( 0, 0, pTex->m_Width, pTex->m_Height);
|
|
|
|
// set fragment program
|
|
vpGlare->mfSet(true, 0);
|
|
fpGlareMap->mfSet(true, 0);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// set default image enhancing values
|
|
float pGlareMapConsts[]= { 0.2f, 0.2f, 0.2f, 1.0f };
|
|
float pSaturationConsts[]= { 0.0f, 0.0f, 0.0f, 0.2f };
|
|
float pContrastConsts[]= { 0.0f, 0.0f, 0.85f, 0.15f };
|
|
// make smooth transition
|
|
float fAdjustStep=pTimer->GetFrameTime();
|
|
m_pVars->m_pCurrGlareMapConst.r=CLAMP(m_pVars->m_pCurrGlareMapConst.r+(pGlareMapConsts[0]-m_pVars->m_pCurrGlareMapConst.r)*fAdjustStep, 0.0f, 1.0f);
|
|
m_pVars->m_pCurrGlareMapConst.g=CLAMP(m_pVars->m_pCurrGlareMapConst.g+(pGlareMapConsts[1]-m_pVars->m_pCurrGlareMapConst.g)*fAdjustStep, 0.0f, 1.0f);
|
|
m_pVars->m_pCurrGlareMapConst.b=CLAMP(m_pVars->m_pCurrGlareMapConst.b+(pGlareMapConsts[2]-m_pVars->m_pCurrGlareMapConst.b)*fAdjustStep, 0.0f, 1.0f);
|
|
m_pVars->m_pCurrGlareMapConst.a=CLAMP(m_pVars->m_pCurrGlareMapConst.a+(pGlareMapConsts[3]-m_pVars->m_pCurrGlareMapConst.a)*fAdjustStep, 0.0f, 1.0f);
|
|
|
|
// pass constants (note: i negated values from here, since cg generates wrong instructions)
|
|
float pNegCurrGlareMapConst[]={ -m_pVars->m_pCurrGlareMapConst.r, -m_pVars->m_pCurrGlareMapConst.g, -m_pVars->m_pCurrGlareMapConst.b, m_pVars->m_pCurrGlareMapConst.a};
|
|
fpGlareMap->mfParameter4f("vGlare", pNegCurrGlareMapConst);
|
|
|
|
float pfBluredSize[4]={ (float)pScreenTex->m_Width, (float)pScreenTex->m_Height, 0, 0};
|
|
vpGlare->mfParameter4f("vTexCoordScale01", pfBluredSize);
|
|
float pfLumSize[4]= { 1, 1, 0, 0 };
|
|
vpGlare->mfParameter4f("vTexCoordScale02", pfLumSize);
|
|
|
|
// use first mip map
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
STexPic *pWhiteTex = gRenDev->m_TexMan->m_Text_White;
|
|
SetTexture(pRenderer, pWhiteTex, 1, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenQuad,VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
// copy glare texture
|
|
CopyScreenToTexture(pRenderer, pTex);
|
|
|
|
fpGlareMap->mfSet(false, 0);
|
|
vpGlare->mfSet(false, 0);
|
|
|
|
gRenDev->SetViewport( 0, 0, pScreenTex->m_Width, pScreenTex->m_Height);
|
|
BlurTextureHw(m_pVars, pRenderer, pTex, 0, 3, 0, 0);
|
|
|
|
|
|
// if not reset to default, for some reason texture coordinates get wrong
|
|
gRenDev->ResetToDefault();
|
|
|
|
gRenDev->SetViewport(0, 0, pScreenTex->m_Width, pScreenTex->m_Height);
|
|
|
|
// -----------------
|
|
// nightvision+glare
|
|
|
|
// get noise texture
|
|
STexPic *pScreenNoiseTex = gRenDev->m_TexMan->m_Text_ScreenNoise;
|
|
|
|
// set pixel/vertex programs
|
|
vpNightGlare->mfSet(true, 0);
|
|
fpNightGlare->mfSet(true, 0);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// setup noise parameters
|
|
static float fOffsetU=0, fOffsetV=0;
|
|
fOffsetV+=(pTimer->GetFrameTime())*20.0f;
|
|
if(fOffsetV>2.0f)
|
|
{
|
|
fOffsetV=0.0f;
|
|
}
|
|
|
|
float pfNoiseParams[]= { 0.25f, 2.5f, fOffsetU, fOffsetV };
|
|
SCGBind *pNoiseParams = vpNightGlare->mfGetParameterBind("fNoiseParams");
|
|
vpNightGlare->mfParameter(pNoiseParams, pfNoiseParams, 1);
|
|
|
|
// set pixel program constants
|
|
float pGlareData[]= { m_pVars->m_fGlareThreshold, m_pVars->m_fGlareThreshold, m_pVars->m_fGlareThreshold, m_pVars->m_fGlareAmount};
|
|
fpNightGlare->mfParameter4f("Glare", pGlareData);
|
|
|
|
float pNightVisionColor[]= { m_pVars->m_pNightVisionColor.r, m_pVars->m_pNightVisionColor.g, m_pVars->m_pNightVisionColor.b, m_pVars->m_fGlareAmount};
|
|
fpNightGlare->mfParameter4f("NVColor", pNightVisionColor);
|
|
|
|
// set texture coordinates scale (needed for rectangular textures in gl ..)
|
|
float pfScale01[4]={ (float)pScreenTex->m_Width, (float)pScreenTex->m_Height, 0, 0};
|
|
vpNightGlare->mfParameter4f("vTexCoordScale01", pfScale01);
|
|
float pfScale02[4]={ (float)pTex->m_Width, (float)pTex->m_Height, 0, 0};
|
|
vpNightGlare->mfParameter4f("vTexCoordScale02", pfScale02);
|
|
float pfScale03[4]={ (float)pHeatTexture->m_Width, (float)pHeatTexture->m_Height, 0, 0};
|
|
vpNightGlare->mfParameter4f("vTexCoordScale03", pfScale03);
|
|
|
|
// set screen texture
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
// set glare texture
|
|
SetTexture(pRenderer, pTex, 1, GL_LINEAR, GL_LINEAR, 1);
|
|
// heat texture
|
|
SetTexture(pRenderer, pHeatTexture, 2, GL_NEAREST, GL_NEAREST, 1);
|
|
// set noise texture
|
|
SetTexture(pRenderer, pScreenNoiseTex, 3, GL_NEAREST, GL_NEAREST, 0);
|
|
|
|
// render quad
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenQuad, VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
if(m_pVars->m_bFlashBangActive || m_pVars->m_bCartoonActive || m_pVars->m_bBlurActive)
|
|
{
|
|
CopyScreenToTexture(pRenderer, pScreenTex);
|
|
}
|
|
|
|
vpNightGlare->mfSet(false, 0);
|
|
fpNightGlare->mfSet(false, 0);
|
|
|
|
LOG_EFFECT("*** End Cryvision ***\n")
|
|
}
|
|
}
|
|
|
|
// ==============================================================================================
|
|
// FlashBang - grenade flashbang fx
|
|
|
|
if(m_pVars->m_bFlashBangActive)
|
|
{
|
|
LOG_EFFECT("*** Begin FlashBang... ***\n");
|
|
|
|
// get flashbang texture
|
|
STexPic *pTex = gRenDev->m_TexMan->m_Text_FlashBangMap;
|
|
// get vertex/fragment program
|
|
CCGVProgram_GL *vpFlashBang=(CCGVProgram_GL *) m_pVars->m_pVPFlashBang;
|
|
CCGPShader_GL *fpFlashBang=(CCGPShader_GL *) m_pVars->m_pRCFlashBang;
|
|
|
|
pRenderer->EF_SelectTMU(1);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(2);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(3);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(0);
|
|
|
|
// generate flashbang texture if necessary
|
|
if(m_pVars->m_fFlashBangTimeOut==1.0f || m_pVars->m_iFlashBangForce)
|
|
{
|
|
m_pVars->m_iFlashBangForce=0;
|
|
|
|
// setup viewport
|
|
gRenDev->SetViewport( 0, 0, pTex->m_Width, pTex->m_Height );
|
|
|
|
// set screen texture
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
float fOffX=0.5f/(float)pTex->m_Width, fOffY=0.5f/(float)pTex->m_Height;
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenSizeQuad,VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
|
|
// render flashbang flash
|
|
STexPic *pFlashBangFlash = gRenDev->m_TexMan->m_Text_FlashBangFlash;
|
|
gRenDev->SetState(GS_BLSRC_ONE | GS_BLDST_ONE | GS_NODEPTHTEST);
|
|
|
|
// get flashbang properties
|
|
float fPosX, fPosY, fSizeX, fSizeY;
|
|
fPosX=m_pVars->m_fFlashBangFlashPosX;
|
|
fPosY=m_pVars->m_fFlashBangFlashPosY;
|
|
|
|
fSizeX=m_pVars->m_fFlashBangFlashSizeX;
|
|
fSizeY=m_pVars->m_fFlashBangFlashSizeY;
|
|
|
|
gRenDev->Draw2dImage((fPosX-fSizeX*0.5f), (fPosY-fSizeY*0.5f), fSizeX, fSizeY, pFlashBangFlash->GetTextureID());
|
|
//gRenDev->EnableBlend(false);
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
|
|
CopyScreenToTexture(pRenderer, pTex);
|
|
|
|
// blur texture
|
|
BlurTextureHw(m_pVars, pRenderer, pTex, 0, 2, 0, 0);
|
|
}
|
|
|
|
// render flashbang
|
|
gRenDev->SetViewport(0, 0, iWidth, iHeight);
|
|
|
|
// set vertex program
|
|
vpFlashBang->mfSet(true, 0);
|
|
// set fragment program
|
|
fpFlashBang->mfSet(true, 0);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// set texture coordinates scale (needed for rectangular textures in gl ..)
|
|
float pfScale01[4]={ (float)pScreenTex->m_Width, (float)pScreenTex->m_Height, (float)pTex->m_Width, (float)pTex->m_Height};
|
|
vpFlashBang->mfParameter4f("vTexCoordScale", pfScale01);
|
|
|
|
// set fragment vars
|
|
float fBrightness=1.0f;
|
|
fBrightness=InterpolateCubic(0.0f, .0f, 1.0f, .5f, m_pVars->m_fFlashBangTimeOut);
|
|
|
|
float pFlashBang[]= { 0, 0, 0, fBrightness};
|
|
fpFlashBang->mfParameter4f("FlashBang", pFlashBang);
|
|
|
|
// set texture states
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pTex, 1, GL_LINEAR, GL_LINEAR, 1);
|
|
|
|
// activate blending for motion blur
|
|
//gRenDev->EnableBlend();
|
|
//if(m_pVars->m_fFlashBangTimeOut==1.0f)
|
|
//{
|
|
// gRenDev->EnableBlend(0);
|
|
//}
|
|
//gRenDev->SetBlendMode();
|
|
|
|
// still some issues when using motion blur on this one..
|
|
//gRenDev->EnableBlend(0);
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
|
|
// just render..
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenQuad,VERTEX_FORMAT_P3F_TEX2F)), 4);
|
|
|
|
// check if motion blur is not active, else we must update screen texture/or get latest screen texture
|
|
if(m_pVars->m_bCartoonActive || m_pVars->m_bBlurActive)
|
|
{
|
|
CopyScreenToTexture(pRenderer, pScreenTex);
|
|
}
|
|
|
|
// restore stuff
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
vpFlashBang->mfSet(false, 0);
|
|
fpFlashBang->mfSet(false, 0);
|
|
|
|
// sincronize
|
|
float fTimeScale=1.0f;
|
|
|
|
if(m_pVars->m_fFlashBangTimeScale)
|
|
{
|
|
fTimeScale=1.0f/m_pVars->m_fFlashBangTimeScale;
|
|
}
|
|
|
|
float fFrameTime=pTimer->GetFrameTime();
|
|
if(fFrameTime<0.002f)
|
|
{
|
|
fFrameTime=0.002f;
|
|
}
|
|
else
|
|
if(fFrameTime>0.5f)
|
|
{
|
|
fFrameTime=0.5f;
|
|
}
|
|
|
|
m_pVars->m_fFlashBangTimeOut-=fTimeScale*fFrameTime;
|
|
|
|
// reset animation
|
|
if(m_pVars->m_fFlashBangTimeOut<=0.01f)
|
|
{
|
|
m_pVars->m_bFlashBangActive=0;
|
|
m_pVars->m_fFlashBangTimeOut=1.0f;
|
|
}
|
|
|
|
LOG_EFFECT("*** End FlashBang... ***\n");
|
|
}
|
|
|
|
// ==============================================================================================
|
|
// Blur - simple screen blur
|
|
|
|
if(m_pVars->m_bBlurActive)
|
|
{
|
|
LOG_EFFECT("*** Begin blury screen process... ***\n")
|
|
|
|
STexPic *pScreenBluredTex = gRenDev->m_TexMan->m_Text_ScreenLowMap;
|
|
|
|
// get vertex/fragment program
|
|
CCGVProgram_GL *vpBluryMap=(CCGVProgram_GL *) m_pVars->m_pVPBluryScreen;
|
|
CCGPShader_GL *fpBluryMap=(CCGPShader_GL *) m_pVars->m_pRCBluryScreen;
|
|
|
|
gRenDev->SetViewport(0, 0, pScreenBluredTex->m_Width, pScreenBluredTex->m_Height);
|
|
|
|
pRenderer->EF_SelectTMU(1);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(2);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(3);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(0);
|
|
|
|
// setup texture stages/states
|
|
gRenDev->SetMaterialColor(1,1,1, 1);
|
|
gRenDev->SetState(GS_NODEPTHTEST);
|
|
|
|
// setup texture stages/states
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenSizeQuad,VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
|
|
CopyScreenToTexture(pRenderer, pScreenBluredTex);
|
|
|
|
BlurTextureHw(m_pVars, pRenderer, pScreenBluredTex, 0, 4, 0, 0);
|
|
|
|
gRenDev->SetViewport(0, 0, iWidth, iHeight);
|
|
|
|
// set current vertex/fragment program
|
|
vpBluryMap->mfSet(true, NULL);
|
|
fpBluryMap->mfSet(true, NULL);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// set constants
|
|
float pBluryParams[]= { m_pVars->m_pBlurColor.r, m_pVars->m_pBlurColor.g, m_pVars->m_pBlurColor.b, m_pVars->m_fBlurAmount };
|
|
fpBluryMap->mfParameter4f("fBluryParams", pBluryParams);
|
|
|
|
// set texture coordinates scale (needed for rectangular textures in gl ..)
|
|
float pfScale01[4]={ (float)pScreenBluredTex->m_Width, (float)pScreenBluredTex->m_Height, (float)pScreenTex->m_Width, (float)pScreenTex->m_Height};
|
|
vpBluryMap->mfParameter4f("vTexCoordScale", pfScale01);
|
|
|
|
// setup texture stages/states
|
|
SetTexture(pRenderer, pScreenBluredTex, 0, GL_LINEAR, GL_LINEAR, 1);
|
|
SetTexture(pRenderer, pScreenTex, 1, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenQuad,VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
|
|
// check if motion blur is not active, else we must update screen texture/or get latest screen texture
|
|
if(m_pVars->m_bCartoonActive)
|
|
{
|
|
CopyScreenToTexture(pRenderer, pScreenTex);
|
|
}
|
|
|
|
// restore states
|
|
vpBluryMap->mfSet(false, NULL);
|
|
fpBluryMap->mfSet(false, NULL);
|
|
|
|
// set flags
|
|
LOG_EFFECT("*** End blury screen process... ***\n")
|
|
}
|
|
|
|
// ==================================================================
|
|
// Cartoon Fx - cartoon rendering mode
|
|
|
|
if(m_pVars->m_bCartoonActive)
|
|
{
|
|
LOG_EFFECT("*** Begin cartoon mode process... ***\n")
|
|
|
|
// get vertex/fragment program
|
|
CCGVProgram_GL *vpCartoon=(CCGVProgram_GL *) m_pVars->m_pVPCartoon;
|
|
CCGPShader_GL *fpCartoon=(CCGPShader_GL *) m_pVars->m_pRCCartoon;
|
|
CCGPShader_GL *fpCartoonSilhouete=(CCGPShader_GL *) m_pVars->m_pRCCartoonSilhouette;
|
|
|
|
gRenDev->SetViewport(0, 0, iWidth, iHeight);
|
|
|
|
// set current vertex/fragment program
|
|
vpCartoon->mfSet(true, NULL);
|
|
fpCartoon->mfSet(true, NULL);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// set vertex program consts
|
|
// setup texture offsets, for texture neighboors sampling
|
|
float s1=0;
|
|
float t1=0;
|
|
|
|
float pfNoOffset[]={ s1, t1, 0, 0 };
|
|
// set texture coordinates scale (needed for rectangular textures in gl ..)
|
|
float pfScale01[]={ (float)iWidth, (float)iHeight, (float)iWidth, (float)iHeight};
|
|
vpCartoon->mfParameter4f("vTexCoordScale", pfScale01);
|
|
vpCartoon->mfParameter4f("Offset0", pfNoOffset);
|
|
vpCartoon->mfParameter4f("Offset1", pfNoOffset);
|
|
vpCartoon->mfParameter4f("Offset2", pfNoOffset);
|
|
vpCartoon->mfParameter4f("Offset3", pfNoOffset);
|
|
|
|
// render quad
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
// just render
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenQuad, VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
|
|
vpCartoon->mfSet(false, NULL);
|
|
fpCartoon->mfSet(false, NULL);
|
|
|
|
CopyScreenToTexture(pRenderer, pScreenTex);
|
|
|
|
// set current vertex/fragment program
|
|
vpCartoon->mfSet(true, NULL);
|
|
fpCartoonSilhouete->mfSet(true, NULL);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
s1=1.0f;
|
|
t1=1.0f;
|
|
|
|
float pfOffset0[]={ s1*0.5f, t1, 0.0f, 0.0f};
|
|
float pfOffset1[]={ -s1, t1*0.5f, 0.0f, 0.0f};
|
|
float pfOffset2[]={-s1*0.5f, -t1, 0.0f, 0.0f};
|
|
float pfOffset3[]={ s1, -t1*0.5f, 0.0f, 0.0f};
|
|
|
|
// set vertex program consts
|
|
vpCartoon->mfParameter4f("vTexCoordScale", pfScale01);
|
|
vpCartoon->mfParameter4f("Offset0",pfOffset0);
|
|
vpCartoon->mfParameter4f("Offset1",pfOffset1);
|
|
vpCartoon->mfParameter4f("Offset2",pfOffset2);
|
|
vpCartoon->mfParameter4f("Offset3",pfOffset3);
|
|
|
|
// render quad
|
|
SetTexture(pRenderer, pScreenTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pScreenTex, 1, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pScreenTex, 2, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pScreenTex, 3, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
// just render
|
|
gRenDev->SetState(GS_BLSRC_ZERO | GS_BLDST_SRCCOL | GS_NODEPTHTEST);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenQuad, VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
|
|
vpCartoon->mfSet(false, NULL);
|
|
fpCartoonSilhouete->mfSet(false, NULL);
|
|
|
|
LOG_EFFECT("*** End cartoon mode process... ***\n")
|
|
}
|
|
|
|
// ==============================================================================================
|
|
// Motion Blur - simple motion blur, also radial blur
|
|
// ideas:
|
|
// .adding some translation/rotation into radial blur, would look interesting
|
|
// .lerping between radial blur and normal screen
|
|
|
|
if(m_pVars->m_bMotionBlurActive)
|
|
{
|
|
LOG_EFFECT("*** Begin motion blur... ***\n")
|
|
|
|
// get vertex/fragment program
|
|
CCGVProgram_GL *vpMotion=(CCGVProgram_GL *) m_pVars->m_pVPMotion;
|
|
CCGPShader_GL *fpMotion=(CCGPShader_GL *) m_pVars->m_pRCMotion;
|
|
|
|
pRenderer->EF_SelectTMU(1);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(2);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(3);
|
|
pRenderer->EnableTMU(false);
|
|
pRenderer->EF_SelectTMU(0);
|
|
|
|
// create texture if necessary
|
|
STexPic *pTex = gRenDev->m_TexMan->m_Text_PrevScreenMap;
|
|
gRenDev->SetViewport(iTempX, iTempY, iWidth, iHeight);
|
|
|
|
// setup renderstate
|
|
gRenDev->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
|
|
|
|
switch(m_pVars->m_iMotionBlurType)
|
|
{
|
|
// simple motion blur
|
|
case 1:
|
|
{
|
|
float fAmount=CLAMP(m_pVars->m_fMotionBlurAmount*(75.0f*pTimer->GetFrameTime()), 0.0f, 1.0f);
|
|
|
|
// setup texture stages/states
|
|
gRenDev->SetMaterialColor(1,1,1, 1-fAmount);
|
|
gRenDev->SetColorOp(eCO_MODULATE, eCO_MODULATE, eCA_Texture | (eCA_Constant<<3), eCA_Texture | (eCA_Constant<<3));
|
|
SetTexture(pRenderer, pTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenSizeQuad,VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
}
|
|
break;
|
|
|
|
// radial blur
|
|
case 2:
|
|
float fAmount=CLAMP(m_pVars->m_fMotionBlurAmount, 0.0f, 1.0f);
|
|
|
|
// set current vertex/fragment program
|
|
vpMotion->mfSet(true, NULL);
|
|
fpMotion->mfSet(true, NULL);
|
|
pRenderer->EF_CommitPS();
|
|
pRenderer->EF_CommitVS();
|
|
|
|
// setup texture stages/states
|
|
SetTexture(pRenderer, pTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pTex, 1, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pTex, 2, GL_NEAREST, GL_NEAREST, 1);
|
|
SetTexture(pRenderer, pTex, 3, GL_NEAREST, GL_NEAREST, 1);
|
|
|
|
// setup vertex program
|
|
float pfTexSize[]= {(float) pScreenTex->m_Width, (float) pScreenTex->m_Height, 0, 0 };
|
|
SCGBind *pTexSize = vpMotion->mfGetParameterBind("TexSize");
|
|
vpMotion->mfParameter(pTexSize, pfTexSize, 1);
|
|
|
|
SCGBind *pTexScale = vpMotion->mfGetParameterBind("TexScale");
|
|
|
|
// setup fragment program
|
|
|
|
// set constants
|
|
float pMotionParams[]= { 1, 1, 1, 1-fAmount };
|
|
fpMotion->mfParameter4f("fMotionParams", pMotionParams);
|
|
|
|
float fScaleInc= ((float) m_pVars->m_iMotionBlurDisplace)/(float)iWidth;
|
|
float pfTexScale[4];
|
|
|
|
// set texture scale
|
|
pfTexScale[0]=1.0f;//0.99f - (fScaleInc+=fScaleInc);
|
|
pfTexScale[1]=0.99f - (fScaleInc+=fScaleInc*2.0f);
|
|
pfTexScale[2]=0.99f - (fScaleInc+=fScaleInc*0.5f);
|
|
pfTexScale[3]=0.99f - (fScaleInc+=fScaleInc*0.25f);
|
|
vpMotion->mfParameter(pTexScale, pfTexScale, 1);
|
|
|
|
// just render
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenQuad, VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
|
|
// disable current vertex/fragment program
|
|
vpMotion->mfSet(false, NULL);
|
|
fpMotion->mfSet(false, NULL);
|
|
break;
|
|
}
|
|
|
|
// copy into 'previous framebuffer' texture
|
|
CopyScreenToTexture(pRenderer, pTex);
|
|
|
|
LOG_EFFECT("*** End motion blur process... ***\n")
|
|
}
|
|
|
|
// ===================================================
|
|
// Fade Fx - simple fade between screen and some color
|
|
|
|
if(m_pVars->m_bFadeActive)
|
|
{
|
|
LOG_EFFECT("*** Begin screen fade process... ***\n")
|
|
|
|
// sincronize
|
|
float fStep, fSign=(m_pVars->m_fFadeTime<0.0f)? -1.0f: 1.0f;
|
|
|
|
// interpolate values
|
|
if(m_pVars->m_fFadeCurrPreTime>=m_pVars->m_fFadePreTime)
|
|
{
|
|
m_pVars->m_fFadeCurrTime-= pTimer->GetFrameTime();
|
|
// fade its only disabled in 'fade in' case, in fade out case, user should disable it
|
|
if(m_pVars->m_fFadeCurrTime<0.0f)
|
|
{
|
|
m_pVars->m_fFadeCurrTime=0.0f;
|
|
m_pVars->m_fFadePreTime=0.0f;
|
|
m_pVars->m_bFadeActive=0;
|
|
m_pVars->m_fFadeCurrPreTime=0.0f;
|
|
}
|
|
}
|
|
|
|
fStep=m_pVars->m_fFadeCurrTime/fabsf(m_pVars->m_fFadeTime);
|
|
|
|
if(fSign>0.0f)
|
|
{
|
|
fStep=1.0f-fStep;
|
|
}
|
|
|
|
// count 'pre-fade' frame number
|
|
m_pVars->m_fFadeCurrPreTime+=1.0f;
|
|
m_pVars->m_pFadeCurrColor.set(m_pVars->m_pFadeColor.r, m_pVars->m_pFadeColor.g, m_pVars->m_pFadeColor.b, fStep);
|
|
|
|
// copy fade amount
|
|
ICVar *pHudFadeAmount=iConsole->GetCVar("hud_fadeamount");
|
|
if(pHudFadeAmount)
|
|
{
|
|
pHudFadeAmount->Set(1-fStep);
|
|
}
|
|
|
|
// set render states
|
|
gRenDev->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
|
|
gRenDev->SetMaterialColor(m_pVars->m_pFadeCurrColor.r, m_pVars->m_pFadeCurrColor.g, m_pVars->m_pFadeCurrColor.b, m_pVars->m_pFadeCurrColor.a);
|
|
STexPic *pWhiteTex = gRenDev->m_TexMan->m_Text_White;
|
|
SetTexture(pRenderer, pWhiteTex, 0, GL_NEAREST, GL_NEAREST, 1);
|
|
gRenDev->DrawTriStrip(&(CVertexBuffer(pScreenQuad,VERTEX_FORMAT_P3F_TEX2F)),4);
|
|
|
|
LOG_EFFECT("*** End screen fade process... ***\n")
|
|
}
|
|
|
|
gRenDev->Set2DMode(false, 1, 1);
|
|
gRenDev->SetViewport(iTempX, iTempY, iWidth, iHeight);
|
|
gRenDev->ResetToDefault();
|
|
|
|
return 1;
|
|
}
|