mirror of
https://github.com/LCEMP/LCEMP.git
synced 2026-04-23 15:33:58 +00:00
210 lines
7.2 KiB
C++
210 lines
7.2 KiB
C++
#include "stdafx.h"
|
|
#include "Windows64_PostProcess.h"
|
|
#include "GammaPostProcessVS.h"
|
|
#include "GammaPostProcessPS.h"
|
|
|
|
extern ID3D11Device* g_pd3dDevice;
|
|
extern ID3D11DeviceContext* g_pImmediateContext;
|
|
extern IDXGISwapChain* g_pSwapChain;
|
|
extern ID3D11RenderTargetView* g_pRenderTargetView;
|
|
|
|
static ID3D11Texture2D* g_pGammaOffscreenTex = NULL;
|
|
static ID3D11ShaderResourceView* g_pGammaOffscreenSRV = NULL;
|
|
static ID3D11RenderTargetView* g_pGammaOffscreenRTV = NULL;
|
|
static ID3D11VertexShader* g_pGammaVS = NULL;
|
|
static ID3D11PixelShader* g_pGammaPS = NULL;
|
|
static ID3D11Buffer* g_pGammaCB = NULL;
|
|
static ID3D11SamplerState* g_pGammaSampler = NULL;
|
|
static ID3D11RasterizerState* g_pGammaRastState = NULL;
|
|
static ID3D11DepthStencilState* g_pGammaDepthState = NULL;
|
|
static ID3D11BlendState* g_pGammaBlendState = NULL;
|
|
static bool g_gammaPostProcessReady = false;
|
|
static float g_gammaValue = 1.0f;
|
|
|
|
struct GammaCBData
|
|
{
|
|
float gamma;
|
|
float pad[3];
|
|
};
|
|
|
|
|
|
void SetGammaValue(float gamma)
|
|
{
|
|
g_gammaValue = gamma;
|
|
}
|
|
|
|
bool InitGammaPostProcess()
|
|
{
|
|
if (!g_pd3dDevice || !g_pSwapChain) return false;
|
|
|
|
HRESULT hr;
|
|
|
|
ID3D11Texture2D* pBackBuffer = NULL;
|
|
hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
|
|
if (FAILED(hr)) return false;
|
|
|
|
D3D11_TEXTURE2D_DESC bbDesc;
|
|
pBackBuffer->GetDesc(&bbDesc);
|
|
pBackBuffer->Release();
|
|
|
|
D3D11_TEXTURE2D_DESC texDesc;
|
|
ZeroMemory(&texDesc, sizeof(texDesc));
|
|
texDesc.Width = bbDesc.Width;
|
|
texDesc.Height = bbDesc.Height;
|
|
texDesc.MipLevels = 1;
|
|
texDesc.ArraySize = 1;
|
|
texDesc.Format = bbDesc.Format;
|
|
texDesc.SampleDesc.Count = 1;
|
|
texDesc.SampleDesc.Quality = 0;
|
|
texDesc.Usage = D3D11_USAGE_DEFAULT;
|
|
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
|
|
hr = g_pd3dDevice->CreateTexture2D(&texDesc, NULL, &g_pGammaOffscreenTex);
|
|
if (FAILED(hr)) return false;
|
|
|
|
hr = g_pd3dDevice->CreateShaderResourceView(g_pGammaOffscreenTex, NULL, &g_pGammaOffscreenSRV);
|
|
if (FAILED(hr)) return false;
|
|
|
|
hr = g_pd3dDevice->CreateRenderTargetView(g_pGammaOffscreenTex, NULL, &g_pGammaOffscreenRTV);
|
|
if (FAILED(hr)) return false;
|
|
|
|
hr = g_pd3dDevice->CreateVertexShader(g_gammaPostProcessVS, sizeof(g_gammaPostProcessVS), NULL, &g_pGammaVS);
|
|
if (FAILED(hr)) return false;
|
|
|
|
hr = g_pd3dDevice->CreatePixelShader(g_gammaPostProcessPS, sizeof(g_gammaPostProcessPS), NULL, &g_pGammaPS);
|
|
if (FAILED(hr)) return false;
|
|
|
|
D3D11_BUFFER_DESC cbDesc;
|
|
ZeroMemory(&cbDesc, sizeof(cbDesc));
|
|
cbDesc.ByteWidth = sizeof(GammaCBData);
|
|
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
|
|
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
|
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
|
GammaCBData initData = { 1.0f, {0, 0, 0} };
|
|
D3D11_SUBRESOURCE_DATA srData;
|
|
srData.pSysMem = &initData;
|
|
srData.SysMemPitch = 0;
|
|
srData.SysMemSlicePitch = 0;
|
|
hr = g_pd3dDevice->CreateBuffer(&cbDesc, &srData, &g_pGammaCB);
|
|
if (FAILED(hr)) return false;
|
|
|
|
D3D11_SAMPLER_DESC sampDesc;
|
|
ZeroMemory(&sampDesc, sizeof(sampDesc));
|
|
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
|
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
|
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
|
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
|
hr = g_pd3dDevice->CreateSamplerState(&sampDesc, &g_pGammaSampler);
|
|
if (FAILED(hr)) return false;
|
|
|
|
D3D11_RASTERIZER_DESC rasDesc;
|
|
ZeroMemory(&rasDesc, sizeof(rasDesc));
|
|
rasDesc.FillMode = D3D11_FILL_SOLID;
|
|
rasDesc.CullMode = D3D11_CULL_NONE;
|
|
rasDesc.DepthClipEnable = FALSE;
|
|
hr = g_pd3dDevice->CreateRasterizerState(&rasDesc, &g_pGammaRastState);
|
|
if (FAILED(hr)) return false;
|
|
|
|
// Depth stencil state (disabled)
|
|
D3D11_DEPTH_STENCIL_DESC dsDesc;
|
|
ZeroMemory(&dsDesc, sizeof(dsDesc));
|
|
dsDesc.DepthEnable = FALSE;
|
|
dsDesc.StencilEnable = FALSE;
|
|
hr = g_pd3dDevice->CreateDepthStencilState(&dsDesc, &g_pGammaDepthState);
|
|
if (FAILED(hr)) return false;
|
|
|
|
D3D11_BLEND_DESC blendDesc;
|
|
ZeroMemory(&blendDesc, sizeof(blendDesc));
|
|
blendDesc.RenderTarget[0].BlendEnable = FALSE;
|
|
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
|
hr = g_pd3dDevice->CreateBlendState(&blendDesc, &g_pGammaBlendState);
|
|
if (FAILED(hr)) return false;
|
|
|
|
g_gammaPostProcessReady = true;
|
|
return true;
|
|
}
|
|
|
|
void ApplyGammaPostProcess()
|
|
{
|
|
if (!g_gammaPostProcessReady) return;
|
|
|
|
if (g_gammaValue > 0.99f && g_gammaValue < 1.01f) return;
|
|
|
|
ID3D11DeviceContext* ctx = g_pImmediateContext;
|
|
|
|
ID3D11Texture2D* pBackBuffer = NULL;
|
|
HRESULT hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
|
|
if (FAILED(hr)) return;
|
|
ctx->CopyResource(g_pGammaOffscreenTex, pBackBuffer);
|
|
|
|
D3D11_MAPPED_SUBRESOURCE mapped;
|
|
hr = ctx->Map(g_pGammaCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
GammaCBData* cb = (GammaCBData*)mapped.pData;
|
|
cb->gamma = g_gammaValue;
|
|
ctx->Unmap(g_pGammaCB, 0);
|
|
}
|
|
|
|
ID3D11RenderTargetView* oldRTV = NULL;
|
|
ID3D11DepthStencilView* oldDSV = NULL;
|
|
ctx->OMGetRenderTargets(1, &oldRTV, &oldDSV);
|
|
|
|
UINT numViewports = 1;
|
|
D3D11_VIEWPORT oldViewport;
|
|
ctx->RSGetViewports(&numViewports, &oldViewport);
|
|
|
|
ID3D11RenderTargetView* bbRTV = g_pRenderTargetView;
|
|
ctx->OMSetRenderTargets(1, &bbRTV, NULL);
|
|
|
|
// Set viewport to full screen
|
|
D3D11_TEXTURE2D_DESC bbDesc;
|
|
pBackBuffer->GetDesc(&bbDesc);
|
|
pBackBuffer->Release();
|
|
|
|
D3D11_VIEWPORT vp;
|
|
vp.Width = (FLOAT)bbDesc.Width;
|
|
vp.Height = (FLOAT)bbDesc.Height;
|
|
vp.MinDepth = 0.0f;
|
|
vp.MaxDepth = 1.0f;
|
|
vp.TopLeftX = 0;
|
|
vp.TopLeftY = 0;
|
|
ctx->RSSetViewports(1, &vp);
|
|
|
|
ctx->IASetInputLayout(NULL);
|
|
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
|
ctx->VSSetShader(g_pGammaVS, NULL, 0);
|
|
ctx->PSSetShader(g_pGammaPS, NULL, 0);
|
|
ctx->PSSetShaderResources(0, 1, &g_pGammaOffscreenSRV);
|
|
ctx->PSSetSamplers(0, 1, &g_pGammaSampler);
|
|
ctx->PSSetConstantBuffers(0, 1, &g_pGammaCB);
|
|
ctx->RSSetState(g_pGammaRastState);
|
|
ctx->OMSetDepthStencilState(g_pGammaDepthState, 0);
|
|
float blendFactor[4] = { 0, 0, 0, 0 };
|
|
ctx->OMSetBlendState(g_pGammaBlendState, blendFactor, 0xFFFFFFFF);
|
|
|
|
ctx->Draw(3, 0);
|
|
|
|
ID3D11ShaderResourceView* nullSRV = NULL;
|
|
ctx->PSSetShaderResources(0, 1, &nullSRV);
|
|
|
|
ctx->OMSetRenderTargets(1, &oldRTV, oldDSV);
|
|
ctx->RSSetViewports(1, &oldViewport);
|
|
if (oldRTV) oldRTV->Release();
|
|
if (oldDSV) oldDSV->Release();
|
|
}
|
|
|
|
void CleanupGammaPostProcess()
|
|
{
|
|
if (g_pGammaBlendState) { g_pGammaBlendState->Release(); g_pGammaBlendState = NULL; }
|
|
if (g_pGammaDepthState) { g_pGammaDepthState->Release(); g_pGammaDepthState = NULL; }
|
|
if (g_pGammaRastState) { g_pGammaRastState->Release(); g_pGammaRastState = NULL; }
|
|
if (g_pGammaSampler) { g_pGammaSampler->Release(); g_pGammaSampler = NULL; }
|
|
if (g_pGammaCB) { g_pGammaCB->Release(); g_pGammaCB = NULL; }
|
|
if (g_pGammaPS) { g_pGammaPS->Release(); g_pGammaPS = NULL; }
|
|
if (g_pGammaVS) { g_pGammaVS->Release(); g_pGammaVS = NULL; }
|
|
if (g_pGammaOffscreenRTV) { g_pGammaOffscreenRTV->Release(); g_pGammaOffscreenRTV = NULL; }
|
|
if (g_pGammaOffscreenSRV) { g_pGammaOffscreenSRV->Release(); g_pGammaOffscreenSRV = NULL; }
|
|
if (g_pGammaOffscreenTex) { g_pGammaOffscreenTex->Release(); g_pGammaOffscreenTex = NULL; }
|
|
g_gammaPostProcessReady = false;
|
|
}
|