renderObjectExample.cpp 9.1 KB

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