SSAOShader.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include <random>
  2. #include "client/engine/shader/SSAOShader.h"
  3. #include "client/engine/Wrapper.h"
  4. SSAOShader::SSAOShader()
  5. {
  6. }
  7. SSAOShader::~SSAOShader()
  8. {
  9. glDeleteFramebuffers(1, &framebuffer);
  10. glDeleteTextures(1, &texture);
  11. glDeleteTextures(1, &noiseTexture);
  12. }
  13. bool SSAOShader::init()
  14. {
  15. program.compile("resources/shader/ssaoVertex.vs", "resources/shader/ssaoFragment.fs");
  16. if(!program.isValid())
  17. {
  18. return false;
  19. }
  20. // generate framebuffer
  21. glGenFramebuffers(1, &framebuffer);
  22. glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
  23. // color texture
  24. glGenTextures(1, &texture);
  25. glBindTexture(GL_TEXTURE_2D, texture);
  26. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, Engine::getWidth(), Engine::getHeight(), 0, GL_RGB, GL_FLOAT, NULL);
  27. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  28. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  29. // attache color texture to framebuffer
  30. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
  31. // check if framebuffer is okay
  32. if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  33. {
  34. cout << "ssao frame buffer is not complete!" << endl;
  35. return false;
  36. }
  37. // unbind framebuffer
  38. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  39. // generate noise data
  40. std::uniform_real_distribution<float> randomF(0.0, 1.0);
  41. std::default_random_engine gen;
  42. float noise[48];
  43. for(int i = 0; i < 16; i++)
  44. {
  45. noise[i * 3] = randomF(gen) * 2.0 - 1.0;
  46. noise[i * 3 + 1] = randomF(gen) * 2.0 - 1.0;
  47. noise[i * 3 + 2] = 0.0f;
  48. }
  49. // noise texture
  50. glGenTextures(1, &noiseTexture);
  51. glBindTexture(GL_TEXTURE_2D, noiseTexture);
  52. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 4, 4, 0, GL_RGB, GL_FLOAT, noise);
  53. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  54. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  55. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  56. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  57. // get uniform locations
  58. unifProjMatrix = glGetUniformLocation(program.getProgram(), "projMatrix");
  59. unifNumberOfSamples = glGetUniformLocation(program.getProgram(), "numberOfSamples");
  60. unifRadius = glGetUniformLocation(program.getProgram(), "radius");
  61. unifWidth = glGetUniformLocation(program.getProgram(), "width");
  62. unifHeight = glGetUniformLocation(program.getProgram(), "height");
  63. return true;
  64. }
  65. void SSAOShader::resize()
  66. {
  67. glBindTexture(GL_TEXTURE_2D, texture);
  68. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, Engine::getWidth(), Engine::getHeight(), 0, GL_RGB, GL_FLOAT, NULL);
  69. }
  70. void SSAOShader::preRender(const float* projMatrix)
  71. {
  72. // bind ssao shader program
  73. glUseProgram(program.getProgram());
  74. // set projection matrix uniform
  75. glUniformMatrix4fv(unifProjMatrix, 1, 0, projMatrix);
  76. // set other uniforms
  77. glUniform1i(unifNumberOfSamples, numberOfSamples);
  78. glUniform1f(unifRadius, radius);
  79. glUniform1i(unifWidth, Engine::getWidth());
  80. glUniform1i(unifHeight, Engine::getHeight());
  81. // bind ssao framebuffer
  82. glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
  83. // clear color buffer
  84. glClear(GL_COLOR_BUFFER_BIT);
  85. // depth testing is not needed
  86. glDisable(GL_DEPTH_TEST);
  87. }
  88. void SSAOShader::bindTexture(unsigned int textureUnit)
  89. {
  90. glActiveTexture(GL_TEXTURE0 + textureUnit);
  91. glBindTexture(GL_TEXTURE_2D, texture);
  92. }
  93. void SSAOShader::bindNoiseTexture(unsigned int textureUnit)
  94. {
  95. glActiveTexture(GL_TEXTURE0 + textureUnit);
  96. glBindTexture(GL_TEXTURE_2D, noiseTexture);
  97. }
  98. void SSAOShader::setNumberOfSamples(int amount)
  99. {
  100. numberOfSamples = min(max(amount, 0), 64);
  101. }
  102. int SSAOShader::getNumberOfSamples() const
  103. {
  104. return numberOfSamples;
  105. }
  106. void SSAOShader::setSampleRadius(float sampleRadius)
  107. {
  108. numberOfSamples = min(max(sampleRadius, 0.05f), 20.0f);
  109. }
  110. float SSAOShader::getSampleRadius() const
  111. {
  112. return radius;
  113. }