gfxDevice.h 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _GFXDEVICE_H_
  23. #define _GFXDEVICE_H_
  24. #ifndef _GFXADAPTER_H_
  25. #include "gfx/gfxAdapter.h"
  26. #endif
  27. #ifndef _GFXTARGET_H_
  28. #include "gfx/gfxTarget.h"
  29. #endif
  30. #ifndef _GFXVERTEXBUFFER_H_
  31. #include "gfx/gfxVertexBuffer.h"
  32. #endif
  33. #ifndef _GFXSTATEBLOCK_H_
  34. #include "gfx/gfxStateBlock.h"
  35. #endif
  36. #ifndef _GFXSHADER_H_
  37. #include "gfx/gfxShader.h"
  38. #endif
  39. #ifndef _GFXCUBEMAP_H_
  40. #include "gfx/gfxCubemap.h"
  41. #endif
  42. #ifndef _TDICTIONARY_H_
  43. #include "core/util/tDictionary.h"
  44. #endif
  45. #ifndef _TSIGNAL_H_
  46. #include "core/util/tSignal.h"
  47. #endif
  48. #ifndef _GFXDEVICESTATISTICS_H_
  49. #include "gfx/gfxDeviceStatistics.h"
  50. #endif
  51. #ifndef _MATHUTIL_FRUSTUM_H_
  52. #include "math/util/frustum.h"
  53. #endif
  54. #ifndef _PLATFORM_PLATFORMTIMER_H_
  55. #include "platform/platformTimer.h"
  56. #endif
  57. class FontRenderBatcher;
  58. class GFont;
  59. class GFXCardProfiler;
  60. class GFXDrawUtil;
  61. class GFXFence;
  62. class GFXOcclusionQuery;
  63. class GFXPrimitiveBuffer;
  64. class GFXShader;
  65. class GFXStateBlock;
  66. class GFXShaderConstBuffer;
  67. class GFXTextureManager;
  68. // Global macro
  69. #define GFX GFXDevice::get()
  70. #define MAX_MRT_TARGETS 4
  71. //-----------------------------------------------------------------------------
  72. /// GFXDevice is the TSE graphics interface layer. This allows the TSE to
  73. /// do many things, such as use multiple render devices for multi-head systems,
  74. /// and allow a game to render in DirectX 9, OpenGL or any other API which has
  75. /// a GFX implementation seamlessly. There are many concepts in GFX device which
  76. /// may not be familiar to you, especially if you have not used DirectX.
  77. /// @n
  78. /// <b>Buffers</b>
  79. /// There are three types of buffers in GFX: vertex, index and primitive. Please
  80. /// note that index buffers are not accessable outside the GFX layer, they are wrapped
  81. /// by primitive buffers. Primitive buffers will be explained in detail later.
  82. /// Buffers are allocated and deallocated using their associated allocXBuffer and
  83. /// freeXBuffer methods on the device. When a buffer is allocated you pass in a
  84. /// pointer to, depending on the buffer, a vertex type pointer or a U16 pointer.
  85. /// During allocation, this pointer is set to the address of where you should
  86. /// copy in the information for this buffer. You must the tell the GFXDevice
  87. /// that the information is in, and it should prepare the buffer for use by calling
  88. /// the prepare method on it. Dynamic vertex buffer example:
  89. /// @code
  90. /// GFXVertexP *verts; // Making a buffer containing verticies with only position
  91. ///
  92. /// // Allocate a dynamic vertex buffer to hold 3 vertices and use *verts as the location to copy information into
  93. /// GFXVertexBufferHandle vb = GFX->allocVertexBuffer( 3, &verts, true );
  94. ///
  95. /// // Now set the information, we're making a triangle
  96. /// verts[0].point = Point3F( 200.f, 200.f, 0.f );
  97. /// verts[1].point = Point3F( 200.f, 400.f, 0.f );
  98. /// verts[2].point = Point3F( 400.f, 200.f, 0.f );
  99. ///
  100. /// // Tell GFX that the information is in and it should be made ready for use
  101. /// // Note that nothing is done with verts, this should not and MUST NOT be deleted
  102. /// // stored, or otherwise used after prepare is called.
  103. /// GFX->prepare( vb );
  104. ///
  105. /// // Because this is a dynamic vertex buffer, it is only assured to be valid until someone
  106. /// // else allocates a dynamic vertex buffer, so we will render it now
  107. /// GFX->setVertexBuffer( vb );
  108. /// GFX->drawPrimitive( GFXTriangleStrip, 0, 1 );
  109. ///
  110. /// // Now because this is a dynamic vertex buffer it MUST NOT BE FREED you are only
  111. /// // given a handle to a vertex buffer which belongs to the device
  112. /// @endcode
  113. ///
  114. /// To use a static vertex buffer, it is very similar, this is an example using a
  115. /// static primitive buffer:
  116. /// @n
  117. /// This takes place inside a constructor for a class which has a member variable
  118. /// called mPB which is the primitive buffer for the class instance.
  119. /// @code
  120. /// U16 *idx; // This is going to be where to write indices
  121. /// GFXPrimitiveInfo *primitiveInfo; // This will be where to write primitive information
  122. ///
  123. /// // Allocate a primitive buffer with 4 indices, and 1 primitive described for use
  124. /// mPB = GFX->allocPrimitiveBuffer( 4, &idx, 1, &primitiveInfo );
  125. ///
  126. /// // Write the index information, this is going to be for the outline of a triangle using
  127. /// // a line strip
  128. /// idx[0] = 0;
  129. /// idx[1] = 1;
  130. /// idx[2] = 2;
  131. /// idx[3] = 0;
  132. ///
  133. /// // Write the information for the primitive
  134. /// primitiveInfo->indexStart = 0; // Starting with index 0
  135. /// primitiveInfo->minVertex = 0; // The minimum vertex index is 0
  136. /// primitiveInfo->maxVertex = 3; // The maximum vertex index is 3
  137. /// primitiveInfo->primitiveCount = 3; // There are 3 lines we are drawing
  138. /// primitiveInfo->type = GFXLineStrip; // This primitive info describes a line strip
  139. /// @endcode
  140. /// The following code takes place in the destructor for the same class
  141. /// @code
  142. /// // Because this is a static buffer it's our responsibility to free it when we are done
  143. /// GFX->freePrimitiveBuffer( mPB );
  144. /// @endcode
  145. /// This last bit takes place in the rendering function for the class
  146. /// @code
  147. /// // You need to set a vertex buffer as well, primitive buffers contain indexing
  148. /// // information, not vertex information. This is so you could have, say, a static
  149. /// // vertex buffer, and a dynamic primitive buffer.
  150. ///
  151. /// // This sets the primitive buffer to the static buffer we allocated in the constructor
  152. /// GFX->setPrimitiveBuffer( mPB );
  153. ///
  154. /// // Draw the first primitive contained in the set primitive buffer, our primitive buffer
  155. /// // has only one primitive, so we could also technically call GFX->drawPrimitives(); and
  156. /// // get the same result.
  157. /// GFX->drawPrimitive( 0 );
  158. /// @endcode
  159. /// If you need any more examples on how to use these buffers please see the rest of the engine.
  160. /// @n
  161. /// <b>Primitive Buffers</b>
  162. /// @n
  163. /// Primitive buffers wrap and extend the concept of index buffers. The purpose of a primitive
  164. /// buffer is to let objects store all information they have to render their primitives in
  165. /// a central place. Say that a shape is made up of triangle strips and triangle fans, it would
  166. /// still have only one primitive buffer which contained primitive information for each strip
  167. /// and fan. It could then draw itself with one call.
  168. ///
  169. /// TO BE FINISHED LATER
  170. class GFXDevice
  171. {
  172. private:
  173. friend class GFXInit;
  174. friend class GFXPrimitiveBufferHandle;
  175. friend class GFXVertexBufferHandleBase;
  176. friend class GFXTextureObject;
  177. friend class GFXTexHandle;
  178. friend class GFXVertexFormat;
  179. friend class GFXTestFullscreenToggle;
  180. friend class TestGFXTextureCube;
  181. friend class TestGFXRenderTargetCube;
  182. friend class TestGFXRenderTargetStack;
  183. friend class GFXResource;
  184. friend class LightMatInstance; // For stencil interface
  185. //--------------------------------------------------------------------------
  186. // Static GFX interface
  187. //--------------------------------------------------------------------------
  188. public:
  189. enum GFXDeviceEventType
  190. {
  191. /// The device has been created, but not initialized
  192. deCreate,
  193. /// The device has been initialized
  194. deInit,
  195. /// The device is about to be destroyed.
  196. deDestroy,
  197. /// The device has started rendering a frame
  198. deStartOfFrame,
  199. /// The device is about to finish rendering a frame
  200. deEndOfFrame,
  201. /// The device has started rendering a frame's field (such as for side-by-side rendering)
  202. deStartOfField,
  203. /// The device is about to finish rendering a frame's field
  204. deEndOfField,
  205. };
  206. typedef Signal <bool (GFXDeviceEventType)> DeviceEventSignal;
  207. static DeviceEventSignal& getDeviceEventSignal();
  208. static GFXDevice *get() { return smGFXDevice; }
  209. static void initConsole();
  210. static bool destroy();
  211. static bool devicePresent() { return (smGFXDevice && smGFXDevice->getAdapterType() != NullDevice); }
  212. private:
  213. /// @name Device management variables
  214. /// @{
  215. static GFXDevice * smGFXDevice; ///< Global GFXDevice
  216. /// @}
  217. //--------------------------------------------------------------------------
  218. // Core GFX interface
  219. //--------------------------------------------------------------------------
  220. public:
  221. enum GFXDeviceRenderStyles
  222. {
  223. RS_Standard = 0,
  224. RS_StereoSideBySide = (1<<0),
  225. };
  226. private:
  227. /// Adapter for this device.
  228. GFXAdapter mAdapter;
  229. protected:
  230. /// List of valid video modes for this device.
  231. Vector<GFXVideoMode> mVideoModes;
  232. /// The CardProfiler for this device.
  233. GFXCardProfiler *mCardProfiler;
  234. /// Head of the resource list.
  235. ///
  236. /// @see GFXResource
  237. GFXResource *mResourceListHead;
  238. /// Set once the device is active.
  239. bool mCanCurrentlyRender;
  240. /// Set if we're in a mode where we want rendering to occur.
  241. bool mAllowRender;
  242. /// The style of rendering that is to be performed, based on GFXDeviceRenderStyles
  243. U32 mCurrentRenderStyle;
  244. /// The current projection offset. May be used during side-by-side rendering, for example.
  245. Point2F mCurrentProjectionOffset;
  246. /// Eye offset used when using a stereo rendering style
  247. Point3F mStereoEyeOffset;
  248. /// This will allow querying to see if a device is initialized and ready to
  249. /// have operations performed on it.
  250. bool mInitialized;
  251. /// This is called before this, or any other device, is deleted in the global destroy()
  252. /// method. It allows the device to clean up anything while everything is still valid.
  253. virtual void preDestroy();
  254. /// Set the adapter that this device is using. For use by GFXInit::createDevice only.
  255. virtual void setAdapter(const GFXAdapter& adapter) { mAdapter = adapter; }
  256. /// Notify GFXDevice that we are initialized
  257. virtual void deviceInited();
  258. public:
  259. GFXDevice();
  260. virtual ~GFXDevice();
  261. /// Initialize this GFXDevice, optionally specifying a platform window to
  262. /// bind to.
  263. virtual void init( const GFXVideoMode &mode, PlatformWindow *window = NULL ) = 0;
  264. /// Returns true if the scene has begun and its
  265. /// safe to make rendering calls.
  266. /// @see beginScene
  267. /// @see endScene
  268. bool canCurrentlyRender() const { return mCanCurrentlyRender; }
  269. void setAllowRender( bool render ) { mAllowRender = render; }
  270. inline bool allowRender() const { return mAllowRender; }
  271. /// Retrieve the current rendering style based on GFXDeviceRenderStyles
  272. U32 getCurrentRenderStyle() const { return mCurrentRenderStyle; }
  273. /// Set the current rendering style, based on GFXDeviceRenderStyles
  274. void setCurrentRenderStyle(U32 style) { mCurrentRenderStyle = style; }
  275. /// Set the current projection offset used during stereo rendering
  276. const Point2F& getCurrentProjectionOffset() { return mCurrentProjectionOffset; }
  277. /// Get the current projection offset used during stereo rendering
  278. void setCurrentProjectionOffset(const Point2F& offset) { mCurrentProjectionOffset = offset; }
  279. /// Get the current eye offset used during stereo rendering
  280. const Point3F& getStereoEyeOffset() { return mStereoEyeOffset; }
  281. /// Set the current eye offset used during stereo rendering
  282. void setStereoEyeOffset(const Point3F& offset) { mStereoEyeOffset = offset; }
  283. GFXCardProfiler* getCardProfiler() const { return mCardProfiler; }
  284. /// Returns active graphics adapter type.
  285. virtual GFXAdapterType getAdapterType()=0;
  286. /// Returns the Adapter that was used to create this device
  287. virtual const GFXAdapter& getAdapter() { return mAdapter; }
  288. /// @}
  289. /// @name Debug Methods
  290. /// @{
  291. virtual void enterDebugEvent(ColorI color, const char *name) = 0;
  292. virtual void leaveDebugEvent() = 0;
  293. virtual void setDebugMarker(ColorI color, const char *name) = 0;
  294. /// @}
  295. /// @name Resource debug methods
  296. /// @{
  297. /// Lists how many of each GFX resource (e.g. textures, texture targets, shaders, etc.) GFX is aware of
  298. /// @param unflaggedOnly If true, this method only counts unflagged resources
  299. virtual void listResources(bool unflaggedOnly);
  300. /// Flags all resources GFX is currently aware of
  301. virtual void flagCurrentResources();
  302. /// Clears the flag on all resources GFX is currently aware of
  303. virtual void clearResourceFlags();
  304. /// Dumps a description of the specified resource types to the console
  305. /// @param resNames A string of space separated class names (e.g. "GFXTextureObject GFXTextureTarget GFXShader")
  306. /// to describe to the console
  307. /// @param file A path to the file to write the descriptions to. If it is NULL or "", descriptions are
  308. /// written to the console.
  309. /// @param unflaggedOnly If true, this method only counts unflagged resources
  310. /// @note resNames is case sensitive because there is no dStristr function.
  311. virtual void describeResources(const char* resName, const char* file, bool unflaggedOnly);
  312. /// Returns the current GFXDeviceStatistics, stats are cleared every ::beginScene call.
  313. GFXDeviceStatistics* getDeviceStatistics() { return &mDeviceStatistics; }
  314. protected:
  315. GFXDeviceStatistics mDeviceStatistics;
  316. /// This is a helper method for describeResourcesToFile. It walks through the
  317. /// GFXResource list and sorts it by item type, putting the resources into the proper vector.
  318. /// @see describeResources
  319. virtual void fillResourceVectors(const char* resNames, bool unflaggedOnly, Vector<GFXResource*> &textureObjects,
  320. Vector<GFXResource*> &textureTargets, Vector<GFXResource*> &windowTargets, Vector<GFXResource*> &vertexBuffers,
  321. Vector<GFXResource*> &primitiveBuffers, Vector<GFXResource*> &fences, Vector<GFXResource*> &cubemaps,
  322. Vector<GFXResource*> &shaders, Vector<GFXResource*> &stateblocks);
  323. public:
  324. /// @}
  325. /// @name Video Mode Functions
  326. /// @{
  327. /// Enumerates the supported video modes of the device
  328. virtual void enumerateVideoModes() = 0;
  329. /// Returns the video mode list.
  330. /// @see GFXVideoMode
  331. const Vector<GFXVideoMode>* const getVideoModeList() const { return &mVideoModes; }
  332. /// Returns the first format from the list which meets all
  333. /// the criteria of the texture profile and query options.
  334. virtual GFXFormat selectSupportedFormat(GFXTextureProfile *profile,
  335. const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter) = 0;
  336. /// @}
  337. //-----------------------------------------------------------------------------
  338. protected:
  339. /// @name State tracking variables
  340. /// @{
  341. /// Set if ANY state is dirty, including matrices or primitive buffers.
  342. bool mStateDirty;
  343. enum TexDirtyType
  344. {
  345. GFXTDT_Normal,
  346. GFXTDT_Cube
  347. };
  348. GFXTexHandle mCurrentTexture[TEXTURE_STAGE_COUNT];
  349. GFXTexHandle mNewTexture[TEXTURE_STAGE_COUNT];
  350. GFXCubemapHandle mCurrentCubemap[TEXTURE_STAGE_COUNT];
  351. GFXCubemapHandle mNewCubemap[TEXTURE_STAGE_COUNT];
  352. TexDirtyType mTexType[TEXTURE_STAGE_COUNT];
  353. bool mTextureDirty[TEXTURE_STAGE_COUNT];
  354. bool mTexturesDirty;
  355. // This maps a GFXStateBlockDesc hash value to a GFXStateBlockRef
  356. typedef Map<U32, GFXStateBlockRef> StateBlockMap;
  357. StateBlockMap mCurrentStateBlocks;
  358. // This tracks whether or not our state block is dirty.
  359. bool mStateBlockDirty;
  360. GFXStateBlockRef mCurrentStateBlock;
  361. GFXStateBlockRef mNewStateBlock;
  362. GFXShaderConstBuffer *mCurrentShaderConstBuffer;
  363. /// A global forced wireframe mode.
  364. static bool smWireframe;
  365. /// The global vsync state.
  366. static bool smDisableVSync;
  367. /// The forced shader model version if non-zero.
  368. static F32 smForcedPixVersion;
  369. /// Disable all hardware occlusion queries causing
  370. /// them to return only the visibile state.
  371. static bool smDisableOcclusionQuery;
  372. /// @}
  373. /// @name Light Tracking
  374. /// @{
  375. GFXLightInfo mCurrentLight[LIGHT_STAGE_COUNT];
  376. bool mCurrentLightEnable[LIGHT_STAGE_COUNT];
  377. bool mLightDirty[LIGHT_STAGE_COUNT];
  378. bool mLightsDirty;
  379. ColorF mGlobalAmbientColor;
  380. bool mGlobalAmbientColorDirty;
  381. /// @}
  382. /// @name Fixed function material tracking
  383. /// @{
  384. GFXLightMaterial mCurrentLightMaterial;
  385. bool mLightMaterialDirty;
  386. /// @}
  387. /// @name Bitmap modulation and color stack
  388. /// @{
  389. ///
  390. /// @}
  391. /// @see getDeviceSwizzle32
  392. Swizzle<U8, 4> *mDeviceSwizzle32;
  393. /// @see getDeviceSwizzle24
  394. Swizzle<U8, 3> *mDeviceSwizzle24;
  395. //-----------------------------------------------------------------------------
  396. /// @name Matrix managing variables
  397. /// @{
  398. ///
  399. MatrixF mWorldMatrix[WORLD_STACK_MAX];
  400. bool mWorldMatrixDirty;
  401. S32 mWorldStackSize;
  402. MatrixF mProjectionMatrix;
  403. bool mProjectionMatrixDirty;
  404. MatrixF mViewMatrix;
  405. bool mViewMatrixDirty;
  406. MatrixF mTextureMatrix[TEXTURE_STAGE_COUNT];
  407. bool mTextureMatrixDirty[TEXTURE_STAGE_COUNT];
  408. bool mTextureMatrixCheckDirty;
  409. /// @}
  410. /// @name Current frustum planes
  411. /// @{
  412. ///
  413. Frustum mFrustum;
  414. //-----------------------------------------------------------------------------
  415. /// @name Stateblock functions
  416. /// @{
  417. /// Called by GFXDevice to create a device specific stateblock
  418. virtual GFXStateBlockRef createStateBlockInternal(const GFXStateBlockDesc& desc) = 0;
  419. /// Called by GFXDevice to actually set a stateblock.
  420. /// @param force If true, set all states
  421. virtual void setStateBlockInternal(GFXStateBlock* block, bool force) = 0;
  422. /// @}
  423. /// Called by base GFXDevice to actually set a const buffer
  424. virtual void setShaderConstBufferInternal(GFXShaderConstBuffer* buffer) = 0;
  425. virtual void setTextureInternal(U32 textureUnit, const GFXTextureObject*texture) = 0;
  426. virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable) = 0;
  427. virtual void setGlobalAmbientInternal(ColorF color) = 0;
  428. virtual void setLightMaterialInternal(const GFXLightMaterial mat) = 0;
  429. virtual bool beginSceneInternal() = 0;
  430. virtual void endSceneInternal() = 0;
  431. /// @name State Initialization.
  432. /// @{
  433. /// State initialization. This MUST BE CALLED in setVideoMode after the device
  434. /// is created.
  435. virtual void initStates() = 0;
  436. /// @}
  437. //-----------------------------------------------------------------------------
  438. /// This function must be implemented differently per
  439. /// API and it should set ONLY the current matrix.
  440. /// For example, in OpenGL, there should be NO matrix stack
  441. /// activity, all the stack stuff is managed in the GFX layer.
  442. ///
  443. /// OpenGL does not have separate world and
  444. /// view matrices. It has ModelView which is world * view.
  445. /// You must take this into consideration.
  446. ///
  447. /// @param mtype Which matrix to set, world/view/projection
  448. /// @param mat Matrix to assign
  449. virtual void setMatrix( GFXMatrixType mtype, const MatrixF &mat ) = 0;
  450. //-----------------------------------------------------------------------------
  451. protected:
  452. /// @name Buffer Allocation
  453. /// These methods are implemented per-device and are called by the GFX layer
  454. /// when a user calls an alloc
  455. ///
  456. /// @note Primitive Buffers are NOT implemented per device, they wrap index buffers
  457. /// @{
  458. /// This allocates a vertex buffer and returns a pointer to the allocated buffer.
  459. /// This function should not be called directly - rather it should be used by
  460. /// the GFXVertexBufferHandle class.
  461. virtual GFXVertexBuffer *allocVertexBuffer( U32 numVerts,
  462. const GFXVertexFormat *vertexFormat,
  463. U32 vertSize,
  464. GFXBufferType bufferType ) = 0;
  465. /// Called from GFXVertexFormat to allocate the hardware
  466. /// specific vertex declaration for rendering.
  467. virtual GFXVertexDecl* allocVertexDecl( const GFXVertexFormat *vertexFormat ) = 0;
  468. /// Sets the current vertex declaration on the device.
  469. virtual void setVertexDecl( const GFXVertexDecl *decl ) = 0;
  470. /// Sets the vertex buffer on the device.
  471. virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer ) = 0;
  472. /// Set the vertex stream frequency on the device.
  473. virtual void setVertexStreamFrequency( U32 stream, U32 frequency ) = 0;
  474. /// The maximum number of supported vertex streams which
  475. /// may be more than the device supports.
  476. static const U32 VERTEX_STREAM_COUNT = 4;
  477. StrongRefPtr<GFXVertexBuffer> mCurrentVertexBuffer[VERTEX_STREAM_COUNT];
  478. bool mVertexBufferDirty[VERTEX_STREAM_COUNT];
  479. U32 mVertexBufferFrequency[VERTEX_STREAM_COUNT];
  480. bool mVertexBufferFrequencyDirty[VERTEX_STREAM_COUNT];
  481. const GFXVertexDecl *mCurrVertexDecl;
  482. bool mVertexDeclDirty;
  483. StrongRefPtr<GFXPrimitiveBuffer> mCurrentPrimitiveBuffer;
  484. bool mPrimitiveBufferDirty;
  485. /// This allocates a primitive buffer and returns a pointer to the allocated buffer.
  486. /// A primitive buffer's type argument refers to the index data - the primitive data will
  487. /// always be preserved from call to call.
  488. ///
  489. /// @note All index buffers use unsigned 16-bit indices.
  490. virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices,
  491. U32 numPrimitives,
  492. GFXBufferType bufferType ) = 0;
  493. /// @}
  494. //---------------------------------------
  495. // SFX buffer
  496. //---------------------------------------
  497. protected:
  498. GFXTexHandle mFrontBuffer[2];
  499. U32 mCurrentFrontBufferIdx;
  500. //---------------------------------------
  501. // Render target related
  502. //---------------------------------------
  503. /// A stack of previously active render targets.
  504. Vector<GFXTargetRef> mRTStack;
  505. /// The current render target which may or may not
  506. /// not be yet activated.
  507. /// @see mRTDirty
  508. GFXTargetRef mCurrentRT;
  509. /// This tracks a previously activated render target
  510. /// which need to be deactivated.
  511. GFXTargetRef mRTDeactivate;
  512. /// This is set when the current and/or deactivate render
  513. /// targets have changed and the device need to update
  514. /// its state on the next draw/clear.
  515. bool mRTDirty;
  516. /// Updates the render targets and viewport in a device
  517. /// specific manner when they are dirty.
  518. virtual void _updateRenderTargets() = 0;
  519. /// The current viewport rect.
  520. RectI mViewport;
  521. /// If true the viewport has been changed and
  522. /// it must be updated on the next draw/clear.
  523. bool mViewportDirty;
  524. public:
  525. /// @name Texture functions
  526. /// @{
  527. protected:
  528. GFXTextureManager * mTextureManager;
  529. public:
  530. virtual GFXCubemap * createCubemap() = 0;
  531. inline GFXTextureManager *getTextureManager()
  532. {
  533. return mTextureManager;
  534. }
  535. ///@}
  536. /// Swizzle to convert 32bpp bitmaps from RGBA to the native device format.
  537. const Swizzle<U8, 4> *getDeviceSwizzle32() const
  538. {
  539. return mDeviceSwizzle32;
  540. }
  541. /// Swizzle to convert 24bpp bitmaps from RGB to the native device format.
  542. const Swizzle<U8, 3> *getDeviceSwizzle24() const
  543. {
  544. return mDeviceSwizzle24;
  545. }
  546. /// @name Render Target functions
  547. /// @{
  548. /// Allocate a target for doing render to texture operations, with no
  549. /// depth/stencil buffer.
  550. virtual GFXTextureTarget *allocRenderToTextureTarget()=0;
  551. /// Allocate a target for a given window.
  552. virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window)=0;
  553. /// Store the current render target to restore later.
  554. void pushActiveRenderTarget();
  555. /// Restore the previous render target.
  556. void popActiveRenderTarget();
  557. /// Assign a new active render target.
  558. void setActiveRenderTarget( GFXTarget *target, bool updateViewport=true );
  559. /// Returns the current active render target.
  560. inline GFXTarget* getActiveRenderTarget() { return mCurrentRT; }
  561. ///@}
  562. /// @name Shader functions
  563. /// @{
  564. virtual F32 getPixelShaderVersion() const = 0;
  565. virtual void setPixelShaderVersion( F32 version ) = 0;
  566. /// Returns the number of texture samplers that can be used in a shader rendering pass
  567. virtual U32 getNumSamplers() const = 0;
  568. /// Returns the number of simultaneous render targets supported by the device.
  569. virtual U32 getNumRenderTargets() const = 0;
  570. virtual void setShader( GFXShader *shader ) {}
  571. virtual void disableShaders() {}
  572. /// Set the buffer! (Actual set happens on the next draw call, just like textures, state blocks, etc)
  573. void setShaderConstBuffer(GFXShaderConstBuffer* buffer);
  574. /// Creates a new empty shader which must be initialized
  575. /// and deleted by the caller.
  576. /// @see GFXShader::init
  577. virtual GFXShader* createShader() = 0;
  578. /// @}
  579. //-----------------------------------------------------------------------------
  580. /// @name Rendering methods
  581. /// @{
  582. ///
  583. virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil ) = 0;
  584. virtual bool beginScene();
  585. virtual void endScene();
  586. virtual void beginField();
  587. virtual void endField();
  588. PlatformTimer *mFrameTime;
  589. virtual GFXTexHandle & getFrontBuffer(){ return mFrontBuffer[mCurrentFrontBufferIdx]; }
  590. void setPrimitiveBuffer( GFXPrimitiveBuffer *buffer );
  591. /// Sets the vertex buffer.
  592. ///
  593. /// When setting the stream 0 vertex buffer it will automatically
  594. /// set its associated vertex format as the active format.
  595. ///
  596. /// @param buffer The vertex buffer or NULL to clear the buffer.
  597. /// @param stream The stream index of the vertex source stream to place the buffer.
  598. /// @param frequency The stream frequency of the vertex buffer.
  599. void setVertexBuffer( GFXVertexBuffer *buffer, U32 stream = 0, U32 frequency = 0 );
  600. /// Sets the current vertex format.
  601. ///
  602. /// This should only be used if the vertex format of the stream 0 vertex
  603. /// buffer is different from the one associated to it. Typically this
  604. /// is used when rendering from multiple vertex streams.
  605. ///
  606. void setVertexFormat( const GFXVertexFormat *vertexFormat );
  607. virtual void drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount ) = 0;
  608. /// The parameters to drawIndexedPrimitive are somewhat complicated. From a raw-data stand point
  609. /// they evaluate to something like the following:
  610. /// @code
  611. /// U16 indicies[] = { 0, 1, 2, 1, 0, 0, 2 };
  612. /// Point3F verts[] = { Point3F( 0.0f, 0.0f, 0.0f ), Point3F( 0.0f, 1.0f, 0.0f ), Point3F( 0.0f, 0.0f, 1.0f ) };
  613. ///
  614. /// GFX->drawIndexedPrimitive( GFXLineList, // Drawing a list of lines, each line is two verts
  615. /// 0, // vertex 0 will be referenced so minIndex = 0
  616. /// 3, // 3 verticies will be used for this draw call
  617. /// 1, // We want index 1 to be the first index used, so indicies 1-6 will be used
  618. /// 3 // Drawing 3 LineList primitives, meaning 6 verts will be drawn
  619. /// );
  620. ///
  621. /// U16 *idxPtr = &indicies[1]; // 1 = startIndex, so the pointer is offset such that:
  622. /// // idxPtr[0] is the same as indicies[1]
  623. ///
  624. /// U32 numVertsToDrawFromBuffer = primitiveCount * 2; // 2 verts define a line in the GFXLineList primitive type (6)
  625. /// @endcode
  626. ///
  627. /// @param primType Type of primitive to draw
  628. ///
  629. /// @param startVertex This defines index zero. Its the offset from the start of
  630. /// the vertex buffer to the first vertex.
  631. ///
  632. /// @param minIndex The smallest index into the vertex stream which will be used for this draw call.
  633. /// This is a zero based index relative to startVertex. It is strictly a performance
  634. /// hint for implementations. No vertex below minIndex will be referenced by this draw
  635. /// call. For device implementors, this should _not_ be used to offset the vertex buffer,
  636. /// or index buffer.
  637. ///
  638. /// @param numVerts The number of verticies which will be referenced in this draw call. This is not
  639. /// the number of verticies which will be drawn. That is a function of 'primType' and
  640. /// 'primitiveCount'.
  641. ///
  642. /// @param startIndex An offset from the start of the index buffer to specify where to start. If
  643. /// 'idxBuffer' is a pointer to an array of integers, this could be written as
  644. /// int *offsetIdx = idxBuffer + startIndex;
  645. ///
  646. /// @param primitiveCount The number of primitives of type 'primType' to draw.
  647. ///
  648. virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
  649. U32 startVertex,
  650. U32 minIndex,
  651. U32 numVerts,
  652. U32 startIndex,
  653. U32 primitiveCount ) = 0;
  654. void drawPrimitive( const GFXPrimitive &prim );
  655. void drawPrimitive( U32 primitiveIndex );
  656. void drawPrimitives();
  657. void drawPrimitiveBuffer( GFXPrimitiveBuffer *buffer );
  658. /// @}
  659. //-----------------------------------------------------------------------------
  660. /// Allocate a fence. The API specific implementation of GFXDevice is responsible
  661. /// to make sure that the proper type is used. GFXGeneralFence should work in
  662. /// all cases.
  663. virtual GFXFence *createFence() = 0;
  664. /// Returns a hardware occlusion query object or NULL
  665. /// if this device does not support them.
  666. virtual GFXOcclusionQuery* createOcclusionQuery() { return NULL; }
  667. /// @name Light Settings
  668. /// NONE of these should be overridden by API implementations
  669. /// because of the state caching stuff.
  670. /// @{
  671. void setLight(U32 stage, GFXLightInfo* light);
  672. void setLightMaterial(GFXLightMaterial mat);
  673. void setGlobalAmbientColor(ColorF color);
  674. /// @}
  675. /// @name Texture State Settings
  676. /// NONE of these should be overridden by API implementations
  677. /// because of the state caching stuff.
  678. /// @{
  679. ///
  680. void setTexture(U32 stage, GFXTextureObject*texture);
  681. void setCubeTexture( U32 stage, GFXCubemap *cubemap );
  682. inline GFXTextureObject* getCurrentTexture( U32 stage ) { return mCurrentTexture[stage]; }
  683. /// @}
  684. /// @name State Block Interface
  685. /// @{
  686. /// Creates a state block object based on the desc passed in. This object
  687. /// represents an immutable state.
  688. virtual GFXStateBlockRef createStateBlock( const GFXStateBlockDesc &desc );
  689. /// Sets the current stateblock (actually activated in ::updateStates)
  690. virtual void setStateBlock( GFXStateBlock *block );
  691. /// This sets a stateblock directly from the description
  692. /// structure. Its acceptable to use this for debug rendering
  693. /// and other low frequency rendering tasks.
  694. virtual void setStateBlockByDesc( const GFXStateBlockDesc &desc );
  695. /// @}
  696. /// @name General state interface
  697. /// @{
  698. /// Sets the dirty Render/Texture/Sampler states from the caching system
  699. void updateStates(bool forceSetAll = false);
  700. /// Returns the forced global wireframe state.
  701. static bool getWireframe() { return smWireframe; }
  702. /// Returns true if the occlusion query is disabled.
  703. static bool getDisableOcclusionQuery() { return smDisableOcclusionQuery; }
  704. /// @}
  705. //-----------------------------------------------------------------------------
  706. /// @name Matrix interface
  707. /// @{
  708. /// Sets the top of the world matrix stack
  709. /// @param newWorld New world matrix to set
  710. void setWorldMatrix( const MatrixF &newWorld );
  711. /// Gets the matrix on the top of the world matrix stack
  712. inline const MatrixF &getWorldMatrix() const { return mWorldMatrix[mWorldStackSize]; }
  713. /// Pushes the world matrix stack and copies the current top
  714. /// matrix to the new top of the stack
  715. void pushWorldMatrix();
  716. /// Pops the world matrix stack
  717. void popWorldMatrix();
  718. /// Sets the projection matrix
  719. /// @param newProj New projection matrix to set
  720. void setProjectionMatrix( const MatrixF &newProj );
  721. /// Gets the projection matrix
  722. inline const MatrixF &getProjectionMatrix() const { return mProjectionMatrix; }
  723. /// Sets the view matrix
  724. /// @param newView New view matrix to set
  725. void setViewMatrix( const MatrixF &newView );
  726. /// Gets the view matrix
  727. inline const MatrixF &getViewMatrix() const { return mViewMatrix; }
  728. /// Multiplies the matrix at the top of the world matrix stack by a matrix
  729. /// and replaces the top of the matrix stack with the result
  730. /// @param mat Matrix to multiply
  731. void multWorld( const MatrixF &mat );
  732. /// Set texture matrix for a sampler
  733. void setTextureMatrix( const U32 stage, const MatrixF &texMat );
  734. /// Set an area of the target to render to.
  735. void setViewport( const RectI &rect );
  736. /// Get the current area of the target we will render to.
  737. const RectI &getViewport() const { return mViewport; }
  738. virtual void setClipRect( const RectI &rect ) = 0;
  739. virtual const RectI &getClipRect() const = 0;
  740. /// Set the projection frustum.
  741. ///
  742. /// @see MathUtils::makeFrustum()
  743. virtual void setFrustum( F32 left, F32 right,
  744. F32 bottom, F32 top,
  745. F32 nearPlane, F32 farPlane,
  746. bool bRotate = true);
  747. ///
  748. virtual void setFrustum( const Frustum& frust,
  749. bool bRotate = true );
  750. /// Get the projection frustum.
  751. void getFrustum( F32 *left,
  752. F32 *right,
  753. F32 *bottom,
  754. F32 *top,
  755. F32 *nearPlane,
  756. F32 *farPlane,
  757. bool *isOrtho ) const;
  758. /// Get the projection frustum.
  759. const Frustum& getFrustum() const { return mFrustum; }
  760. /// This will construct and apply an orthographic projection matrix with the provided parameters
  761. /// @param doRotate If set to true, the resulting matrix will be rotated PI/2 around the X axis
  762. // for support in tsShapeInstance. You probably want to leave this as 'false'.
  763. void setOrtho(F32 left, F32 right, F32 bottom, F32 top, F32 nearPlane, F32 farPlane, bool doRotate = false);
  764. /// Return true if the current frustum uses orthographic projection rather than perspective projection.
  765. bool isFrustumOrtho() const { return mFrustum.isOrtho(); }
  766. /// @}
  767. /// Returns the scale for converting world space
  768. /// units to screen space units... aka pixels.
  769. ///
  770. /// This is the true scale which is best used for GUI
  771. /// drawing. For doing lod calculations you should be
  772. /// using the functions in SceneState which is adjusted
  773. /// for special cases like shadows and reflections.
  774. ///
  775. /// @see SceneState::getWorldToScreenScale()
  776. /// @see SceneState::projectRadius()
  777. ///
  778. Point2F getWorldToScreenScale() const;
  779. public:
  780. enum GenericShaderType
  781. {
  782. GSColor = 0,
  783. GSTexture,
  784. GSModColorTexture,
  785. GSAddColorTexture,
  786. GSTargetRestore,
  787. GS_COUNT
  788. };
  789. /// This is a helper function to set a default shader for rendering GUI elements
  790. /// on systems which do not support fixed-function operations as well as for
  791. /// things which need just generic position/texture/color shaders
  792. ///
  793. /// @param type Type of generic shader, add your own if you need
  794. virtual void setupGenericShaders( GenericShaderType type = GSColor ) {};
  795. /// Get the fill convention for this device
  796. virtual F32 getFillConventionOffset() const = 0;
  797. virtual U32 getMaxDynamicVerts() = 0;
  798. virtual U32 getMaxDynamicIndices() = 0;
  799. virtual void doParanoidStateCheck(){};
  800. /// Get access to this device's drawing utility class.
  801. GFXDrawUtil *getDrawUtil();
  802. #ifndef TORQUE_SHIPPING
  803. /// This is a method designed for debugging. It will allow you to dump the states
  804. /// in the render manager out to a file so that it can be diffed and examined.
  805. void dumpStates( const char *fileName ) const;
  806. #else
  807. void dumpStates( const char *fileName ) const {};
  808. #endif
  809. protected:
  810. GFXDrawUtil *mDrawer;
  811. };
  812. //-----------------------------------------------------------------------------
  813. // Matrix interface
  814. inline void GFXDevice::setWorldMatrix( const MatrixF &newWorld )
  815. {
  816. mWorldMatrixDirty = true;
  817. mStateDirty = true;
  818. mWorldMatrix[mWorldStackSize] = newWorld;
  819. }
  820. inline void GFXDevice::pushWorldMatrix()
  821. {
  822. mWorldMatrixDirty = true;
  823. mStateDirty = true;
  824. mWorldStackSize++;
  825. AssertFatal( mWorldStackSize < WORLD_STACK_MAX, "GFX: Exceeded world matrix stack size" );
  826. mWorldMatrix[mWorldStackSize] = mWorldMatrix[mWorldStackSize - 1];
  827. }
  828. inline void GFXDevice::popWorldMatrix()
  829. {
  830. mWorldMatrixDirty = true;
  831. mStateDirty = true;
  832. mWorldStackSize--;
  833. AssertFatal( mWorldStackSize >= 0, "GFX: Negative WorldStackSize!" );
  834. }
  835. inline void GFXDevice::multWorld( const MatrixF &mat )
  836. {
  837. mWorldMatrixDirty = true;
  838. mStateDirty = true;
  839. mWorldMatrix[mWorldStackSize].mul(mat);
  840. }
  841. inline void GFXDevice::setProjectionMatrix( const MatrixF &newProj )
  842. {
  843. mProjectionMatrixDirty = true;
  844. mStateDirty = true;
  845. mProjectionMatrix = newProj;
  846. }
  847. inline void GFXDevice::setViewMatrix( const MatrixF &newView )
  848. {
  849. mStateDirty = true;
  850. mViewMatrixDirty = true;
  851. mViewMatrix = newView;
  852. }
  853. inline void GFXDevice::setTextureMatrix( const U32 stage, const MatrixF &texMat )
  854. {
  855. AssertFatal( stage < TEXTURE_STAGE_COUNT, "Out of range texture sampler" );
  856. mStateDirty = true;
  857. mTextureMatrixDirty[stage] = true;
  858. mTextureMatrix[stage] = texMat;
  859. mTextureMatrixCheckDirty = true;
  860. }
  861. //-----------------------------------------------------------------------------
  862. // Buffer management
  863. inline void GFXDevice::setVertexBuffer( GFXVertexBuffer *buffer, U32 stream, U32 frequency )
  864. {
  865. AssertFatal( stream < VERTEX_STREAM_COUNT, "GFXDevice::setVertexBuffer - Bad stream index!" );
  866. if ( buffer && stream == 0 )
  867. setVertexFormat( &buffer->mVertexFormat );
  868. if ( buffer != mCurrentVertexBuffer[stream] )
  869. {
  870. mCurrentVertexBuffer[stream] = buffer;
  871. mVertexBufferDirty[stream] = true;
  872. mStateDirty = true;
  873. }
  874. if ( mVertexBufferFrequency[stream] != frequency )
  875. {
  876. mVertexBufferFrequency[stream] = frequency;
  877. mVertexBufferFrequencyDirty[stream] = true;
  878. mStateDirty = true;
  879. }
  880. }
  881. inline void GFXDevice::setVertexFormat( const GFXVertexFormat *vertexFormat )
  882. {
  883. if ( vertexFormat->getDecl() == mCurrVertexDecl )
  884. return;
  885. mCurrVertexDecl = vertexFormat->getDecl();
  886. mVertexDeclDirty = true;
  887. mStateDirty = true;
  888. }
  889. #endif // _GFXDEVICE_H_