Files
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

1744 lines
50 KiB
C++

//
// Title : Sprite2d.cpp
// Author :
// Started :
//
// 2008/06/24 - Andrzej: - v3.0: cleanup & refactoring, gBlitMatrix has been retired,
// current grcViewport modified for 2D ortho projection,
// CustomVertexPushBuffer support added;
// 2010/03/22 - Andrzej: - all sprite rendering methods use normalised ((0,0)->(1,1)) screen coords mapping;
//
//
//
//
//
//
#include "renderer/sprite2d.h"
// Rage headers
#include "grcore/allocscope.h"
#include "grcore/device.h"
#include "grcore/texture.h"
#include "grcore/im.h"
#include "grcore/quads.h"
#include "paging/dictionary.h"
#include "grcore/effect.h"
#include "grcore/fvf.h"
#include "grcore/vertexbuffer.h"
#include "grcore/vertexbuffereditor.h"
#include "grcore/indexbuffer.h"
#include "grcore/device.h"
#if RSG_ORBIS
#include "grcore/texture_gnm.h"
#include "grcore/rendertarget_gnm.h"
#endif
#include "grmodel/modelfactory.h"
#include "system/system.h"
#include "system/xtl.h"
// Framework headers
#include "fwmaths/Rect.h" // fwRect()...
#include "fwtl/customvertexpushbuffer.h"
#include "fwscene/stores/txdstore.h"
// Game headers
#include "camera/CamInterface.h"
#include "camera/viewports/Viewport.h"
#include "camera/viewports/ViewportManager.h"
#include "Frontend/ui_channel.h"
#include "Renderer/rendertargets.h"
#include "Renderer/Deferred/GBuffer.h"
#include "shaders/ShaderLib.h"
#include "streaming/streaming.h"
RENDER_OPTIMISATIONS()
//
//
//
//
grmShader *CSprite2d::m_imShader = NULL;
#if DEVICE_MSAA
grmShader *CSprite2d::m_imShaderMS = NULL;
#endif
static grcEffectTechnique m_blitTechniqueGta = grcetNONE;
static grcEffectTechnique m_blitTechniqueGtaDO = grcetNONE;
#if GS_INSTANCED_CUBEMAP
static grcEffectTechnique m_blitTechniqueCoronaCubeInst = grcetNONE;
#endif
static grcEffectTechnique m_blitTechniqueCorona = grcetNONE;
static grcEffectTechnique m_blitTechniqueColorCorrected = grcetNONE;
static grcEffectTechnique m_blitTechniqueColorCorrectedGradient = grcetNONE;
static grcEffectTechnique m_blitTechniqueSeeThrough = grcetNONE;
static grcEffectTechnique m_blitTechniqueRefMipBlur = grcetNONE;
static grcEffectTechnique m_blitTechniqueRefMipBlurBlend = grcetNONE;
static grcEffectTechnique m_blitTechniqueRefSkyPortal = grcetNONE;
static grcEffectTechnique m_blitTechniqueDistantLights = grcetNONE;
PPU_ONLY(static grcEffectTechnique m_resolveTechniqueMSAA2x = grcetNONE);
PPU_ONLY(static grcEffectTechnique m_resolveTechniqueMSAA4x = grcetNONE);
PPU_ONLY(static grcEffectTechnique m_resolveTechnique = grcetNONE);
static grcEffectTechnique m_resolveDepthTechnique = grcetNONE;
static grcEffectTechnique m_copyGBufferTechnique = grcetNONE;
static grcEffectTechnique m_blitTechniqueGameGlows = grcetNONE;
static grcEffectTechnique m_toneMapTechnique = grcetNONE;
static grcEffectTechnique m_luminanceToAlphaTechnique = grcetNONE;
static grcEffectTechnique m_gBufferSplatTechnique = grcetNONE;
static grcEffectTechnique m_UIWorldIconTechnique = grcetNONE;
static grcEffectTechnique m_blitTechniqueMipMap = grcetNONE;
#if __BANK
static grcEffectTechnique m_blitTechniqueSignedNormalize = grcetNONE;
#endif
#if USE_HQ_ANTIALIASING
static grcEffectTechnique m_highQualityAATechnique = grcetNONE;
#endif // USE_HQ_ANTIALIASING
#if __PPU
static grcEffectTechnique m_zCullReloadTechnique = grcetNONE;
#endif
static grcEffectTechnique m_alphaMaskToStencilMaskTechnique = grcetNONE;
#if __XENON
static grcEffectTechnique m_restoreHiZTechnique = grcetNONE;
static grcEffectTechnique m_restoreDepthTechnique = grcetNONE;
#endif
static grcEffectVar m_shdDiffuseTextureID = grcevNONE;
static grcEffectVar m_shdRefMipBlurParamsID = grcevNONE;
static grcEffectVar m_shdLightningConstants = grcevNONE;
#if USE_HQ_ANTIALIASING
static grcEffectVar m_shdTransparentSrcMapParamsID = grcevNONE;
#endif // USE_HQ_ANTIALIASING
static grcEffectVar m_shdCoronasDepthMapID = grcevNONE;
static grcEffectVar m_shdDepthPointMapID = grcevNONE;
static grcEffectVar m_shdRenderPointMapID = grcevNONE;
static grcEffectVar m_shdRenderPointMapINTID = grcevNONE;
static grcEffectVar m_shdRenderPointMapINTParamID = grcevNONE;
static grcEffectVar m_shdRenderCubeMapID = grcevNONE;
static grcEffectVar m_shdRenderTexArrayID = grcevNONE;
static grcEffectVar m_shdRefMipBlurMapID = grcevNONE;
#if DEVICE_MSAA
static grcEffectVar m_shdRenderTexMsaaID = grcevNONE;
static grcEffectVar m_shdRenderTexMsaaParamID = grcevNONE;
static grcEffectVar m_shdRenderTexMsaaINTID = grcevNONE;
static grcEffectVar m_shdRenderTexMsaaDepth = grcevNONE;
#endif
#if DEVICE_EQAA
static grcEffectVar m_shdRenderTexFmaskID = grcevNONE;
#endif
static grcEffectVar m_shdGeneralParams0ID = grcevNONE;
static grcEffectVar m_shdGeneralParams1ID = grcevNONE;
#if __XENON
static grcEffectVar m_shdDepthTextureID = grcevNONE;
#endif
static grcEffectVar m_shdTexelSizeID = grcevNONE;
static grcEffectVar m_shdNoiseTextureID = grcevNONE;
static grcEffectVar m_shdTonemapColorFilterParams0ID = grcevNONE;
static grcEffectVar m_shdTonemapColorFilterParams1ID = grcevNONE;
#if __PPU
static grcEffectVar m_shdRenderQuincunxMapID = grcevNONE;
static grcEffectVar m_shdRenderQuincunxAltMapID = grcevNONE;
static grcEffectVar m_shdRenderGaussMapID = grcevNONE;
#if 0 == PSN_USE_FP16
static grcEffectTechnique m_shdRenderIMLitPackedID = grcetNONE;
static grcEffectTechnique m_shdRenderIMLitUnpackedID = grcetNONE;
#endif // 0 == PSN_USE_FP16
#endif // __PPU
#if DEVICE_MSAA
static grcEffectTechnique m_resolveDepthMSTechnique = grcetNONE;
#endif //DEVICE_MSAA
bool CUIWorldIconQuad::sm_initializedCommon = false;
grcBlendStateHandle CUIWorldIconQuad::sm_StandardSpriteBlendStateHandle = grcStateBlock::BS_Invalid;
float CUIWorldIconQuad::sm_screenRatio = 1.0f;
static grcEffectTechnique m_blitTechniqueSprite3d = grcetNONE;
#if USE_MULTIHEAD_FADE
#include "fwsys/timer.h"
namespace fade
{
static grcEffectTechnique m_technique = grcetNONE;
static grcEffectVar m_shdAreaParams = grcevNONE;
static grcEffectVar m_shdTimeParams = grcevNONE;
static grcEffectVar m_shdWaveParams = grcevNONE;
static Vector4 m_areaParams (0.0f, 0.0f, 1.0f, 1.0f);
static Vector4 m_timeParams (0.0f, 1.0f, 0.0f, 0.0f);
static Vector4 m_waveParams (1.0f, 1.0f, 0.0f, 0.0f);
}
u32 CSprite2d::GetFadeCurrentTime()
{
return fwTimer::GetSystemTimeInMilliseconds();
}
// name: CSprite2d::SetMultiFadeParams
// description: Initialize mult-head fade parameters
// returns: End time in milliseconds
u32 CSprite2d::SetMultiFadeParams(const fwRect &safeArea, bool bIn, u32 uDurationSec,
float fAcceleration, float fWaveSize, float fAlphaOffset, bool bInstantShudders, u32 uExtraTime)
{
int iBlinderDelay = bIn ? 0 : uExtraTime;
const u32 uTimeMs = GetFadeCurrentTime() + iBlinderDelay;
const u32 uDurationMs = bInstantShudders ? 0 : 1000*uDurationSec + static_cast<int>( 1000.f*fWaveSize+0.5f );
float cx=0.f,cy=0.f;
safeArea.GetCentre(cx,cy);
fade::m_areaParams = Vector4( cx, 1.f-cy, 0.5f*safeArea.GetWidth(), 0.5f*safeArea.GetHeight() );
fade::m_timeParams = Vector4( 0.001f * uTimeMs, uDurationSec && !bInstantShudders ? 1.f/uDurationSec : 0.f, 0.5f*fAcceleration, bIn ? 1.f:0.f );
fade::m_waveParams = Vector4( 1.f / fWaveSize, fAlphaOffset, 0.f, 0.f );
return uTimeMs + uDurationMs;
}
void CSprite2d::ResetMultiFadeArea()
{
fwRect area(0.f, 0.f, 1.f, 1.f);
if (GRCDEVICE.GetMonitorConfig().isMultihead())
{
area = GRCDEVICE.GetMonitorConfig().getLandscapeMonitor().getArea();
}
else
{
const float SIXTEEN_BY_NINE = 16.0f/9.0f;
float fAspect = CHudTools::GetAspectRatio();
if(fAspect > SIXTEEN_BY_NINE)
{
float fDifference = (SIXTEEN_BY_NINE / fAspect) * 0.5f;
area = fwRect(0.5f - fDifference, 0, 0.5f + fDifference, 1.0f);
}
}
float cx=0.f,cy=0.f;
area.GetCentre(cx,cy);
fade::m_areaParams = Vector4( cx, 1.f-cy, 0.5f*area.GetWidth(), 0.5f*area.GetHeight() );
}
// name: CSprite2d::DrawMultiFade
// description: Draw a full-screen multi-head fade
// used for movie-cutscene transitions in multi-head configurations
void CSprite2d::DrawMultiFade(bool bUseTime)
{
Vector4 timePar;
if(bUseTime)
{
const float curTime = 0.001f * GetFadeCurrentTime();
timePar.x = (curTime - fade::m_timeParams.x) * fade::m_timeParams.y;
timePar.y = 0.f;
timePar.z = fade::m_timeParams.z;
timePar.w = fade::m_timeParams.w;
}
else
{
timePar.x = 1.0f;
timePar.y = 0.f;
timePar.z = fade::m_timeParams.z;
timePar.w = fade::m_timeParams.w;
}
AssertVerify(m_imShader->BeginDraw(grmShader::RMC_DRAW, FALSE, fade::m_technique));
m_imShader->SetVar(fade::m_shdAreaParams, fade::m_areaParams);
m_imShader->SetVar(fade::m_shdTimeParams, timePar);
m_imShader->SetVar(fade::m_shdWaveParams, fade::m_waveParams);
m_imShader->Bind(0);
#if 0 //INPUT_UNIT_QUAD
GRCDEVICE.DrawUnitQuad(true);
#else
grcDrawSingleQuadf( 0.f,0.f, 1.f,1.f, 0.f, 0.f,0.f,1.f,1.f, Color32() );
#endif
m_imShader->UnBind();
m_imShader->EndDraw();
}
#endif //USE_MULTIHEAD_FADE
//
// name: Delete
// description: Delete texture
void CSprite2d::Delete()
{
if (m_pTexture != NULL )
{
m_pTexture->Release();
m_pTexture = NULL;
}
}
//
// Name : SetTexture
// Purpose : Loads a texture
// Parameters : None
// Returns : Nothing
//
void CSprite2d::SetTexture(const char *pTextureName)
{
// check we aren't trying to change the texture while on the render thread
Assert(!m_pTexture || !CSystem::IsThisThreadId(SYS_THREAD_RENDER));
Delete();
if(pTextureName)
{
m_pTexture = fwTxd::GetCurrent()->Lookup(pTextureName);
if(m_pTexture == NULL)
{
//m_pTexture = grcTextureFactory::GetInstance().Create(pTextureName);
}
else
{
m_pTexture->AddRef();
}
}
}
//
//
//
//
void CSprite2d::SetTexture(grcTexture *pTexture)
{
Delete();
m_pTexture = pTexture;
if(m_pTexture)
{
m_pTexture->AddRef();
}
}
//
// name: CSprite2d::SetRenderState
// description: set render state to draw this sprite
void CSprite2d::SetRenderState()
{
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER)); // this command is forbidden outwith the render thread
CSprite2d::SetRenderState(m_pTexture);
}
//
// name: CSprite2d::SetRenderState
// description: set render state to draw a sprite with these params
void CSprite2d::SetRenderState(const grcTexture* pTex)
{
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER)); // this command is forbidden outwith the render thread
m_imShader->SetVar(m_shdDiffuseTextureID, pTex);
grcBindTexture(pTex);
if(grcViewport::GetCurrent())
{
grcWorldIdentity();
}
}
void CSprite2d::ClearRenderState()
{
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER));
m_imShader->SetVar(m_shdDiffuseTextureID, grcTexture::None);
grcBindTexture(grcTexture::None);
}
void CSprite2d::SetRefMipBlurParams(const Vector4& params, const grcTexture *pTex)
{
m_imShader->SetVar(m_shdRefMipBlurParamsID, params);
m_imShader->SetVar(m_shdRenderCubeMapID, pTex);
}
void CSprite2d::SetRefMipBlurMap(grcTexture *tex)
{
m_imShader->SetVar(m_shdRefMipBlurMapID, tex);
}
void CSprite2d::SetColorFilterParams(const Vector4 &colorFilter0, const Vector4 &colorFilter1)
{
m_imShader->SetVar(m_shdTonemapColorFilterParams0ID, colorFilter0);
m_imShader->SetVar(m_shdTonemapColorFilterParams1ID, colorFilter1);
}
void CSprite2d::SetLightningConstants(const Vector2& params)
{
m_imShader->SetVar(m_shdLightningConstants, params);
}
void CSprite2d::SetTexelSize(const Vector2 &size)
{
const Vector4 texSize(size.x,size.y,0.0f,0.0f);
m_imShader->SetVar(m_shdTexelSizeID,texSize);
}
void CSprite2d::SetTexelSize(const Vector4 &size)
{
m_imShader->SetVar(m_shdTexelSizeID,size);
}
void CSprite2d::SetGeneralParams(const Vector4 &params0, const Vector4 &params1)
{
m_imShader->SetVar(m_shdGeneralParams0ID, params0);
m_imShader->SetVar(m_shdGeneralParams1ID, params1);
}
void CSprite2d::SetDepthTexture(grcTexture *tex)
{
m_imShader->SetVar(m_shdCoronasDepthMapID,tex);
m_imShader->SetVar(m_shdDepthPointMapID,tex);
}
void CSprite2d::SetNoiseTexture(grcTexture *tex)
{
m_imShader->SetVar(m_shdNoiseTextureID, tex);
}
GRC_ALLOC_SCOPE_DECLARE_GLOBAL(static, s_CustomListAllocScope)
void CSprite2d::BeginCustomList(CustomShaderType type, const grcTexture *pTex, const int pass /*= -1*/)
{
GRC_ALLOC_SCOPE_PUSH(s_CustomListAllocScope)
// set the default render state and texture variable
m_imShader->SetVar(m_shdDiffuseTextureID, pTex);
float TexSizeX = 1.0f;
float TexSizeY = 1.0f;
float InvTexSizeX = 1.0f;
float InvTexSizeY = 1.0f;
if(pTex)
{
TexSizeX = (float)pTex->GetWidth();
TexSizeY = (float)pTex->GetHeight();
InvTexSizeX = 1.0f / TexSizeX;
InvTexSizeY = 1.0f / TexSizeY;
}
#if PGHANDLE_REF_COUNT
m_type = type;
#endif
// Select technique and set any extra texture / renderstate required
grcEffectTechnique t_shaderTechnique=grcetNONE;
int t_shaderPass=0;
switch(type)
{
case CS_CORONA_DEFAULT:
Assert(pass == 0 || pass == 1 || pass == 2);
t_shaderTechnique=m_blitTechniqueCorona;
t_shaderPass=pass; // default=0
break;
case CS_CORONA_SIMPLE_REFLECTION:
t_shaderTechnique=m_blitTechniqueCorona;
t_shaderPass=3;
break;
case CS_CORONA_PARABOLOID_REFLECTION:
t_shaderTechnique=m_blitTechniqueCorona;
t_shaderPass=4;
break;
#if GS_INSTANCED_CUBEMAP
case CS_CORONA_CUBEINST_REFLECTION:
t_shaderTechnique=m_blitTechniqueCoronaCubeInst;
t_shaderPass=0;
break;
#endif
case CS_CORONA_LIGHTNING:
t_shaderTechnique=m_blitTechniqueCorona;
t_shaderPass=5;
break;
case CS_COLORCORRECTED:
t_shaderTechnique=m_blitTechniqueColorCorrected;
t_shaderPass=0;
break;
case CS_COLORCORRECTED_GRADIENT:
t_shaderTechnique=m_blitTechniqueColorCorrectedGradient;
t_shaderPass=0;
break;
case CS_SEETHROUGH:
t_shaderTechnique=m_blitTechniqueSeeThrough;
t_shaderPass=0;
break;
case CS_MIPMAP_BLUR_0:
t_shaderTechnique=m_blitTechniqueRefMipBlur;
t_shaderPass=pass;
m_imShader->SetVar(m_shdRenderPointMapID, pTex);
break;
case CS_MIPMAP_BLUR_BLEND:
t_shaderTechnique=m_blitTechniqueRefMipBlurBlend;
t_shaderPass=0;
break;
//#if SCAN_SKY_PORTALS_FOR_REFLECTION
case CS_REFLECTION_SKY_PORTALS:
t_shaderTechnique=m_blitTechniqueRefSkyPortal;
t_shaderPass=0;
break;
//#endif // SCAN_SKY_PORTALS_FOR_REFLECTION
#if __PPU
case CS_RESOLVE_MSAA2X:
m_imShader->SetVar(m_shdRenderQuincunxMapID,pTex);
m_imShader->SetVar(m_shdRenderQuincunxAltMapID,pTex);
t_shaderTechnique = m_resolveTechniqueMSAA2x;
t_shaderPass = 0;
break;
case CS_RESOLVE_MSAA4X:
m_imShader->SetVar(m_shdRenderGaussMapID,pTex);
t_shaderTechnique = m_resolveTechniqueMSAA4x;
t_shaderPass = 0;
break;
case CS_RESOLVE_SDDOWNSAMPLEFILTER:
t_shaderTechnique = m_resolveTechnique;
t_shaderPass = 0;
break;
case CS_RESOLVE_DEPTHTOVS:
m_imShader->SetVar(m_shdRenderPointMapID,pTex);
t_shaderTechnique = m_resolveTechnique;
t_shaderPass = 1;
break;
case CS_RESOLVE_ALPHASTENCIL:
t_shaderTechnique = m_resolveTechnique;
t_shaderPass = 2;
break;
#if 0 == PSN_USE_FP16
case CS_IM_LIT_PACKED:
t_shaderTechnique = m_shdRenderIMLitPackedID;
t_shaderPass = 0;
break;
case CS_IM_UNLIT_PACKED:
t_shaderTechnique = m_shdRenderIMLitUnpackedID;
t_shaderPass = 0;
break;
#endif // 0 == PSN_USE_FP16
case CS_SCULL_RELOAD:
t_shaderTechnique = m_zCullReloadTechnique;
t_shaderPass = 0;
break;
case CS_ZCULL_RELOAD:
t_shaderTechnique = m_zCullReloadTechnique;
t_shaderPass = 1;
break;
case CS_ZCULL_RELOAD_GT:
t_shaderTechnique = m_zCullReloadTechnique;
t_shaderPass = 2;
break;
case CS_ZCULL_NEAR_RELOAD:
t_shaderTechnique = m_zCullReloadTechnique;
t_shaderPass = 3;
break;
#endif // __PPU
case CS_ALPHA_MASK_TO_STENCIL_MASK:
m_imShader->SetVar(m_shdRenderPointMapID,pTex);
t_shaderTechnique = m_alphaMaskToStencilMaskTechnique;
t_shaderPass = 0;
break;
#if __XENON
case CS_ALPHA_MASK_TO_STENCIL_MASK_STENCIL_AS_COLOR:
m_imShader->SetVar(m_shdRenderPointMapID,pTex);
t_shaderTechnique = m_alphaMaskToStencilMaskTechnique;
t_shaderPass = 1;
break;
case CS_RESTORE_HIZ:
t_shaderTechnique = m_restoreHiZTechnique;
t_shaderPass = 0;
break;
case CS_RSTORE_GBUFFER_DEPTH:
t_shaderTechnique = m_restoreDepthTechnique;
t_shaderPass = pass;
m_imShader->SetVar(m_shdDepthTextureID, pTex);
break;
#endif
case CS_COPY_GBUFFER:
t_shaderTechnique = m_copyGBufferTechnique;
t_shaderPass = 0;
break;
case CS_RESOLVE_DEPTH:
t_shaderTechnique = m_resolveDepthTechnique;
t_shaderPass = 0;
break;
case CS_BLIT:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 1;
break;
case CS_BLIT_NOFILTERING:
m_imShader->SetVar(m_shdRenderPointMapID,pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 2;
break;
case CS_BLIT_DEPTH:
m_imShader->SetVar(m_shdRenderPointMapID,pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 3;
break;
case CS_BLIT_STENCIL:
m_imShader->SetVar(m_shdRenderPointMapINTParamID, Vec4V(TexSizeX, TexSizeY, InvTexSizeX, InvTexSizeY));
m_imShader->SetVar(m_shdRenderPointMapINTID,pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 4;
break;
case CS_BLIT_SHOW_ALPHA:
m_imShader->SetVar(m_shdRenderPointMapID, pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 5;
break;
case CS_BLIT_GAMMA:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 6;
break;
case CS_BLIT_POW:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 7;
break;
case CS_BLIT_CALIBRATION:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 8;
break;
case CS_BLIT_CUBE_MAP:
m_imShader->SetVar(m_shdRenderCubeMapID,pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 9;
break;
case CS_BLIT_PARABOLOID:
m_imShader->SetVar(m_shdRenderCubeMapID,pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 10;
break;
case CS_BLIT_AA:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 11;
break;
case CS_BLIT_AAAlpha:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 12;
break;
case CS_BLIT_COLOUR:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 13;
break;
case CS_BLIT_TO_ALPHA:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 14;
break;
case CS_BLIT_TO_ALPHA_BLUR:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 15;
break;
case CS_BLIT_DEPTH_TO_ALPHA:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 16;
break;
case CS_FOWCOUNT:
m_imShader->SetVar(m_shdRenderPointMapID, pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 17;
break;
case CS_FOWAVERAGE:
m_imShader->SetVar(m_shdRenderPointMapID, pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 18;
break;
case CS_FOWFILL:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 19;
break;
#if RSG_ORBIS || __D3D11
case CS_BLIT_TEX_ARRAY:
m_imShader->SetVar(m_shdRenderTexArrayID,pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 20;
break;
#endif // RSG_ORBIS || __D3D11
#if DEVICE_MSAA
case CS_BLIT_MSAA_DEPTH:
m_imShader->SetVar(m_shdRenderTexMsaaParamID, Vec4V(TexSizeX, TexSizeY, InvTexSizeX, InvTexSizeY));
m_imShader->SetVar(m_shdRenderTexMsaaID,pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 21;
break;
case CS_BLIT_MSAA_STENCIL:
m_imShader->SetVar(m_shdRenderTexMsaaINTID,pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 22;
break;
case CS_BLIT_MSAA:
m_imShader->SetVar(m_shdRenderTexMsaaParamID, Vec4V(TexSizeX, TexSizeY, InvTexSizeX, InvTexSizeY));
m_imShader->SetVar(m_shdRenderTexMsaaID,pTex);
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 23;
break;
case CS_BLIT_FMASK:
m_imShader->SetVar(m_shdRenderTexMsaaParamID, Vec4V(TexSizeX, TexSizeY, InvTexSizeX, InvTexSizeY));
m_imShader->SetVar(m_shdRenderTexMsaaID, pTex);
# if DEVICE_EQAA
m_imShader->SetVar(m_shdRenderTexFmaskID, static_cast<const grcRenderTargetMSAA*>(pTex)->GetResolveFragmentMask());
# endif // DEVICE_EQAA
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 24;
break;
#endif // DEVICE_MSAA
case CS_BLIT_XZ_SWIZZLE:
t_shaderTechnique = m_blitTechniqueGta;
t_shaderPass = 21 + 4*DEVICE_MSAA;
break;
case CS_MIPMAP:
t_shaderTechnique = m_blitTechniqueMipMap;
t_shaderPass = pass;
break;
case CS_DISTANT_LIGHTS:
t_shaderTechnique = m_blitTechniqueDistantLights;
t_shaderPass = pass == -1 ? 0 : pass;
break;
case CS_GAMEGLOWS:
t_shaderTechnique = m_blitTechniqueGameGlows;
#if RSG_PC
if( GRCDEVICE.GetMSAA()>1 )
{
m_imShader->SetVar(m_shdRenderTexMsaaParamID, Vec4V(TexSizeX, TexSizeY, InvTexSizeX, InvTexSizeY));
m_imShader->SetVar(m_shdRenderTexMsaaID, pTex);
t_shaderPass = 1;
}
else
#endif // RSG_ PC
{
t_shaderPass = 0;
}
break;
case CS_FSGAMEGLOWS:
t_shaderTechnique = m_blitTechniqueGameGlows;
#if RSG_PC
if( GRCDEVICE.GetMSAA()>1 )
{
m_imShader->SetVar(m_shdRenderTexMsaaParamID, Vec4V(TexSizeX, TexSizeY, InvTexSizeX, InvTexSizeY));
m_imShader->SetVar(m_shdRenderTexMsaaID, pTex);
t_shaderPass = 3;
}
else
{
t_shaderPass = 2;
}
#else
t_shaderPass = 1;
#endif
break;
case CS_FSGAMEGLOWSMARKER:
t_shaderTechnique = m_blitTechniqueGameGlows;
#if RSG_PC
// We're using the resolved post alpha depth buffer, so no need for the MSAA version.
//if( GRCDEVICE.GetMSAA()>1 )
//{
// m_imShader->SetVar(m_shdRenderTexMsaaParamID, Vec4V(TexSizeX, TexSizeY, InvTexSizeX, InvTexSizeY));
// m_imShader->SetVar(m_shdRenderTexMsaaID, pTex);
// t_shaderPass = 5;
//}
//else
{
t_shaderPass = 4;
}
#else
t_shaderPass = 2;
#endif
break;
case CS_COPYDEPTH:
t_shaderTechnique = m_resolveDepthTechnique;
t_shaderPass = 0;
break;
case CS_TONEMAP:
m_imShader->SetVar(m_shdRenderPointMapID, pTex);
t_shaderTechnique = m_toneMapTechnique;
t_shaderPass = pass == -1 ? 0 : pass;
t_shaderPass = 0;
break;
case CS_LUMINANCE_TO_ALPHA:
m_imShader->SetVar(m_shdRenderPointMapID, pTex);
t_shaderTechnique = m_luminanceToAlphaTechnique;
t_shaderPass = 0;
break;
case CS_GBUFFER_SPLAT:
t_shaderTechnique = m_gBufferSplatTechnique;
t_shaderPass = 0;
break;
#if USE_HQ_ANTIALIASING
case CS_HIGHQUALITY_AA:
m_imShader->SetVar(m_shdTransparentSrcMapParamsID, pTex);
t_shaderTechnique = m_highQualityAATechnique;
t_shaderPass = 0;
break;
#endif
#if __BANK
case CS_SIGNED_AS_UNSIGNED:
t_shaderTechnique = m_blitTechniqueSignedNormalize;
t_shaderPass = 0;
break;
#endif
case CS_COUNT:
default:
Assertf(false,"CSprite2d::BeginCustomList: Using unkown shader type");
break;
}
AssertVerify(m_imShader->BeginDraw(grmShader::RMC_DRAW, FALSE, t_shaderTechnique));
m_imShader->Bind(t_shaderPass);
}
void CSprite2d::EndCustomList()
{
m_imShader->UnBind();
m_imShader->EndDraw();
m_imShader->SetVar(m_shdDiffuseTextureID, grcTexture::None);
m_imShader->SetVar(m_shdGeneralParams0ID, Vector4(1.0, 1.0, 1.0, 0.0));
m_imShader->SetVar(m_shdGeneralParams1ID, Vector4(0.0, 0.0, 0.0, 0.0));
# if PGHANDLE_REF_COUNT
switch(m_type)
{
case CS_MIPMAP_BLUR_0:
# if __PPU
case CS_RESOLVE_DEPTHTOVS:
# endif
case CS_ALPHA_MASK_TO_STENCIL_MASK:
XENON_ONLY(case CS_ALPHA_MASK_TO_STENCIL_MASK_STENCIL_AS_COLOR: )
case CS_BLIT_NOFILTERING:
case CS_BLIT_DEPTH:
case CS_BLIT_SHOW_ALPHA:
case CS_TONEMAP:
m_imShader->SetVar(m_shdRenderPointMapID, grcTexture::None);
break;
case CS_BLIT_STENCIL:
m_imShader->SetVar(m_shdRenderPointMapINTID, grcTexture::None);
break;
# if __PPU
case CS_RESOLVE_MSAA2X:
m_imShader->SetVar(m_shdRenderQuincunxMapID, grcTexture::None);
m_imShader->SetVar(m_shdRenderQuincunxAltMapID, grcTexture::None);
break;
case CS_RESOLVE_MSAA4X:
m_imShader->SetVar(m_shdRenderGaussMapID, grcTexture::None);
break;
# endif
# if __XENON
case CS_RSTORE_GBUFFER_DEPTH:
case CS_COPY_GBUFFER_DEPTH:
m_imShader->SetVar(m_shdDepthTextureID, grcTexture::None);
break;
# endif
case CS_BLIT_CUBE_MAP:
m_imShader->SetVar(m_shdRenderCubeMapID, grcTexture::None);
break;
default:;
}
# endif
GRC_ALLOC_SCOPE_POP(s_CustomListAllocScope)
}
#if DEVICE_MSAA
void CSprite2d::BeginCustomListMS(CustomShaderType type, const grcTexture *pTex, const int /*pass*/ /*= -1*/)
{
GRC_ALLOC_SCOPE_PUSH(s_CustomListAllocScope)
// set the default render state and texture variable
m_imShaderMS->SetVar(m_shdDiffuseTextureID, pTex);
#if PGHANDLE_REF_COUNT
m_type = type;
#endif
// Select technique and set any extra texture / renderstate required
grcEffectTechnique t_shaderTechnique=grcetNONE;
int t_shaderPass=0;
switch(type)
{
case CS_RESOLVE_DEPTH_MS_SAMPLE0:
t_shaderTechnique = m_resolveDepthMSTechnique;
t_shaderPass = 0;
m_imShaderMS->SetVar(m_shdRenderTexMsaaDepth,pTex);
break;
case CS_RESOLVE_DEPTH_MS_MIN:
t_shaderTechnique = m_resolveDepthMSTechnique;
t_shaderPass = 1;
m_imShaderMS->SetVar(m_shdRenderTexMsaaDepth,pTex);
break;
case CS_RESOLVE_DEPTH_MS_MAX:
t_shaderTechnique = m_resolveDepthMSTechnique;
t_shaderPass = 2;
m_imShaderMS->SetVar(m_shdRenderTexMsaaDepth,pTex);
break;
case CS_RESOLVE_DEPTH_DOMINANT:
t_shaderTechnique = m_resolveDepthMSTechnique;
t_shaderPass = 3;
m_imShaderMS->SetVar(m_shdRenderTexMsaaDepth,pTex);
break;
case CS_COUNT:
default:
Assertf(false,"CSprite2d::BeginCustomList: Using unkown shader type");
break;
}
AssertVerify(m_imShaderMS->BeginDraw(grmShader::RMC_DRAW, FALSE, t_shaderTechnique));
m_imShaderMS->Bind(t_shaderPass);
}
void CSprite2d::EndCustomListMS()
{
m_imShaderMS->UnBind();
m_imShaderMS->EndDraw();
GRC_ALLOC_SCOPE_POP(s_CustomListAllocScope)
}
#endif //DEVISE_MSAA
// ================================================================================================
// ================================================================================================
// ================================================================================================
// TODO -- move this stuff out of sprite2d.cpp
fwRect PixelsToNormalised(const fwRect& rect)
{
const float oow = 1.0f/GRCDEVICE.GetWidth();
const float ooh = 1.0f/GRCDEVICE.GetHeight();
fwRect r;
// the reason i'm not using the fwRect ctor here is because the order of the arguments is *not* LEFT-TOP-RIGHT-BOTTOM
r.left = +(2.0f*oow*rect.left - 1.0f);
r.top = -(2.0f*ooh*rect.top - 1.0f);
r.right = +(2.0f*oow*rect.right - 1.0f);
r.bottom = -(2.0f*ooh*rect.bottom - 1.0f);
return r;
}
fwRect TexelsToNormalised(const fwRect& rect, const grcTexture* texture)
{
const float oow = 1.0f/texture->GetWidth();
const float ooh = 1.0f/texture->GetHeight();
fwRect r;
// the reason i'm not using the fwRect ctor here is because the order of the arguments is *not* LEFT-TOP-RIGHT-BOTTOM
r.left = oow*rect.left;
r.top = ooh*rect.top;
r.right = oow*rect.right;
r.bottom = ooh*rect.bottom;
return r;
}
// ================================================================================================
// ================================================================================================
// ================================================================================================
//
//
// new BlitRectf uses (0,0)->(1,1) vp mapping
//
void CSprite2d::DrawUIWorldIcon(const Vector3 &pt1, const Vector3 &pt2, const Vector3 &pt3, const Vector3 &pt4,
float UNUSED_PARAM(zVal),
const Vector2 &uv1, const Vector2 &uv2, const Vector2 &uv3, const Vector2 &uv4,
const Color32 &color)
{
grcWorldIdentity();
grcStateBlock::SetRasterizerState(grcStateBlock::RS_NoBackfaceCull);
grcStateBlock::SetDepthStencilState(CShaderLib::DSS_TestOnly_Invert);
AssertVerify(m_imShader->BeginDraw(grmShader::RMC_DRAW, FALSE, m_UIWorldIconTechnique));
m_imShader->Bind(0);
{
grcBegin(drawTriStrip,4);
grcVertex(pt1.x, pt1.y, pt1.z, 0, 0, -1, color, uv1.x, uv1.y);
grcVertex(pt2.x, pt2.y, pt2.z, 0, 0, -1, color, uv2.x, uv2.y);
grcVertex(pt3.x, pt3.y, pt3.z, 0, 0, -1, color, uv3.x, uv3.y);
grcVertex(pt4.x, pt4.y, pt4.z, 0, 0, -1, color, uv4.x, uv4.y);
grcEnd();
}
m_imShader->UnBind();
m_imShader->EndDraw();
}
//
//
// new BlitRectf uses (0,0)->(1,1) vp mapping
//
void CSprite2d::DrawRect(const Vector2 &pt1, const Vector2 &pt2, const Vector2 &pt3, const Vector2 &pt4,
float zVal,
const Vector2 &uv1, const Vector2 &uv2, const Vector2 &uv3, const Vector2 &uv4,
const Color32 &color)
{
GRC_ALLOC_SCOPE_AUTO_PUSH_POP()
PreDrawShape();
{
grcBegin(drawTriStrip,4);
grcVertex(pt1.x, pt1.y, zVal, 0, 0, -1, color, uv1.x, uv1.y);
grcVertex(pt2.x, pt2.y, zVal, 0, 0, -1, color, uv2.x, uv2.y);
grcVertex(pt3.x, pt3.y, zVal, 0, 0, -1, color, uv3.x, uv3.y);
grcVertex(pt4.x, pt4.y, zVal, 0, 0, -1, color, uv4.x, uv4.y);
grcEnd();
}
PostDrawShape();
}
//
//
// description: Draw a 2d rectangle with solid colour.
// Rectf() uses (0,0)->(1,1) vp mapping
//
void CSprite2d::DrawRect(float x1, float y1, float x2, float y2, float zVal, const Color32& color)
{
GRC_ALLOC_SCOPE_AUTO_PUSH_POP()
grcStateBlock::SetRasterizerState(grcStateBlock::RS_NoBackfaceCull);
fwRect rect01(0,1,1,0);
SetBlitMatrix(NULL, &rect01, false);
// diffuse-only technique:
AssertVerify(m_imShader->BeginDraw(grmShader::RMC_DRAW, FALSE, m_blitTechniqueGtaDO));
m_imShader->Bind(0);
{
grcBegin(drawTriStrip,4);
grcVertex(x1, y1, zVal, 0.0f, 0.0f, -1.0f, color, 0, 0);
grcVertex(x1, y2, zVal, 0.0f, 0.0f, -1.0f, color, 0, 0);
grcVertex(x2, y1, zVal, 0.0f, 0.0f, -1.0f, color, 0, 0);
grcVertex(x2, y2, zVal, 0.0f, 0.0f, -1.0f, color, 0, 0);
grcEnd();
}
PostDrawShape();
}
void CSprite2d::PreDrawShape()
{
fwRect rect01(0,1,1,0);
SetBlitMatrix(NULL, &rect01, false);
AssertVerify(m_imShader->BeginDraw(grmShader::RMC_DRAW, FALSE, m_blitTechniqueGta));
m_imShader->Bind(0);
}
void CSprite2d::PostDrawShape()
{
m_imShader->UnBind();
m_imShader->EndDraw();
CSprite2d::RestoreLastViewport(FALSE);
}
//
//
// description: Draw a 2d rectangle into GUI area (preferred screen).
// Rectf() uses (0,0)->(1,1) vp mapping
//
void CSprite2d::DrawRectGUI(const fwRect &r, const Color32 &rgba)
{
#if SUPPORT_MULTI_MONITOR
const fwRect area = GRCDEVICE.GetMonitorConfig().getLandscapeMonitor().getArea();
#else
const fwRect area = GRCDEVICE.GetMonitorConfig().m_WholeScreen.getArea();
#endif //SUPPORT_MULTI_MONITOR
DrawRect( fwRect(
area.left + area.GetWidth()*r.left,
area.bottom + area.GetHeight()*r.bottom,
area.left + area.GetWidth()*r.right,
area.bottom + area.GetHeight()*r.top
), rgba);
}
//
// name: CSprite2d::Draw
// description: Draw a 2d sprite
void CSprite2d::Draw(const Vector2 &pt1, const Vector2 &pt2, const Vector2 &pt3, const Vector2 &pt4, const Color32 &rgba)
{
grcBegin(drawTriStrip,4);
grcVertex(pt1.x, pt1.y, 0.0f, 0, 0, -1, rgba, 0.0f, 1.0f);
grcVertex(pt2.x, pt2.y, 0.0f, 0, 0, -1, rgba, 0.0f, 0.0f);
grcVertex(pt3.x, pt3.y, 0.0f, 0, 0, -1, rgba, 1.0f, 1.0f);
grcVertex(pt4.x, pt4.y, 0.0f, 0, 0, -1, rgba, 1.0f, 0.0f);
grcEnd();
}
void CSprite2d::Draw(const Vector2 &pt1, const Vector2 &pt2, const Vector2 &pt3, const Vector2 &pt4, const Vector2 &uv1, const Vector2 &uv2, const Vector2 &uv3, const Vector2 &uv4, const Color32 &rgba)
{
grcBegin(drawTriStrip,4);
grcVertex(pt1.x, pt1.y, 0.0f, 0, 0, -1, rgba, uv1.x, uv1.y);
grcVertex(pt2.x, pt2.y, 0.0f, 0, 0, -1, rgba, uv2.x, uv2.y);
grcVertex(pt3.x, pt3.y, 0.0f, 0, 0, -1, rgba, uv3.x, uv3.y);
grcVertex(pt4.x, pt4.y, 0.0f, 0, 0, -1, rgba, uv4.x, uv4.y);
grcEnd();
}
void CSprite2d::DrawSwitch( bool MULTI_MONITOR_ONLY(bGUI), bool bRect, float zVal,
const Vector2 &pt1, const Vector2 &pt2, const Vector2 &pt3, const Vector2 &pt4,
const Vector2 &uv1, const Vector2 &uv2, const Vector2 &uv3, const Vector2 &uv4,
const Color32 &rgba)
{
Vector2 tmp[] = {pt1,pt2,pt3,pt4};
#if SUPPORT_MULTI_MONITOR
if (bGUI)
{
MoveToScreenGUI(tmp);
}
#endif //SUPPORT_MULTI_MONITOR
if (bRect)
{
DrawRect( tmp[0],tmp[1],tmp[2],tmp[3], zVal, uv1,uv2,uv3,uv4, rgba );
}else
{
Draw( tmp[0],tmp[1],tmp[2],tmp[3], uv1,uv2,uv3,uv4, rgba );
}
}
#if SUPPORT_MULTI_MONITOR
bool CSprite2d::MoveToScreenGUI(Vector2 *const points, const int number)
{
const fwRect area = GRCDEVICE.GetMonitorConfig().getLandscapeMonitor().getArea();
const Vector2 vSize( area.GetWidth(), area.GetHeight() );
const Vector2 vOffset( area.left, area.bottom );
for (int i=0; i<number; ++i)
{
points[i] = points[i] * vSize + vOffset;
}
return vSize.Dot(vSize) < 0.99;
}
void CSprite2d::MovePosVectorToScreenGUI(Vector2 &pos, Vector2 &vec)
{
const fwRect &area = GRCDEVICE.GetMonitorConfig().getLandscapeMonitor().getArea();
pos.x = pos.x * area.GetWidth() + area.left;
pos.y = pos.y * area.GetHeight() + area.bottom;
vec.x *= area.GetWidth();
vec.y *= area.GetHeight();
}
#endif //SUPPORT_MULTI_MONITOR
//
//
// renders 3D sprite:
//
void CSprite2d::DrawSprite3D(float x, float y, float z, float width, float height, const Color32& color, const grcTexture* pTex, const Vector2& uv0, const Vector2& uv1)
{
GRC_ALLOC_SCOPE_AUTO_PUSH_POP()
grcStateBlock::SetRasterizerState(grcStateBlock::RS_NoBackfaceCull);
const Vector4 vecWidthHeight(width, height, 0.0f, 0.0f);
m_imShader->SetVar(m_shdGeneralParams0ID, vecWidthHeight);
m_imShader->SetVar(m_shdDiffuseTextureID, pTex);
grcBindTexture(pTex);
AssertVerify(m_imShader->BeginDraw(grmShader::RMC_DRAW, FALSE, m_blitTechniqueSprite3d));
m_imShader->Bind(0);
{
grcBegin(drawTriStrip,4);
grcVertex(x, y, z, uv0.x, uv0.y, 0.0f, color, 0.0f, 0.0f); // (x0,y0)
grcVertex(x, y, z, uv0.x, uv1.y, 0.0f, color, 0.0f, 1.0f); // (x0,y1)
grcVertex(x, y, z, uv1.x, uv0.y, 0.0f, color, 1.0f, 0.0f); // (x1,y0)
grcVertex(x, y, z, uv1.x, uv1.y, 0.0f, color, 1.0f, 1.0f); // (x1,y1)
grcEnd();
}
m_imShader->UnBind();
m_imShader->EndDraw();
m_imShader->SetVar(m_shdDiffuseTextureID, grcTexture::None);
m_imShader->SetVar(m_shdGeneralParams0ID, Vector4(1.0, 1.0, 1.0, 0.0));
grcBindTexture(grcTexture::None);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//
//
void CSprite2d::Init(unsigned /*initMode*/)
{
USE_MEMBUCKET(MEMBUCKET_RENDER);
//
// initialize shader stuff:
//
m_imShader = grmShaderFactory::GetInstance().Create(/*"im"*/);
Assert(m_imShader);
m_imShader->Load("im");
m_blitTechniqueGta = m_imShader->LookupTechnique("gtadrawblit");
m_blitTechniqueGtaDO = m_imShader->LookupTechnique("gtadrawblit_do");
// new 2d techniques moved from deferred lighting
#if GS_INSTANCED_CUBEMAP
m_blitTechniqueCoronaCubeInst = m_imShader->LookupTechnique("corona_cubeinst_draw");
#endif
m_blitTechniqueCorona = m_imShader->LookupTechnique("corona");
m_blitTechniqueColorCorrected = m_imShader->LookupTechnique("colorcorrectedunlit");
m_blitTechniqueColorCorrectedGradient = m_imShader->LookupTechnique("colorcorrectedunlitgradient");
m_blitTechniqueSeeThrough = m_imShader->LookupTechnique("seethrough");
m_blitTechniqueRefMipBlur = m_imShader->LookupTechnique("refMipBlur");
m_blitTechniqueRefMipBlurBlend = m_imShader->LookupTechnique("refMipBlurBlend");
m_blitTechniqueRefSkyPortal = m_imShader->LookupTechnique("refSkyPortal");
m_resolveDepthTechnique = m_imShader->LookupTechnique("CopyDepth");
m_copyGBufferTechnique = m_imShader->LookupTechnique("CopyGBuffer");
m_blitTechniqueDistantLights = m_imShader->LookupTechnique("DistantLights");
m_blitTechniqueGameGlows = m_imShader->LookupTechnique("GameGlows");
m_toneMapTechnique = m_imShader->LookupTechnique("ToneMap");
m_UIWorldIconTechnique = m_imShader->LookupTechnique("unlit_draw");
m_luminanceToAlphaTechnique = m_imShader->LookupTechnique("LuminanceToAlpha");
m_blitTechniqueMipMap = m_imShader->LookupTechnique("mipMap");
#if __BANK
m_blitTechniqueSignedNormalize = m_imShader->LookupTechnique("visualizeSignedTexture");
#endif
#if __XENON
m_restoreHiZTechnique = m_imShader->LookupTechnique("RestoreHiZ");
m_restoreDepthTechnique = m_imShader->LookupTechnique("RestoreDepth");
#endif
#if __PPU
m_gBufferSplatTechnique = m_imShader->LookupTechnique("gbuffersplat");
m_resolveTechniqueMSAA2x = m_imShader->LookupTechnique("Msaa2xAccuview");
m_resolveTechniqueMSAA4x = m_imShader->LookupTechnique("Msaa4x");
m_zCullReloadTechnique = m_imShader->LookupTechnique("ZCullReload");
m_resolveTechnique = m_imShader->LookupTechnique("psnResolves");
#endif // __PPU
#if USE_HQ_ANTIALIASING
m_highQualityAATechnique = m_imShader->LookupTechnique("HighQualityAA");
#endif // USE_HQ_ANTIALIASING
m_alphaMaskToStencilMaskTechnique = m_imShader->LookupTechnique("AlphaMaskToStencilMask");
m_shdDiffuseTextureID = m_imShader->LookupVar("DiffuseTex");
m_shdRefMipBlurParamsID = m_imShader->LookupVar("RefMipBlurParams");
m_shdLightningConstants = m_imShader->LookupVar("LightningConstants");
m_shdCoronasDepthMapID = m_imShader->LookupVar("CoronasDepthMap");
m_shdDepthPointMapID = m_imShader->LookupVar("DepthPointMap");
m_shdRenderPointMapID = m_imShader->LookupVar("RenderPointMap");
m_shdRenderPointMapINTID = m_imShader->LookupVar("RenderPointMapINT");
m_shdRenderCubeMapID = m_imShader->LookupVar("RenderCubeMap");
m_shdRenderTexArrayID = m_imShader->LookupVar("RenderTexArray");
m_shdRefMipBlurMapID = m_imShader->LookupVar("RefMipBlurMap");
m_shdGeneralParams0ID = m_imShader->LookupVar("GeneralParams0");
m_shdGeneralParams1ID = m_imShader->LookupVar("GeneralParams1");
m_shdRenderPointMapINTParamID = m_imShader->LookupVar("RenderPointMapINTParam");
m_shdTonemapColorFilterParams0ID = m_imShader->LookupVar("tonemapColorFilterParams0");
m_shdTonemapColorFilterParams1ID = m_imShader->LookupVar("tonemapColorFilterParams1");
#if DEVICE_MSAA
m_shdRenderTexMsaaID = m_imShader->LookupVar("RenderTexMSAA");
m_shdRenderTexMsaaINTID = m_imShader->LookupVar("RenderTexMSAAINT");
m_shdRenderTexMsaaParamID = m_imShader->LookupVar("RenderTexMSAAParam");
#endif
#if DEVICE_EQAA
m_shdRenderTexFmaskID = m_imShader->LookupVar("RenderTexFmask");
#endif
#if USE_HQ_ANTIALIASING
m_shdTransparentSrcMapParamsID = m_imShader->LookupVar("TransparentSrcMap");
#endif // USE_HQ_ANTIALIASING
#if __XENON
m_shdDepthTextureID = m_imShader->LookupVar("DepthTexture");
#endif
m_shdNoiseTextureID = m_imShader->LookupVar("NoiseTexture");
m_shdTexelSizeID = m_imShader->LookupVar("TexelSize");
#if __PPU
m_shdRenderQuincunxMapID = m_imShader->LookupVar("RenderQuincunxMap");
m_shdRenderQuincunxAltMapID = m_imShader->LookupVar("RenderQuincunxAltMap");
m_shdRenderGaussMapID = m_imShader->LookupVar("RenderGaussMap");
#if 0 == PSN_USE_FP16
m_shdRenderIMLitPackedID = m_imShader->LookupTechnique("packed_draw");
m_shdRenderIMLitUnpackedID = m_imShader->LookupTechnique("packed_unlit_draw");
#endif // 0 == PSN_USE_FP16
#endif // __PPU
#if USE_MULTIHEAD_FADE
fade::m_technique = m_imShader->LookupTechnique("RadialFade");
fade::m_shdAreaParams = m_imShader->LookupVar("RadialFadeArea");
fade::m_shdTimeParams = m_imShader->LookupVar("RadialFadeTime");
fade::m_shdWaveParams = m_imShader->LookupVar("RadialWaveParam");
#endif //USE_MULTIHEAD_FADE
#if DEVICE_MSAA
ASSET.PushFolder("common:/shaders");
m_imShaderMS = grmShaderFactory::GetInstance().Create(/*"imMS"*/);
Assert(m_imShaderMS);
m_imShaderMS->Load("imMS");
m_shdRenderTexMsaaDepth = m_imShaderMS->LookupVar("DepthTextureMS");
m_resolveDepthMSTechnique = m_imShaderMS->LookupTechnique("ResolveDepthMS");
ASSET.PopFolder();
#endif //DEVICE_MSAA
m_blitTechniqueSprite3d = m_imShader->LookupTechnique("draw_sprite3d");
Assert(m_blitTechniqueSprite3d);
}
//
//
//
//
void CSprite2d::Shutdown(unsigned /*shutdownMode*/)
{
// shutdown shader:
m_imShader->SetVar(m_shdDiffuseTextureID, (grcTexture*)NULL);
if(m_imShader)
{
delete m_imShader;
m_imShader = NULL;
}
#if DEVICE_MSAA
if(m_imShaderMS)
{
delete m_imShaderMS;
m_imShaderMS = NULL;
}
#endif //DEVICE_MSAA
}
static bool ms_bAutoRestoreLastViewport[NUMBER_OF_RENDER_THREADS] = {FALSE};
static grcViewport *lastViewport[NUMBER_OF_RENDER_THREADS] = {NULL};
//
//
// sets sprite2d blit matrix (for m_blitTechniqueGta)
// it's done only once per frame (it's global variable)
//
void CSprite2d::SetBlitMatrix(grcViewport *vp, fwRect *rect, bool bForce)
{
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER)); // this command is forbidden outwith the render thread
Assert(grcViewport::GetCurrent()); // current viewport must be present
if(!vp)
vp = grcViewport::GetCurrent();
Assert(vp);
// reset current viewport to ortho2D projection:
const unsigned rti = g_RenderThreadIndex;
if(bForce || (vp!=lastViewport[rti]) || (vp->IsPerspective()))
{
lastViewport[rti] = vp;
if(ms_bAutoRestoreLastViewport[rti])
{
CSprite2d::StoreViewport(lastViewport[rti]);
}
vp->SetWorldIdentity();
vp->SetCameraIdentity();
if(rect)
{
vp->Ortho(rect->left, rect->right, rect->bottom, rect->top, 0.0f, 1.0f);
}
else
{
// change projection to Ortho(x,x+width,y+height,y,0,+1) based on current window transform
vp->Screen();
}
}
}//end of SetBlitMatrix()...
//
//
// resets default VP mapping to (0,0)->(W,H)
// (as majority of Rage-level stuff requires it to work - e.g. mouse RAG, timebars, etc.):
//
void CSprite2d::ResetDefaultScreenVP()
{
grcViewport* m_StoredViewport = grcViewport::SetCurrent(grcViewport::GetDefaultScreen());
if(grcViewport::GetCurrent())
grcViewport::GetCurrent()->Screen();
grcViewport::SetCurrent(m_StoredViewport);
}
// stored viewport values:
#define INIT_IDENTITY_MATRIX(...) \
__VA_ARGS__ \
1.f, 0.f, 0.f, 0.f, \
0.f, 1.f, 0.f, 0.f, \
0.f, 0.f, 1.f, 0.f, \
0.f, 0.f, 0.f, 1.f,
#define INIT_IDENTITY_MATRIX_1 INIT_IDENTITY_MATRIX()
#define INIT_IDENTITY_MATRIX_2 INIT_IDENTITY_MATRIX(INIT_IDENTITY_MATRIX_1)
#define INIT_IDENTITY_MATRIX_3 INIT_IDENTITY_MATRIX(INIT_IDENTITY_MATRIX_2)
#define INIT_IDENTITY_MATRIX_4 INIT_IDENTITY_MATRIX(INIT_IDENTITY_MATRIX_3)
#define INIT_IDENTITY_MATRIX_5 INIT_IDENTITY_MATRIX(INIT_IDENTITY_MATRIX_4)
#define INIT_IDENTITY_MATRIX_6 INIT_IDENTITY_MATRIX(INIT_IDENTITY_MATRIX_5)
#define INIT_IDENTITY_MATRIX_7 INIT_IDENTITY_MATRIX(INIT_IDENTITY_MATRIX_6)
#define INIT_IDENTITY_MATRIX_8 INIT_IDENTITY_MATRIX(INIT_IDENTITY_MATRIX_7)
#if NUMBER_OF_RENDER_THREADS == 1
# define INIT_IDENTITY_MATRICES INIT_IDENTITY_MATRIX_1
#elif NUMBER_OF_RENDER_THREADS == 2
# define INIT_IDENTITY_MATRICES INIT_IDENTITY_MATRIX_2
#elif NUMBER_OF_RENDER_THREADS == 3
# define INIT_IDENTITY_MATRICES INIT_IDENTITY_MATRIX_3
#elif NUMBER_OF_RENDER_THREADS == 4
# define INIT_IDENTITY_MATRICES INIT_IDENTITY_MATRIX_4
#elif NUMBER_OF_RENDER_THREADS == 5
# define INIT_IDENTITY_MATRICES INIT_IDENTITY_MATRIX_5
#elif NUMBER_OF_RENDER_THREADS == 6
# define INIT_IDENTITY_MATRICES INIT_IDENTITY_MATRIX_6
#elif NUMBER_OF_RENDER_THREADS == 7
# define INIT_IDENTITY_MATRICES INIT_IDENTITY_MATRIX_7
#elif NUMBER_OF_RENDER_THREADS == 8
# define INIT_IDENTITY_MATRICES INIT_IDENTITY_MATRIX_8
#else
# error "number of render threads not currently supported"
#endif
static ALIGNAS(16) float ms_lastProjectionMtxF32[] = { INIT_IDENTITY_MATRICES };
static ALIGNAS(16) float ms_lastCameraMtxF32[] = { INIT_IDENTITY_MATRICES };
static ALIGNAS(16) float ms_lastWorldMtxF32[] = { INIT_IDENTITY_MATRICES };
static Mat44V* const ms_lastProjectionMtx = (Mat44V*)ms_lastProjectionMtxF32;
static Mat34V* const ms_lastCameraMtx = (Mat34V*)ms_lastCameraMtxF32;
static Mat34V* const ms_lastWorldMtx = (Mat34V*)ms_lastWorldMtxF32;
static grcViewport *ms_lastStoredViewport[NUMBER_OF_RENDER_THREADS] = {NULL};
void CSprite2d::StoreViewport(grcViewport *vp)
{
if(vp)
{
const unsigned rti = g_RenderThreadIndex;
Assertf(ms_lastStoredViewport[rti]==NULL, "Sprite2d: Previously stored viewport has not been restored!");
ms_lastStoredViewport[rti] = vp;
ms_lastProjectionMtx[rti] = vp->GetProjection();
ms_lastCameraMtx[rti] = vp->GetCameraMtx();
ms_lastWorldMtx[rti] = vp->GetWorldMtx();
}
}
//
//
//
//
void CSprite2d::RestoreLastViewport(bool bForce)
{
const unsigned rti = g_RenderThreadIndex;
if((bForce || ms_bAutoRestoreLastViewport[rti]) && ms_lastStoredViewport[rti])
{
ms_lastStoredViewport[rti]->SetCameraMtx(ms_lastCameraMtx[rti]);
ms_lastStoredViewport[rti]->SetWorldMtx(ms_lastWorldMtx[rti]);
ms_lastStoredViewport[rti]->SetProjection(ms_lastProjectionMtx[rti]);
ms_lastStoredViewport[rti] = NULL;
}
}
//
// use this with care, at it slows down sprite2d rendering:
// if TRUE, then viewport is restored to perspective after EVERY sprite2d call
// use only for debug rendering and when 2d/3d font text is mixed with 3d lines
// (e.g. CRenderPhaseDebug3d::AddToDrawList())
//
// best practice is to separate 2d text rendering and any 3d rendering
// (render them in different renderphases, using separate viewports, etc.)
//
void CSprite2d::SetAutoRestoreViewport(bool bRestore)
{
ms_bAutoRestoreLastViewport[g_RenderThreadIndex] = bRestore;
}
//
//
//
//
void CSprite2d::OverrideBlitMatrix(grcViewport& vp)
{
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER)); // this command is forbidden outwith the render thread
fwRect rect01(0,1,1,0);
SetBlitMatrix(&vp, &rect01, TRUE);
}
//
//
//
//
void CSprite2d::OverrideBlitMatrix(float width, float height)
{
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER)); // this command is forbidden outwith the render thread
CSprite2d::OverrideBlitMatrix(0.0f, width, 0.0f, height);
}
//
//
//
//
void CSprite2d::OverrideBlitMatrix(float left, float right, float top, float bottom)
{
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER)); // this command is forbidden outwith the render thread
fwRect rect(left, bottom, right, top);
SetBlitMatrix(NULL, &rect, TRUE);
}
//
//
//
//
void CSprite2d::ResetBlitMatrix()
{
Assert(CSystem::IsThisThreadId(SYS_THREAD_RENDER)); // this command is forbidden outwith the render thread
fwRect rect01(0,1,1,0);
SetBlitMatrix(NULL, &rect01, TRUE);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CUIWorldIconQuad::CUIWorldIconQuad()
: m_worldPosition(0.0f, 0.0f, 0.0f)
, m_size(0.0f, 0.0f)
, m_color(255, 255, 255, 255)
, m_useAlpha(true)
, m_isTextureSet(false)
, m_pTextureName(NULL)
, m_pTextureDictionary(NULL)
, m_textureSlot(-1)
{
Clear();
InitCommon();
}
CUIWorldIconQuad::~CUIWorldIconQuad()
{
Clear();
}
void CUIWorldIconQuad::Clear()
{
m_sprite.Delete();
m_useAlpha = true;
m_worldPosition.Set(0.0f, 0.0f, 0.0f);
m_size.Set(0.0f, 0.0f);
m_color.Set(255, 255, 255, 255);
if(m_isTextureSet)
g_TxdStore.RemoveRef(m_textureSlot, REF_OTHER);
m_isTextureSet = false;
m_textureSlot = -1;
m_pTextureName = NULL;
m_pTextureDictionary = NULL;
}
void CUIWorldIconQuad::Update()
{
if(!m_isTextureSet)
{
if(m_textureSlot != -1 && m_pTextureName)
{
LoadTexure();
}
else if(m_pTextureName && m_pTextureDictionary)
{
SetTexture(m_pTextureName, m_pTextureDictionary);
}
}
}
float CUIWorldIconQuad::GetWidth() const
{
return float(m_sprite.GetTexture()->GetWidth()) * m_size.x;
}
float CUIWorldIconQuad::GetHeight() const
{
return float(m_sprite.GetTexture()->GetHeight()) * m_size.y;
}
bool CUIWorldIconQuad::HasTexture() const
{
return m_sprite.HasTexture();
}
void CUIWorldIconQuad::AddToDrawList()
{
if(!m_isTextureSet)
{
return;
}
if(!uiVerify(m_sprite.HasTexture()))
{
return;
}
float halfWidth = GetWidth() * 0.5f;
float halfHeight = GetHeight() * 0.5f;
Vector3 camRight = camInterface::GetRight();
Vector3 camUp = camInterface::GetUp();
Vector3 r1 = m_worldPosition - (camRight*halfWidth) + (camUp*halfHeight);
Vector3 r2 = m_worldPosition - (camRight*halfWidth) - (camUp*halfHeight);
Vector3 r3 = m_worldPosition + (camRight*halfWidth) + (camUp*halfHeight);
Vector3 r4 = m_worldPosition + (camRight*halfWidth) - (camUp*halfHeight);
Vector2 uv1(0.0f, 0.0f);
Vector2 uv2(0.0f, 1.0f);
Vector2 uv3(1.0f, 0.0f);
Vector2 uv4(1.0f, 1.0f);
DLC(CDrawUIWorldIcon, (r1, r2, r3, r4, uv1, uv2, uv3, uv4, m_color, m_sprite.GetTexture(), m_textureSlot.Get(),
m_useAlpha ? sm_StandardSpriteBlendStateHandle : grcStateBlock::BS_Default));
}
void CUIWorldIconQuad::SetTexture(const char* pTextName, const char* pTextDictionary)
{
bool shouldLoad = true;
if(m_isTextureSet)
{
if(stricmp(m_pTextureName, pTextName) != 0 ||
stricmp(m_pTextureDictionary, pTextDictionary) != 0 ||
!uiVerifyf(CStreaming::HasObjectLoaded(m_textureSlot, g_TxdStore.GetStreamingModuleId()), "CUIWorldIconQuad::SetTexture - For some reason the texture isn't loaded, forcing it to be loaded again. refCount=%d", g_TxdStore.GetNumRefs(m_textureSlot))
)
{
g_TxdStore.RemoveRef(m_textureSlot, REF_OTHER);
m_isTextureSet = false;
m_textureSlot = -1;
}
else
{
shouldLoad = false;
}
}
else
{
m_textureSlot = -1;
}
m_pTextureName = pTextName;
m_pTextureDictionary = pTextDictionary;
if(shouldLoad && uiVerify(m_pTextureDictionary))
{
m_textureSlot = g_TxdStore.FindSlot(m_pTextureDictionary);
LoadTexure();
}
}
void CUIWorldIconQuad::LoadTexure()
{
if(!uiVerify(m_textureSlot.Get() >= 0) && uiVerify(m_pTextureDictionary))
{
m_textureSlot = g_TxdStore.FindSlot(m_pTextureDictionary);
}
if(uiVerify(m_pTextureName) && m_textureSlot.Get() >= 0)
{
if(CStreaming::HasObjectLoaded(m_textureSlot, g_TxdStore.GetStreamingModuleId()))
{
g_TxdStore.PushCurrentTxd();
g_TxdStore.SetCurrentTxd(m_textureSlot);
m_sprite.SetTexture(m_pTextureName);
g_TxdStore.PopCurrentTxd();
g_TxdStore.AddRef(m_textureSlot, REF_OTHER);
m_isTextureSet = true;
}
else
{
CStreaming::RequestObject(m_textureSlot, g_TxdStore.GetStreamingModuleId(), STRFLAG_FORCE_LOAD);
}
}
}
void CUIWorldIconQuad::InitCommon()
{
if(!sm_initializedCommon)
{
grcBlendStateDesc textQuadBlendState;
textQuadBlendState.BlendRTDesc[0].BlendEnable = true;
textQuadBlendState.BlendRTDesc[0].SrcBlend = grcRSV::BLEND_SRCALPHA;
textQuadBlendState.BlendRTDesc[0].DestBlend = grcRSV::BLEND_INVSRCALPHA;
textQuadBlendState.BlendRTDesc[0].BlendOp = grcRSV::BLENDOP_ADD;
textQuadBlendState.BlendRTDesc[0].SrcBlendAlpha = grcRSV::BLEND_SRCALPHA;
textQuadBlendState.BlendRTDesc[0].DestBlendAlpha = grcRSV::BLEND_INVSRCALPHA;
textQuadBlendState.BlendRTDesc[0].BlendOpAlpha = grcRSV::BLENDOP_ADD;
textQuadBlendState.BlendRTDesc[0].RenderTargetWriteMask = grcRSV::COLORWRITEENABLE_ALL;
sm_StandardSpriteBlendStateHandle = grcStateBlock::CreateBlendState(textQuadBlendState);
}
}
//eof