renderMeshExample.cpp
Engine/source/T3D/examples/renderMeshExample.cpp
Public Functions
ConsoleDocClass(RenderMeshExample , "@brief An example scene object which renders <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">mesh.\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. There are several valid ways <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> an " "object in Torque. This class implements the preferred rendering method which " "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 setup and rendering <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">you.\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>" )
DefineEngineMethod(RenderMeshExample , postApply , void , () , "A utility method <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> forcing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> network <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">update.\n</a>" )
Detailed Description
Public Functions
ConsoleDocClass(RenderMeshExample , "@brief An example scene object which renders <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">mesh.\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. There are several valid ways <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> an " "object in Torque. This class implements the preferred rendering method which " "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 setup and rendering <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">you.\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>" )
DefineEngineMethod(RenderMeshExample , postApply , void , () , "A utility method <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> forcing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> network <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">update.\n</a>" )
IMPLEMENT_CO_NETOBJECT_V1(RenderMeshExample )
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 "platform/platform.h" 25#include "T3D/examples/renderMeshExample.h" 26 27#include "math/mathIO.h" 28#include "scene/sceneRenderState.h" 29#include "console/consoleTypes.h" 30#include "core/stream/bitStream.h" 31#include "materials/materialManager.h" 32#include "materials/baseMatInstance.h" 33#include "renderInstance/renderPassManager.h" 34#include "lighting/lightQuery.h" 35#include "console/engineAPI.h" 36 37IMPLEMENT_CO_NETOBJECT_V1(RenderMeshExample); 38 39ConsoleDocClass( RenderMeshExample, 40 "@brief An example scene object which renders a mesh.\n\n" 41 "This class implements a basic SceneObject that can exist in the world at a " 42 "3D position and render itself. There are several valid ways to render an " 43 "object in Torque. This class implements the preferred rendering method which " 44 "is to submit a MeshRenderInst along with a Material, vertex buffer, " 45 "primitive buffer, and transform and allow the RenderMeshMgr handle the " 46 "actual setup and rendering for you.\n\n" 47 "See the C++ code for implementation details.\n\n" 48 "@ingroup Examples\n" ); 49 50 51//----------------------------------------------------------------------------- 52// Object setup and teardown 53//----------------------------------------------------------------------------- 54RenderMeshExample::RenderMeshExample() 55{ 56 // Flag this object so that it will always 57 // be sent across the network to clients 58 mNetFlags.set( Ghostable | ScopeAlways ); 59 60 // Set it as a "static" object that casts shadows 61 mTypeMask |= StaticObjectType | StaticShapeObjectType; 62 63 // Make sure we the Material instance to NULL 64 // so we don't try to access it incorrectly 65 mMaterialInst = NULL; 66 67 initMaterialAsset(Material); 68} 69 70RenderMeshExample::~RenderMeshExample() 71{ 72 if ( mMaterialInst ) 73 SAFE_DELETE( mMaterialInst ); 74} 75 76//----------------------------------------------------------------------------- 77// Object Editing 78//----------------------------------------------------------------------------- 79void RenderMeshExample::initPersistFields() 80{ 81 addGroup( "Rendering" ); 82 scriptBindMaterialAsset(Material, RenderMeshExample, "The material used to render the mesh."); 83 endGroup( "Rendering" ); 84 85 // SceneObject already handles exposing the transform 86 Parent::initPersistFields(); 87} 88 89void RenderMeshExample::inspectPostApply() 90{ 91 Parent::inspectPostApply(); 92 93 // Flag the network mask to send the updates 94 // to the client object 95 setMaskBits( UpdateMask ); 96} 97 98bool RenderMeshExample::onAdd() 99{ 100 if ( !Parent::onAdd() ) 101 return false; 102 103 // Set up a 1x1x1 bounding box 104 mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ), 105 Point3F( 0.5f, 0.5f, 0.5f ) ); 106 107 resetWorldBox(); 108 109 // Add this object to the scene 110 addToScene(); 111 112 // Refresh this object's material (if any) 113 updateMaterial(); 114 115 return true; 116} 117 118void RenderMeshExample::onRemove() 119{ 120 // Remove this object from the scene 121 removeFromScene(); 122 123 Parent::onRemove(); 124} 125 126void RenderMeshExample::setTransform(const MatrixF & mat) 127{ 128 // Let SceneObject handle all of the matrix manipulation 129 Parent::setTransform( mat ); 130 131 // Dirty our network mask so that the new transform gets 132 // transmitted to the client object 133 setMaskBits( TransformMask ); 134} 135 136U32 RenderMeshExample::packUpdate( NetConnection *conn, U32 mask, BitStream *stream ) 137{ 138 // Allow the Parent to get a crack at writing its info 139 U32 retMask = Parent::packUpdate( conn, mask, stream ); 140 141 // Write our transform information 142 if ( stream->writeFlag( mask & TransformMask ) ) 143 { 144 mathWrite(*stream, getTransform()); 145 mathWrite(*stream, getScale()); 146 } 147 148 // Write out any of the updated editable properties 149 if (stream->writeFlag(mask & UpdateMask)) 150 { 151 packMaterialAsset(conn, Material); 152 } 153 154 return retMask; 155} 156 157void RenderMeshExample::unpackUpdate(NetConnection *conn, BitStream *stream) 158{ 159 // Let the Parent read any info it sent 160 Parent::unpackUpdate(conn, stream); 161 162 if ( stream->readFlag() ) // TransformMask 163 { 164 mathRead(*stream, &mObjToWorld); 165 mathRead(*stream, &mObjScale); 166 167 setTransform( mObjToWorld ); 168 } 169 170 if ( stream->readFlag() ) // UpdateMask 171 { 172 unpackMaterialAsset(conn, Material); 173 174 if ( isProperlyAdded() ) 175 updateMaterial(); 176 } 177} 178 179//----------------------------------------------------------------------------- 180// Object Rendering 181//----------------------------------------------------------------------------- 182void RenderMeshExample::createGeometry() 183{ 184 static const Point3F cubePoints[8] = 185 { 186 Point3F( 1, -1, -1), Point3F( 1, -1, 1), Point3F( 1, 1, -1), Point3F( 1, 1, 1), 187 Point3F(-1, -1, -1), Point3F(-1, 1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, 1) 188 }; 189 190 static const Point3F cubeNormals[6] = 191 { 192 Point3F( 1, 0, 0), Point3F(-1, 0, 0), Point3F( 0, 1, 0), 193 Point3F( 0, -1, 0), Point3F( 0, 0, 1), Point3F( 0, 0, -1) 194 }; 195 196 static const Point2F cubeTexCoords[4] = 197 { 198 Point2F( 0, 0), Point2F( 0, -1), 199 Point2F( 1, 0), Point2F( 1, -1) 200 }; 201 202 static const U32 cubeFaces[36][3] = 203 { 204 { 3, 0, 3 }, { 0, 0, 0 }, { 1, 0, 1 }, 205 { 2, 0, 2 }, { 0, 0, 0 }, { 3, 0, 3 }, 206 { 7, 1, 1 }, { 4, 1, 2 }, { 5, 1, 0 }, 207 { 6, 1, 3 }, { 4, 1, 2 }, { 7, 1, 1 }, 208 { 3, 2, 1 }, { 5, 2, 2 }, { 2, 2, 0 }, 209 { 7, 2, 3 }, { 5, 2, 2 }, { 3, 2, 1 }, 210 { 1, 3, 3 }, { 4, 3, 0 }, { 6, 3, 1 }, 211 { 0, 3, 2 }, { 4, 3, 0 }, { 1, 3, 3 }, 212 { 3, 4, 3 }, { 6, 4, 0 }, { 7, 4, 1 }, 213 { 1, 4, 2 }, { 6, 4, 0 }, { 3, 4, 3 }, 214 { 2, 5, 1 }, { 4, 5, 2 }, { 0, 5, 0 }, 215 { 5, 5, 3 }, { 4, 5, 2 }, { 2, 5, 1 } 216 }; 217 218 // Fill the vertex buffer 219 VertexType *pVert = NULL; 220 221 mVertexBuffer.set( GFX, 36, GFXBufferTypeStatic ); 222 pVert = mVertexBuffer.lock(); 223 224 Point3F halfSize = getObjBox().getExtents() * 0.5f; 225 226 for (U32 i = 0; i < 36; i++) 227 { 228 const U32& vdx = cubeFaces[i][0]; 229 const U32& ndx = cubeFaces[i][1]; 230 const U32& tdx = cubeFaces[i][2]; 231 232 pVert[i].point = cubePoints[vdx] * halfSize; 233 pVert[i].normal = cubeNormals[ndx]; 234 pVert[i].texCoord = cubeTexCoords[tdx]; 235 } 236 237 mVertexBuffer.unlock(); 238 239 // Fill the primitive buffer 240 U16 *pIdx = NULL; 241 242 mPrimitiveBuffer.set( GFX, 36, 12, GFXBufferTypeStatic ); 243 244 mPrimitiveBuffer.lock(&pIdx); 245 246 for (U16 i = 0; i < 36; i++) 247 pIdx[i] = i; 248 249 mPrimitiveBuffer.unlock(); 250} 251 252void RenderMeshExample::updateMaterial() 253{ 254 if (mMaterialAsset.notNull()) 255 { 256 if (mMaterialInst && String(mMaterialAsset->getMaterialDefinitionName()).equal(mMaterialInst->getMaterial()->getName(), String::NoCase)) 257 return; 258 259 SAFE_DELETE(mMaterialInst); 260 261 mMaterialInst = MATMGR->createMatInstance(mMaterialAsset->getMaterialDefinitionName(), getGFXVertexFormat< VertexType >()); 262 263 if (!mMaterialInst) 264 Con::errorf("RenderMeshExample::updateMaterial - no Material called '%s'", mMaterialAsset->getMaterialDefinitionName()); 265 } 266} 267 268void RenderMeshExample::prepRenderImage( SceneRenderState *state ) 269{ 270 // Do a little prep work if needed 271 if ( mVertexBuffer.isNull() ) 272 createGeometry(); 273 274 // If we have no material then skip out. 275 if ( !mMaterialInst || !state) 276 return; 277 278 // If we don't have a material instance after the override then 279 // we can skip rendering all together. 280 BaseMatInstance *matInst = state->getOverrideMaterial( mMaterialInst ); 281 if ( !matInst ) 282 return; 283 284 // Get a handy pointer to our RenderPassmanager 285 RenderPassManager *renderPass = state->getRenderPass(); 286 287 // Allocate an MeshRenderInst so that we can submit it to the RenderPassManager 288 MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>(); 289 290 // Set our RenderInst as a standard mesh render 291 ri->type = RenderPassManager::RIT_Mesh; 292 293 //If our material has transparency set on this will redirect it to proper render bin 294 if ( matInst->getMaterial()->isTranslucent() ) 295 { 296 ri->type = RenderPassManager::RIT_Translucent; 297 ri->translucentSort = true; 298 } 299 300 // Calculate our sorting point 301 if ( state ) 302 { 303 // Calculate our sort point manually. 304 const Box3F& rBox = getRenderWorldBox(); 305 ri->sortDistSq = rBox.getSqDistanceToPoint( state->getCameraPosition() ); 306 } 307 else 308 ri->sortDistSq = 0.0f; 309 310 // Set up our transforms 311 MatrixF objectToWorld = getRenderTransform(); 312 objectToWorld.scale( getScale() ); 313 314 ri->objectToWorld = renderPass->allocUniqueXform( objectToWorld ); 315 ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View); 316 ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection); 317 318 // If our material needs lights then fill the RIs 319 // light vector with the best lights. 320 if ( matInst->isForwardLit() ) 321 { 322 LightQuery query; 323 query.init( getWorldSphere() ); 324 query.getLights( ri->lights, 8 ); 325 } 326 327 // Make sure we have an up-to-date backbuffer in case 328 // our Material would like to make use of it 329 // NOTICE: SFXBB is removed and refraction is disabled! 330 //ri->backBuffTex = GFX->getSfxBackBuffer(); 331 332 // Set our Material 333 ri->matInst = matInst; 334 335 // Set up our vertex buffer and primitive buffer 336 ri->vertBuff = &mVertexBuffer; 337 ri->primBuff = &mPrimitiveBuffer; 338 339 ri->prim = renderPass->allocPrim(); 340 ri->prim->type = GFXTriangleList; 341 ri->prim->minIndex = 0; 342 ri->prim->startIndex = 0; 343 ri->prim->numPrimitives = 12; 344 ri->prim->startVertex = 0; 345 ri->prim->numVertices = 36; 346 347 // We sort by the material then vertex buffer 348 ri->defaultKey = matInst->getStateHint(); 349 ri->defaultKey2 = (uintptr_t)ri->vertBuff; // Not 64bit safe! 350 351 // Submit our RenderInst to the RenderPassManager 352 state->getRenderPass()->addInst( ri ); 353} 354 355DefineEngineMethod( RenderMeshExample, postApply, void, (),, 356 "A utility method for forcing a network update.\n") 357{ 358 object->inspectPostApply(); 359} 360