Files
FC1/RenderDll/XRenderD3D9/D3DRenderRE.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

1822 lines
54 KiB
C++

/*=============================================================================
D3DRenderRE.cpp : implementation of the Rendering RenderElements pipeline.
Copyright 2001 Crytek Studios. All Rights Reserved.
Revision history:
* Created by Honitch Andrey
=============================================================================*/
#include "RenderPCH.h"
#include "DriverD3D9.h"
#include "I3dengine.h"
#include "D3DCGPShader.h"
#include "D3DCGVProgram.h"
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
//=======================================================================
void CRE2DQuad::mfPrepare()
{
gRenDev->EF_CheckOverflow(0, 0, this);
gRenDev->m_RP.m_pRE = this;
gRenDev->m_RP.m_RendNumIndices = 0;
gRenDev->m_RP.m_FirstVertex = 0;
gRenDev->m_RP.m_RendNumVerts = 4;
int w=800;
int h=600;
m_arrVerts[0].xyz.x = (float)w;
m_arrVerts[0].xyz.y = 0;
m_arrVerts[0].xyz.z = 0;
m_arrVerts[0].st[0] = 1;
m_arrVerts[0].st[1] = 0;
m_arrVerts[1].xyz.x = 0;
m_arrVerts[1].xyz.y = 0;
m_arrVerts[1].xyz.z = 0;
m_arrVerts[1].st[0] = 0;
m_arrVerts[1].st[1] = 0;
m_arrVerts[2].xyz.x = (float)w;
m_arrVerts[2].xyz.y = (float)h;
m_arrVerts[2].xyz.z = 0;
m_arrVerts[2].st[0] = 1;
m_arrVerts[2].st[1] = 1;
m_arrVerts[3].xyz.x = 0;
m_arrVerts[3].xyz.y = (float)h;
m_arrVerts[3].xyz.z = 0;
m_arrVerts[3].st[0] = 0;
m_arrVerts[3].st[1] = 1;
}
bool CRE2DQuad::mfDraw(SShader *ef, SShaderPass *sfm)
{
// setup screen aligned quad...
struct_VERTEX_FORMAT_P3F_TEX2F pScreenQuad[] =
{
Vec3(0, 0, 0), 0, 0,
Vec3(0, 1, 0), 0, 1,
Vec3(1, 0, 0), 1, 0,
Vec3(1, 1, 0), 1, 1,
};
gRenDev->Set2DMode(true, 1, 1);
gRenDev->DrawTriStrip(&CVertexBuffer(pScreenQuad,VERTEX_FORMAT_P3F_TEX2F),4);
gRenDev->Set2DMode(false, 1, 1);
return true;
}
void CREFlareGeom::mfCheckVis(CFColor &col, CCObject *obj)
{
float Depth[3][3];
float ft;
float f;
CD3D9Renderer *rd = gcpRendD3D;
int re = 0;//rd->mfGetRecurseLevel();
SFlareFrame *ff = &mFlareFr[re];
LPDIRECT3DDEVICE9 pd3dDevice = rd->mfGetD3DDevice();
IDirect3DSurface9 *ZSurf = rd->mfGetZSurface();
D3DSURFACE_DESC *ddsd = rd->mfGetZSurfaceDesc();
// Lock Z surface.
int minx, miny, maxx, maxy;
int hgt = rd->GetHeight();
int wdt = rd->GetWidth();
int y = hgt - ff->mY;
if (ff->mX-5 < 0)
minx = 0;
else
minx = ff->mX-5;
if (y-5 < 0)
miny = 0;
else
miny = y-5;
if (ff->mX+5 > wdt)
maxx = wdt;
else
maxx = ff->mX+5;
if (y+5 > hgt)
maxy = hgt;
else
maxy = y+5;
D3DLOCKED_RECT rc;
//HRESULT ddrval = ZSurf->LockRect( &rc, NULL, D3DLOCK_READONLY );
//if( ddrval!=D3D_OK )
{
//iLog->Log("D3D Driver: Lock on Zbuffer failed (%s)\n", rd->D3DError(ddrval));
return;
}
int i, j;
switch( ddsd->Format )
{
case D3DFMT_D16:
{
ushort* src = (ushort*)rc.pBits;
int pitch = rc.Pitch>>1;
src = &src[minx+miny*pitch];
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
Depth[i][j] = src[j*5] / 65536.0f;
}
src += pitch*5;
}
}
break;
case D3DFMT_D24S8:
{
DWORD* src = (DWORD*)rc.pBits;
int pitch = rc.Pitch>>2;
src = &src[minx+miny*pitch];
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
Depth[i][j] = (src[j*5]>>8) / 16777216.0f;
}
src += pitch*5;
}
}
break;
#ifndef _XBOX
case D3DFMT_D32:
{
DWORD* src = (DWORD*)rc.pBits;
int pitch = rc.Pitch>>2;
src = &src[minx+miny*pitch];
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
Depth[i][j] = src[j*5] / 4294967296.0f;
}
src += pitch*5;
}
}
break;
#endif
}
ZSurf->UnlockRect();
float Scale = 0;
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
float Dept = (Depth[i][j]-rd->mMinDepth) / (rd->mMaxDepth-rd->mMinDepth);
f = gRenDev->m_ProjMatrix(3,2)/(Dept*gRenDev->m_ProjMatrix(2,3)-gRenDev->m_ProjMatrix(2,2)) - ff->mDepth;
if (f < 24.0f)
{
if (i==1 && j==1)
Scale += 3.0f;
else
if (i==1 || j==1)
Scale += 2.0f;
else
Scale += 1.0f;
}
}
}
ff->mScale = Scale / 9.0f;
if (ff->mScale > 1.0f)
ff->mScale = 1.0f;
if (ff->mScale)
{
if (!ff->mbVis)
{
ff->mbVis = true;
ff->mDecayTime = gRenDev->m_RP.m_RealTime-0.001f;
}
ft = (gRenDev->m_RP.m_RealTime - ff->mDecayTime) * CRenderer::CV_r_coronafade;
if (ft > 1.0f)
ft = 1.0f;
ft *= ff->mScale;
}
else
{
if (ff->mbVis)
{
ff->mbVis = false;
ff->mDecayTime = gRenDev->m_RP.m_RealTime-0.001f;
}
ft = 1.0f - (gRenDev->m_RP.m_RealTime - ff->mDecayTime) * CRenderer::CV_r_coronafade;
if (ft > 1.0f)
ft = 1.0f;
ft *= ff->mScale;
}
col = ff->mColor;
col.a = ft;
col.ClampAlpha();
}
//=========================================================================================
static void _Draw3dBBoxSolid(const Vec3d &mins,const Vec3d &maxs)
{
int nOffs;
CD3D9Renderer *r = gcpRendD3D;
LPDIRECT3DDEVICE9 dv = r->mfGetD3DDevice();
HRESULT hr;
struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad;
// Set the vertex shader to the FVF fixed function shader
r->EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F);
vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)r->GetVBPtr3D(4, nOffs);
vQuad[0].xyz = Vec3d(mins.x,mins.y,mins.z); vQuad[0].st[0] = vQuad[0].st[1] = 0; vQuad[0].color.dcolor = -1;
vQuad[1].xyz = Vec3d(mins.x,mins.y,maxs.z); vQuad[1].st[0] = vQuad[1].st[1] = 0; vQuad[1].color.dcolor = -1;
vQuad[2].xyz = Vec3d(maxs.x,mins.y,maxs.z); vQuad[2].st[0] = vQuad[2].st[1] = 0; vQuad[2].color.dcolor = -1;
vQuad[3].xyz = Vec3d(maxs.x,mins.y,mins.z); vQuad[3].st[0] = vQuad[3].st[1] = 0; vQuad[3].color.dcolor = -1;
r->UnlockVB3D();
// Bind our vertex as the first data stream of our device
dv->SetStreamSource(0, r->m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F));
// Render the two triangles from the data stream
hr = dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2);
vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)r->GetVBPtr3D(4, nOffs);
vQuad[0].xyz = Vec3d(mins.x,mins.y,mins.z); vQuad[0].st[0] = vQuad[0].st[1] = 0; vQuad[0].color.dcolor = -1;
vQuad[1].xyz = Vec3d(mins.x,mins.y,maxs.z); vQuad[1].st[0] = vQuad[1].st[1] = 0; vQuad[1].color.dcolor = -1;
vQuad[2].xyz = Vec3d(mins.x,maxs.y,maxs.z); vQuad[2].st[0] = vQuad[2].st[1] = 0; vQuad[2].color.dcolor = -1;
vQuad[3].xyz = Vec3d(mins.x,maxs.y,mins.z); vQuad[3].st[0] = vQuad[3].st[1] = 0; vQuad[3].color.dcolor = -1;
r->UnlockVB3D();
// Bind our vertex as the first data stream of our device
dv->SetStreamSource(0, r->m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F));
// Render the two triangles from the data stream
hr = dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2);
vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)r->GetVBPtr3D(4, nOffs);
vQuad[0].xyz = Vec3d(mins.x,maxs.y,mins.z); vQuad[0].st[0] = vQuad[0].st[1] = 0; vQuad[0].color.dcolor = -1;
vQuad[1].xyz = Vec3d(mins.x,maxs.y,maxs.z); vQuad[1].st[0] = vQuad[1].st[1] = 0; vQuad[1].color.dcolor = -1;
vQuad[2].xyz = Vec3d(maxs.x,maxs.y,maxs.z); vQuad[2].st[0] = vQuad[2].st[1] = 0; vQuad[2].color.dcolor = -1;
vQuad[3].xyz = Vec3d(maxs.x,maxs.y,mins.z); vQuad[3].st[0] = vQuad[3].st[1] = 0; vQuad[3].color.dcolor = -1;
r->UnlockVB3D();
// Bind our vertex as the first data stream of our device
dv->SetStreamSource(0, r->m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F));
// Render the two triangles from the data stream
hr = dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2);
vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)r->GetVBPtr3D(4, nOffs);
vQuad[0].xyz = Vec3d(maxs.x,maxs.y,mins.z); vQuad[0].st[0] = vQuad[0].st[1] = 0; vQuad[0].color.dcolor = -1;
vQuad[1].xyz = Vec3d(maxs.x,maxs.y,maxs.z); vQuad[1].st[0] = vQuad[1].st[1] = 0; vQuad[1].color.dcolor = -1;
vQuad[2].xyz = Vec3d(maxs.x,mins.y,maxs.z); vQuad[2].st[0] = vQuad[2].st[1] = 0; vQuad[2].color.dcolor = -1;
vQuad[3].xyz = Vec3d(maxs.x,mins.y,mins.z); vQuad[3].st[0] = vQuad[3].st[1] = 0; vQuad[3].color.dcolor = -1;
r->UnlockVB3D();
// Bind our vertex as the first data stream of our device
dv->SetStreamSource(0, r->m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F));
// Render the two triangles from the data stream
hr = dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2);
// top
vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)r->GetVBPtr3D(4, nOffs);
vQuad[0].xyz = Vec3d(maxs.x,maxs.y,maxs.z); vQuad[0].st[0] = vQuad[0].st[1] = 0; vQuad[0].color.dcolor = -1;
vQuad[1].xyz = Vec3d(mins.x,maxs.y,maxs.z); vQuad[1].st[0] = vQuad[1].st[1] = 0; vQuad[1].color.dcolor = -1;
vQuad[2].xyz = Vec3d(mins.x,mins.y,maxs.z); vQuad[2].st[0] = vQuad[2].st[1] = 0; vQuad[2].color.dcolor = -1;
vQuad[3].xyz = Vec3d(maxs.x,mins.y,maxs.z); vQuad[3].st[0] = vQuad[3].st[1] = 0; vQuad[3].color.dcolor = -1;
r->UnlockVB3D();
// Bind our vertex as the first data stream of our device
dv->SetStreamSource(0, r->m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F));
// Render the two triangles from the data stream
hr = dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2);
// bottom
vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)r->GetVBPtr3D(4, nOffs);
vQuad[0].xyz = Vec3d(maxs.x,mins.y,mins.z); vQuad[0].st[0] = vQuad[0].st[1] = 0; vQuad[0].color.dcolor = -1;
vQuad[1].xyz = Vec3d(mins.x,mins.y,mins.z); vQuad[1].st[0] = vQuad[1].st[1] = 0; vQuad[1].color.dcolor = -1;
vQuad[2].xyz = Vec3d(mins.x,maxs.y,mins.z); vQuad[2].st[0] = vQuad[2].st[1] = 0; vQuad[2].color.dcolor = -1;
vQuad[3].xyz = Vec3d(maxs.x,maxs.y,mins.z); vQuad[3].st[0] = vQuad[3].st[1] = 0; vQuad[3].color.dcolor = -1;
r->UnlockVB3D();
// Bind our vertex as the first data stream of our device
dv->SetStreamSource(0, r->m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F));
// Render the two triangles from the data stream
hr = dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2);
r->m_nPolygons+=12;
}
CREOcclusionQuery::~CREOcclusionQuery()
{
int i;
mfReset();
for (i=0; i<8; i++)
{
}
}
void CREOcclusionQuery::mfReset()
{
LPDIRECT3DQUERY9 pVizQuery = (LPDIRECT3DQUERY9)m_nOcclusionID;
if (pVizQuery)
{
pVizQuery->Release();
m_nOcclusionID = 0;
}
}
bool CREOcclusionQuery::mfDraw(SShader *ef, SShaderPass *sfm)
{
CD3D9Renderer *r = gcpRendD3D;
LPDIRECT3DDEVICE9 dv = r->mfGetD3DDevice();
HRESULT hr;
if (!(r->m_Features & RFT_OCCLUSIONTEST))
{
m_nVisSamples = r->GetWidth()*r->GetHeight();
return true;
}
int nFrame = r->GetFrameID();
// if(nFrame&1)
// return true;
if ( m_nCheckFrame != nFrame )
{
if(m_nCheckFrame)
{
m_nVisSamples=0;
// Stupidly block until we have a query result
LPDIRECT3DQUERY9 pVizQuery = (LPDIRECT3DQUERY9)m_nOcclusionID;
if (pVizQuery)
{
double time = sCycles2();
bool bInfinite = false;
while (pVizQuery->GetData((void *) &m_nVisSamples, sizeof(DWORD), D3DGETDATA_FLUSH) == S_FALSE)
{
double dif = sCycles2()+34-time;
if (dif*1000.0*g_SecondsPerCycle > 5000)
{
// 5 seconds in the loop
bInfinite = true;
break;
}
}
r->m_RP.m_PS.m_fOcclusionTime += (float)((sCycles2()+34-time)*1000.0*g_SecondsPerCycle);
if (bInfinite)
iLog->Log("Error: Seems like infinite loop in occlusion query");
}
}
m_nCheckFrame = nFrame;
}
if (!m_nOcclusionID)
{
// Create the query if we can
{
// Create visibility queries
LPDIRECT3DQUERY9 pVizQuery = NULL;
hr = dv->CreateQuery (D3DQUERYTYPE_OCCLUSION, &pVizQuery);
if (pVizQuery)
m_nOcclusionID = (UINT_PTR)pVizQuery;
}
}
if (m_nDrawFrame != nFrame)
{ // draw bbox
LPDIRECT3DQUERY9 pVizQuery = (LPDIRECT3DQUERY9)m_nOcclusionID;
if (pVizQuery)
{
pVizQuery->Issue (D3DISSUE_BEGIN);
_Draw3dBBoxSolid(m_vBoxMin-Vec3d(0.05f,0.05f,0.05f),m_vBoxMax+Vec3d(0.05f,0.05f,0.05f));
pVizQuery->Issue (D3DISSUE_END);
}
m_nDrawFrame = nFrame;
}
return true;
}
void CRETempMesh::mfReset()
{
gRenDev->ReleaseBuffer(m_VBuffer);
gRenDev->ReleaseIndexBuffer(&m_Inds);
m_VBuffer = NULL;
}
bool CRETempMesh::mfPreDraw(SShaderPass *sl)
{
CVertexBuffer *vb = m_VBuffer;
for (int i=0; i<VSF_NUM; i++)
{
if (vb->m_VS[i].m_bLocked)
gcpRendD3D->UnlockBuffer(vb, i);
}
if (!m_Inds.m_nItems)
return false;
LPDIRECT3DDEVICE9 dv = gcpRendD3D->mfGetD3DDevice();
HRESULT h;
h = dv->SetStreamSource( 0, (IDirect3DVertexBuffer9 *)vb->m_VS[VSF_GENERAL].m_VertBuf.m_pPtr, 0, m_VertexSize[vb->m_vertexformat]);
if (gRenDev->m_RP.m_FlagsModificators & RBMF_TANGENTSUSED)
{
gRenDev->m_RP.m_PersFlags |= RBPF_USESTREAM1;
h = dv->SetStreamSource( 1, (IDirect3DVertexBuffer9 *)vb->m_VS[VSF_TANGENTS].m_VertBuf.m_pPtr, 0, sizeof(SPipTangents));
}
else
if (gRenDev->m_RP.m_PersFlags & RBPF_USESTREAM1)
{
gRenDev->m_RP.m_PersFlags &= ~RBPF_USESTREAM1;
h = dv->SetStreamSource( 1, NULL, 0, 0);
}
if (gRenDev->m_RP.m_PersFlags & RBPF_USESTREAM2)
{
gRenDev->m_RP.m_PersFlags &= ~RBPF_USESTREAM2;
h = dv->SetStreamSource( 2, NULL, 0, 0);
}
h = dv->SetIndices((IDirect3DIndexBuffer9 *)m_Inds.m_VertBuf.m_pPtr);
return true;
}
bool CRETempMesh::mfDraw(SShader *ef, SShaderPass *sl)
{
CD3D9Renderer *r = gcpRendD3D;
CVertexBuffer *vb = m_VBuffer;
if (!vb)
return false;
// Hardware shader
int nPrimType = R_PRIMV_TRIANGLES;
r->EF_DrawIndexedMesh(nPrimType);
vb->m_bFenceSet = true;
return true;
}
bool CREOcLeaf::mfPreDraw(SShaderPass *sl)
{
CLeafBuffer *lb = m_pBuffer->GetVertexContainer();
// Should never happen. Video buffer is missing
if (!lb->m_pVertexBuffer)
return false;
CD3D9Renderer *rd = gcpRendD3D;
for (int i=0; i<VSF_NUM; i++)
{
if (lb->m_pVertexBuffer->m_VS[i].m_bLocked)
rd->UnlockBuffer(lb->m_pVertexBuffer, i);
}
LPDIRECT3DDEVICE9 dv = rd->mfGetD3DDevice();
HRESULT h;
int nOffs;
IDirect3DVertexBuffer9 *vptr = (IDirect3DVertexBuffer9 *)lb->m_pVertexBuffer->GetStream(VSF_GENERAL, &nOffs);
vptr = vptr ? vptr : rd->m_pVB3D[1];
h = dv->SetStreamSource( 0, vptr, nOffs, m_VertexSize[lb->m_pVertexBuffer->m_vertexformat]);
if (rd->m_RP.m_FlagsModificators & RBMF_TANGENTSUSED)
{
rd->m_RP.m_PersFlags |= RBPF_USESTREAM1;
vptr = (IDirect3DVertexBuffer9 *)lb->m_pVertexBuffer->GetStream(VSF_TANGENTS, &nOffs);
vptr = vptr ? vptr : rd->m_pVB3D[2];
h = dv->SetStreamSource( 1, vptr, nOffs, sizeof(SPipTangents));
}
else
if (rd->m_RP.m_PersFlags & RBPF_USESTREAM1)
{
rd->m_RP.m_PersFlags &= ~RBPF_USESTREAM1;
h = dv->SetStreamSource( 1, NULL, 0, 0);
}
if (rd->m_RP.m_FlagsModificators & RBMF_LMTCUSED)
{
rd->m_RP.m_PersFlags |= RBPF_USESTREAM2;
if (rd->m_RP.m_pCurObject->m_pLMTCBufferO && rd->m_RP.m_pCurObject->m_pLMTCBufferO->m_pVertexBuffer)
{
vptr = (IDirect3DVertexBuffer9 *)rd->m_RP.m_pCurObject->m_pLMTCBufferO->m_pVertexBuffer->GetStream(VSF_GENERAL, &nOffs);
h = dv->SetStreamSource(2, vptr, nOffs, m_VertexSize[rd->m_RP.m_pCurObject->m_pLMTCBufferO->m_pVertexBuffer->m_vertexformat]);
}
}
else
if (rd->m_RP.m_PersFlags & RBPF_USESTREAM2)
{
rd->m_RP.m_PersFlags &= ~RBPF_USESTREAM2;
h = dv->SetStreamSource( 2, NULL, 0, 0);
}
if (CRenderer::CV_r_cullgeometryforlights && rd->EF_IsOnlyLightPass((SShaderPassHW *)sl) && rd->m_RP.m_pCurLightIndices != &rd->m_RP.m_FakeLightIndices)
{
assert(rd->m_RP.m_pCurLightIndices);
SVertexStream *vi = rd->m_RP.m_pCurLightIndices->GetIndexBuffer();
IDirect3DIndexBuffer9 *pIndBuf = (IDirect3DIndexBuffer9 *)vi->m_VertBuf.m_pPtr;
assert(pIndBuf);
h = dv->SetIndices(pIndBuf);
}
else
{
IDirect3DIndexBuffer9 *pIndBuf = (IDirect3DIndexBuffer9 *)m_pBuffer->m_Indices.m_VertBuf.m_pPtr;
//assert(pIndBuf);
h = dv->SetIndices(pIndBuf);
}
return true;
}
bool CREOcLeaf::mfDraw(SShader *ef, SShaderPass *sl)
{
CD3D9Renderer *r = gcpRendD3D;
CLeafBuffer *lb = m_pBuffer;
// Hardware effector
if (ef->m_HWTechniques.Num())
{
r->EF_DrawIndexedMesh(lb->m_nPrimetiveType);
return true;
}
r->DrawBuffer(lb->m_pVertexBuffer, &lb->m_Indices, m_pChunk->nNumIndices, m_pChunk->nFirstIndexId, lb->m_nPrimetiveType,m_pChunk->nFirstVertId,m_pChunk->nNumVerts);
return (true);
}
// ===============================================================
// mfDraw - glare fx's
// Last Update: 04/06/2003
bool CREGlare::mfDraw(SShader *ef, SShaderPass *sfm)
{
//// setup screen aligned quad
//struct_VERTEX_FORMAT_P3F_TEX2F pScreenQuad[] =
//{
// 0, 0, 0, 0, 0,
// 0, 1, 0, 0, 1,
// 1, 0, 0, 1, 0,
// 1, 1, 0, 1, 1,
//};
//// render quad
//gRenDev->Set2DMode(true, 1, 1);
//gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenQuad, VERTEX_FORMAT_P3F_TEX2F)), 4);
//gRenDev->Set2DMode(false, 1, 1);
return true;
}
// ===============================================================
// FlashBang fx
// Last Update: 24/04/2003
// render flashbang
bool CREFlashBang::mfDraw(SShader *ef, SShaderPass *sfm)
{
//// sincronize
//ITimer *pTimer=iSystem->GetITimer();
//m_fFlashTimeOut-= (0.00009f*m_fTimeScale*(pTimer->GetFrameTime()*1000.0f));
//// reset animation
//if(m_fFlashTimeOut<=0.01f)
//{
// m_bIsActive=0;
// m_fFlashTimeOut=1.0f;
//}
//// setup screen aligned quad
//struct_VERTEX_FORMAT_P3F_TEX2F pScreenQuad[] =
//{
// 800, 600, 0, 1, 1,
// 800, 0, 0, 1, 0,
// 0, 600, 0, 0, 1,
// 0, 0, 0, 0, 0,
//};
//// render quad
//gRenDev->DrawTriStrip(&(CVertexBuffer (pScreenQuad,VERTEX_FORMAT_P3F_TEX2F)), 4);
return true;
}
void CREOcLeaf::mfEndFlush(void)
{
}
bool CRETriMeshShadow::mfDraw(SShader *ef, SShaderPass *sfm)
{
if(m_nCurrInst<0 || m_nCurrInst>=MAX_SV_INSTANCES)
{
// iLog->Log("Warning: CRETriMeshShadow::mfDraw: m_nCurrInst not set");
return false;
}
CD3D9Renderer *rd = gcpRendD3D;
LPDIRECT3DDEVICE9 dv = rd->mfGetD3DDevice();
rd->CV_ind_VisualizeShadowVolumes = (rd->GetPolygonMode() == R_WIREFRAME_MODE);
CDLight *pDL = NULL;
if (rd->m_RP.m_DynLMask)
{
for (int n=0; n<rd->m_RP.m_DLights[SRendItem::m_RecurseLevel].Num(); n++)
{
if (rd->m_RP.m_DynLMask & (1<<n))
{
pDL = rd->m_RP.m_DLights[SRendItem::m_RecurseLevel][n];
break;
}
}
}
if (pDL && pDL->m_sWidth && pDL->m_sHeight)
rd->EF_Scissor(true, pDL->m_sX, pDL->m_sY, pDL->m_sWidth, pDL->m_sHeight);
if (gRenDev->CV_ind_VisualizeShadowVolumes)
{
rd->EF_SetGlobalColor(1,1,1,1);
rd->EF_SetState(GS_NODEPTHTEST | GS_STENCIL);
}
else
rd->EF_SetState(GS_NOCOLMASK | GS_STENCIL);
rd->EF_SetColorOp(eCO_DISABLE, eCO_DISABLE, DEF_TEXARG0, DEF_TEXARG0);
if (rd->m_d3dCaps.StencilCaps & D3DSTENCILCAPS_TWOSIDED)
{
// using 2-sided stencil
if(m_arrLBuffers[m_nCurrInst].pVB && m_arrLBuffers[m_nCurrInst].pVB->m_pVertexBuffer)
{
rd->EF_SetStencilState(STENCOP_FAIL(FSS_STENCOP_KEEP) |
STENCOP_ZFAIL(FSS_STENCOP_DECR_WRAP) |
STENCOP_PASS(FSS_STENCOP_KEEP) |
STENC_FUNC(FSS_STENCFUNC_ALWAYS) |
STENCOP_CCW_FAIL(FSS_STENCOP_KEEP) |
STENCOP_CCW_ZFAIL(FSS_STENCOP_INCR_WRAP) |
STENCOP_CCW_PASS(FSS_STENCOP_KEEP) |
STENC_CCW_FUNC(FSS_STENCFUNC_ALWAYS) |
FSS_STENCIL_TWOSIDED,
0, -1);
rd->D3DSetCull(eCULL_None);
CVertexBuffer * pVB = m_arrLBuffers[m_nCurrInst].pVB->m_pVertexBuffer;
SVertexStream *Indices = &m_arrLBuffers[m_nCurrInst].pVB->m_Indices;
int nIndices;
if (m_nRendIndices)
nIndices = m_nRendIndices;
else
nIndices = Indices->m_nItems;
assert(nIndices);
if (Indices->m_bLocked)
rd->UpdateIndexBuffer(Indices, NULL, 0, true);
rd->DrawBuffer(pVB, Indices, nIndices, 0, R_PRIMV_TRIANGLES);
gRenDev->m_nShadowVolumePolys += nIndices/3;
}
}
else
{
if(m_arrLBuffers[m_nCurrInst].pVB && m_arrLBuffers[m_nCurrInst].pVB->m_pVertexBuffer)
{
rd->EF_SetStencilState(STENCOP_FAIL(FSS_STENCOP_KEEP) |
STENCOP_ZFAIL(FSS_STENCOP_INCR) |
STENCOP_PASS(FSS_STENCOP_KEEP) |
STENC_FUNC(FSS_STENCFUNC_ALWAYS),
0, -1);
rd->D3DSetCull(eCULL_Front);
CVertexBuffer * pVB = m_arrLBuffers[m_nCurrInst].pVB->m_pVertexBuffer;
SVertexStream *Indices = &m_arrLBuffers[m_nCurrInst].pVB->m_Indices;
int nIndices;
if (m_nRendIndices)
nIndices = m_nRendIndices;
else
nIndices = Indices->m_nItems;
assert(nIndices);
if (Indices->m_bLocked)
rd->UpdateIndexBuffer(Indices, NULL, 0, true);
rd->DrawBuffer(pVB, Indices, nIndices, 0, R_PRIMV_TRIANGLES);
rd->EF_SetStencilState(STENCOP_FAIL(FSS_STENCOP_KEEP) |
STENCOP_ZFAIL(FSS_STENCOP_DECR) |
STENCOP_PASS(FSS_STENCOP_KEEP) |
STENC_FUNC(FSS_STENCFUNC_ALWAYS),
0, -1);
rd->D3DSetCull(eCULL_Back);
rd->DrawBuffer(pVB, Indices, nIndices, 0, R_PRIMV_TRIANGLES);
rd->SetFenceCompleted(pVB); // set it explicitly since second DrawBuffer do not set it
gRenDev->m_nShadowVolumePolys += nIndices/3;
}
}
m_nCurrInst = -1;
return true;
}
/*
bool CRETriMeshAdditionalShadow::mfDraw(SShader *ef, SShaderPass *sfm)
{
return true;
} */
///////////////////////////////////////////////////////////////////
// Render shadows on the object as first pass
///////////////////////////////////////////////////////////////////
/*bool CREShadowMap::mfDraw(SShader *ef, SShaderPass *sfm)
{
return true;
} */
//===================================================================================
bool CREFlare::mfCheckVis(CCObject *obj)
{
if (!obj)
return false;
Vec3d or = obj->GetTranslation();
//bool bVis = false;
bool bSun = false;
int i, j;
CD3D9Renderer *rd = gcpRendD3D;
LPDIRECT3DDEVICE9 dv = rd->mfGetD3DDevice();
HRESULT hr;
if (m_Importance <= CRenderer::CV_r_coronas)
{
float fScaleCorona = m_fScaleCorona;
if (m_pScaleCoronaParams)
fScaleCorona = m_pScaleCoronaParams->mfGet();
if (obj->m_ObjFlags & FOB_DRSUN)
{
bSun = true;
//or.Normalize();
//or *= 500.0f;
//or += gRenDev->m_RP.m_ViewOrg;
}
if (bSun && (gRenDev->m_RP.m_PersFlags & RBPF_DONTDRAWSUN))
return false;
D3DXMATRIX mIdent;
D3DXMatrixIdentity(&mIdent);
Matrix44 projMatr, camMatr;
camMatr = rd->m_prevCamera.GetVCMatrixD3D9();
float fov=rd->m_prevCamera.GetFov()*rd->m_prevCamera.GetProjRatio();
D3DXMatrixPerspectiveFovRH((D3DXMATRIX *)&projMatr, fov, 1.0f/rd->m_prevCamera.GetProjRatio(), rd->m_prevCamera.GetZMin(), rd->m_prevCamera.GetZMax());
dv->SetTransform(D3DTS_VIEW, (D3DXMATRIX *)&camMatr);
dv->SetTransform(D3DTS_PROJECTION, (D3DXMATRIX *)&projMatr);
Vec3 camVecs[3];
camVecs[1][0] = camMatr(0,1);
camVecs[1][1] = camMatr(1,1);
camVecs[1][2] = camMatr(2,1);
camVecs[2][0] = camMatr(0,0);
camVecs[2][1] = camMatr(1,0);
camVecs[2][2] = camMatr(2,0);
if (CRenderer::CV_r_SunStyleCoronas)
bSun = true;
float fFade = 1.0f;
bool bRays = bSun && CRenderer::CV_r_checkSunVis == 2;
if (!bSun)
{
float fFogEnd = rd->m_FS.m_FogEnd;
float fDist = (rd->m_RP.m_ViewOrg-or).Length();
float fStartFade = fFogEnd/3.0f*2.0f;
float fEndFade = fStartFade*1.5f;
if (fDist > fEndFade)
fFade = 0;
else
if (fDist < fStartFade)
fFade = 1.0f;
else
fFade = (fEndFade-fDist) / (fEndFade-fStartFade);
}
obj->m_TempVars[2] = 0;
int vp[4];
rd->GetViewport(&vp[0], &vp[1], &vp[2], &vp[3]);
D3DVIEWPORT9 D3DVP;
D3DVP.X = vp[0];
D3DVP.Y = vp[1];
D3DVP.Width = vp[2];
D3DVP.Height = vp[3];
D3DVP.MinZ = 0;
D3DVP.MaxZ = 1;
Vec3 vScr;
D3DXVec3Project((D3DXVECTOR3 *)&vScr, (D3DXVECTOR3 *)&or, &D3DVP, (D3DXMATRIX *)&projMatr, (D3DXMATRIX *)&camMatr, &mIdent);
int n = 2;
obj->m_Trans2[0] = vScr.x;
obj->m_Trans2[1] = vScr.y;
obj->m_Trans2[2] = vScr.z;
float fCheckInterval = m_fFadeTime;
if (fCheckInterval < 0)
fCheckInterval = CRenderer::CV_r_coronafade*0.125f;
if (bRays)
fCheckInterval *= 0.5f;
if (obj->m_fLightFadeTime-1.0f > rd->m_RP.m_RealTime)
obj->m_fLightFadeTime = rd->m_RP.m_RealTime;
if (rd->m_RP.m_RealTime-obj->m_fLightFadeTime < fCheckInterval)
{
dv->SetTransform(D3DTS_VIEW, rd->m_matView->GetTop());
dv->SetTransform(D3DTS_PROJECTION, rd->m_matProj->GetTop());
return true;
}
obj->m_fLightFadeTime = gRenDev->m_RP.m_RealTime;
vScr.x = obj->m_Trans2[0];
vScr.y = obj->m_Trans2[1];
vScr.z = obj->m_Trans2[2];
float fIntens = 0;
if (vScr.x>=0 && vScr.y>=0 && vScr.x<vp[2] && vScr.y<vp[3] && fFade)
{
int minx, miny, maxx, maxy;
int wdt = rd->m_d3dsdBackBuffer.Width;
int hgt = rd->m_d3dsdBackBuffer.Height;
int sx = (int)vScr.x;
int sy = (int)vScr.y;
if (sx-2 < 0)
minx = 0;
else
minx = sx-2;
if (sy-2 < 0)
miny = 0;
else
miny = sy-2;
if (sx+2 > wdt)
maxx = wdt;
else
maxx = sx+2;
if (sy+2 > hgt)
maxy = hgt;
else
maxy = sy+2;
D3DLOCKED_RECT rc;
gRenDev->m_TexMan->m_Text_White->Set();
rd->D3DSetCull(eCULL_None);
if (!(rd->m_Features & RFT_OCCLUSIONTEST))
{
// Lock back surface.
rd->m_matProj->Push();
D3DXMatrixOrthoRH(rd->m_matProj->GetTop(), (float)rd->GetWidth(), (float)rd->GetHeight(), -20.0, 0.0);
dv->SetTransform(D3DTS_PROJECTION, rd->m_matProj->GetTop());
rd->PushMatrix();
rd->m_matView->LoadIdentity();
dv->SetTransform(D3DTS_VIEW, rd->m_matView->GetTop());
rd->EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0);
// set alpha to 0
{
rd->EF_SetState(GS_NODEPTHTEST);
rd->DrawQuad((float)minx, (float)miny, (float)maxx, (float)maxy, CFColor(0.0f), vScr.z);
}
// Set alpha mask of visible areas (1 is visible)
{
rd->EF_SetState(0);
rd->DrawQuad((float)minx, (float)miny, (float)maxx, (float)maxy, CFColor(1.0f), vScr.z);
}
IDirect3DSurface9 * pTar = rd->mfGetBackSurface();
DWORD dwPixSize = 4;
D3DSURFACE_DESC dc;
pTar->GetDesc(&dc);
switch(dc.Format)
{
case D3DFMT_R8G8B8:
dwPixSize = 3;
break;
case D3DFMT_R5G6B5:
case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
dwPixSize = 2;
break;
};
hr = pTar->LockRect( &rc, NULL, D3DLOCK_READONLY );
if( hr!=D3D_OK )
{
// iLog->Log("D3D Driver: Lock on BackBuffer failed (%s)\n", rd->D3DError(hr));
return false;
}
int dwAccum = 0;
for (i=miny; i<maxy; i++)
{
byte *pPtr = (byte *)rc.pBits;
pPtr += i*rc.Pitch + minx*dwPixSize;
for (j=minx; j<maxx; j++)
{
int Val = *pPtr;
if (abs(i-sy) > 1)
Val >>= 1;
if (abs(j-sx) > 1)
Val >>= 1;
dwAccum += Val;
pPtr += dwPixSize;
}
}
hr = pTar->UnlockRect();
rd->PopMatrix();
rd->m_matProj->Pop();
dv->SetTransform(D3DTS_PROJECTION, rd->m_matProj->GetTop());
dwAccum /= (int)((maxy-miny) * (maxx-minx));
//bVis = dwAccum > 10 ? true : false;
fIntens = min(1.0f, ((float)dwAccum/190.0f));
obj->m_AmbColor[0] = obj->m_AmbColor[1];
obj->m_AmbColor[1] = obj->m_AmbColor[2];
obj->m_AmbColor[2] = obj->m_TempVars[3];
obj->m_TempVars[3] = obj->m_Angs2[0];
obj->m_Angs2[0] = obj->m_Angs2[1];
obj->m_Angs2[1] = obj->m_Angs2[2];
obj->m_Angs2[2] = obj->m_TempVars[4];
obj->m_TempVars[4] = fIntens;
}
else
{
CREOcclusionQuery *pRE = (CREOcclusionQuery *)obj->m_RE;
if (!pRE || m_nFrameQuery != rd->m_nFrameReset || !pRE->m_nOcclusionID)
{
m_nFrameQuery = rd->m_nFrameReset;
obj->m_RE = NULL;
// Create visibility queries
LPDIRECT3DQUERY9 pVizQuery = NULL;
hr = dv->CreateQuery (D3DQUERYTYPE_OCCLUSION, &pVizQuery);
if (pVizQuery)
{
obj->m_RE = rd->EF_CreateRE(eDATA_OcclusionQuery);
pRE = (CREOcclusionQuery *)obj->m_RE;
if (pRE)
{
pRE->m_nOcclusionID = (UINT_PTR)pVizQuery;
pRE->m_nVisSamples = 0;
}
}
}
else
{
CREOcclusionQuery *pRE = (CREOcclusionQuery *)obj->m_RE;
int nFrame = rd->GetFrameID();
if ( pRE->m_nCheckFrame != nFrame )
{
if(pRE->m_nCheckFrame)
{
pRE->m_nVisSamples=0;
// Stupidly block until we have a query result
LPDIRECT3DQUERY9 pVizQuery = (LPDIRECT3DQUERY9)pRE->m_nOcclusionID;
if (pVizQuery)
{
double time = sCycles2();
bool bInfinite = false;
while (pVizQuery->GetData((void *) &pRE->m_nVisSamples, sizeof(DWORD), D3DGETDATA_FLUSH) == S_FALSE)
{
double dif = sCycles2()+34-time;
if (dif*1000.0*g_SecondsPerCycle > 5000.0)
{
// 5 seconds in the loop
bInfinite = true;
break;
}
}
rd->m_RP.m_PS.m_fOcclusionTime += (float)((sCycles2()+34-time)*1000.0*g_SecondsPerCycle);
if (bInfinite)
iLog->Log("Error: Seems like infinite loop in flare occlusion query");
}
}
pRE->m_nCheckFrame = nFrame;
}
}
pRE = (CREOcclusionQuery *)obj->m_RE;
LPDIRECT3DQUERY9 pVizQuery = NULL;
if (pRE)
pVizQuery = (LPDIRECT3DQUERY9)pRE->m_nOcclusionID;
if (pVizQuery)
{
Vec3d vx0, vy0, v;
v = or - rd->m_prevCamera.GetPos();
float dist = v.Length();
if (m_fDistSizeFactor != 1.0f)
dist = cry_powf(dist, m_fDistSizeFactor);
float fScaleCorona = m_fScaleCorona;
if (obj->m_pLight && obj->m_pLight->m_fCoronaScale)
fScaleCorona *= obj->m_pLight->m_fCoronaScale;
dist *= fScaleCorona * CRenderer::CV_r_coronasizescale;
vx0 = camVecs[1] * dist * 0.1f * m_fVisAreaScale;
vy0 = camVecs[2] * dist * 0.1f * m_fVisAreaScale;
rd->EF_SetState(GS_NOCOLMASK);
CD3D9TexMan::BindNULL(1);
rd->EF_SelectTMU(0);
UCol col;
col.dcolor = -1;
int nOffs;
struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)rd->GetVBPtr3D(4, nOffs);
vQuad[0].xyz = or + vx0 + vy0;
vQuad[0].st[0] = 0.0f; vQuad[0].st[1] = 0.0f;
vQuad[0].color = col;
vQuad[1].xyz = or + vx0 - vy0;
vQuad[1].st[0] = 0.0f; vQuad[1].st[1] = 1.0f;
vQuad[1].color = col;
vQuad[2].xyz = or - vx0 - vy0;
vQuad[2].st[0] = 1.0f; vQuad[2].st[1] = 1.0f;
vQuad[2].color = col;
vQuad[3].xyz = or - vx0 + vy0;
vQuad[3].st[0] = 1.0f; vQuad[3].st[1] = 0.0f;
vQuad[3].color = col;
rd->UnlockVB3D();
pVizQuery->Issue (D3DISSUE_BEGIN);
// Bind our vertex as the first data stream of our device
dv->SetStreamSource(0, rd->m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F));
rd->EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F);
// Render the 2 triangles from the data stream
dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2);
pVizQuery->Issue (D3DISSUE_END);
//bVis = pRE->m_nVisSamples > 10 ? true : false;
Vec3 ProjV[4];
for (int n=0; n<4; n++)
{
D3DXVec3Project((D3DXVECTOR3 *)&ProjV[n], (D3DXVECTOR3 *)&vQuad[n].xyz, &D3DVP, (D3DXMATRIX *)projMatr.GetData(), (D3DXMATRIX *)camMatr.GetData(), &mIdent);
}
float nX = fabsf(ProjV[1].x - ProjV[0].x);
float nY = fabsf(ProjV[2].y - ProjV[0].y);
float area = nX * nY; //(float)(gRenDev->GetWidth() * gRenDev->GetHeight());
fIntens = (float)pRE->m_nVisSamples / area;
fIntens *= fFade;
if (fIntens < 0.05f)
fIntens = 0;
else
if (bRays)
fIntens = max(0.75f, fIntens);
obj->m_AmbColor[0] = obj->m_AmbColor[1];
obj->m_AmbColor[1] = obj->m_AmbColor[2];
obj->m_AmbColor[2] = obj->m_TempVars[3];
obj->m_TempVars[3] = obj->m_Angs2[0];
obj->m_Angs2[0] = obj->m_Angs2[1];
obj->m_Angs2[1] = obj->m_Angs2[2];
obj->m_Angs2[2] = obj->m_TempVars[4];
obj->m_TempVars[4] = fIntens;
}
}
}
else
{
obj->m_AmbColor[0] = obj->m_AmbColor[1];
obj->m_AmbColor[1] = obj->m_AmbColor[2];
obj->m_AmbColor[2] = obj->m_TempVars[3];
obj->m_TempVars[3] = obj->m_Angs2[0];
obj->m_Angs2[0] = obj->m_Angs2[1];
obj->m_Angs2[1] = obj->m_Angs2[2];
obj->m_Angs2[2] = obj->m_TempVars[4];
obj->m_TempVars[4] = 0;
}
if (fIntens >= 0.05f && bRays)
{
int sizeMask = 64;
int sizeMask2 = sizeMask/2;
if ((rd->m_RP.m_PersFlags & RBPF_HDR) && rd->m_nHDRType == 1)
hr = dv->SetRenderTarget(0, rd->mfGetBackSurface());
int sizeTex = 128;//m_Map->GetWidth();
if (!obj->m_TexId0)
{
byte *data = new byte[sizeMask*sizeMask*4];
char name[128];
sprintf(name, "$AutoCoronas_%d", gcpRendD3D->m_TexGenID++);
STexPic *tp = rd->m_TexMan->CreateTexture(name, sizeMask, sizeMask, 1, FT_NOMIPS | FT_ALLOCATED | FT_HASALPHA, FT2_NODXT | FT2_RENDERTARGET | FT_CLAMP, data, eTT_Base, -1.0f, -1.0f, 0, NULL, 0, eTF_8888);
delete [] data;
obj->m_TexId0 = tp->m_Id;
}
if (!obj->m_TexId1)
{
byte *data = new byte[sizeTex*sizeTex*4];
char name[128];
sprintf(name, "$AutoCoronas_%d", gcpRendD3D->m_TexGenID++);
STexPic *tp = rd->m_TexMan->CreateTexture(name, sizeTex, sizeTex, 1, FT_NOMIPS | FT_ALLOCATED | FT_HASALPHA, FT2_NODXT | FT2_RENDERTARGET, data, eTT_Base, -1.0f, -1.0f, 0, NULL, 0, eTF_8888);
delete [] data;
obj->m_TexId1 = tp->m_Id;
}
rd->EF_PushFog();
rd->EnableFog(false);
rd->m_matProj->Push();
D3DXMatrixOrthoRH(rd->m_matProj->GetTop(), (float)rd->GetWidth(), (float)rd->GetHeight(), -20.0, 0.0);
dv->SetTransform(D3DTS_PROJECTION, rd->m_matProj->GetTop());
rd->PushMatrix();
rd->m_matView->LoadIdentity();
dv->SetTransform(D3DTS_VIEW, rd->m_matView->GetTop());
rd->SetCullMode(R_CULL_NONE);
rd->SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0);
gRenDev->m_TexMan->m_Text_White->Set();
float fsizeMask2 = (float)sizeMask2;
// set alpha to 0
{
rd->EF_SetState(GS_NODEPTHTEST);
rd->DrawQuad(vScr.x-fsizeMask2, vScr.y-fsizeMask2, vScr.x+fsizeMask2, vScr.y+fsizeMask2, CFColor(0.0f));
}
// Set alpha mask of visible areas (1 is visible)
{
rd->EF_SetState(0);
rd->DrawQuad(vScr.x-fsizeMask2, vScr.y-fsizeMask2, vScr.x+fsizeMask2, vScr.y+fsizeMask2, CFColor(1.0f));
}
// Read z-mask to target texture 0 as source for bluring
RECT rc = {max((int)vScr.x-sizeMask2+1, vp[0]), max((int)vScr.y-sizeMask2+1,vp[1]), min((int)vScr.x+sizeMask2,vp[2]-1), min((int)vScr.y+sizeMask2,vp[3]-1)};
if((rc.right - rc.left) > 0 && rc.bottom - rc.top >0)
{
STexPic *t = (STexPic *)rd->m_TexMan->m_Textures[obj->m_TexId0];
IDirect3DTexture9 * pID3DTexture = (IDirect3DTexture9 * )t->m_RefTex.m_VidTex;
if(pID3DTexture)
{
IDirect3DSurface9 * pTexSurf;
pID3DTexture->GetSurfaceLevel(0, &pTexSurf);
IDirect3DSurface9 * pTar = rd->mfGetBackSurface();
dv->StretchRect(pTar, &rc, pTexSurf, NULL, D3DTEXF_NONE);
pTexSurf->Release();
}
}
// Scale factor
obj->m_TempVars[1] = 8.0f;
int nPasses = 32;
float fSizeTex = (float)sizeTex;
// Result blured texture size
obj->m_TempVars[2] = fSizeTex;
float fScale = fScaleCorona * obj->m_TempVars[1];
float fDif = fSizeTex / (float)sizeMask;
float fSizeTex2 = fSizeTex / 2.0f;
float fLast = fSizeTex2 / (fScale * fDif);
float fCur = fSizeTex2 * 2;
float fDelt = (fLast - fCur) / (float)nPasses;
float fCurAlpha = 0.0f;
float fDeltAlpha = 1.0f / (float)nPasses;
float fPosx = (float)(rd->GetWidth()/2);
float fPosy = (float)(rd->GetHeight()/2);
rd->EF_SetState(GS_COLMASKONLYALPHA | GS_NODEPTHTEST);
gRenDev->m_TexMan->m_Text_White->Set();
rd->DrawQuad(fPosx-fSizeTex2, fPosy-fSizeTex2, fPosx+fSizeTex2, fPosy+fSizeTex2, CFColor(0.2f));
//gRenDev->SetTexture(obj->m_TexId0, eTT_Base);
STexPic *t = (STexPic *)rd->m_TexMan->m_Textures[obj->m_TexId0];
rd->SetTexture(t->m_Bind, eTT_Base);
// Radially blur the alpha texture
for (int pass=0; pass<nPasses; pass++)
{
rd->EF_SetState(GS_COLMASKONLYALPHA | GS_BLSRC_ONE | GS_BLDST_ONE | GS_NODEPTHTEST);
// for inverse color
//gRenDev->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
rd->DrawQuad(fPosx-fCur, fPosy-fCur, fPosx+fCur, fPosy+fCur, CFColor(fDeltAlpha));
fCur += fDelt;
fCurAlpha += fDeltAlpha;
}
// Generate blured alpha texture without mip-maps
{
RECT rc = {max((int)(fPosx-fSizeTex2)+1, vp[0]), max((int)(fPosy-fSizeTex2)+1,vp[1]), min((int)(fPosx+fSizeTex2),vp[2]-1), min((int)(fPosy+fSizeTex2),vp[3]-1)};
if((rc.right - rc.left) > 0 && rc.bottom - rc.top >0)
{
STexPic *t = (STexPic *)rd->m_TexMan->m_Textures[obj->m_TexId1];
IDirect3DTexture9 * pID3DTexture = (IDirect3DTexture9 * )t->m_RefTex.m_VidTex;
if(pID3DTexture)
{
IDirect3DSurface9 * pTexSurf;
pID3DTexture->GetSurfaceLevel(0, &pTexSurf);
IDirect3DSurface9 * pTar = rd->mfGetBackSurface();
HRESULT hr = dv->StretchRect(pTar, &rc, pTexSurf, NULL, D3DTEXF_NONE);
pTexSurf->Release();
}
}
}
rd->PopMatrix();
rd->m_matProj->Pop();
dv->SetTransform(D3DTS_PROJECTION, rd->m_matProj->GetTop());
rd->EF_PopFog();
rd->SetTexture(0, eTT_Base);
if ((rd->m_RP.m_PersFlags & RBPF_HDR) && rd->m_nHDRType == 1)
hr = dv->SetRenderTarget(0, rd->m_pHDRTargetSurf);
}
dv->SetTransform(D3DTS_VIEW, rd->m_matView->GetTop());
dv->SetTransform(D3DTS_PROJECTION, rd->m_matProj->GetTop());
}
return true;
}
void CREFlare::mfDrawCorona(SShader *ef, CFColor &col)
{
CD3D9Renderer *rd = gcpRendD3D;
LPDIRECT3DDEVICE9 dv = rd->mfGetD3DDevice();
Vec3d vx0, vy0, vx1, vy1, or, v, norm;
if (m_Importance > CRenderer::CV_r_coronas)
return;
CCObject *obj = rd->m_RP.m_pCurObject;
or = obj->GetTranslation();
bool bSun = false;
if (obj->m_ObjFlags & FOB_DRSUN)
{
bSun = true;
//or.Normalize();
//or *= 500.0f;
//or += gRenDev->m_RP.m_ViewOrg;
}
if (bSun && rd->m_bHeatVision)
return;
vx0 = rd->m_RP.m_CamVecs[1];
vx1 = vx0;
vy0 = rd->m_RP.m_CamVecs[2];
vy1 = vy0;
v = or - rd->m_RP.m_ViewOrg;
//Vec3d cn = v.normalize();
//or = cn * 512;
float dist = v.Length();
float distX = dist;
if (m_fDistSizeFactor != 1.0f)
distX = cry_powf(distX, m_fDistSizeFactor);
float distY = distX;
float fScaleCorona = m_fScaleCorona;
if (m_pScaleCoronaParams)
fScaleCorona = m_pScaleCoronaParams->mfGet();
if (obj->m_pLight && obj->m_pLight->m_fCoronaScale)
fScaleCorona *= obj->m_pLight->m_fCoronaScale;
if (obj->m_TempVars[2])
{
distX *= fScaleCorona * (obj->m_TempVars[2]/128.0f) * CRenderer::CV_r_coronasizescale;
distY *= fScaleCorona * (obj->m_TempVars[2]/128.0f) * CRenderer::CV_r_coronasizescale;
}
else
{
distX *= fScaleCorona * CRenderer::CV_r_coronasizescale;
distY *= fScaleCorona * CRenderer::CV_r_coronasizescale;
}
if (rd->m_RP.m_PersFlags & RBPF_HDR)
{
//distX *= 0.25f;
//distY *= 0.25f;
}
float fDecay = col[3];
fDecay *= CRenderer::CV_r_coronacolorscale;
norm = rd->m_RP.m_CamVecs[0];
bool bBlind = false;
if (m_bBlind && obj->m_pLight)
{
CDLight *dl = obj->m_pLight;
if (dl->m_Flags & DLF_PROJECT)
{
bBlind = true;
v.Normalize();
float fDot = -(v * dl->m_Orientation.m_vForward);
if (fDot < 0.0f)
return;
float fBlindSize = fDot * m_fSizeBlindScale + m_fSizeBlindBias;
float fBlindIntens = fDot * m_fIntensBlindScale + m_fIntensBlindBias;
fDecay *= fBlindIntens;
distX *= fBlindSize;
distY *= fBlindSize;
/*
vx0 += distX * dl->m_Orientation.m_vForward;
vy0 += distY * dl->m_Orientation.m_vForward;
vx1 += distX * -dl->m_Orientation.m_vForward;
vy1 += distY * -dl->m_Orientation.m_vForward;
*/
vx0 *= distX;// * dl->m_Orientation.m_vForward;
vy0 *= distY;// * dl->m_Orientation.m_vForward;
vx1 *= -distX;// * -dl->m_Orientation.m_vForward;
vy1 *= -distY;// * -dl->m_Orientation.m_vForward;
float fDot1 = (rd->m_RP.m_CamVecs[1] * dl->m_Orientation.m_vForward);
float k=0.1f;
fDot1 = fDot1*(1.0f-k) + k;
vx0 *= fDot1+1.0f;
vx1 *= 1.0f - fDot1 + k;
float fDot2 = (rd->m_RP.m_CamVecs[2] * dl->m_Orientation.m_vForward);
fDot2 = fDot2*(1.0f-k) + k;
vy0 *= fDot2+1.0f;
vy1 *= 1.0f - fDot2 + k;
}
}
if (!bBlind)
{
vx0 *= distX;
vy0 *= distY;
vx1 *= -distX;
vy1 *= -distY;
}
if (m_fDistIntensityFactor != 1.0f)
fDecay = fDecay * cry_powf(dist, m_fDistIntensityFactor);
if (fDecay <= 0.001f)
return;
else
if (fDecay > 1.0f)
fDecay = 1.0f;
CD3D9TexMan::BindNULL(1);
rd->EF_SelectTMU(0);
rd->D3DSetCull(eCULL_None);
rd->EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0);
if (rd->m_RP.m_TexStages[0].TCIndex != 0)
{
rd->m_RP.m_TexStages[0].TCIndex = 0;
dv->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
}
CFColor c;
float fMax = max(col.r, max(col.b, col.g));
if (fMax > 1.0f)
col.NormalizeCol(c);
else
c = col;
if (m_Pass)
{
int St = m_Pass->m_RenderState & GS_BLEND_MASK;
if (St == (GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA))
{
c[3] = fDecay;
}
else
{
c[0] = c[0] * fDecay;
c[1] = c[1] * fDecay;
c[2] = c[2] * fDecay;
}
}
else
{
if (bSun)
{
c[0] = c[0] * fDecay;
c[1] = c[1] * fDecay;
c[2] = c[2] * fDecay;
c[3] = fDecay;
}
else
{
c[0] = c[0] * fDecay;
c[1] = c[1] * fDecay;
c[2] = c[2] * fDecay;
}
}
if (CRenderer::CV_r_SunStyleCoronas)
bSun = true;
bool bRays = CRenderer::CV_r_checkSunVis == 2 && bSun;
rd->EF_PushFog();
rd->EnableFog(false);
CCGPShader_D3D *fpDrawFlare = NULL;
if ((rd->m_RP.m_PersFlags & RBPF_HDR) && rd->m_nHDRType == 1)
{
if (!rd->m_RP.m_PS_HDR_DrawFlare)
rd->m_RP.m_PS_HDR_DrawFlare = CPShader::mfForName("CGRC_HDR_DrawFlare_PS20");
fpDrawFlare = (CCGPShader_D3D *)rd->m_RP.m_PS_HDR_DrawFlare;
if (fpDrawFlare)
fpDrawFlare->mfSet(true, 0);
}
//if (CRenderer::CV_r_checkSunVis == 1 || CRenderer::CV_r_checkSunVis == 3 || !bSun || obj->m_TexId1<=0)
{
if (bRays)
rd->EF_SetState(GS_BLSRC_ONE | GS_BLDST_ONE);
else
rd->EF_SetState(GS_BLSRC_ONE | GS_BLDST_ONE | GS_NODEPTHTEST);
if (m_Map)
m_Map->Set();
int nOffs;
struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)rd->GetVBPtr3D(10, nOffs);
if (vQuad)
{
DWORD col = D3DRGBA(c.r, c.g, c.b, c.a);
vQuad[0].xyz = or;
vQuad[0].st[0] = 0.5f; vQuad[0].st[1] = 0.5f;
vQuad[0].color.dcolor = col;
vQuad[1].xyz = or + vx0 + vy0;
vQuad[1].st[0] = 0.0f; vQuad[1].st[1] = 0.0f;
vQuad[1].color.dcolor = col;
vQuad[2].xyz = or + vx0;
vQuad[2].st[0] = 0.0f; vQuad[2].st[1] = 0.5f;
vQuad[2].color.dcolor = col;
vQuad[3].xyz = or + vx0 + vy1;
vQuad[3].st[0] = 0.0f; vQuad[3].st[1] = 1.0f;
vQuad[3].color.dcolor = col;
vQuad[4].xyz = or + vy1;
vQuad[4].st[0] = 0.5f; vQuad[4].st[1] = 1.0f;
vQuad[4].color.dcolor = col;
vQuad[5].xyz = or + vx1 + vy1;
vQuad[5].st[0] = 1.0f; vQuad[5].st[1] = 1.0f;
vQuad[5].color.dcolor = col;
vQuad[6].xyz = or + vx1;
vQuad[6].st[0] = 1.0f; vQuad[6].st[1] = 0.5f;
vQuad[6].color.dcolor = col;
vQuad[7].xyz = or + vx1 + vy0;
vQuad[7].st[0] = 1.0f; vQuad[7].st[1] = 0.0f;
vQuad[7].color.dcolor = col;
vQuad[8].xyz = or + vy0;
vQuad[8].st[0] = 0.5f; vQuad[8].st[1] = 0.0f;
vQuad[8].color.dcolor = col;
vQuad[9].xyz = or + vx0 + vy0;
vQuad[9].st[0] = 0.0f; vQuad[9].st[1] = 0.0f;
vQuad[9].color.dcolor = col;
rd->UnlockVB3D();
// Bind our vertex as the first data stream of our device
dv->SetStreamSource(0, gcpRendD3D->m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F));
rd->EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F);
// Render the 8 triangles from the data stream
if (m_Pass && m_Pass->m_TUnits.Num())
{
CVProgram *curVP = NULL;
CVProgram *newVP;
SShaderPassHW *slw = m_Pass;
newVP = slw->m_VProgram;
if (newVP)
rd->m_RP.m_FlagsPerFlush |= RBSI_USEVP;
if (slw->mfSetTextures())
{
// Set vertex program for the current pass if needed
if (newVP != curVP)
{
if (newVP)
{
curVP = newVP;
curVP->mfSet(true, slw, VPF_DONTSETMATRICES);
}
else
curVP = NULL;
}
rd->EF_ApplyMatrixOps(slw->m_MatrixOps, true);
// Set Render states for the current pass
int State;
if (rd->m_RP.m_RendPass || (rd->m_RP.m_ObjFlags & FOB_LIGHTPASS))
State = slw->m_SecondRenderState;
else
State = slw->m_RenderState;
rd->EF_SetState(State);
if (curVP)
{
curVP->mfSetStateMatrices();
curVP->mfSetVariables(false, &slw->m_VPParamsNoObj);
curVP->mfSetVariables(true, &slw->m_VPParamsObj);
}
else
{
rd->m_RP.m_CurrentVLights = 0;
rd->m_RP.m_PersFlags &= ~RBPF_VSNEEDSET;
}
// Set Pixel shaders and Register combiners for the current pass
if (slw->m_FShader)
slw->m_FShader->mfSet(true, slw);
else
rd->m_RP.m_PersFlags &= ~RBPF_PS1NEEDSET;
if (slw->m_FShader)
slw->m_FShader->mfSetVariables(true, slw->m_CGFSParamsObj);
else
rd->EF_CommitTexStageState();
rd->m_RP.m_RendPass++;
int bFogOverrided = 0;
rd->EF_CommitShadersState();
if (rd->m_FS.m_bEnable)
bFogOverrided = rd->EF_FogCorrection(false, false);
{
PROFILE_FRAME(Draw_ShaderIndexMesh);
dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 8);
}
rd->EF_FogRestore(bFogOverrided);
}
slw->mfResetTextures();
rd->EF_ApplyMatrixOps(slw->m_MatrixOps, false);
}
else
dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 8);
}
}
if (fpDrawFlare)
fpDrawFlare->mfSet(false, 0);
//else
if (bRays)
{
rd->EF_SetState(GS_BLSRC_ONE | GS_BLDST_ONE | GS_NODEPTHTEST);
rd->EF_SelectTMU(0);
rd->EnableTMU(true);
m_Map->Set();
rd->EF_SelectTMU(1);
rd->EnableTMU(true);
STexPic *t = (STexPic *)rd->m_TexMan->m_Textures[obj->m_TexId1];
rd->m_TexMan->SetTexture(t->m_Bind, eTT_Base);
CPShader *pRC = PShaderForName(rd->m_RP.m_RCSun, "CGRCSun");
if (pRC)
pRC->mfSet(true);
rd->m_RP.m_FlagsPerFlush |= RBSI_RGBGEN;
int nOffs;
struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)rd->GetVBPtr3D(10, nOffs);
DWORD col = D3DRGBA(c.r, c.g, c.b, c.a);
vQuad[0].xyz = or;
vQuad[0].st[1] = 0.5f; vQuad[0].st[0] = 0.5f;
vQuad[0].color.dcolor = col;
vQuad[1].xyz = or + vx0 + vy0;
vQuad[1].st[1] = 0.0f; vQuad[1].st[0] = 1.0f;
vQuad[1].color.dcolor = col;
vQuad[2].xyz = or + vx0;
vQuad[2].st[1] = 0.0f; vQuad[2].st[0] = 0.5f;
vQuad[2].color.dcolor = col;
vQuad[3].xyz = or + vx0 + vy1;
vQuad[3].st[1] = 0.0f; vQuad[3].st[0] = 0.0f;
vQuad[3].color.dcolor = col;
vQuad[4].xyz = or + vy1;
vQuad[4].st[1] = 0.5f; vQuad[4].st[0] = 0.0f;
vQuad[4].color.dcolor = col;
vQuad[5].xyz = or + vx1 + vy1;
vQuad[5].st[1] = 1.0f; vQuad[5].st[0] = 0.0f;
vQuad[5].color.dcolor = col;
vQuad[6].xyz = or + vx1;
vQuad[6].st[1] = 1.0f; vQuad[6].st[0] = 0.5f;
vQuad[6].color.dcolor = col;
vQuad[7].xyz = or + vx1 + vy0;
vQuad[7].st[1] = 1.0f; vQuad[7].st[0] = 1.0f;
vQuad[7].color.dcolor = col;
vQuad[8].xyz = or + vy0;
vQuad[8].st[1] = 0.5f; vQuad[8].st[0] = 1.0f;
vQuad[8].color.dcolor = col;
vQuad[9].xyz = or + vx0 + vy0;
vQuad[9].st[1] = 0.0f; vQuad[9].st[0] = 1.0f;
vQuad[9].color.dcolor = col;
rd->UnlockVB3D();
// Bind our vertex as the first data stream of our device
dv->SetStreamSource(0, gcpRendD3D->m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F));
rd->EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F);
// Render the 8 triangles from the data stream
dv->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
rd->m_RP.m_TexStages[1].TCIndex = 0;
dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 8);
if (pRC)
pRC->mfSet(false);
rd->EnableTMU(false);
rd->EF_SelectTMU(0);
}
rd->m_nPolygons += 8;
rd->EF_PopFog();
}
void CREFlare::mfDrawFlares(SShader *ef, CFColor &col)
{
CSunFlares *lfl = ef->m_Flares;
CD3D9Renderer *rd = gcpRendD3D;
int i;
SSunFlare *fl;
Vec3d lv;
if (!CRenderer::CV_r_flares || !lfl)
return;
CCObject *obj = rd->m_RP.m_pCurObject;
Vec3d or = obj->GetTranslation();
if (obj->m_ObjFlags & FOB_DRSUN)
{
if (rd->m_bHeatVision)
return;
}
Vec3d vFromPt = rd->m_RP.m_ViewOrg;
Vec3d vViewVec = rd->m_RP.m_CamVecs[0];
Vec3d vLightVec = or - vFromPt;
vLightVec.Normalize();
// Compute the vector and center point for the lens flare axis
float fDot = vLightVec | vViewVec;
if (fDot <= 0.2f)
return;
Vec3d vNewLightPt = vFromPt + 1.0f/fDot * vLightVec;
Vec3d vCenterPt = vFromPt + vViewVec;
Vec3d vAxisVec = vNewLightPt - vCenterPt;
// Store the lens flares positions for each flare
for (i=0; i<lfl->m_NumFlares; i++)
{
fl = &lfl->m_Flares[i];
// Store the position of the flare along the axis
fl->m_Position = vCenterPt + vAxisVec * fl->m_Loc;
// Store the render size of the flare. This is the lens flare size
// corrected for the orientation of the flaring axis.
fl->m_RenderSize = fl->m_Scale;//fViewScale * fl->scale;
}
rd->EF_SelectTMU(0);
rd->EF_SetState(GS_BLSRC_ONE | GS_BLDST_ONE | GS_NODEPTHTEST);
rd->SetCullMode(R_CULL_NONE);
rd->SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0);
Vec3d VecX = rd->m_RP.m_CamVecs[1];
Vec3d VecY = rd->m_RP.m_CamVecs[2];
Vec3d v;
fDot *= col.a;
// Do the flares
for (i=0; i<lfl->m_NumFlares; i++)
{
fl = &lfl->m_Flares[i];
Vec3d vx = VecX * fl->m_RenderSize;
Vec3d vy = VecY * fl->m_RenderSize;
CFColor col = fl->m_Color * fDot;
fl->m_Tex->Set();
rd->DrawQuad3D(fl->m_Position+vx+vy, fl->m_Position-vx+vy, fl->m_Position-vx-vy, fl->m_Position+vx-vy, col);
rd->m_nPolygons += 2;
}
}
static float sInterpolate(float& pprev, float& prev, float& next, float& nnext, float ppweight, float pweight, float nweight, float nnweight)
{
return pprev*ppweight + prev*pweight + next*nweight + nnext*nnweight;
}
static float sSpline(float x)
{
float fX = fabsf(x);
if(fX > 2.0f)
return 0;
if(fX > 1.0f)
return (2.0f-fX)*(2.0f-fX)*(2.0f-fX)/6.0f;
return 2.0f/3.0f-fX*fX+0.5f*fX*fX*fX;
}
static float *sObjBright(float fTime, CCObject *obj)
{
if (fTime <= obj->m_Angs2[0])
return &obj->m_AmbColor[0];
if (fTime <= obj->m_Angs2[1])
return &obj->m_AmbColor[1];
if (fTime <= obj->m_Angs2[2])
return &obj->m_AmbColor[2];
return &obj->m_fHeatFactor;
}
bool CREFlare::mfDraw(SShader *ef, SShaderPass *sfm)
{
CD3D9Renderer *rd = gcpRendD3D;
LPDIRECT3DDEVICE9 dv = rd->mfGetD3DDevice();
if (!CRenderer::CV_r_flares && m_Importance > CRenderer::CV_r_coronas)
return false;
dv->SetTransform(D3DTS_VIEW, (D3DMATRIX *)rd->m_CameraMatrix.GetData());
CCObject *obj = rd->m_RP.m_pCurObject;
if ((obj->m_ObjFlags & FOB_DRSUN) && (rd->m_RP.m_PersFlags & RBPF_DONTDRAWSUN))
return false;
float fBrightness = (obj->m_AmbColor[0]+obj->m_AmbColor[1]+obj->m_AmbColor[2]+
obj->m_Angs2[0]+obj->m_Angs2[1]+obj->m_Angs2[2]+
obj->m_TempVars[3]+obj->m_TempVars[4]) * 0.125f;
if (!fBrightness)
return false;
obj->m_Color.r = m_Color.r;
obj->m_Color.g = m_Color.g;
obj->m_Color.b = m_Color.b;
obj->m_Color.a = fBrightness; //ft;
mfDrawCorona(ef, obj->m_Color);
mfDrawFlares(ef, obj->m_Color);
return true;
}
void CLeafBuffer::DrawImmediately()
{
}
bool CREClearStencil::mfDraw(SShader *ef, SShaderPass *sfm)
{
gcpRendD3D->m_pd3dDevice->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 1.0f, 0);
return true;
}
bool CREHDRProcess::mfDraw(SShader *ef, SShaderPass *sfm)
{
assert (gcpRendD3D->m_RP.m_PersFlags & RBPF_HDR);
assert(gcpRendD3D->m_pHDRTargetSurf);
if (!(gcpRendD3D->m_RP.m_PersFlags & RBPF_HDR))
return false;
if (!gcpRendD3D->m_pHDRTargetSurf)
return false;
gcpRendD3D->EF_HDRPostProcessing();
return true;
}