PolyCamera.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*
  2. * PolyCamera.cpp
  3. * Poly
  4. *
  5. * Created by Ivan Safrin on 3/26/08.
  6. * Copyright 2008 Ivan Safrin. All rights reserved.
  7. *
  8. */
  9. #include "PolyCamera.h"
  10. using namespace Polycode;
  11. Camera::Camera(Scene *parentScene) : SceneEntity() {
  12. setParentScene(parentScene);
  13. orthoMode = false;
  14. fov = 45.0f;
  15. exposureLevel = 1.0f;
  16. _hasFilterShader = false;
  17. fovSet = false;
  18. }
  19. Camera::~Camera() {
  20. }
  21. void Camera::setExposureLevel(Number level) {
  22. exposureLevel = level;
  23. }
  24. Number Camera::getExposureLevel() {
  25. return exposureLevel;
  26. }
  27. void Camera::setFOV(Number fov) {
  28. this->fov = fov;
  29. fovSet = true;
  30. }
  31. Number Camera::getFOV() {
  32. return fov;
  33. }
  34. bool Camera::isSphereInFrustrum(Vector3 pos, Number fRadius) {
  35. for( int i = 0; i < 6; ++i )
  36. {
  37. if( frustumPlanes[i][0] * pos.x +
  38. frustumPlanes[i][1] * pos.y +
  39. frustumPlanes[i][2] * pos.z +
  40. frustumPlanes[i][3] <= -fRadius )
  41. return false;
  42. }
  43. return true;
  44. }
  45. void Camera::setOrthoMode(bool mode) {
  46. orthoMode = mode;
  47. }
  48. bool Camera::getOrthoMode() {
  49. return orthoMode;
  50. }
  51. void Camera::buildFrustrumPlanes() {
  52. Matrix4 p;
  53. Matrix4 mv;
  54. Matrix4 mvp;
  55. Number t;
  56. p = CoreServices::getInstance()->getRenderer()->getProjectionMatrix();
  57. mv = CoreServices::getInstance()->getRenderer()->getModelviewMatrix();
  58. //
  59. // Concatenate the projection matrix and the model-view matrix to produce
  60. // a combined model-view-projection matrix.
  61. //
  62. mvp.ml[ 0] = mv.ml[ 0] * p.ml[ 0] + mv.ml[ 1] * p.ml[ 4] + mv.ml[ 2] * p.ml[ 8] + mv.ml[ 3] * p.ml[12];
  63. mvp.ml[ 1] = mv.ml[ 0] * p.ml[ 1] + mv.ml[ 1] * p.ml[ 5] + mv.ml[ 2] * p.ml[ 9] + mv.ml[ 3] * p.ml[13];
  64. mvp.ml[ 2] = mv.ml[ 0] * p.ml[ 2] + mv.ml[ 1] * p.ml[ 6] + mv.ml[ 2] * p.ml[10] + mv.ml[ 3] * p.ml[14];
  65. mvp.ml[ 3] = mv.ml[ 0] * p.ml[ 3] + mv.ml[ 1] * p.ml[ 7] + mv.ml[ 2] * p.ml[11] + mv.ml[ 3] * p.ml[15];
  66. mvp.ml[ 4] = mv.ml[ 4] * p.ml[ 0] + mv.ml[ 5] * p.ml[ 4] + mv.ml[ 6] * p.ml[ 8] + mv.ml[ 7] * p.ml[12];
  67. mvp.ml[ 5] = mv.ml[ 4] * p.ml[ 1] + mv.ml[ 5] * p.ml[ 5] + mv.ml[ 6] * p.ml[ 9] + mv.ml[ 7] * p.ml[13];
  68. mvp.ml[ 6] = mv.ml[ 4] * p.ml[ 2] + mv.ml[ 5] * p.ml[ 6] + mv.ml[ 6] * p.ml[10] + mv.ml[ 7] * p.ml[14];
  69. mvp.ml[ 7] = mv.ml[ 4] * p.ml[ 3] + mv.ml[ 5] * p.ml[ 7] + mv.ml[ 6] * p.ml[11] + mv.ml[ 7] * p.ml[15];
  70. mvp.ml[ 8] = mv.ml[ 8] * p.ml[ 0] + mv.ml[ 9] * p.ml[ 4] + mv.ml[10] * p.ml[ 8] + mv.ml[11] * p.ml[12];
  71. mvp.ml[ 9] = mv.ml[ 8] * p.ml[ 1] + mv.ml[ 9] * p.ml[ 5] + mv.ml[10] * p.ml[ 9] + mv.ml[11] * p.ml[13];
  72. mvp.ml[10] = mv.ml[ 8] * p.ml[ 2] + mv.ml[ 9] * p.ml[ 6] + mv.ml[10] * p.ml[10] + mv.ml[11] * p.ml[14];
  73. mvp.ml[11] = mv.ml[ 8] * p.ml[ 3] + mv.ml[ 9] * p.ml[ 7] + mv.ml[10] * p.ml[11] + mv.ml[11] * p.ml[15];
  74. mvp.ml[12] = mv.ml[12] * p.ml[ 0] + mv.ml[13] * p.ml[ 4] + mv.ml[14] * p.ml[ 8] + mv.ml[15] * p.ml[12];
  75. mvp.ml[13] = mv.ml[12] * p.ml[ 1] + mv.ml[13] * p.ml[ 5] + mv.ml[14] * p.ml[ 9] + mv.ml[15] * p.ml[13];
  76. mvp.ml[14] = mv.ml[12] * p.ml[ 2] + mv.ml[13] * p.ml[ 6] + mv.ml[14] * p.ml[10] + mv.ml[15] * p.ml[14];
  77. mvp.ml[15] = mv.ml[12] * p.ml[ 3] + mv.ml[13] * p.ml[ 7] + mv.ml[14] * p.ml[11] + mv.ml[15] * p.ml[15];
  78. //
  79. // Extract the frustum's right clipping plane and normalize it.
  80. //
  81. frustumPlanes[0][0] = mvp.ml[ 3] - mvp.ml[ 0];
  82. frustumPlanes[0][1] = mvp.ml[ 7] - mvp.ml[ 4];
  83. frustumPlanes[0][2] = mvp.ml[11] - mvp.ml[ 8];
  84. frustumPlanes[0][3] = mvp.ml[15] - mvp.ml[12];
  85. t = (Number) sqrt( frustumPlanes[0][0] * frustumPlanes[0][0] +
  86. frustumPlanes[0][1] * frustumPlanes[0][1] +
  87. frustumPlanes[0][2] * frustumPlanes[0][2] );
  88. frustumPlanes[0][0] /= t;
  89. frustumPlanes[0][1] /= t;
  90. frustumPlanes[0][2] /= t;
  91. frustumPlanes[0][3] /= t;
  92. //
  93. // Extract the frustum's left clipping plane and normalize it.
  94. //
  95. frustumPlanes[1][0] = mvp.ml[ 3] + mvp.ml[ 0];
  96. frustumPlanes[1][1] = mvp.ml[ 7] + mvp.ml[ 4];
  97. frustumPlanes[1][2] = mvp.ml[11] + mvp.ml[ 8];
  98. frustumPlanes[1][3] = mvp.ml[15] + mvp.ml[12];
  99. t = (Number) sqrt( frustumPlanes[1][0] * frustumPlanes[1][0] +
  100. frustumPlanes[1][1] * frustumPlanes[1][1] +
  101. frustumPlanes[1][2] * frustumPlanes[1][2] );
  102. frustumPlanes[1][0] /= t;
  103. frustumPlanes[1][1] /= t;
  104. frustumPlanes[1][2] /= t;
  105. frustumPlanes[1][3] /= t;
  106. //
  107. // Extract the frustum's bottom clipping plane and normalize it.
  108. //
  109. frustumPlanes[2][0] = mvp.ml[ 3] + mvp.ml[ 1];
  110. frustumPlanes[2][1] = mvp.ml[ 7] + mvp.ml[ 5];
  111. frustumPlanes[2][2] = mvp.ml[11] + mvp.ml[ 9];
  112. frustumPlanes[2][3] = mvp.ml[15] + mvp.ml[13];
  113. t = (Number) sqrt( frustumPlanes[2][0] * frustumPlanes[2][0] +
  114. frustumPlanes[2][1] * frustumPlanes[2][1] +
  115. frustumPlanes[2][2] * frustumPlanes[2][2] );
  116. frustumPlanes[2][0] /= t;
  117. frustumPlanes[2][1] /= t;
  118. frustumPlanes[2][2] /= t;
  119. frustumPlanes[2][3] /= t;
  120. //
  121. // Extract the frustum's top clipping plane and normalize it.
  122. //
  123. frustumPlanes[3][0] = mvp.ml[ 3] - mvp.ml[ 1];
  124. frustumPlanes[3][1] = mvp.ml[ 7] - mvp.ml[ 5];
  125. frustumPlanes[3][2] = mvp.ml[11] - mvp.ml[ 9];
  126. frustumPlanes[3][3] = mvp.ml[15] - mvp.ml[13];
  127. t = (Number) sqrt( frustumPlanes[3][0] * frustumPlanes[3][0] +
  128. frustumPlanes[3][1] * frustumPlanes[3][1] +
  129. frustumPlanes[3][2] * frustumPlanes[3][2] );
  130. frustumPlanes[3][0] /= t;
  131. frustumPlanes[3][1] /= t;
  132. frustumPlanes[3][2] /= t;
  133. frustumPlanes[3][3] /= t;
  134. //
  135. // Extract the frustum's far clipping plane and normalize it.
  136. //
  137. frustumPlanes[4][0] = mvp.ml[ 3] - mvp.ml[ 2];
  138. frustumPlanes[4][1] = mvp.ml[ 7] - mvp.ml[ 6];
  139. frustumPlanes[4][2] = mvp.ml[11] - mvp.ml[10];
  140. frustumPlanes[4][3] = mvp.ml[15] - mvp.ml[14];
  141. t = (Number) sqrt( frustumPlanes[4][0] * frustumPlanes[4][0] +
  142. frustumPlanes[4][1] * frustumPlanes[4][1] +
  143. frustumPlanes[4][2] * frustumPlanes[4][2] );
  144. frustumPlanes[4][0] /= t;
  145. frustumPlanes[4][1] /= t;
  146. frustumPlanes[4][2] /= t;
  147. frustumPlanes[4][3] /= t;
  148. //
  149. // Extract the frustum's near clipping plane and normalize it.
  150. //
  151. frustumPlanes[5][0] = mvp.ml[ 3] + mvp.ml[ 2];
  152. frustumPlanes[5][1] = mvp.ml[ 7] + mvp.ml[ 6];
  153. frustumPlanes[5][2] = mvp.ml[11] + mvp.ml[10];
  154. frustumPlanes[5][3] = mvp.ml[15] + mvp.ml[14];
  155. t = (Number) sqrt( frustumPlanes[5][0] * frustumPlanes[5][0] +
  156. frustumPlanes[5][1] * frustumPlanes[5][1] +
  157. frustumPlanes[5][2] * frustumPlanes[5][2] );
  158. frustumPlanes[5][0] /= t;
  159. frustumPlanes[5][1] /= t;
  160. frustumPlanes[5][2] /= t;
  161. frustumPlanes[5][3] /= t;
  162. }
  163. bool Camera::canSee(SceneEntity *entity) {
  164. return isSphereInFrustrum(*entity->getPosition(), entity->getBBoxRadius());
  165. }
  166. void Camera::setParentScene(Scene *parentScene) {
  167. this->parentScene = parentScene;
  168. }
  169. void Camera::setPostFilter(String shaderName) {
  170. Material *shaderMaterial = (Material*) CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_MATERIAL, shaderName);
  171. if(shaderMaterial)
  172. createPostFilter(shaderMaterial);
  173. }
  174. void Camera::createPostFilter(Material *shaderMaterial) {
  175. if(!shaderMaterial)
  176. return;
  177. if(shaderMaterial->getNumShaders() == 0)
  178. return;
  179. this->filterShaderMaterial = shaderMaterial;
  180. // TODO: make it save the textures to resource manager and check if they there
  181. // originalSceneTexture = CoreServices::getInstance()->getMaterialManager()->createNewTexture(CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes());
  182. // zBufferSceneTexture = CoreServices::getInstance()->getMaterialManager()->createFramebufferTexture(CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes(), 0);
  183. CoreServices::getInstance()->getRenderer()->createRenderTextures(&originalSceneTexture, &zBufferSceneTexture, CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes());
  184. for(int i=0; i < shaderMaterial->getNumShaders(); i++) {
  185. ShaderBinding* binding = shaderMaterial->getShader(i)->createBinding();
  186. binding->addTexture("PolySceneRender", originalSceneTexture);
  187. binding->addTexture("PolySceneZBuffer", zBufferSceneTexture);
  188. localShaderOptions.push_back(binding);
  189. }
  190. _hasFilterShader = true;
  191. }
  192. bool Camera::hasFilterShader() {
  193. return _hasFilterShader;
  194. }
  195. void Camera::setLightDepthTexture(Texture *texture) {
  196. for(int i=0; i < localShaderOptions.size(); i++) {
  197. localShaderOptions[i]->clearTexture("PolyLight0ZBuffer");
  198. localShaderOptions[i]->addTexture("PolyLight0ZBuffer", texture);
  199. }
  200. }
  201. void Camera::drawFilter() {
  202. if(!filterShaderMaterial)
  203. return;
  204. CoreServices::getInstance()->getRenderer()->bindFrameBufferTexture(zBufferSceneTexture);
  205. parentScene->Render();
  206. CoreServices::getInstance()->getRenderer()->unbindFramebuffers();
  207. ShaderBinding* materialBinding;
  208. for(int i=0; i < filterShaderMaterial->getNumShaders(); i++) {
  209. materialBinding = filterShaderMaterial->getShaderBinding(i);
  210. CoreServices::getInstance()->getRenderer()->applyMaterial(filterShaderMaterial, localShaderOptions[i], i);
  211. if(i==filterShaderMaterial->getNumShaders()-1) {
  212. CoreServices::getInstance()->getRenderer()->clearScreen();
  213. CoreServices::getInstance()->getRenderer()->loadIdentity();
  214. CoreServices::getInstance()->getRenderer()->drawScreenQuad(CoreServices::getInstance()->getRenderer()->getXRes(), CoreServices::getInstance()->getRenderer()->getYRes());
  215. } else {
  216. for(int j=0; j < materialBinding->getNumOutTargetBindings(); j++) {
  217. CoreServices::getInstance()->getRenderer()->bindFrameBufferTexture(materialBinding->getOutTargetBinding(j)->texture);
  218. CoreServices::getInstance()->getRenderer()->drawScreenQuad(materialBinding->getOutTargetBinding(j)->width, materialBinding->getOutTargetBinding(j)->height);
  219. CoreServices::getInstance()->getRenderer()->unbindFramebuffers();
  220. }
  221. }
  222. CoreServices::getInstance()->getRenderer()->clearShader();
  223. CoreServices::getInstance()->getRenderer()->loadIdentity();
  224. }
  225. }
  226. void Camera::doCameraTransform() {
  227. if(fovSet)
  228. CoreServices::getInstance()->getRenderer()->setFOV(fov);
  229. CoreServices::getInstance()->getRenderer()->setExposureLevel(exposureLevel);
  230. if(matrixDirty) {
  231. rebuildTransformMatrix();
  232. }
  233. Matrix4 camMatrix = getConcatenatedMatrix();
  234. CoreServices::getInstance()->getRenderer()->setCameraMatrix(camMatrix);
  235. camMatrix = camMatrix.inverse();
  236. CoreServices::getInstance()->getRenderer()->multModelviewMatrix(camMatrix);
  237. }