BsD3D9RenderSystem.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. #pragma once
  2. #include "BsD3D9Prerequisites.h"
  3. #include "BsString.h"
  4. #include "BsRenderSystem.h"
  5. #include "BsRenderSystemCapabilities.h"
  6. #include "BsD3D9Mappings.h"
  7. namespace BansheeEngine
  8. {
  9. /**
  10. Implementation of DirectX9 as a rendering system.
  11. */
  12. class BS_D3D9_EXPORT D3D9RenderSystem : public RenderSystem
  13. {
  14. public:
  15. // constructor
  16. D3D9RenderSystem(HINSTANCE hInstance);
  17. // destructor
  18. ~D3D9RenderSystem();
  19. /**
  20. * @copydoc RenderSystem::getName()
  21. */
  22. const String& getName() const;
  23. /**
  24. * @copydoc RenderSystem::getShadingLanguageName()
  25. */
  26. const String& getShadingLanguageName() const;
  27. /**
  28. * @copydoc RenderSystem::setRenderTarget()
  29. */
  30. void setRenderTarget(RenderTargetPtr target);
  31. /**
  32. * @copydoc RenderSystem::bindGpuProgram()
  33. */
  34. void bindGpuProgram(HGpuProgram prg);
  35. /**
  36. * @copydoc RenderSystem::unbindGpuProgram()
  37. */
  38. void unbindGpuProgram(GpuProgramType gptype);
  39. /**
  40. * @copydoc RenderSystem::bindGpuParams()
  41. */
  42. void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
  43. /**
  44. * @copydoc RenderSystem::setVertexBuffers()
  45. */
  46. void setVertexBuffers(UINT32 index, VertexBufferPtr* buffers, UINT32 numBuffers);
  47. /**
  48. * @copydoc RenderSystem::setIndexBuffer()
  49. */
  50. void setIndexBuffer(const IndexBufferPtr& buffer);
  51. /**
  52. * @copydoc RenderSystem::setVertexDeclaration()
  53. */
  54. void setVertexDeclaration(VertexDeclarationPtr vertexDeclaration);
  55. /**
  56. * @copydoc RenderSystem::setDrawOperation()
  57. */
  58. void setDrawOperation(DrawOperationType op);
  59. /**
  60. * @copydoc RenderSystem::setSamplerState()
  61. */
  62. void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr);
  63. /**
  64. * @copydoc RenderSystem::setSamplerState()
  65. */
  66. void setSamplerState(GpuProgramType gptype, UINT16 unit, const SamplerStatePtr& state);
  67. /**
  68. * @copydoc RenderSystem::setBlendState()
  69. */
  70. void setBlendState(const BlendStatePtr& blendState);
  71. /**
  72. * @copydoc RenderSystem::setRasterizerState()
  73. */
  74. void setRasterizerState(const RasterizerStatePtr& rasterizerState);
  75. /**
  76. * @copydoc RenderSystem::setDepthStencilState()
  77. */
  78. void setDepthStencilState(const DepthStencilStatePtr& depthStencilState, UINT32 stencilRefValue);
  79. /**
  80. * @copydoc RenderSystem::setViewport()
  81. */
  82. void setViewport(Viewport vp);
  83. /**
  84. * @copydoc RenderSystem::beginFrame()
  85. */
  86. void beginFrame();
  87. /**
  88. * @copydoc RenderSystem::endFrame()
  89. */
  90. void endFrame();
  91. /**
  92. * @copydoc RenderSystem::draw()
  93. */
  94. void draw(UINT32 vertexOffset, UINT32 vertexCount);
  95. /**
  96. * @copydoc RenderSystem::drawIndexed()
  97. */
  98. void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, UINT32 vertexCount);
  99. void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom);
  100. /**
  101. * @copydoc RenderSystem::clearRenderTarget()
  102. */
  103. void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0);
  104. /**
  105. * @copydoc RenderSystem::clearViewport()
  106. */
  107. void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0);
  108. void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram = false);
  109. float getHorizontalTexelOffset();
  110. float getVerticalTexelOffset();
  111. float getMinimumDepthInputValue();
  112. float getMaximumDepthInputValue();
  113. VertexElementType getColorVertexElementType() const;
  114. /************************************************************************/
  115. /* Internal use by DX9 RenderSystem only */
  116. /************************************************************************/
  117. static D3D9ResourceManager* getResourceManager();
  118. static D3D9DeviceManager* getDeviceManager();
  119. static IDirect3D9* getDirect3D9();
  120. static UINT getResourceCreationDeviceCount();
  121. static IDirect3DDevice9* getResourceCreationDevice(UINT index);
  122. static IDirect3DDevice9* getActiveD3D9Device();
  123. void determineMultisampleSettings(IDirect3DDevice9* d3d9Device, UINT32 multisampleCount, const String& multisampleHint, D3DFORMAT d3dPixelFormat,
  124. bool fullScreen, D3DMULTISAMPLE_TYPE *outMultisampleType, DWORD *outMultisampleQuality) const;
  125. void registerWindow(RenderWindow& renderWindow);
  126. private:
  127. static D3D9RenderSystem* msD3D9RenderSystem;
  128. IDirect3D9* mpD3D;
  129. bool mIsFrameInProgress;
  130. bool mRestoreFrameOnReset;
  131. mutable D3D9DriverList* mDriverList;
  132. D3D9Driver* mActiveD3DDriver;
  133. HINSTANCE mhInstance;
  134. UINT32 mViewportLeft, mViewportTop, mViewportWidth, mViewportHeight;
  135. RECT mScissorRect;
  136. DrawOperationType mCurrentDrawOperation;
  137. /// structure holding texture unit settings for every stage
  138. struct sD3DTextureStageDesc
  139. {
  140. /// the type of the texture
  141. D3D9Mappings::eD3DTexType texType;
  142. /// which texCoordIndex to use
  143. size_t coordIndex;
  144. /// texture
  145. IDirect3DBaseTexture9 *pTex;
  146. /// vertex texture
  147. IDirect3DBaseTexture9 *pVertexTex;
  148. };
  149. UINT32 mNumTexStages;
  150. sD3DTextureStageDesc* mTexStageDesc;
  151. D3D9DriverList* getDirect3DDrivers() const;
  152. // state management methods, very primitive !!!
  153. HRESULT __SetRenderState(D3DRENDERSTATETYPE state, DWORD value);
  154. HRESULT __SetSamplerState(DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value);
  155. HRESULT __SetTextureStageState(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value);
  156. HRESULT __SetFloatRenderState(D3DRENDERSTATETYPE state, float value)
  157. {
  158. return __SetRenderState(state, *((LPDWORD)(&value)));
  159. }
  160. /// return anisotropy level
  161. DWORD _getCurrentAnisotropy(UINT32 unit);
  162. bool _checkMultiSampleQuality(D3DMULTISAMPLE_TYPE type, DWORD *outQuality, D3DFORMAT format, UINT adapterNum, D3DDEVTYPE deviceType, BOOL fullScreen);
  163. D3D9HLSLProgramFactory* mHLSLProgramFactory;
  164. D3D9ResourceManager* mResourceManager;
  165. D3D9DeviceManager* mDeviceManager;
  166. /// Internal method for populating the capabilities structure
  167. virtual RenderSystemCapabilities* createRenderSystemCapabilities() const;
  168. RenderSystemCapabilities* updateRenderSystemCapabilities(D3D9RenderWindow* renderWindow);
  169. /** See RenderSystem definition */
  170. virtual void initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps);
  171. void convertVertexShaderCaps(RenderSystemCapabilities* rsc) const;
  172. void convertPixelShaderCaps(RenderSystemCapabilities* rsc) const;
  173. protected:
  174. // I know that's a lot of friends, but I'd rather have friend classes than exposing the needed methods
  175. // as public interface.
  176. friend class D3D9Texture;
  177. friend class D3D9RenderWindow;
  178. friend class D3D9Device;
  179. friend class D3D9TextureManager;
  180. friend class D3D9DeviceManager;
  181. friend class D3D9RenderWindowManager;
  182. void initialize_internal(AsyncOp& asyncOp);
  183. void destroy_internal();
  184. void setClipPlanesImpl(const PlaneList& clipPlanes);
  185. String getErrorDescription( long errorNumber ) const;
  186. void setClipPlane (UINT16 index, float A, float B, float C, float D);
  187. void enableClipPlane (UINT16 index, bool enable);
  188. HINSTANCE getInstanceHandle() const { return mhInstance; }
  189. /**
  190. * @brief Returns the D3D9 specific mode used for drawing, depending on the
  191. * currently set draw operation;
  192. */
  193. D3DPRIMITIVETYPE getD3D9PrimitiveType() const;
  194. /** Check whether or not filtering is supported for the precise texture format requested
  195. with the given usage options.
  196. */
  197. bool checkTextureFilteringSupported(TextureType ttype, PixelFormat format, int usage);
  198. /************************************************************************/
  199. /* Sampler states */
  200. /************************************************************************/
  201. /** Sets the texture addressing mode for a texture unit.*/
  202. void setTextureAddressingMode(UINT16 stage, const UVWAddressingMode& uvw);
  203. /** Sets a single filter for a given texture unit.
  204. @param unit The texture unit to set the filtering options for
  205. @param ftype The filter type
  206. @param filter The filter to be used
  207. */
  208. void setTextureFiltering(UINT16 unit, FilterType ftype, FilterOptions filter);
  209. /** Sets the maximal anisotropy for the specified texture unit.*/
  210. void setTextureAnisotropy(UINT16 unit, unsigned int maxAnisotropy);
  211. /** Sets the texture border colour for a texture unit.*/
  212. void setTextureBorderColor(UINT16 stage, const Color& color);
  213. /** Sets the mipmap bias value for a given texture unit.
  214. @remarks
  215. This allows you to adjust the mipmap calculation up or down for a
  216. given texture unit. Negative values force a larger mipmap to be used,
  217. positive values force a smaller mipmap to be used. Units are in numbers
  218. of levels, so +1 forces the mipmaps to one smaller level.
  219. @note Only does something if render system has capability RSC_MIPMAP_LOD_BIAS.
  220. */
  221. void setTextureMipmapBias(UINT16 unit, float bias);
  222. /************************************************************************/
  223. /* Blend states */
  224. /************************************************************************/
  225. /** Sets the global blending factors for combining subsequent renders with the existing frame contents.
  226. The result of the blending operation is:</p>
  227. <p align="center">final = (texture * sourceFactor) + (pixel * destFactor)</p>
  228. Each of the factors is specified as one of a number of options, as specified in the SceneBlendFactor
  229. enumerated type.
  230. By changing the operation you can change addition between the source and destination pixels to a different operator.
  231. @param sourceFactor The source factor in the above calculation, i.e. multiplied by the texture colour components.
  232. @param destFactor The destination factor in the above calculation, i.e. multiplied by the pixel colour components.
  233. @param op The blend operation mode for combining pixels
  234. */
  235. void setSceneBlending( BlendFactor sourceFactor, BlendFactor destFactor, BlendOperation op );
  236. /** Sets the global blending factors for combining subsequent renders with the existing frame contents.
  237. The result of the blending operation is:</p>
  238. <p align="center">final = (texture * sourceFactor) + (pixel * destFactor)</p>
  239. Each of the factors is specified as one of a number of options, as specified in the SceneBlendFactor
  240. enumerated type.
  241. @param sourceFactor The source factor in the above calculation, i.e. multiplied by the texture colour components.
  242. @param destFactor The destination factor in the above calculation, i.e. multiplied by the pixel colour components.
  243. @param sourceFactorAlpha The source factor in the above calculation for the alpha channel, i.e. multiplied by the texture alpha components.
  244. @param destFactorAlpha The destination factor in the above calculation for the alpha channel, i.e. multiplied by the pixel alpha components.
  245. @param op The blend operation mode for combining pixels
  246. @param alphaOp The blend operation mode for combining pixel alpha values
  247. */
  248. void setSceneBlending( BlendFactor sourceFactor, BlendFactor destFactor, BlendFactor sourceFactorAlpha,
  249. BlendFactor destFactorAlpha, BlendOperation op, BlendOperation alphaOp );
  250. /** Sets the global alpha rejection approach for future renders.
  251. By default images are rendered regardless of texture alpha. This method lets you change that.
  252. @param func The comparison function which must pass for a pixel to be written.
  253. @param val The value to compare each pixels alpha value to (0-255)
  254. */
  255. void setAlphaTest(CompareFunction func, unsigned char value);
  256. /**
  257. * @brief Enable alpha coverage if supported.
  258. */
  259. void setAlphaToCoverage(bool enabled);
  260. /** Sets whether or not colour buffer writing is enabled, and for which channels.
  261. @remarks
  262. For some advanced effects, you may wish to turn off the writing of certain colour
  263. channels, or even all of the colour channels so that only the depth buffer is updated
  264. in a rendering pass. However, the chances are that you really want to use this option
  265. through the Material class.
  266. @param red, green, blue, alpha Whether writing is enabled for each of the 4 colour channels. */
  267. void setColorBufferWriteEnabled(bool red, bool green, bool blue, bool alpha);
  268. /************************************************************************/
  269. /* Rasterizer states */
  270. /************************************************************************/
  271. /** Sets the culling mode for the render system based on the 'vertex winding'.
  272. A typical way for the rendering engine to cull triangles is based on the
  273. 'vertex winding' of triangles. Vertex winding refers to the direction in
  274. which the vertices are passed or indexed to in the rendering operation as viewed
  275. from the camera, and will wither be clockwise or anticlockwise (that's 'counterclockwise' for
  276. you Americans out there ;) The default is CULL_CLOCKWISE i.e. that only triangles whose vertices
  277. are passed/indexed in anticlockwise order are rendered - this is a common approach and is used in 3D studio models
  278. for example. You can alter this culling mode if you wish but it is not advised unless you know what you are doing.
  279. You may wish to use the CULL_NONE option for mesh data that you cull yourself where the vertex
  280. winding is uncertain.
  281. */
  282. void setCullingMode(CullingMode mode);
  283. /** Sets how to rasterise triangles, as points, wireframe or solid polys. */
  284. void setPolygonMode(PolygonMode level);
  285. /** Sets the depth bias, NB you should use the Material version of this.
  286. @remarks
  287. When polygons are coplanar, you can get problems with 'depth fighting' where
  288. the pixels from the two polys compete for the same screen pixel. This is particularly
  289. a problem for decals (polys attached to another surface to represent details such as
  290. bulletholes etc.).
  291. @par
  292. A way to combat this problem is to use a depth bias to adjust the depth buffer value
  293. used for the decal such that it is slightly higher than the true value, ensuring that
  294. the decal appears on top.
  295. @note
  296. The final bias value is a combination of a constant bias and a bias proportional
  297. to the maximum depth slope of the polygon being rendered. The final bias
  298. is constantBias + slopeScaleBias * maxslope. Slope scale biasing is
  299. generally preferable but is not available on older hardware.
  300. @param constantBias The constant bias value, expressed as a value in
  301. homogeneous depth coordinates.
  302. @param slopeScaleBias The bias value which is factored by the maximum slope
  303. of the polygon, see the description above. This is not supported by all
  304. cards.
  305. */
  306. void setDepthBias(float constantBias, float slopeScaleBias);
  307. /**
  308. * @brief Scissor test allows you to 'mask off' rendering in all but a given rectangular area
  309. * identified by the rectangle set by setScissorRect().
  310. */
  311. void setScissorTestEnable(bool enable);
  312. /**
  313. * @brief Only applies when rendering to a multisample render target.
  314. * If disabled all of the samples will be taken from the center of the pixel,
  315. * effectively making the image aliased. Default value is true where samples are
  316. * picked randomly within the pixel.
  317. */
  318. void setMultisampleAntialiasEnable(bool enable);
  319. /**
  320. * @brief Only applies when rendering to a non-multisample render target.
  321. * If enabled, lines will be antialiased. Default state is disabled.
  322. */
  323. void setAntialiasedLineEnable(bool enable);
  324. /************************************************************************/
  325. /* Depth stencil state */
  326. /************************************************************************/
  327. /** Sets the mode of operation for depth buffer tests from this point onwards.
  328. Sometimes you may wish to alter the behaviour of the depth buffer to achieve
  329. special effects. Because it's unlikely that you'll set these options for an entire frame,
  330. but rather use them to tweak settings between rendering objects, this is an internal
  331. method (indicated by the '_' prefix) which will be used by a SceneManager implementation
  332. rather than directly from the client application.
  333. If this method is never called the settings are automatically the same as the default parameters.
  334. @param depthTest If true, the depth buffer is tested for each pixel and the frame buffer is only updated
  335. if the depth function test succeeds. If false, no test is performed and pixels are always written.
  336. @param depthWrite If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds.
  337. If false, the depth buffer is left unchanged even if a new pixel is written.
  338. @param depthFunction Sets the function required for the depth test.
  339. */
  340. void setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL);
  341. /** Sets whether or not the depth buffer check is performed before a pixel write.
  342. @param enabled If true, the depth buffer is tested for each pixel and the frame buffer is only updated
  343. if the depth function test succeeds. If false, no test is performed and pixels are always written.
  344. */
  345. void setDepthBufferCheckEnabled(bool enabled = true);
  346. /** Sets whether or not the depth buffer is updated after a pixel write.
  347. @param enabled If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds.
  348. If false, the depth buffer is left unchanged even if a new pixel is written.
  349. */
  350. void setDepthBufferWriteEnabled(bool enabled = true);
  351. /** Sets the comparison function for the depth buffer check.
  352. Advanced use only - allows you to choose the function applied to compare the depth values of
  353. new and existing pixels in the depth buffer. Only an issue if the deoth buffer check is enabled
  354. (see _setDepthBufferCheckEnabled)
  355. @param func The comparison between the new depth and the existing depth which must return true
  356. for the new pixel to be written.
  357. */
  358. void setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL);
  359. /** Turns stencil buffer checking on or off.
  360. @remarks
  361. Stencilling (masking off areas of the rendering target based on the stencil
  362. buffer) can be turned on or off using this method. By default, stencilling is
  363. disabled.
  364. */
  365. void setStencilCheckEnabled(bool enabled);
  366. /** This method allows you to set stencil buffer operations in one call.
  367. @param stencilFailOp The action to perform when the stencil check fails
  368. @param depthFailOp The action to perform when the stencil check passes, but the
  369. depth buffer check still fails
  370. @param passOp The action to take when both the stencil and depth check pass.
  371. @param ccw If set to true, the stencil operations will be applied to counterclockwise
  372. faces. Otherwise they will be applied to clockwise faces.
  373. */
  374. void setStencilBufferOperations(StencilOperation stencilFailOp = SOP_KEEP,
  375. StencilOperation depthFailOp = SOP_KEEP, StencilOperation passOp = SOP_KEEP,
  376. bool ccw = true);
  377. /**
  378. * @brief Sets a stencil buffer comparison function. The result of this will cause one of 3 actions depending on whether the test fails,
  379. * succeeds but with the depth buffer check still failing, or succeeds with the
  380. * depth buffer check passing too.
  381. * @param ccw If set to true, the stencil operations will be applied to counterclockwise
  382. * faces. Otherwise they will be applied to clockwise faces.
  383. */
  384. void setStencilBufferFunc(CompareFunction func = CMPF_ALWAYS_PASS, bool ccw = true);
  385. /**
  386. * @brief The bitmask applied to both the stencil value and the reference value
  387. * before comparison
  388. */
  389. void setStencilBufferReadMask(UINT32 mask = 0xFFFFFFFF);
  390. /**
  391. * @brief The bitmask applied to the stencil value before writing it to the stencil buffer.
  392. */
  393. void setStencilBufferWriteMask(UINT32 mask = 0xFFFFFFFF);
  394. /**
  395. * @brief Sets a reference values used for stencil buffer comparisons.
  396. * Actual comparison function and stencil operations are set by setting the DepthStencilState.
  397. */
  398. void setStencilRefValue(UINT32 refValue);
  399. void clearArea(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, const RectI& clearArea = RectI::EMPTY);
  400. /// Notify when a device has been lost.
  401. void notifyOnDeviceLost(D3D9Device* device);
  402. /// Notify when a device has been reset.
  403. void notifyOnDeviceReset(D3D9Device* device);
  404. };
  405. }