DragonNest/Common/EternityEngine/EtWater.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

258 lines
7.7 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "EtWater.h"
#include "EtSaveMat.h"
#include "EtOptionController.h"
#include "EtRenderStack.h"
#include "EtCamera.h"
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
CEtWater *g_pEtWater = NULL;
CEtWater *GetEtWater()
{
return g_pEtWater;
}
void DeleteWaterMap()
{
SAFE_DELETE( g_pEtWater );
}
void CreateSimpleWaterMap( int nCount )
{
SAFE_DELETE( g_pEtWater );
g_pEtWater = new CEtWater;
g_pEtWater->Initialize( nCount );
}
CEtWater::CEtWater(void)
{
m_fWaterBakeTime = 0.f;
EtMatrixIdentity(&m_WaterBakeViewParam);
EtMatrixIdentity(&m_WaterBakeLastView);
memset( m_fAveDeltaTime, 0, sizeof(m_fAveDeltaTime) );
m_nDeltaIndex = 0;
m_bOptimize = false;
m_pBackupDepthTarget = NULL;
m_pBackupRenderTarget = NULL;
SecureZeroMemory( &m_BackupViewport, sizeof(m_BackupViewport) );
}
CEtWater::~CEtWater(void)
{
Clear();
}
void CEtWater::Clear()
{
int i, nSize;
nSize = (int)m_WaterResources.size();
for( i = 0; i < nSize; i++) {
SAFE_RELEASE_SPTR( m_WaterResources[i].hWaterMap );
}
m_WaterResources.clear();
SAFE_RELEASE_SPTR( m_hWaterMapDepth );
}
void CEtWater::Initialize( int nCount )
{
Clear();
SGraphicOption Option;
GetEtOptionController()->GetGraphicOption( Option );
m_nWaterMapSize = 512;
switch( Option.WaterQuality )
{
case WQ_HIGH:
m_nWaterMapSize = 1024;
break;
case WQ_NORMAL:
case WQ_LOW:
m_nWaterMapSize = 512;
break;
}
m_WaterResources.resize( nCount );
for( int i = 0; i < nCount; i++) {
m_WaterResources[i].hWaterMap = CEtTexture::CreateRenderTargetTexture( m_nWaterMapSize, m_nWaterMapSize, FMT_A8R8G8B8 );
}
SAFE_RELEASE_SPTR( m_hWaterMapDepth );
m_hWaterMapDepth = CEtDepth::CreateDepthStencil( m_nWaterMapSize, m_nWaterMapSize );
GetCurRenderStack()->SetWaterCount( nCount );
}
EtMatrix CEtWater::GetViewProjMat(int index)
{
EtPlane WaterPlane(0, 1, 0, -m_WaterResources[index].fWaterHeight );
EtMatrix ReflectMat;
EtCameraHandle hCamera = CEtCamera::GetActiveCamera();
if( hCamera )
{
EtMatrix MatWaterProj;
EtMatrix CamMat = *hCamera->GetInvViewMat();
EtMatrixReflect(&ReflectMat, &WaterPlane );
EtMatrixMultiply(&ReflectMat, &CamMat, &ReflectMat );
EtMatrixInverse(&ReflectMat, 0, &ReflectMat);
// <20><><EFBFBD><EFBFBD> 20<32><30><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20>ø<EFBFBD>..
EtMatrixPerspectiveFovLH( &MatWaterProj, hCamera->GetFOV(), hCamera->GetAspectRatio(), hCamera->GetCameraNear(), hCamera->GetCameraFar() * hCamera->GetWaterFarRatio() );
EtMatrixMultiply(&ReflectMat, &ReflectMat, &MatWaterProj );
}
else {
EtMatrixIdentity(&ReflectMat);
}
return ReflectMat;
}
void CEtWater::BeginWater( int index )
{
m_pBackupRenderTarget = GetEtDevice()->GetRenderTarget();
m_pBackupDepthTarget = GetEtDevice()->GetDepthStencilSurface();
GetEtDevice()->SetRenderTarget( m_WaterResources[index].hWaterMap->GetSurfaceLevel() );
GetEtDevice()->SetDepthStencilSurface( m_hWaterMapDepth->GetDepthBuffer() );
GetEtDevice()->SetCullMode( CULL_CW );
GetEtDevice()->ClearBuffer( 0xffffffff, 1.0f, 0 );
GetEtSaveMat()->EnableSaveTransMat( false );
EtPlane WaterPlane(0, 1, 0, -m_WaterResources[index].fWaterHeight);
const float fDummyHeight = 30.f;
m_BackupCamMat = *CEtCamera::GetActiveCamera()->GetInvViewMat();
EtMatrix ReflectMat, CamMat = m_BackupCamMat;
if( CamMat._42 < m_WaterResources[index].fWaterHeight+fDummyHeight+1.f ) {
CamMat._42 = m_WaterResources[index].fWaterHeight+fDummyHeight+1.f;
}
EtMatrixReflect(&ReflectMat, &WaterPlane );
EtMatrixMultiply(&ReflectMat, &CamMat, &ReflectMat );
CEtCamera::GetActiveCamera()->Update( &ReflectMat );
GetEtDevice()->GetViewport( &m_BackupViewport );
EtViewPort waterViewport;
waterViewport.X = 0;
waterViewport.Y = 0;
waterViewport.Width = m_nWaterMapSize;
waterViewport.Height = m_nWaterMapSize;
waterViewport.MinZ = 0;
waterViewport.MaxZ = 1;
GetEtDevice()->SetViewport( &waterViewport );
EtPlane ClipPlane;
// WaterPlane.d += fDummyHeight;
D3DXVECTOR3 v1(0, 0, 0);
D3DXVECTOR3 v2(100000.f, 0, 0);
D3DXVECTOR3 v3(0, 0, 100000.f);
v1.y = -(D3DXVec3Dot(&v1, (D3DXVECTOR3*)&WaterPlane) + WaterPlane.d ) / WaterPlane.b;
v2.y = -(D3DXVec3Dot(&v2, (D3DXVECTOR3*)&WaterPlane) + WaterPlane.d ) / WaterPlane.b;
v3.y = -(D3DXVec3Dot(&v3, (D3DXVECTOR3*)&WaterPlane) + WaterPlane.d ) / WaterPlane.b;
EtMatrix ViewProjMat = *CEtCamera::GetActiveCamera()->GetViewProjMat();
D3DXVec3TransformCoord(&v1, &v1, &ViewProjMat );
D3DXVec3TransformCoord(&v2, &v2, &ViewProjMat );
D3DXVec3TransformCoord(&v3, &v3, &ViewProjMat );
D3DXPlaneFromPoints(&ClipPlane, &v1, &v2, &v3);
if(ClipPlane.c < 0.f) {
ClipPlane = -ClipPlane;
}
((IDirect3DDevice9*)GetEtDevice()->GetDevicePtr())->SetClipPlane(0, (float*)&ClipPlane);
GetEtDevice()->SetRenderState( D3DRS_CLIPPLANEENABLE, D3DCLIPPLANE0);
}
void CEtWater::EndWater(int index)
{
GetEtDevice()->SetRenderState( D3DRS_CLIPPLANEENABLE, 0);
GetEtDevice()->SetViewport( &m_BackupViewport );
CEtCamera::GetActiveCamera()->Update( &m_BackupCamMat );
GetEtDevice()->SetCullMode( CULL_CCW );
GetEtDevice()->SetRenderTarget( m_pBackupRenderTarget );
GetEtDevice()->SetDepthStencilSurface( m_pBackupDepthTarget );
GetEtSaveMat()->EnableSaveTransMat( true );
}
void CEtWater::Bake( CEtRenderStack *pRenderStack, float fElapsedTime )
{
const int nElemCount = _countof( m_fAveDeltaTime );
m_fAveDeltaTime[ m_nDeltaIndex++ ] = fElapsedTime;
m_nDeltaIndex %= nElemCount;
float fAveDelta = 0.f;
for( int i = 0; i < _countof(m_fAveDeltaTime); i++) {
fAveDelta += m_fAveDeltaTime[ i ];
}
fAveDelta /= nElemCount;
EtCameraHandle hCamera = CEtCamera::GetActiveCamera();
int nWaterCount = (int)m_WaterResources.size();
if( !m_bOptimize || (1.0f / fAveDelta) >= 60 ) {
m_WaterBakeLastView = m_WaterBakeViewParam = *hCamera->GetViewMat();
for( int i = 0; i < nWaterCount; i++) {
//if( m_WaterResources[i].bIgnoreBake ) continue; // continue<75><65><EFBFBD><EFBFBD> <20><> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD> clear<61><72> <20>ؾ<EFBFBD><D8BE>ϴϱ<CFB4>. <20>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
pRenderStack->Sort( CEtRenderStack::PASS_WATER + i, true);
BeginWater( i );
pRenderStack->RenderBlock( (CEtRenderStack::PassType)(CEtRenderStack::PASS_WATER + i) );
EndWater( i );
}
}
else {
static float fBakeTerm = 1.f / 15.f;
m_fWaterBakeTime += EtMin( fBakeTerm, fElapsedTime );
if( m_fWaterBakeTime >= fBakeTerm ) {
m_fWaterBakeTime -= fBakeTerm;
m_WaterBakeLastView = m_WaterBakeViewParam = *hCamera->GetViewMat();
for( int i = 0; i < nWaterCount; i++) {
//if( m_WaterResources[i].bIgnoreBake ) continue;
pRenderStack->Sort( CEtRenderStack::PASS_WATER + i, true);
BeginWater( i );
pRenderStack->RenderBlock( (CEtRenderStack::PassType)(CEtRenderStack::PASS_WATER + i) );
EndWater( i );
}
}
else {
float fRatio = 1.0f - (m_fWaterBakeTime / fBakeTerm);
EtMatrix currMat = *hCamera->GetViewMat();
EtMatrix lastMat = m_WaterBakeLastView;
D3DXMatrixInverse(&currMat, 0, &currMat);
D3DXMatrixInverse(&lastMat, 0, &lastMat);
EtVector3 vCamPos = *(EtVector3*)&currMat._41;
EtVector3 vCamLastPos = *(EtVector3*)&lastMat._41;
EtVec3Lerp(&vCamPos, &vCamLastPos, &vCamPos, fRatio);
EtMatrix MatCurrent = currMat;
EtMatrix MatLast = lastMat;
MatCurrent._41 = MatCurrent._42 = MatCurrent._43 = 0.f;
MatLast._41 = MatLast._42 = MatLast._43 = 0.f;
EtQuat qCurrent, qLast, q;
EtQuaternionRotationMatrix(&qCurrent, &MatCurrent );
EtQuaternionRotationMatrix(&qLast, &MatLast );
EtQuaternionSlerp( &q, &qLast, &qCurrent, fRatio );
EtMatrix MatResult;
EtMatrixRotationQuaternion( &MatResult, &q );
MatResult._41 = vCamPos.x;
MatResult._42 = vCamPos.y;
MatResult._43 = vCamPos.z;
D3DXMatrixInverse(&MatResult, 0, &MatResult);
m_WaterBakeViewParam = MatResult;
for( int i = 0; i < nWaterCount; i++) {
pRenderStack->ClearElement( CEtRenderStack::PASS_WATER + i );
}
}
}
}