Skip to content

Commit

Permalink
SWM: Ported main "Second Viewport" code ("Real" 3D scopes)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShokerStlk authored and Xottab-DUTY committed Mar 31, 2018
1 parent fe7cf48 commit 21e6e35
Show file tree
Hide file tree
Showing 25 changed files with 206 additions and 3 deletions.
16 changes: 15 additions & 1 deletion src/Layers/xrRenderPC_R1/FStaticRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,22 @@ void CRender::OnFrame()
Models->DeleteQueue();
}

// Перед началом рендера мира --#SM+#-- +SecondVP+
void CRender::BeforeWorldRender() {}
void CRender::AfterWorldRender() {}

// После рендера мира и пост-эффектов --#SM+#-- +SecondVP+
void CRender::AfterWorldRender()
{
if (Device.m_SecondViewport.IsSVPFrame())
{
// Делает копию бэкбуфера (текущего экрана) в рендер-таргет второго вьюпорта
IRender_Target* T = getTarget();
IDirect3DSurface9* pBackBuffer = nullptr;
HW.pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer); // Получаем ссылку на бэкбуфер
D3DXLoadSurfaceFromSurface(Target->RT_SecondVP->pRT, 0, 0, pBackBuffer, 0, 0, D3DX_DEFAULT, 0);
pBackBuffer->Release(); // Корректно очищаем ссылку на бэкбуфер (иначе игра зависнет в опциях)
}
}

// Implementation
IRender_ObjectSpecific* CRender::ros_create(IRenderable* parent) { return new CROS_impl(); }
Expand Down
5 changes: 5 additions & 0 deletions src/Layers/xrRenderPC_R1/FStaticRender_RenderTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
static LPCSTR RTname = "$user$rendertarget";
static LPCSTR RTname_color_map = "$user$rendertarget_color_map";
static LPCSTR RTname_distort = "$user$distort";
static LPCSTR RTname_SecondVP = "$user$viewport2"; //--#SM+#-- +SecondVP+

CRenderTarget::CRenderTarget()
{
bAvailable = FALSE;
RT = nullptr;
RT_color_map = nullptr;
RT_SecondVP = nullptr; //--#SM+# +SecondVP+
pTempZB = nullptr;
ZB = nullptr;
pFB = nullptr;
Expand Down Expand Up @@ -64,6 +66,8 @@ BOOL CRenderTarget::Create()
}
// RImplementation.o.color_mapping = RT_color_map->valid();

RT_SecondVP.create(RTname_SecondVP, rtWidth, rtHeight, HW.Caps.fTarget); //--#SM+#-- +SecondVP+

