-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEffectHelper.h
128 lines (101 loc) · 3.39 KB
/
EffectHelper.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//***************************************************************************************
// EffectsHelper.h by X_Jun(MKXJun) (C) 2018-2020 All Rights Reserved.
// Licensed under the MIT License.
//
// 定义一些实用的特效类
// Define utility effect classes.
//***************************************************************************************
//
// 该头文件需要在包含特效类实现的源文件中使用,且必须晚于Effects.h和d3dUtil.h包含
//
#ifndef EFFECTHELPER_H
#define EFFECTHELPER_H
// 若类需要内存对齐,从该类派生
template<class DerivedType>
struct AlignedType
{
static void* operator new(size_t size)
{
const size_t alignedSize = __alignof(DerivedType);
static_assert(alignedSize > 8, "AlignedNew is only useful for types with > 8 byte alignment! Did you forget a __declspec(align) on DerivedType?");
void* ptr = _aligned_malloc(size, alignedSize);
if (!ptr)
throw std::bad_alloc();
return ptr;
}
static void operator delete(void * ptr)
{
_aligned_free(ptr);
}
};
struct CBufferBase
{
template<class T>
using ComPtr = Microsoft::WRL::ComPtr<T>;
CBufferBase() : isDirty() {}
~CBufferBase() = default;
BOOL isDirty;
ComPtr<ID3D11Buffer> cBuffer;
virtual HRESULT CreateBuffer(ID3D11Device * device) = 0;
virtual void UpdateBuffer(ID3D11DeviceContext * deviceContext) = 0;
virtual void BindVS(ID3D11DeviceContext * deviceContext) = 0;
virtual void BindHS(ID3D11DeviceContext * deviceContext) = 0;
virtual void BindDS(ID3D11DeviceContext * deviceContext) = 0;
virtual void BindGS(ID3D11DeviceContext * deviceContext) = 0;
virtual void BindCS(ID3D11DeviceContext * deviceContext) = 0;
virtual void BindPS(ID3D11DeviceContext * deviceContext) = 0;
};
template<UINT startSlot, class T>
struct CBufferObject : CBufferBase
{
T data;
CBufferObject() : CBufferBase(), data() {}
HRESULT CreateBuffer(ID3D11Device * device) override
{
if (cBuffer != nullptr)
return S_OK;
D3D11_BUFFER_DESC cbd;
ZeroMemory(&cbd, sizeof(cbd));
cbd.Usage = D3D11_USAGE_DYNAMIC;
cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbd.ByteWidth = sizeof(T);
return device->CreateBuffer(&cbd, nullptr, cBuffer.GetAddressOf());
}
void UpdateBuffer(ID3D11DeviceContext * deviceContext) override
{
if (isDirty)
{
isDirty = false;
D3D11_MAPPED_SUBRESOURCE mappedData;
deviceContext->Map(cBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedData);
memcpy_s(mappedData.pData, sizeof(T), &data, sizeof(T));
deviceContext->Unmap(cBuffer.Get(), 0);
}
}
void BindVS(ID3D11DeviceContext * deviceContext) override
{
deviceContext->VSSetConstantBuffers(startSlot, 1, cBuffer.GetAddressOf());
}
void BindHS(ID3D11DeviceContext * deviceContext) override
{
deviceContext->HSSetConstantBuffers(startSlot, 1, cBuffer.GetAddressOf());
}
void BindDS(ID3D11DeviceContext * deviceContext) override
{
deviceContext->DSSetConstantBuffers(startSlot, 1, cBuffer.GetAddressOf());
}
void BindGS(ID3D11DeviceContext * deviceContext) override
{
deviceContext->GSSetConstantBuffers(startSlot, 1, cBuffer.GetAddressOf());
}
void BindCS(ID3D11DeviceContext * deviceContext) override
{
deviceContext->CSSetConstantBuffers(startSlot, 1, cBuffer.GetAddressOf());
}
void BindPS(ID3D11DeviceContext * deviceContext) override
{
deviceContext->PSSetConstantBuffers(startSlot, 1, cBuffer.GetAddressOf());
}
};
#endif