LightSample.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. #include "LightSample.h"
  2. #include "SamplesGame.h"
  3. #if defined(ADD_SAMPLE)
  4. ADD_SAMPLE("Graphics", "Light", LightSample, 11);
  5. #endif
  6. LightSample::LightSample()
  7. : _font(NULL),
  8. _scene(NULL),
  9. _modelNode(NULL),
  10. _directionalLightNode(NULL),
  11. _pointLightNode(NULL),
  12. _spotLightNode(NULL),
  13. _usedForMoving(NULL),
  14. _model(NULL),
  15. _directionalLightQuadModel(NULL),
  16. _spotLightQuadModel(NULL),
  17. _pointLightQuadModel(NULL),
  18. _unlitMaterial(NULL),
  19. _texturedMaterial(NULL),
  20. _bumpedMaterial(NULL),
  21. _bumpedSpecularMaterial(NULL),
  22. _lighting(NULL),
  23. _noLight(NULL),
  24. _directional(NULL),
  25. _spot(NULL),
  26. _point(NULL),
  27. _properties(NULL),
  28. _redSlider(NULL),
  29. _greenSlider(NULL),
  30. _blueSlider(NULL),
  31. _specularSlider(NULL),
  32. _addSpecular(NULL),
  33. _addBumped(NULL),
  34. _form(NULL),
  35. _touched(false),
  36. _touchX(0),
  37. _touchY(0)
  38. {
  39. }
  40. void LightSample::initialize()
  41. {
  42. // Create the font for drawing the framerate.
  43. _font = Font::create("res/common/arial.gpb");
  44. // Load the scene
  45. _scene = Scene::load("res/common/lightBrickWall.gpb");
  46. // Get the wall model node
  47. _modelNode = _scene->findNode("wall");
  48. _model = _modelNode->getModel();
  49. // Create a directional light and a reference icon for the light
  50. Light* directionalLight = Light::createDirectional(Vector3::one());
  51. _directionalLightNode = Node::create("directionalLight");
  52. _directionalLightNode->setLight(directionalLight);
  53. SAFE_RELEASE(directionalLight);
  54. Mesh* directionalLightQuadMesh = Mesh::createQuad(-0.3f, -0.3f, 0.6f, 0.6f);
  55. _directionalLightQuadModel = Model::create(directionalLightQuadMesh);
  56. SAFE_RELEASE(directionalLightQuadMesh);
  57. setUnlitMaterialTexture(_directionalLightQuadModel, "res/png/light-directional.png");
  58. _directionalLightNode->setModel(_directionalLightQuadModel);
  59. _directionalLightNode->setTranslation(0.0f, 0.0f, 7.0f);
  60. _scene->addNode(_directionalLightNode);
  61. // Create a spotlight and create a reference icon for the light
  62. Light* spotLight = Light::createSpot(Vector3::one(), 100.0f, MATH_DEG_TO_RAD(30.0f), MATH_DEG_TO_RAD(40.0f));
  63. _spotLightNode = Node::create("spotLight");
  64. _spotLightNode->setLight(spotLight);
  65. SAFE_RELEASE(spotLight);
  66. Mesh* spotLightQuadMesh = Mesh::createQuad(-0.3f, -0.3f, 0.6f, 0.6f);
  67. _spotLightQuadModel = Model::create(spotLightQuadMesh);
  68. SAFE_RELEASE(spotLightQuadMesh);
  69. setUnlitMaterialTexture(_spotLightQuadModel, "res/png/light-spot.png");
  70. _spotLightNode->setModel(_spotLightQuadModel);
  71. _spotLightNode->setTranslation(0.0f, 0.0f, 8.0f);
  72. _scene->addNode(_spotLightNode);
  73. // Create a point light and create a reference icon for the light
  74. Light* pointLight = Light::createPoint(Vector3::one(), 16.0f);
  75. _pointLightNode = Node::create("pointLight");
  76. _pointLightNode->setLight(pointLight);
  77. SAFE_RELEASE(pointLight);
  78. Mesh* pointLightQuadMesh = Mesh::createQuad(-0.3f, -0.3f, 0.6f, 0.6f);
  79. _pointLightQuadModel = Model::create(pointLightQuadMesh);
  80. SAFE_RELEASE(pointLightQuadMesh);
  81. setUnlitMaterialTexture(_pointLightQuadModel, "res/png/light-point.png");
  82. _pointLightNode->setModel(_pointLightQuadModel);
  83. _pointLightNode->setTranslation(0.0f, 0.0f, 8.0f);
  84. _scene->addNode(_pointLightNode);
  85. // Create and initialize ui form
  86. _form = Form::create("res/common/light.form");
  87. _properties = static_cast<Container*>(_form->getControl("lightProperties"));
  88. _redSlider = static_cast<Slider*>(_form->getControl("redSlider"));
  89. _redSlider->addListener(this, Control::Listener::VALUE_CHANGED);
  90. _greenSlider = static_cast<Slider*>(_form->getControl("greenSlider"));
  91. _greenSlider->addListener(this, Control::Listener::VALUE_CHANGED);
  92. _blueSlider = static_cast<Slider*>(_form->getControl("blueSlider"));
  93. _blueSlider->addListener(this, Control::Listener::VALUE_CHANGED);
  94. _specularSlider = static_cast<Slider*>(_form->getControl("specularSlider"));
  95. _specularSlider->addListener(this, Control::Listener::VALUE_CHANGED);
  96. _noLight = static_cast<RadioButton*>(_form->getControl("noLighting"));
  97. _noLight->addListener(this, Control::Listener::VALUE_CHANGED);
  98. _directional = static_cast<RadioButton*>(_form->getControl("directional"));
  99. _directional->addListener(this, Control::Listener::VALUE_CHANGED);
  100. _spot = static_cast<RadioButton*>(_form->getControl("spot"));
  101. _spot->addListener(this, Control::Listener::VALUE_CHANGED);
  102. _point = static_cast<RadioButton*>(_form->getControl("point"));
  103. _point->addListener(this, Control::Listener::VALUE_CHANGED);
  104. _addSpecular = static_cast<CheckBox*>(_form->getControl("specularCheckBox"));
  105. _addSpecular->addListener(this, Control::Listener::VALUE_CHANGED);
  106. _addBumped = static_cast<CheckBox*>(_form->getControl("bumpedCheckBox"));
  107. _addBumped->addListener(this, Control::Listener::VALUE_CHANGED);
  108. _properties->setEnabled(false);
  109. _noLight->setSelected(true);
  110. _form->setConsumeInputEvents(false);
  111. // Create and initialize lights and materials for lights
  112. _lighting = Material::create("res/common/light.material");
  113. _model->setMaterial(_lighting);
  114. initializeDirectionalTechnique("directional");
  115. initializeDirectionalTechnique("directionalSpecular");
  116. initializeDirectionalTechnique("directionalBumped");
  117. initializeDirectionalTechnique("directionalSpecularBumped");
  118. initializeSpotTechnique("spot");
  119. initializeSpotTechnique("spotSpecular");
  120. initializeSpotTechnique("spotBumped");
  121. initializeSpotTechnique("spotSpecularBumped");
  122. initializePointTechnique("point");
  123. initializePointTechnique("pointSpecular");
  124. initializePointTechnique("pointBumped");
  125. initializePointTechnique("pointSpecularBumped");
  126. setSpecularValue(_specularSlider->getValue());
  127. }
  128. void LightSample::finalize()
  129. {
  130. SAFE_RELEASE(_directionalLightQuadModel);
  131. SAFE_RELEASE(_directionalLightNode);
  132. SAFE_RELEASE(_spotLightQuadModel);
  133. SAFE_RELEASE(_spotLightNode);
  134. SAFE_RELEASE(_pointLightQuadModel);
  135. SAFE_RELEASE(_pointLightNode);
  136. SAFE_RELEASE(_lighting);
  137. SAFE_RELEASE(_font);
  138. SAFE_RELEASE(_scene);
  139. SAFE_RELEASE(_form);
  140. }
  141. void LightSample::update(float elapsedTime)
  142. {
  143. }
  144. void LightSample::render(float elapsedTime)
  145. {
  146. // Clear the color and depth buffers
  147. clear(CLEAR_COLOR_DEPTH, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0);
  148. _model->draw();
  149. if(_directional->isSelected())
  150. {
  151. _directionalLightQuadModel->draw();
  152. }
  153. else if (_spot->isSelected())
  154. {
  155. _spotLightQuadModel->draw();
  156. }
  157. else if (_point->isSelected())
  158. {
  159. _pointLightQuadModel->draw();
  160. }
  161. _form->draw();
  162. drawFrameRate(_font, Vector4(0, 0.5f, 1, 1), 5, 1, getFrameRate());
  163. }
  164. void LightSample::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  165. {
  166. switch (evt)
  167. {
  168. case Touch::TOUCH_PRESS:
  169. {
  170. _touched = true;
  171. _touchX = x;
  172. _touchY = y;
  173. Ray pickRay;
  174. _scene->getActiveCamera()->pickRay(getViewport(), _touchX, _touchY, &pickRay);
  175. if (_directional->isSelected() && pickRay.intersects(_directionalLightQuadModel->getMesh()->getBoundingBox()))
  176. {
  177. _usedForMoving = _directionalLightNode;
  178. }
  179. else if (_spot->isSelected() && pickRay.intersects(_spotLightQuadModel->getMesh()->getBoundingBox()))
  180. {
  181. _usedForMoving = _spotLightNode;
  182. }
  183. else if (_point->isSelected() && pickRay.intersects(_pointLightQuadModel->getMesh()->getBoundingBox()))
  184. {
  185. _usedForMoving = _pointLightNode;
  186. }
  187. else
  188. {
  189. _usedForMoving = NULL;
  190. }
  191. }
  192. break;
  193. case Touch::TOUCH_RELEASE:
  194. {
  195. _touched = false;
  196. _touchX = 0;
  197. _touchY = 0;
  198. _usedForMoving = NULL;
  199. }
  200. break;
  201. case Touch::TOUCH_MOVE:
  202. {
  203. int deltaX = x - _touchX;
  204. _touchX = x;
  205. int deltaY = y - _touchY;
  206. _touchY = y;
  207. Matrix m;
  208. _modelNode->getWorldMatrix().transpose(&m);
  209. // Yaw in world frame
  210. Vector3 yaw;
  211. m.getUpVector(&yaw);
  212. _modelNode->rotate(yaw, MATH_DEG_TO_RAD(deltaX * 0.5f));
  213. // Roll in world frame
  214. Vector3 pitch;
  215. m.getRightVector(&pitch);
  216. _modelNode->rotate(pitch, MATH_DEG_TO_RAD(deltaY * 0.5f));
  217. }
  218. break;
  219. default:
  220. break;
  221. };
  222. }
  223. void LightSample::keyEvent(Keyboard::KeyEvent evt, int key)
  224. {
  225. switch(evt)
  226. {
  227. case Keyboard::KEY_PRESS:
  228. switch (key)
  229. {
  230. case Keyboard::KEY_ESCAPE:
  231. exit();
  232. break;
  233. }
  234. break;
  235. case Keyboard::KEY_RELEASE:
  236. break;
  237. }
  238. }
  239. void LightSample::controlEvent(Control* control, EventType evt)
  240. {
  241. bool changeTechnique = false;
  242. switch(evt)
  243. {
  244. case Control::Listener::VALUE_CHANGED:
  245. if ((control == _redSlider) || (control == _greenSlider) || (control == _blueSlider))
  246. {
  247. Vector3 color(_redSlider->getValue(), _greenSlider->getValue(), _blueSlider->getValue());
  248. setColorValue(color);
  249. }
  250. else if (control == _specularSlider)
  251. {
  252. setSpecularValue(_specularSlider->getValue());
  253. }
  254. else if (control == _noLight)
  255. {
  256. changeTechnique = true;
  257. if (_noLight->isSelected())
  258. {
  259. _properties->setEnabled(false);
  260. }
  261. }
  262. else if ((control == _directional) || (control == _spot) || (control == _point))
  263. {
  264. changeTechnique = true;
  265. if (!_noLight->isSelected())
  266. {
  267. _properties->setEnabled(true);
  268. }
  269. }
  270. else if ((control == _addSpecular) || (control == _addBumped))
  271. {
  272. changeTechnique = true;
  273. }
  274. break;
  275. }
  276. if (_lighting && changeTechnique)
  277. {
  278. if (_noLight->isSelected())
  279. {
  280. _lighting->setTechnique("unlit");
  281. }
  282. else if (_directional->isSelected() && !_addSpecular->isChecked() && !_addBumped->isChecked())
  283. {
  284. _lighting->setTechnique("directional");
  285. }
  286. else if (_directional->isSelected() && _addSpecular->isChecked() && !_addBumped->isChecked())
  287. {
  288. _lighting->setTechnique("directionalSpecular");
  289. }
  290. else if (_directional->isSelected() && !_addSpecular->isChecked() && _addBumped->isChecked())
  291. {
  292. _lighting->setTechnique("directionalBumped");
  293. }
  294. else if (_directional->isSelected() && _addSpecular->isChecked() && _addBumped->isChecked())
  295. {
  296. _lighting->setTechnique("directionalSpecularBumped");
  297. }
  298. else if (_spot->isSelected() && !_addSpecular->isChecked() && !_addBumped->isChecked())
  299. {
  300. _lighting->setTechnique("spot");
  301. }
  302. else if (_spot->isSelected() && _addSpecular->isChecked() && !_addBumped->isChecked())
  303. {
  304. _lighting->setTechnique("spotSpecular");
  305. }
  306. else if (_spot->isSelected() && !_addSpecular->isChecked() && _addBumped->isChecked())
  307. {
  308. _lighting->setTechnique("spotBumped");
  309. }
  310. else if (_spot->isSelected() && _addSpecular->isChecked() && _addBumped->isChecked())
  311. {
  312. _lighting->setTechnique("spotSpecularBumped");
  313. }
  314. else if (_point->isSelected() && !_addSpecular->isChecked() && !_addBumped->isChecked())
  315. {
  316. _lighting->setTechnique("point");
  317. }
  318. else if (_point->isSelected() && _addSpecular->isChecked() && !_addBumped->isChecked())
  319. {
  320. _lighting->setTechnique("pointSpecular");
  321. }
  322. else if (_point->isSelected() && !_addSpecular->isChecked() && _addBumped->isChecked())
  323. {
  324. _lighting->setTechnique("pointBumped");
  325. }
  326. else if (_point->isSelected() && _addSpecular->isChecked() && _addBumped->isChecked())
  327. {
  328. _lighting->setTechnique("pointSpecularBumped");
  329. }
  330. }
  331. }
  332. void LightSample::initializeDirectionalTechnique(const char* technique)
  333. {
  334. _lighting->getTechnique(technique)->getParameter("u_lightDirection")->bindValue(_directionalLightNode, &Node::getForwardVectorWorld);
  335. _lighting->getTechnique(technique)->getParameter("u_lightColor")->setValue(Vector3(_redSlider->getValue(), _greenSlider->getValue(), _blueSlider->getValue()));
  336. _lighting->getTechnique(technique)->getParameter("u_ambientColor")->setValue(Vector3(0.0f, 0.0f, 0.0f));
  337. }
  338. void LightSample::initializeSpotTechnique(const char* technique)
  339. {
  340. _lighting->getTechnique(technique)->getParameter("u_spotLightInnerAngleCos")->setValue(_spotLightNode->getLight()->getInnerAngleCos());
  341. _lighting->getTechnique(technique)->getParameter("u_spotLightOuterAngleCos")->setValue(_spotLightNode->getLight()->getOuterAngleCos());
  342. _lighting->getTechnique(technique)->getParameter("u_spotLightRangeInverse")->setValue(_spotLightNode->getLight()->getRangeInverse());
  343. _lighting->getTechnique(technique)->getParameter("u_spotLightDirection")->bindValue(_spotLightNode, &Node::getForwardVectorView);
  344. _lighting->getTechnique(technique)->getParameter("u_spotLightPosition")->bindValue(_spotLightNode, &Node::getTranslationView);
  345. _lighting->getTechnique(technique)->getParameter("u_ambientColor")->setValue(Vector3(0.0f, 0.0f, 0.0f));
  346. _lighting->getTechnique(technique)->getParameter("u_lightColor")->setValue(Vector3(_redSlider->getValue(), _greenSlider->getValue(), _blueSlider->getValue()));
  347. }
  348. void LightSample::initializePointTechnique(const char* technique)
  349. {
  350. _lighting->getTechnique(technique)->getParameter("u_pointLightPosition")->bindValue(_pointLightNode, &Node::getTranslationView);
  351. _lighting->getTechnique(technique)->getParameter("u_pointLightRangeInverse")->setValue(_pointLightNode->getLight()->getRangeInverse());
  352. _lighting->getTechnique(technique)->getParameter("u_ambientColor")->setValue(Vector3(0.0f, 0.0f, 0.0f));
  353. _lighting->getTechnique(technique)->getParameter("u_lightColor")->setValue(Vector3(_redSlider->getValue(), _greenSlider->getValue(), _blueSlider->getValue()));
  354. }
  355. void LightSample::setUnlitMaterialTexture(Model* model, const char* texturePath, bool mipmap)
  356. {
  357. Material* material = model->setMaterial("res/shaders/textured-unlit.vert", "res/shaders/textured-unlit.frag");
  358. material->setParameterAutoBinding("u_worldViewProjectionMatrix", "WORLD_VIEW_PROJECTION_MATRIX");
  359. // Load the texture from file.
  360. Texture::Sampler* sampler = material->getParameter("u_diffuseTexture")->setValue(texturePath, mipmap);
  361. if (mipmap)
  362. {
  363. sampler->setFilterMode(Texture::LINEAR_MIPMAP_LINEAR, Texture::LINEAR);
  364. }
  365. else
  366. {
  367. sampler->setFilterMode(Texture::LINEAR, Texture::LINEAR);
  368. }
  369. sampler->setWrapMode(Texture::CLAMP, Texture::CLAMP);
  370. material->getStateBlock()->setCullFace(true);
  371. material->getStateBlock()->setDepthTest(true);
  372. material->getStateBlock()->setDepthWrite(true);
  373. material->getStateBlock()->setBlend(true);
  374. material->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
  375. material->getStateBlock()->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA);
  376. }
  377. void LightSample::setColorValue(const Vector3& value)
  378. {
  379. _lighting->getTechnique(("directional"))->getParameter("u_lightColor")->setValue(value);
  380. _lighting->getTechnique(("directionalSpecular"))->getParameter("u_lightColor")->setValue(value);
  381. _lighting->getTechnique(("directionalBumped"))->getParameter("u_lightColor")->setValue(value);
  382. _lighting->getTechnique(("directionalSpecularBumped"))->getParameter("u_lightColor")->setValue(value);
  383. _lighting->getTechnique(("spot"))->getParameter("u_lightColor")->setValue(value);
  384. _lighting->getTechnique(("spotSpecular"))->getParameter("u_lightColor")->setValue(value);
  385. _lighting->getTechnique(("spotBumped"))->getParameter("u_lightColor")->setValue(value);
  386. _lighting->getTechnique(("spotSpecularBumped"))->getParameter("u_lightColor")->setValue(value);
  387. _lighting->getTechnique(("point"))->getParameter("u_lightColor")->setValue(value);
  388. _lighting->getTechnique(("pointSpecular"))->getParameter("u_lightColor")->setValue(value);
  389. _lighting->getTechnique(("pointBumped"))->getParameter("u_lightColor")->setValue(value);
  390. _lighting->getTechnique(("pointSpecularBumped"))->getParameter("u_lightColor")->setValue(value);
  391. }
  392. void LightSample::setSpecularValue(float value)
  393. {
  394. _lighting->getTechnique("directionalSpecular")->getParameter("u_specularExponent")->setValue(value);
  395. _lighting->getTechnique("directionalSpecularBumped")->getParameter("u_specularExponent")->setValue(value);
  396. _lighting->getTechnique("spotSpecular")->getParameter("u_specularExponent")->setValue(value);
  397. _lighting->getTechnique("spotSpecularBumped")->getParameter("u_specularExponent")->setValue(value);
  398. _lighting->getTechnique("pointSpecular")->getParameter("u_specularExponent")->setValue(value);
  399. _lighting->getTechnique("pointSpecularBumped")->getParameter("u_specularExponent")->setValue(value);
  400. }