TestUserShader2.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #pragma once
  2. #include "test.h"
  3. class LightningMaterial : public Material
  4. {
  5. public:
  6. const VertexDeclaration* _vdecl;
  7. ShaderProgramGL* _lightShader;
  8. Vector2 _light;
  9. vector<vertexPCT2T2> _vertices;
  10. AnimationFrame _normal;
  11. spNativeTexture _base;
  12. LightningMaterial()
  13. {
  14. _normal = resources.getResAnim("normal")->getFrame(0);
  15. _light = getStage()->getSize() / 2;
  16. IVideoDriver* driver = IVideoDriver::instance;
  17. _vdecl = driver->getVertexDeclaration(vertexPCT2T2::FORMAT);
  18. //load vertex shader
  19. file::buffer vsdata;
  20. file::read("light_vs.glsl", vsdata);
  21. vsdata.push_back(0);///null terminating string
  22. unsigned int vs = ShaderProgramGL::createShader(GL_VERTEX_SHADER, (const char*)&vsdata.front(), "", "");
  23. //load fragment shader
  24. file::buffer fsdata;
  25. file::read("light_fs.glsl", fsdata);
  26. fsdata.push_back(0);///null terminating string
  27. unsigned int ps = ShaderProgramGL::createShader(GL_FRAGMENT_SHADER, (const char*)&fsdata.front(), "", "");
  28. //link into 1 shader program
  29. unsigned int pr = ShaderProgramGL::createProgram(vs, ps, static_cast<const VertexDeclarationGL*>(IVideoDriver::instance->getVertexDeclaration(vertexPCT2T2::FORMAT)));
  30. _lightShader = new ShaderProgramGL(pr);
  31. //set shader and apply samplers uniforms
  32. driver->setShaderProgram(_lightShader);
  33. driver->setUniformInt("base_texture", 0);
  34. driver->setUniformInt("normal_texture", 1);
  35. }
  36. void apply(Material* prev) override
  37. {
  38. IVideoDriver* driver = IVideoDriver::instance;
  39. driver->setShaderProgram(_lightShader);
  40. Vector2 light = getStage()->getDescendant("light")->getPosition();
  41. driver->setUniform("light", light);
  42. driver->setUniform("mat", STDRenderer::getCurrent()->getViewProjection());
  43. driver->setTexture(1, _normal.getDiffuse().base);
  44. driver->setState(IVideoDriver::STATE_BLEND, 0);
  45. driver->setBlendFunc(IVideoDriver::BT_ONE, IVideoDriver::BT_ONE_MINUS_SRC_ALPHA);
  46. driver->setBlendFunc(IVideoDriver::BT_SRC_ALPHA, IVideoDriver::BT_ONE_MINUS_SRC_ALPHA);
  47. }
  48. void finish() override
  49. {
  50. drawBatch(IVideoDriver::instance);
  51. }
  52. void drawBatch(IVideoDriver* driver)
  53. {
  54. size_t count = _vertices.size();
  55. if (!count)
  56. return;
  57. size_t indices = (count * 3) / 2;
  58. driver->setTexture(0, _base);
  59. driver->draw(IVideoDriver::PT_TRIANGLES, _vdecl, &_vertices.front(), (unsigned int)count, &STDRenderer::indices16.front(), (unsigned int)indices);
  60. _vertices.clear();
  61. }
  62. void doRender(Sprite* sprite, const RenderState& rs) override
  63. {
  64. Material::setCurrent(this);
  65. vertexPCT2T2 v[4];
  66. const AnimationFrame& frame = sprite->getAnimFrame();
  67. if (frame.getDiffuse().base != _base)
  68. {
  69. drawBatch(IVideoDriver::instance);
  70. _base = frame.getDiffuse().base;
  71. }
  72. fillQuadT2(v, frame.getSrcRect(), _normal.getSrcRect(), sprite->getDestRect(), rs.transform, 0xffFFffFF);
  73. _vertices.insert(_vertices.end(), v, v + 4);
  74. }
  75. };
  76. class TestUserShader2 : public Test
  77. {
  78. public:
  79. Draggable drag;
  80. TestUserShader2()
  81. {
  82. LightningMaterial* mat = new LightningMaterial;
  83. spSprite spr = new Sprite();
  84. spr->setResAnim(resources.getResAnim("tiled2"));
  85. spr->setScale(2);
  86. spr->setAnchor(0.5f, 0.5f);
  87. spr->setPosition(content->getSize() / 2);
  88. spr->attachTo(content);
  89. spr->setMaterial(mat);
  90. spr = new Sprite();
  91. spr->setResAnim(resources.getResAnim("tiled2"));
  92. spr->setScale(2);
  93. spr->setAnchor(0.5f, 0.5f);
  94. spr->setPosition(content->getSize() / 2 + Vector2(300, 50));
  95. spr->attachTo(content);
  96. spr->setMaterial(mat);
  97. spr = new Sprite();
  98. spr->setResAnim(resources.getResAnim("tiled2"));
  99. spr->setScale(2);
  100. spr->setAnchor(0.5f, 0.5f);
  101. spr->setPosition(content->getSize() / 2 + Vector2(-200, 50));
  102. spr->attachTo(content);
  103. spr->setMaterial(mat);
  104. spSprite light = new Sprite;
  105. light->setName("light");
  106. light->setResAnim(resources.getResAnim("light"));
  107. light->setAnchor(0.5f, 0.5f);
  108. drag.init(light.get());
  109. light->setPosition(getSize() / 2);
  110. content->addChild(light);
  111. }
  112. };