From 5be37b6363650f130cfe7929d591908ae8f30278 Mon Sep 17 00:00:00 2001 From: shenlei Date: Mon, 28 Sep 2026 13:02:31 +0900 Subject: [PATCH] port EterLib LensFlare/ScreenFilter/Decal verbatim (unit C part 1) Co-Authored-By: Claude Opus 5.5 --- audit/history.jsonl | 1 + audit/port-map/EterLib/Decal.cpp.json | 56 ++ audit/port-map/EterLib/LensFlare.cpp.json | 132 ++++ audit/port-map/EterLib/ScreenFilter.cpp.json | 45 ++ extension/src/platform/EterLib/Decal.cpp | 49 -- extension/src/platform/EterLib/LensFlare.cpp | 107 ---- .../src/platform/EterLib/ScreenFilter.cpp | 36 -- extension/src/port/EterLib/Decal.cpp | 287 +++++++++ extension/src/port/EterLib/LensFlare.cpp | 599 ++++++++++++++++++ extension/src/port/EterLib/ScreenFilter.cpp | 52 ++ 10 files changed, 1172 insertions(+), 192 deletions(-) create mode 100644 audit/port-map/EterLib/Decal.cpp.json create mode 100644 audit/port-map/EterLib/LensFlare.cpp.json create mode 100644 audit/port-map/EterLib/ScreenFilter.cpp.json delete mode 100644 extension/src/platform/EterLib/Decal.cpp delete mode 100644 extension/src/platform/EterLib/LensFlare.cpp delete mode 100644 extension/src/platform/EterLib/ScreenFilter.cpp create mode 100644 extension/src/port/EterLib/Decal.cpp create mode 100644 extension/src/port/EterLib/LensFlare.cpp create mode 100644 extension/src/port/EterLib/ScreenFilter.cpp diff --git a/audit/history.jsonl b/audit/history.jsonl index 9d425f6c..3a81719c 100644 --- a/audit/history.jsonl +++ b/audit/history.jsonl @@ -559,3 +559,4 @@ {"date": "2026-09-28T01:35:06+00:00", "unit": "GameLib/MapOutdoorRenderHTP.cpp", "action": "match 40250 lighting state in terrain splat passes: unlit base textures, temporary lit shadow pass, white fog color only for shadow pass", "evidence": "reference MapOutdoorRenderHTP.cpp non-WORLD_EDITOR branch; native fake-server scene rerun pending"} {"date": "2026-09-28T03:54:13+00:00", "unit": "EterLib/GrpScreen.cpp + native D3D8 fixed-function emulation (RecordingDevice / native_render)", "action": "unit A: D3D8 texcoord generation + D3DTS_TEXTUREn in shader (CPU uv baking removed), 8-light D3D lighting (no attenuation clamp, spot theta/2 phi/2, emissive source, NORMALIZENORMALS, inverse-transpose normals), 8-bit alpha test, clears in draw order, dynamic D3D viewport + MinZ/MaxZ, black back-buffer clear, white default diffuse, alpha blend mirrors colour factors; removed sphere-map and multiplicative-shadow hacks; CScreen ms_clearDepth/ms_diffuseColor initialisers fixed to 40250 values; capture v8; --screenshot-out readback", "evidence": "ctest 35/35 (login_live excluded); mt_native_render fake-server 240/900-frame screenshots vs baseline: game frame mean abs diff 0.55/255, char select model now placed by introselect.py grp.SetViewport(270/w,...); Windows reference frame pending (NEEDS_LIVE)"} {"date": "2026-09-28T03:59:30+00:00", "unit": "EterLib/GrpLightManager.cpp", "action": "unit B: platform stub removed, 40250 GrpLightManager.cpp copied verbatim into port/ (port_copy.py); CPythonApplication::Create now calls m_LightManager.Initialize() (40250 :1263) so light IDs start at skip index 1; 40250 never calls FlushLight/RestoreLight, so no device-light change", "evidence": "ctest 35/35 (login_live excluded); fake-server frame 900 vs baseline mean abs diff 0.21/255"} +{"date": "2026-09-28T04:02:30+00:00", "unit": "EterLib/LensFlare.cpp + ScreenFilter.cpp + Decal.cpp", "action": "unit C (part 1): platform stubs removed, 40250 sources copied verbatim (GL code is commented out in 40250 too); CMapOutdoor callers were already ported, so lens flare, screen filter and CDecal clipping (TerrainDecal) now run", "evidence": "ctest 35/35 (login_live excluded); fake-server frame 900 vs unit B mean abs diff 0.014/255; flare/filter visuals NEEDS_LIVE"} diff --git a/audit/port-map/EterLib/Decal.cpp.json b/audit/port-map/EterLib/Decal.cpp.json new file mode 100644 index 00000000..c733952e --- /dev/null +++ b/audit/port-map/EterLib/Decal.cpp.json @@ -0,0 +1,56 @@ +{ + "reference": "EterLib/Decal.cpp", + "reference_sha256": "eb168acde9da2224ef64d6dee14ccc675ee0e633e8d843f2d02ad905d016391a", + "priority": "P4", + "contracts": [], + "functions": { + "CDecal::CDecal": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/Decal.cpp:CDecal::CDecal" + ] + }, + "CDecal::~CDecal": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/Decal.cpp:CDecal::~CDecal" + ] + }, + "CDecal::Clear": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/Decal.cpp:CDecal::Clear" + ] + }, + "CDecal::ClipMesh": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/Decal.cpp:CDecal::ClipMesh" + ] + }, + "CDecal::AddPolygon": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/Decal.cpp:CDecal::AddPolygon" + ] + }, + "CDecal::ClipPolygon": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/Decal.cpp:CDecal::ClipPolygon" + ] + }, + "CDecal::ClipPolygonAgainstPlane": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/Decal.cpp:CDecal::ClipPolygonAgainstPlane" + ] + }, + "CDecal::Render": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/Decal.cpp:CDecal::Render" + ] + } + } +} diff --git a/audit/port-map/EterLib/LensFlare.cpp.json b/audit/port-map/EterLib/LensFlare.cpp.json new file mode 100644 index 00000000..ac96c4ab --- /dev/null +++ b/audit/port-map/EterLib/LensFlare.cpp.json @@ -0,0 +1,132 @@ +{ + "reference": "EterLib/LensFlare.cpp", + "reference_sha256": "844534f423925fd0250f49f86898da5b02e55882bcca9e972ccba5cabb310cae", + "priority": "P4", + "contracts": [], + "functions": { + "CLensFlare::CLensFlare": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::CLensFlare" + ] + }, + "CLensFlare::~CLensFlare": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::~CLensFlare" + ] + }, + "CLensFlare::Interpolate": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::Interpolate" + ] + }, + "CLensFlare::Compute": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::Compute" + ] + }, + "CLensFlare::DrawBeforeFlare": { + "status": "NEEDS_LIVE", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::DrawBeforeFlare" + ], + "note": "verbatim; on-screen result needs the Windows reference frame" + }, + "CLensFlare::DrawAfterFlare": { + "status": "NEEDS_LIVE", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::DrawAfterFlare" + ], + "note": "verbatim; on-screen result needs the Windows reference frame" + }, + "CLensFlare::SetMainFlare": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::SetMainFlare" + ] + }, + "CLensFlare::DrawFlare": { + "status": "NEEDS_LIVE", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::DrawFlare" + ], + "note": "verbatim; on-screen result needs the Windows reference frame" + }, + "CLensFlare::CharacterizeFlare": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::CharacterizeFlare" + ] + }, + "CLensFlare::Initialize": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::Initialize" + ] + }, + "CLensFlare::SetFlareLocation": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::SetFlareLocation" + ] + }, + "CLensFlare::SetBrightnesses": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::SetBrightnesses" + ] + }, + "CLensFlare::ReadControlPixels": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::ReadControlPixels" + ] + }, + "CLensFlare::AdjustBrightness": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::AdjustBrightness" + ] + }, + "CLensFlare::ReadDepthPixels": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::ReadDepthPixels" + ], + "note": "body is commented out in 40250; kept empty" + }, + "CLensFlare::ClampBrightness": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CLensFlare::ClampBrightness" + ] + }, + "CFlare::CFlare": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CFlare::CFlare" + ] + }, + "CFlare::~CFlare": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CFlare::~CFlare" + ] + }, + "CFlare::Init": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CFlare::Init" + ] + }, + "CFlare::Draw": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/LensFlare.cpp:CFlare::Draw" + ] + } + } +} diff --git a/audit/port-map/EterLib/ScreenFilter.cpp.json b/audit/port-map/EterLib/ScreenFilter.cpp.json new file mode 100644 index 00000000..fb77dd01 --- /dev/null +++ b/audit/port-map/EterLib/ScreenFilter.cpp.json @@ -0,0 +1,45 @@ +{ + "reference": "EterLib/ScreenFilter.cpp", + "reference_sha256": "9a1faf7801b9848d9757a7cbe61903f025e6c7217ed37b2de5208ae97950a289", + "priority": "P4", + "contracts": [], + "functions": { + "CScreenFilter::Render": { + "status": "NEEDS_LIVE", + "impl": [ + "extension/src/port/EterLib/ScreenFilter.cpp:CScreenFilter::Render" + ], + "note": "verbatim full-screen blend quad; on-screen result needs the Windows reference frame" + }, + "CScreenFilter::SetEnable": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/ScreenFilter.cpp:CScreenFilter::SetEnable" + ] + }, + "CScreenFilter::SetBlendType": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/ScreenFilter.cpp:CScreenFilter::SetBlendType" + ] + }, + "CScreenFilter::SetColor": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/ScreenFilter.cpp:CScreenFilter::SetColor" + ] + }, + "CScreenFilter::CScreenFilter": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/ScreenFilter.cpp:CScreenFilter::CScreenFilter" + ] + }, + "CScreenFilter::~CScreenFilter": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/ScreenFilter.cpp:CScreenFilter::~CScreenFilter" + ] + } + } +} diff --git a/extension/src/platform/EterLib/Decal.cpp b/extension/src/platform/EterLib/Decal.cpp deleted file mode 100644 index a1156d1e..00000000 --- a/extension/src/platform/EterLib/Decal.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// Platform skeleton for EterLib/Decal.h (40250 EterLib/Decal.cpp), generated by platform_stub.py. -// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation. -#include "EterLib/StdAfx.h" -#include "EterLib/Decal.h" - -#include "../PlatformStub.h" - -CDecal::CDecal() : m_cfDecalEpsilon(0.25f) // initializers as in 40250 -{ - MT_PLATFORM_STUB(); -} - -CDecal::~CDecal() -{ - MT_PLATFORM_STUB(); -} - -auto CDecal::Clear() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CDecal::Render() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CDecal::AddPolygon(DWORD, const D3DXVECTOR3 *, const D3DXVECTOR3 *) -> bool -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} - -auto CDecal::ClipMesh(DWORD, const D3DXVECTOR3 *, const D3DXVECTOR3 *) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CDecal::ClipPolygon(DWORD, const D3DXVECTOR3 *, const D3DXVECTOR3 *, D3DXVECTOR3 *, D3DXVECTOR3 *) const -> DWORD -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} - -auto CDecal::ClipPolygonAgainstPlane(const D3DXPLANE &, DWORD, const D3DXVECTOR3 *, const D3DXVECTOR3 *, D3DXVECTOR3 *, D3DXVECTOR3 *) -> DWORD -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} diff --git a/extension/src/platform/EterLib/LensFlare.cpp b/extension/src/platform/EterLib/LensFlare.cpp deleted file mode 100644 index 6123b21e..00000000 --- a/extension/src/platform/EterLib/LensFlare.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// Platform skeleton for EterLib/LensFlare.h (40250 EterLib/LensFlare.cpp), generated by platform_stub.py. -// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation. -#include "EterLib/StdAfx.h" -#include "EterLib/LensFlare.h" - -#include "../PlatformStub.h" - -auto CFlare::Draw(float, int, int, int, int) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CFlare::Init(std::string) -> void -{ - MT_PLATFORM_STUB(); -} - -CFlare::CFlare() -{ - MT_PLATFORM_STUB(); -} - -CFlare::~CFlare() -{ - MT_PLATFORM_STUB(); -} - -CLensFlare::CLensFlare() -{ - MT_PLATFORM_STUB(); -} - -CLensFlare::~CLensFlare() -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::Compute(const D3DXVECTOR3 &) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::DrawBeforeFlare() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::DrawAfterFlare() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::DrawFlare() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::SetMainFlare(std::string, float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::Initialize(std::string) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::SetFlareLocation(double, double) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::SetBrightnesses(float, float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::ReadControlPixels() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::AdjustBrightness() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::CharacterizeFlare(bool, bool, float, const D3DXCOLOR &) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::Interpolate(float, float, float) -> float -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} - -auto CLensFlare::ReadDepthPixels(float *) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLensFlare::ClampBrightness() -> void -{ - MT_PLATFORM_STUB(); -} diff --git a/extension/src/platform/EterLib/ScreenFilter.cpp b/extension/src/platform/EterLib/ScreenFilter.cpp deleted file mode 100644 index 2fc184b1..00000000 --- a/extension/src/platform/EterLib/ScreenFilter.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Platform skeleton for EterLib/ScreenFilter.h (40250 EterLib/ScreenFilter.cpp), generated by platform_stub.py. -// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation. -#include "EterLib/StdAfx.h" -#include "EterLib/ScreenFilter.h" - -#include "../PlatformStub.h" - -CScreenFilter::CScreenFilter() -{ - MT_PLATFORM_STUB(); -} - -CScreenFilter::~CScreenFilter() -{ - MT_PLATFORM_STUB(); -} - -auto CScreenFilter::SetEnable(BOOL) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CScreenFilter::SetBlendType(BYTE, BYTE) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CScreenFilter::SetColor(const D3DXCOLOR &) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CScreenFilter::Render() -> void -{ - MT_PLATFORM_STUB(); -} diff --git a/extension/src/port/EterLib/Decal.cpp b/extension/src/port/EterLib/Decal.cpp new file mode 100644 index 00000000..2e42a93c --- /dev/null +++ b/extension/src/port/EterLib/Decal.cpp @@ -0,0 +1,287 @@ +// Decal.cpp: implementation of the CDecal class. +// +////////////////////////////////////////////////////////////////////// + +#include "StdAfx.h" +#include "Decal.h" +#include "StateManager.h" + +////////////////////////////////////////////////////////////////////// +// CDecal +////////////////////////////////////////////////////////////////////// + +CDecal::CDecal():m_cfDecalEpsilon(0.25f) +{ + Clear(); +} + +CDecal::~CDecal() +{ + Clear(); +} + +void CDecal::Clear() +{ + m_v3Center = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_v3Normal = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + + m_v4LeftPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + m_v4RightPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + m_v4TopPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + m_v4BottomPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + m_v4FrontPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + m_v4BackPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + + m_dwVertexCount = 0; + m_dwPrimitiveCount = 0; + + m_TriangleFanStructVector.clear(); + + memset(m_Vertices, 0, sizeof(m_Vertices)); + memset(m_Indices, 0, sizeof(m_Indices)); +} + +void CDecal::ClipMesh(DWORD dwPrimitiveCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 *c_pv3Normal) +{ + D3DXVECTOR3 v3NewVertex[9]; + D3DXVECTOR3 v3NewNormal[9]; + + // Clip one triangle at a time + for(DWORD dwi = 0; dwi < dwPrimitiveCount; ++dwi) + { + const D3DXVECTOR3 & v3_1 = c_pv3Vertex[3 * dwi]; + const D3DXVECTOR3 & v3_2 = c_pv3Vertex[3 * dwi + 1]; + const D3DXVECTOR3 & v3_3 = c_pv3Vertex[3 * dwi + 2]; + + D3DXVECTOR3 v3Cross; + const auto vv_ = (v3_2 - v3_1); + const auto vv_2 = (v3_3 - v3_1); + D3DXVec3Cross(&v3Cross, &vv_, &vv_2); + if (D3DXVec3Dot(&m_v3Normal, &v3Cross) > ( m_cfDecalEpsilon ) * D3DXVec3Length(&v3Cross)) + { + v3NewVertex[0] = v3_1; + v3NewVertex[1] = v3_2; + v3NewVertex[2] = v3_3; + + v3NewNormal[0] = c_pv3Normal[3 * dwi]; + v3NewNormal[1] = c_pv3Normal[3 * dwi + 1]; + v3NewNormal[2] = c_pv3Normal[3 * dwi + 2]; + + DWORD dwCount = ClipPolygon(3, v3NewVertex, v3NewNormal, v3NewVertex, v3NewNormal); + if ((dwCount != 0) && (!AddPolygon(dwCount, v3NewVertex, v3NewNormal))) break; + } + } +} + +bool CDecal::AddPolygon(DWORD dwAddCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 * /*c_pv3Normal */) +{ + if (m_dwVertexCount + dwAddCount >= MAX_DECAL_VERTICES) + return false; + + TTRIANGLEFANSTRUCT aTriangleFanStruct; + aTriangleFanStruct.m_wMinIndex = m_dwVertexCount; + aTriangleFanStruct.m_dwVertexCount = dwAddCount; + aTriangleFanStruct.m_dwPrimitiveCount = dwAddCount - 2; + aTriangleFanStruct.m_dwVBOffset = m_dwVertexCount; + + m_TriangleFanStructVector.push_back(aTriangleFanStruct); + + DWORD dwCount = m_dwVertexCount; + + // Add polygon as a triangle fan + WORD * wIndex = m_Indices + dwCount; + + m_dwPrimitiveCount += dwAddCount - 2; + //float fOne_over_1MinusDecalEpsilon = 1.0f / (1.0f - m_cfDecalEpsilon); + + // Assign vertex colors + for (DWORD dwVertexNum = 0; dwVertexNum < dwAddCount; ++dwVertexNum) + { + *wIndex++ = (WORD) dwCount; + m_Vertices[dwCount].position = c_pv3Vertex[dwVertexNum]; + //const D3DXVECTOR3 & v3Normal = c_pv3Normal[dwVertexNum]; + //float fAlpha = (D3DXVec3Dot(&m_v3Normal, &v3Normal) / D3DXVec3Length(&v3Normal) - m_cfDecalEpsilon) * fOne_over_1MinusDecalEpsilon; + //m_Vertices[dwCount].diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, (fAlpha > 0.0f) ? fAlpha : 0.0f); + m_Vertices[dwCount].diffuse = 0xFFFFFFFF; + ++dwCount; + } + + m_dwVertexCount = dwCount; + return true; +} + +DWORD CDecal::ClipPolygon(DWORD dwVertexCount, + const D3DXVECTOR3 *c_pv3Vertex, + const D3DXVECTOR3 *c_pv3Normal, + D3DXVECTOR3 *c_pv3NewVertex, + D3DXVECTOR3 *c_pv3NewNormal) const +{ + D3DXVECTOR3 v3TempVertex[9]; + D3DXVECTOR3 v3TempNormal[9]; + + // Clip against all six planes + DWORD dwCount = ClipPolygonAgainstPlane(m_v4LeftPlane, dwVertexCount, c_pv3Vertex, c_pv3Normal, v3TempVertex, v3TempNormal); + if (dwCount != 0) + { + dwCount = ClipPolygonAgainstPlane(m_v4RightPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal); + if (dwCount != 0) + { + dwCount = ClipPolygonAgainstPlane(m_v4BottomPlane, dwCount, c_pv3NewVertex, c_pv3NewNormal, v3TempVertex, v3TempNormal); + if (dwCount != 0) + { + dwCount = ClipPolygonAgainstPlane(m_v4TopPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal); + if (dwCount != 0) + { + dwCount = ClipPolygonAgainstPlane(m_v4BackPlane, dwCount, c_pv3NewVertex, c_pv3NewNormal, v3TempVertex, v3TempNormal); + if (dwCount != 0) + { + dwCount = ClipPolygonAgainstPlane(m_v4FrontPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal); + } + } + } + } + } + return dwCount; +} + +DWORD CDecal::ClipPolygonAgainstPlane(const D3DXPLANE& c_rv4Plane, + DWORD dwVertexCount, + const D3DXVECTOR3 *c_pv3Vertex, + const D3DXVECTOR3 *c_pv3Normal, + D3DXVECTOR3 *c_pv3NewVertex, + D3DXVECTOR3 *c_pv3NewNormal) +{ + bool bNegative[10]; + + // Classify vertices + DWORD dwNegativeCount = 0; + for (DWORD dwi = 0; dwi < dwVertexCount; ++dwi) + { + bool bNeg = (D3DXPlaneDotCoord(&c_rv4Plane, &c_pv3Vertex[dwi]) < 0.0F); + bNegative[dwi] = bNeg; + dwNegativeCount += bNeg; + } + + // Discard this polygon if it's completely culled + if (dwNegativeCount == dwVertexCount) + return 0; + + DWORD dwCount = 0; + for (DWORD dwCurIndex = 0; dwCurIndex < dwVertexCount; ++dwCurIndex) + { + // dwPrevIndex is the index of the previous vertex + DWORD dwPrevIndex = (dwCurIndex != 0) ? dwCurIndex - 1 : dwVertexCount - 1; + + if (bNegative[dwCurIndex]) + { + if (!bNegative[dwPrevIndex]) + { + // Current vertex is on negative side of plane, + // but previous vertex is on positive side. + const D3DXVECTOR3& v3_1 = c_pv3Vertex[dwPrevIndex]; + const D3DXVECTOR3& v3_2 = c_pv3Vertex[dwCurIndex]; + float ft = D3DXPlaneDotCoord(&c_rv4Plane, &v3_1) / (c_rv4Plane.a * (v3_1.x - v3_2.x) + c_rv4Plane.b * (v3_1.y - v3_2.y) + c_rv4Plane.c * (v3_1.z - v3_2.z)); + c_pv3NewVertex[dwCount] = v3_1 * (1.0f - ft) + v3_2 * ft; + const D3DXVECTOR3& v3_n1 = c_pv3Normal[dwPrevIndex]; + const D3DXVECTOR3& v3_n2 = c_pv3Normal[dwCurIndex]; + c_pv3NewNormal[dwCount] = v3_n1 * (1.0f - ft) + v3_n2 * ft; + ++dwCount; + } + } + else + { + if (bNegative[dwPrevIndex]) + { + // Current vertex is on positive side of plane, + // but previous vertex is on negative side. + const D3DXVECTOR3& v3_1 = c_pv3Vertex[dwCurIndex]; + const D3DXVECTOR3& v3_2 = c_pv3Vertex[dwPrevIndex]; + float ft = D3DXPlaneDotCoord(&c_rv4Plane, &v3_1) / (c_rv4Plane.a * (v3_1.x - v3_2.x) + c_rv4Plane.b * (v3_1.y - v3_2.y) + c_rv4Plane.c * (v3_1.z - v3_2.z)); + c_pv3NewVertex[dwCount] = v3_1 * (1.0f - ft) + v3_2 * ft; + const D3DXVECTOR3& v3_n1 = c_pv3Normal[dwCurIndex]; + const D3DXVECTOR3& v3_n2 = c_pv3Normal[dwPrevIndex]; + c_pv3NewNormal[dwCount] = v3_n1 * (1.0f - ft) + v3_n2 * ft; + ++dwCount; + } + + // Include current vertex + c_pv3NewVertex[dwCount] = c_pv3Vertex[dwCurIndex]; + c_pv3NewNormal[dwCount] = c_pv3Normal[dwCurIndex]; + ++dwCount; + } + } + + // Return number of vertices in clipped polygon + return dwCount; +} + +/* +void CDecal::Update() +{ +} +*/ + +void CDecal::Render() +{ + D3DXMATRIX matWorld; + D3DXMatrixIdentity(&matWorld); + STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + + for (DWORD dwi = 0; dwi < m_TriangleFanStructVector.size(); ++dwi) + STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, + m_TriangleFanStructVector[dwi].m_wMinIndex, + m_TriangleFanStructVector[dwi].m_dwVertexCount, + m_TriangleFanStructVector[dwi].m_dwPrimitiveCount, + m_Indices + m_TriangleFanStructVector[dwi].m_wMinIndex, + D3DFMT_INDEX16, + m_Vertices, + sizeof(TPDTVertex)); +} + +/* +////////////////////////////////////////////////////////////////////////// +// CDecalManager +////////////////////////////////////////////////////////////////////////// +CDecalManager aDecalManager; + +CDecalManager::CDecalManager() +{ + m_DecalPtrVector.clear(); +} + +CDecalManager::~CDecalManager() +{ + m_DecalPtrVector.clear(); +} + +void CDecalManager::Add(CDecal * pDecal) +{ + m_DecalPtrVector.push_back(pDecal); +} + +void CDecalManager::Remove(CDecal * pDecal) +{ + std::vector::iterator aIterator; + for (aIterator = m_DecalPtrVector.begin(); aIterator != m_DecalPtrVector.end();) + { + if (*aIterator == pDecal) + aIterator = m_DecalPtrVector.erase(aIterator); + else + ++aIterator; + } +} + +void CDecalManager::Update() +{ + for (DWORD dwi = 0; dwi < m_DecalPtrVector.size(); ++dwi) + m_DecalPtrVector[dwi]->Update(); +} + +void CDecalManager::Render() +{ + for (DWORD dwi = 0; dwi < m_DecalPtrVector.size(); ++dwi) + m_DecalPtrVector[dwi]->Render(); +} +*/ diff --git a/extension/src/port/EterLib/LensFlare.cpp b/extension/src/port/EterLib/LensFlare.cpp new file mode 100644 index 00000000..3e4b18b9 --- /dev/null +++ b/extension/src/port/EterLib/LensFlare.cpp @@ -0,0 +1,599 @@ +/////////////////////////////////////////////////////////////////////// +// CLensFlare Class +// +// (c) 2003 IDV, Inc. +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com +// + + +/////////////////////////////////////////////////////////////////////// +// Preprocessor +#include "StdAfx.h" +#include "LensFlare.h" +#include "Camera.h" +#include "StateManager.h" +#include "ResourceManager.h" + +#include +using namespace std; + +/////////////////////////////////////////////////////////////////////// +// Variables + +static string g_strFiles[] = +{ + "flare2.dds", + "flare1.dds", + "flare2.dds", + "flare1.dds", + "flare6.dds", + "flare4.dds", + "flare2.dds", + "flare3.dds", + "" +}; +static float g_fPosition[] = +{ + -0.55f, + -0.5f, + -0.45f, + 0.2f, + 0.3f, + 0.95f, + 0.9f, + 1.0f +}; +static float g_fWidth[] = +{ + 20.0f, + 32.0f, + 20.0f, + 32.0f, + 100.0f, + 32.0f, + 20.0f, + 250.0f +}; + +static float g_afColors[ ][4] = +{ + { 1.0f, 1.0f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 0.8f }, + { 0.3f, 0.5f, 1.0f, 0.9f }, + { 0.3f, 0.5f, 1.0f, 0.6f }, + { 1.0f, 0.6f, 0.9f, 0.4f }, + { 1.0f, 0.0f, 0.0f, 0.5f }, + { 1.0f, 0.6f, 0.3f, 0.4f } +}; + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::CLensFlare + +CLensFlare::CLensFlare() : + m_fSunSize(0), + m_fBeforeBright(0.0f), + m_fAfterBright(0.0f), + m_bFlareVisible(false), + m_bDrawFlare(true), + m_bDrawBrightScreen(true), + m_bEnabled(true), + m_bShowMainFlare(true), + m_fMaxBrightness(1.0f) +{ + m_pControlPixels = new float[c_nDepthTestDimension * c_nDepthTestDimension]; + m_pTestPixels = new float[c_nDepthTestDimension * c_nDepthTestDimension]; + m_afColor[0] = m_afColor[1] = m_afColor[2] = 1.0f; +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::~CLensFlare + +CLensFlare::~CLensFlare() +{ + delete[] m_pControlPixels; + delete[] m_pTestPixels; +} + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::Interpolate + +float CLensFlare::Interpolate(float fStart, float fEnd, float fPercent) +{ + return fStart + (fEnd - fStart) * fPercent; +} + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::DrawBeforeFlare + +void CLensFlare::Compute(const D3DXVECTOR3 & c_rv3LightDirection) +{ + float afSunPos[3]; + + D3DXVECTOR3 v3Target = CCameraManager::Instance().GetCurrentCamera()->GetTarget(); + + afSunPos[0] = v3Target.x - c_rv3LightDirection.x * 99999999.0f; + afSunPos[1] = v3Target.y - c_rv3LightDirection.y * 99999999.0f; + afSunPos[2] = v3Target.z - c_rv3LightDirection.z * 99999999.0f; + + float fX, fY; + ProjectPosition(afSunPos[0], afSunPos[1], afSunPos[2], &fX, &fY); + + // set flare location + SetFlareLocation(fX, fY); + + // determine visibility + float fSunVectorMagnitude = sqrtf(afSunPos[0] * afSunPos[0] + + afSunPos[1] * afSunPos[1] + + afSunPos[2] * afSunPos[2]); + float afSunVector[3]; + afSunVector[0] = -afSunPos[0] / fSunVectorMagnitude; + afSunVector[1] = -afSunPos[1] / fSunVectorMagnitude; + afSunVector[2] = -afSunPos[2] / fSunVectorMagnitude; + + float afCameraDirection[3]; + afCameraDirection[0] = ms_matView._13; + afCameraDirection[1] = ms_matView._23; + afCameraDirection[2] = ms_matView._33; + + + float fDotProduct = + (afSunVector[0] * afCameraDirection[0]) + + (afSunVector[1] * afCameraDirection[1]) + + (afSunVector[2] * afCameraDirection[2]); + + if (acosf(fDotProduct) < 0.5f * D3DX_PI) + SetVisible(true); + else + SetVisible(false); + + // set flare brightness + fX /= ms_Viewport.Width; + fY /= ms_Viewport.Height; + + float fDistance = sqrtf(((0.5f - fX) * (0.5f - fX)) + ((0.5f - fY) * (0.5f - fY))); + float fBeforeBright = Interpolate(0.0f, c_fHalfMaxBright, 1.0f - (fDistance * c_fDistanceScale)); + float fAfterBright = Interpolate(0.0f, 1.0f, 1.0f - (fDistance * c_fDistanceScale)); + + SetBrightnesses(fBeforeBright, fAfterBright); +} + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::DrawBeforeFlare + +void CLensFlare::DrawBeforeFlare() +{ + if (!m_bFlareVisible || !m_bEnabled || !m_bShowMainFlare) + return; + + if (m_SunFlareImageInstance.IsEmpty()) + return; + + D3DXMATRIX matProj; + D3DXMatrixOrthoOffCenterRH(&matProj, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f); + STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matProj); + STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity); + + D3DXMATRIX matWorld; + D3DXMatrixTranslation(&matWorld, m_afFlarePos[0], m_afFlarePos[1], 0.0f); + STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld); + + STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); // glDisable(GL_DEPTH_TEST); + STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // glDisable(GL_CULL_FACE); + STATEMANAGER.SaveRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); // glShadeModel(GL_FLAT); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE); // glDisable(GL_ALPHA_TEST); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // glEnable(GL_BLEND); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + /* + if (m_fBeforeBright != 0.0f && m_bDrawFlare && m_bDrawBrightScreen && false) // 왠 false? + { + glColor4f(1.0f, 1.0f, 1.0f, m_fBeforeBright); + glDisable(GL_TEXTURE_2D); + glBegin(GL_TRIANGLE_STRIP); + glVertex2f(0.0f, 0.0f); + glVertex2f(0.0f, 1.0f); + glVertex2f(1.0f, 0.0f); + glVertex2f(1.0f, 1.0f); + glEnd(); + } + */ + float fAspectRatio = ms_Viewport.Width / float(ms_Viewport.Height); + float fHeight = m_fSunSize * fAspectRatio; + D3DXCOLOR color(1.0f, 1.0f, 1.0f, 1.0f); + + SVertex vertices[4]; + vertices[0].x = -m_fSunSize; + vertices[0].y = -fHeight; + vertices[0].z = 0.0f; + vertices[0].color = color; + vertices[0].u = 0.0f; + vertices[0].v = 0.0f; + + vertices[1].x = -m_fSunSize; + vertices[1].y = fHeight; + vertices[1].z = 0.0f; + vertices[1].color = color; + vertices[1].u = 0.0f; + vertices[1].v = 1.0f; + + vertices[2].x = m_fSunSize; + vertices[2].y = -fHeight; + vertices[2].z = 0.0f; + vertices[2].color = color; + vertices[2].u = 1.0f; + vertices[2].v = 0.0f; + + vertices[3].x = m_fSunSize; + vertices[3].y = fHeight; + vertices[3].z = 0.0f; + vertices[3].color = color; + vertices[3].u = 1.0f; + vertices[3].v = 1.0f; + + STATEMANAGER.SetTexture(0, m_SunFlareImageInstance.GetTexturePointer()->GetD3DTexture()); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(SVertex)); + + STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); + STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); // glDisable(GL_DEPTH_TEST); + STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); // glDisable(GL_CULL_FACE); + STATEMANAGER.RestoreRenderState(D3DRS_SHADEMODE); // glShadeModel(GL_FLAT); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); // glDisable(GL_ALPHA_TEST); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); // glEnable(GL_BLEND); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + + STATEMANAGER.RestoreTransform(D3DTS_VIEW); + STATEMANAGER.RestoreTransform(D3DTS_PROJECTION); +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::DrawAfterFlare + +void CLensFlare::DrawAfterFlare() +{ + if (m_bEnabled && m_fAfterBright != 0.0f && m_bDrawBrightScreen) + { + SetDiffuseColor(m_afColor[0], m_afColor[1], m_afColor[2], m_fAfterBright); + RenderBar2d(0.0f, 0.0f, 1024.0f, 1024.0f); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::SetMainFlare + +void CLensFlare::SetMainFlare(string strSunFile, float fSunSize) +{ + if (m_bEnabled && m_bShowMainFlare) + { + m_fSunSize = fSunSize; + CResource * pResource = CResourceManager::Instance().GetResourcePointer(strSunFile.c_str()); + + if (!pResource->IsType(CGraphicImage::Type())) + assert(false); + + m_SunFlareImageInstance.SetImagePointer(static_cast (pResource)); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::DrawFlare + +void CLensFlare::DrawFlare() +{ + if (m_bEnabled && m_bFlareVisible && m_bDrawFlare && m_fAfterBright != 0.0f) + { + //glPushAttrib(GL_ENABLE_BIT); + STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE); // glDisable(GL_LIGHTING); + STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); // glDisable(GL_DEPTH_TEST); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // glDisable(GL_CULL_FACE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE); // glDisable(GL_ALPHA_TEST); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // glEnable(GL_BLEND); + + D3DXMATRIX matProj; + D3DXMatrixOrthoOffCenterRH(&matProj, 0.0f, ms_Viewport.Width, ms_Viewport.Height, 0.0f, -1.0f, 1.0f); + STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matProj); + STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity); + + STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity); + //glMatrixMode(GL_MODELVIEW); + //glLoadIdentity(); + + //glDisable(GL_TEXTURE_2D); + DrawAfterFlare(); + + //glEnable(GL_TEXTURE_2D); + m_cFlare.Draw(m_fAfterBright, + ms_Viewport.Width, + ms_Viewport.Height, + static_cast(m_afFlareWinPos[0]), + static_cast(m_afFlareWinPos[1])); + + STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); // glDisable(GL_LIGHTING); + STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); // glDisable(GL_DEPTH_TEST); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); // glDisable(GL_CULL_FACE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); // glEnable(GL_BLEND); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); // glDisable(GL_ALPHA_TEST); + + STATEMANAGER.RestoreTransform(D3DTS_PROJECTION); + STATEMANAGER.RestoreTransform(D3DTS_VIEW); + //glDisable(GL_TEXTURE_2D); + //glPopAttrib(); + } +} + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::CharacterizeFlare +void CLensFlare::CharacterizeFlare(bool bEnabled, bool bShowMainFlare, float fMaxBrightness, const D3DXCOLOR & c_rColor) +{ + m_bEnabled = bEnabled; + m_bShowMainFlare = bShowMainFlare; + m_fMaxBrightness = fMaxBrightness; + + m_afColor[0] = c_rColor.r; + m_afColor[1] = c_rColor.g; + m_afColor[2] = c_rColor.b; +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::Initialize +void CLensFlare::Initialize(std::string strPath) +{ + if (m_bEnabled) + m_cFlare.Init(strPath); +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::SetFlareLocation +void CLensFlare::SetFlareLocation(double dX, double dY) +{ + if (m_bEnabled) + { + m_afFlareWinPos[0] = float(dX); + m_afFlareWinPos[1] = float(dY); + + m_afFlarePos[0] = float(dX) / ms_Viewport.Width; + m_afFlarePos[1] = float(dY) / ms_Viewport.Height; + } +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::SetBrightnesses + +void CLensFlare::SetBrightnesses(float fBeforeBright, float fAfterBright) +{ + if (m_bEnabled) + { + m_fBeforeBright = fBeforeBright; + m_fAfterBright = fAfterBright; + + ClampBrightness(); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::ReadControlPixels + +void CLensFlare::ReadControlPixels() +{ + if (m_bEnabled) + ReadDepthPixels(m_pControlPixels); +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::AdjustBrightness + +void CLensFlare::AdjustBrightness() +{ + if (m_bEnabled) + { + ReadDepthPixels(m_pTestPixels); + + int nDifferent = 0; + + for (int i = 0; i < c_nDepthTestDimension * c_nDepthTestDimension; ++i) + if (m_pTestPixels[i] != m_pControlPixels[i]) + ++nDifferent; + + float fAdjust = (static_cast(nDifferent) / (c_nDepthTestDimension * c_nDepthTestDimension)); + fAdjust = sqrtf(fAdjust) * 0.85f; + m_fAfterBright *= 1.0f - fAdjust; + } +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::ReadDepthPixels + +void CLensFlare::ReadDepthPixels(float * /*pPixels*/) +{ + /* + LPDIRECT3DSURFACE8 lpSurface; + if (FAILED(ms_lpd3dDevice->GetDepthStencilSurface(&lpSurface))) + assert(false); + + D3DLOCKED_RECT rect; + lpSurface->LockRect(&rect, NULL, D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE); + + lpSurface->UnlockRect(); + */ + /* + glReadPixels(GLint(m_afFlareWinPos[0] - c_nDepthTestDimension / 2), + GLint(m_afFlareWinPos[1] - c_nDepthTestDimension / 2), + c_nDepthTestDimension, c_nDepthTestDimension, + GL_DEPTH_COMPONENT, GL_FLOAT, pPixels); + */ +} + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::ClampBrightness + +void CLensFlare::ClampBrightness() +{ + // before + if (m_fBeforeBright < 0.0f) + m_fBeforeBright = 0.0f; + else if (m_fBeforeBright > 1.0f) + m_fBeforeBright = 1.0f; + + m_fBeforeBright *= m_fMaxBrightness; + + if (m_fAfterBright < 0.0f) + m_fAfterBright = 0.0f; + else if (m_fAfterBright > 1.0f) + m_fAfterBright = 1.0f; + + m_fAfterBright *= m_fMaxBrightness; +} + +/////////////////////////////////////////////////////////////////////// +// CFlare implementation +/////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////// +// CFlare::CFlare + +CFlare::CFlare() +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CFlare::~CFlare + +CFlare::~CFlare() +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CFlare::Init + +void CFlare::Init(std::string strPath) +{ + int i = 0; + + while (g_strFiles[i] != "") + { + CResource * pResource = CResourceManager::Instance().GetResourcePointer((strPath + "/" + string(g_strFiles[i])).c_str()); + + if (!pResource->IsType(CGraphicImage::Type())) + assert(false); + + SFlarePiece * pPiece = new SFlarePiece; + + pPiece->m_imageInstance.SetImagePointer(static_cast (pResource)); + pPiece->m_fPosition = g_fPosition[i]; + pPiece->m_fWidth = g_fWidth[i]; + pPiece->m_pColor = g_afColors[i]; + + m_vFlares.push_back(pPiece); + i++; + } +} + + +/////////////////////////////////////////////////////////////////////// +// CFlare::Draw +void CFlare::Draw(float fBrightScale, int nWidth, int nHeight, int nX, int nY) +{ + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + + float fDX = float(nX) - float(nWidth) / 2.0f; + float fDY = float(nY) - float(nHeight) / 2.0f; + + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + for (unsigned int i = 0; i < m_vFlares.size(); i++) + { + float fCenterX = float(nX) - (m_vFlares[i]->m_fPosition + 1.0f) * fDX; + float fCenterY = float(nY) - (m_vFlares[i]->m_fPosition + 1.0f) * fDY; + float fW = m_vFlares[i]->m_fWidth; + + D3DXCOLOR d3dColor(m_vFlares[i]->m_pColor[0] * fBrightScale, + m_vFlares[i]->m_pColor[1] * fBrightScale, + m_vFlares[i]->m_pColor[2] * fBrightScale, + m_vFlares[i]->m_pColor[3] * fBrightScale); + + STATEMANAGER.SetTexture(0, m_vFlares[i]->m_imageInstance.GetTexturePointer()->GetD3DTexture()); + + TVertex vertices[4]; + + vertices[0].u = 0.0f; + vertices[0].v = 0.0f; + vertices[0].x = fCenterX - fW; + vertices[0].y = fCenterY - fW; + vertices[0].z = 0.0f; + vertices[0].color = d3dColor; + + vertices[1].u = 0.0f; + vertices[1].v = 1.0f; + vertices[1].x = fCenterX - fW; + vertices[1].y = fCenterY + fW; + vertices[1].z = 0.0f; + vertices[1].color = d3dColor; + + vertices[2].u = 1.0f; + vertices[2].v = 0.0f; + vertices[2].x = fCenterX + fW; + vertices[2].y = fCenterY - fW; + vertices[2].z = 0.0f; + vertices[2].color = d3dColor; + + vertices[3].u = 1.0f; + vertices[3].v = 1.0f; + vertices[3].x = fCenterX + fW; + vertices[3].y = fCenterY + fW; + vertices[3].z = 0.0f; + vertices[3].color = d3dColor; + + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(TVertex)); + } + + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); +} diff --git a/extension/src/port/EterLib/ScreenFilter.cpp b/extension/src/port/EterLib/ScreenFilter.cpp new file mode 100644 index 00000000..52ee9e1f --- /dev/null +++ b/extension/src/port/EterLib/ScreenFilter.cpp @@ -0,0 +1,52 @@ +#include "StdAfx.h" +#include "ScreenFilter.h" +#include "StateManager.h" + +void CScreenFilter::Render() +{ + if (!m_bEnable) + return; + + STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &ms_matIdentity); + STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity); + STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, m_bySrcType); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, m_byDestType); + + SetOrtho2D(CScreen::ms_iWidth, CScreen::ms_iHeight, 400.0f); + SetDiffuseColor(m_Color.r, m_Color.g, m_Color.b, m_Color.a); + RenderBar2d(0, 0, CScreen::ms_iWidth, CScreen::ms_iHeight); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + STATEMANAGER.RestoreTransform(D3DTS_VIEW); + STATEMANAGER.RestoreTransform(D3DTS_PROJECTION); +} + +void CScreenFilter::SetEnable(BOOL /*bFlag*/) +{ + m_bEnable = FALSE; +} + +void CScreenFilter::SetBlendType(BYTE bySrcType, BYTE byDestType) +{ + m_bySrcType = bySrcType; + m_byDestType = byDestType; +} +void CScreenFilter::SetColor(const D3DXCOLOR & c_rColor) +{ + m_Color = c_rColor; +} + +CScreenFilter::CScreenFilter() +{ + m_bEnable = FALSE; + m_bySrcType = D3DBLEND_SRCALPHA; + m_byDestType = D3DBLEND_INVSRCALPHA; + m_Color = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f); +} +CScreenFilter::~CScreenFilter() +{ +}