CppRenderClassFile.cpp.template 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #include "@.h"
  2. #include "platform/platform.h"
  3. #include "math/mathIO.h"
  4. #include "scene/sceneRenderState.h"
  5. #include "console/consoleTypes.h"
  6. #include "core/stream/bitStream.h"
  7. #include "materials/materialManager.h"
  8. #include "materials/baseMatInstance.h"
  9. #include "renderInstance/renderPassManager.h"
  10. #include "lighting/lightQuery.h"
  11. #include "console/engineAPI.h"
  12. IMPLEMENT_CO_NETOBJECT_V1(@);
  13. ConsoleDocClass( @,
  14. "@brief An example scene object which renders a mesh.\n\n" );
  15. //-----------------------------------------------------------------------------
  16. // Object setup and teardown
  17. //-----------------------------------------------------------------------------
  18. @::@()
  19. {
  20. // Flag this object so that it will always
  21. // be sent across the network to clients
  22. mNetFlags.set( Ghostable | ScopeAlways );
  23. // Set it as a "static" object that casts shadows
  24. mTypeMask |= StaticObjectType | StaticShapeObjectType;
  25. // Make sure we the Material instance to NULL
  26. // so we don't try to access it incorrectly
  27. mMaterialInst = NULL;
  28. }
  29. @::~@()
  30. {
  31. if ( mMaterialInst )
  32. SAFE_DELETE( mMaterialInst );
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Object Editing
  36. //-----------------------------------------------------------------------------
  37. void @::initPersistFields()
  38. {
  39. addGroup( "Rendering" );
  40. addField( "material", TypeMaterialName, Offset( mMaterialName, @ ),
  41. "The name of the material used to render the mesh." );
  42. endGroup( "Rendering" );
  43. // SceneObject already handles exposing the transform
  44. Parent::initPersistFields();
  45. }
  46. void @::inspectPostApply()
  47. {
  48. Parent::inspectPostApply();
  49. // Flag the network mask to send the updates
  50. // to the client object
  51. setMaskBits( UpdateMask );
  52. }
  53. bool @::onAdd()
  54. {
  55. if ( !Parent::onAdd() )
  56. return false;
  57. // Set up a 1x1x1 bounding box
  58. mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ),
  59. Point3F( 0.5f, 0.5f, 0.5f ) );
  60. resetWorldBox();
  61. // Add this object to the scene
  62. addToScene();
  63. // Refresh this object's material (if any)
  64. updateMaterial();
  65. return true;
  66. }
  67. void @::onRemove()
  68. {
  69. // Remove this object from the scene
  70. removeFromScene();
  71. Parent::onRemove();
  72. }
  73. void @::setTransform(const MatrixF & mat)
  74. {
  75. // Let SceneObject handle all of the matrix manipulation
  76. Parent::setTransform( mat );
  77. // Dirty our network mask so that the new transform gets
  78. // transmitted to the client object
  79. setMaskBits( TransformMask );
  80. }
  81. U32 @::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
  82. {
  83. // Allow the Parent to get a crack at writing its info
  84. U32 retMask = Parent::packUpdate( conn, mask, stream );
  85. // Write our transform information
  86. if ( stream->writeFlag( mask & TransformMask ) )
  87. {
  88. mathWrite(*stream, getTransform());
  89. mathWrite(*stream, getScale());
  90. }
  91. // Write out any of the updated editable properties
  92. if ( stream->writeFlag( mask & UpdateMask ) )
  93. stream->write( mMaterialName );
  94. return retMask;
  95. }
  96. void @::unpackUpdate(NetConnection *conn, BitStream *stream)
  97. {
  98. // Let the Parent read any info it sent
  99. Parent::unpackUpdate(conn, stream);
  100. if ( stream->readFlag() ) // TransformMask
  101. {
  102. mathRead(*stream, &mObjToWorld);
  103. mathRead(*stream, &mObjScale);
  104. setTransform( mObjToWorld );
  105. }
  106. if ( stream->readFlag() ) // UpdateMask
  107. {
  108. stream->read( &mMaterialName );
  109. if ( isProperlyAdded() )
  110. updateMaterial();
  111. }
  112. }
  113. //-----------------------------------------------------------------------------
  114. // Object Rendering
  115. //-----------------------------------------------------------------------------
  116. void @::createGeometry()
  117. {
  118. static const Point3F cubePoints[8] =
  119. {
  120. Point3F( 1, -1, -1), Point3F( 1, -1, 1), Point3F( 1, 1, -1), Point3F( 1, 1, 1),
  121. Point3F(-1, -1, -1), Point3F(-1, 1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, 1)
  122. };
  123. static const Point3F cubeNormals[6] =
  124. {
  125. Point3F( 1, 0, 0), Point3F(-1, 0, 0), Point3F( 0, 1, 0),
  126. Point3F( 0, -1, 0), Point3F( 0, 0, 1), Point3F( 0, 0, -1)
  127. };
  128. static const Point2F cubeTexCoords[4] =
  129. {
  130. Point2F( 0, 0), Point2F( 0, -1),
  131. Point2F( 1, 0), Point2F( 1, -1)
  132. };
  133. static const U32 cubeFaces[36][3] =
  134. {
  135. { 3, 0, 3 }, { 0, 0, 0 }, { 1, 0, 1 },
  136. { 2, 0, 2 }, { 0, 0, 0 }, { 3, 0, 3 },
  137. { 7, 1, 1 }, { 4, 1, 2 }, { 5, 1, 0 },
  138. { 6, 1, 3 }, { 4, 1, 2 }, { 7, 1, 1 },
  139. { 3, 2, 1 }, { 5, 2, 2 }, { 2, 2, 0 },
  140. { 7, 2, 3 }, { 5, 2, 2 }, { 3, 2, 1 },
  141. { 1, 3, 3 }, { 4, 3, 0 }, { 6, 3, 1 },
  142. { 0, 3, 2 }, { 4, 3, 0 }, { 1, 3, 3 },
  143. { 3, 4, 3 }, { 6, 4, 0 }, { 7, 4, 1 },
  144. { 1, 4, 2 }, { 6, 4, 0 }, { 3, 4, 3 },
  145. { 2, 5, 1 }, { 4, 5, 2 }, { 0, 5, 0 },
  146. { 5, 5, 3 }, { 4, 5, 2 }, { 2, 5, 1 }
  147. };
  148. // Fill the vertex buffer
  149. VertexType *pVert = NULL;
  150. mVertexBuffer.set( GFX, 36, GFXBufferTypeStatic );
  151. pVert = mVertexBuffer.lock();
  152. Point3F halfSize = getObjBox().getExtents() * 0.5f;
  153. for (U32 i = 0; i < 36; i++)
  154. {
  155. const U32& vdx = cubeFaces[i][0];
  156. const U32& ndx = cubeFaces[i][1];
  157. const U32& tdx = cubeFaces[i][2];
  158. pVert[i].point = cubePoints[vdx] * halfSize;
  159. pVert[i].normal = cubeNormals[ndx];
  160. pVert[i].texCoord = cubeTexCoords[tdx];
  161. }
  162. mVertexBuffer.unlock();
  163. // Fill the primitive buffer
  164. U16 *pIdx = NULL;
  165. mPrimitiveBuffer.set( GFX, 36, 12, GFXBufferTypeStatic );
  166. mPrimitiveBuffer.lock(&pIdx);
  167. for (U16 i = 0; i < 36; i++)
  168. pIdx[i] = i;
  169. mPrimitiveBuffer.unlock();
  170. }
  171. void @::updateMaterial()
  172. {
  173. if ( mMaterialName.isEmpty() )
  174. return;
  175. // If the material name matches then don't bother updating it.
  176. if ( mMaterialInst && mMaterialName.equal( mMaterialInst->getMaterial()->getName(), String::NoCase ) )
  177. return;
  178. SAFE_DELETE( mMaterialInst );
  179. mMaterialInst = MATMGR->createMatInstance( mMaterialName, getGFXVertexFormat< VertexType >() );
  180. if ( !mMaterialInst )
  181. Con::errorf( "@::updateMaterial - no Material called '%s'", mMaterialName.c_str() );
  182. }
  183. void @::prepRenderImage( SceneRenderState *state )
  184. {
  185. // Do a little prep work if needed
  186. if ( mVertexBuffer.isNull() )
  187. createGeometry();
  188. // If we have no material then skip out.
  189. if ( !mMaterialInst || !state)
  190. return;
  191. // If we don't have a material instance after the override then
  192. // we can skip rendering all together.
  193. BaseMatInstance *matInst = state->getOverrideMaterial( mMaterialInst );
  194. if ( !matInst )
  195. return;
  196. // Get a handy pointer to our RenderPassmanager
  197. RenderPassManager *renderPass = state->getRenderPass();
  198. // Allocate an MeshRenderInst so that we can submit it to the RenderPassManager
  199. MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>();
  200. // Set our RenderInst as a standard mesh render
  201. ri->type = RenderPassManager::RIT_Mesh;
  202. //If our material has transparency set on this will redirect it to proper render bin
  203. if ( matInst->getMaterial()->isTranslucent() )
  204. {
  205. ri->type = RenderPassManager::RIT_Translucent;
  206. ri->translucentSort = true;
  207. }
  208. // Calculate our sorting point
  209. if ( state )
  210. {
  211. // Calculate our sort point manually.
  212. const Box3F& rBox = getRenderWorldBox();
  213. ri->sortDistSq = rBox.getSqDistanceToPoint( state->getCameraPosition() );
  214. }
  215. else
  216. ri->sortDistSq = 0.0f;
  217. // Set up our transforms
  218. MatrixF objectToWorld = getRenderTransform();
  219. objectToWorld.scale( getScale() );
  220. ri->objectToWorld = renderPass->allocUniqueXform( objectToWorld );
  221. ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View);
  222. ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection);
  223. // If our material needs lights then fill the RIs
  224. // light vector with the best lights.
  225. if ( matInst->isForwardLit() )
  226. {
  227. LightQuery query;
  228. query.init( getWorldSphere() );
  229. query.getLights( ri->lights, 8 );
  230. }
  231. // Make sure we have an up-to-date backbuffer in case
  232. // our Material would like to make use of it
  233. // NOTICE: SFXBB is removed and refraction is disabled!
  234. //ri->backBuffTex = GFX->getSfxBackBuffer();
  235. // Set our Material
  236. ri->matInst = matInst;
  237. // Set up our vertex buffer and primitive buffer
  238. ri->vertBuff = &mVertexBuffer;
  239. ri->primBuff = &mPrimitiveBuffer;
  240. ri->prim = renderPass->allocPrim();
  241. ri->prim->type = GFXTriangleList;
  242. ri->prim->minIndex = 0;
  243. ri->prim->startIndex = 0;
  244. ri->prim->numPrimitives = 12;
  245. ri->prim->startVertex = 0;
  246. ri->prim->numVertices = 36;
  247. // We sort by the material then vertex buffer
  248. ri->defaultKey = matInst->getStateHint();
  249. ri->defaultKey2 = (uintptr_t)ri->vertBuff; // Not 64bit safe!
  250. // Submit our RenderInst to the RenderPassManager
  251. state->getRenderPass()->addInst( ri );
  252. }
  253. DefineEngineMethod( @, postApply, void, (),,
  254. "A utility method for forcing a network update.\n")
  255. {
  256. object->inspectPostApply();
  257. }