gfxDevice.h 41 KB

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