meshRenderSystem.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. #include "T3D/systems/render/meshRenderSystem.h"
  2. #include "gfx/gfxTransformSaver.h"
  3. #include "lighting/lightQuery.h"
  4. #include "renderInstance/renderPassManager.h"
  5. #include "materials/materialManager.h"
  6. #include "materials/baseMatInstance.h"
  7. Vector<MeshRenderSystem::BufferMaterials> MeshRenderSystem::mBufferMaterials(0);
  8. Vector<MeshRenderSystem::BufferSet> MeshRenderSystem::mStaticBuffers(0);
  9. void MeshRenderSystem::render(SceneManager *sceneManager, SceneRenderState* state)
  10. {
  11. if (sceneManager == nullptr || state == nullptr)
  12. return;
  13. Frustum viewFrustum = state->getCullingFrustum();
  14. MatrixF camTransform = state->getCameraTransform();
  15. U32 count = MeshRenderSystemInterface::all.size();
  16. for (U32 i = 0; i < count; i++)
  17. {
  18. //Server side items exist for data, but we don't actually render them
  19. bool isClient = MeshRenderSystemInterface::all[i]->mIsClient;
  20. if (!MeshRenderSystemInterface::all[i]->mIsClient)
  21. continue;
  22. bool isStatic = MeshRenderSystemInterface::all[i]->mStatic;
  23. if (MeshRenderSystemInterface::all[i]->mStatic)
  24. continue;
  25. //First, do frustum culling
  26. if (viewFrustum.isCulled(MeshRenderSystemInterface::all[i]->mBounds))
  27. continue;
  28. // Set the query box for the container query. Never
  29. // make it larger than the frustum's AABB. In the editor,
  30. // always query the full frustum as that gives objects
  31. // the opportunity to render editor visualizations even if
  32. // they are otherwise not in view.
  33. if (!state->getCullingFrustum().getBounds().isOverlapped(state->getRenderArea()))
  34. {
  35. // This handles fringe cases like flying backwards into a zone where you
  36. // end up pretty much standing on a zone border and looking directly into
  37. // its "walls". In that case the traversal area will be behind the frustum
  38. // (remember that the camera isn't where visibility starts, it's the near
  39. // distance).
  40. continue;
  41. }
  42. //We can then sort our objects by range since we have it already, so we can do occlusion culling be rendering front-to-back
  43. //if we've made it this far, call down to the render function to actually display our stuff
  44. renderInterface(i, state);
  45. }
  46. //Static Batch rendering
  47. if ( /*!mMaterialInst ||*/ !state)
  48. return;
  49. BaseMatInstance *matInst = MATMGR->getWarningMatInstance();
  50. // Get a handy pointer to our RenderPassmanager
  51. RenderPassManager *renderPass = state->getRenderPass();
  52. for (U32 i = 0; i < mStaticBuffers.size(); i++)
  53. {
  54. for (U32 b = 0; b < mStaticBuffers[i].buffers.size(); b++)
  55. {
  56. if (mStaticBuffers[i].buffers[b].vertData.empty())
  57. continue;
  58. MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>();
  59. // Set our RenderInst as a standard mesh render
  60. ri->type = RenderPassManager::RIT_Mesh;
  61. //If our material has transparency set on this will redirect it to proper render bin
  62. if (matInst->getMaterial()->isTranslucent())
  63. {
  64. ri->type = RenderPassManager::RIT_Translucent;
  65. ri->translucentSort = true;
  66. }
  67. // Calculate our sorting point
  68. if (state)
  69. {
  70. // Calculate our sort point manually.
  71. const Box3F& rBox = Box3F(1000);// getRenderWorldBox();
  72. ri->sortDistSq = rBox.getSqDistanceToPoint(state->getCameraPosition());
  73. }
  74. else
  75. ri->sortDistSq = 0.0f;
  76. // Set up our transforms
  77. MatrixF objectToWorld = MatrixF::Identity;//getRenderTransform();
  78. //objectToWorld.scale(getScale());
  79. ri->objectToWorld = renderPass->allocUniqueXform(objectToWorld);
  80. ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View);
  81. ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection);
  82. // If our material needs lights then fill the RIs
  83. // light vector with the best lights.
  84. /*if (matInst->isForwardLit())
  85. {
  86. LightQuery query;
  87. query.init(getWorldSphere());
  88. query.getLights(ri->lights, 8);
  89. }*/
  90. // Make sure we have an up-to-date backbuffer in case
  91. // our Material would like to make use of it
  92. // NOTICE: SFXBB is removed and refraction is disabled!
  93. //ri->backBuffTex = GFX->getSfxBackBuffer();
  94. // Set our Material
  95. ri->matInst = matInst;
  96. // Set up our vertex buffer and primitive buffer
  97. ri->vertBuff = &mStaticBuffers[i].buffers[b].vertexBuffer;
  98. ri->primBuff = &mStaticBuffers[i].buffers[b].primitiveBuffer;
  99. ri->prim = renderPass->allocPrim();
  100. ri->prim->type = GFXTriangleList;
  101. ri->prim->minIndex = 0;
  102. ri->prim->startIndex = 0;
  103. ri->prim->numPrimitives = mStaticBuffers[i].buffers[b].primData.size();
  104. ri->prim->startVertex = 0;
  105. ri->prim->numVertices = mStaticBuffers[i].buffers[b].vertData.size();
  106. // We sort by the material then vertex buffer
  107. ri->defaultKey = matInst->getStateHint();
  108. ri->defaultKey2 = (uintptr_t)ri->vertBuff;
  109. // Submit our RenderInst to the RenderPassManager
  110. state->getRenderPass()->addInst(ri);
  111. }
  112. }
  113. }
  114. void MeshRenderSystem::renderInterface(U32 interfaceIndex, SceneRenderState* state)
  115. {
  116. //Fetch
  117. MeshRenderSystemInterface* interface = MeshRenderSystemInterface::all[interfaceIndex];
  118. if (interface->mShapeInstance == nullptr)
  119. return;
  120. Point3F cameraOffset;
  121. interface->mTransform.getColumn(3, &cameraOffset);
  122. cameraOffset -= state->getDiffuseCameraPosition();
  123. F32 dist = cameraOffset.len();
  124. if (dist < 0.01f)
  125. dist = 0.01f;
  126. Point3F objScale = interface->mScale;
  127. F32 invScale = (1.0f / getMax(getMax(objScale.x, objScale.y), objScale.z));
  128. interface->mShapeInstance->setDetailFromDistance(state, dist * invScale);
  129. if (interface->mShapeInstance->getCurrentDetail() < 0)
  130. return;
  131. GFXTransformSaver saver;
  132. // Set up our TS render state.
  133. TSRenderState rdata;
  134. rdata.setSceneState(state);
  135. rdata.setFadeOverride(1.0f);
  136. rdata.setOriginSort(false);
  137. // We might have some forward lit materials
  138. // so pass down a query to gather lights.
  139. LightQuery query;
  140. query.init(interface->mSphere);
  141. rdata.setLightQuery(&query);
  142. MatrixF mat = interface->mTransform;
  143. mat.scale(objScale);
  144. GFX->setWorldMatrix(mat);
  145. interface->mShapeInstance->render(rdata);
  146. }
  147. void MeshRenderSystem::rebuildBuffers()
  148. {
  149. U32 BUFFER_SIZE = 65000;
  150. Vector<U32> tempIndices;
  151. tempIndices.reserve(4);
  152. Box3F newBounds = Box3F::Zero;
  153. mStaticBuffers.clear();
  154. for (U32 i = 0; i < MeshRenderSystemInterface::all.size(); i++)
  155. {
  156. if (!MeshRenderSystemInterface::all[i]->mIsEnabled)
  157. continue;
  158. if (!MeshRenderSystemInterface::all[i]->mIsClient || !MeshRenderSystemInterface::all[i]->mStatic)
  159. continue;
  160. //TODO: Properly re-implement StaticElements to container owner interfaces and buffer sets
  161. for (U32 j = 0; j < MeshRenderSystemInterface::all[i]->mGeometry.mPolyList.size(); j++)
  162. {
  163. const OptimizedPolyList::Poly& poly = MeshRenderSystemInterface::all[i]->mGeometry.mPolyList[j];
  164. if (poly.vertexCount < 3)
  165. continue;
  166. tempIndices.setSize(poly.vertexCount);
  167. dMemset(tempIndices.address(), 0, poly.vertexCount);
  168. if (poly.type == OptimizedPolyList::TriangleStrip ||
  169. poly.type == OptimizedPolyList::TriangleFan)
  170. {
  171. tempIndices[0] = 0;
  172. U32 idx = 1;
  173. for (U32 k = 1; k < poly.vertexCount; k += 2)
  174. tempIndices[idx++] = k;
  175. for (U32 k = ((poly.vertexCount - 1) & (~0x1)); k > 0; k -= 2)
  176. tempIndices[idx++] = k;
  177. }
  178. else if (poly.type == OptimizedPolyList::TriangleList)
  179. {
  180. for (U32 k = 0; k < poly.vertexCount; k++)
  181. tempIndices[k] = k;
  182. }
  183. else
  184. continue;
  185. //got our data, now insert it into the correct buffer!
  186. S32 bufferId = findBufferSetByMaterial(poly.material);
  187. if (bufferId == -1)
  188. {
  189. //add a new buffer set if we didn't get a match!
  190. BufferSet newSet;
  191. newSet.surfaceMaterialId = poly.material;
  192. mStaticBuffers.push_back(newSet);
  193. bufferId = mStaticBuffers.size() - 1;
  194. }
  195. //see if this would push us over our buffer size limit, if it is, make a new buffer for this set
  196. if (mStaticBuffers[bufferId].buffers.last().vertData.size() + 3 > BUFFER_SIZE
  197. || mStaticBuffers[bufferId].buffers.last().primData.size() + 1 > BUFFER_SIZE)
  198. {
  199. //yep, we'll overstep with this, so spool up a new buffer in this set
  200. BufferSet::Buffers newBuffer = BufferSet::Buffers();
  201. mStaticBuffers[bufferId].buffers.push_back(newBuffer);
  202. }
  203. const U32& firstIdx = MeshRenderSystemInterface::all[i]->mGeometry.mIndexList[poly.vertexStart];
  204. const OptimizedPolyList::VertIndex& firstVertIdx = MeshRenderSystemInterface::all[i]->mGeometry.mVertexList[firstIdx];
  205. //Vector<Point3F> geomPoints = MeshRenderSystemInterface::all[i]->mGeometry.mPoints;
  206. //Vector<Point3F> geomNormals = MeshRenderSystemInterface::all[i]->mGeometry.mNormals;
  207. //Vector<Point2F> geoUVs = MeshRenderSystemInterface::all[i]->mGeometry.mUV0s;
  208. for (U32 k = 1; k < poly.vertexCount - 1; k++)
  209. {
  210. const U32& secondIdx = MeshRenderSystemInterface::all[i]->mGeometry.mIndexList[poly.vertexStart + tempIndices[k]];
  211. const U32& thirdIdx = MeshRenderSystemInterface::all[i]->mGeometry.mIndexList[poly.vertexStart + tempIndices[k + 1]];
  212. const OptimizedPolyList::VertIndex& secondVertIdx = MeshRenderSystemInterface::all[i]->mGeometry.mVertexList[secondIdx];
  213. const OptimizedPolyList::VertIndex& thirdVertIdx = MeshRenderSystemInterface::all[i]->mGeometry.mVertexList[thirdIdx];
  214. Point3F points[3];
  215. points[0] = MeshRenderSystemInterface::all[i]->mGeometry.mPoints[firstVertIdx.vertIdx];
  216. points[1] = MeshRenderSystemInterface::all[i]->mGeometry.mPoints[secondVertIdx.vertIdx];
  217. points[2] = MeshRenderSystemInterface::all[i]->mGeometry.mPoints[thirdVertIdx.vertIdx];
  218. Point3F normals[3];
  219. normals[0] = MeshRenderSystemInterface::all[i]->mGeometry.mNormals[firstVertIdx.normalIdx];
  220. normals[1] = MeshRenderSystemInterface::all[i]->mGeometry.mNormals[secondVertIdx.normalIdx];
  221. normals[2] = MeshRenderSystemInterface::all[i]->mGeometry.mNormals[thirdVertIdx.normalIdx];
  222. Point3F tangents[3];
  223. tangents[0] = mCross(points[1] - points[0], normals[0]);
  224. tangents[1] = mCross(points[2] - points[1], normals[1]);
  225. tangents[2] = mCross(points[0] - points[2], normals[2]);
  226. Point2F uvs[3];
  227. uvs[0] = MeshRenderSystemInterface::all[i]->mGeometry.mUV0s[firstVertIdx.uv0Idx];
  228. uvs[1] = MeshRenderSystemInterface::all[i]->mGeometry.mUV0s[secondVertIdx.uv0Idx];
  229. uvs[2] = MeshRenderSystemInterface::all[i]->mGeometry.mUV0s[thirdVertIdx.uv0Idx];
  230. mStaticBuffers[bufferId].vertCount += 3;
  231. mStaticBuffers[bufferId].primCount += 1;
  232. for (U32 v = 0; v < 3; ++v)
  233. {
  234. //Build the vert and store it to the buffers!
  235. GFXVertexPNTT bufVert;
  236. bufVert.point = points[v];
  237. bufVert.normal = normals[v];
  238. bufVert.tangent = tangents[v];
  239. bufVert.texCoord = uvs[v];
  240. newBounds.extend(points[v]);
  241. mStaticBuffers[bufferId].buffers.last().vertData.push_back(bufVert);
  242. U32 vertPrimId = mStaticBuffers[bufferId].buffers.last().vertData.size() - 1;
  243. mStaticBuffers[bufferId].buffers.last().primData.push_back(vertPrimId);
  244. mStaticBuffers[bufferId].center += points[v];
  245. }
  246. }
  247. }
  248. }
  249. //Now, iterate through the organized data and turn them into renderable buffers
  250. for (U32 i = 0; i < mStaticBuffers.size(); i++)
  251. {
  252. for (U32 b = 0; b < mStaticBuffers[i].buffers.size(); b++)
  253. {
  254. BufferSet::Buffers& buffers = mStaticBuffers[i].buffers[b];
  255. //if there's no data to be had in this buffer, just skip it
  256. if (buffers.vertData.empty())
  257. continue;
  258. buffers.vertexBuffer.set(GFX, buffers.vertData.size(), GFXBufferTypeStatic);
  259. GFXVertexPNTT *pVert = buffers.vertexBuffer.lock();
  260. for (U32 v = 0; v < buffers.vertData.size(); v++)
  261. {
  262. pVert->normal = buffers.vertData[v].normal;
  263. pVert->tangent = buffers.vertData[v].tangent;
  264. //pVert->color = buffers.vertData[v].color;
  265. pVert->point = buffers.vertData[v].point;
  266. pVert->texCoord = buffers.vertData[v].texCoord;
  267. pVert++;
  268. }
  269. buffers.vertexBuffer.unlock();
  270. // Allocate PB
  271. buffers.primitiveBuffer.set(GFX, buffers.primData.size(), buffers.primData.size() / 3, GFXBufferTypeStatic);
  272. U16 *pIndex;
  273. buffers.primitiveBuffer.lock(&pIndex);
  274. for (U16 primDataIDx = 0; primDataIDx < buffers.primData.size(); primDataIDx++)
  275. {
  276. *pIndex = primDataIDx;
  277. pIndex++;
  278. }
  279. buffers.primitiveBuffer.unlock();
  280. }
  281. mStaticBuffers[i].center /= mStaticBuffers[i].vertCount;
  282. }
  283. //mObjBox = newBounds;
  284. //resetWorldBox();
  285. }
  286. U32 MeshRenderSystem::findBufferSetByMaterial(U32 matId)
  287. {
  288. for (U32 i = 0; i < mStaticBuffers.size(); i++)
  289. {
  290. if (mStaticBuffers[i].surfaceMaterialId == matId)
  291. return i;
  292. }
  293. return -1;
  294. }