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 | #pragma once |
4 | |
5 | #include "BsPrerequisites.h" |
6 | #include "Utility/BsModule.h" |
7 | #include "Math/BsRect2.h" |
8 | #include "Math/BsVector2I.h" |
9 | #include "Math/BsRect2I.h" |
10 | #include "Renderer/BsRendererMaterial.h" |
11 | #include "Renderer/BsParamBlocks.h" |
12 | |
13 | namespace bs { namespace ct |
14 | { |
15 | /** @addtogroup Renderer-Engine-Internal |
16 | * @{ |
17 | */ |
18 | |
19 | /** Shader that copies a source texture into a render target, and optionally resolves it. */ |
20 | class BlitMat : public RendererMaterial<BlitMat> |
21 | { |
22 | RMAT_DEF("Blit.bsl" ); |
23 | |
24 | /** Helper method used for initializing variations of this material. */ |
25 | template<UINT32 msaa, bool color> |
26 | static const ShaderVariation& getVariation() |
27 | { |
28 | static ShaderVariation variation = ShaderVariation( |
29 | SmallVector<ShaderVariation::Param, 4>({ |
30 | ShaderVariation::Param("MSAA_COUNT" , msaa), |
31 | ShaderVariation::Param("COLOR" , color), |
32 | })); |
33 | |
34 | return variation; |
35 | } |
36 | public: |
37 | BlitMat(); |
38 | |
39 | /** Executes the material on the currently bound render target, copying from @p source. */ |
40 | void execute(const SPtr<Texture>& source, const Rect2& area, bool flipUV); |
41 | |
42 | /** |
43 | * Returns the material variation matching the provided parameters. |
44 | * |
45 | * @param msaaCount Number of MSAA samples in the input texture. If larger than 1 the texture will be resolved |
46 | * before written to the destination. |
47 | * @param isColor If true the input is assumed to be a 4-component color texture. If false it is assumed |
48 | * the input is a 1-component depth texture. This controls how is the texture resolve and is |
49 | * only relevant if @p msaaCount > 1. Color texture MSAA samples will be averaged, while for |
50 | * depth textures the minimum of all samples will be used. |
51 | */ |
52 | static BlitMat* getVariation(UINT32 msaaCount, bool isColor); |
53 | private: |
54 | GpuParamTexture mSource; |
55 | }; |
56 | |
57 | BS_PARAM_BLOCK_BEGIN(ClearParamDef) |
58 | BS_PARAM_BLOCK_ENTRY(INT32, gClearValue) |
59 | BS_PARAM_BLOCK_END |
60 | |
61 | extern ClearParamDef gClearParamDef; |
62 | |
63 | /** Shader that clears the currently bound render target to an integer value. */ |
64 | class ClearMat : public RendererMaterial<ClearMat> |
65 | { |
66 | RMAT_DEF("Clear.bsl" ); |
67 | |
68 | public: |
69 | ClearMat(); |
70 | |
71 | /** Executes the material on the currently bound render target, clearing to to @p value. */ |
72 | void execute(UINT32 value); |
73 | private: |
74 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
75 | }; |
76 | |
77 | /** |
78 | * Contains various utility methods that make various common operations in the renderer easier. |
79 | * |
80 | * @note Core thread only. |
81 | */ |
82 | class BS_EXPORT RendererUtility : public Module<RendererUtility> |
83 | { |
84 | public: |
85 | RendererUtility(); |
86 | ~RendererUtility() = default; |
87 | |
88 | /** |
89 | * Activates the specified material pass for rendering. Any further draw calls will be executed using this pass. |
90 | * |
91 | * @param[in] material Material containing the pass. |
92 | * @param[in] passIdx Index of the pass in the material. |
93 | * @param[in] techniqueIdx Index of the technique the pass belongs to, if the material has multiple techniques. |
94 | * |
95 | * @note Core thread. |
96 | */ |
97 | void setPass(const SPtr<Material>& material, UINT32 passIdx = 0, UINT32 techniqueIdx = 0); |
98 | |
99 | /** |
100 | * Activates the specified material pass for compute. Any further dispatch calls will be executed using this pass. |
101 | * |
102 | * @param[in] material Material containing the pass. |
103 | * @param[in] passIdx Index of the pass in the material. |
104 | * |
105 | * @note Core thread. |
106 | */ |
107 | void setComputePass(const SPtr<Material>& material, UINT32 passIdx = 0); |
108 | |
109 | /** |
110 | * Sets parameters (textures, samplers, buffers) for the currently active pass. |
111 | * |
112 | * @param[in] params Object containing the parameters. |
113 | * @param[in] passIdx Pass for which to set the parameters. |
114 | * |
115 | * @note Core thread. |
116 | */ |
117 | void setPassParams(const SPtr<GpuParamsSet>& params, UINT32 passIdx = 0); |
118 | |
119 | /** |
120 | * Draws the specified mesh. |
121 | * |
122 | * @param[in] mesh Mesh to draw. |
123 | * @param[in] numInstances Number of times to draw the mesh using instanced rendering. |
124 | * |
125 | * @note Core thread. |
126 | */ |
127 | void draw(const SPtr<MeshBase>& mesh, UINT32 numInstances = 1); |
128 | |
129 | /** |
130 | * Draws the specified mesh. |
131 | * |
132 | * @param[in] mesh Mesh to draw. |
133 | * @param[in] subMesh Portion of the mesh to draw. |
134 | * @param[in] numInstances Number of times to draw the mesh using instanced rendering. |
135 | * |
136 | * @note Core thread. |
137 | */ |
138 | void draw(const SPtr<MeshBase>& mesh, const SubMesh& subMesh, UINT32 numInstances = 1); |
139 | |
140 | /** |
141 | * Draws the specified mesh with an additional vertex buffer containing morph shape vertices. |
142 | * |
143 | * @param[in] mesh Mesh to draw. |
144 | * @param[in] subMesh Portion of the mesh to draw. |
145 | * @param[in] morphVertices Buffer containing the morph shape vertices. Will be bound to stream 1. |
146 | * Expected to contain the same number of vertices as the source mesh. |
147 | * @param[in] morphVertexDeclaration Vertex declaration describing vertices of the provided mesh and the vertices |
148 | * provided in the morph vertex buffer. |
149 | * |
150 | * @note Core thread. |
151 | */ |
152 | void drawMorph(const SPtr<MeshBase>& mesh, const SubMesh& subMesh, const SPtr<VertexBuffer>& morphVertices, |
153 | const SPtr<VertexDeclaration>& morphVertexDeclaration); |
154 | |
155 | /** |
156 | * Blits contents of the provided texture into the currently bound render target. If the provided texture contains |
157 | * multiple samples, they will be resolved. |
158 | * |
159 | * @param[in] texture Source texture to blit. |
160 | * @param[in] area Area of the source texture to blit in pixels. If width or height is zero it is assumed |
161 | * the entire texture should be blitted. |
162 | * @param[in] flipUV If true, vertical UV coordinate will be flipped upside down. |
163 | * @param[in] isDepth If true, the input texture is assumed to be a depth texture (instead of a color one). |
164 | * Multisampled depth textures will be resolved by taking the minimum value of all samples, |
165 | * unlike color textures which wil be averaged. |
166 | */ |
167 | void blit(const SPtr<Texture>& texture, const Rect2I& area = Rect2I::EMPTY, bool flipUV = false, |
168 | bool isDepth = false); |
169 | |
170 | /** |
171 | * Draws a quad over the entire viewport in normalized device coordinates. |
172 | * |
173 | * @param[in] uv UV coordinates to assign to the corners of the quad. |
174 | * @param[in] textureSize Size of the texture the UV coordinates are specified for. If the UV coordinates are |
175 | * already in normalized (0, 1) range then keep this value as is. If the UV coordinates |
176 | * are in texels then set this value to the texture size so they can be normalized |
177 | * internally. |
178 | * @param[in] numInstances How many instances of the quad to draw (using instanced rendering). Useful when |
179 | * drawing to 3D textures. |
180 | * @param[in] flipUV If true, vertical UV coordinate will be flipped upside down. |
181 | * |
182 | * @note Core thread. |
183 | */ |
184 | void drawScreenQuad(const Rect2& uv, const Vector2I& textureSize = Vector2I(1, 1), |
185 | UINT32 numInstances = 1, bool flipUV = false); |
186 | |
187 | /** |
188 | * Draws a quad over the entire viewport in normalized device coordinates. |
189 | * |
190 | * @param[in] numInstances How many instances of the quad to draw (using instanced rendering). Useful when |
191 | * drawing to 3D textures. |
192 | * |
193 | * @note Core thread. |
194 | */ |
195 | void drawScreenQuad(UINT32 numInstances = 1) |
196 | { |
197 | Rect2 uv(0.0f, 0.0f, 1.0f, 1.0f); |
198 | Vector2I textureSize(1, 1); |
199 | |
200 | drawScreenQuad(uv, textureSize, numInstances); |
201 | } |
202 | |
203 | /** |
204 | * Clears the currently bound render target to the provided integer value. This is similar to |
205 | * RenderAPI::clearRenderTarget(), except it supports integer clears. |
206 | */ |
207 | void clear(UINT32 value); |
208 | |
209 | /** Returns a unit sphere stencil mesh. */ |
210 | SPtr<Mesh> getSphereStencil() const { return mUnitSphereStencilMesh; } |
211 | |
212 | /** Returns a unit axis aligned box stencil mesh. */ |
213 | SPtr<Mesh> getBoxStencil() const { return mUnitBoxStencilMesh; } |
214 | |
215 | /** |
216 | * Returns a stencil mesh used for a spot light. Actual vertex positions need to be computed in shader as this |
217 | * method will return uninitialized vertex positions. |
218 | */ |
219 | SPtr<Mesh> getSpotLightStencil() const { return mSpotLightStencilMesh; } |
220 | |
221 | /** Returns a mesh that can be used for rendering a skybox. */ |
222 | SPtr<Mesh> getSkyBoxMesh() const { return mSkyBoxMesh; } |
223 | |
224 | private: |
225 | static constexpr UINT32 NUM_QUAD_VB_SLOTS = 1024; |
226 | |
227 | SPtr<IndexBuffer> mFullScreenQuadIB; |
228 | SPtr<VertexBuffer> mFullScreenQuadVB; |
229 | SPtr<VertexDataDesc> mFullscreenQuadVDesc; |
230 | SPtr<VertexDeclaration> mFullscreenQuadVDecl; |
231 | UINT32 mNextQuadVBSlot = 0; |
232 | |
233 | SPtr<Mesh> mUnitSphereStencilMesh; |
234 | SPtr<Mesh> mUnitBoxStencilMesh; |
235 | SPtr<Mesh> mSpotLightStencilMesh; |
236 | SPtr<Mesh> mSkyBoxMesh; |
237 | }; |
238 | |
239 | /** Provides easy access to RendererUtility. */ |
240 | BS_EXPORT RendererUtility& gRendererUtility(); |
241 | |
242 | /** @} */ |
243 | }} |
244 | |