1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #include "RenderAPI/BsBlendState.h" |
4 | #include "Managers/BsRenderStateManager.h" |
5 | #include "RenderAPI/BsRenderAPI.h" |
6 | #include "Private/RTTI/BsBlendStateRTTI.h" |
7 | #include "Resources/BsResources.h" |
8 | |
9 | namespace bs |
10 | { |
11 | bool RENDER_TARGET_BLEND_STATE_DESC::operator == (const RENDER_TARGET_BLEND_STATE_DESC& rhs) const |
12 | { |
13 | return blendEnable == rhs.blendEnable && |
14 | srcBlend == rhs.srcBlend && |
15 | dstBlend == rhs.dstBlend && |
16 | blendOp == rhs.blendOp && |
17 | srcBlendAlpha == rhs.srcBlendAlpha && |
18 | dstBlendAlpha == rhs.dstBlendAlpha && |
19 | blendOpAlpha == rhs.blendOpAlpha && |
20 | renderTargetWriteMask == rhs.renderTargetWriteMask; |
21 | } |
22 | |
23 | bool BLEND_STATE_DESC::operator == (const BLEND_STATE_DESC& rhs) const |
24 | { |
25 | bool equals = alphaToCoverageEnable == rhs.alphaToCoverageEnable && |
26 | independantBlendEnable == rhs.independantBlendEnable; |
27 | |
28 | if (equals) |
29 | { |
30 | for (UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++) |
31 | { |
32 | equals &= renderTargetDesc[i] == rhs.renderTargetDesc[i]; |
33 | } |
34 | } |
35 | |
36 | return equals; |
37 | } |
38 | |
39 | BlendProperties::BlendProperties(const BLEND_STATE_DESC& desc) |
40 | :mData(desc), mHash(BlendState::generateHash(desc)) |
41 | { } |
42 | |
43 | bool BlendProperties::getBlendEnabled(UINT32 renderTargetIdx) const |
44 | { |
45 | assert(renderTargetIdx < BS_MAX_MULTIPLE_RENDER_TARGETS); |
46 | |
47 | return mData.renderTargetDesc[renderTargetIdx].blendEnable; |
48 | } |
49 | |
50 | BlendFactor BlendProperties::getSrcBlend(UINT32 renderTargetIdx) const |
51 | { |
52 | assert(renderTargetIdx < BS_MAX_MULTIPLE_RENDER_TARGETS); |
53 | |
54 | return mData.renderTargetDesc[renderTargetIdx].srcBlend; |
55 | } |
56 | |
57 | BlendFactor BlendProperties::getDstBlend(UINT32 renderTargetIdx) const |
58 | { |
59 | assert(renderTargetIdx < BS_MAX_MULTIPLE_RENDER_TARGETS); |
60 | |
61 | return mData.renderTargetDesc[renderTargetIdx].dstBlend; |
62 | } |
63 | |
64 | BlendOperation BlendProperties::getBlendOperation(UINT32 renderTargetIdx) const |
65 | { |
66 | assert(renderTargetIdx < BS_MAX_MULTIPLE_RENDER_TARGETS); |
67 | |
68 | return mData.renderTargetDesc[renderTargetIdx].blendOp; |
69 | } |
70 | |
71 | BlendFactor BlendProperties::getAlphaSrcBlend(UINT32 renderTargetIdx) const |
72 | { |
73 | assert(renderTargetIdx < BS_MAX_MULTIPLE_RENDER_TARGETS); |
74 | |
75 | return mData.renderTargetDesc[renderTargetIdx].srcBlendAlpha; |
76 | } |
77 | |
78 | BlendFactor BlendProperties::getAlphaDstBlend(UINT32 renderTargetIdx) const |
79 | { |
80 | assert(renderTargetIdx < BS_MAX_MULTIPLE_RENDER_TARGETS); |
81 | |
82 | return mData.renderTargetDesc[renderTargetIdx].dstBlendAlpha; |
83 | } |
84 | |
85 | BlendOperation BlendProperties::getAlphaBlendOperation(UINT32 renderTargetIdx) const |
86 | { |
87 | assert(renderTargetIdx < BS_MAX_MULTIPLE_RENDER_TARGETS); |
88 | |
89 | return mData.renderTargetDesc[renderTargetIdx].blendOpAlpha; |
90 | } |
91 | |
92 | UINT8 BlendProperties::getRenderTargetWriteMask(UINT32 renderTargetIdx) const |
93 | { |
94 | assert(renderTargetIdx < BS_MAX_MULTIPLE_RENDER_TARGETS); |
95 | |
96 | return mData.renderTargetDesc[renderTargetIdx].renderTargetWriteMask; |
97 | } |
98 | |
99 | BlendState::BlendState(const BLEND_STATE_DESC& desc) |
100 | :mProperties(desc), mId(0) |
101 | { } |
102 | |
103 | BlendState::~BlendState() |
104 | { |
105 | |
106 | } |
107 | |
108 | SPtr<ct::BlendState> BlendState::getCore() const |
109 | { |
110 | return std::static_pointer_cast<ct::BlendState>(mCoreSpecific); |
111 | } |
112 | |
113 | SPtr<ct::CoreObject> BlendState::createCore() const |
114 | { |
115 | SPtr<ct::BlendState> core = ct::RenderStateManager::instance()._createBlendState(mProperties.mData); |
116 | mId = core->getId(); // Accessing core from sim thread is okay here since core ID is immutable |
117 | |
118 | return core; |
119 | } |
120 | |
121 | const BlendProperties& BlendState::getProperties() const |
122 | { |
123 | return mProperties; |
124 | } |
125 | |
126 | const SPtr<BlendState>& BlendState::getDefault() |
127 | { |
128 | return RenderStateManager::instance().getDefaultBlendState(); |
129 | } |
130 | |
131 | SPtr<BlendState> BlendState::create(const BLEND_STATE_DESC& desc) |
132 | { |
133 | return RenderStateManager::instance().createBlendState(desc); |
134 | } |
135 | |
136 | UINT64 BlendState::generateHash(const BLEND_STATE_DESC& desc) |
137 | { |
138 | size_t hash = 0; |
139 | bs_hash_combine(hash, desc.alphaToCoverageEnable); |
140 | bs_hash_combine(hash, desc.independantBlendEnable); |
141 | |
142 | for (UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++) |
143 | { |
144 | bs_hash_combine(hash, desc.renderTargetDesc[i].blendEnable); |
145 | bs_hash_combine(hash, (UINT32)desc.renderTargetDesc[i].srcBlend); |
146 | bs_hash_combine(hash, (UINT32)desc.renderTargetDesc[i].dstBlend); |
147 | bs_hash_combine(hash, (UINT32)desc.renderTargetDesc[i].blendOp); |
148 | bs_hash_combine(hash, (UINT32)desc.renderTargetDesc[i].srcBlendAlpha); |
149 | bs_hash_combine(hash, (UINT32)desc.renderTargetDesc[i].dstBlendAlpha); |
150 | bs_hash_combine(hash, (UINT32)desc.renderTargetDesc[i].blendOpAlpha); |
151 | bs_hash_combine(hash, desc.renderTargetDesc[i].renderTargetWriteMask); |
152 | } |
153 | |
154 | return (UINT64)hash; |
155 | } |
156 | |
157 | /************************************************************************/ |
158 | /* RTTI */ |
159 | /************************************************************************/ |
160 | |
161 | RTTITypeBase* BlendState::getRTTIStatic() |
162 | { |
163 | return BlendStateRTTI::instance(); |
164 | } |
165 | |
166 | RTTITypeBase* BlendState::getRTTI() const |
167 | { |
168 | return BlendState::getRTTIStatic(); |
169 | } |
170 | |
171 | namespace ct |
172 | { |
173 | BlendState::BlendState(const BLEND_STATE_DESC& desc, UINT32 id) |
174 | :mProperties(desc), mId(id) |
175 | { |
176 | |
177 | } |
178 | |
179 | BlendState::~BlendState() |
180 | { |
181 | |
182 | } |
183 | |
184 | void BlendState::initialize() |
185 | { |
186 | // Since we cache states it's possible this object was already initialized |
187 | // (i.e. multiple sim-states can share a single core-state) |
188 | if (isInitialized()) |
189 | return; |
190 | |
191 | createInternal(); |
192 | CoreObject::initialize(); |
193 | } |
194 | |
195 | const BlendProperties& BlendState::getProperties() const |
196 | { |
197 | return mProperties; |
198 | } |
199 | |
200 | SPtr<BlendState> BlendState::create(const BLEND_STATE_DESC& desc) |
201 | { |
202 | return RenderStateManager::instance().createBlendState(desc); |
203 | } |
204 | |
205 | const SPtr<BlendState>& BlendState::getDefault() |
206 | { |
207 | return RenderStateManager::instance().getDefaultBlendState(); |
208 | } |
209 | } |
210 | } |