mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-11 22:54:34 +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
346
Engine/source/T3D/examples/renderMeshExample.cpp
Normal file
346
Engine/source/T3D/examples/renderMeshExample.cpp
Normal file
|
|
@ -0,0 +1,346 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "T3D/examples/renderMeshExample.h"
|
||||
|
||||
#include "math/mathIO.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "materials/materialManager.h"
|
||||
#include "materials/baseMatInstance.h"
|
||||
#include "renderInstance/renderPassManager.h"
|
||||
#include "lighting/lightQuery.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(RenderMeshExample);
|
||||
|
||||
ConsoleDocClass( RenderMeshExample,
|
||||
"@brief An example scene object which renders a mesh.\n\n"
|
||||
"This class implements a basic SceneObject that can exist in the world at a "
|
||||
"3D position and render itself. There are several valid ways to render an "
|
||||
"object in Torque. This class implements the preferred rendering method which "
|
||||
"is to submit a MeshRenderInst along with a Material, vertex buffer, "
|
||||
"primitive buffer, and transform and allow the RenderMeshMgr handle the "
|
||||
"actual setup and rendering for you.\n\n"
|
||||
"See the C++ code for implementation details.\n\n"
|
||||
"@ingroup Examples\n" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object setup and teardown
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderMeshExample::RenderMeshExample()
|
||||
{
|
||||
// Flag this object so that it will always
|
||||
// be sent across the network to clients
|
||||
mNetFlags.set( Ghostable | ScopeAlways );
|
||||
|
||||
// Set it as a "static" object that casts shadows
|
||||
mTypeMask |= StaticObjectType | StaticShapeObjectType;
|
||||
|
||||
// Make sure we the Material instance to NULL
|
||||
// so we don't try to access it incorrectly
|
||||
mMaterialInst = NULL;
|
||||
}
|
||||
|
||||
RenderMeshExample::~RenderMeshExample()
|
||||
{
|
||||
if ( mMaterialInst )
|
||||
SAFE_DELETE( mMaterialInst );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object Editing
|
||||
//-----------------------------------------------------------------------------
|
||||
void RenderMeshExample::initPersistFields()
|
||||
{
|
||||
addGroup( "Rendering" );
|
||||
addField( "material", TypeMaterialName, Offset( mMaterialName, RenderMeshExample ),
|
||||
"The name of the material used to render the mesh." );
|
||||
endGroup( "Rendering" );
|
||||
|
||||
// SceneObject already handles exposing the transform
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void RenderMeshExample::inspectPostApply()
|
||||
{
|
||||
Parent::inspectPostApply();
|
||||
|
||||
// Flag the network mask to send the updates
|
||||
// to the client object
|
||||
setMaskBits( UpdateMask );
|
||||
}
|
||||
|
||||
bool RenderMeshExample::onAdd()
|
||||
{
|
||||
if ( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
// Set up a 1x1x1 bounding box
|
||||
mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ),
|
||||
Point3F( 0.5f, 0.5f, 0.5f ) );
|
||||
|
||||
resetWorldBox();
|
||||
|
||||
// Add this object to the scene
|
||||
addToScene();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderMeshExample::onRemove()
|
||||
{
|
||||
// Remove this object from the scene
|
||||
removeFromScene();
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
void RenderMeshExample::setTransform(const MatrixF & mat)
|
||||
{
|
||||
// Let SceneObject handle all of the matrix manipulation
|
||||
Parent::setTransform( mat );
|
||||
|
||||
// Dirty our network mask so that the new transform gets
|
||||
// transmitted to the client object
|
||||
setMaskBits( TransformMask );
|
||||
}
|
||||
|
||||
U32 RenderMeshExample::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
|
||||
{
|
||||
// Allow the Parent to get a crack at writing its info
|
||||
U32 retMask = Parent::packUpdate( conn, mask, stream );
|
||||
|
||||
// Write our transform information
|
||||
if ( stream->writeFlag( mask & TransformMask ) )
|
||||
{
|
||||
mathWrite(*stream, getTransform());
|
||||
mathWrite(*stream, getScale());
|
||||
}
|
||||
|
||||
// Write out any of the updated editable properties
|
||||
if ( stream->writeFlag( mask & UpdateMask ) )
|
||||
stream->write( mMaterialName );
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
void RenderMeshExample::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||
{
|
||||
// Let the Parent read any info it sent
|
||||
Parent::unpackUpdate(conn, stream);
|
||||
|
||||
if ( stream->readFlag() ) // TransformMask
|
||||
{
|
||||
mathRead(*stream, &mObjToWorld);
|
||||
mathRead(*stream, &mObjScale);
|
||||
|
||||
setTransform( mObjToWorld );
|
||||
}
|
||||
|
||||
if ( stream->readFlag() ) // UpdateMask
|
||||
{
|
||||
stream->read( &mMaterialName );
|
||||
|
||||
if ( isProperlyAdded() )
|
||||
updateMaterial();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object Rendering
|
||||
//-----------------------------------------------------------------------------
|
||||
void RenderMeshExample::createGeometry()
|
||||
{
|
||||
static const Point3F cubePoints[8] =
|
||||
{
|
||||
Point3F( 1, -1, -1), Point3F( 1, -1, 1), Point3F( 1, 1, -1), Point3F( 1, 1, 1),
|
||||
Point3F(-1, -1, -1), Point3F(-1, 1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, 1)
|
||||
};
|
||||
|
||||
static const Point3F cubeNormals[6] =
|
||||
{
|
||||
Point3F( 1, 0, 0), Point3F(-1, 0, 0), Point3F( 0, 1, 0),
|
||||
Point3F( 0, -1, 0), Point3F( 0, 0, 1), Point3F( 0, 0, -1)
|
||||
};
|
||||
|
||||
static const Point2F cubeTexCoords[4] =
|
||||
{
|
||||
Point2F( 0, 0), Point2F( 0, -1),
|
||||
Point2F( 1, 0), Point2F( 1, -1)
|
||||
};
|
||||
|
||||
static const U32 cubeFaces[36][3] =
|
||||
{
|
||||
{ 3, 0, 3 }, { 0, 0, 0 }, { 1, 0, 1 },
|
||||
{ 2, 0, 2 }, { 0, 0, 0 }, { 3, 0, 3 },
|
||||
{ 7, 1, 1 }, { 4, 1, 2 }, { 5, 1, 0 },
|
||||
{ 6, 1, 3 }, { 4, 1, 2 }, { 7, 1, 1 },
|
||||
{ 3, 2, 1 }, { 5, 2, 2 }, { 2, 2, 0 },
|
||||
{ 7, 2, 3 }, { 5, 2, 2 }, { 3, 2, 1 },
|
||||
{ 1, 3, 3 }, { 4, 3, 0 }, { 6, 3, 1 },
|
||||
{ 0, 3, 2 }, { 4, 3, 0 }, { 1, 3, 3 },
|
||||
{ 3, 4, 3 }, { 6, 4, 0 }, { 7, 4, 1 },
|
||||
{ 1, 4, 2 }, { 6, 4, 0 }, { 3, 4, 3 },
|
||||
{ 2, 5, 1 }, { 4, 5, 2 }, { 0, 5, 0 },
|
||||
{ 5, 5, 3 }, { 4, 5, 2 }, { 2, 5, 1 }
|
||||
};
|
||||
|
||||
// Fill the vertex buffer
|
||||
VertexType *pVert = NULL;
|
||||
|
||||
mVertexBuffer.set( GFX, 36, GFXBufferTypeStatic );
|
||||
pVert = mVertexBuffer.lock();
|
||||
|
||||
Point3F halfSize = getObjBox().getExtents() * 0.5f;
|
||||
|
||||
for (U32 i = 0; i < 36; i++)
|
||||
{
|
||||
const U32& vdx = cubeFaces[i][0];
|
||||
const U32& ndx = cubeFaces[i][1];
|
||||
const U32& tdx = cubeFaces[i][2];
|
||||
|
||||
pVert[i].point = cubePoints[vdx] * halfSize;
|
||||
pVert[i].normal = cubeNormals[ndx];
|
||||
pVert[i].texCoord = cubeTexCoords[tdx];
|
||||
}
|
||||
|
||||
mVertexBuffer.unlock();
|
||||
|
||||
// Fill the primitive buffer
|
||||
U16 *pIdx = NULL;
|
||||
|
||||
mPrimitiveBuffer.set( GFX, 36, 12, GFXBufferTypeStatic );
|
||||
|
||||
mPrimitiveBuffer.lock(&pIdx);
|
||||
|
||||
for (U16 i = 0; i < 36; i++)
|
||||
pIdx[i] = i;
|
||||
|
||||
mPrimitiveBuffer.unlock();
|
||||
}
|
||||
|
||||
void RenderMeshExample::updateMaterial()
|
||||
{
|
||||
if ( mMaterialName.isEmpty() )
|
||||
return;
|
||||
|
||||
// If the material name matches then don't bother updating it.
|
||||
if ( mMaterialInst && mMaterialName.equal( mMaterialInst->getMaterial()->getName(), String::NoCase ) )
|
||||
return;
|
||||
|
||||
SAFE_DELETE( mMaterialInst );
|
||||
|
||||
mMaterialInst = MATMGR->createMatInstance( mMaterialName, getGFXVertexFormat< VertexType >() );
|
||||
if ( !mMaterialInst )
|
||||
Con::errorf( "RenderMeshExample::updateMaterial - no Material called '%s'", mMaterialName.c_str() );
|
||||
}
|
||||
|
||||
void RenderMeshExample::prepRenderImage( SceneRenderState *state )
|
||||
{
|
||||
// Do a little prep work if needed
|
||||
if ( mVertexBuffer.isNull() )
|
||||
createGeometry();
|
||||
|
||||
// If we have no material then skip out.
|
||||
if ( !mMaterialInst )
|
||||
return;
|
||||
|
||||
// If we don't have a material instance after the override then
|
||||
// we can skip rendering all together.
|
||||
BaseMatInstance *matInst = state->getOverrideMaterial( mMaterialInst );
|
||||
if ( !matInst )
|
||||
return;
|
||||
|
||||
// Get a handy pointer to our RenderPassmanager
|
||||
RenderPassManager *renderPass = state->getRenderPass();
|
||||
|
||||
// Allocate an MeshRenderInst so that we can submit it to the RenderPassManager
|
||||
MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>();
|
||||
|
||||
// Set our RenderInst as a standard mesh render
|
||||
ri->type = RenderPassManager::RIT_Mesh;
|
||||
|
||||
// Calculate our sorting point
|
||||
if ( state )
|
||||
{
|
||||
// Calculate our sort point manually.
|
||||
const Box3F& rBox = getRenderWorldBox();
|
||||
ri->sortDistSq = rBox.getSqDistanceToPoint( state->getCameraPosition() );
|
||||
}
|
||||
else
|
||||
ri->sortDistSq = 0.0f;
|
||||
|
||||
// Set up our transforms
|
||||
MatrixF objectToWorld = getRenderTransform();
|
||||
objectToWorld.scale( getScale() );
|
||||
|
||||
ri->objectToWorld = renderPass->allocUniqueXform( objectToWorld );
|
||||
ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View);
|
||||
ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection);
|
||||
|
||||
// If our material needs lights then fill the RIs
|
||||
// light vector with the best lights.
|
||||
if ( matInst->isForwardLit() )
|
||||
{
|
||||
LightQuery query;
|
||||
query.init( getWorldSphere() );
|
||||
query.getLights( ri->lights, 8 );
|
||||
}
|
||||
|
||||
// Make sure we have an up-to-date backbuffer in case
|
||||
// our Material would like to make use of it
|
||||
// NOTICE: SFXBB is removed and refraction is disabled!
|
||||
//ri->backBuffTex = GFX->getSfxBackBuffer();
|
||||
|
||||
// Set our Material
|
||||
ri->matInst = matInst;
|
||||
|
||||
// Set up our vertex buffer and primitive buffer
|
||||
ri->vertBuff = &mVertexBuffer;
|
||||
ri->primBuff = &mPrimitiveBuffer;
|
||||
|
||||
ri->prim = renderPass->allocPrim();
|
||||
ri->prim->type = GFXTriangleList;
|
||||
ri->prim->minIndex = 0;
|
||||
ri->prim->startIndex = 0;
|
||||
ri->prim->numPrimitives = 12;
|
||||
ri->prim->startVertex = 0;
|
||||
ri->prim->numVertices = 36;
|
||||
|
||||
// We sort by the material then vertex buffer
|
||||
ri->defaultKey = matInst->getStateHint();
|
||||
ri->defaultKey2 = (U32)ri->vertBuff; // Not 64bit safe!
|
||||
|
||||
// Submit our RenderInst to the RenderPassManager
|
||||
state->getRenderPass()->addInst( ri );
|
||||
}
|
||||
|
||||
DefineEngineMethod( RenderMeshExample, postApply, void, (),,
|
||||
"A utility method for forcing a network update.\n")
|
||||
{
|
||||
object->inspectPostApply();
|
||||
}
|
||||
134
Engine/source/T3D/examples/renderMeshExample.h
Normal file
134
Engine/source/T3D/examples/renderMeshExample.h
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _RENDERMESHEXAMPLE_H_
|
||||
#define _RENDERMESHEXAMPLE_H_
|
||||
|
||||
#ifndef _SCENEOBJECT_H_
|
||||
#include "scene/sceneObject.h"
|
||||
#endif
|
||||
#ifndef _GFXVERTEXBUFFER_H_
|
||||
#include "gfx/gfxVertexBuffer.h"
|
||||
#endif
|
||||
#ifndef _GFXPRIMITIVEBUFFER_H_
|
||||
#include "gfx/gfxPrimitiveBuffer.h"
|
||||
#endif
|
||||
|
||||
class BaseMatInstance;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This class implements a basic SceneObject that can exist in the world at a
|
||||
// 3D position and render itself. There are several valid ways to render an
|
||||
// object in Torque. This class implements the preferred rendering method which
|
||||
// is to submit a MeshRenderInst along with a Material, vertex buffer,
|
||||
// primitive buffer, and transform and allow the RenderMeshMgr handle the
|
||||
// actual setup and rendering for you.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class RenderMeshExample : public SceneObject
|
||||
{
|
||||
typedef SceneObject Parent;
|
||||
|
||||
// Networking masks
|
||||
// We need to implement a mask specifically to handle
|
||||
// updating our transform from the server object to its
|
||||
// client-side "ghost". We also need to implement a
|
||||
// maks for handling editor updates to our properties
|
||||
// (like material).
|
||||
enum MaskBits
|
||||
{
|
||||
TransformMask = Parent::NextFreeMask << 0,
|
||||
UpdateMask = Parent::NextFreeMask << 1,
|
||||
NextFreeMask = Parent::NextFreeMask << 2
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Rendering variables
|
||||
//--------------------------------------------------------------------------
|
||||
// The name of the Material we will use for rendering
|
||||
String mMaterialName;
|
||||
// The actual Material instance
|
||||
BaseMatInstance* mMaterialInst;
|
||||
|
||||
// Define our vertex format here so we don't have to
|
||||
// change it in multiple spots later
|
||||
typedef GFXVertexPNT VertexType;
|
||||
|
||||
// The GFX vertex and primitive buffers
|
||||
GFXVertexBufferHandle< VertexType > mVertexBuffer;
|
||||
GFXPrimitiveBufferHandle mPrimitiveBuffer;
|
||||
|
||||
public:
|
||||
RenderMeshExample();
|
||||
virtual ~RenderMeshExample();
|
||||
|
||||
// Declare this object as a ConsoleObject so that we can
|
||||
// instantiate it into the world and network it
|
||||
DECLARE_CONOBJECT(RenderMeshExample);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Object Editing
|
||||
// Since there is always a server and a client object in Torque and we
|
||||
// actually edit the server object we need to implement some basic
|
||||
// networking functions
|
||||
//--------------------------------------------------------------------------
|
||||
// Set up any fields that we want to be editable (like position)
|
||||
static void initPersistFields();
|
||||
|
||||
// Allows the object to update its editable settings
|
||||
// from the server object to the client
|
||||
virtual void inspectPostApply();
|
||||
|
||||
// Handle when we are added to the scene and removed from the scene
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
|
||||
// Override this so that we can dirty the network flag when it is called
|
||||
void setTransform( const MatrixF &mat );
|
||||
|
||||
// This function handles sending the relevant data from the server
|
||||
// object to the client object
|
||||
U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
|
||||
// This function handles receiving relevant data from the server
|
||||
// object and applying it to the client object
|
||||
void unpackUpdate( NetConnection *conn, BitStream *stream );
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Object Rendering
|
||||
// Torque utilizes a "batch" rendering system. This means that it builds a
|
||||
// list of objects that need to render (via RenderInst's) and then renders
|
||||
// them all in one batch. This allows it to optimized on things like
|
||||
// minimizing texture, state, and shader switching by grouping objects that
|
||||
// use the same Materials.
|
||||
//--------------------------------------------------------------------------
|
||||
// Create the geometry for rendering
|
||||
void createGeometry();
|
||||
|
||||
// Get the Material instance
|
||||
void updateMaterial();
|
||||
|
||||
// This is the function that allows this object to submit itself for rendering
|
||||
void prepRenderImage( SceneRenderState *state );
|
||||
};
|
||||
|
||||
#endif // _RENDERMESHEXAMPLE_H_
|
||||
280
Engine/source/T3D/examples/renderObjectExample.cpp
Normal file
280
Engine/source/T3D/examples/renderObjectExample.cpp
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "T3D/examples/renderObjectExample.h"
|
||||
|
||||
#include "math/mathIO.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "materials/sceneData.h"
|
||||
#include "gfx/gfxDebugEvent.h"
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "renderInstance/renderPassManager.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(RenderObjectExample);
|
||||
|
||||
ConsoleDocClass( RenderObjectExample,
|
||||
"@brief An example scene object which renders using a callback.\n\n"
|
||||
"This class implements a basic SceneObject that can exist in the world at a "
|
||||
"3D position and render itself. Note that RenderObjectExample handles its own "
|
||||
"rendering by submitting itself as an ObjectRenderInst (see "
|
||||
"renderInstance\renderPassmanager.h) along with a delegate for its render() "
|
||||
"function. However, the preffered rendering method in the engine is to submit "
|
||||
"a MeshRenderInst along with a Material, vertex buffer, primitive buffer, and "
|
||||
"transform and allow the RenderMeshMgr handle the actual rendering. You can "
|
||||
"see this implemented in RenderMeshExample.\n\n"
|
||||
"See the C++ code for implementation details.\n\n"
|
||||
"@ingroup Examples\n" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object setup and teardown
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderObjectExample::RenderObjectExample()
|
||||
{
|
||||
// Flag this object so that it will always
|
||||
// be sent across the network to clients
|
||||
mNetFlags.set( Ghostable | ScopeAlways );
|
||||
|
||||
// Set it as a "static" object
|
||||
mTypeMask |= StaticObjectType | StaticShapeObjectType;
|
||||
}
|
||||
|
||||
RenderObjectExample::~RenderObjectExample()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object Editing
|
||||
//-----------------------------------------------------------------------------
|
||||
void RenderObjectExample::initPersistFields()
|
||||
{
|
||||
// SceneObject already handles exposing the transform
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool RenderObjectExample::onAdd()
|
||||
{
|
||||
if ( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
// Set up a 1x1x1 bounding box
|
||||
mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ),
|
||||
Point3F( 0.5f, 0.5f, 0.5f ) );
|
||||
|
||||
resetWorldBox();
|
||||
|
||||
// Add this object to the scene
|
||||
addToScene();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderObjectExample::onRemove()
|
||||
{
|
||||
// Remove this object from the scene
|
||||
removeFromScene();
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
void RenderObjectExample::setTransform(const MatrixF & mat)
|
||||
{
|
||||
// Let SceneObject handle all of the matrix manipulation
|
||||
Parent::setTransform( mat );
|
||||
|
||||
// Dirty our network mask so that the new transform gets
|
||||
// transmitted to the client object
|
||||
setMaskBits( TransformMask );
|
||||
}
|
||||
|
||||
U32 RenderObjectExample::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
|
||||
{
|
||||
// Allow the Parent to get a crack at writing its info
|
||||
U32 retMask = Parent::packUpdate( conn, mask, stream );
|
||||
|
||||
// Write our transform information
|
||||
if ( stream->writeFlag( mask & TransformMask ) )
|
||||
{
|
||||
mathWrite(*stream, getTransform());
|
||||
mathWrite(*stream, getScale());
|
||||
}
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
void RenderObjectExample::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||
{
|
||||
// Let the Parent read any info it sent
|
||||
Parent::unpackUpdate(conn, stream);
|
||||
|
||||
if ( stream->readFlag() ) // TransformMask
|
||||
{
|
||||
mathRead(*stream, &mObjToWorld);
|
||||
mathRead(*stream, &mObjScale);
|
||||
|
||||
setTransform( mObjToWorld );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object Rendering
|
||||
//-----------------------------------------------------------------------------
|
||||
void RenderObjectExample::createGeometry()
|
||||
{
|
||||
static const Point3F cubePoints[8] =
|
||||
{
|
||||
Point3F( 1.0f, -1.0f, -1.0f), Point3F( 1.0f, -1.0f, 1.0f),
|
||||
Point3F( 1.0f, 1.0f, -1.0f), Point3F( 1.0f, 1.0f, 1.0f),
|
||||
Point3F(-1.0f, -1.0f, -1.0f), Point3F(-1.0f, 1.0f, -1.0f),
|
||||
Point3F(-1.0f, -1.0f, 1.0f), Point3F(-1.0f, 1.0f, 1.0f)
|
||||
};
|
||||
|
||||
static const Point3F cubeNormals[6] =
|
||||
{
|
||||
Point3F( 1.0f, 0.0f, 0.0f), Point3F(-1.0f, 0.0f, 0.0f),
|
||||
Point3F( 0.0f, 1.0f, 0.0f), Point3F( 0.0f, -1.0f, 0.0f),
|
||||
Point3F( 0.0f, 0.0f, 1.0f), Point3F( 0.0f, 0.0f, -1.0f)
|
||||
};
|
||||
|
||||
static const ColorI cubeColors[3] =
|
||||
{
|
||||
ColorI( 255, 0, 0, 255 ),
|
||||
ColorI( 0, 255, 0, 255 ),
|
||||
ColorI( 0, 0, 255, 255 )
|
||||
};
|
||||
|
||||
static const U32 cubeFaces[36][3] =
|
||||
{
|
||||
{ 3, 0, 0 }, { 0, 0, 0 }, { 1, 0, 0 },
|
||||
{ 2, 0, 0 }, { 0, 0, 0 }, { 3, 0, 0 },
|
||||
{ 7, 1, 0 }, { 4, 1, 0 }, { 5, 1, 0 },
|
||||
{ 6, 1, 0 }, { 4, 1, 0 }, { 7, 1, 0 },
|
||||
{ 3, 2, 1 }, { 5, 2, 1 }, { 2, 2, 1 },
|
||||
{ 7, 2, 1 }, { 5, 2, 1 }, { 3, 2, 1 },
|
||||
{ 1, 3, 1 }, { 4, 3, 1 }, { 6, 3, 1 },
|
||||
{ 0, 3, 1 }, { 4, 3, 1 }, { 1, 3, 1 },
|
||||
{ 3, 4, 2 }, { 6, 4, 2 }, { 7, 4, 2 },
|
||||
{ 1, 4, 2 }, { 6, 4, 2 }, { 3, 4, 2 },
|
||||
{ 2, 5, 2 }, { 4, 5, 2 }, { 0, 5, 2 },
|
||||
{ 5, 5, 2 }, { 4, 5, 2 }, { 2, 5, 2 }
|
||||
};
|
||||
|
||||
// Fill the vertex buffer
|
||||
VertexType *pVert = NULL;
|
||||
|
||||
mVertexBuffer.set( GFX, 36, GFXBufferTypeStatic );
|
||||
pVert = mVertexBuffer.lock();
|
||||
|
||||
Point3F halfSize = getObjBox().getExtents() * 0.5f;
|
||||
|
||||
for (U32 i = 0; i < 36; i++)
|
||||
{
|
||||
const U32& vdx = cubeFaces[i][0];
|
||||
const U32& ndx = cubeFaces[i][1];
|
||||
const U32& cdx = cubeFaces[i][2];
|
||||
|
||||
pVert[i].point = cubePoints[vdx] * halfSize;
|
||||
pVert[i].normal = cubeNormals[ndx];
|
||||
pVert[i].color = cubeColors[cdx];
|
||||
}
|
||||
|
||||
mVertexBuffer.unlock();
|
||||
|
||||
// Set up our normal and reflection StateBlocks
|
||||
GFXStateBlockDesc desc;
|
||||
|
||||
// The normal StateBlock only needs a default StateBlock
|
||||
mNormalSB = GFX->createStateBlock( desc );
|
||||
|
||||
// The reflection needs its culling reversed
|
||||
desc.cullDefined = true;
|
||||
desc.cullMode = GFXCullCW;
|
||||
mReflectSB = GFX->createStateBlock( desc );
|
||||
}
|
||||
|
||||
void RenderObjectExample::prepRenderImage( SceneRenderState *state )
|
||||
{
|
||||
// Do a little prep work if needed
|
||||
if ( mVertexBuffer.isNull() )
|
||||
createGeometry();
|
||||
|
||||
// Allocate an ObjectRenderInst so that we can submit it to the RenderPassManager
|
||||
ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
|
||||
|
||||
// Now bind our rendering function so that it will get called
|
||||
ri->renderDelegate.bind( this, &RenderObjectExample::render );
|
||||
|
||||
// Set our RenderInst as a standard object render
|
||||
ri->type = RenderPassManager::RIT_Object;
|
||||
|
||||
// Set our sorting keys to a default value
|
||||
ri->defaultKey = 0;
|
||||
ri->defaultKey2 = 0;
|
||||
|
||||
// Submit our RenderInst to the RenderPassManager
|
||||
state->getRenderPass()->addInst( ri );
|
||||
}
|
||||
|
||||
void RenderObjectExample::render( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat )
|
||||
{
|
||||
if ( overrideMat )
|
||||
return;
|
||||
|
||||
if ( mVertexBuffer.isNull() )
|
||||
return;
|
||||
|
||||
PROFILE_SCOPE(RenderObjectExample_Render);
|
||||
|
||||
// Set up a GFX debug event (this helps with debugging rendering events in external tools)
|
||||
GFXDEBUGEVENT_SCOPE( RenderObjectExample_Render, ColorI::RED );
|
||||
|
||||
// GFXTransformSaver is a handy helper class that restores
|
||||
// the current GFX matrices to their original values when
|
||||
// it goes out of scope at the end of the function
|
||||
GFXTransformSaver saver;
|
||||
|
||||
// Calculate our object to world transform matrix
|
||||
MatrixF objectToWorld = getRenderTransform();
|
||||
objectToWorld.scale( getScale() );
|
||||
|
||||
// Apply our object transform
|
||||
GFX->multWorld( objectToWorld );
|
||||
|
||||
// Deal with reflect pass otherwise
|
||||
// set the normal StateBlock
|
||||
if ( state->isReflectPass() )
|
||||
GFX->setStateBlock( mReflectSB );
|
||||
else
|
||||
GFX->setStateBlock( mNormalSB );
|
||||
|
||||
// Set up the "generic" shaders
|
||||
// These handle rendering on GFX layers that don't support
|
||||
// fixed function. Otherwise they disable shaders.
|
||||
GFX->setupGenericShaders( GFXDevice::GSModColorTexture );
|
||||
|
||||
// Set the vertex buffer
|
||||
GFX->setVertexBuffer( mVertexBuffer );
|
||||
|
||||
// Draw our triangles
|
||||
GFX->drawPrimitive( GFXTriangleList, 0, 12 );
|
||||
}
|
||||
136
Engine/source/T3D/examples/renderObjectExample.h
Normal file
136
Engine/source/T3D/examples/renderObjectExample.h
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _RENDEROBJECTEXAMPLE_H_
|
||||
#define _RENDEROBJECTEXAMPLE_H_
|
||||
|
||||
#ifndef _SCENEOBJECT_H_
|
||||
#include "scene/sceneObject.h"
|
||||
#endif
|
||||
#ifndef _GFXSTATEBLOCK_H_
|
||||
#include "gfx/gfxStateBlock.h"
|
||||
#endif
|
||||
#ifndef _GFXVERTEXBUFFER_H_
|
||||
#include "gfx/gfxVertexBuffer.h"
|
||||
#endif
|
||||
#ifndef _GFXPRIMITIVEBUFFER_H_
|
||||
#include "gfx/gfxPrimitiveBuffer.h"
|
||||
#endif
|
||||
|
||||
class BaseMatInstance;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This class implements a basic SceneObject that can exist in the world at a
|
||||
// 3D position and render itself. Note that RenderObjectExample handles its own
|
||||
// rendering by submitting itself as an ObjectRenderInst (see
|
||||
// renderInstance\renderPassmanager.h) along with a delegate for its render()
|
||||
// function. However, the preffered rendering method in the engine is to submit
|
||||
// a MeshRenderInst along with a Material, vertex buffer, primitive buffer, and
|
||||
// transform and allow the RenderMeshMgr handle the actual rendering. You can
|
||||
// see this implemented in RenderMeshExample.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class RenderObjectExample : public SceneObject
|
||||
{
|
||||
typedef SceneObject Parent;
|
||||
|
||||
// Networking masks
|
||||
// We need to implement at least one of these to allow
|
||||
// the client version of the object to receive updates
|
||||
// from the server version (like if it has been moved
|
||||
// or edited)
|
||||
enum MaskBits
|
||||
{
|
||||
TransformMask = Parent::NextFreeMask << 0,
|
||||
NextFreeMask = Parent::NextFreeMask << 1
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Rendering variables
|
||||
//--------------------------------------------------------------------------
|
||||
// Define our vertex format here so we don't have to
|
||||
// change it in multiple spots later
|
||||
typedef GFXVertexPCN VertexType;
|
||||
|
||||
// The handles for our StateBlocks
|
||||
GFXStateBlockRef mNormalSB;
|
||||
GFXStateBlockRef mReflectSB;
|
||||
|
||||
// The GFX vertex and primitive buffers
|
||||
GFXVertexBufferHandle< VertexType > mVertexBuffer;
|
||||
|
||||
public:
|
||||
RenderObjectExample();
|
||||
virtual ~RenderObjectExample();
|
||||
|
||||
// Declare this object as a ConsoleObject so that we can
|
||||
// instantiate it into the world and network it
|
||||
DECLARE_CONOBJECT(RenderObjectExample);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Object Editing
|
||||
// Since there is always a server and a client object in Torque and we
|
||||
// actually edit the server object we need to implement some basic
|
||||
// networking functions
|
||||
//--------------------------------------------------------------------------
|
||||
// Set up any fields that we want to be editable (like position)
|
||||
static void initPersistFields();
|
||||
|
||||
// Handle when we are added to the scene and removed from the scene
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
|
||||
// Override this so that we can dirty the network flag when it is called
|
||||
void setTransform( const MatrixF &mat );
|
||||
|
||||
// This function handles sending the relevant data from the server
|
||||
// object to the client object
|
||||
U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
|
||||
// This function handles receiving relevant data from the server
|
||||
// object and applying it to the client object
|
||||
void unpackUpdate( NetConnection *conn, BitStream *stream );
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Object Rendering
|
||||
// Torque utilizes a "batch" rendering system. This means that it builds a
|
||||
// list of objects that need to render (via RenderInst's) and then renders
|
||||
// them all in one batch. This allows it to optimized on things like
|
||||
// minimizing texture, state, and shader switching by grouping objects that
|
||||
// use the same Materials. For this example, however, we are just going to
|
||||
// get this object added to the list of objects that handle their own
|
||||
// rendering.
|
||||
//--------------------------------------------------------------------------
|
||||
// Create the geometry for rendering
|
||||
void createGeometry();
|
||||
|
||||
// This is the function that allows this object to submit itself for rendering
|
||||
void prepRenderImage( SceneRenderState *state );
|
||||
|
||||
// This is the function that actually gets called to do the rendering
|
||||
// Note that there is no longer a predefined name for this function.
|
||||
// Instead, when we submit our ObjectRenderInst in prepRenderImage(),
|
||||
// we bind this function as our rendering delegate function
|
||||
void render( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );
|
||||
};
|
||||
|
||||
#endif // _RENDEROBJECTEXAMPLE_H_
|
||||
273
Engine/source/T3D/examples/renderShapeExample.cpp
Normal file
273
Engine/source/T3D/examples/renderShapeExample.cpp
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "T3D/examples/renderShapeExample.h"
|
||||
|
||||
#include "math/mathIO.h"
|
||||
#include "sim/netConnection.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/resourceManager.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "renderInstance/renderPassManager.h"
|
||||
#include "lighting/lightQuery.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(RenderShapeExample);
|
||||
|
||||
ConsoleDocClass( RenderShapeExample,
|
||||
"@brief An example scene object which renders a DTS.\n\n"
|
||||
"This class implements a basic SceneObject that can exist in the world at a "
|
||||
"3D position and render itself. There are several valid ways to render an "
|
||||
"object in Torque. This class makes use of the 'TS' (three space) shape "
|
||||
"system. TS manages loading the various mesh formats supported by Torque as "
|
||||
"well was rendering those meshes (including LOD and animation...though this "
|
||||
"example doesn't include any animation over time).\n\n"
|
||||
"See the C++ code for implementation details.\n\n"
|
||||
"@ingroup Examples\n" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object setup and teardown
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderShapeExample::RenderShapeExample()
|
||||
{
|
||||
// Flag this object so that it will always
|
||||
// be sent across the network to clients
|
||||
mNetFlags.set( Ghostable | ScopeAlways );
|
||||
|
||||
// Set it as a "static" object.
|
||||
mTypeMask |= StaticObjectType | StaticShapeObjectType;
|
||||
|
||||
// Make sure to initialize our TSShapeInstance to NULL
|
||||
mShapeInstance = NULL;
|
||||
}
|
||||
|
||||
RenderShapeExample::~RenderShapeExample()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object Editing
|
||||
//-----------------------------------------------------------------------------
|
||||
void RenderShapeExample::initPersistFields()
|
||||
{
|
||||
addGroup( "Rendering" );
|
||||
addField( "shapeFile", TypeStringFilename, Offset( mShapeFile, RenderShapeExample ),
|
||||
"The path to the DTS shape file." );
|
||||
endGroup( "Rendering" );
|
||||
|
||||
// SceneObject already handles exposing the transform
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void RenderShapeExample::inspectPostApply()
|
||||
{
|
||||
Parent::inspectPostApply();
|
||||
|
||||
// Flag the network mask to send the updates
|
||||
// to the client object
|
||||
setMaskBits( UpdateMask );
|
||||
}
|
||||
|
||||
bool RenderShapeExample::onAdd()
|
||||
{
|
||||
if ( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
// Set up a 1x1x1 bounding box
|
||||
mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ),
|
||||
Point3F( 0.5f, 0.5f, 0.5f ) );
|
||||
|
||||
resetWorldBox();
|
||||
|
||||
// Add this object to the scene
|
||||
addToScene();
|
||||
|
||||
// Setup the shape.
|
||||
createShape();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderShapeExample::onRemove()
|
||||
{
|
||||
// Remove this object from the scene
|
||||
removeFromScene();
|
||||
|
||||
// Remove our TSShapeInstance
|
||||
if ( mShapeInstance )
|
||||
SAFE_DELETE( mShapeInstance );
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
void RenderShapeExample::setTransform(const MatrixF & mat)
|
||||
{
|
||||
// Let SceneObject handle all of the matrix manipulation
|
||||
Parent::setTransform( mat );
|
||||
|
||||
// Dirty our network mask so that the new transform gets
|
||||
// transmitted to the client object
|
||||
setMaskBits( TransformMask );
|
||||
}
|
||||
|
||||
U32 RenderShapeExample::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
|
||||
{
|
||||
// Allow the Parent to get a crack at writing its info
|
||||
U32 retMask = Parent::packUpdate( conn, mask, stream );
|
||||
|
||||
// Write our transform information
|
||||
if ( stream->writeFlag( mask & TransformMask ) )
|
||||
{
|
||||
mathWrite(*stream, getTransform());
|
||||
mathWrite(*stream, getScale());
|
||||
}
|
||||
|
||||
// Write out any of the updated editable properties
|
||||
if ( stream->writeFlag( mask & UpdateMask ) )
|
||||
{
|
||||
stream->write( mShapeFile );
|
||||
|
||||
// Allow the server object a chance to handle a new shape
|
||||
createShape();
|
||||
}
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
void RenderShapeExample::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||
{
|
||||
// Let the Parent read any info it sent
|
||||
Parent::unpackUpdate(conn, stream);
|
||||
|
||||
if ( stream->readFlag() ) // TransformMask
|
||||
{
|
||||
mathRead(*stream, &mObjToWorld);
|
||||
mathRead(*stream, &mObjScale);
|
||||
|
||||
setTransform( mObjToWorld );
|
||||
}
|
||||
|
||||
if ( stream->readFlag() ) // UpdateMask
|
||||
{
|
||||
stream->read( &mShapeFile );
|
||||
|
||||
if ( isProperlyAdded() )
|
||||
createShape();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object Rendering
|
||||
//-----------------------------------------------------------------------------
|
||||
void RenderShapeExample::createShape()
|
||||
{
|
||||
if ( mShapeFile.isEmpty() )
|
||||
return;
|
||||
|
||||
// If this is the same shape then no reason to update it
|
||||
if ( mShapeInstance && mShapeFile.equal( mShape.getPath().getFullPath(), String::NoCase ) )
|
||||
return;
|
||||
|
||||
// Clean up our previous shape
|
||||
if ( mShapeInstance )
|
||||
SAFE_DELETE( mShapeInstance );
|
||||
mShape = NULL;
|
||||
|
||||
// Attempt to get the resource from the ResourceManager
|
||||
mShape = ResourceManager::get().load( mShapeFile );
|
||||
|
||||
if ( !mShape )
|
||||
{
|
||||
Con::errorf( "RenderShapeExample::createShape() - Unable to load shape: %s", mShapeFile.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
// Attempt to preload the Materials for this shape
|
||||
if ( isClientObject() &&
|
||||
!mShape->preloadMaterialList( mShape.getPath() ) &&
|
||||
NetConnection::filesWereDownloaded() )
|
||||
{
|
||||
mShape = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the bounding box
|
||||
mObjBox = mShape->bounds;
|
||||
resetWorldBox();
|
||||
setRenderTransform(mObjToWorld);
|
||||
|
||||
// Create the TSShapeInstance
|
||||
mShapeInstance = new TSShapeInstance( mShape, isClientObject() );
|
||||
}
|
||||
|
||||
void RenderShapeExample::prepRenderImage( SceneRenderState *state )
|
||||
{
|
||||
// Make sure we have a TSShapeInstance
|
||||
if ( !mShapeInstance )
|
||||
return;
|
||||
|
||||
// Calculate the distance of this object from the camera
|
||||
Point3F cameraOffset;
|
||||
getRenderTransform().getColumn( 3, &cameraOffset );
|
||||
cameraOffset -= state->getDiffuseCameraPosition();
|
||||
F32 dist = cameraOffset.len();
|
||||
if ( dist < 0.01f )
|
||||
dist = 0.01f;
|
||||
|
||||
// Set up the LOD for the shape
|
||||
F32 invScale = ( 1.0f / getMax( getMax( mObjScale.x, mObjScale.y ), mObjScale.z ) );
|
||||
|
||||
mShapeInstance->setDetailFromDistance( state, dist * invScale );
|
||||
|
||||
// Make sure we have a valid level of detail
|
||||
if ( mShapeInstance->getCurrentDetail() < 0 )
|
||||
return;
|
||||
|
||||
// GFXTransformSaver is a handy helper class that restores
|
||||
// the current GFX matrices to their original values when
|
||||
// it goes out of scope at the end of the function
|
||||
GFXTransformSaver saver;
|
||||
|
||||
// Set up our TS render state
|
||||
TSRenderState rdata;
|
||||
rdata.setSceneState( state );
|
||||
rdata.setFadeOverride( 1.0f );
|
||||
|
||||
// We might have some forward lit materials
|
||||
// so pass down a query to gather lights.
|
||||
LightQuery query;
|
||||
query.init( getWorldSphere() );
|
||||
rdata.setLightQuery( &query );
|
||||
|
||||
// Set the world matrix to the objects render transform
|
||||
MatrixF mat = getRenderTransform();
|
||||
mat.scale( mObjScale );
|
||||
GFX->setWorldMatrix( mat );
|
||||
|
||||
// Animate the the shape
|
||||
mShapeInstance->animate();
|
||||
|
||||
// Allow the shape to submit the RenderInst(s) for itself
|
||||
mShapeInstance->render( rdata );
|
||||
}
|
||||
119
Engine/source/T3D/examples/renderShapeExample.h
Normal file
119
Engine/source/T3D/examples/renderShapeExample.h
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _RENDERSHAPEEXAMPLE_H_
|
||||
#define _RENDERSHAPEEXAMPLE_H_
|
||||
|
||||
#ifndef _SCENEOBJECT_H_
|
||||
#include "scene/sceneObject.h"
|
||||
#endif
|
||||
#ifndef _TSSHAPEINSTANCE_H_
|
||||
#include "ts/tsShapeInstance.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This class implements a basic SceneObject that can exist in the world at a
|
||||
// 3D position and render itself. There are several valid ways to render an
|
||||
// object in Torque. This class makes use of the "TS" (three space) shape
|
||||
// system. TS manages loading the various mesh formats supported by Torque as
|
||||
// well was rendering those meshes (including LOD and animation...though this
|
||||
// example doesn't include any animation over time).
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class RenderShapeExample : public SceneObject
|
||||
{
|
||||
typedef SceneObject Parent;
|
||||
|
||||
// Networking masks
|
||||
// We need to implement a mask specifically to handle
|
||||
// updating our transform from the server object to its
|
||||
// client-side "ghost". We also need to implement a
|
||||
// maks for handling editor updates to our properties
|
||||
// (like material).
|
||||
enum MaskBits
|
||||
{
|
||||
TransformMask = Parent::NextFreeMask << 0,
|
||||
UpdateMask = Parent::NextFreeMask << 1,
|
||||
NextFreeMask = Parent::NextFreeMask << 2
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Rendering variables
|
||||
//--------------------------------------------------------------------------
|
||||
// The name of the shape file we will use for rendering
|
||||
String mShapeFile;
|
||||
// The actual shape instance
|
||||
TSShapeInstance* mShapeInstance;
|
||||
// Store the resource so we can access the filename later
|
||||
Resource<TSShape> mShape;
|
||||
|
||||
public:
|
||||
RenderShapeExample();
|
||||
virtual ~RenderShapeExample();
|
||||
|
||||
// Declare this object as a ConsoleObject so that we can
|
||||
// instantiate it into the world and network it
|
||||
DECLARE_CONOBJECT(RenderShapeExample);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Object Editing
|
||||
// Since there is always a server and a client object in Torque and we
|
||||
// actually edit the server object we need to implement some basic
|
||||
// networking functions
|
||||
//--------------------------------------------------------------------------
|
||||
// Set up any fields that we want to be editable (like position)
|
||||
static void initPersistFields();
|
||||
|
||||
// Allows the object to update its editable settings
|
||||
// from the server object to the client
|
||||
virtual void inspectPostApply();
|
||||
|
||||
// Handle when we are added to the scene and removed from the scene
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
|
||||
// Override this so that we can dirty the network flag when it is called
|
||||
void setTransform( const MatrixF &mat );
|
||||
|
||||
// This function handles sending the relevant data from the server
|
||||
// object to the client object
|
||||
U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
|
||||
// This function handles receiving relevant data from the server
|
||||
// object and applying it to the client object
|
||||
void unpackUpdate( NetConnection *conn, BitStream *stream );
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Object Rendering
|
||||
// Torque utilizes a "batch" rendering system. This means that it builds a
|
||||
// list of objects that need to render (via RenderInst's) and then renders
|
||||
// them all in one batch. This allows it to optimized on things like
|
||||
// minimizing texture, state, and shader switching by grouping objects that
|
||||
// use the same Materials.
|
||||
//--------------------------------------------------------------------------
|
||||
// Create the geometry for rendering
|
||||
void createShape();
|
||||
|
||||
// This is the function that allows this object to submit itself for rendering
|
||||
void prepRenderImage( SceneRenderState *state );
|
||||
};
|
||||
|
||||
#endif // _RENDERSHAPEEXAMPLE_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue