gfxDevice.h

Engine/source/gfx/gfxDevice.h

More...

Classes:

class

GFXDevice is the TSE graphics interface layer.

Public Defines

define
GFX() ()
define
GFXAssertFatal(x, error) 
define

Detailed Description

Public Defines

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