Engine directory for ticket #1

This commit is contained in:
DavidWyand-GG 2012-09-19 11:15:01 -04:00
parent 352279af7a
commit 7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions

View file

@ -0,0 +1,287 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gfx/sim/cubemapData.h"
#include "core/stream/bitStream.h"
#include "console/consoleTypes.h"
#include "gfx/gfxCubemap.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxTransformSaver.h"
#include "gfx/gfxDebugEvent.h"
#include "scene/sceneManager.h"
#include "console/engineAPI.h"
#include "math/mathUtils.h"
IMPLEMENT_CONOBJECT( CubemapData );
CubemapData::CubemapData()
{
mCubemap = NULL;
mDynamic = false;
mDynamicSize = 512;
mDynamicNearDist = 0.1f;
mDynamicFarDist = 100.0f;
mDynamicObjectTypeMask = 0;
#ifdef INIT_HACK
mInit = false;
#endif
}
CubemapData::~CubemapData()
{
mCubemap = NULL;
}
ConsoleDocClass( CubemapData,
"@brief Used to create static or dynamic cubemaps.\n\n"
"This object is used with Material, WaterObject, and other objects for cubemap reflections.\n\n"
"A simple declaration of a static cubemap:\n"
"@tsexample\n"
"singleton CubemapData( SkyboxCubemap )\n"
"{\n"
" cubeFace[0] = \"./skybox_1\";\n"
" cubeFace[1] = \"./skybox_2\";\n"
" cubeFace[2] = \"./skybox_3\";\n"
" cubeFace[3] = \"./skybox_4\";\n"
" cubeFace[4] = \"./skybox_5\";\n"
" cubeFace[5] = \"./skybox_6\";\n"
"};\n"
"@endtsexample\n"
"@note The dynamic cubemap functionality in CubemapData has been depreciated in favor of ReflectorDesc.\n"
"@see ReflectorDesc\n"
"@ingroup GFX\n" );
void CubemapData::initPersistFields()
{
addField( "cubeFace", TypeStringFilename, Offset(mCubeFaceFile, CubemapData), 6,
"@brief The 6 cubemap face textures for a static cubemap.\n\n"
"They are in the following order:\n"
" - cubeFace[0] is -X\n"
" - cubeFace[1] is +X\n"
" - cubeFace[2] is -Z\n"
" - cubeFace[3] is +Z\n"
" - cubeFace[4] is -Y\n"
" - cubeFace[5] is +Y\n" );
addField("dynamic", TypeBool, Offset(mDynamic, CubemapData),
"Set to true if this is a dynamic cubemap. The default is false." );
addField("dynamicSize", TypeS32, Offset(mDynamicSize, CubemapData),
"The size of each dynamic cubemap face in pixels." );
addField("dynamicNearDist", TypeF32, Offset(mDynamicNearDist, CubemapData),
"The near clip distance used when rendering to the dynamic cubemap." );
addField("dynamicFarDist", TypeF32, Offset(mDynamicFarDist, CubemapData),
"The far clip distance used when rendering to the dynamic cubemap." );
addField("dynamicObjectTypeMask", TypeS32, Offset(mDynamicObjectTypeMask, CubemapData),
"The typemask used to filter the objects rendered to the dynamic cubemap." );
Parent::initPersistFields();
}
bool CubemapData::onAdd()
{
if( !Parent::onAdd() )
return false;
// Do NOT call this here as it forces every single cubemap defined to load its images, immediately, without mercy
// createMap();
return true;
}
void CubemapData::createMap()
{
if( !mCubemap )
{
if( mDynamic )
{
mCubemap = GFX->createCubemap();
mCubemap->initDynamic( mDynamicSize );
mDepthBuff = GFXTexHandle( mDynamicSize, mDynamicSize, GFXFormatD24S8,
&GFXDefaultZTargetProfile, avar("%s() - mDepthBuff (line %d)", __FUNCTION__, __LINE__));
mRenderTarget = GFX->allocRenderToTextureTarget();
}
else
{
bool initSuccess = true;
for( U32 i=0; i<6; i++ )
{
if( !mCubeFaceFile[i].isEmpty() )
{
if(!mCubeFace[i].set(mCubeFaceFile[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - mCubeFace[%d] (line %d)", __FUNCTION__, i, __LINE__) ))
{
Con::errorf("CubemapData::createMap - Failed to load texture '%s'", mCubeFaceFile[i].c_str());
initSuccess = false;
}
}
}
if( initSuccess )
{
mCubemap = GFX->createCubemap();
mCubemap->initStatic( mCubeFace );
}
}
}
}
void CubemapData::updateDynamic(SceneManager* sm, const Point3F& pos)
{
AssertFatal(mDynamic, "This is not a dynamic cubemap!");
GFXDEBUGEVENT_SCOPE( CubemapData_updateDynamic, ColorI::WHITE );
#ifdef INIT_HACK
if( mInit ) return;
mInit = true;
#endif
GFX->pushActiveRenderTarget();
mRenderTarget->attachTexture(GFXTextureTarget::DepthStencil, mDepthBuff );
// store current matrices
GFXTransformSaver saver;
F32 oldVisibleDist = sm->getVisibleDistance();
// set projection to 90 degrees vertical and horizontal
{
F32 left, right, top, bottom;
MathUtils::makeFrustum( &left, &right, &top, &bottom, M_HALFPI_F, 1.0f, mDynamicNearDist );
GFX->setFrustum( left, right, bottom, top, mDynamicNearDist, mDynamicFarDist );
}
sm->setVisibleDistance(mDynamicFarDist);
// We don't use a special clipping projection, but still need to initialize
// this for objects like SkyBox which will use it during a reflect pass.
gClientSceneGraph->setNonClipProjection( (MatrixF&) GFX->getProjectionMatrix() );
// Loop through the six faces of the cube map.
for(U32 i=0; i<6; i++)
{
// Standard view that will be overridden below.
VectorF vLookatPt(0.0f, 0.0f, 0.0f), vUpVec(0.0f, 0.0f, 0.0f), vRight(0.0f, 0.0f, 0.0f);
switch( i )
{
case 0 : // D3DCUBEMAP_FACE_POSITIVE_X:
vLookatPt = VectorF( 1.0f, 0.0f, 0.0f );
vUpVec = VectorF( 0.0f, 1.0f, 0.0f );
break;
case 1 : // D3DCUBEMAP_FACE_NEGATIVE_X:
vLookatPt = VectorF( -1.0f, 0.0f, 0.0f );
vUpVec = VectorF( 0.0f, 1.0f, 0.0f );
break;
case 2 : // D3DCUBEMAP_FACE_POSITIVE_Y:
vLookatPt = VectorF( 0.0f, 1.0f, 0.0f );
vUpVec = VectorF( 0.0f, 0.0f,-1.0f );
break;
case 3 : // D3DCUBEMAP_FACE_NEGATIVE_Y:
vLookatPt = VectorF( 0.0f, -1.0f, 0.0f );
vUpVec = VectorF( 0.0f, 0.0f, 1.0f );
break;
case 4 : // D3DCUBEMAP_FACE_POSITIVE_Z:
vLookatPt = VectorF( 0.0f, 0.0f, 1.0f );
vUpVec = VectorF( 0.0f, 1.0f, 0.0f );
break;
case 5: // D3DCUBEMAP_FACE_NEGATIVE_Z:
vLookatPt = VectorF( 0.0f, 0.0f, -1.0f );
vUpVec = VectorF( 0.0f, 1.0f, 0.0f );
break;
}
// create camera matrix
VectorF cross = mCross( vUpVec, vLookatPt );
cross.normalizeSafe();
MatrixF matView(true);
matView.setColumn( 0, cross );
matView.setColumn( 1, vLookatPt );
matView.setColumn( 2, vUpVec );
matView.setPosition( pos );
matView.inverse();
GFX->pushWorldMatrix();
GFX->setWorldMatrix(matView);
mRenderTarget->attachTexture( GFXTextureTarget::Color0, mCubemap, i );
GFX->setActiveRenderTarget( mRenderTarget );
GFX->clear( GFXClearStencil | GFXClearTarget | GFXClearZBuffer, ColorI( 64, 64, 64 ), 1.f, 0 );
// render scene
sm->renderScene( SPT_Reflect, mDynamicObjectTypeMask );
// Resolve render target for each face
mRenderTarget->resolve();
GFX->popWorldMatrix();
}
// restore render surface and depth buffer
GFX->popActiveRenderTarget();
mRenderTarget->attachTexture(GFXTextureTarget::Color0, NULL);
sm->setVisibleDistance(oldVisibleDist);
}
void CubemapData::updateFaces()
{
bool initSuccess = true;
for( U32 i=0; i<6; i++ )
{
if( !mCubeFaceFile[i].isEmpty() )
{
if(!mCubeFace[i].set(mCubeFaceFile[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - mCubeFace[%d] (line %d)", __FUNCTION__, i, __LINE__) ))
{
initSuccess = false;
Con::errorf("CubemapData::createMap - Failed to load texture '%s'", mCubeFaceFile[i].c_str());
}
}
}
if( initSuccess )
{
mCubemap = NULL;
mCubemap = GFX->createCubemap();
mCubemap->initStatic( mCubeFace );
}
}
DefineEngineMethod( CubemapData, updateFaces, void, (),,
"Update the assigned cubemaps faces." )
{
object->updateFaces();
}
DefineEngineMethod( CubemapData, getFilename, const char*, (),,
"Returns the script filename of where the CubemapData object was "
"defined. This is used by the material editor." )
{
return object->getFilename();
}

View file

@ -0,0 +1,87 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _CUBEMAPDATA_H_
#define _CUBEMAPDATA_H_
#ifndef _SIMOBJECT_H_
#include "console/simObject.h"
#endif
#ifndef _GFXCUBEMAP_H_
#include "gfx/gfxCubemap.h"
#endif
#ifndef _GFXTARGET_H_
#include "gfx/gfxTarget.h"
#endif
#ifndef _SCENEMANAGER_H_
#include "scene/sceneManager.h"
#endif
/// A script interface for creating static or dynamic cubemaps.
class CubemapData : public SimObject
{
typedef SimObject Parent;
public:
GFXCubemapHandle mCubemap;
CubemapData();
~CubemapData();
bool onAdd();
static void initPersistFields();
DECLARE_CONOBJECT(CubemapData);
// Force creation of cubemap
void createMap();
// Update a dynamic cubemap @ pos
void updateDynamic(SceneManager* sm, const Point3F& pos);
void updateFaces();
// Dynamic cube map support
bool mDynamic;
U32 mDynamicSize;
F32 mDynamicNearDist;
F32 mDynamicFarDist;
U32 mDynamicObjectTypeMask;
protected:
FileName mCubeFaceFile[6];
GFXTexHandle mCubeFace[6];
GFXTexHandle mDepthBuff;
GFXTextureTargetRef mRenderTarget;
#ifdef INIT_HACK
bool mInit;
#endif
};
#endif // CUBEMAPDATA

View file

@ -0,0 +1,433 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gfx/sim/debugDraw.h"
#include "gfx/gFont.h"
#include "gfx/gfxDrawUtil.h"
#include "gfx/gfxTransformSaver.h"
#include "gfx/gfxDebugEvent.h"
#include "math/mathUtils.h"
#include "math/util/frustum.h"
#include "console/console.h"
#include "scene/sceneManager.h"
#include "core/module.h"
#include "console/engineAPI.h"
#include "math/mPolyhedron.impl.h"
MODULE_BEGIN( DebugDrawer )
MODULE_INIT_AFTER( Sim )
MODULE_INIT_AFTER( GFX )
// DebugDrawer will register itself as a SimObject and
// thus get automatically shut down with Sim.
MODULE_INIT
{
DebugDrawer::init();
}
MODULE_END;
DebugDrawer* DebugDrawer::sgDebugDrawer = NULL;
IMPLEMENT_CONOBJECT(DebugDrawer);
ConsoleDocClass( DebugDrawer,
"@brief A debug helper for rendering debug primitives to the scene.\n\n"
"The DebugDrawer is used to render debug primitives to the scene for testing. It is "
"often useful when debugging collision code or complex 3d algorithms to have "
"them draw debug information, like culling hulls or bounding volumes, normals, "
"simple lines, and so forth.\n\n"
"A key feature of the DebugDrawer is that each primitive gets a \"time to live\" (TTL) "
"which allows them to continue to render to the scene for a fixed period of time. You "
"can freeze or resume the system at any time to allow you to examine the output.\n"
"@tsexample\n"
"DebugDraw.drawLine( %player.getMuzzlePoint( 0 ), %hitPoint );\n"
"DebugDraw.setLastTTL( 5000 ); // 5 seconds.\n"
"@endtsexample\n"
"The DebugDrawer renders solely in world space and all primitives are rendered with the "
"cull mode disabled.\n"
"@note This feature can easily be used to cheat in online games, so you should be sure "
"it is disabled in your shipping game. By default the DebugDrawer is disabled in all "
"TORQUE_SHIPPING builds.\n"
"@ingroup GFX\n" );
DebugDrawer::DebugDrawer()
{
mHead = NULL;
isFrozen = false;
shouldToggleFreeze = false;
#ifdef ENABLE_DEBUGDRAW
isDrawing = true;
#else
isDrawing = false;
#endif
}
DebugDrawer::~DebugDrawer()
{
if( sgDebugDrawer == this )
sgDebugDrawer = NULL;
}
DebugDrawer* DebugDrawer::get()
{
if (sgDebugDrawer)
{
return sgDebugDrawer;
} else {
DebugDrawer::init();
return sgDebugDrawer;
}
}
void DebugDrawer::init()
{
#ifdef ENABLE_DEBUGDRAW
sgDebugDrawer = new DebugDrawer();
sgDebugDrawer->registerObject("DebugDraw");
Sim::getRootGroup()->addObject( sgDebugDrawer );
Con::warnf( "DebugDrawer Enabled!" );
#endif
}
void DebugDrawer::setupStateBlocks()
{
GFXStateBlockDesc d;
d.setCullMode(GFXCullNone);
mRenderZOnSB = GFX->createStateBlock(d);
d.setZReadWrite(false);
mRenderZOffSB = GFX->createStateBlock(d);
}
void DebugDrawer::render()
{
#ifdef ENABLE_DEBUGDRAW
if(!isDrawing)
return;
GFXDEBUGEVENT_SCOPE( DebugDrawer, ColorI::GREEN );
if (!mRenderZOnSB)
{
setupStateBlocks();
String fontCacheDir = Con::getVariable("$GUI::fontCacheDirectory");
mFont = GFont::create("Arial", 12, fontCacheDir);
}
SimTime curTime = Sim::getCurrentTime();
GFX->disableShaders();
for(DebugPrim **walk = &mHead; *walk; )
{
DebugPrim *p = *walk;
// Set up the state block...
GFXStateBlockRef currSB;
if(p->useZ)
currSB = mRenderZOnSB;
else
currSB = mRenderZOffSB;
GFX->setStateBlock( currSB );
Point3F d;
switch(p->type)
{
case DebugPrim::Tri:
PrimBuild::begin( GFXLineStrip, 4);
PrimBuild::color(p->color);
PrimBuild::vertex3fv(p->a);
PrimBuild::vertex3fv(p->b);
PrimBuild::vertex3fv(p->c);
PrimBuild::vertex3fv(p->a);
PrimBuild::end();
break;
case DebugPrim::Box:
d = p->a - p->b;
GFX->getDrawUtil()->drawCube(currSB->getDesc(), d * 0.5, (p->a + p->b) * 0.5, p->color);
break;
case DebugPrim::Line:
PrimBuild::begin( GFXLineStrip, 2);
PrimBuild::color(p->color);
PrimBuild::vertex3fv(p->a);
PrimBuild::vertex3fv(p->b);
PrimBuild::end();
break;
case DebugPrim::Text:
{
GFXTransformSaver saver;
Point3F result;
if (MathUtils::mProjectWorldToScreen(p->a, &result, GFX->getViewport(), GFX->getWorldMatrix(), GFX->getProjectionMatrix()))
{
GFX->setClipRect(GFX->getViewport());
GFX->getDrawUtil()->setBitmapModulation(p->color);
GFX->getDrawUtil()->drawText(mFont, Point2I(result.x, result.y), p->mText);
}
}
break;
}
// Ok, we've got data, now freeze here if needed.
if (shouldToggleFreeze)
{
isFrozen = !isFrozen;
shouldToggleFreeze = false;
}
if(p->dieTime <= curTime && !isFrozen && p->dieTime != U32_MAX)
{
*walk = p->next;
mPrimChunker.free(p);
}
else
walk = &((*walk)->next);
}
#endif
}
void DebugDrawer::drawBox(const Point3F &a, const Point3F &b, const ColorF &color)
{
if(isFrozen || !isDrawing)
return;
DebugPrim *n = mPrimChunker.alloc();
n->useZ = true;
n->dieTime = 0;
n->a = a;
n->b = b;
n->color = color;
n->type = DebugPrim::Box;
n->next = mHead;
mHead = n;
}
void DebugDrawer::drawLine(const Point3F &a, const Point3F &b, const ColorF &color)
{
if(isFrozen || !isDrawing)
return;
DebugPrim *n = mPrimChunker.alloc();
n->useZ = true;
n->dieTime = 0;
n->a = a;
n->b = b;
n->color = color;
n->type = DebugPrim::Line;
n->next = mHead;
mHead = n;
}
void DebugDrawer::drawTri(const Point3F &a, const Point3F &b, const Point3F &c, const ColorF &color)
{
if(isFrozen || !isDrawing)
return;
DebugPrim *n = mPrimChunker.alloc();
n->useZ = true;
n->dieTime = 0;
n->a = a;
n->b = b;
n->c = c;
n->color = color;
n->type = DebugPrim::Tri;
n->next = mHead;
mHead = n;
}
void DebugDrawer::drawPolyhedron( const AnyPolyhedron& polyhedron, const ColorF& color )
{
const PolyhedronData::Edge* edges = polyhedron.getEdges();
const Point3F* points = polyhedron.getPoints();
const U32 numEdges = polyhedron.getNumEdges();
for( U32 i = 0; i < numEdges; ++ i )
{
const PolyhedronData::Edge& edge = edges[ i ];
drawLine( points[ edge.vertex[ 0 ] ], points[ edge.vertex[ 1 ] ], color );
}
}
void DebugDrawer::drawPolyhedronDebugInfo( const AnyPolyhedron& polyhedron, const MatrixF& transform, const Point3F& scale )
{
Point3F center = polyhedron.getCenterPoint();
center.convolve( scale );
transform.mulP( center );
// Render plane indices and normals.
const U32 numPlanes = polyhedron.getNumPlanes();
for( U32 i = 0; i < numPlanes; ++ i )
{
const AnyPolyhedron::PlaneType& plane = polyhedron.getPlanes()[ i ];
Point3F planePos = plane.getPosition();
planePos.convolve( scale );
transform.mulP( planePos );
Point3F normal = plane.getNormal();
transform.mulV( normal );
drawText( planePos, String::ToString( i ), ColorI::BLACK );
drawLine( planePos, planePos + normal, ColorI::GREEN );
}
// Render edge indices and direction indicators.
const U32 numEdges = polyhedron.getNumEdges();
for( U32 i = 0; i < numEdges; ++ i )
{
const AnyPolyhedron::EdgeType& edge = polyhedron.getEdges()[ i ];
Point3F v1 = polyhedron.getPoints()[ edge.vertex[ 0 ] ];
Point3F v2 = polyhedron.getPoints()[ edge.vertex[ 1 ] ];
v1.convolve( scale );
v2.convolve( scale );
transform.mulP( v1 );
transform.mulP( v2 );
const Point3F midPoint = v1 + ( v2 - v1 ) / 2.f;
drawText( midPoint, String::ToString( "%i (%i, %i)", i, edge.face[ 0 ], edge.face[ 1 ] ), ColorI::WHITE );
// Push out the midpoint away from the center to place the direction indicator.
Point3F pushDir = midPoint - center;
pushDir.normalize();
const Point3F dirPoint = midPoint + pushDir;
const Point3F lineDir = ( v2 - v1 ) / 2.f;
drawLine( dirPoint, dirPoint + lineDir, ColorI::RED );
}
// Render point indices and coordinates.
const U32 numPoints = polyhedron.getNumPoints();
for( U32 i = 0; i < numPoints; ++ i )
{
Point3F p = polyhedron.getPoints()[ i ];
p.convolve( scale );
transform.mulP( p );
drawText( p, String::ToString( "%i: (%.2f, %.2f, %.2f)", i, p.x, p.y, p.z ), ColorF::WHITE );
}
}
void DebugDrawer::drawText(const Point3F& pos, const String& text, const ColorF &color)
{
if(isFrozen || !isDrawing)
return;
DebugPrim *n = mPrimChunker.alloc();
n->useZ = false;
n->dieTime = 0;
n->a = pos;
n->color = color;
dStrncpy(n->mText, text.c_str(), 256);
n->type = DebugPrim::Text;
n->next = mHead;
mHead = n;
}
void DebugDrawer::setLastTTL(U32 ms)
{
AssertFatal(mHead, "Tried to set last with nothing in the list!");
if (ms != U32_MAX)
mHead->dieTime = Sim::getCurrentTime() + ms;
else
mHead->dieTime = U32_MAX;
}
void DebugDrawer::setLastZTest(bool enabled)
{
AssertFatal(mHead, "Tried to set last with nothing in the list!");
mHead->useZ = enabled;
}
DefineEngineMethod( DebugDrawer, drawLine, void, ( Point3F a, Point3F b, ColorF color ), ( ColorF::WHITE ),
"Draws a line primitive between two 3d points." )
{
object->drawLine( a, b, color );
}
DefineEngineMethod( DebugDrawer, drawBox, void, ( Point3F a, Point3F b, ColorF color ), ( ColorF::WHITE ),
"Draws an axis aligned box primitive within the two 3d points." )
{
object->drawBox( a, b, color );
}
DefineEngineMethod( DebugDrawer, setLastTTL, void, ( U32 ms ),,
"Sets the \"time to live\" (TTL) for the last rendered primitive." )
{
object->setLastTTL( ms );
}
DefineEngineMethod( DebugDrawer, setLastZTest, void, ( bool enabled ),,
"Sets the z buffer reading state for the last rendered primitive." )
{
object->setLastZTest( enabled );
}
DefineEngineMethod( DebugDrawer, toggleFreeze, void, (),,
"Toggles freeze mode which keeps the currently rendered primitives from expiring." )
{
object->toggleFreeze();
}
DefineEngineMethod( DebugDrawer, toggleDrawing, void, (),,
"Toggles the rendering of DebugDrawer primitives." )
{
object->toggleDrawing();
}

View file

@ -0,0 +1,197 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _DEBUGDRAW_H_
#define _DEBUGDRAW_H_
#ifndef _SIMOBJECT_H_
#include "console/simObject.h"
#endif
#ifndef _GFXDEVICE_H_
#include "gfx/gfxDevice.h"
#endif
#ifndef _PRIMBUILDER_H_
#include "gfx/primBuilder.h"
#endif
#ifndef _GFONT_H_
#include "gfx/gFont.h"
#endif
#ifndef _DATACHUNKER_H_
#include "core/dataChunker.h"
#endif
#ifndef _MPOLYHEDRON_H_
#include "math/mPolyhedron.h"
#endif
class GFont;
// We enable the debug drawer for non-shipping
// builds.... you better be using shipping builds
// for your final release.
#ifndef TORQUE_SHIPPING
#define ENABLE_DEBUGDRAW
#endif
/// Debug output class.
///
/// This class provides you with a flexible means of drawing debug output. It is
/// often useful when debugging collision code or complex 3d algorithms to have
/// them draw debug information, like culling hulls or bounding volumes, normals,
/// simple lines, and so forth. In TGE1.2, which was based directly on a simple
/// OpenGL rendering layer, it was a simple matter to do debug rendering directly
/// inline.
///
/// Unfortunately, this doesn't hold true with more complex rendering scenarios,
/// where render modes and targets may be in abritrary states. In addition, it is
/// often useful to be able to freeze frame debug information for closer inspection.
///
/// Therefore, Torque provides a global DebugDrawer instance, called gDebugDraw, which
/// you can use to draw debug information. It exposes a number of methods for drawing
/// a variety of debug primitives, including lines, triangles and boxes.
/// Internally, DebugDrawer maintains a list of active debug primitives, and draws the
/// contents of the list after each frame is done rendering. This way, you can be
/// assured that your debug rendering won't interfere with TSE's various effect
/// rendering passes or render-to-target calls.
///
/// The DebugDrawer can also be used for more interesting uses, like freezing its
/// primitive list so you can look at a situation more closely, or dumping the
/// primitive list to disk for closer analysis.
///
/// DebugDrawer is accessible by script under the name DebugDrawer, and by C++ under
/// the symbol gDebugDraw. There are a variety of methods available for drawing
/// different sorts of output; see the class reference for more information.
///
/// DebugDrawer works solely in worldspace. Primitives are rendered with cull mode of
/// none.
///
class DebugDrawer : public SimObject
{
public:
DECLARE_CONOBJECT(DebugDrawer);
DebugDrawer();
~DebugDrawer();
static DebugDrawer* get();
/// Called at engine init to set up the global debug draw object.
static void init();
/// Called globally to render debug draw state. Also does state updates.
void render();
void toggleFreeze() { shouldToggleFreeze = true; };
void toggleDrawing()
{
#ifdef ENABLE_DEBUGDRAW
isDrawing = !isDrawing;
#endif
};
/// @name ddrawmeth Debug Draw Methods
///
/// @{
void drawBox(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawLine(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawTri(const Point3F &a, const Point3F &b, const Point3F &c, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawText(const Point3F& pos, const String& text, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
/// Render a wireframe view of the given polyhedron.
void drawPolyhedron( const AnyPolyhedron& polyhedron, const ColorF& color = ColorF( 1.f, 1.f, 1.f ) );
/// Render the plane indices, edge indices, edge direction indicators, and point coordinates
/// of the given polyhedron for debugging.
///
/// Green lines are plane normals. Red lines point from edge midpoints along the edge direction (i.e. to the
/// second vertex). This shows if the orientation is correct to yield CW ordering for face[0]. Indices and
/// coordinates of vertices are shown in white. Plane indices are rendered in black. Edge indices and their
/// plane indices are rendered in white.
void drawPolyhedronDebugInfo( const AnyPolyhedron& polyhedron, const MatrixF& transform, const Point3F& scale );
/// Set the TTL for the last item we entered...
///
/// Primitives default to lasting one frame (ie, ttl=0)
enum {
DD_INFINITE = U32_MAX
};
// How long should this primitive be draw for, 0 = one frame, DD_INFINITE = draw forever
void setLastTTL(U32 ms);
/// Disable/enable z testing on the last primitive.
///
/// Primitives default to z testing on.
void setLastZTest(bool enabled);
/// @}
private:
typedef SimObject Parent;
static DebugDrawer* sgDebugDrawer;
struct DebugPrim
{
/// Color used for this primitive.
ColorF color;
/// Points used to store positional data. Exact semantics determined by type.
Point3F a, b, c;
enum {
Tri,
Box,
Line,
Text
} type; ///< Type of the primitive. The meanings of a,b,c are determined by this.
SimTime dieTime; ///< Time at which we should remove this from the list.
bool useZ; ///< If true, do z-checks for this primitive.
char mText[256]; // Text to display
DebugPrim *next;
};
FreeListChunker<DebugPrim> mPrimChunker;
DebugPrim *mHead;
bool isFrozen;
bool shouldToggleFreeze;
bool isDrawing;
GFXStateBlockRef mRenderZOffSB;
GFXStateBlockRef mRenderZOnSB;
Resource<GFont> mFont;
void setupStateBlocks();
};
#endif // _DEBUGDRAW_H_

View file

@ -0,0 +1,362 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gfx/sim/gfxStateBlockData.h"
#include "console/consoleTypes.h"
#include "gfx/gfxStringEnumTranslate.h"
IMPLEMENT_CONOBJECT( GFXStateBlockData );
ConsoleDocClass( GFXStateBlockData,
"@brief A state block description for rendering.\n\n"
"This object is used with ShaderData in CustomMaterial and PostEffect to define the "
"render state.\n"
"@tsexample\n"
"singleton GFXStateBlockData( PFX_DOFDownSampleStateBlock )\n"
"{\n"
" zDefined = true;\n"
" zEnable = false;\n"
" zWriteEnable = false;\n"
"\n"
" samplersDefined = true;\n"
" samplerStates[0] = SamplerClampLinear;\n"
" samplerStates[1] = SamplerClampPoint;\n"
"\n"
" // Copy the clamped linear sampler, but change\n"
" // the u coord to wrap for this special case.\n"
" samplerStates[2] = new GFXSamplerStateData( : SamplerClampLinear )\n"
" {\n"
" addressModeU = GFXAddressWrap;\n"
" };\n"
"};\n"
"@endtsexample\n"
"@note The 'xxxxDefined' fields are used to know what groups of fields are modified "
"when combining multiple state blocks in material processing. You should take care to "
"enable the right ones when setting values.\n"
"@ingroup GFX\n" );
GFXStateBlockData::GFXStateBlockData()
{
for (U32 i = 0; i < TEXTURE_STAGE_COUNT; i++)
mSamplerStates[i] = NULL;
}
void GFXStateBlockData::initPersistFields()
{
addGroup( "Alpha Blending" );
addField( "blendDefined", TypeBool, Offset(mState.blendDefined, GFXStateBlockData),
"Set to true if the alpha blend state is not all defaults." );
addField( "blendEnable", TypeBool, Offset(mState.blendEnable, GFXStateBlockData),
"Enables alpha blending. The default is false." );
addField( "blendSrc", TypeGFXBlend, Offset(mState.blendSrc, GFXStateBlockData),
"The source blend state. The default is GFXBlendOne." );
addField("blendDest", TypeGFXBlend, Offset(mState.blendDest, GFXStateBlockData),
"The destination blend state. The default is GFXBlendZero." );
addField("blendOp", TypeGFXBlendOp, Offset(mState.blendOp, GFXStateBlockData),
"The arithmetic operation applied to alpha blending. The default is GFXBlendOpAdd." );
endGroup( "Alpha Blending" );
addGroup( "Separate Alpha Blending" );
addField( "separateAlphaBlendDefined", TypeBool, Offset(mState.separateAlphaBlendDefined, GFXStateBlockData),
"Set to true if the seperate alpha blend state is not all defaults." );
addField( "separateAlphaBlendEnable", TypeBool, Offset(mState.separateAlphaBlendEnable, GFXStateBlockData),
"Enables the separate blend mode for the alpha channel. The default is false." );
addField( "separateAlphaBlendSrc", TypeGFXBlend, Offset(mState.separateAlphaBlendSrc, GFXStateBlockData),
"The source blend state. The default is GFXBlendOne." );
addField( "separateAlphaBlendDest", TypeGFXBlend, Offset(mState.separateAlphaBlendDest, GFXStateBlockData),
"The destination blend state. The default is GFXBlendZero." );
addField( "separateAlphaBlendOp", TypeGFXBlendOp, Offset(mState.separateAlphaBlendOp, GFXStateBlockData),
"The arithmetic operation applied to separate alpha blending. The default is GFXBlendOpAdd." );
endGroup( "Separate Alpha Blending" );
addGroup( "Alpha Test" );
addField( "alphaDefined", TypeBool, Offset(mState.alphaDefined, GFXStateBlockData),
"Set to true if the alpha test state is not all defaults." );
addField( "alphaTestEnable", TypeBool, Offset(mState.alphaTestEnable, GFXStateBlockData),
"Enables per-pixel alpha testing. The default is false." );
addField( "alphaTestFunc", TypeGFXCmpFunc, Offset(mState.alphaTestFunc, GFXStateBlockData),
"The test function used to accept or reject a pixel based on its alpha value. The default is GFXCmpGreaterEqual." );
addField( "alphaTestRef", TypeS32, Offset(mState.alphaTestRef, GFXStateBlockData),
"The reference alpha value against which pixels are tested. The default is zero." );
endGroup( "Alpha Test" );
addGroup( "Color Write" );
addField( "colorWriteDefined", TypeBool, Offset(mState.colorWriteDefined, GFXStateBlockData),
"Set to true if the color write state is not all defaults." );
addField( "colorWriteRed", TypeBool, Offset(mState.colorWriteRed, GFXStateBlockData),
"Enables red channel writes. The default is true." );
addField( "colorWriteBlue", TypeBool, Offset(mState.colorWriteBlue, GFXStateBlockData),
"Enables blue channel writes. The default is true." );
addField( "colorWriteGreen", TypeBool, Offset(mState.colorWriteGreen, GFXStateBlockData),
"Enables green channel writes. The default is true." );
addField( "colorWriteAlpha", TypeBool, Offset(mState.colorWriteAlpha, GFXStateBlockData),
"Enables alpha channel writes. The default is true." );
endGroup( "Color Write" );
addGroup( "Culling" );
addField("cullDefined", TypeBool, Offset(mState.cullDefined, GFXStateBlockData),
"Set to true if the culling state is not all defaults." );
addField("cullMode", TypeGFXCullMode, Offset(mState.cullMode, GFXStateBlockData),
"Defines how back facing triangles are culled if at all. The default is GFXCullCCW." );
endGroup( "Culling" );
addGroup( "Depth" );
addField( "zDefined", TypeBool, Offset(mState.zDefined, GFXStateBlockData),
"Set to true if the depth state is not all defaults." );
addField( "zEnable", TypeBool, Offset(mState.zEnable, GFXStateBlockData),
"Enables z-buffer reads. The default is true." );
addField( "zWriteEnable", TypeBool, Offset(mState.zWriteEnable, GFXStateBlockData),
"Enables z-buffer writes. The default is true." );
addField( "zFunc", TypeGFXCmpFunc, Offset(mState.zFunc, GFXStateBlockData),
"The depth comparision function which a pixel must pass to be written to the z-buffer. The default is GFXCmpLessEqual." );
addField( "zBias", TypeF32, Offset(mState.zBias, GFXStateBlockData),
"A floating-point bias used when comparing depth values. The default is zero." );
addField( "zSlopeBias", TypeF32, Offset(mState.zSlopeBias, GFXStateBlockData),
"An additional floating-point bias based on the maximum depth slop of the triangle being rendered. The default is zero." );
endGroup( "Depth" );
addGroup( "Stencil" );
addField( "stencilDefined", TypeBool, Offset(mState.stencilDefined, GFXStateBlockData),
"Set to true if the stencil state is not all defaults." );
addField( "stencilEnable", TypeBool, Offset(mState.stencilEnable, GFXStateBlockData),
"Enables stenciling. The default is false." );
addField( "stencilFailOp", TypeGFXStencilOp, Offset(mState.stencilFailOp, GFXStateBlockData),
"The stencil operation to perform if the stencil test fails. The default is GFXStencilOpKeep." );
addField( "stencilZFailOp", TypeGFXStencilOp, Offset(mState.stencilZFailOp, GFXStateBlockData),
"The stencil operation to perform if the stencil test passes and the depth test fails. The default is GFXStencilOpKeep." );
addField( "stencilPassOp", TypeGFXStencilOp, Offset(mState.stencilPassOp, GFXStateBlockData),
"The stencil operation to perform if both the stencil and the depth tests pass. The default is GFXStencilOpKeep." );
addField( "stencilFunc", TypeGFXCmpFunc, Offset(mState.stencilFunc, GFXStateBlockData),
"The comparison function to test the reference value to a stencil buffer entry. The default is GFXCmpNever." );
addField( "stencilRef", TypeS32, Offset(mState.stencilRef, GFXStateBlockData),
"The reference value for the stencil test. The default is zero." );
addField( "stencilMask", TypeS32, Offset(mState.stencilMask, GFXStateBlockData),
"The mask applied to the reference value and each stencil buffer entry to determine the significant bits for the stencil test. The default is 0xFFFFFFFF." );
addField( "stencilWriteMask", TypeS32, Offset(mState.stencilWriteMask, GFXStateBlockData),
"The write mask applied to values written into the stencil buffer. The default is 0xFFFFFFFF." );
endGroup( "Stencil" );
addGroup( "Fixed Function" );
addField( "ffLighting", TypeBool, Offset(mState.ffLighting, GFXStateBlockData),
"Enables fixed function lighting when rendering without a shader on geometry with vertex normals. The default is false." );
addField( "vertexColorEnable", TypeBool, Offset(mState.vertexColorEnable, GFXStateBlockData),
"Enables fixed function vertex coloring when rendering without a shader. The default is false." );
endGroup( "Fixed Function" );
addGroup( "Sampler States" );
addField( "samplersDefined", TypeBool, Offset(mState.samplersDefined, GFXStateBlockData),
"Set to true if the sampler states are not all defaults." );
addField( "samplerStates", TYPEID<GFXSamplerStateData>(), Offset(mSamplerStates, GFXStateBlockData), TEXTURE_STAGE_COUNT,
"The array of texture sampler states.\n"
"@note Not all graphics devices support 16 samplers. In general "
"all systems support 4 samplers with most modern cards doing 8." );
addField( "textureFactor", TypeColorI, Offset(mState.textureFactor, GFXStateBlockData),
"The color used for multiple-texture blending with the GFXTATFactor texture-blending argument or "
"the GFXTOPBlendFactorAlpha texture-blending operation. The default is opaque white (255, 255, 255, 255)." );
endGroup( "Sampler States" );
Parent::initPersistFields();
}
bool GFXStateBlockData::onAdd()
{
if (!Parent::onAdd())
return false;
for (U32 i = 0; i < TEXTURE_STAGE_COUNT; i++)
{
if (mSamplerStates[i])
mSamplerStates[i]->setSamplerState(mState.samplers[i]);
}
return true;
}
IMPLEMENT_CONOBJECT( GFXSamplerStateData );
ConsoleDocClass( GFXSamplerStateData,
"@brief A sampler state used by GFXStateBlockData.\n\n"
"The samplers define how a texture will be sampled when used from the shader "
"or fixed function device\n"
"@tsexample\n"
"singleton GFXSamplerStateData(SamplerClampLinear)\n"
"{\n"
" textureColorOp = GFXTOPModulate;\n"
" addressModeU = GFXAddressClamp;\n"
" addressModeV = GFXAddressClamp;\n"
" addressModeW = GFXAddressClamp;\n"
" magFilter = GFXTextureFilterLinear;\n"
" minFilter = GFXTextureFilterLinear;\n"
" mipFilter = GFXTextureFilterLinear;\n"
"};\n"
"@endtsexample\n"
"There are a few predefined samplers in the core scripts which you can use with "
"GFXStateBlockData for the most common rendering cases:\n"
" - SamplerClampLinear\n"
" - SamplerClampPoint\n"
" - SamplerWrapLinear\n"
" - SamplerWrapPoint\n"
"\n"
"@see GFXStateBlockData\n"
"@ingroup GFX\n" );
void GFXSamplerStateData::initPersistFields()
{
Parent::initPersistFields();
addGroup( "Color Op" );
addField("textureColorOp", TypeGFXTextureOp, Offset(mState.textureColorOp, GFXSamplerStateData),
"The texture color blending operation. The default value is GFXTOPDisable which disables the sampler." );
addField("colorArg1", TYPEID< GFXTextureArgument >(), Offset(mState.colorArg1, GFXSamplerStateData),
"The first color argument for the texture stage. The default value is GFXTACurrent." );
addField("colorArg2", TYPEID< GFXTextureArgument >(), Offset(mState.colorArg2, GFXSamplerStateData),
"The second color argument for the texture stage. The default value is GFXTATexture." );
addField("colorArg3", TYPEID< GFXTextureArgument >(), Offset(mState.colorArg3, GFXSamplerStateData),
"The third color argument for triadic operations (multiply, add, and linearly interpolate). The default value is GFXTACurrent." );
endGroup( "Color Op" );
addGroup( "Alpha Op" );
addField("alphaOp", TypeGFXTextureOp, Offset(mState.alphaOp, GFXSamplerStateData),
"The texture alpha blending operation. The default value is GFXTOPModulate." );
addField("alphaArg1", TYPEID< GFXTextureArgument >(), Offset(mState.alphaArg1, GFXSamplerStateData),
"The first alpha argument for the texture stage. The default value is GFXTATexture." );
addField("alphaArg2", TYPEID< GFXTextureArgument >(), Offset(mState.alphaArg2, GFXSamplerStateData),
"The second alpha argument for the texture stage. The default value is GFXTADiffuse." );
addField("alphaArg3", TYPEID< GFXTextureArgument >(), Offset(mState.alphaArg3, GFXSamplerStateData),
"The third alpha channel selector operand for triadic operations (multiply, add, and linearly interpolate). The default value is GFXTACurrent." );
endGroup( "Alpha Op" );
addGroup( "Address Mode" );
addField("addressModeU", TypeGFXTextureAddressMode, Offset(mState.addressModeU, GFXSamplerStateData),
"The texture address mode for the u coordinate. The default is GFXAddressWrap." );
addField("addressModeV", TypeGFXTextureAddressMode, Offset(mState.addressModeV, GFXSamplerStateData),
"The texture address mode for the v coordinate. The default is GFXAddressWrap." );
addField("addressModeW", TypeGFXTextureAddressMode, Offset(mState.addressModeW, GFXSamplerStateData),
"The texture address mode for the w coordinate. The default is GFXAddressWrap." );
endGroup( "Address Mode" );
addGroup( "Filter State" );
addField("magFilter", TypeGFXTextureFilterType, Offset(mState.magFilter, GFXSamplerStateData),
"The texture magnification filter. The default is GFXTextureFilterLinear." );
addField("minFilter", TypeGFXTextureFilterType, Offset(mState.minFilter, GFXSamplerStateData),
"The texture minification filter. The default is GFXTextureFilterLinear." );
addField("mipFilter", TypeGFXTextureFilterType, Offset(mState.mipFilter, GFXSamplerStateData),
"The texture mipmap filter used during minification. The default is GFXTextureFilterLinear." );
addField("mipLODBias", TypeF32, Offset(mState.mipLODBias, GFXSamplerStateData),
"The mipmap level of detail bias. The default value is zero." );
addField("maxAnisotropy", TypeS32, Offset(mState.maxAnisotropy, GFXSamplerStateData),
"The maximum texture anisotropy. The default value is 1." );
endGroup( "Filter State" );
addField("textureTransform", TypeGFXTextureTransformFlags, Offset(mState.textureTransform, GFXSamplerStateData),
"Sets the texture transform state. The default is GFXTTFFDisable." );
addField("resultArg", TypeGFXTextureArgument, Offset(mState.resultArg, GFXSamplerStateData),
"The selection of the destination register for the result of this stage. The default is GFXTACurrent." );
}
/// Copies the data of this object into desc
void GFXSamplerStateData::setSamplerState(GFXSamplerStateDesc& desc)
{
desc = mState;
}

View file

@ -0,0 +1,71 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef __GFXSTATEBLOCKDATA_H_
#define __GFXSTATEBLOCKDATA_H_
#ifndef _GFXSTATEBLOCK_H_
#include "gfx/gfxStateBlock.h"
#endif
#ifndef _SIMOBJECT_H_
#include "console/simObject.h"
#endif
class GFXSamplerStateData;
/// Allows definition of render state via script, basically wraps a GFXStateBlockDesc
class GFXStateBlockData : public SimObject
{
typedef SimObject Parent;
GFXStateBlockDesc mState;
GFXSamplerStateData* mSamplerStates[TEXTURE_STAGE_COUNT];
public:
GFXStateBlockData();
// SimObject
virtual bool onAdd();
static void initPersistFields();
// GFXStateBlockData
const GFXStateBlockDesc getState() const { return mState; }
DECLARE_CONOBJECT(GFXStateBlockData);
};
/// Allows definition of sampler state via script, basically wraps a GFXSamplerStateDesc
class GFXSamplerStateData : public SimObject
{
typedef SimObject Parent;
GFXSamplerStateDesc mState;
public:
// SimObject
static void initPersistFields();
/// Copies the data of this object into desc
void setSamplerState(GFXSamplerStateDesc& desc);
DECLARE_CONOBJECT(GFXSamplerStateData);
};
#endif // __GFXSTATEBLOCKDATA_H_