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
13namespace 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