CmForwardRenderer.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "CmForwardRenderer.h"
  2. #include "CmCamera.h"
  3. #include "CmSceneManager.h"
  4. #include "CmRenderSystemManager.h"
  5. #include "CmRenderSystem.h"
  6. #include "CmRenderable.h"
  7. #include "CmMaterial.h"
  8. #include "CmMesh.h"
  9. #include "CmPass.h"
  10. #include "CmApplication.h"
  11. namespace CamelotEngine
  12. {
  13. ForwardRenderer::ForwardRenderer()
  14. {
  15. }
  16. ForwardRenderer::~ForwardRenderer()
  17. { }
  18. const String& ForwardRenderer::getName() const
  19. {
  20. static String name = "ForwardRenderer";
  21. return name;
  22. }
  23. void ForwardRenderer::renderAll()
  24. {
  25. return; // TODO - Temporarily I don't want to run this
  26. RenderSystem* renderSystem = RenderSystemManager::getActive();
  27. // TODO - No point in setting these each frame?
  28. renderSystem->setInvertVertexWinding_internal(false);
  29. renderSystem->setDepthBufferParams_internal();
  30. const vector<CameraPtr>::type& allCameras = gSceneManager().getAllCameras();
  31. for(auto iter = allCameras.begin(); iter != allCameras.end(); ++iter)
  32. {
  33. render(*iter);
  34. }
  35. renderSystem->swapAllRenderTargetBuffers(false);
  36. }
  37. void ForwardRenderer::render(const CameraPtr camera)
  38. {
  39. vector<RenderablePtr>::type allRenderables = gSceneManager().getVisibleRenderables(camera);
  40. RenderSystem* renderSystem = RenderSystemManager::getActive();
  41. renderSystem->setViewport_internal(*camera->getViewport());
  42. Matrix4 projMatrixCstm = camera->getProjectionMatrix();
  43. Matrix4 viewMatrixCstm = camera->getViewMatrix();
  44. Matrix4 viewProjMatrix = projMatrixCstm * viewMatrixCstm;
  45. renderSystem->clearFrameBuffer_internal(FBT_COLOUR | FBT_DEPTH, Color::Blue);
  46. renderSystem->beginFrame_internal();
  47. // TODO - sort renderables by material/pass/parameters to minimize state changes
  48. for(auto iter = allRenderables.begin(); iter != allRenderables.end(); ++iter)
  49. {
  50. MaterialRef material = (*iter)->getMaterial();
  51. if(material == nullptr || !material.isResolved())
  52. continue;
  53. MeshRef mesh = (*iter)->getMesh();
  54. if(mesh == nullptr || !mesh.isResolved())
  55. continue;
  56. // TODO - Renderer should ensure shader is compatible with it, and it contains all the needed parameters
  57. // (probably at an earlier stage). e.g. I want the user to be warned if the shader doesn't contain matViewProjection param
  58. // (or should we just ignore such missing parameters?)
  59. material->setMat4("matViewProjection", viewProjMatrix);
  60. for(UINT32 i = 0; i < material->getNumPasses(); i++)
  61. {
  62. setPass(material->getPass(i));
  63. setPassParameters(material->getPassParameters(i));
  64. renderSystem->render_internal(mesh->getRenderOperation());
  65. }
  66. }
  67. renderSystem->endFrame_internal();
  68. // TODO - Sort renderables
  69. // Render them
  70. }
  71. void ForwardRenderer::setPass(PassPtr pass)
  72. {
  73. // TODO - When applying passes, don't re-apply states that are already the same as from previous pass.
  74. // Also check if it's maybe the exactly the same pass as the previous one.
  75. mActivePass = pass;
  76. RenderSystem* renderSystem = RenderSystemManager::getActive();
  77. GpuProgramRef vertProgram = pass->getVertexProgram();
  78. if(vertProgram)
  79. {
  80. renderSystem->bindGpuProgram(vertProgram);
  81. }
  82. else
  83. {
  84. //if(renderSystem->isGpuProgramBound(GPT_VERTEX_PROGRAM))
  85. renderSystem->unbindGpuProgram(GPT_VERTEX_PROGRAM);
  86. }
  87. GpuProgramRef fragProgram = pass->getFragmentProgram();
  88. if(fragProgram)
  89. {
  90. renderSystem->bindGpuProgram(fragProgram);
  91. }
  92. else
  93. {
  94. //if(renderSystem->isGpuProgramBound(GPT_FRAGMENT_PROGRAM))
  95. renderSystem->unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
  96. }
  97. GpuProgramRef geomProgram = pass->getGeometryProgram();
  98. if(geomProgram)
  99. {
  100. renderSystem->bindGpuProgram(geomProgram);
  101. }
  102. else
  103. {
  104. //if(renderSystem->isGpuProgramBound(GPT_GEOMETRY_PROGRAM))
  105. renderSystem->unbindGpuProgram(GPT_GEOMETRY_PROGRAM);
  106. }
  107. // The rest of the settings are the same no matter whether we use programs or not
  108. // Set scene blending
  109. if ( pass->hasSeparateSceneBlending( ) )
  110. {
  111. renderSystem->setSeparateSceneBlending_internal(
  112. pass->getSourceBlendFactor(), pass->getDestBlendFactor(),
  113. pass->getSourceBlendFactorAlpha(), pass->getDestBlendFactorAlpha(),
  114. pass->getSceneBlendingOperation(),
  115. pass->hasSeparateSceneBlendingOperations() ? pass->getSceneBlendingOperation() : pass->getSceneBlendingOperationAlpha() );
  116. }
  117. else
  118. {
  119. if(pass->hasSeparateSceneBlendingOperations( ) )
  120. {
  121. renderSystem->setSeparateSceneBlending_internal(
  122. pass->getSourceBlendFactor(), pass->getDestBlendFactor(),
  123. pass->getSourceBlendFactor(), pass->getDestBlendFactor(),
  124. pass->getSceneBlendingOperation(), pass->getSceneBlendingOperationAlpha() );
  125. }
  126. else
  127. {
  128. renderSystem->setSceneBlending_internal(
  129. pass->getSourceBlendFactor(), pass->getDestBlendFactor(), pass->getSceneBlendingOperation() );
  130. }
  131. }
  132. // Set point parameters
  133. renderSystem->setPointParameters_internal(
  134. pass->getPointSize(),
  135. false,
  136. false,
  137. false,
  138. false,
  139. pass->getPointMinSize(),
  140. pass->getPointMaxSize());
  141. // TODO - Try to limit amount of state changes, if previous state is already the same (especially with textures)
  142. // TODO: Disable remaining texture units
  143. //renderSystem->_disableTextureUnitsFrom(pass->getNumTextures());
  144. // Set up non-texture related material settings
  145. // Depth buffer settings
  146. renderSystem->setDepthBufferFunction_internal(pass->getDepthFunction());
  147. renderSystem->setDepthBufferCheckEnabled_internal(pass->getDepthCheckEnabled());
  148. renderSystem->setDepthBufferWriteEnabled_internal(pass->getDepthWriteEnabled());
  149. renderSystem->setDepthBias_internal(pass->getDepthBiasConstant(), pass->getDepthBiasSlopeScale());
  150. // Alpha-reject settings
  151. renderSystem->setAlphaRejectSettings_internal(
  152. pass->getAlphaRejectFunction(), pass->getAlphaRejectValue(), pass->isAlphaToCoverageEnabled());
  153. // Set colour write mode
  154. // Right now we only use on/off, not per-channel
  155. bool colWrite = pass->getColourWriteEnabled();
  156. renderSystem->setColorBufferWriteEnabled_internal(colWrite, colWrite, colWrite, colWrite);
  157. // Culling mode
  158. renderSystem->setCullingMode_internal(pass->getCullingMode());
  159. // Polygon mode
  160. renderSystem->setPolygonMode_internal(pass->getPolygonMode());
  161. }
  162. void ForwardRenderer::setPassParameters(PassParametersPtr params)
  163. {
  164. // TODO - When applying passes, don't re-apply states that are already the same as from previous pass.
  165. RenderSystem* renderSystem = RenderSystemManager::getActive();
  166. if(mActivePass == nullptr)
  167. CM_EXCEPT(InternalErrorException, "Trying to set pass parameters, but no pass is set.");
  168. GpuProgramRef vertProgram = mActivePass->getVertexProgram();
  169. if(vertProgram)
  170. renderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, params->mVertParams, GPV_ALL);
  171. GpuProgramRef fragProgram = mActivePass->getFragmentProgram();
  172. if(fragProgram)
  173. renderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, params->mFragParams, GPV_ALL);
  174. GpuProgramRef geomProgram = mActivePass->getGeometryProgram();
  175. if(geomProgram)
  176. renderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, params->mGeomParams, GPV_ALL);
  177. }
  178. }