1+ #pragma once
2+ #include " pch.h"
3+ #include " Env.h"
4+ #include < directxcolors.h>
5+
6+ using namespace DirectX ;
7+
8+
9+ struct SimpleVertex {
10+ XMFLOAT3 Pos;
11+ XMFLOAT4 TexCoord;
12+ };
13+
14+
15+ class Effect {
16+ public:
17+ Effect (D2D_SIZE_U inputSize, ID3D11RenderTargetView* output, ID3D11SamplerState* linearSampler, D2D1_VECTOR_2F scale): _output(output), _linearSampler(linearSampler) {
18+ _d3dDevice = Env::$instance->GetD3DDevice ();
19+ _d3dDC = Env::$instance->GetD3DDC ();
20+
21+ ComPtr<ID3D11Resource> outputResource;
22+ output->GetResource (&outputResource);
23+ ComPtr<ID3D11Texture2D> outputTexture;
24+ outputResource.As <ID3D11Texture2D>(&outputTexture);
25+ D3D11_TEXTURE2D_DESC desc;
26+ outputTexture->GetDesc (&desc);
27+ D2D1_SIZE_U outputTextureSize = { desc.Width , desc.Height };
28+
29+ _vp.Width = (float )outputTextureSize.width ;
30+ _vp.Height = (float )outputTextureSize.height ;
31+ _vp.MinDepth = 0 .0f ;
32+ _vp.MaxDepth = 1 .0f ;
33+
34+ // 编译顶点着色器
35+ ComPtr<ID3DBlob> blob = nullptr ;
36+ Debug::ThrowIfComFailed (
37+ _CompileShaderFromFile (L" shaders\\ Lanczos6.hlsl" , " VS" , " vs_5_0" , &blob),
38+ L" "
39+ );
40+
41+ Debug::ThrowIfComFailed (
42+ _d3dDevice->CreateVertexShader (blob->GetBufferPointer (), blob->GetBufferSize (), nullptr , &_vsShader),
43+ L" "
44+ );
45+
46+ // 创建输入布局
47+ D3D11_INPUT_ELEMENT_DESC layout[] = {
48+ { " POSITION" , 0 , DXGI_FORMAT_R32G32B32_FLOAT, 0 , 0 , D3D11_INPUT_PER_VERTEX_DATA, 0 },
49+ { " TEXCOORD" , 0 , DXGI_FORMAT_R32G32B32A32_FLOAT, 0 , sizeof (XMFLOAT3), D3D11_INPUT_PER_VERTEX_DATA, 0 },
50+ };
51+ UINT numElements = ARRAYSIZE (layout);
52+ Debug::ThrowIfComFailed (
53+ _d3dDevice->CreateInputLayout (layout, numElements, blob->GetBufferPointer (),
54+ blob->GetBufferSize (), &_vtxLayout),
55+ L" "
56+ );
57+
58+ // 编译像素着色器
59+ Debug::ThrowIfComFailed (
60+ _CompileShaderFromFile (L" shaders\\ Lanczos6.hlsl" , " PS" , " ps_5_0" , &blob),
61+ L" "
62+ );
63+ Debug::ThrowIfComFailed (
64+ _d3dDevice->CreatePixelShader (blob->GetBufferPointer (), blob->GetBufferSize (), nullptr , &_psShader),
65+ L" "
66+ );
67+
68+
69+ // 创建顶点缓冲区
70+ D2D1_SIZE_U outputSize = {
71+ (UINT32)lroundf (inputSize.width * scale.x ),
72+ (UINT32)lroundf (inputSize.height * scale.y )
73+ };
74+
75+ float outputLeft, outputTop, outputRight, outputBottom;
76+ if (outputTextureSize.width == outputSize.width && outputTextureSize.height == outputSize.height ) {
77+ outputLeft = outputBottom = -1 ;
78+ outputRight = outputTop = 1 ;
79+ } else {
80+ outputLeft = std::floorf (((float )outputTextureSize.width - outputSize.width ) / 2 ) * 2 / outputTextureSize.width - 1 ;
81+ outputTop = 1 - std::ceilf (((float )outputTextureSize.height - outputSize.height ) / 2 ) * 2 / outputTextureSize.height ;
82+ outputRight = outputLeft + 2 * outputSize.width / (float )outputTextureSize.width ;
83+ outputBottom = outputTop - 2 * outputSize.height / (float )outputTextureSize.height ;
84+ }
85+
86+ float pixelWidth = 1 .0f / inputSize.width ;
87+ float pixelHeight = 1 .0f / inputSize.height ;
88+ SimpleVertex vertices[] = {
89+ { XMFLOAT3 (outputLeft, outputTop, 0 .5f ), XMFLOAT4 (0 .0f , 0 .0f , pixelWidth, pixelHeight)},
90+ { XMFLOAT3 (outputRight, outputTop, 0 .5f ), XMFLOAT4 (1 .0f , 0 .0f , pixelWidth, pixelHeight) },
91+ { XMFLOAT3 (outputLeft, outputBottom, 0 .5f ), XMFLOAT4 (0 .0f , 1 .0f , pixelWidth, pixelHeight) },
92+ { XMFLOAT3 (outputRight, outputBottom, 0 .5f ), XMFLOAT4 (1 .0f , 1 .0f , pixelWidth, pixelHeight) }
93+ };
94+ D3D11_BUFFER_DESC bd = {};
95+ bd.Usage = D3D11_USAGE_DEFAULT;
96+ bd.ByteWidth = sizeof (vertices);
97+ bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
98+
99+ D3D11_SUBRESOURCE_DATA InitData = {};
100+ InitData.pSysMem = vertices;
101+ Debug::ThrowIfComFailed (
102+ _d3dDevice->CreateBuffer (&bd, &InitData, &_vtxBuffer),
103+ L" "
104+ );
105+ }
106+
107+ void Apply (ID3D11ShaderResourceView* input) {
108+ _d3dDC->RSSetViewports (1 , &_vp);
109+ _d3dDC->OMSetRenderTargets (1 , &_output, nullptr );
110+
111+ _d3dDC->IASetInputLayout (_vtxLayout.Get ());
112+
113+ UINT stride = sizeof (SimpleVertex);
114+ UINT offset = 0 ;
115+ auto t = _vtxBuffer.Get ();
116+ _d3dDC->IASetVertexBuffers (0 , 1 , &t, &stride, &offset);
117+
118+ _d3dDC->VSSetShader (_vsShader.Get (), nullptr , 0 );
119+
120+ _d3dDC->PSSetShader (_psShader.Get (), nullptr , 0 );
121+ _d3dDC->PSSetSamplers (0 , 1 , &_linearSampler);
122+ _d3dDC->PSSetShaderResources (0 , 1 , &input);
123+
124+ _d3dDC->Draw (4 , 0 );
125+ }
126+ private:
127+ HRESULT _CompileShaderFromFile (const WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut) {
128+ DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
129+ #ifdef _DEBUG
130+ // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
131+ // Setting this flag improves the shader debugging experience, but still allows
132+ // the shaders to be optimized and to run exactly the way they will run in
133+ // the release configuration of this program.
134+ dwShaderFlags |= D3DCOMPILE_DEBUG;
135+
136+ // Disable optimizations to further improve shader debugging
137+ dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION;
138+ #endif
139+
140+ ComPtr<ID3DBlob> pErrorBlob = nullptr ;
141+ HRESULT hr = D3DCompileFromFile (szFileName, nullptr , nullptr , szEntryPoint, szShaderModel,
142+ dwShaderFlags, 0 , ppBlobOut, &pErrorBlob);
143+ if (FAILED (hr)) {
144+ if (pErrorBlob) {
145+ OutputDebugStringA (reinterpret_cast <const char *>(pErrorBlob->GetBufferPointer ()));
146+ }
147+ return hr;
148+ }
149+
150+ return S_OK;
151+ }
152+
153+
154+ ID3D11Device3* _d3dDevice = nullptr ;
155+ ID3D11DeviceContext4* _d3dDC = nullptr ;
156+ ID3D11SamplerState* _linearSampler = nullptr ;
157+ ComPtr<ID3D11VertexShader> _vsShader = nullptr ;
158+ ComPtr<ID3D11PixelShader> _psShader = nullptr ;
159+ ComPtr<ID3D11InputLayout> _vtxLayout = nullptr ;
160+ ComPtr<ID3D11Buffer> _vtxBuffer = nullptr ;
161+
162+ ID3D11RenderTargetView* _output;
163+ D3D11_VIEWPORT _vp{};
164+ };
0 commit comments