renderObjectExample.cpp
Engine/source/T3D/examples/renderObjectExample.cpp
Public Functions
ConsoleDocClass(RenderObjectExample , "@brief An example scene object which renders using <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">callback.\n\n</a>" "This class implements <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> basic <a href="/coding/class/classsceneobject/">SceneObject</a> that can exist in the world at <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> " "3D position and <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> itself. Note that <a href="/coding/class/classrenderobjectexample/">RenderObjectExample</a> handles its own " "rendering by submitting itself as an <a href="/coding/class/structobjectrenderinst/">ObjectRenderInst</a> (see " "renderInstance\renderPassmanager.h) along with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> delegate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> its <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a>() " "function. However, the preffered rendering method in the engine is <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> submit " "<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/structmeshrenderinst/">MeshRenderInst</a> along with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> Material, vertex buffer, primitive buffer, and " "transform and allow the <a href="/coding/class/classrendermeshmgr/">RenderMeshMgr</a> handle the actual rendering. You can " "see this implemented in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">RenderMeshExample.\n\n</a>" "See the C++code <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> implementation <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">details.\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Examples\n</a>" )
Detailed Description
Public Functions
ConsoleDocClass(RenderObjectExample , "@brief An example scene object which renders using <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">callback.\n\n</a>" "This class implements <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> basic <a href="/coding/class/classsceneobject/">SceneObject</a> that can exist in the world at <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> " "3D position and <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> itself. Note that <a href="/coding/class/classrenderobjectexample/">RenderObjectExample</a> handles its own " "rendering by submitting itself as an <a href="/coding/class/structobjectrenderinst/">ObjectRenderInst</a> (see " "renderInstance\renderPassmanager.h) along with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> delegate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> its <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a>() " "function. However, the preffered rendering method in the engine is <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> submit " "<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/structmeshrenderinst/">MeshRenderInst</a> along with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> Material, vertex buffer, primitive buffer, and " "transform and allow the <a href="/coding/class/classrendermeshmgr/">RenderMeshMgr</a> handle the actual rendering. You can " "see this implemented in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">RenderMeshExample.\n\n</a>" "See the C++code <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> implementation <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">details.\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Examples\n</a>" )
IMPLEMENT_CO_NETOBJECT_V1(RenderObjectExample )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "T3D/examples/renderObjectExample.h" 25 26#include "math/mathIO.h" 27#include "scene/sceneRenderState.h" 28#include "core/stream/bitStream.h" 29#include "materials/sceneData.h" 30#include "gfx/gfxDebugEvent.h" 31#include "gfx/gfxTransformSaver.h" 32#include "renderInstance/renderPassManager.h" 33 34 35IMPLEMENT_CO_NETOBJECT_V1(RenderObjectExample); 36 37ConsoleDocClass( RenderObjectExample, 38 "@brief An example scene object which renders using a callback.\n\n" 39 "This class implements a basic SceneObject that can exist in the world at a " 40 "3D position and render itself. Note that RenderObjectExample handles its own " 41 "rendering by submitting itself as an ObjectRenderInst (see " 42 "renderInstance\renderPassmanager.h) along with a delegate for its render() " 43 "function. However, the preffered rendering method in the engine is to submit " 44 "a MeshRenderInst along with a Material, vertex buffer, primitive buffer, and " 45 "transform and allow the RenderMeshMgr handle the actual rendering. You can " 46 "see this implemented in RenderMeshExample.\n\n" 47 "See the C++ code for implementation details.\n\n" 48 "@ingroup Examples\n" ); 49 50//----------------------------------------------------------------------------- 51// Object setup and teardown 52//----------------------------------------------------------------------------- 53RenderObjectExample::RenderObjectExample() 54{ 55 // Flag this object so that it will always 56 // be sent across the network to clients 57 mNetFlags.set( Ghostable | ScopeAlways ); 58 59 // Set it as a "static" object 60 mTypeMask |= StaticObjectType | StaticShapeObjectType; 61} 62 63RenderObjectExample::~RenderObjectExample() 64{ 65} 66 67//----------------------------------------------------------------------------- 68// Object Editing 69//----------------------------------------------------------------------------- 70void RenderObjectExample::initPersistFields() 71{ 72 // SceneObject already handles exposing the transform 73 Parent::initPersistFields(); 74} 75 76bool RenderObjectExample::onAdd() 77{ 78 if ( !Parent::onAdd() ) 79 return false; 80 81 // Set up a 1x1x1 bounding box 82 mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ), 83 Point3F( 0.5f, 0.5f, 0.5f ) ); 84 85 resetWorldBox(); 86 87 // Add this object to the scene 88 addToScene(); 89 90 return true; 91} 92 93void RenderObjectExample::onRemove() 94{ 95 // Remove this object from the scene 96 removeFromScene(); 97 98 Parent::onRemove(); 99} 100 101void RenderObjectExample::setTransform(const MatrixF & mat) 102{ 103 // Let SceneObject handle all of the matrix manipulation 104 Parent::setTransform( mat ); 105 106 // Dirty our network mask so that the new transform gets 107 // transmitted to the client object 108 setMaskBits( TransformMask ); 109} 110 111U32 RenderObjectExample::packUpdate( NetConnection *conn, U32 mask, BitStream *stream ) 112{ 113 // Allow the Parent to get a crack at writing its info 114 U32 retMask = Parent::packUpdate( conn, mask, stream ); 115 116 // Write our transform information 117 if ( stream->writeFlag( mask & TransformMask ) ) 118 { 119 mathWrite(*stream, getTransform()); 120 mathWrite(*stream, getScale()); 121 } 122 123 return retMask; 124} 125 126void RenderObjectExample::unpackUpdate(NetConnection *conn, BitStream *stream) 127{ 128 // Let the Parent read any info it sent 129 Parent::unpackUpdate(conn, stream); 130 131 if ( stream->readFlag() ) // TransformMask 132 { 133 mathRead(*stream, &mObjToWorld); 134 mathRead(*stream, &mObjScale); 135 136 setTransform( mObjToWorld ); 137 } 138} 139 140//----------------------------------------------------------------------------- 141// Object Rendering 142//----------------------------------------------------------------------------- 143void RenderObjectExample::createGeometry() 144{ 145 static const Point3F cubePoints[8] = 146 { 147 Point3F( 1.0f, -1.0f, -1.0f), Point3F( 1.0f, -1.0f, 1.0f), 148 Point3F( 1.0f, 1.0f, -1.0f), Point3F( 1.0f, 1.0f, 1.0f), 149 Point3F(-1.0f, -1.0f, -1.0f), Point3F(-1.0f, 1.0f, -1.0f), 150 Point3F(-1.0f, -1.0f, 1.0f), Point3F(-1.0f, 1.0f, 1.0f) 151 }; 152 153 static const Point3F cubeNormals[6] = 154 { 155 Point3F( 1.0f, 0.0f, 0.0f), Point3F(-1.0f, 0.0f, 0.0f), 156 Point3F( 0.0f, 1.0f, 0.0f), Point3F( 0.0f, -1.0f, 0.0f), 157 Point3F( 0.0f, 0.0f, 1.0f), Point3F( 0.0f, 0.0f, -1.0f) 158 }; 159 160 static const ColorI cubeColors[3] = 161 { 162 ColorI( 255, 0, 0, 255 ), 163 ColorI( 0, 255, 0, 255 ), 164 ColorI( 0, 0, 255, 255 ) 165 }; 166 167 static const U32 cubeFaces[36][3] = 168 { 169 { 3, 0, 0 }, { 0, 0, 0 }, { 1, 0, 0 }, 170 { 2, 0, 0 }, { 0, 0, 0 }, { 3, 0, 0 }, 171 { 7, 1, 0 }, { 4, 1, 0 }, { 5, 1, 0 }, 172 { 6, 1, 0 }, { 4, 1, 0 }, { 7, 1, 0 }, 173 { 3, 2, 1 }, { 5, 2, 1 }, { 2, 2, 1 }, 174 { 7, 2, 1 }, { 5, 2, 1 }, { 3, 2, 1 }, 175 { 1, 3, 1 }, { 4, 3, 1 }, { 6, 3, 1 }, 176 { 0, 3, 1 }, { 4, 3, 1 }, { 1, 3, 1 }, 177 { 3, 4, 2 }, { 6, 4, 2 }, { 7, 4, 2 }, 178 { 1, 4, 2 }, { 6, 4, 2 }, { 3, 4, 2 }, 179 { 2, 5, 2 }, { 4, 5, 2 }, { 0, 5, 2 }, 180 { 5, 5, 2 }, { 4, 5, 2 }, { 2, 5, 2 } 181 }; 182 183 // Fill the vertex buffer 184 VertexType *pVert = NULL; 185 186 mVertexBuffer.set( GFX, 36, GFXBufferTypeStatic ); 187 pVert = mVertexBuffer.lock(); 188 189 Point3F halfSize = getObjBox().getExtents() * 0.5f; 190 191 for (U32 i = 0; i < 36; i++) 192 { 193 const U32& vdx = cubeFaces[i][0]; 194 const U32& ndx = cubeFaces[i][1]; 195 const U32& cdx = cubeFaces[i][2]; 196 197 pVert[i].point = cubePoints[vdx] * halfSize; 198 pVert[i].normal = cubeNormals[ndx]; 199 pVert[i].color = cubeColors[cdx]; 200 } 201 202 mVertexBuffer.unlock(); 203 204 // Set up our normal and reflection StateBlocks 205 GFXStateBlockDesc desc; 206 207 // The normal StateBlock only needs a default StateBlock 208 mNormalSB = GFX->createStateBlock( desc ); 209 210 // The reflection needs its culling reversed 211 desc.cullDefined = true; 212 desc.cullMode = GFXCullCW; 213 mReflectSB = GFX->createStateBlock( desc ); 214} 215 216void RenderObjectExample::prepRenderImage( SceneRenderState *state ) 217{ 218 // Do a little prep work if needed 219 if ( mVertexBuffer.isNull() ) 220 createGeometry(); 221 222 // Allocate an ObjectRenderInst so that we can submit it to the RenderPassManager 223 ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>(); 224 225 // Now bind our rendering function so that it will get called 226 ri->renderDelegate.bind( this, &RenderObjectExample::render ); 227 228 // Set our RenderInst as a standard object render 229 ri->type = RenderPassManager::RIT_Object; 230 231 // Set our sorting keys to a default value 232 ri->defaultKey = 0; 233 ri->defaultKey2 = 0; 234 235 // Submit our RenderInst to the RenderPassManager 236 state->getRenderPass()->addInst( ri ); 237} 238 239void RenderObjectExample::render( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) 240{ 241 if ( overrideMat ) 242 return; 243 244 if ( mVertexBuffer.isNull() ) 245 return; 246 247 PROFILE_SCOPE(RenderObjectExample_Render); 248 249 // Set up a GFX debug event (this helps with debugging rendering events in external tools) 250 GFXDEBUGEVENT_SCOPE( RenderObjectExample_Render, ColorI::RED ); 251 252 // GFXTransformSaver is a handy helper class that restores 253 // the current GFX matrices to their original values when 254 // it goes out of scope at the end of the function 255 GFXTransformSaver saver; 256 257 // Calculate our object to world transform matrix 258 MatrixF objectToWorld = getRenderTransform(); 259 objectToWorld.scale( getScale() ); 260 261 // Apply our object transform 262 GFX->multWorld( objectToWorld ); 263 264 // Deal with reflect pass otherwise 265 // set the normal StateBlock 266 if ( state->isReflectPass() ) 267 GFX->setStateBlock( mReflectSB ); 268 else 269 GFX->setStateBlock( mNormalSB ); 270 271 // Set up the "generic" shaders 272 // These handle rendering on GFX layers that don't support 273 // fixed function. Otherwise they disable shaders. 274 GFX->setupGenericShaders( GFXDevice::GSModColorTexture ); 275 276 // Set the vertex buffer 277 GFX->setVertexBuffer( mVertexBuffer ); 278 279 // Draw our triangles 280 GFX->drawPrimitive( GFXTriangleList, 0, 12 ); 281} 282