if ((rtHeight != Device.dwHeight) || (rtWidth != Device.dwWidth))
{
R_CHK(HW.pDevice->CreateDepthStencilSurface(
Expand Down Expand Up @@ -111,6 +115,7 @@ CRenderTarget::~CRenderTarget()
s_postprocess_D[0].destroy();
s_postprocess[1].destroy();
g_postprocess.destroy();
RT_SecondVP.destroy(); //--#SM+#-- +SecondVP+
RT_distort.destroy();
RT_color_map.destroy();
RT.destroy();
Expand Down
3 changes: 3 additions & 0 deletions src/Layers/xrRenderPC_R1/FStaticRender_RenderTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

class CRenderTarget : public IRender_Target
{
public:
ref_rt RT_SecondVP; //--#SM+#-- +SecondVP+

private:
BOOL bAvailable;
u32 rtWidth;
Expand Down
16 changes: 16 additions & 0 deletions src/Layers/xrRenderPC_R2/r2_R_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,3 +513,19 @@ void CRender::render_forward()

RImplementation.o.distortion = FALSE; // disable distorion
}

// Перед началом рендера мира --#SM+#-- +SecondVP+
void CRender::BeforeWorldRender() {}

// После рендера мира и пост-эффектов --#SM+#-- +SecondVP+
void CRender::AfterWorldRender()
{
if (Device.m_SecondViewport.IsSVPFrame())
{
// Делает копию бэкбуфера (текущего экрана) в рендер-таргет второго вьюпорта
IDirect3DSurface9* pBackBuffer = NULL;
HW.pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer); // Получаем ссылку на бэкбуфер
D3DXLoadSurfaceFromSurface(Target->rt_secondVP->pRT, 0, 0, pBackBuffer, 0, 0, D3DX_DEFAULT, 0);
pBackBuffer->Release(); // Корректно очищаем ссылку на бэкбуфер (иначе игра зависнет в опциях)
}
}
2 changes: 2 additions & 0 deletions src/Layers/xrRenderPC_R2/r2_rendertarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ CRenderTarget::CRenderTarget()
// generic(LDR) RTs
rt_Generic_0.create(r2_RT_generic0, w, h, D3DFMT_A8R8G8B8);
rt_Generic_1.create(r2_RT_generic1, w, h, D3DFMT_A8R8G8B8);
rt_secondVP.create (r2_RT_secondVP, w, h, D3DFMT_A8R8G8B8); //--#SM+#-- +SecondVP+

// Igor: for volumetric lights
// rt_Generic_2.create (r2_RT_generic2,w,h,D3DFMT_A8R8G8B8 );
// temp: for higher quality blends
Expand Down
3 changes: 3 additions & 0 deletions src/Layers/xrRenderPC_R2/r2_rendertarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class CRenderTarget : public IRender_Target
ref_rt rt_LUM_64; // 64bit, 64x64, log-average in all components
ref_rt rt_LUM_8; // 64bit, 8x8, log-average in all components

// Second viewport
ref_rt rt_secondVP; // 32bit (r,g,b,a) --//#SM+#-- +SecondVP+

// Igor: for async screenshots
IDirect3DSurface9* pFB; // 32bit (r,g,b,a) is situated in the system memory

Expand Down
12 changes: 12 additions & 0 deletions src/Layers/xrRenderPC_R2/r2_rendertarget_phase_combine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ void CRenderTarget::phase_combine()

//*** exposure-pipeline
u32 gpu_id = Device.dwFrame % HW.Caps.iGPUNum;

if (Device.m_SecondViewport.IsSVPActive()) //--#SM+#-- +SecondVP+ Fix for screen flickering
{
// clang-format off
gpu_id = (Device.dwFrame - 1) % HW.Caps.iGPUNum; // Фикс "мерцания" tonemapping (HDR) после выключения двойного рендера.
// Побочный эффект - при работе двойного рендера скорость изменения tonemapping (HDR) падает в два раза
// Мерцание связано с тем, что HDR для своей работы хранит уменьшенние копии "прошлых кадров"
// Эти кадры относительно похожи друг на друга, однако при включЄнном двойном рендере
// в половине кадров оказывается картинка из второго рендера, и поскольку она часто может отличатся по цвету\яркости
// то при попытке создания "плавного" перехода между ними получается эффект мерцания
// clang-format on
}
{
t_LUM_src->surface_set(rt_LUM_pool[gpu_id * 2 + 0]->pSurface);
t_LUM_dest->surface_set(rt_LUM_pool[gpu_id * 2 + 1]->pSurface);
Expand Down
2 changes: 2 additions & 0 deletions src/Layers/xrRenderPC_R2/r2_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
#define r2_jitter_mipped "$user$jitter_mipped" // --- dither
#define r2_sunmask "sunmask"

#define r2_RT_secondVP "$user$viewport2" // --#SM+#-- +SecondVP+ Хранит картинку со второго вьюпорта

#define JITTER(a) r2_jitter #a

const float SMAP_near_plane = .1f;
Expand Down
2 changes: 2 additions & 0 deletions src/Layers/xrRenderPC_R3/r2_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
#define r2_jitter_mipped "$user$jitter_mipped" // --- dither
#define r2_sunmask "sunmask"

#define r2_RT_secondVP "$user$viewport2" // --#SM+#-- +SecondVP+ Хранит картинку со второго вьюпорта

#define JITTER(a) r2_jitter #a

const float SMAP_near_plane = .1f;
Expand Down
2 changes: 2 additions & 0 deletions src/Layers/xrRenderPC_R3/r3.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ class CRender : public D3DXRenderBase
virtual void ScreenshotAsyncBegin();
virtual void ScreenshotAsyncEnd(CMemoryWriter& memory_writer);
virtual void OnFrame();
virtual void BeforeWorldRender(); //--#SM+#-- +SecondVP+ Вызывается перед началом рендера мира и пост-эффектов
virtual void AfterWorldRender(); //--#SM+#-- +SecondVP+ Вызывается после рендера мира и перед UI

void BeforeWorldRender() override; //--#SM+#-- +SecondVP+ Вызывается перед началом рендера мира и пост-эффектов
void AfterWorldRender() override; //--#SM+#-- +SecondVP+ Вызывается после рендера мира и перед UI
Expand Down
16 changes: 16 additions & 0 deletions src/Layers/xrRenderPC_R3/r3_R_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,3 +566,19 @@ void CRender::render_forward()

RImplementation.o.distortion = FALSE; // disable distorion
}

// Перед началом рендера мира --#SM+#-- +SecondVP+
void CRender::BeforeWorldRender() {}

// После рендера мира и пост-эффектов --#SM+#-- +SecondVP+
void CRender::AfterWorldRender()
{
if (Device.m_SecondViewport.IsSVPFrame())
{
// Делает копию бэкбуфера (текущего экрана) в рендер-таргет второго вьюпорта
ID3D10Texture2D* pBuffer = NULL;
HW.m_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBuffer);
HW.pDevice->CopyResource(Target->rt_secondVP->pSurface, pBuffer);
pBuffer->Release(); // Корректно очищаем ссылку на бэкбуфер (иначе игра зависнет в опциях)
}
}
1 change: 1 addition & 0 deletions src/Layers/xrRenderPC_R3/r3_rendertarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ CRenderTarget::CRenderTarget()
rt_Generic_0.create(r2_RT_generic0, w, h, D3DFMT_A8R8G8B8, 1);
rt_Generic_1.create(r2_RT_generic1, w, h, D3DFMT_A8R8G8B8, 1);
rt_Generic.create(r2_RT_generic, w, h, D3DFMT_A8R8G8B8, 1);
rt_secondVP.create (r2_RT_secondVP, w, h, D3DFMT_A8R8G8B8, 1); //--#SM+#-- +SecondVP+

if (RImplementation.o.dx10_msaa)
{
Expand Down
4 changes: 4 additions & 0 deletions src/Layers/xrRenderPC_R3/r3_rendertarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ class CRenderTarget : public IRender_Target
ref_rt rt_Accumulator_temp; // only for HW which doesn't feature fp16 blend
ref_rt rt_Generic_0; // 32bit (r,g,b,a) // post-process, intermidiate results, etc.
ref_rt rt_Generic_1; // 32bit (r,g,b,a) // post-process, intermidiate results, etc.

// Second viewport
ref_rt rt_secondVP; // 32bit (r,g,b,a) --//#SM+#-- +SecondVP+

// Igor: for volumetric lights
ref_rt rt_Generic_2; // 32bit (r,g,b,a) // post-process, intermidiate results, etc.
ref_rt rt_Bloom_1; // 32bit, dim/4 (r,g,b,?)
Expand Down
12 changes: 12 additions & 0 deletions src/Layers/xrRenderPC_R3/r3_rendertarget_phase_combine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ void CRenderTarget::phase_combine()

//*** exposure-pipeline
u32 gpu_id = Device.dwFrame % HW.Caps.iGPUNum;

if (Device.m_SecondViewport.IsSVPActive()) //--#SM+#-- +SecondVP+ Fix for screen flickering
{
// clang-format off
gpu_id = (Device.dwFrame - 1) % HW.Caps.iGPUNum; // Фикс "мерцания" tonemapping (HDR) после выключения двойного рендера.
// Побочный эффект - при работе двойного рендера скорость изменения tonemapping (HDR) падает в два раза
// Мерцание связано с тем, что HDR для своей работы хранит уменьшенние копии "прошлых кадров"
// Эти кадры относительно похожи друг на друга, однако при включЄнном двойном рендере
// в половине кадров оказывается картинка из второго рендера, и поскольку она часто может отличатся по цвету\яркости
// то при попытке создания "плавного" перехода между ними получается эффект мерцания
// clang-format on
}
{
t_LUM_src->surface_set(rt_LUM_pool[gpu_id * 2 + 0]->pSurface);
t_LUM_dest->surface_set(rt_LUM_pool[gpu_id * 2 + 1]->pSurface);
Expand Down
2 changes: 2 additions & 0 deletions src/Layers/xrRenderPC_R4/r2_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
#define r2_jitter_mipped "$user$jitter_mipped" // --- dither
#define r2_sunmask "sunmask"

#define r2_RT_secondVP "$user$viewport2" // --#SM+#-- +SecondVP+ Хранит картинку со второго вьюпорта

#define JITTER(a) r2_jitter #a

const float SMAP_near_plane = .1f;
Expand Down
2 changes: 2 additions & 0 deletions src/Layers/xrRenderPC_R4/r4.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ class CRender : public D3DXRenderBase
virtual void ScreenshotAsyncBegin();
virtual void ScreenshotAsyncEnd(CMemoryWriter& memory_writer);
virtual void OnFrame();
virtual void BeforeWorldRender(); //--#SM+#-- +SecondVP+ Вызывается перед началом рендера мира и пост-эффектов
virtual void AfterWorldRender(); //--#SM+#-- +SecondVP+ Вызывается после рендера мира и перед UI

void BeforeWorldRender() override; //--#SM+#-- +SecondVP+ Вызывается перед началом рендера мира и пост-эффектов
void AfterWorldRender() override; //--#SM+#-- +SecondVP+ Вызывается после рендера мира и перед UI
Expand Down
16 changes: 16 additions & 0 deletions src/Layers/xrRenderPC_R4/r4_R_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,3 +567,19 @@ void CRender::render_forward()

RImplementation.o.distortion = FALSE; // disable distorion
}

// Перед началом рендера мира --#SM+#-- +SecondVP+
void CRender::BeforeWorldRender() {}

// После рендера мира и пост-эффектов --#SM+#-- +SecondVP+
void CRender::AfterWorldRender()
{
if (Device.m_SecondViewport.IsSVPFrame())
{
// Делает копию бэкбуфера (текущего экрана) в рендер-таргет второго вьюпорта
ID3DTexture2D* pBuffer = NULL;
HW.m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBuffer);
HW.pContext->CopyResource(Target->rt_secondVP->pSurface, pBuffer);
pBuffer->Release(); // Корректно очищаем ссылку на бэкбуфер (иначе игра зависнет в опциях)
}
}
1 change: 1 addition & 0 deletions src/Layers/xrRenderPC_R4/r4_rendertarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ CRenderTarget::CRenderTarget()
rt_Generic_0.create(r2_RT_generic0, w, h, D3DFMT_A8R8G8B8, 1);
rt_Generic_1.create(r2_RT_generic1, w, h, D3DFMT_A8R8G8B8, 1);
rt_Generic.create(r2_RT_generic, w, h, D3DFMT_A8R8G8B8, 1);
rt_secondVP.create (r2_RT_secondVP, w, h, D3DFMT_A8R8G8B8, 1); //--#SM+#-- +SecondVP+

if (RImplementation.o.dx10_msaa)
{
Expand Down
4 changes: 4 additions & 0 deletions src/Layers/xrRenderPC_R4/r4_rendertarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ class CRenderTarget : public IRender_Target
ref_rt rt_Accumulator_temp; // only for HW which doesn't feature fp16 blend
ref_rt rt_Generic_0; // 32bit (r,g,b,a) // post-process, intermidiate results, etc.
ref_rt rt_Generic_1; // 32bit (r,g,b,a) // post-process, intermidiate results, etc.

// Second viewport
ref_rt rt_secondVP; // 32bit (r,g,b,a) --//#SM+#-- +SecondVP+

// Igor: for volumetric lights
ref_rt rt_Generic_2; // 32bit (r,g,b,a) // post-process, intermidiate results, etc.
ref_rt rt_Bloom_1; // 32bit, dim/4 (r,g,b,?)
Expand Down
13 changes: 13 additions & 0 deletions src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ void CRenderTarget::phase_combine()

//*** exposure-pipeline
u32 gpu_id = Device.dwFrame % HW.Caps.iGPUNum;

if (Device.m_SecondViewport.IsSVPActive()) //--#SM+#-- +SecondVP+
{
// clang-format off
gpu_id = (Device.dwFrame - 1) % HW.Caps.iGPUNum; // Фикс "мерцания" tonemapping (HDR) после выключения двойного рендера.
// Побочный эффект - при работе двойного рендера скорость изменения tonemapping (HDR) падает в два раза
// Мерцание связано с тем, что HDR для своей работы хранит уменьшенние копии "прошлых кадров"
// Эти кадры относительно похожи друг на друга, однако при включенном двойном рендере
// в половине кадров оказывается картинка из второго рендера, и поскольку она часто может отличатся по цвету\яркости
// то при попытке создания "плавного" перехода между ними получается эффект мерцания
// clang-format on
}

{
t_LUM_src->surface_set(rt_LUM_pool[gpu_id * 2 + 0]->pSurface);
t_LUM_dest->surface_set(rt_LUM_pool[gpu_id * 2 + 1]->pSurface);
Expand Down
17 changes: 16 additions & 1 deletion src/xrEngine/CameraManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,22 @@ void CCameraManager::ApplyDevice(float _viewport_near)
// projection
Device.fFOV = m_cam_info.fFov;
Device.fASPECT = m_cam_info.fAspect;
Device.mProject.build_projection(deg2rad(m_cam_info.fFov), m_cam_info.fAspect, _viewport_near, m_cam_info.fFar);

//--#SM+# Begin-- +SecondVP+
// Пересчитываем FOV для второго вьюпорта [Recalculate scene FOV for SecondVP frame]
if (Device.m_SecondViewport.IsSVPFrame())
{
// Для второго вьюпорта FOV выставляем здесь
Device.fFOV *= g_pGamePersistent->m_pGShaderConstants->hud_params.y;

// Предупреждаем что мы изменили настройки камеры
Device.m_SecondViewport.isCamReady = true;
}
else
Device.m_SecondViewport.isCamReady = false;

Device.mProject.build_projection(deg2rad(Device.fFOV), m_cam_info.fAspect, _viewport_near, m_cam_info.fFar);
//--#SM+# End--

if (g_pGamePersistent && g_pGamePersistent->m_pMainMenu->IsActive())
ResetPP();
Expand Down
5 changes: 5 additions & 0 deletions src/xrEngine/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,8 @@ void CLoadScreenRenderer::stop()
}

void CLoadScreenRenderer::OnRender() { pApp->load_draw_internal(); }

bool CRenderDevice::CSecondVPParams::IsSVPFrame() //--#SM+#-- +SecondVP+
{
return IsSVPActive() && Device.dwFrame % frameDelay == 0;
}
28 changes: 28 additions & 0 deletions src/xrEngine/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,29 @@ class ENGINE_API CRenderDeviceBase : public IRenderDevice, public CRenderDeviceD
// refs
class ENGINE_API CRenderDevice : public CRenderDeviceBase
{
public:
class ENGINE_API CSecondVPParams //--#SM+#-- +SecondVP+
{
bool isActive; // Флаг активации рендера во второй вьюпорт
u8 frameDelay; // На каком кадре с момента прошлого рендера во второй вьюпорт мы начнём новый
//(не может быть меньше 2 - каждый второй кадр, чем больше тем более низкий FPS во втором вьюпорте)

public:
bool isCamReady; // Флаг готовности камеры (FOV, позиция, и т.п) к рендеру второго вьюпорта

IC bool IsSVPActive() { return isActive; }
IC void SetSVPActive(bool bState) { isActive = bState; }
bool IsSVPFrame();

IC u8 GetSVPFrameDelay() { return frameDelay; }
void SetSVPFrameDelay(u8 iDelay)
{
frameDelay = iDelay;
clamp<u8>(frameDelay, 2, u8(-1));
}
};

private:
// Main objects used for creating and rendering the 3D scene
u32 m_dwWindowStyle;
CTimer TimerMM;
Expand Down Expand Up @@ -177,6 +200,7 @@ class ENGINE_API CRenderDevice : public CRenderDeviceBase
CRegistrator<pureFrame> seqFrameMT;
CRegistrator<pureDeviceReset> seqDeviceReset;
xr_vector<fastdelegate::FastDelegate0<>> seqParallel;
CSecondVPParams m_SecondViewport; //--#SM+#-- +SecondVP+

Fmatrix mInvFullTransform;

Expand All @@ -190,6 +214,10 @@ class ENGINE_API CRenderDevice : public CRenderDeviceBase
b_is_Ready = FALSE;
Timer.Start();
m_bNearer = FALSE;
//--#SM+#-- +SecondVP+
m_SecondViewport.SetSVPActive(false);
m_SecondViewport.SetSVPFrameDelay(2);
m_SecondViewport.isCamReady = false;
};

void Pause(BOOL bOn, BOOL bTimer, BOOL bSound, LPCSTR reason);
Expand Down
Loading

0 comments on commit 21e6e35

Please sign in to comment.