CmRenderSystem.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. #pragma once
  2. #include "CmPrerequisites.h"
  3. #include <memory>
  4. #include "CmString.h"
  5. #include "CmSamplerState.h"
  6. #include "CmCommonEnums.h"
  7. #include "BsRenderStats.h"
  8. #include "CmCommandQueue.h"
  9. #include "CmDrawOps.h"
  10. #include "CmRenderSystemCapabilities.h"
  11. #include "CmRenderTarget.h"
  12. #include "CmRenderTexture.h"
  13. #include "CmRenderWindow.h"
  14. #include "CmGpuProgram.h"
  15. #include "CmVertexDeclaration.h"
  16. #include "CmPlane.h"
  17. #include "CmModule.h"
  18. #include "BsEvent.h"
  19. namespace BansheeEngine
  20. {
  21. /**
  22. * @brief Render system provides base functionality for a rendering API like
  23. * DirectX or OpenGL. Most of the class is abstract and specific
  24. * subclass for each rendering API needs to be implemented.
  25. *
  26. * @note Core thread only unless specifically noted otherwise on per-method basis.
  27. */
  28. class CM_EXPORT RenderSystem : public Module<RenderSystem>
  29. {
  30. public:
  31. RenderSystem();
  32. virtual ~RenderSystem();
  33. /**
  34. * @brief Returns the name of the rendering system.
  35. *
  36. * @note Thread safe.
  37. */
  38. virtual const String& getName() const = 0;
  39. /**
  40. * @brief Gets the name of the primary shading language
  41. * used by the rendering system.
  42. *
  43. * @note Thread safe.
  44. */
  45. virtual const String& getShadingLanguageName() const = 0;
  46. /**
  47. * @brief Sets a sampler state for the specified texture unit.
  48. *
  49. * @see SamplerState
  50. */
  51. virtual void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerStatePtr& samplerState) = 0;
  52. /**
  53. * @brief Sets a blend state used for all active render targets.
  54. *
  55. * @see BlendState
  56. */
  57. virtual void setBlendState(const BlendStatePtr& blendState) = 0;
  58. /**
  59. * @brief Sets a state that controls various rasterizer options.
  60. *
  61. * @see RasterizerState
  62. */
  63. virtual void setRasterizerState(const RasterizerStatePtr& rasterizerState) = 0;
  64. /**
  65. * @brief Sets a state that controls depth & stencil buffer options.
  66. *
  67. * @see DepthStencilState
  68. */
  69. virtual void setDepthStencilState(const DepthStencilStatePtr& depthStencilState, UINT32 stencilRefValue) = 0;
  70. /**
  71. * @brief Binds a texture to the pipeline for the specified GPU program type at the specified slot.
  72. * If the slot matches the one configured in the GPU program the program will be able to access
  73. * this texture on the GPU.
  74. */
  75. virtual void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr) = 0;
  76. /**
  77. * @brief Turns off a texture unit.
  78. */
  79. virtual void disableTextureUnit(GpuProgramType gptype, UINT16 texUnit);
  80. /**
  81. * @brief Signals that rendering for a specific viewport has started. Any draw calls
  82. * need to be called between beginFrame and endFrame. You may not switch render targets
  83. * until you call endFrame.
  84. */
  85. virtual void beginFrame() = 0;
  86. /**
  87. * @brief Ends that rendering to a specific viewport has ended.
  88. */
  89. virtual void endFrame() = 0;
  90. /**
  91. * @brief Sets the active viewport that will be used for all render operations.
  92. * Viewport will change active render target if needed.
  93. */
  94. virtual void setViewport(const ViewportPtr& vp) = 0;
  95. /**
  96. * @brief Sets the provided vertex buffers starting at the specified source index.
  97. * Set buffer to nullptr to clear the buffer at the specified index.
  98. */
  99. virtual void setVertexBuffers(UINT32 index, VertexBufferPtr* buffers, UINT32 numBuffers) = 0;
  100. /**
  101. * @brief Sets an index buffer to use when drawing. Indices in an index buffer
  102. * reference vertices in the vertex buffer, which increases cache coherency
  103. * and reduces the size of vertex buffers by eliminating duplicate data.
  104. */
  105. virtual void setIndexBuffer(const IndexBufferPtr& buffer) = 0;
  106. /**
  107. * @brief Sets the vertex declaration to use when drawing. Vertex declaration
  108. * is used to decode contents of a single vertex in a vertex buffer.
  109. */
  110. virtual void setVertexDeclaration(VertexDeclarationPtr vertexDeclaration) = 0;
  111. /**
  112. * @brief Sets the draw operation that determines how to interpret the elements
  113. * of the index or vertex buffers.
  114. */
  115. virtual void setDrawOperation(DrawOperationType op) = 0;
  116. /**
  117. * @brief A helper method that provides a simple way of rendering a single object. It will
  118. * automatically set up vertex declaration, draw operation, vertex and index buffers and
  119. * draw them.
  120. *
  121. * @param mesh The mesh.
  122. * @param indexOffset (optional) Offset into the mesh buffer to start drawing from.
  123. * @param indexCount (optional) Number of indexes to draw, starting at the offset. Ignored if "drawIndexed" is false. If 0 all indices in the mesh will be drawn.
  124. * @param useIndices (optional) If true, drawing is done using the index buffer on the mesh and the provided offset and size, otherwise all mesh vertices are drawn sequentially.
  125. * @param drawOp (optional) Draw operation to use when rendering.
  126. */
  127. virtual void render(const MeshBasePtr& mesh, UINT32 indexOffset = 0, UINT32 indexCount = 0, bool useIndices = true, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
  128. /**
  129. * @brief Draw an object based on currently bound GPU programs, vertex declaration and vertex buffers.
  130. *
  131. * Draws directly from the vertex buffer without using indices.
  132. */
  133. virtual void draw(UINT32 vertexOffset, UINT32 vertexCount) = 0;
  134. /**
  135. * @brief Draw an object based on currently bound GPU programs, vertex declaration, vertex
  136. * and index buffers.
  137. */
  138. virtual void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, UINT32 vertexCount) = 0;
  139. /**
  140. * @brief Swap the front and back buffer of the specified render target.
  141. */
  142. virtual void swapBuffers(RenderTargetPtr target);
  143. /**
  144. * @brief Gets the capabilities of the render system.
  145. *
  146. * @note Thread safe.
  147. */
  148. const RenderSystemCapabilities* getCapabilities() const;
  149. /**
  150. * @brief Returns information about the driver version.
  151. */
  152. virtual const DriverVersion& getDriverVersion() const;
  153. /**
  154. * @brief Binds the provided GPU program to the pipeline. Any following
  155. * draw operations will use this program.
  156. *
  157. * @note You need to bind at least a vertex and a fragment program in order to draw something.
  158. */
  159. virtual void bindGpuProgram(HGpuProgram prg);
  160. /**
  161. * @brief Binds GPU program parameters. Caller must ensure these match the previously
  162. * bound GPU program.
  163. */
  164. virtual void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params) = 0;
  165. /**
  166. * @brief Unbinds a program of a given type.
  167. */
  168. virtual void unbindGpuProgram(GpuProgramType gptype);
  169. /**
  170. * @brief Query if a GPU program of a given type is currently bound.
  171. */
  172. virtual bool isGpuProgramBound(GpuProgramType gptype);
  173. /**
  174. * @brief Sets up clip planes that will clip drawn geometry on the negative side of the planes.
  175. */
  176. virtual void setClipPlanes(const PlaneList& clipPlanes);
  177. /**
  178. * @brief Adds a new clip plane. All drawn geometry will be clipped to this plane.
  179. */
  180. virtual void addClipPlane(const Plane& p);
  181. /**
  182. * @brief Clears all clip planes.
  183. */
  184. virtual void resetClipPlanes();
  185. /**
  186. * @brief Allows you to set up a region in which rendering can take place. Coordinates are in pixels.
  187. * No rendering will be done to render target pixels outside of the provided region.
  188. */
  189. virtual void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom) = 0;
  190. /**
  191. * @brief Clears the currently active render target.
  192. *
  193. * @param buffers Combination of one or more elements of FrameBufferType
  194. * denoting which buffers are to be cleared.
  195. * @param color (optional) The color to clear the color buffer with, if enabled.
  196. * @param depth (optional) The value to initialise the depth buffer with, if enabled.
  197. * @param stencil (optional) The value to initialise the stencil buffer with, if enabled.
  198. */
  199. virtual void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0) = 0;
  200. /**
  201. * @brief Clears the currently active viewport (i.e. it clears just a sub-area of a render-target that is covered by the viewport,
  202. * as opposed to clearRenderTarget which always clears the entire render target).
  203. *
  204. * @param buffers Combination of one or more elements of FrameBufferType
  205. * denoting which buffers are to be cleared.
  206. * @param color (optional) The color to clear the color buffer with, if enabled.
  207. * @param depth (optional) The value to initialise the depth buffer with, if enabled.
  208. * @param stencil (optional) The value to initialise the stencil buffer with, if enabled.
  209. */
  210. virtual void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0) = 0;
  211. /**
  212. * @brief Change the render target into which we want to draw.
  213. */
  214. virtual void setRenderTarget(RenderTargetPtr target) = 0;
  215. /**
  216. * @brief Updates the resource with the specified data.
  217. *
  218. * @note It is assumed GpuResourceData has been locked before being passed here. Data will be unlocked
  219. * when this method finishes.
  220. */
  221. void writeSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceDataPtr& data, bool discardEntireBuffer, AsyncOp& asyncOp);
  222. /**
  223. * @brief Reads data from a resource into a pre-allocated GpuResourceData instance.
  224. *
  225. * @note It is assumed GpuResourceData has been locked before being passed here. Data will be unlocked
  226. * when this method finishes.
  227. */
  228. void readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, GpuResourceDataPtr& data, AsyncOp& asyncOp);
  229. /************************************************************************/
  230. /* UTILITY METHODS */
  231. /************************************************************************/
  232. /**
  233. * @brief Gets the native type used for vertex colors.
  234. *
  235. * @note Thread safe.
  236. */
  237. virtual VertexElementType getColorVertexElementType() const = 0;
  238. /**
  239. * @brief Contains a default matrix into a matrix suitable for use
  240. * by this specific render system.
  241. *
  242. * @note Thread safe.
  243. */
  244. virtual void convertProjectionMatrix(const Matrix4& matrix,
  245. Matrix4& dest, bool forGpuProgram = false) = 0;
  246. /**
  247. * @brief Gets horizontal texel offset used for mapping texels to pixels
  248. * in this render system.
  249. *
  250. * @note Thread safe.
  251. */
  252. virtual float getHorizontalTexelOffset() = 0;
  253. /**
  254. * @brief Gets vertical texel offset used for mapping texels to pixels
  255. * in this render system.
  256. *
  257. * @note Thread safe.
  258. */
  259. virtual float getVerticalTexelOffset() = 0;
  260. /**
  261. * @brief Gets the minimum (closest) depth value used by this
  262. * render system.
  263. *
  264. * @note Thread safe.
  265. */
  266. virtual float getMinimumDepthInputValue() = 0;
  267. /**
  268. * @brief Gets the maximum (farthest) depth value used by this
  269. * render system.
  270. *
  271. * @note Thread safe.
  272. */
  273. virtual float getMaximumDepthInputValue() = 0;
  274. /**
  275. * @brief Returns an object containing various rendering statistics.
  276. *
  277. * @note Do not modify the returned state unless you know what you are doing, it will
  278. * change the actual internal object.
  279. */
  280. RenderStats& getRenderStats() { return mRenderStats; }
  281. /************************************************************************/
  282. /* INTERNAL METHODS */
  283. /************************************************************************/
  284. protected:
  285. /**
  286. * @brief Initializes the render system and creates a primary render window.
  287. *
  288. * @note Although I'd like otherwise, due to the nature of some render system implementations,
  289. * you cannot initialize the render system without a window.
  290. *
  291. * Sim thread.
  292. */
  293. RenderWindowPtr initialize(const RENDER_WINDOW_DESC& primaryWindowDesc);
  294. /**
  295. * @brief Performs second part of the initialization (on Core thread), first part
  296. * being in initialize().
  297. */
  298. virtual void initialize_internal(AsyncOp& asyncOp);
  299. /**
  300. * @brief Shuts down the render system and cleans up all resources.
  301. *
  302. * @note Sim thread.
  303. */
  304. void destroy();
  305. /**
  306. * @brief Performs second part of render system shutdown on the core thread.
  307. */
  308. virtual void destroy_internal();
  309. /**
  310. * @copydoc setClipPlanes.
  311. */
  312. virtual void setClipPlanesImpl(const PlaneList& clipPlanes) = 0;
  313. /************************************************************************/
  314. /* INTERNAL DATA */
  315. /************************************************************************/
  316. protected:
  317. friend class RenderSystemManager;
  318. RenderTargetPtr mActiveRenderTarget;
  319. RenderStats mRenderStats;
  320. DriverVersion mDriverVersion;
  321. CullingMode mCullingMode;
  322. UINT16 mDisabledTexUnitsFrom;
  323. bool mVertexProgramBound;
  324. bool mGeometryProgramBound;
  325. bool mFragmentProgramBound;
  326. bool mDomainProgramBound;
  327. bool mHullProgramBound;
  328. bool mComputeProgramBound;
  329. PlaneList mClipPlanes;
  330. bool mClipPlanesDirty;
  331. RenderSystemCapabilities* mCurrentCapabilities;
  332. // TODO - Only used between initialize and initialize_internal. Handle it better?
  333. RENDER_WINDOW_DESC mPrimaryWindowDesc;
  334. };
  335. }