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 "BsCorePrerequisites.h"
6#include "Image/BsTexture.h"
7#include "RenderAPI/BsRenderTarget.h"
8
9namespace bs
10{
11 /** @addtogroup RenderAPI
12 * @{
13 */
14
15 /** Structure that describes a render texture color and depth/stencil surfaces. */
16 struct BS_CORE_EXPORT RENDER_TEXTURE_DESC
17 {
18 RENDER_SURFACE_DESC colorSurfaces[BS_MAX_MULTIPLE_RENDER_TARGETS];
19 RENDER_SURFACE_DESC depthStencilSurface;
20 };
21
22 namespace ct { struct RENDER_TEXTURE_DESC; }
23
24 /** Contains various properties that describe a render texture. */
25 class BS_CORE_EXPORT RenderTextureProperties : public RenderTargetProperties
26 {
27 public:
28 RenderTextureProperties(const RENDER_TEXTURE_DESC& desc, bool requiresFlipping);
29 RenderTextureProperties(const ct::RENDER_TEXTURE_DESC& desc, bool requiresFlipping);
30 virtual ~RenderTextureProperties() { }
31
32 private:
33 void construct(const TextureProperties* textureProps, UINT32 numSlices, UINT32 mipLevel, bool requiresFlipping,
34 bool hwGamma);
35
36 friend class ct::RenderTexture;
37 friend class RenderTexture;
38 };
39
40 /**
41 * Render target specialization that allows you to render into one or multiple textures. Such textures can then be used
42 * in other operations as GPU program input.
43 *
44 * @note Sim thread only. Retrieve core implementation from getCore() for core thread only functionality.
45 */
46 class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Rendering) RenderTexture : public RenderTarget
47 {
48 public:
49 virtual ~RenderTexture() = default;
50
51 /** @copydoc TextureManager::createRenderTexture(const TEXTURE_DESC&, bool, PixelFormat) */
52 static SPtr<RenderTexture> create(const TEXTURE_DESC& colorDesc,
53 bool createDepth = true, PixelFormat depthStencilFormat = PF_D32);
54
55 /** @copydoc TextureManager::createRenderTexture(const RENDER_TEXTURE_DESC&) */
56 static SPtr<RenderTexture> create(const RENDER_TEXTURE_DESC& desc);
57
58 /**
59 * Returns a color surface texture you may bind as an input to an GPU program.
60 *
61 * @note Be aware that you cannot bind a render texture for reading and writing at the same time.
62 */
63 const HTexture& getColorTexture(UINT32 idx) const { return mBindableColorTex[idx]; }
64
65 /**
66 * Returns a depth/stencil surface texture you may bind as an input to an GPU program.
67 *
68 * @note Be aware that you cannot bind a render texture for reading and writing at the same time.
69 */
70 const HTexture& getDepthStencilTexture() const { return mBindableDepthStencilTex; }
71
72 /**
73 * Retrieves a core implementation of a render texture usable only from the core thread.
74 *
75 * @note Core thread only.
76 */
77 SPtr<ct::RenderTexture> getCore() const;
78
79 /** Returns properties that describe the render texture. */
80 const RenderTextureProperties& getProperties() const;
81
82 protected:
83 friend class TextureManager;
84
85 RenderTexture(const RENDER_TEXTURE_DESC& desc);
86
87 /** @copydoc CoreObject::createCore */
88 SPtr<ct::CoreObject> createCore() const override;
89
90 /** @copydoc CoreObject::syncToCore */
91 CoreSyncData syncToCore(FrameAlloc* allocator) override;
92
93 protected:
94 HTexture mBindableColorTex[BS_MAX_MULTIPLE_RENDER_TARGETS];
95 HTexture mBindableDepthStencilTex;
96
97 RENDER_TEXTURE_DESC mDesc;
98
99 /************************************************************************/
100 /* SERIALIZATION */
101 /************************************************************************/
102 public:
103 friend class RenderTextureRTTI;
104 static RTTITypeBase* getRTTIStatic();
105 RTTITypeBase* getRTTI() const override;
106 };
107
108 /** @} */
109
110 namespace ct
111 {
112 /** @addtogroup RenderAPI-Internal
113 * @{
114 */
115
116 /**
117 * @see bs::RENDER_TEXTURE_DESC
118 *
119 * @note References core textures instead of texture handles.
120 */
121 struct BS_CORE_EXPORT RENDER_TEXTURE_DESC
122 {
123 RENDER_SURFACE_DESC colorSurfaces[BS_MAX_MULTIPLE_RENDER_TARGETS];
124 RENDER_SURFACE_DESC depthStencilSurface;
125 };
126
127 /**
128 * Provides access to internal render texture implementation usable only from the core thread.
129 *
130 * @note Core thread only.
131 */
132 class BS_CORE_EXPORT RenderTexture : public RenderTarget
133 {
134 public:
135 RenderTexture(const RENDER_TEXTURE_DESC& desc, UINT32 deviceIdx);
136 virtual ~RenderTexture() = default;
137
138 /** @copydoc CoreObject::initialize */
139 void initialize() override;
140
141 /** @copydoc TextureManager::createRenderTexture(const RENDER_TEXTURE_DESC&, UINT32) */
142 static SPtr<RenderTexture> create(const RENDER_TEXTURE_DESC& desc, UINT32 deviceIdx = 0);
143
144 /**
145 * Returns a color surface texture you may bind as an input to an GPU program.
146 *
147 * @note Be aware that you cannot bind a render texture for reading and writing at the same time.
148 */
149 SPtr<Texture> getColorTexture(UINT32 idx) const { return mDesc.colorSurfaces[idx].texture; }
150
151 /**
152 * Returns a depth/stencil surface texture you may bind as an input to an GPU program.
153 *
154 * @note Be aware that you cannot bind a render texture for reading and writing at the same time.
155 */
156 SPtr<Texture> getDepthStencilTexture() const { return mDesc.depthStencilSurface.texture; }
157
158 /** Returns properties that describe the render texture. */
159 const RenderTextureProperties& getProperties() const;
160
161 protected:
162 /** @copydoc CoreObject::syncToCore */
163 void syncToCore(const CoreSyncData& data) override;
164
165 private:
166 /** Throws an exception of the color and depth/stencil buffers aren't compatible. */
167 void throwIfBuffersDontMatch() const;
168
169 protected:
170 friend class bs::RenderTexture;
171
172 SPtr<TextureView> mColorSurfaces[BS_MAX_MULTIPLE_RENDER_TARGETS];
173 SPtr<TextureView> mDepthStencilSurface;
174
175 RENDER_TEXTURE_DESC mDesc;
176 };
177
178 /** @} */
179 }
180}