LightSample.cpp 17 KB

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