mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 23:24:41 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
287
Engine/source/gfx/sim/cubemapData.cpp
Normal file
287
Engine/source/gfx/sim/cubemapData.cpp
Normal 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();
|
||||
}
|
||||
87
Engine/source/gfx/sim/cubemapData.h
Normal file
87
Engine/source/gfx/sim/cubemapData.h
Normal 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
|
||||
|
||||
433
Engine/source/gfx/sim/debugDraw.cpp
Normal file
433
Engine/source/gfx/sim/debugDraw.cpp
Normal 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();
|
||||
}
|
||||
|
||||
197
Engine/source/gfx/sim/debugDraw.h
Normal file
197
Engine/source/gfx/sim/debugDraw.h
Normal 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_
|
||||
362
Engine/source/gfx/sim/gfxStateBlockData.cpp
Normal file
362
Engine/source/gfx/sim/gfxStateBlockData.cpp
Normal 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;
|
||||
}
|
||||
71
Engine/source/gfx/sim/gfxStateBlockData.h
Normal file
71
Engine/source/gfx/sim/gfxStateBlockData.h
Normal 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_
|
||||
Loading…
Add table
Add a link
Reference in a new issue