CmMaterial.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "CmMaterial.h"
  2. #include "CmException.h"
  3. #include "CmShader.h"
  4. #include "CmTechnique.h"
  5. #include "CmPass.h"
  6. #include "CmRenderSystemManager.h"
  7. #include "CmRenderSystem.h"
  8. #include "CmGpuProgramParams.h"
  9. #include "CmGpuProgram.h"
  10. #include "CmMaterialRTTI.h"
  11. namespace CamelotEngine
  12. {
  13. void Material::setShader(ShaderPtr shader)
  14. {
  15. mShader = shader;
  16. initBestTechnique();
  17. }
  18. void Material::initBestTechnique()
  19. {
  20. mBestTechnique = nullptr;
  21. mParameters.clear();
  22. if(mShader)
  23. {
  24. mBestTechnique = mShader->getBestTechnique();
  25. if(mBestTechnique)
  26. {
  27. for(UINT32 i = 0; i < mBestTechnique->getNumPasses(); i++)
  28. {
  29. PassPtr curPass = mBestTechnique->getPass(i);
  30. ParamsPerPass params;
  31. GpuProgramRef vertProgram = curPass->getVertexProgram();
  32. if(vertProgram)
  33. params.mVertParams = vertProgram->createParameters();
  34. GpuProgramRef fragProgram = curPass->getFragmentProgram();
  35. if(fragProgram)
  36. params.mFragParams = fragProgram->createParameters();
  37. GpuProgramRef geomProgram = curPass->getGeometryProgram();
  38. if(geomProgram)
  39. params.mGeomParams = geomProgram->createParameters();
  40. mParameters.push_back(params);
  41. }
  42. }
  43. }
  44. }
  45. void Material::throwIfNotInitialized() const
  46. {
  47. if(mShader == nullptr)
  48. {
  49. CM_EXCEPT(InternalErrorException, "Material does not have shader set.");
  50. }
  51. if(mBestTechnique == nullptr)
  52. {
  53. CM_EXCEPT(InternalErrorException, "Shader does not contain a supported technique.");
  54. }
  55. }
  56. void Material::setTexture(const String& name, TextureRef& value)
  57. {
  58. throwIfNotInitialized();
  59. setParam(name, value);
  60. }
  61. void Material::setFloat(const String& name, float value)
  62. {
  63. throwIfNotInitialized();
  64. setParam(name, value);
  65. }
  66. void Material::setColor(const String& name, const Color& value)
  67. {
  68. throwIfNotInitialized();
  69. setParam(name, value);
  70. }
  71. void Material::setVec2(const String& name, const Vector2& value)
  72. {
  73. throwIfNotInitialized();
  74. setParam(name, value);
  75. }
  76. void Material::setVec3(const String& name, const Vector3& value)
  77. {
  78. throwIfNotInitialized();
  79. setParam(name, value);
  80. }
  81. void Material::setVec4(const String& name, const Vector4& value)
  82. {
  83. throwIfNotInitialized();
  84. setParam(name, value);
  85. }
  86. void Material::setMat3(const String& name, const Matrix3& value)
  87. {
  88. throwIfNotInitialized();
  89. setParam(name, value);
  90. }
  91. void Material::setMat4(const String& name, const Matrix4& value)
  92. {
  93. throwIfNotInitialized();
  94. setParam(name, value);
  95. }
  96. UINT32 Material::getNumPasses() const
  97. {
  98. throwIfNotInitialized();
  99. return mShader->getBestTechnique()->getNumPasses();
  100. }
  101. PassPtr Material::getPass(UINT32 passIdx) const
  102. {
  103. if(passIdx < 0 || passIdx >= mShader->getBestTechnique()->getNumPasses())
  104. CM_EXCEPT(InvalidParametersException, "Invalid pass index.");
  105. return mShader->getBestTechnique()->getPass(passIdx);
  106. }
  107. void Material::applyPass(UINT32 passIdx)
  108. {
  109. throwIfNotInitialized();
  110. // TODO - I need to take care to minimize shader and shader constant (especially texture) changes
  111. RenderSystem* renderSystem = RenderSystemManager::getActive();
  112. PassPtr curPass = mBestTechnique->getPass(passIdx);
  113. ParamsPerPass params = mParameters[passIdx];
  114. GpuProgramRef vertProgram = curPass->getVertexProgram();
  115. if(vertProgram)
  116. {
  117. renderSystem->bindGpuProgram(vertProgram->_getBindingDelegate());
  118. renderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, params.mVertParams, GPV_ALL);
  119. }
  120. GpuProgramRef fragProgram = curPass->getFragmentProgram();
  121. if(fragProgram)
  122. {
  123. renderSystem->bindGpuProgram(fragProgram->_getBindingDelegate());
  124. renderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, params.mFragParams, GPV_ALL);
  125. }
  126. GpuProgramRef geomProgram = curPass->getGeometryProgram();
  127. if(geomProgram)
  128. {
  129. renderSystem->bindGpuProgram(geomProgram->_getBindingDelegate());
  130. renderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, params.mGeomParams, GPV_ALL);
  131. }
  132. }
  133. RTTITypeBase* Material::getRTTIStatic()
  134. {
  135. return MaterialRTTI::instance();
  136. }
  137. RTTITypeBase* Material::getRTTI() const
  138. {
  139. return Material::getRTTIStatic();
  140. }
  141. }