mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 03:33:48 +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
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 );
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue