gfxDevice.h 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  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 rendered a frame and ended the scene
  202. dePostFrame,
  203. /// The device has started rendering a frame's field (such as for side-by-side rendering)
  204. deStartOfField,
  205. /// left stereo frame has been rendered
  206. deLeftStereoFrameRendered,
  207. /// right stereo frame has been rendered
  208. deRightStereoFrameRendered,
  209. /// The device is about to finish rendering a frame's field
  210. deEndOfField,
  211. };
  212. typedef Signal <bool (GFXDeviceEventType)> DeviceEventSignal;
  213. static DeviceEventSignal& getDeviceEventSignal();
  214. static GFXDevice *get() { return smGFXDevice; }
  215. static void initConsole();
  216. static bool destroy();
  217. static bool devicePresent() { return (smGFXDevice && smGFXDevice->getAdapterType() != NullDevice); }
  218. private:
  219. /// @name Device management variables
  220. /// @{
  221. static GFXDevice * smGFXDevice; ///< Global GFXDevice
  222. /// @}
  223. //--------------------------------------------------------------------------
  224. // Core GFX interface
  225. //--------------------------------------------------------------------------
  226. public:
  227. enum GFXDeviceRenderStyles
  228. {
  229. RS_Standard = 0,
  230. RS_StereoSideBySide = (1<<0), // Render into current Render Target side-by-side
  231. RS_StereoSeparate = (1<<1) // Render in two separate passes (then combined by vr compositor)
  232. };
  233. enum GFXDeviceLimits
  234. {
  235. NumStereoPorts = 2
  236. };
  237. private:
  238. /// Adapter for this device.
  239. GFXAdapter mAdapter;
  240. protected:
  241. /// List of valid video modes for this device.
  242. Vector<GFXVideoMode> mVideoModes;
  243. /// The CardProfiler for this device.
  244. GFXCardProfiler *mCardProfiler;
  245. /// Head of the resource list.
  246. ///
  247. /// @see GFXResource
  248. GFXResource *mResourceListHead;
  249. /// Set once the device is active.
  250. bool mCanCurrentlyRender;
  251. /// Set if we're in a mode where we want rendering to occur.
  252. bool mAllowRender;
  253. /// The style of rendering that is to be performed, based on GFXDeviceRenderStyles
  254. U32 mCurrentRenderStyle;
  255. /// Current stereo target being rendered to
  256. S32 mCurrentStereoTarget;
  257. /// Eye offset used when using a stereo rendering style
  258. Point3F mStereoEyeOffset[NumStereoPorts];
  259. /// Center matrix for head
  260. MatrixF mStereoHeadTransform;
  261. /// Left and right matrix for eyes
  262. MatrixF mStereoEyeTransforms[NumStereoPorts];
  263. /// Inverse of mStereoEyeTransforms
  264. MatrixF mInverseStereoEyeTransforms[NumStereoPorts];
  265. /// Fov port settings
  266. FovPort mFovPorts[NumStereoPorts];
  267. /// Destination viewports for stereo rendering
  268. RectI mStereoViewports[NumStereoPorts];
  269. /// Destination targets for stereo rendering
  270. GFXTextureTarget* mStereoTargets[NumStereoPorts];
  271. /// This will allow querying to see if a device is initialized and ready to
  272. /// have operations performed on it.
  273. bool mInitialized;
  274. bool mReset;
  275. /// This is called before this, or any other device, is deleted in the global destroy()
  276. /// method. It allows the device to clean up anything while everything is still valid.
  277. virtual void preDestroy();
  278. /// Set the adapter that this device is using. For use by GFXInit::createDevice only.
  279. virtual void setAdapter(const GFXAdapter& adapter) { mAdapter = adapter; }
  280. /// Notify GFXDevice that we are initialized
  281. virtual void deviceInited();
  282. public:
  283. GFXDevice();
  284. virtual ~GFXDevice();
  285. /// Initialize this GFXDevice, optionally specifying a platform window to
  286. /// bind to.
  287. virtual void init( const GFXVideoMode &mode, PlatformWindow *window = NULL ) = 0;
  288. /// Returns true if the scene has begun and its
  289. /// safe to make rendering calls.
  290. /// @see beginScene
  291. /// @see endScene
  292. bool canCurrentlyRender() const { return mCanCurrentlyRender; }
  293. bool recentlyReset(){ return mReset; }
  294. void beginReset(){ mReset = true; }
  295. void finalizeReset(){ mReset = false; }
  296. void setAllowRender( bool render ) { mAllowRender = render; }
  297. inline bool allowRender() const { return mAllowRender; }
  298. /// Retrieve the current rendering style based on GFXDeviceRenderStyles
  299. U32 getCurrentRenderStyle() const { return mCurrentRenderStyle; }
  300. /// Retrieve the current stereo target being rendered to
  301. S32 getCurrentStereoTarget() const { return mCurrentStereoTarget; }
  302. /// Set the current rendering style, based on GFXDeviceRenderStyles
  303. void setCurrentRenderStyle(U32 style) { mCurrentRenderStyle = style; }
  304. /// Set the current stereo target being rendered to (in case we're doing anything with postfx)
  305. void setCurrentStereoTarget(const F32 targetId) { mCurrentStereoTarget = targetId; }
  306. /// Get the current eye offset used during stereo rendering
  307. const Point3F* getStereoEyeOffsets() { return mStereoEyeOffset; }
  308. const MatrixF& getStereoHeadTransform() { return mStereoHeadTransform; }
  309. const MatrixF* getStereoEyeTransforms() { return mStereoEyeTransforms; }
  310. const MatrixF* getInverseStereoEyeTransforms() { return mInverseStereoEyeTransforms; }
  311. /// Sets the head matrix for stereo rendering
  312. void setStereoHeadTransform(const MatrixF &mat) { mStereoHeadTransform = mat; }
  313. /// Set the current eye offset used during stereo rendering
  314. void setStereoEyeOffsets(Point3F *offsets) { dMemcpy(mStereoEyeOffset, offsets, sizeof(Point3F) * NumStereoPorts); }
  315. void setStereoEyeTransforms(MatrixF *transforms) { dMemcpy(mStereoEyeTransforms, transforms, sizeof(mStereoEyeTransforms)); dMemcpy(mInverseStereoEyeTransforms, transforms, sizeof(mInverseStereoEyeTransforms)); mInverseStereoEyeTransforms[0].inverse(); mInverseStereoEyeTransforms[1].inverse(); }
  316. /// Set the current eye offset used during stereo rendering. Assumes NumStereoPorts are available.
  317. void setStereoFovPort(const FovPort *ports) { dMemcpy(mFovPorts, ports, sizeof(mFovPorts)); }
  318. /// Get the current eye offset used during stereo rendering
  319. const FovPort* getStereoFovPort() { return mFovPorts; }
  320. /// Sets stereo viewports
  321. void setSteroViewports(const RectI *ports) { dMemcpy(mStereoViewports, ports, sizeof(RectI) * NumStereoPorts); }
  322. /// Sets stereo render targets
  323. void setStereoTargets(GFXTextureTarget **targets) { mStereoTargets[0] = targets[0]; mStereoTargets[1] = targets[1]; }
  324. RectI* getStereoViewports() { return mStereoViewports; }
  325. /// Activates a stereo render target, setting the correct viewport to render eye contents.
  326. /// If eyeId is -1, set a viewport encompassing the entire size of the render targets.
  327. void activateStereoTarget(S32 eyeId)
  328. {
  329. if (eyeId == -1)
  330. {
  331. if (mStereoTargets[0])
  332. {
  333. setActiveRenderTarget(mStereoTargets[0], true);
  334. }
  335. }
  336. else
  337. {
  338. if (mStereoTargets[eyeId])
  339. {
  340. setActiveRenderTarget(mStereoTargets[eyeId], false);
  341. }
  342. setViewport(mStereoViewports[eyeId]);
  343. }
  344. mCurrentStereoTarget = eyeId;
  345. }
  346. GFXCardProfiler* getCardProfiler() const { return mCardProfiler; }
  347. /// Returns active graphics adapter type.
  348. virtual GFXAdapterType getAdapterType()=0;
  349. /// Returns the Adapter that was used to create this device
  350. virtual const GFXAdapter& getAdapter() { return mAdapter; }
  351. /// @}
  352. /// @name Debug Methods
  353. /// @{
  354. virtual void enterDebugEvent(ColorI color, const char *name) = 0;
  355. virtual void leaveDebugEvent() = 0;
  356. virtual void setDebugMarker(ColorI color, const char *name) = 0;
  357. /// @}
  358. /// @name Resource debug methods
  359. /// @{
  360. /// Lists how many of each GFX resource (e.g. textures, texture targets, shaders, etc.) GFX is aware of
  361. /// @param unflaggedOnly If true, this method only counts unflagged resources
  362. virtual void listResources(bool unflaggedOnly);
  363. /// Flags all resources GFX is currently aware of
  364. virtual void flagCurrentResources();
  365. /// Clears the flag on all resources GFX is currently aware of
  366. virtual void clearResourceFlags();
  367. /// Dumps a description of the specified resource types to the console
  368. /// @param resNames A string of space separated class names (e.g. "GFXTextureObject GFXTextureTarget GFXShader")
  369. /// to describe to the console
  370. /// @param file A path to the file to write the descriptions to. If it is NULL or "", descriptions are
  371. /// written to the console.
  372. /// @param unflaggedOnly If true, this method only counts unflagged resources
  373. /// @note resNames is case sensitive because there is no dStristr function.
  374. virtual void describeResources(const char* resName, const char* file, bool unflaggedOnly);
  375. /// Returns the current GFXDeviceStatistics, stats are cleared every ::beginScene call.
  376. GFXDeviceStatistics* getDeviceStatistics() { return &mDeviceStatistics; }
  377. protected:
  378. GFXDeviceStatistics mDeviceStatistics;
  379. /// This is a helper method for describeResourcesToFile. It walks through the
  380. /// GFXResource list and sorts it by item type, putting the resources into the proper vector.
  381. /// @see describeResources
  382. virtual void fillResourceVectors(const char* resNames, bool unflaggedOnly, Vector<GFXResource*> &textureObjects,
  383. Vector<GFXResource*> &textureTargets, Vector<GFXResource*> &windowTargets, Vector<GFXResource*> &vertexBuffers,
  384. Vector<GFXResource*> &primitiveBuffers, Vector<GFXResource*> &fences, Vector<GFXResource*> &cubemaps,
  385. Vector<GFXResource*> &shaders, Vector<GFXResource*> &stateblocks);
  386. public:
  387. /// @}
  388. /// @name Video Mode Functions
  389. /// @{
  390. /// Enumerates the supported video modes of the device
  391. virtual void enumerateVideoModes() = 0;
  392. /// Returns the video mode list.
  393. /// @see GFXVideoMode
  394. const Vector<GFXVideoMode>* const getVideoModeList() const { return &mVideoModes; }
  395. /// Returns the first format from the list which meets all
  396. /// the criteria of the texture profile and query options.
  397. virtual GFXFormat selectSupportedFormat(GFXTextureProfile *profile,
  398. const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter) = 0;
  399. /// @}
  400. //-----------------------------------------------------------------------------
  401. protected:
  402. /// @name State tracking variables
  403. /// @{
  404. /// Set if ANY state is dirty, including matrices or primitive buffers.
  405. bool mStateDirty;
  406. enum TexDirtyType
  407. {
  408. GFXTDT_Normal,
  409. GFXTDT_Cube
  410. };
  411. GFXTexHandle mCurrentTexture[TEXTURE_STAGE_COUNT];
  412. GFXTexHandle mNewTexture[TEXTURE_STAGE_COUNT];
  413. GFXCubemapHandle mCurrentCubemap[TEXTURE_STAGE_COUNT];
  414. GFXCubemapHandle mNewCubemap[TEXTURE_STAGE_COUNT];
  415. TexDirtyType mTexType[TEXTURE_STAGE_COUNT];
  416. bool mTextureDirty[TEXTURE_STAGE_COUNT];
  417. bool mTexturesDirty;
  418. // This maps a GFXStateBlockDesc hash value to a GFXStateBlockRef
  419. typedef Map<U32, GFXStateBlockRef> StateBlockMap;
  420. StateBlockMap mCurrentStateBlocks;
  421. // This tracks whether or not our state block is dirty.
  422. bool mStateBlockDirty;
  423. GFXStateBlockRef mCurrentStateBlock;
  424. GFXStateBlockRef mNewStateBlock;
  425. GFXShaderConstBuffer *mCurrentShaderConstBuffer;
  426. /// A global forced wireframe mode.
  427. static bool smWireframe;
  428. /// The global vsync state.
  429. static bool smDisableVSync;
  430. /// The forced shader model version if non-zero.
  431. static F32 smForcedPixVersion;
  432. /// Disable all hardware occlusion queries causing
  433. /// them to return only the visibile state.
  434. static bool smDisableOcclusionQuery;
  435. /// @}
  436. /// @name Light Tracking
  437. /// @{
  438. GFXLightInfo mCurrentLight[LIGHT_STAGE_COUNT];
  439. bool mCurrentLightEnable[LIGHT_STAGE_COUNT];
  440. bool mLightDirty[LIGHT_STAGE_COUNT];
  441. bool mLightsDirty;
  442. ColorF mGlobalAmbientColor;
  443. bool mGlobalAmbientColorDirty;
  444. /// @}
  445. /// @name Fixed function material tracking
  446. /// @{
  447. GFXLightMaterial mCurrentLightMaterial;
  448. bool mLightMaterialDirty;
  449. /// @}
  450. /// @name Bitmap modulation and color stack
  451. /// @{
  452. ///
  453. /// @}
  454. /// @see getDeviceSwizzle32
  455. Swizzle<U8, 4> *mDeviceSwizzle32;
  456. /// @see getDeviceSwizzle24
  457. Swizzle<U8, 3> *mDeviceSwizzle24;
  458. //-----------------------------------------------------------------------------
  459. /// @name Matrix managing variables
  460. /// @{
  461. ///
  462. MatrixF mWorldMatrix[WORLD_STACK_MAX];
  463. bool mWorldMatrixDirty;
  464. S32 mWorldStackSize;
  465. MatrixF mProjectionMatrix;
  466. bool mProjectionMatrixDirty;
  467. MatrixF mViewMatrix;
  468. bool mViewMatrixDirty;
  469. MatrixF mTextureMatrix[TEXTURE_STAGE_COUNT];
  470. bool mTextureMatrixDirty[TEXTURE_STAGE_COUNT];
  471. bool mTextureMatrixCheckDirty;
  472. /// @}
  473. /// @name Current frustum planes
  474. /// @{
  475. ///
  476. Frustum mFrustum;
  477. //-----------------------------------------------------------------------------
  478. /// @name Stateblock functions
  479. /// @{
  480. /// Called by GFXDevice to create a device specific stateblock
  481. virtual GFXStateBlockRef createStateBlockInternal(const GFXStateBlockDesc& desc) = 0;
  482. /// Called by GFXDevice to actually set a stateblock.
  483. /// @param force If true, set all states
  484. virtual void setStateBlockInternal(GFXStateBlock* block, bool force) = 0;
  485. /// @}
  486. /// Called by base GFXDevice to actually set a const buffer
  487. virtual void setShaderConstBufferInternal(GFXShaderConstBuffer* buffer) = 0;
  488. virtual void setTextureInternal(U32 textureUnit, const GFXTextureObject*texture) = 0;
  489. virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable) = 0;
  490. virtual void setGlobalAmbientInternal(ColorF color) = 0;
  491. virtual void setLightMaterialInternal(const GFXLightMaterial mat) = 0;
  492. virtual bool beginSceneInternal() = 0;
  493. virtual void endSceneInternal() = 0;
  494. /// @name State Initialization.
  495. /// @{
  496. /// State initialization. This MUST BE CALLED in setVideoMode after the device
  497. /// is created.
  498. virtual void initStates() = 0;
  499. /// @}
  500. //-----------------------------------------------------------------------------
  501. /// This function must be implemented differently per
  502. /// API and it should set ONLY the current matrix.
  503. /// For example, in OpenGL, there should be NO matrix stack
  504. /// activity, all the stack stuff is managed in the GFX layer.
  505. ///
  506. /// OpenGL does not have separate world and
  507. /// view matrices. It has ModelView which is world * view.
  508. /// You must take this into consideration.
  509. ///
  510. /// @param mtype Which matrix to set, world/view/projection
  511. /// @param mat Matrix to assign
  512. virtual void setMatrix( GFXMatrixType mtype, const MatrixF &mat ) = 0;
  513. //-----------------------------------------------------------------------------
  514. protected:
  515. /// @name Buffer Allocation
  516. /// These methods are implemented per-device and are called by the GFX layer
  517. /// when a user calls an alloc
  518. ///
  519. /// @note Primitive Buffers are NOT implemented per device, they wrap index buffers
  520. /// @{
  521. /// This allocates a vertex buffer and returns a pointer to the allocated buffer.
  522. /// This function should not be called directly - rather it should be used by
  523. /// the GFXVertexBufferHandle class.
  524. virtual GFXVertexBuffer *allocVertexBuffer( U32 numVerts,
  525. const GFXVertexFormat *vertexFormat,
  526. U32 vertSize,
  527. GFXBufferType bufferType,
  528. void* data = NULL ) = 0;
  529. /// Called from GFXVertexFormat to allocate the hardware
  530. /// specific vertex declaration for rendering.
  531. virtual GFXVertexDecl* allocVertexDecl( const GFXVertexFormat *vertexFormat ) = 0;
  532. /// Sets the current vertex declaration on the device.
  533. virtual void setVertexDecl( const GFXVertexDecl *decl ) = 0;
  534. /// Sets the vertex buffer on the device.
  535. virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer ) = 0;
  536. /// Set the vertex stream frequency on the device.
  537. virtual void setVertexStreamFrequency( U32 stream, U32 frequency ) = 0;
  538. /// The maximum number of supported vertex streams which
  539. /// may be more than the device supports.
  540. static const U32 VERTEX_STREAM_COUNT = 4;
  541. StrongRefPtr<GFXVertexBuffer> mCurrentVertexBuffer[VERTEX_STREAM_COUNT];
  542. bool mVertexBufferDirty[VERTEX_STREAM_COUNT];
  543. U32 mVertexBufferFrequency[VERTEX_STREAM_COUNT];
  544. bool mVertexBufferFrequencyDirty[VERTEX_STREAM_COUNT];
  545. const GFXVertexDecl *mCurrVertexDecl;
  546. bool mVertexDeclDirty;
  547. StrongRefPtr<GFXPrimitiveBuffer> mCurrentPrimitiveBuffer;
  548. bool mPrimitiveBufferDirty;
  549. /// This allocates a primitive buffer and returns a pointer to the allocated buffer.
  550. /// A primitive buffer's type argument refers to the index data - the primitive data will
  551. /// always be preserved from call to call.
  552. ///
  553. /// @note All index buffers use unsigned 16-bit indices.
  554. virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices,
  555. U32 numPrimitives,
  556. GFXBufferType bufferType,
  557. void* data = NULL ) = 0;
  558. /// @}
  559. //---------------------------------------
  560. // SFX buffer
  561. //---------------------------------------
  562. protected:
  563. GFXTexHandle mFrontBuffer[2];
  564. U32 mCurrentFrontBufferIdx;
  565. //---------------------------------------
  566. // Render target related
  567. //---------------------------------------
  568. /// A stack of previously active render targets.
  569. Vector<GFXTargetRef> mRTStack;
  570. /// The current render target which may or may not
  571. /// not be yet activated.
  572. /// @see mRTDirty
  573. GFXTargetRef mCurrentRT;
  574. /// This tracks a previously activated render target
  575. /// which need to be deactivated.
  576. GFXTargetRef mRTDeactivate;
  577. /// This is set when the current and/or deactivate render
  578. /// targets have changed and the device need to update
  579. /// its state on the next draw/clear.
  580. bool mRTDirty;
  581. /// Updates the render targets and viewport in a device
  582. /// specific manner when they are dirty.
  583. virtual void _updateRenderTargets() = 0;
  584. /// The current viewport rect.
  585. RectI mViewport;
  586. /// If true the viewport has been changed and
  587. /// it must be updated on the next draw/clear.
  588. bool mViewportDirty;
  589. public:
  590. /// @name Texture functions
  591. /// @{
  592. protected:
  593. GFXTextureManager * mTextureManager;
  594. public:
  595. virtual GFXCubemap * createCubemap() = 0;
  596. inline GFXTextureManager *getTextureManager()
  597. {
  598. return mTextureManager;
  599. }
  600. ///@}
  601. /// Swizzle to convert 32bpp bitmaps from RGBA to the native device format.
  602. const Swizzle<U8, 4> *getDeviceSwizzle32() const
  603. {
  604. return mDeviceSwizzle32;
  605. }
  606. /// Swizzle to convert 24bpp bitmaps from RGB to the native device format.
  607. const Swizzle<U8, 3> *getDeviceSwizzle24() const
  608. {
  609. return mDeviceSwizzle24;
  610. }
  611. /// @name Render Target functions
  612. /// @{
  613. /// Allocate a target for doing render to texture operations, with no
  614. /// depth/stencil buffer.
  615. virtual GFXTextureTarget *allocRenderToTextureTarget()=0;
  616. /// Allocate a target for a given window.
  617. virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window)=0;
  618. /// Store the current render target to restore later.
  619. void pushActiveRenderTarget();
  620. /// Restore the previous render target.
  621. void popActiveRenderTarget();
  622. /// Assign a new active render target.
  623. void setActiveRenderTarget( GFXTarget *target, bool updateViewport=true );
  624. /// Returns the current active render target.
  625. inline GFXTarget* getActiveRenderTarget() { return mCurrentRT; }
  626. ///@}
  627. /// @name Shader functions
  628. /// @{
  629. virtual F32 getPixelShaderVersion() const = 0;
  630. virtual void setPixelShaderVersion( F32 version ) = 0;
  631. /// Returns the number of texture samplers that can be used in a shader rendering pass
  632. virtual U32 getNumSamplers() const = 0;
  633. /// Returns the number of simultaneous render targets supported by the device.
  634. virtual U32 getNumRenderTargets() const = 0;
  635. virtual void setShader( GFXShader *shader, bool force = false ) {}
  636. virtual void disableShaders( bool force = false ) {} // TODO Remove when T3D 4.0
  637. /// Set the buffer! (Actual set happens on the next draw call, just like textures, state blocks, etc)
  638. void setShaderConstBuffer(GFXShaderConstBuffer* buffer);
  639. /// Creates a new empty shader which must be initialized
  640. /// and deleted by the caller.
  641. /// @see GFXShader::init
  642. virtual GFXShader* createShader() = 0;
  643. /// @}
  644. //-----------------------------------------------------------------------------
  645. /// @name Rendering methods
  646. /// @{
  647. ///
  648. virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil ) = 0;
  649. virtual bool beginScene();
  650. virtual void endScene();
  651. virtual void beginField();
  652. virtual void endField();
  653. PlatformTimer *mFrameTime;
  654. virtual GFXTexHandle & getFrontBuffer(){ return mFrontBuffer[mCurrentFrontBufferIdx]; }
  655. void setPrimitiveBuffer( GFXPrimitiveBuffer *buffer );
  656. /// Sets the vertex buffer.
  657. ///
  658. /// When setting the stream 0 vertex buffer it will automatically
  659. /// set its associated vertex format as the active format.
  660. ///
  661. /// @param buffer The vertex buffer or NULL to clear the buffer.
  662. /// @param stream The stream index of the vertex source stream to place the buffer.
  663. /// @param frequency The stream frequency of the vertex buffer.
  664. void setVertexBuffer( GFXVertexBuffer *buffer, U32 stream = 0, U32 frequency = 0 );
  665. /// Sets the current vertex format.
  666. ///
  667. /// This should only be used if the vertex format of the stream 0 vertex
  668. /// buffer is different from the one associated to it. Typically this
  669. /// is used when rendering from multiple vertex streams.
  670. ///
  671. void setVertexFormat( const GFXVertexFormat *vertexFormat );
  672. virtual void drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount ) = 0;
  673. /// The parameters to drawIndexedPrimitive are somewhat complicated. From a raw-data stand point
  674. /// they evaluate to something like the following:
  675. /// @code
  676. /// U16 indicies[] = { 0, 1, 2, 1, 0, 0, 2 };
  677. /// Point3F verts[] = { Point3F( 0.0f, 0.0f, 0.0f ), Point3F( 0.0f, 1.0f, 0.0f ), Point3F( 0.0f, 0.0f, 1.0f ) };
  678. ///
  679. /// GFX->drawIndexedPrimitive( GFXLineList, // Drawing a list of lines, each line is two verts
  680. /// 0, // vertex 0 will be referenced so minIndex = 0
  681. /// 3, // 3 verticies will be used for this draw call
  682. /// 1, // We want index 1 to be the first index used, so indicies 1-6 will be used
  683. /// 3 // Drawing 3 LineList primitives, meaning 6 verts will be drawn
  684. /// );
  685. ///
  686. /// U16 *idxPtr = &indicies[1]; // 1 = startIndex, so the pointer is offset such that:
  687. /// // idxPtr[0] is the same as indicies[1]
  688. ///
  689. /// U32 numVertsToDrawFromBuffer = primitiveCount * 2; // 2 verts define a line in the GFXLineList primitive type (6)
  690. /// @endcode
  691. ///
  692. /// @param primType Type of primitive to draw
  693. ///
  694. /// @param startVertex This defines index zero. Its the offset from the start of
  695. /// the vertex buffer to the first vertex.
  696. ///
  697. /// @param minIndex The smallest index into the vertex stream which will be used for this draw call.
  698. /// This is a zero based index relative to startVertex. It is strictly a performance
  699. /// hint for implementations. No vertex below minIndex will be referenced by this draw
  700. /// call. For device implementors, this should _not_ be used to offset the vertex buffer,
  701. /// or index buffer.
  702. ///
  703. /// @param numVerts The number of verticies which will be referenced in this draw call. This is not
  704. /// the number of verticies which will be drawn. That is a function of 'primType' and
  705. /// 'primitiveCount'.
  706. ///
  707. /// @param startIndex An offset from the start of the index buffer to specify where to start. If
  708. /// 'idxBuffer' is a pointer to an array of integers, this could be written as
  709. /// int *offsetIdx = idxBuffer + startIndex;
  710. ///
  711. /// @param primitiveCount The number of primitives of type 'primType' to draw.
  712. ///
  713. virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
  714. U32 startVertex,
  715. U32 minIndex,
  716. U32 numVerts,
  717. U32 startIndex,
  718. U32 primitiveCount ) = 0;
  719. void drawPrimitive( const GFXPrimitive &prim );
  720. void drawPrimitive( U32 primitiveIndex );
  721. void drawPrimitives();
  722. void drawPrimitiveBuffer( GFXPrimitiveBuffer *buffer );
  723. /// @}
  724. //-----------------------------------------------------------------------------
  725. /// Allocate a fence. The API specific implementation of GFXDevice is responsible
  726. /// to make sure that the proper type is used. GFXGeneralFence should work in
  727. /// all cases.
  728. virtual GFXFence *createFence() = 0;
  729. /// Returns a hardware occlusion query object or NULL
  730. /// if this device does not support them.
  731. virtual GFXOcclusionQuery* createOcclusionQuery() { return NULL; }
  732. /// @name Light Settings
  733. /// NONE of these should be overridden by API implementations
  734. /// because of the state caching stuff.
  735. /// @{
  736. void setLight(U32 stage, GFXLightInfo* light);
  737. void setLightMaterial(const GFXLightMaterial& mat);
  738. void setGlobalAmbientColor(const ColorF& color);
  739. /// @}
  740. /// @name Texture State Settings
  741. /// NONE of these should be overridden by API implementations
  742. /// because of the state caching stuff.
  743. /// @{
  744. ///
  745. void setTexture(U32 stage, GFXTextureObject*texture);
  746. void setCubeTexture( U32 stage, GFXCubemap *cubemap );
  747. inline GFXTextureObject* getCurrentTexture( U32 stage ) { return mCurrentTexture[stage]; }
  748. /// @}
  749. /// @name State Block Interface
  750. /// @{
  751. /// Creates a state block object based on the desc passed in. This object
  752. /// represents an immutable state.
  753. virtual GFXStateBlockRef createStateBlock( const GFXStateBlockDesc &desc );
  754. /// Sets the current stateblock (actually activated in ::updateStates)
  755. virtual void setStateBlock( GFXStateBlock *block );
  756. GFXStateBlock* getStateBlock() { return mNewStateBlock; }
  757. /// This sets a stateblock directly from the description
  758. /// structure. Its acceptable to use this for debug rendering
  759. /// and other low frequency rendering tasks.
  760. virtual void setStateBlockByDesc( const GFXStateBlockDesc &desc );
  761. /// @}
  762. /// @name General state interface
  763. /// @{
  764. /// Sets the dirty Render/Texture/Sampler states from the caching system
  765. void updateStates(bool forceSetAll = false);
  766. /// Returns the forced global wireframe state.
  767. static bool getWireframe() { return smWireframe; }
  768. /// Returns true if the occlusion query is disabled.
  769. static bool getDisableOcclusionQuery() { return smDisableOcclusionQuery; }
  770. /// @}
  771. //-----------------------------------------------------------------------------
  772. /// @name Matrix interface
  773. /// @{
  774. /// Sets the top of the world matrix stack
  775. /// @param newWorld New world matrix to set
  776. void setWorldMatrix( const MatrixF &newWorld );
  777. /// Gets the matrix on the top of the world matrix stack
  778. inline const MatrixF &getWorldMatrix() const { return mWorldMatrix[mWorldStackSize]; }
  779. /// Pushes the world matrix stack and copies the current top
  780. /// matrix to the new top of the stack
  781. void pushWorldMatrix();
  782. /// Pops the world matrix stack
  783. void popWorldMatrix();
  784. /// Sets the projection matrix
  785. /// @param newProj New projection matrix to set
  786. void setProjectionMatrix( const MatrixF &newProj );
  787. /// Gets the projection matrix
  788. inline const MatrixF &getProjectionMatrix() const { return mProjectionMatrix; }
  789. /// Sets the view matrix
  790. /// @param newView New view matrix to set
  791. void setViewMatrix( const MatrixF &newView );
  792. /// Gets the view matrix
  793. inline const MatrixF &getViewMatrix() const { return mViewMatrix; }
  794. /// Multiplies the matrix at the top of the world matrix stack by a matrix
  795. /// and replaces the top of the matrix stack with the result
  796. /// @param mat Matrix to multiply
  797. void multWorld( const MatrixF &mat );
  798. /// Set texture matrix for a sampler
  799. void setTextureMatrix( const U32 stage, const MatrixF &texMat );
  800. /// Set an area of the target to render to.
  801. void setViewport( const RectI &rect );
  802. /// Get the current area of the target we will render to.
  803. const RectI &getViewport() const { return mViewport; }
  804. virtual void setClipRect( const RectI &rect ) = 0;
  805. virtual const RectI &getClipRect() const = 0;
  806. /// Set the projection frustum.
  807. ///
  808. /// @see MathUtils::makeFrustum()
  809. virtual void setFrustum( F32 left, F32 right,
  810. F32 bottom, F32 top,
  811. F32 nearPlane, F32 farPlane,
  812. bool bRotate = true);
  813. ///
  814. virtual void setFrustum( const Frustum& frust,
  815. bool bRotate = true );
  816. /// Get the projection frustum.
  817. void getFrustum( F32 *left,
  818. F32 *right,
  819. F32 *bottom,
  820. F32 *top,
  821. F32 *nearPlane,
  822. F32 *farPlane,
  823. bool *isOrtho ) const;
  824. /// Get the projection frustum.
  825. const Frustum& getFrustum() const { return mFrustum; }
  826. /// This will construct and apply an orthographic projection matrix with the provided parameters
  827. /// @param doRotate If set to true, the resulting matrix will be rotated PI/2 around the X axis
  828. // for support in tsShapeInstance. You probably want to leave this as 'false'.
  829. void setOrtho(F32 left, F32 right, F32 bottom, F32 top, F32 nearPlane, F32 farPlane, bool doRotate = false);
  830. /// Return true if the current frustum uses orthographic projection rather than perspective projection.
  831. bool isFrustumOrtho() const { return mFrustum.isOrtho(); }
  832. /// @}
  833. /// Returns the scale for converting world space
  834. /// units to screen space units... aka pixels.
  835. ///
  836. /// This is the true scale which is best used for GUI
  837. /// drawing. For doing lod calculations you should be
  838. /// using the functions in SceneState which is adjusted
  839. /// for special cases like shadows and reflections.
  840. ///
  841. /// @see SceneState::getWorldToScreenScale()
  842. /// @see SceneState::projectRadius()
  843. ///
  844. Point2F getWorldToScreenScale() const;
  845. public:
  846. enum GenericShaderType
  847. {
  848. GSColor = 0,
  849. GSTexture,
  850. GSModColorTexture,
  851. GSAddColorTexture,
  852. GSTargetRestore,
  853. GS_COUNT
  854. };
  855. /// This is a helper function to set a default shader for rendering GUI elements
  856. /// on systems which do not support fixed-function operations as well as for
  857. /// things which need just generic position/texture/color shaders
  858. ///
  859. /// @param type Type of generic shader, add your own if you need
  860. virtual void setupGenericShaders( GenericShaderType type = GSColor ) {};
  861. /// Get the fill convention for this device
  862. virtual F32 getFillConventionOffset() const = 0;
  863. virtual U32 getMaxDynamicVerts() = 0;
  864. virtual U32 getMaxDynamicIndices() = 0;
  865. virtual void doParanoidStateCheck(){};
  866. /// Get access to this device's drawing utility class.
  867. GFXDrawUtil *getDrawUtil();
  868. #ifndef TORQUE_SHIPPING
  869. /// This is a method designed for debugging. It will allow you to dump the states
  870. /// in the render manager out to a file so that it can be diffed and examined.
  871. void dumpStates( const char *fileName ) const;
  872. #else
  873. void dumpStates( const char *fileName ) const {};
  874. #endif
  875. protected:
  876. GFXDrawUtil *mDrawer;
  877. };
  878. //-----------------------------------------------------------------------------
  879. // Matrix interface
  880. inline void GFXDevice::setWorldMatrix( const MatrixF &newWorld )
  881. {
  882. mWorldMatrixDirty = true;
  883. mStateDirty = true;
  884. mWorldMatrix[mWorldStackSize] = newWorld;
  885. }
  886. inline void GFXDevice::pushWorldMatrix()
  887. {
  888. mWorldMatrixDirty = true;
  889. mStateDirty = true;
  890. mWorldStackSize++;
  891. AssertFatal( mWorldStackSize < WORLD_STACK_MAX, "GFX: Exceeded world matrix stack size" );
  892. mWorldMatrix[mWorldStackSize] = mWorldMatrix[mWorldStackSize - 1];
  893. }
  894. inline void GFXDevice::popWorldMatrix()
  895. {
  896. mWorldMatrixDirty = true;
  897. mStateDirty = true;
  898. mWorldStackSize--;
  899. AssertFatal( mWorldStackSize >= 0, "GFX: Negative WorldStackSize!" );
  900. }
  901. inline void GFXDevice::multWorld( const MatrixF &mat )
  902. {
  903. mWorldMatrixDirty = true;
  904. mStateDirty = true;
  905. mWorldMatrix[mWorldStackSize].mul(mat);
  906. }
  907. inline void GFXDevice::setProjectionMatrix( const MatrixF &newProj )
  908. {
  909. mProjectionMatrixDirty = true;
  910. mStateDirty = true;
  911. mProjectionMatrix = newProj;
  912. }
  913. inline void GFXDevice::setViewMatrix( const MatrixF &newView )
  914. {
  915. mStateDirty = true;
  916. mViewMatrixDirty = true;
  917. mViewMatrix = newView;
  918. }
  919. inline void GFXDevice::setTextureMatrix( const U32 stage, const MatrixF &texMat )
  920. {
  921. AssertFatal( stage < TEXTURE_STAGE_COUNT, "Out of range texture sampler" );
  922. mStateDirty = true;
  923. mTextureMatrixDirty[stage] = true;
  924. mTextureMatrix[stage] = texMat;
  925. mTextureMatrixCheckDirty = true;
  926. }
  927. //-----------------------------------------------------------------------------
  928. // Buffer management
  929. inline void GFXDevice::setVertexBuffer( GFXVertexBuffer *buffer, U32 stream, U32 frequency )
  930. {
  931. AssertFatal( stream < VERTEX_STREAM_COUNT, "GFXDevice::setVertexBuffer - Bad stream index!" );
  932. if ( buffer && stream == 0 )
  933. setVertexFormat( &buffer->mVertexFormat );
  934. if ( buffer != mCurrentVertexBuffer[stream] )
  935. {
  936. mCurrentVertexBuffer[stream] = buffer;
  937. mVertexBufferDirty[stream] = true;
  938. mStateDirty = true;
  939. }
  940. if ( mVertexBufferFrequency[stream] != frequency )
  941. {
  942. mVertexBufferFrequency[stream] = frequency;
  943. mVertexBufferFrequencyDirty[stream] = true;
  944. mStateDirty = true;
  945. }
  946. }
  947. inline void GFXDevice::setVertexFormat( const GFXVertexFormat *vertexFormat )
  948. {
  949. if ( vertexFormat->getDecl() == mCurrVertexDecl )
  950. return;
  951. mCurrVertexDecl = vertexFormat->getDecl();
  952. mVertexDeclDirty = true;
  953. mStateDirty = true;
  954. }
  955. #if defined(TORQUE_DEBUG) && defined(TORQUE_DEBUG_GFX)
  956. #define GFXAssertFatal(x, error) AssertFatal(x, error)
  957. #else
  958. #define GFXAssertFatal(x, error)
  959. #endif
  960. #endif // _GFXDEVICE_H_