mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 04:34:48 +00:00
Processed core, tools and default modules to utilize assets Converted all console types that were string based, such as TypeImageFilename to utilize const char*/the string table, which avoids a lot of type swapping shenanigans and avoids string corruption Removed unneeded MainEditor mockup module Removed some unused/duplicate image assets from the tools
1141 lines
41 KiB
C++
1141 lines
41 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2012 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
#pragma once
|
|
#ifndef _GFXDEVICE_H_
|
|
#define _GFXDEVICE_H_
|
|
|
|
#ifndef _GFXADAPTER_H_
|
|
#include "gfx/gfxAdapter.h"
|
|
#endif
|
|
#ifndef _GFXTARGET_H_
|
|
#include "gfx/gfxTarget.h"
|
|
#endif
|
|
#ifndef _GFXVERTEXBUFFER_H_
|
|
#include "gfx/gfxVertexBuffer.h"
|
|
#endif
|
|
#ifndef _GFXSTATEBLOCK_H_
|
|
#include "gfx/gfxStateBlock.h"
|
|
#endif
|
|
#ifndef _GFXSHADER_H_
|
|
#include "gfx/gfxShader.h"
|
|
#endif
|
|
#ifndef _GFXCUBEMAP_H_
|
|
#include "gfx/gfxCubemap.h"
|
|
#endif
|
|
#ifndef _TDICTIONARY_H_
|
|
#include "core/util/tDictionary.h"
|
|
#endif
|
|
#ifndef _TSIGNAL_H_
|
|
#include "core/util/tSignal.h"
|
|
#endif
|
|
#ifndef _GFXDEVICESTATISTICS_H_
|
|
#include "gfx/gfxDeviceStatistics.h"
|
|
#endif
|
|
#ifndef _MATHUTIL_FRUSTUM_H_
|
|
#include "math/util/frustum.h"
|
|
#endif
|
|
|
|
#ifndef _PLATFORM_PLATFORMTIMER_H_
|
|
#include "platform/platformTimer.h"
|
|
#endif
|
|
#include "gfxTextureArray.h"
|
|
|
|
class FontRenderBatcher;
|
|
class GFont;
|
|
class GFXCardProfiler;
|
|
class GFXDrawUtil;
|
|
class GFXFence;
|
|
class GFXOcclusionQuery;
|
|
class GFXPrimitiveBuffer;
|
|
class GFXShader;
|
|
class GFXStateBlock;
|
|
class GFXShaderConstBuffer;
|
|
class GFXTextureManager;
|
|
|
|
// Global macro
|
|
#define GFX GFXDevice::get()
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// GFXDevice is the TSE graphics interface layer. This allows the TSE to
|
|
/// do many things, such as use multiple render devices for multi-head systems,
|
|
/// and allow a game to render in DirectX 9, OpenGL or any other API which has
|
|
/// a GFX implementation seamlessly. There are many concepts in GFX device which
|
|
/// may not be familiar to you, especially if you have not used DirectX.
|
|
/// @n
|
|
/// <b>Buffers</b>
|
|
/// There are three types of buffers in GFX: vertex, index and primitive. Please
|
|
/// note that index buffers are not accessable outside the GFX layer, they are wrapped
|
|
/// by primitive buffers. Primitive buffers will be explained in detail later.
|
|
/// Buffers are allocated and deallocated using their associated allocXBuffer and
|
|
/// freeXBuffer methods on the device. When a buffer is allocated you pass in a
|
|
/// pointer to, depending on the buffer, a vertex type pointer or a U16 pointer.
|
|
/// During allocation, this pointer is set to the address of where you should
|
|
/// copy in the information for this buffer. You must the tell the GFXDevice
|
|
/// that the information is in, and it should prepare the buffer for use by calling
|
|
/// the prepare method on it. Dynamic vertex buffer example:
|
|
/// @code
|
|
/// GFXVertexP *verts; // Making a buffer containing verticies with only position
|
|
///
|
|
/// // Allocate a dynamic vertex buffer to hold 3 vertices and use *verts as the location to copy information into
|
|
/// GFXVertexBufferHandle vb = GFX->allocVertexBuffer( 3, &verts, true );
|
|
///
|
|
/// // Now set the information, we're making a triangle
|
|
/// verts[0].point = Point3F( 200.f, 200.f, 0.f );
|
|
/// verts[1].point = Point3F( 200.f, 400.f, 0.f );
|
|
/// verts[2].point = Point3F( 400.f, 200.f, 0.f );
|
|
///
|
|
/// // Tell GFX that the information is in and it should be made ready for use
|
|
/// // Note that nothing is done with verts, this should not and MUST NOT be deleted
|
|
/// // stored, or otherwise used after prepare is called.
|
|
/// GFX->prepare( vb );
|
|
///
|
|
/// // Because this is a dynamic vertex buffer, it is only assured to be valid until someone
|
|
/// // else allocates a dynamic vertex buffer, so we will render it now
|
|
/// GFX->setVertexBuffer( vb );
|
|
/// GFX->drawPrimitive( GFXTriangleStrip, 0, 1 );
|
|
///
|
|
/// // Now because this is a dynamic vertex buffer it MUST NOT BE FREED you are only
|
|
/// // given a handle to a vertex buffer which belongs to the device
|
|
/// @endcode
|
|
///
|
|
/// To use a static vertex buffer, it is very similar, this is an example using a
|
|
/// static primitive buffer:
|
|
/// @n
|
|
/// This takes place inside a constructor for a class which has a member variable
|
|
/// called mPB which is the primitive buffer for the class instance.
|
|
/// @code
|
|
/// U16 *idx; // This is going to be where to write indices
|
|
/// GFXPrimitiveInfo *primitiveInfo; // This will be where to write primitive information
|
|
///
|
|
/// // Allocate a primitive buffer with 4 indices, and 1 primitive described for use
|
|
/// mPB = GFX->allocPrimitiveBuffer( 4, &idx, 1, &primitiveInfo );
|
|
///
|
|
/// // Write the index information, this is going to be for the outline of a triangle using
|
|
/// // a line strip
|
|
/// idx[0] = 0;
|
|
/// idx[1] = 1;
|
|
/// idx[2] = 2;
|
|
/// idx[3] = 0;
|
|
///
|
|
/// // Write the information for the primitive
|
|
/// primitiveInfo->indexStart = 0; // Starting with index 0
|
|
/// primitiveInfo->minVertex = 0; // The minimum vertex index is 0
|
|
/// primitiveInfo->maxVertex = 3; // The maximum vertex index is 3
|
|
/// primitiveInfo->primitiveCount = 3; // There are 3 lines we are drawing
|
|
/// primitiveInfo->type = GFXLineStrip; // This primitive info describes a line strip
|
|
/// @endcode
|
|
/// The following code takes place in the destructor for the same class
|
|
/// @code
|
|
/// // Because this is a static buffer it's our responsibility to free it when we are done
|
|
/// GFX->freePrimitiveBuffer( mPB );
|
|
/// @endcode
|
|
/// This last bit takes place in the rendering function for the class
|
|
/// @code
|
|
/// // You need to set a vertex buffer as well, primitive buffers contain indexing
|
|
/// // information, not vertex information. This is so you could have, say, a static
|
|
/// // vertex buffer, and a dynamic primitive buffer.
|
|
///
|
|
/// // This sets the primitive buffer to the static buffer we allocated in the constructor
|
|
/// GFX->setPrimitiveBuffer( mPB );
|
|
///
|
|
/// // Draw the first primitive contained in the set primitive buffer, our primitive buffer
|
|
/// // has only one primitive, so we could also technically call GFX->drawPrimitives(); and
|
|
/// // get the same result.
|
|
/// GFX->drawPrimitive( 0 );
|
|
/// @endcode
|
|
/// If you need any more examples on how to use these buffers please see the rest of the engine.
|
|
/// @n
|
|
/// <b>Primitive Buffers</b>
|
|
/// @n
|
|
/// Primitive buffers wrap and extend the concept of index buffers. The purpose of a primitive
|
|
/// buffer is to let objects store all information they have to render their primitives in
|
|
/// a central place. Say that a shape is made up of triangle strips and triangle fans, it would
|
|
/// still have only one primitive buffer which contained primitive information for each strip
|
|
/// and fan. It could then draw itself with one call.
|
|
///
|
|
/// TO BE FINISHED LATER
|
|
class GFXDevice
|
|
{
|
|
private:
|
|
friend class GFXInit;
|
|
friend class GFXPrimitiveBufferHandle;
|
|
friend class GFXVertexBufferHandleBase;
|
|
friend class GFXTextureObject;
|
|
friend class GFXTexHandle;
|
|
friend class GFXVertexFormat;
|
|
friend class GFXResource;
|
|
friend class LightMatInstance; // For stencil interface
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Static GFX interface
|
|
//--------------------------------------------------------------------------
|
|
public:
|
|
|
|
enum GFXDeviceEventType
|
|
{
|
|
/// The device has been created, but not initialized
|
|
deCreate,
|
|
|
|
/// The device has been initialized
|
|
deInit,
|
|
|
|
/// The device is about to be destroyed.
|
|
deDestroy,
|
|
|
|
/// The device has started rendering a frame
|
|
deStartOfFrame,
|
|
|
|
/// The device is about to finish rendering a frame
|
|
deEndOfFrame,
|
|
|
|
/// The device has rendered a frame and ended the scene
|
|
dePostFrame,
|
|
|
|
/// The device has started rendering a frame's field (such as for side-by-side rendering)
|
|
deStartOfField,
|
|
|
|
/// left stereo frame has been rendered
|
|
deLeftStereoFrameRendered,
|
|
|
|
/// right stereo frame has been rendered
|
|
deRightStereoFrameRendered,
|
|
|
|
/// The device is about to finish rendering a frame's field
|
|
deEndOfField,
|
|
};
|
|
|
|
typedef Signal <bool (GFXDeviceEventType)> DeviceEventSignal;
|
|
static DeviceEventSignal& getDeviceEventSignal();
|
|
|
|
static GFXDevice *get() { return smGFXDevice; }
|
|
|
|
static void initConsole();
|
|
static bool destroy();
|
|
|
|
static bool devicePresent() { return (smGFXDevice && smGFXDevice->getAdapterType() != NullDevice); }
|
|
|
|
private:
|
|
/// @name Device management variables
|
|
/// @{
|
|
static GFXDevice * smGFXDevice; ///< Global GFXDevice
|
|
|
|
/// @}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Core GFX interface
|
|
//--------------------------------------------------------------------------
|
|
public:
|
|
enum GFXDeviceRenderStyles
|
|
{
|
|
RS_Standard = 0,
|
|
RS_StereoSideBySide = (1<<0), // Render into current Render Target side-by-side
|
|
RS_StereoSeparate = (1<<1) // Render in two separate passes (then combined by vr compositor)
|
|
};
|
|
|
|
enum GFXDeviceLimits
|
|
{
|
|
NumStereoPorts = 2
|
|
};
|
|
|
|
private:
|
|
|
|
/// Adapter for this device.
|
|
GFXAdapter mAdapter;
|
|
|
|
protected:
|
|
/// List of valid video modes for this device.
|
|
Vector<GFXVideoMode> mVideoModes;
|
|
|
|
/// The CardProfiler for this device.
|
|
GFXCardProfiler *mCardProfiler;
|
|
|
|
/// Head of the resource list.
|
|
///
|
|
/// @see GFXResource
|
|
GFXResource *mResourceListHead;
|
|
|
|
/// Set once the device is active.
|
|
bool mCanCurrentlyRender;
|
|
|
|
/// Set if we're in a mode where we want rendering to occur.
|
|
bool mAllowRender;
|
|
|
|
/// The style of rendering that is to be performed, based on GFXDeviceRenderStyles
|
|
U32 mCurrentRenderStyle;
|
|
|
|
/// Current stereo target being rendered to
|
|
S32 mCurrentStereoTarget;
|
|
|
|
/// Eye offset used when using a stereo rendering style
|
|
Point3F mStereoEyeOffset[NumStereoPorts];
|
|
|
|
/// Center matrix for head
|
|
MatrixF mStereoHeadTransform;
|
|
|
|
/// Left and right matrix for eyes
|
|
MatrixF mStereoEyeTransforms[NumStereoPorts];
|
|
|
|
/// Inverse of mStereoEyeTransforms
|
|
MatrixF mInverseStereoEyeTransforms[NumStereoPorts];
|
|
|
|
/// Fov port settings
|
|
FovPort mFovPorts[NumStereoPorts];
|
|
|
|
/// Destination viewports for stereo rendering
|
|
RectI mStereoViewports[NumStereoPorts];
|
|
|
|
/// Destination targets for stereo rendering
|
|
GFXTextureTarget* mStereoTargets[NumStereoPorts];
|
|
|
|
/// This will allow querying to see if a device is initialized and ready to
|
|
/// have operations performed on it.
|
|
bool mInitialized;
|
|
bool mReset;
|
|
|
|
/// This is called before this, or any other device, is deleted in the global destroy()
|
|
/// method. It allows the device to clean up anything while everything is still valid.
|
|
virtual void preDestroy();
|
|
|
|
/// Set the adapter that this device is using. For use by GFXInit::createDevice only.
|
|
virtual void setAdapter(const GFXAdapter& adapter) { mAdapter = adapter; }
|
|
|
|
/// Notify GFXDevice that we are initialized
|
|
virtual void deviceInited();
|
|
public:
|
|
GFXDevice();
|
|
virtual ~GFXDevice();
|
|
|
|
/// Initialize this GFXDevice, optionally specifying a platform window to
|
|
/// bind to.
|
|
virtual void init( const GFXVideoMode &mode, PlatformWindow *window = NULL ) = 0;
|
|
|
|
/// Returns true if the scene has begun and its
|
|
/// safe to make rendering calls.
|
|
/// @see beginScene
|
|
/// @see endScene
|
|
bool canCurrentlyRender() const { return mCanCurrentlyRender; }
|
|
|
|
bool recentlyReset(){ return mReset; }
|
|
void beginReset(){ mReset = true; }
|
|
void finalizeReset(){ mReset = false; }
|
|
|
|
void setAllowRender( bool render ) { mAllowRender = render; }
|
|
|
|
inline bool allowRender() const { return mAllowRender; }
|
|
|
|
/// Retrieve the current rendering style based on GFXDeviceRenderStyles
|
|
U32 getCurrentRenderStyle() const { return mCurrentRenderStyle; }
|
|
|
|
/// Retrieve the current stereo target being rendered to
|
|
S32 getCurrentStereoTarget() const { return mCurrentStereoTarget; }
|
|
|
|
/// Set the current rendering style, based on GFXDeviceRenderStyles
|
|
void setCurrentRenderStyle(U32 style) { mCurrentRenderStyle = style; }
|
|
|
|
/// Set the current stereo target being rendered to (in case we're doing anything with postfx)
|
|
void setCurrentStereoTarget(const F32 targetId) { mCurrentStereoTarget = targetId; }
|
|
|
|
/// Get the current eye offset used during stereo rendering
|
|
const Point3F* getStereoEyeOffsets() { return mStereoEyeOffset; }
|
|
|
|
const MatrixF& getStereoHeadTransform() { return mStereoHeadTransform; }
|
|
const MatrixF* getStereoEyeTransforms() { return mStereoEyeTransforms; }
|
|
const MatrixF* getInverseStereoEyeTransforms() { return mInverseStereoEyeTransforms; }
|
|
|
|
/// Sets the head matrix for stereo rendering
|
|
void setStereoHeadTransform(const MatrixF &mat) { mStereoHeadTransform = mat; }
|
|
|
|
/// Set the current eye offset used during stereo rendering
|
|
void setStereoEyeOffsets(Point3F *offsets) { dMemcpy(mStereoEyeOffset, offsets, sizeof(Point3F) * NumStereoPorts); }
|
|
|
|
void setStereoEyeTransforms(MatrixF *transforms) { dMemcpy(mStereoEyeTransforms, transforms, sizeof(mStereoEyeTransforms)); dMemcpy(mInverseStereoEyeTransforms, transforms, sizeof(mInverseStereoEyeTransforms)); mInverseStereoEyeTransforms[0].inverse(); mInverseStereoEyeTransforms[1].inverse(); }
|
|
|
|
/// Set the current eye offset used during stereo rendering. Assumes NumStereoPorts are available.
|
|
void setStereoFovPort(const FovPort *ports) { dMemcpy(mFovPorts, ports, sizeof(mFovPorts)); }
|
|
|
|
/// Get the current eye offset used during stereo rendering
|
|
const FovPort* getStereoFovPort() { return mFovPorts; }
|
|
|
|
/// Sets stereo viewports
|
|
void setSteroViewports(const RectI *ports) { dMemcpy(mStereoViewports, ports, sizeof(RectI) * NumStereoPorts); }
|
|
|
|
/// Sets stereo render targets
|
|
void setStereoTargets(GFXTextureTarget **targets) { mStereoTargets[0] = targets[0]; mStereoTargets[1] = targets[1]; }
|
|
|
|
RectI* getStereoViewports() { return mStereoViewports; }
|
|
|
|
/// Activates a stereo render target, setting the correct viewport to render eye contents.
|
|
/// If eyeId is -1, set a viewport encompassing the entire size of the render targets.
|
|
void activateStereoTarget(S32 eyeId)
|
|
{
|
|
if (eyeId == -1)
|
|
{
|
|
if (mStereoTargets[0])
|
|
{
|
|
setActiveRenderTarget(mStereoTargets[0], true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (mStereoTargets[eyeId])
|
|
{
|
|
setActiveRenderTarget(mStereoTargets[eyeId], false);
|
|
}
|
|
setViewport(mStereoViewports[eyeId]);
|
|
}
|
|
|
|
mCurrentStereoTarget = eyeId;
|
|
}
|
|
|
|
GFXCardProfiler* getCardProfiler() const { return mCardProfiler; }
|
|
|
|
/// Returns active graphics adapter type.
|
|
virtual GFXAdapterType getAdapterType()=0;
|
|
|
|
/// Returns the Adapter that was used to create this device
|
|
virtual const GFXAdapter& getAdapter() { return mAdapter; }
|
|
|
|
/// @}
|
|
|
|
/// @name Debug Methods
|
|
/// @{
|
|
|
|
virtual void enterDebugEvent(ColorI color, const char *name) = 0;
|
|
virtual void leaveDebugEvent() = 0;
|
|
virtual void setDebugMarker(ColorI color, const char *name) = 0;
|
|
virtual const char* interpretDebugResult(long result) { return "Not Implemented"; };
|
|
/// @}
|
|
|
|
/// @name Resource debug methods
|
|
/// @{
|
|
|
|
/// Lists how many of each GFX resource (e.g. textures, texture targets, shaders, etc.) GFX is aware of
|
|
/// @param unflaggedOnly If true, this method only counts unflagged resources
|
|
virtual void listResources(bool unflaggedOnly);
|
|
|
|
/// Flags all resources GFX is currently aware of
|
|
virtual void flagCurrentResources();
|
|
|
|
/// Clears the flag on all resources GFX is currently aware of
|
|
virtual void clearResourceFlags();
|
|
|
|
/// Dumps a description of the specified resource types to the console
|
|
/// @param resNames A string of space separated class names (e.g. "GFXTextureObject GFXTextureTarget GFXShader")
|
|
/// to describe to the console
|
|
/// @param file A path to the file to write the descriptions to. If it is NULL or "", descriptions are
|
|
/// written to the console.
|
|
/// @param unflaggedOnly If true, this method only counts unflagged resources
|
|
/// @note resNames is case sensitive because there is no dStristr function.
|
|
virtual void describeResources(const char* resName, const char* file, bool unflaggedOnly);
|
|
|
|
/// Returns the current GFXDeviceStatistics, stats are cleared every ::beginScene call.
|
|
GFXDeviceStatistics* getDeviceStatistics() { return &mDeviceStatistics; }
|
|
protected:
|
|
GFXDeviceStatistics mDeviceStatistics;
|
|
|
|
/// This is a helper method for describeResourcesToFile. It walks through the
|
|
/// GFXResource list and sorts it by item type, putting the resources into the proper vector.
|
|
/// @see describeResources
|
|
virtual void fillResourceVectors(const char* resNames, bool unflaggedOnly, Vector<GFXResource*> &textureObjects,
|
|
Vector<GFXResource*> &textureTargets, Vector<GFXResource*> &windowTargets, Vector<GFXResource*> &vertexBuffers,
|
|
Vector<GFXResource*> &primitiveBuffers, Vector<GFXResource*> &fences, Vector<GFXResource*> &cubemaps,
|
|
Vector<GFXResource*> &shaders, Vector<GFXResource*> &stateblocks);
|
|
public:
|
|
|
|
/// @}
|
|
|
|
/// @name Video Mode Functions
|
|
/// @{
|
|
/// Enumerates the supported video modes of the device
|
|
virtual void enumerateVideoModes() = 0;
|
|
|
|
/// Returns the video mode list.
|
|
/// @see GFXVideoMode
|
|
const Vector<GFXVideoMode>* const getVideoModeList() const { return &mVideoModes; }
|
|
|
|
/// Returns the first format from the list which meets all
|
|
/// the criteria of the texture profile and query options.
|
|
virtual GFXFormat selectSupportedFormat(GFXTextureProfile *profile,
|
|
const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter) = 0;
|
|
|
|
/// @}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
protected:
|
|
|
|
/// @name State tracking variables
|
|
/// @{
|
|
|
|
/// Set if ANY state is dirty, including matrices or primitive buffers.
|
|
bool mStateDirty;
|
|
|
|
enum TexDirtyType
|
|
{
|
|
GFXTDT_Normal,
|
|
GFXTDT_Cube,
|
|
GFXTDT_CubeArray,
|
|
GFXTDT_TextureArray
|
|
};
|
|
|
|
GFXTexHandle mCurrentTexture[GFX_TEXTURE_STAGE_COUNT];
|
|
GFXTexHandle mNewTexture[GFX_TEXTURE_STAGE_COUNT];
|
|
GFXCubemapHandle mCurrentCubemap[GFX_TEXTURE_STAGE_COUNT];
|
|
GFXCubemapHandle mNewCubemap[GFX_TEXTURE_STAGE_COUNT];
|
|
GFXCubemapArrayHandle mCurrentCubemapArray[GFX_TEXTURE_STAGE_COUNT];
|
|
GFXCubemapArrayHandle mNewCubemapArray[GFX_TEXTURE_STAGE_COUNT];
|
|
GFXTextureArrayHandle mCurrentTextureArray[GFX_TEXTURE_STAGE_COUNT];
|
|
GFXTextureArrayHandle mNewTextureArray[GFX_TEXTURE_STAGE_COUNT];
|
|
|
|
TexDirtyType mTexType[GFX_TEXTURE_STAGE_COUNT];
|
|
bool mTextureDirty[GFX_TEXTURE_STAGE_COUNT];
|
|
bool mTexturesDirty;
|
|
|
|
// This maps a GFXStateBlockDesc hash value to a GFXStateBlockRef
|
|
typedef Map<U32, GFXStateBlockRef> StateBlockMap;
|
|
StateBlockMap mCurrentStateBlocks;
|
|
|
|
// This tracks whether or not our state block is dirty.
|
|
bool mStateBlockDirty;
|
|
GFXStateBlockRef mCurrentStateBlock;
|
|
GFXStateBlockRef mNewStateBlock;
|
|
|
|
GFXShaderConstBuffer *mCurrentShaderConstBuffer;
|
|
|
|
/// A global forced wireframe mode.
|
|
static bool smWireframe;
|
|
|
|
/// The global vsync state.
|
|
static bool smDisableVSync;
|
|
|
|
/// The forced shader model version if non-zero.
|
|
static F32 smForcedPixVersion;
|
|
|
|
/// Disable all hardware occlusion queries causing
|
|
/// them to return only the visibile state.
|
|
static bool smDisableOcclusionQuery;
|
|
|
|
/// @}
|
|
|
|
/// @see getDeviceSwizzle32
|
|
Swizzle<U8, 4> *mDeviceSwizzle32;
|
|
|
|
/// @see getDeviceSwizzle24
|
|
Swizzle<U8, 3> *mDeviceSwizzle24;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// @name Matrix managing variables
|
|
/// @{
|
|
|
|
///
|
|
MatrixF mWorldMatrix[GFX_WORLD_STACK_MAX];
|
|
|
|
S32 mWorldStackSize;
|
|
|
|
MatrixF mProjectionMatrix;
|
|
|
|
MatrixF mViewMatrix;
|
|
|
|
/// @}
|
|
|
|
/// @name Current frustum planes
|
|
/// @{
|
|
|
|
///
|
|
Frustum mFrustum;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// @name Stateblock functions
|
|
/// @{
|
|
|
|
/// Called by GFXDevice to create a device specific stateblock
|
|
virtual GFXStateBlockRef createStateBlockInternal(const GFXStateBlockDesc& desc) = 0;
|
|
/// Called by GFXDevice to actually set a stateblock.
|
|
/// @param force If true, set all states
|
|
virtual void setStateBlockInternal(GFXStateBlock* block, bool force) = 0;
|
|
/// @}
|
|
|
|
/// Called by base GFXDevice to actually set a const buffer
|
|
virtual void setShaderConstBufferInternal(GFXShaderConstBuffer* buffer) = 0;
|
|
|
|
virtual void setTextureInternal(U32 textureUnit, const GFXTextureObject*texture) = 0;
|
|
|
|
virtual bool beginSceneInternal() = 0;
|
|
virtual void endSceneInternal() = 0;
|
|
|
|
/// @name State Initialization.
|
|
/// @{
|
|
|
|
/// State initialization. This MUST BE CALLED in setVideoMode after the device
|
|
/// is created.
|
|
virtual void initStates() = 0;
|
|
/// @}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
protected:
|
|
|
|
|
|
/// @name Buffer Allocation
|
|
/// These methods are implemented per-device and are called by the GFX layer
|
|
/// when a user calls an alloc
|
|
///
|
|
/// @note Primitive Buffers are NOT implemented per device, they wrap index buffers
|
|
/// @{
|
|
|
|
/// This allocates a vertex buffer and returns a pointer to the allocated buffer.
|
|
/// This function should not be called directly - rather it should be used by
|
|
/// the GFXVertexBufferHandle class.
|
|
virtual GFXVertexBuffer *allocVertexBuffer( U32 numVerts,
|
|
const GFXVertexFormat *vertexFormat,
|
|
U32 vertSize,
|
|
GFXBufferType bufferType,
|
|
void* data = NULL ) = 0;
|
|
|
|
/// Called from GFXVertexFormat to allocate the hardware
|
|
/// specific vertex declaration for rendering.
|
|
virtual GFXVertexDecl* allocVertexDecl( const GFXVertexFormat *vertexFormat ) = 0;
|
|
|
|
/// Sets the current vertex declaration on the device.
|
|
virtual void setVertexDecl( const GFXVertexDecl *decl ) = 0;
|
|
|
|
/// Sets the vertex buffer on the device.
|
|
virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer ) = 0;
|
|
|
|
/// Set the vertex stream frequency on the device.
|
|
virtual void setVertexStreamFrequency( U32 stream, U32 frequency ) = 0;
|
|
|
|
/// The maximum number of supported vertex streams which
|
|
/// may be more than the device supports.
|
|
static const U32 VERTEX_STREAM_COUNT = 4;
|
|
|
|
StrongRefPtr<GFXVertexBuffer> mCurrentVertexBuffer[VERTEX_STREAM_COUNT];
|
|
bool mVertexBufferDirty[VERTEX_STREAM_COUNT];
|
|
U32 mVertexBufferFrequency[VERTEX_STREAM_COUNT];
|
|
bool mVertexBufferFrequencyDirty[VERTEX_STREAM_COUNT];
|
|
|
|
const GFXVertexDecl *mCurrVertexDecl;
|
|
bool mVertexDeclDirty;
|
|
|
|
StrongRefPtr<GFXPrimitiveBuffer> mCurrentPrimitiveBuffer;
|
|
bool mPrimitiveBufferDirty;
|
|
|
|
/// This allocates a primitive buffer and returns a pointer to the allocated buffer.
|
|
/// A primitive buffer's type argument refers to the index data - the primitive data will
|
|
/// always be preserved from call to call.
|
|
///
|
|
/// @note All index buffers use unsigned 16-bit indices.
|
|
virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices,
|
|
U32 numPrimitives,
|
|
GFXBufferType bufferType,
|
|
void* data = NULL ) = 0;
|
|
|
|
/// @}
|
|
|
|
protected:
|
|
|
|
//---------------------------------------
|
|
// Render target related
|
|
//---------------------------------------
|
|
|
|
/// A stack of previously active render targets.
|
|
Vector<GFXTargetRef> mRTStack;
|
|
|
|
/// The current render target which may or may not
|
|
/// not be yet activated.
|
|
/// @see mRTDirty
|
|
GFXTargetRef mCurrentRT;
|
|
|
|
/// This tracks a previously activated render target
|
|
/// which need to be deactivated.
|
|
GFXTargetRef mRTDeactivate;
|
|
|
|
/// This is set when the current and/or deactivate render
|
|
/// targets have changed and the device need to update
|
|
/// its state on the next draw/clear.
|
|
bool mRTDirty;
|
|
|
|
/// Updates the render targets and viewport in a device
|
|
/// specific manner when they are dirty.
|
|
virtual void _updateRenderTargets() = 0;
|
|
|
|
/// The current viewport rect.
|
|
RectI mViewport;
|
|
|
|
/// If true the viewport has been changed and
|
|
/// it must be updated on the next draw/clear.
|
|
bool mViewportDirty;
|
|
|
|
public:
|
|
|
|
/// @name Texture functions
|
|
/// @{
|
|
protected:
|
|
GFXTextureManager * mTextureManager;
|
|
|
|
public:
|
|
virtual GFXCubemap * createCubemap() = 0;
|
|
virtual GFXCubemapArray *createCubemapArray() = 0;
|
|
virtual GFXTextureArray *createTextureArray() = 0;
|
|
|
|
inline GFXTextureManager *getTextureManager()
|
|
{
|
|
return mTextureManager;
|
|
}
|
|
|
|
///@}
|
|
|
|
/// Swizzle to convert 32bpp bitmaps from RGBA to the native device format.
|
|
const Swizzle<U8, 4> *getDeviceSwizzle32() const
|
|
{
|
|
return mDeviceSwizzle32;
|
|
}
|
|
|
|
/// Swizzle to convert 24bpp bitmaps from RGB to the native device format.
|
|
const Swizzle<U8, 3> *getDeviceSwizzle24() const
|
|
{
|
|
return mDeviceSwizzle24;
|
|
}
|
|
|
|
/// @name Render Target functions
|
|
/// @{
|
|
|
|
/// Allocate a target for doing render to texture operations, with no
|
|
/// depth/stencil buffer.
|
|
virtual GFXTextureTarget *allocRenderToTextureTarget(bool genMips = true) = 0;
|
|
|
|
/// Allocate a target for a given window.
|
|
virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window)=0;
|
|
|
|
/// Store the current render target to restore later.
|
|
void pushActiveRenderTarget();
|
|
|
|
/// Restore the previous render target.
|
|
void popActiveRenderTarget();
|
|
|
|
/// Assign a new active render target.
|
|
void setActiveRenderTarget( GFXTarget *target, bool updateViewport=true );
|
|
|
|
/// Returns the current active render target.
|
|
inline GFXTarget* getActiveRenderTarget() { return mCurrentRT; }
|
|
|
|
///@}
|
|
|
|
/// @name Shader functions
|
|
/// @{
|
|
virtual F32 getPixelShaderVersion() const = 0;
|
|
virtual void setPixelShaderVersion( F32 version ) = 0;
|
|
|
|
/// Returns the number of texture samplers that can be used in a shader rendering pass
|
|
virtual U32 getNumSamplers() const = 0;
|
|
|
|
/// Returns the number of simultaneous render targets supported by the device.
|
|
virtual U32 getNumRenderTargets() const = 0;
|
|
|
|
virtual void setShader( GFXShader *shader, bool force = false ) {}
|
|
|
|
/// Set the buffer! (Actual set happens on the next draw call, just like textures, state blocks, etc)
|
|
void setShaderConstBuffer(GFXShaderConstBuffer* buffer);
|
|
|
|
/// Creates a new empty shader which must be initialized
|
|
/// and deleted by the caller.
|
|
/// @see GFXShader::init
|
|
virtual GFXShader* createShader() = 0;
|
|
|
|
/// @}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// @name Copying methods
|
|
/// @{
|
|
|
|
virtual void copyResource(GFXTextureObject *pDst, GFXCubemap *pSrc, const U32 face) = 0;
|
|
|
|
/// @}
|
|
|
|
/// @name Rendering methods
|
|
/// @{
|
|
|
|
///
|
|
virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil ) = 0;
|
|
virtual void clearColorAttachment(const U32 attachment, const LinearColorF& color) = 0;
|
|
virtual bool beginScene();
|
|
virtual void endScene();
|
|
virtual void beginField();
|
|
virtual void endField();
|
|
PlatformTimer *mFrameTime;
|
|
|
|
void setPrimitiveBuffer( GFXPrimitiveBuffer *buffer );
|
|
|
|
/// Sets the vertex buffer.
|
|
///
|
|
/// When setting the stream 0 vertex buffer it will automatically
|
|
/// set its associated vertex format as the active format.
|
|
///
|
|
/// @param buffer The vertex buffer or NULL to clear the buffer.
|
|
/// @param stream The stream index of the vertex source stream to place the buffer.
|
|
/// @param frequency The stream frequency of the vertex buffer.
|
|
void setVertexBuffer( GFXVertexBuffer *buffer, U32 stream = 0, U32 frequency = 0 );
|
|
|
|
/// Sets the current vertex format.
|
|
///
|
|
/// This should only be used if the vertex format of the stream 0 vertex
|
|
/// buffer is different from the one associated to it. Typically this
|
|
/// is used when rendering from multiple vertex streams.
|
|
///
|
|
void setVertexFormat( const GFXVertexFormat *vertexFormat );
|
|
|
|
virtual void drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount ) = 0;
|
|
|
|
/// The parameters to drawIndexedPrimitive are somewhat complicated. From a raw-data stand point
|
|
/// they evaluate to something like the following:
|
|
/// @code
|
|
/// U16 indicies[] = { 0, 1, 2, 1, 0, 0, 2 };
|
|
/// Point3F verts[] = { Point3F( 0.0f, 0.0f, 0.0f ), Point3F( 0.0f, 1.0f, 0.0f ), Point3F( 0.0f, 0.0f, 1.0f ) };
|
|
///
|
|
/// GFX->drawIndexedPrimitive( GFXLineList, // Drawing a list of lines, each line is two verts
|
|
/// 0, // vertex 0 will be referenced so minIndex = 0
|
|
/// 3, // 3 verticies will be used for this draw call
|
|
/// 1, // We want index 1 to be the first index used, so indicies 1-6 will be used
|
|
/// 3 // Drawing 3 LineList primitives, meaning 6 verts will be drawn
|
|
/// );
|
|
///
|
|
/// U16 *idxPtr = &indicies[1]; // 1 = startIndex, so the pointer is offset such that:
|
|
/// // idxPtr[0] is the same as indicies[1]
|
|
///
|
|
/// U32 numVertsToDrawFromBuffer = primitiveCount * 2; // 2 verts define a line in the GFXLineList primitive type (6)
|
|
/// @endcode
|
|
///
|
|
/// @param primType Type of primitive to draw
|
|
///
|
|
/// @param startVertex This defines index zero. Its the offset from the start of
|
|
/// the vertex buffer to the first vertex.
|
|
///
|
|
/// @param minIndex The smallest index into the vertex stream which will be used for this draw call.
|
|
/// This is a zero based index relative to startVertex. It is strictly a performance
|
|
/// hint for implementations. No vertex below minIndex will be referenced by this draw
|
|
/// call. For device implementors, this should _not_ be used to offset the vertex buffer,
|
|
/// or index buffer.
|
|
///
|
|
/// @param numVerts The number of verticies which will be referenced in this draw call. This is not
|
|
/// the number of verticies which will be drawn. That is a function of 'primType' and
|
|
/// 'primitiveCount'.
|
|
///
|
|
/// @param startIndex An offset from the start of the index buffer to specify where to start. If
|
|
/// 'idxBuffer' is a pointer to an array of integers, this could be written as
|
|
/// int *offsetIdx = idxBuffer + startIndex;
|
|
///
|
|
/// @param primitiveCount The number of primitives of type 'primType' to draw.
|
|
///
|
|
virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
|
|
U32 startVertex,
|
|
U32 minIndex,
|
|
U32 numVerts,
|
|
U32 startIndex,
|
|
U32 primitiveCount ) = 0;
|
|
|
|
void drawPrimitive( const GFXPrimitive &prim );
|
|
void drawPrimitive( U32 primitiveIndex );
|
|
void drawPrimitives();
|
|
/// @}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// Allocate a fence. The API specific implementation of GFXDevice is responsible
|
|
/// to make sure that the proper type is used. GFXGeneralFence should work in
|
|
/// all cases.
|
|
virtual GFXFence *createFence() = 0;
|
|
|
|
/// Returns a hardware occlusion query object or NULL
|
|
/// if this device does not support them.
|
|
virtual GFXOcclusionQuery* createOcclusionQuery() { return NULL; }
|
|
|
|
/// @name Texture State Settings
|
|
/// NONE of these should be overridden by API implementations
|
|
/// because of the state caching stuff.
|
|
/// @{
|
|
|
|
///
|
|
void setTexture(U32 stage, GFXTextureObject *texture);
|
|
void setCubeTexture( U32 stage, GFXCubemap *cubemap );
|
|
void setCubeArrayTexture( U32 stage, GFXCubemapArray *cubemapArray);
|
|
void setTextureArray( U32 stage, GFXTextureArray *textureArray);
|
|
inline GFXTextureObject* getCurrentTexture( U32 stage ) { return mCurrentTexture[stage]; }
|
|
|
|
/// @}
|
|
|
|
/// @name State Block Interface
|
|
/// @{
|
|
|
|
/// Creates a state block object based on the desc passed in. This object
|
|
/// represents an immutable state.
|
|
virtual GFXStateBlockRef createStateBlock( const GFXStateBlockDesc &desc );
|
|
|
|
/// Sets the current stateblock (actually activated in ::updateStates)
|
|
virtual void setStateBlock( GFXStateBlock *block );
|
|
|
|
GFXStateBlock* getStateBlock() { return mNewStateBlock; }
|
|
|
|
/// This sets a stateblock directly from the description
|
|
/// structure. Its acceptable to use this for debug rendering
|
|
/// and other low frequency rendering tasks.
|
|
virtual void setStateBlockByDesc( const GFXStateBlockDesc &desc );
|
|
|
|
/// @}
|
|
|
|
/// @name General state interface
|
|
/// @{
|
|
/// Sets the dirty Render/Texture/Sampler states from the caching system
|
|
void updateStates(bool forceSetAll = false);
|
|
void clearTextureStateImmediate(U32 stage);
|
|
|
|
/// Returns the forced global wireframe state.
|
|
static bool getWireframe() { return smWireframe; }
|
|
|
|
/// Returns true if the occlusion query is disabled.
|
|
static bool getDisableOcclusionQuery() { return smDisableOcclusionQuery; }
|
|
/// @}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// @name Matrix interface
|
|
/// @{
|
|
|
|
/// Sets the top of the world matrix stack
|
|
/// @param newWorld New world matrix to set
|
|
void setWorldMatrix( const MatrixF &newWorld );
|
|
|
|
/// Gets the matrix on the top of the world matrix stack
|
|
inline const MatrixF &getWorldMatrix() const { return mWorldMatrix[mWorldStackSize]; }
|
|
|
|
/// Pushes the world matrix stack and copies the current top
|
|
/// matrix to the new top of the stack
|
|
void pushWorldMatrix();
|
|
|
|
/// Pops the world matrix stack
|
|
void popWorldMatrix();
|
|
|
|
/// Sets the projection matrix
|
|
/// @param newProj New projection matrix to set
|
|
void setProjectionMatrix( const MatrixF &newProj );
|
|
|
|
/// Gets the projection matrix
|
|
inline const MatrixF &getProjectionMatrix() const { return mProjectionMatrix; }
|
|
|
|
/// Sets the view matrix
|
|
/// @param newView New view matrix to set
|
|
void setViewMatrix( const MatrixF &newView );
|
|
|
|
/// Gets the view matrix
|
|
inline const MatrixF &getViewMatrix() const { return mViewMatrix; }
|
|
|
|
/// Multiplies the matrix at the top of the world matrix stack by a matrix
|
|
/// and replaces the top of the matrix stack with the result
|
|
/// @param mat Matrix to multiply
|
|
void multWorld( const MatrixF &mat );
|
|
|
|
/// Set texture matrix for a sampler
|
|
void setTextureMatrix( const U32 stage, const MatrixF &texMat );
|
|
|
|
/// Set an area of the target to render to.
|
|
void setViewport( const RectI &rect );
|
|
|
|
/// Get the current area of the target we will render to.
|
|
const RectI &getViewport() const { return mViewport; }
|
|
|
|
virtual void setClipRect( const RectI &rect ) = 0;
|
|
virtual const RectI &getClipRect() const = 0;
|
|
|
|
/// Set the projection frustum.
|
|
///
|
|
/// @see MathUtils::makeFrustum()
|
|
virtual void setFrustum( F32 left, F32 right,
|
|
F32 bottom, F32 top,
|
|
F32 nearPlane, F32 farPlane,
|
|
bool bRotate = true);
|
|
|
|
///
|
|
virtual void setFrustum( const Frustum& frust,
|
|
bool bRotate = true );
|
|
|
|
/// Get the projection frustum.
|
|
void getFrustum( F32 *left,
|
|
F32 *right,
|
|
F32 *bottom,
|
|
F32 *top,
|
|
F32 *nearPlane,
|
|
F32 *farPlane,
|
|
bool *isOrtho ) const;
|
|
|
|
/// Get the projection frustum.
|
|
const Frustum& getFrustum() const { return mFrustum; }
|
|
|
|
/// This will construct and apply an orthographic projection matrix with the provided parameters
|
|
/// @param doRotate If set to true, the resulting matrix will be rotated PI/2 around the X axis
|
|
// for support in tsShapeInstance. You probably want to leave this as 'false'.
|
|
void setOrtho(F32 left, F32 right, F32 bottom, F32 top, F32 nearPlane, F32 farPlane, bool doRotate = false);
|
|
|
|
/// Return true if the current frustum uses orthographic projection rather than perspective projection.
|
|
bool isFrustumOrtho() const { return mFrustum.isOrtho(); }
|
|
|
|
/// @}
|
|
|
|
/// Returns the scale for converting world space
|
|
/// units to screen space units... aka pixels.
|
|
///
|
|
/// This is the true scale which is best used for GUI
|
|
/// drawing. For doing lod calculations you should be
|
|
/// using the functions in SceneState which is adjusted
|
|
/// for special cases like shadows and reflections.
|
|
///
|
|
/// @see SceneState::getWorldToScreenScale()
|
|
/// @see SceneState::projectRadius()
|
|
///
|
|
Point2F getWorldToScreenScale() const;
|
|
|
|
public:
|
|
enum GenericShaderType
|
|
{
|
|
GSColor = 0,
|
|
GSTexture,
|
|
GSModColorTexture,
|
|
GSAddColorTexture,
|
|
GSTargetRestore,
|
|
GS_COUNT
|
|
};
|
|
|
|
/// This is a helper function to set a default shader for rendering GUI elements
|
|
/// on systems which do not support fixed-function operations as well as for
|
|
/// things which need just generic position/texture/color shaders
|
|
///
|
|
/// @param type Type of generic shader, add your own if you need
|
|
virtual void setupGenericShaders( GenericShaderType type = GSColor ) {};
|
|
|
|
/// Get the fill convention for this device
|
|
virtual F32 getFillConventionOffset() const = 0;
|
|
|
|
virtual U32 getMaxDynamicVerts() = 0;
|
|
virtual U32 getMaxDynamicIndices() = 0;
|
|
|
|
virtual void doParanoidStateCheck(){};
|
|
|
|
/// Get access to this device's drawing utility class.
|
|
GFXDrawUtil *getDrawUtil();
|
|
|
|
#ifndef TORQUE_SHIPPING
|
|
/// This is a method designed for debugging. It will allow you to dump the states
|
|
/// in the render manager out to a file so that it can be diffed and examined.
|
|
void dumpStates( const char *fileName ) const;
|
|
#else
|
|
void dumpStates( const char *fileName ) const {};
|
|
#endif
|
|
protected:
|
|
GFXDrawUtil *mDrawer;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Matrix interface
|
|
|
|
inline void GFXDevice::setWorldMatrix( const MatrixF &newWorld )
|
|
{
|
|
mStateDirty = true;
|
|
mWorldMatrix[mWorldStackSize] = newWorld;
|
|
}
|
|
|
|
inline void GFXDevice::pushWorldMatrix()
|
|
{
|
|
mStateDirty = true;
|
|
mWorldStackSize++;
|
|
AssertFatal( mWorldStackSize < GFX_WORLD_STACK_MAX, "GFX: Exceeded world matrix stack size" );
|
|
mWorldMatrix[mWorldStackSize] = mWorldMatrix[mWorldStackSize - 1];
|
|
}
|
|
|
|
inline void GFXDevice::popWorldMatrix()
|
|
{
|
|
mStateDirty = true;
|
|
mWorldStackSize--;
|
|
AssertFatal( mWorldStackSize >= 0, "GFX: Negative WorldStackSize!" );
|
|
}
|
|
|
|
inline void GFXDevice::multWorld( const MatrixF &mat )
|
|
{
|
|
mStateDirty = true;
|
|
mWorldMatrix[mWorldStackSize].mul(mat);
|
|
}
|
|
|
|
inline void GFXDevice::setProjectionMatrix( const MatrixF &newProj )
|
|
{
|
|
mStateDirty = true;
|
|
mProjectionMatrix = newProj;
|
|
}
|
|
|
|
inline void GFXDevice::setViewMatrix( const MatrixF &newView )
|
|
{
|
|
mStateDirty = true;
|
|
mViewMatrix = newView;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Buffer management
|
|
|
|
inline void GFXDevice::setVertexBuffer( GFXVertexBuffer *buffer, U32 stream, U32 frequency )
|
|
{
|
|
AssertFatal( stream < VERTEX_STREAM_COUNT, "GFXDevice::setVertexBuffer - Bad stream index!" );
|
|
|
|
if ( buffer && stream == 0 )
|
|
setVertexFormat( &buffer->mVertexFormat );
|
|
|
|
if ( buffer != mCurrentVertexBuffer[stream] )
|
|
{
|
|
mCurrentVertexBuffer[stream] = buffer;
|
|
mVertexBufferDirty[stream] = true;
|
|
mStateDirty = true;
|
|
}
|
|
|
|
if ( mVertexBufferFrequency[stream] != frequency )
|
|
{
|
|
mVertexBufferFrequency[stream] = frequency;
|
|
mVertexBufferFrequencyDirty[stream] = true;
|
|
mStateDirty = true;
|
|
}
|
|
}
|
|
|
|
inline void GFXDevice::setVertexFormat( const GFXVertexFormat *vertexFormat )
|
|
{
|
|
if ( vertexFormat->getDecl() == mCurrVertexDecl )
|
|
return;
|
|
|
|
mCurrVertexDecl = vertexFormat->getDecl();
|
|
mVertexDeclDirty = true;
|
|
mStateDirty = true;
|
|
}
|
|
|
|
|
|
#if defined(TORQUE_DEBUG) && defined(TORQUE_DEBUG_GFX)
|
|
#define GFXAssertFatal(x, error) AssertFatal(x, error)
|
|
#else
|
|
#define GFXAssertFatal(x, error)
|
|
#endif
|
|
|
|
#endif // _GFXDEVICE_H_
|