PolyScreen.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * PolyScreen.cpp
  3. * TAU
  4. *
  5. * Created by Ivan Safrin on 3/13/08.
  6. * Copyright 2008 __MyCompanyName__. All rights reserved.
  7. *
  8. */
  9. #include "PolyScreen.h"
  10. using namespace Polycode;
  11. Screen::Screen() : EventDispatcher() {
  12. offset.x = 0;
  13. offset.y = 0;
  14. enabled = true;
  15. focusChild = NULL;
  16. CoreServices::getInstance()->getScreenManager()->addScreen(this);
  17. filterShaderMaterial = NULL;
  18. _hasFilterShader = false;
  19. useNormalizedCoordinates = false;
  20. rootEntity = new ScreenEntity();
  21. addChild(rootEntity);
  22. }
  23. Screen::~Screen() {
  24. for(int i=0; i<children.size();i++) {
  25. // delete children[i];
  26. }
  27. }
  28. void Screen::setNormalizedCoordinates(bool newVal, Number yCoordinateSize) {
  29. useNormalizedCoordinates = newVal;
  30. this->yCoordinateSize = yCoordinateSize;
  31. }
  32. void Screen::handleInputEvent(InputEvent *inputEvent) {
  33. for(int i=children.size()-1; i >= 0; i--) {
  34. switch(inputEvent->getEventCode()) {
  35. case InputEvent::EVENT_MOUSEDOWN:
  36. if(children[i]->_onMouseDown(inputEvent->mousePosition.x-offset.x, inputEvent->mousePosition.y-offset.y, inputEvent->mouseButton, inputEvent->timestamp) &&
  37. children[i]->blockMouseInput)
  38. return;
  39. break;
  40. case InputEvent::EVENT_MOUSEMOVE:
  41. children[i]->_onMouseMove(inputEvent->mousePosition.x-offset.x, inputEvent->mousePosition.y-offset.y, inputEvent->timestamp);
  42. break;
  43. case InputEvent::EVENT_MOUSEUP:
  44. if(children[i]->_onMouseUp(inputEvent->mousePosition.x-offset.x, inputEvent->mousePosition.y-offset.y, inputEvent->mouseButton, inputEvent->timestamp) &&
  45. children[i]->blockMouseInput)
  46. return;
  47. break;
  48. case InputEvent::EVENT_MOUSEWHEEL_UP:
  49. children[i]->_onMouseWheelUp(inputEvent->mousePosition.x-offset.x, inputEvent->mousePosition.y-offset.y, inputEvent->timestamp);
  50. break;
  51. case InputEvent::EVENT_MOUSEWHEEL_DOWN:
  52. children[i]->_onMouseWheelDown(inputEvent->mousePosition.x-offset.x, inputEvent->mousePosition.y-offset.y,inputEvent->timestamp);
  53. break;
  54. case InputEvent::EVENT_KEYDOWN:
  55. children[i]->_onKeyDown(inputEvent->key, inputEvent->charCode);
  56. break;
  57. case InputEvent::EVENT_KEYUP:
  58. children[i]->_onKeyUp(inputEvent->key, inputEvent->charCode);
  59. break;
  60. }
  61. }
  62. }
  63. void Screen::setRenderer(Renderer *renderer) {
  64. this->renderer = renderer;
  65. }
  66. void Screen::setScreenOffset(Number x, Number y) {
  67. offset.x = x;
  68. offset.y = y;
  69. }
  70. Vector2 Screen::getScreenOffset() {
  71. return offset;
  72. }
  73. int Screen::getHighestZIndex() {
  74. int highestZ = 1;
  75. for(int i=0; i<children.size();i++) {
  76. if(children[i]->zindex > highestZ)
  77. highestZ = children[i]->zindex;
  78. }
  79. return highestZ;
  80. }
  81. bool Screen::cmpZindex(const ScreenEntity *left, const ScreenEntity *right) {
  82. return (left->zindex < right->zindex);
  83. }
  84. void Screen::sortChildren() {
  85. std::sort(children.begin(), children.end(), Screen::cmpZindex);
  86. int newz = 1;
  87. for(int i=0; i<children.size();i++) {
  88. children[i]->zindex = newz;
  89. newz++;
  90. }
  91. }
  92. void Screen::handleEvent(Event *event) {
  93. if(event->getEventType() == "ScreenEvent") {
  94. for(int i=0; i<children.size();i++) {
  95. if(children[i] == event->getDispatcher()) {
  96. ScreenEvent *screenEvent = (ScreenEvent*)event;
  97. int highestZ;
  98. switch(screenEvent->getEventCode()) {
  99. case ScreenEvent::ENTITY_MOVE_TOP:
  100. highestZ = getHighestZIndex();
  101. children[i]->zindex = highestZ+1;
  102. sortChildren();
  103. break;
  104. case ScreenEvent::ENTITY_MOVE_BOTTOM:
  105. children[i]->zindex = 0;
  106. sortChildren();
  107. break;
  108. case ScreenEvent::ENTITY_MOVE_UP:
  109. children[i]->zindex++;
  110. sortChildren();
  111. break;
  112. case ScreenEvent::ENTITY_MOVE_DOWN:
  113. children[i]->zindex--;
  114. sortChildren();
  115. break;
  116. }
  117. }
  118. }
  119. }
  120. }
  121. void Screen::setScreenShader(String shaderName) {
  122. filterShaderMaterial = (Material*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_MATERIAL, shaderName);
  123. if(!filterShaderMaterial)
  124. return;
  125. CoreServices::getInstance()->getRenderer()->createRenderTextures(&originalSceneTexture, &zBufferSceneTexture, CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes());
  126. for(int i=0; i < filterShaderMaterial->getNumShaders(); i++) {
  127. ShaderBinding* binding = filterShaderMaterial->getShader(i)->createBinding();
  128. binding->addTexture("tauSceneRender", originalSceneTexture);
  129. binding->addTexture("tauSceneZBuffer", zBufferSceneTexture);
  130. localShaderOptions.push_back(binding);
  131. }
  132. _hasFilterShader = true;
  133. }
  134. void Screen::drawFilter() {
  135. if(!filterShaderMaterial)
  136. return;
  137. CoreServices::getInstance()->getRenderer()->bindFrameBufferTexture(zBufferSceneTexture);
  138. Render();
  139. //CoreServices::getInstance()->getRenderer()->renderToTexture(originalSceneTexture);
  140. CoreServices::getInstance()->getRenderer()->unbindFramebuffers();
  141. ShaderBinding* materialBinding;
  142. for(int i=0; i < filterShaderMaterial->getNumShaders(); i++) {
  143. materialBinding = filterShaderMaterial->getShaderBinding(i);
  144. CoreServices::getInstance()->getRenderer()->applyMaterial(filterShaderMaterial, localShaderOptions[i], i);
  145. if(i==filterShaderMaterial->getNumShaders()-1) {
  146. // CoreServices::getInstance()->getRenderer()->clearScreen();
  147. CoreServices::getInstance()->getRenderer()->loadIdentity();
  148. CoreServices::getInstance()->getRenderer()->drawScreenQuad(CoreServices::getInstance()->getRenderer()->getXRes(), CoreServices::getInstance()->getRenderer()->getYRes());
  149. } else {
  150. for(int j=0; j < materialBinding->getNumOutTargetBindings(); j++) {
  151. // CoreServices::getInstance()->getRenderer()->clearScreen();
  152. // CoreServices::getInstance()->getRenderer()->loadIdentity();
  153. CoreServices::getInstance()->getRenderer()->bindFrameBufferTexture(materialBinding->getOutTargetBinding(j)->texture);
  154. // Logger::log("drawing quad (%s) %f,%f\n", materialBinding->getOutTargetBinding(j)->texture->getResourceName().c_str(), materialBinding->getOutTargetBinding(j)->width, materialBinding->getOutTargetBinding(j)->height);
  155. CoreServices::getInstance()->getRenderer()->drawScreenQuad(materialBinding->getOutTargetBinding(j)->width, materialBinding->getOutTargetBinding(j)->height);
  156. CoreServices::getInstance()->getRenderer()->unbindFramebuffers();
  157. // CoreServices::getInstance()->getRenderer()->renderToTexture(materialBinding->getOutTargetBinding(j)->texture);
  158. }
  159. }
  160. CoreServices::getInstance()->getRenderer()->clearShader();
  161. CoreServices::getInstance()->getRenderer()->loadIdentity();
  162. CoreServices::getInstance()->getRenderer()->setOrthoMode();
  163. /*
  164. CoreServices::getInstance()->getRenderer()->renderToTexture(filterTexture);
  165. CoreServices::getInstance()->getRenderer()->clearScreen();
  166. CoreServices::getInstance()->getRenderer()->loadIdentity();
  167. CoreServices::getInstance()->getRenderer()->drawScreenQuad();
  168. CoreServices::getInstance()->getRenderer()->clearShader();
  169. CoreServices::getInstance()->getRenderer()->loadIdentity();
  170. */
  171. }
  172. }
  173. bool Screen::hasFilterShader() {
  174. return _hasFilterShader;
  175. }
  176. ScreenEntity* Screen::addChild(ScreenEntity *newEntity) {
  177. if(!newEntity)
  178. return NULL;
  179. children.push_back(newEntity);
  180. newEntity->setRenderer(renderer);
  181. newEntity->addEventListener(this, ScreenEvent::ENTITY_MOVE_TOP);
  182. newEntity->addEventListener(this, ScreenEvent::ENTITY_MOVE_BOTTOM);
  183. newEntity->addEventListener(this, ScreenEvent::ENTITY_MOVE_DOWN);
  184. newEntity->addEventListener(this, ScreenEvent::ENTITY_MOVE_UP);
  185. newEntity->zindex = getHighestZIndex()+1;
  186. sortChildren();
  187. return newEntity;
  188. }
  189. ScreenEntity* Screen::removeChild(ScreenEntity *entityToRemove) {
  190. if(!entityToRemove)
  191. return NULL;
  192. entityToRemove->removeEventListener(this, ScreenEvent::ENTITY_MOVE_TOP);
  193. entityToRemove->removeEventListener(this, ScreenEvent::ENTITY_MOVE_BOTTOM);
  194. entityToRemove->removeEventListener(this, ScreenEvent::ENTITY_MOVE_DOWN);
  195. entityToRemove->removeEventListener(this, ScreenEvent::ENTITY_MOVE_UP);
  196. for(int i=0;i<children.size();i++) {
  197. if(children[i] == entityToRemove) {
  198. children.erase(children.begin()+i);
  199. }
  200. }
  201. return entityToRemove;
  202. }
  203. void Screen::Shutdown() {
  204. }
  205. void Screen::Update() {
  206. }
  207. ScreenEntity *Screen::getEntityAt(Number x, Number y) {
  208. for(int i=children.size()-1; i >= 0;i--) {
  209. if(children[i]->hitTest(x,y))
  210. return children[i];
  211. }
  212. return NULL;
  213. }
  214. void Screen::Render() {
  215. Update();
  216. renderer->loadIdentity();
  217. renderer->translate2D(offset.x, offset.y);
  218. renderer->multModelviewMatrix(rootEntity->getConcatenatedMatrix());
  219. for(int i=0; i<children.size();i++) {
  220. if(children[i]->hasFocus && focusChild != children[i] && children[i]->isFocusable()) {
  221. if(focusChild != NULL) {
  222. focusChild->hasFocus = false;
  223. focusChild->onLoseFocus();
  224. }
  225. focusChild = children[i];
  226. focusChild->onGainFocus();
  227. }
  228. children[i]->doUpdates();
  229. children[i]->updateEntityMatrix();
  230. children[i]->transformAndRender();
  231. }
  232. }