diff --git a/Minecraft.Client/Common/PostProcesser.h b/Minecraft.Client/Common/PostProcesser.h index 35fa50809..966d58bc6 100644 --- a/Minecraft.Client/Common/PostProcesser.h +++ b/Minecraft.Client/Common/PostProcesser.h @@ -51,7 +51,10 @@ private: struct GammaCBData { float gamma; - float pad[3]; + float pad; + float uvOffsetX, uvOffsetY; + float uvScaleX, uvScaleY; + float pad2[2]; }; static const char* g_gammaVSCode; diff --git a/Minecraft.Client/GameRenderer.cpp b/Minecraft.Client/GameRenderer.cpp index 169f1280b..73b39529c 100644 --- a/Minecraft.Client/GameRenderer.cpp +++ b/Minecraft.Client/GameRenderer.cpp @@ -954,91 +954,70 @@ float GameRenderer::ComputeGammaFromSlider(float slider0to100) void GameRenderer::CachePlayerGammas() { - for (int j = 0; j < XUSER_MAX_COUNT && j < NUM_LIGHT_TEXTURES; ++j) - { - std::shared_ptr player = Minecraft::GetInstance()->localplayers[j]; - if (!player) - { - m_cachedGammaPerPlayer[j] = 1.0f; - continue; - } + const float slider = app.GetGameSettings(ProfileManager.GetPrimaryPad(), eGameSetting_Gamma); + const float gamma = ComputeGammaFromSlider(slider); - const float slider = app.GetGameSettings(j, eGameSetting_Gamma); // 0..100 - m_cachedGammaPerPlayer[j] = ComputeGammaFromSlider(slider); - } + for (int j = 0; j < XUSER_MAX_COUNT && j < NUM_LIGHT_TEXTURES; ++j) + m_cachedGammaPerPlayer[j] = gamma; } bool GameRenderer::ComputeViewportForPlayer(int j, D3D11_VIEWPORT &outViewport) const { - // Use the actual backbuffer dimensions so viewports adapt to window resize. extern int g_rScreenWidth; extern int g_rScreenHeight; - int active = 0; - int indexMap[NUM_LIGHT_TEXTURES] = {-1, -1, -1, -1}; - for (int i = 0; i < XUSER_MAX_COUNT && i < NUM_LIGHT_TEXTURES; ++i) - { - if (Minecraft::GetInstance()->localplayers[i]) - indexMap[active++] = i; - } - - if (active <= 1) - { - outViewport.TopLeftX = 0.0f; - outViewport.TopLeftY = 0.0f; - outViewport.Width = static_cast(g_rScreenWidth); - outViewport.Height = static_cast(g_rScreenHeight); - outViewport.MinDepth = 0.0f; - outViewport.MaxDepth = 1.0f; - return true; - } - - int k = -1; - for (int ord = 0; ord < active; ++ord) - if (indexMap[ord] == j) - { - k = ord; - break; - } - if (k < 0) + std::shared_ptr player = Minecraft::GetInstance()->localplayers[j]; + if (!player) return false; - const float width = static_cast(g_rScreenWidth); - const float height = static_cast(g_rScreenHeight); + const float w = static_cast(g_rScreenWidth); + const float h = static_cast(g_rScreenHeight); + const float halfW = w * 0.5f; + const float halfH = h * 0.5f; - if (active == 2) + outViewport.MinDepth = 0.0f; + outViewport.MaxDepth = 1.0f; + + switch (static_cast(player->m_iScreenSection)) { - const float halfH = height * 0.5f; - outViewport.TopLeftX = 0.0f; - outViewport.Width = width; - outViewport.MinDepth = 0.0f; - outViewport.MaxDepth = 1.0f; - if (k == 0) - { - outViewport.TopLeftY = 0.0f; - outViewport.Height = halfH; - } - else - { - outViewport.TopLeftY = halfH; - outViewport.Height = halfH; - } - return true; - } - else - { - const float halfW = width * 0.5f; - const float halfH = height * 0.5f; - const int row = (k >= 2) ? 1 : 0; - const int col = (k % 2); - outViewport.TopLeftX = col ? halfW : 0.0f; - outViewport.TopLeftY = row ? halfH : 0.0f; - outViewport.Width = halfW; - outViewport.Height = halfH; - outViewport.MinDepth = 0.0f; - outViewport.MaxDepth = 1.0f; - return true; + case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: + outViewport.TopLeftX = 0; outViewport.TopLeftY = 0; + outViewport.Width = w; outViewport.Height = halfH; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: + outViewport.TopLeftX = 0; outViewport.TopLeftY = halfH; + outViewport.Width = w; outViewport.Height = halfH; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: + outViewport.TopLeftX = 0; outViewport.TopLeftY = 0; + outViewport.Width = halfW; outViewport.Height = h; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: + outViewport.TopLeftX = halfW; outViewport.TopLeftY = 0; + outViewport.Width = halfW; outViewport.Height = h; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: + outViewport.TopLeftX = 0; outViewport.TopLeftY = 0; + outViewport.Width = halfW; outViewport.Height = halfH; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: + outViewport.TopLeftX = halfW; outViewport.TopLeftY = 0; + outViewport.Width = halfW; outViewport.Height = halfH; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: + outViewport.TopLeftX = 0; outViewport.TopLeftY = halfH; + outViewport.Width = halfW; outViewport.Height = halfH; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: + outViewport.TopLeftX = halfW; outViewport.TopLeftY = halfH; + outViewport.Width = halfW; outViewport.Height = halfH; + break; + default: + outViewport.TopLeftX = 0; outViewport.TopLeftY = 0; + outViewport.Width = w; outViewport.Height = h; + break; } + return true; } uint32_t GameRenderer::BuildPlayerViewports(D3D11_VIEWPORT *outViewports, float *outGammas, UINT maxCount) const diff --git a/Minecraft.Client/Windows64/PostProcesser.cpp b/Minecraft.Client/Windows64/PostProcesser.cpp index 4c55d3d98..aabb1f679 100644 --- a/Minecraft.Client/Windows64/PostProcesser.cpp +++ b/Minecraft.Client/Windows64/PostProcesser.cpp @@ -21,13 +21,17 @@ const char* PostProcesser::g_gammaPSCode = "cbuffer GammaCB : register(b0)\n" "{\n" " float gamma;\n" - " float3 pad;\n" + " float _pad;\n" + " float2 uvOffset;\n" + " float2 uvScale;\n" + " float2 _pad2;\n" "};\n" "Texture2D sceneTex : register(t0);\n" "SamplerState sceneSampler : register(s0);\n" "float4 main(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target\n" "{\n" - " float4 color = sceneTex.Sample(sceneSampler, uv);\n" + " float2 texUV = uvOffset + uv * uvScale;\n" + " float4 color = sceneTex.Sample(sceneSampler, texUV);\n" "\n" " color.rgb = max(color.rgb, 0.0);\n" "\n" @@ -158,7 +162,7 @@ void PostProcesser::Init() cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - GammaCBData initData = {1.0f, {0, 0, 0}}; + GammaCBData initData = {1.0f, 0, 0.0f, 0.0f, 1.0f, 1.0f, {0, 0}}; D3D11_SUBRESOURCE_DATA srData; srData.pSysMem = &initData; srData.SysMemPitch = 0; @@ -237,6 +241,10 @@ void PostProcesser::Apply() const { GammaCBData *cb = static_cast(mapped.pData); cb->gamma = m_gamma; + cb->uvOffsetX = 0.0f; + cb->uvOffsetY = 0.0f; + cb->uvScaleX = 1.0f; + cb->uvScaleY = 1.0f; ctx->Unmap(m_pGammaCB, 0); } @@ -333,27 +341,6 @@ void PostProcesser::ApplyFromCopied() const ID3D11DeviceContext* ctx = g_pImmediateContext; - D3D11_MAPPED_SUBRESOURCE mapped; - const D3D11_MAP mapType = m_wineMode ? D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_DISCARD; - const HRESULT hr = ctx->Map(m_pGammaCB, 0, mapType, 0, &mapped); - if (SUCCEEDED(hr)) - { - const auto cb = static_cast(mapped.pData); - cb->gamma = m_gamma; - ctx->Unmap(m_pGammaCB, 0); - } - - ID3D11RenderTargetView* oldRTV = nullptr; - ID3D11DepthStencilView* oldDSV = nullptr; - ctx->OMGetRenderTargets(1, &oldRTV, &oldDSV); - - UINT numViewports = 1; - D3D11_VIEWPORT oldViewport = {}; - ctx->RSGetViewports(&numViewports, &oldViewport); - - ID3D11RenderTargetView* bbRTV = g_pRenderTargetView; - ctx->OMSetRenderTargets(1, &bbRTV, nullptr); - D3D11_VIEWPORT vp; if (m_useCustomViewport) { @@ -369,6 +356,33 @@ void PostProcesser::ApplyFromCopied() const vp.TopLeftY = 0; } + D3D11_MAPPED_SUBRESOURCE mapped; + const D3D11_MAP mapType = m_wineMode ? D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_DISCARD; + const HRESULT hr = ctx->Map(m_pGammaCB, 0, mapType, 0, &mapped); + if (SUCCEEDED(hr)) + { + const auto cb = static_cast(mapped.pData); + cb->gamma = m_gamma; + const float texW = static_cast(m_gammaTexWidth); + const float texH = static_cast(m_gammaTexHeight); + cb->uvOffsetX = vp.TopLeftX / texW; + cb->uvOffsetY = vp.TopLeftY / texH; + cb->uvScaleX = vp.Width / texW; + cb->uvScaleY = vp.Height / texH; + ctx->Unmap(m_pGammaCB, 0); + } + + ID3D11RenderTargetView* oldRTV = nullptr; + ID3D11DepthStencilView* oldDSV = nullptr; + ctx->OMGetRenderTargets(1, &oldRTV, &oldDSV); + + UINT numViewports = 1; + D3D11_VIEWPORT oldViewport = {}; + ctx->RSGetViewports(&numViewports, &oldViewport); + + ID3D11RenderTargetView* bbRTV = g_pRenderTargetView; + ctx->OMSetRenderTargets(1, &bbRTV, nullptr); + ctx->RSSetViewports(1, &vp); ctx->IASetInputLayout(nullptr);