diff --git a/src/graphics/IBL.cpp b/src/graphics/IBL.cpp index 20e4e0956..3f37d068a 100644 --- a/src/graphics/IBL.cpp +++ b/src/graphics/IBL.cpp @@ -22,6 +22,26 @@ #include #include "central_settings.hpp" + +class SpecularIBLGenerator : public Shader, + public TextureReadNew +{ +public: + GLuint m_tu_samples; + SpecularIBLGenerator() + { + loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert", + GL_FRAGMENT_SHADER, "importance_sampling_specular.frag"); + assignUniforms("PermutationMatrix", "ViewportSize"); + m_tu_samples = 1; + assignSamplerNames(m_program, 0, "tex", ST_TRILINEAR_CUBEMAP); + assignTextureUnit(m_tu_samples, "samples"); + } + +}; // SpecularIBLGenerator + +// ============================================================================ static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z) { switch (face) @@ -61,9 +81,10 @@ static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z) float norm = sqrt(x * x + y * y + z * z); x /= norm, y /= norm, z /= norm; return; -} +} // getXYZ +// ---------------------------------------------------------------------------- static void getYml(GLenum face, size_t edge_size, float *Y00, float *Y1minus1, float *Y10, float *Y11, @@ -107,18 +128,18 @@ static void getYml(GLenum face, size_t edge_size, } -static void projectSH(Color *CubemapFace[6], size_t edge_size, - float *Y00[], - float *Y1minus1[], float *Y10[], float *Y11[], - float *Y2minus2[], float *Y2minus1[], float * Y20[], float *Y21[], float *Y22[], - float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff - ) +// ---------------------------------------------------------------------------- +static void projectSH(Color *cubemap_face[6], size_t edge_size, float *Y00[], + float *Y1minus1[], float *Y10[], float *Y11[], + float *Y2minus2[], float *Y2minus1[], float * Y20[], + float *Y21[], float *Y22[], float *blue_sh_coeff, + float *green_sh_coeff, float *red_sh_coeff) { for (unsigned i = 0; i < 9; i++) { - blueSHCoeff[i] = 0; - greenSHCoeff[i] = 0; - redSHCoeff[i] = 0; + blue_sh_coeff[i] = 0; + green_sh_coeff[i] = 0; + red_sh_coeff[i] = 0; } float wh = float(edge_size * edge_size); @@ -127,7 +148,9 @@ static void projectSH(Color *CubemapFace[6], size_t edge_size, float g0 = 0., g1 = 0., g2 = 0., g3 = 0., g4 = 0., g5 = 0., g6 = 0., g7 = 0., g8 = 0.; for (unsigned face = 0; face < 6; face++) { -#pragma omp parallel for reduction(+ : b0, b1, b2, b3, b4, b5, b6, b7, b8, r0, r1, r2, r3, r4, r5, r6, r7, r8, g0, g1, g2, g3, g4, g5, g6, g7, g8) +#pragma omp parallel for reduction(+ : b0, b1, b2, b3, b4, b5, b6, b7, b8, \ + r0, r1, r2, r3, r4, r5, r6, r7, r8, \ + g0, g1, g2, g3, g4, g5, g6, g7, g8) for (int i = 0; i < int(edge_size); i++) { for (unsigned j = 0; j < edge_size; j++) @@ -143,9 +166,9 @@ static void projectSH(Color *CubemapFace[6], size_t edge_size, // Constant obtained by projecting unprojected ref values float solidangle = 2.75f / (wh * pow(d, 1.5f)); // pow(., 2.2) to convert from srgb - float b = CubemapFace[face][edge_size * i + j].Blue; - float g = CubemapFace[face][edge_size * i + j].Green; - float r = CubemapFace[face][edge_size * i + j].Red; + float b = cubemap_face[face][edge_size * i + j].Blue; + float g = cubemap_face[face][edge_size * i + j].Green; + float r = cubemap_face[face][edge_size * i + j].Red; b0 += b * Y00[face][idx] * solidangle; b1 += b * Y1minus1[face][idx] * solidangle; @@ -181,38 +204,46 @@ static void projectSH(Color *CubemapFace[6], size_t edge_size, } } - blueSHCoeff[0] = b0; - blueSHCoeff[1] = b1; - blueSHCoeff[2] = b2; - blueSHCoeff[3] = b3; - blueSHCoeff[4] = b4; - blueSHCoeff[5] = b5; - blueSHCoeff[6] = b6; - blueSHCoeff[7] = b7; - blueSHCoeff[8] = b8; + blue_sh_coeff[0] = b0; + blue_sh_coeff[1] = b1; + blue_sh_coeff[2] = b2; + blue_sh_coeff[3] = b3; + blue_sh_coeff[4] = b4; + blue_sh_coeff[5] = b5; + blue_sh_coeff[6] = b6; + blue_sh_coeff[7] = b7; + blue_sh_coeff[8] = b8; - redSHCoeff[0] = r0; - redSHCoeff[1] = r1; - redSHCoeff[2] = r2; - redSHCoeff[3] = r3; - redSHCoeff[4] = r4; - redSHCoeff[5] = r5; - redSHCoeff[6] = r6; - redSHCoeff[7] = r7; - redSHCoeff[8] = r8; + red_sh_coeff[0] = r0; + red_sh_coeff[1] = r1; + red_sh_coeff[2] = r2; + red_sh_coeff[3] = r3; + red_sh_coeff[4] = r4; + red_sh_coeff[5] = r5; + red_sh_coeff[6] = r6; + red_sh_coeff[7] = r7; + red_sh_coeff[8] = r8; - greenSHCoeff[0] = g0; - greenSHCoeff[1] = g1; - greenSHCoeff[2] = g2; - greenSHCoeff[3] = g3; - greenSHCoeff[4] = g4; - greenSHCoeff[5] = g5; - greenSHCoeff[6] = g6; - greenSHCoeff[7] = g7; - greenSHCoeff[8] = g8; -} + green_sh_coeff[0] = g0; + green_sh_coeff[1] = g1; + green_sh_coeff[2] = g2; + green_sh_coeff[3] = g3; + green_sh_coeff[4] = g4; + green_sh_coeff[5] = g5; + green_sh_coeff[6] = g6; + green_sh_coeff[7] = g7; + green_sh_coeff[8] = g8; +} // projectSH -void SphericalHarmonics(Color *CubemapFace[6], size_t edge_size, float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff) +// ---------------------------------------------------------------------------- +/** Generate the 9 first SH coefficients for each color channel + * using the cubemap provided by CubemapFace. + * \param textures sequence of 6 square textures. + * \param row/columns count of textures. + */ +void generateSphericalHarmonics(Color *cubemap_face[6], size_t edge_size, + float *blue_sh_coeff, float *green_sh_coeff, + float *red_sh_coeff) { float *Y00[6]; float *Y1minus1[6]; @@ -236,15 +267,14 @@ void SphericalHarmonics(Color *CubemapFace[6], size_t edge_size, float *blueSHCo Y21[face] = new float[edge_size * edge_size]; Y22[face] = new float[edge_size * edge_size]; - getYml(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, edge_size, Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]); + getYml(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, edge_size, Y00[face], + Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], + Y2minus1[face], Y20[face], Y21[face], Y22[face]); } - projectSH(CubemapFace, edge_size, - Y00, - Y1minus1, Y10, Y11, - Y2minus2, Y2minus1, Y20, Y21, Y22, - blueSHCoeff, greenSHCoeff, redSHCoeff - ); + projectSH(cubemap_face, edge_size, Y00, Y1minus1, Y10, Y11, Y2minus2, + Y2minus1, Y20, Y21, Y22, blue_sh_coeff, green_sh_coeff, + red_sh_coeff); for (unsigned face = 0; face < 6; face++) { @@ -258,38 +288,49 @@ void SphericalHarmonics(Color *CubemapFace[6], size_t edge_size, float *blueSHCo delete[] Y21[face]; delete[] Y22[face]; } -} +} // generateSphericalHarmonics +// ---------------------------------------------------------------------------- // From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html /** Returns the index-th pair from Hammersley set of pseudo random set. Hammersley set is a uniform distribution between 0 and 1 for 2 components. We use the natural indexation on the set to avoid storing the whole set. \param index of the pair \param size of the set. */ -std::pair HammersleySequence(int index, int samples) +std::pair getHammersleySequence(int index, int samples) { float InvertedBinaryRepresentation = 0.; for (size_t i = 0; i < 32; i++) { - InvertedBinaryRepresentation += ((index >> i) & 0x1) * powf(.5, (float) (i + 1.)); + InvertedBinaryRepresentation += ((index >> i) & 0x1) + * powf(.5, (float) (i + 1.)); } - return std::make_pair(float(index) / float(samples), InvertedBinaryRepresentation); -} + return std::make_pair(float(index) / float(samples), + InvertedBinaryRepresentation); +} // HammersleySequence -/** Returns a pseudo random (theta, phi) generated from a probability density function modeled after Phong function. - \param a pseudo random float pair from a uniform density function between 0 and 1. - \param exponent from the Phong formula. */ -std::pair ImportanceSamplingPhong(std::pair Seeds, float exponent) +// ---------------------------------------------------------------------------- +/** Returns a pseudo random (theta, phi) generated from a probability density + * function modeled after Phong function. + * \param a pseudo random float pair from a uniform density function between + * 0 and 1. + * \param exponent from the Phong formula. + */ +std::pair getImportanceSamplingPhong(std::pair Seeds, + float exponent) { - return std::make_pair(acosf(powf(Seeds.first, 1.f / (exponent + 1.f))), 2.f * 3.14f * Seeds.second); -} + return std::make_pair(acosf(powf(Seeds.first, 1.f / (exponent + 1.f))), + 2.f * 3.14f * Seeds.second); +} // getImportanceSamplingPhong -static -core::matrix4 getPermutationMatrix(size_t indexX, float valX, size_t indexY, float valY, size_t indexZ, float valZ) +// ---------------------------------------------------------------------------- +static core::matrix4 getPermutationMatrix(size_t indexX, float valX, + size_t indexY, float valY, + size_t indexZ, float valZ) { - core::matrix4 resultMat; - float *M = resultMat.pointer(); + core::matrix4 result_mat; + float *M = result_mat.pointer(); memset(M, 0, 16 * sizeof(float)); assert(indexX < 4); assert(indexY < 4); @@ -297,9 +338,10 @@ core::matrix4 getPermutationMatrix(size_t indexX, float valX, size_t indexY, flo M[indexX] = valX; M[4 + indexY] = valY; M[8 + indexZ] = valZ; - return resultMat; -} + return result_mat; +} // getPermutationMatrix +// ---------------------------------------------------------------------------- GLuint generateSpecularCubemap(GLuint probe) { GLuint cubemap_texture; @@ -308,7 +350,10 @@ GLuint generateSpecularCubemap(GLuint probe) glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap_texture); size_t cubemap_size = 256; for (int i = 0; i < 6; i++) - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA16F, cubemap_size, cubemap_size, 0, GL_BGRA, GL_FLOAT, 0); + { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA16F, + cubemap_size, cubemap_size, 0, GL_BGRA, GL_FLOAT, 0); + } glGenerateMipmap(GL_TEXTURE_CUBE_MAP); if (!CVS->isDefferedEnabled()) @@ -320,7 +365,7 @@ GLuint generateSpecularCubemap(GLuint probe) glViewport(0, 0, cubemap_size, cubemap_size); GLenum bufs[] = { GL_COLOR_ATTACHMENT0 }; glDrawBuffers(1, bufs); - UtilShader::SpecularIBLGenerator::getInstance()->use(); + SpecularIBLGenerator::getInstance()->use(); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); @@ -337,7 +382,8 @@ GLuint generateSpecularCubemap(GLuint probe) for (unsigned level = 0; level < 8; level++) { - // Blinn Phong can be approximated by Phong with 4x the specular coefficient + // Blinn Phong can be approximated by Phong with 4x the specular + // coefficient // See http://seblagarde.wordpress.com/2012/03/29/relationship-between-phong-and-blinn-lighting-model/ // NOTE : Removed because it makes too sharp reflexion float roughness = (8 - level) * pow(2.f, 10.f) / 8.f; @@ -346,17 +392,21 @@ GLuint generateSpecularCubemap(GLuint probe) float *tmp = new float[2048]; for (unsigned i = 0; i < 1024; i++) { - std::pair sample = ImportanceSamplingPhong(HammersleySequence(i, 1024), roughness); + std::pair sample = + getImportanceSamplingPhong(getHammersleySequence(i, 1024), + roughness); tmp[2 * i] = sample.first; tmp[2 * i + 1] = sample.second; } glBindVertexArray(0); - glActiveTexture(GL_TEXTURE0 + UtilShader::SpecularIBLGenerator::getInstance()->TU_Samples); + glActiveTexture(GL_TEXTURE0 + + SpecularIBLGenerator::getInstance()->m_tu_samples); GLuint sampleTex, sampleBuffer; glGenBuffers(1, &sampleBuffer); glBindBuffer(GL_TEXTURE_BUFFER, sampleBuffer); - glBufferData(GL_TEXTURE_BUFFER, 2048 * sizeof(float), tmp, GL_STATIC_DRAW); + glBufferData(GL_TEXTURE_BUFFER, 2048 * sizeof(float), tmp, + GL_STATIC_DRAW); glGenTextures(1, &sampleTex); glBindTexture(GL_TEXTURE_BUFFER, sampleTex); glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, sampleBuffer); @@ -365,16 +415,20 @@ GLuint generateSpecularCubemap(GLuint probe) for (unsigned face = 0; face < 6; face++) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap_texture, level); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, + cubemap_texture, level); GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER); assert(status == GL_FRAMEBUFFER_COMPLETE); - UtilShader::SpecularIBLGenerator::getInstance()->setTextureUnits(probe); - UtilShader::SpecularIBLGenerator::getInstance()->setUniforms(M[face], viewportSize); + SpecularIBLGenerator::getInstance()->setTextureUnits(probe); + SpecularIBLGenerator::getInstance()->setUniforms(M[face], + viewportSize); glDrawArrays(GL_TRIANGLES, 0, 3); } - glActiveTexture(GL_TEXTURE0 + UtilShader::SpecularIBLGenerator::getInstance()->TU_Samples); + glActiveTexture( GL_TEXTURE0 + + SpecularIBLGenerator::getInstance()->m_tu_samples); glBindBuffer(GL_TEXTURE_BUFFER, 0); glBindTexture(GL_TEXTURE_BUFFER, 0); @@ -385,4 +439,4 @@ GLuint generateSpecularCubemap(GLuint probe) glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &fbo); return cubemap_texture; -} +} // generateSpecularCubemap diff --git a/src/graphics/IBL.hpp b/src/graphics/IBL.hpp index f9461dd7e..783e4a8a0 100644 --- a/src/graphics/IBL.hpp +++ b/src/graphics/IBL.hpp @@ -27,12 +27,9 @@ struct Color float Blue; }; -/** Generate the 9 first SH coefficients for each color channel -using the cubemap provided by CubemapFace. -* \param textures sequence of 6 square textures. -* \param row/columns count of textures. -*/ -void SphericalHarmonics(Color *CubemapFace[6], size_t edge_size, float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff); +void generateSphericalHarmonics(Color *CubemapFace[6], size_t edge_size, + float *blue_sh_coeff, float *green_sh_coeff, + float *red_sh_coeff); GLuint generateSpecularCubemap(GLuint probe); #endif diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 5e3572852..6ad76bc72 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -295,12 +295,13 @@ void draw3DLine(const core::vector3df& start, end.X, end.Y, end.Z }; - glBindVertexArray(UtilShader::ColoredLine::getInstance()->vao); - glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::getInstance()->vbo); + Shaders::ColoredLine *line = Shaders::ColoredLine::getInstance(); + line->bindVertexArray(); + line->bindBuffer(); glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(float), vertex); - UtilShader::ColoredLine::getInstance()->use(); - UtilShader::ColoredLine::getInstance()->setUniforms(color); + line->use(); + line->setUniforms(color); glDrawArrays(GL_LINES, 0, 2); glGetError(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 5cc3274c1..7f86bb48e 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -192,10 +192,11 @@ void IrrDriver::renderGLSL(float dt) // Render bounding boxes if (irr_driver->getBoundingBoxesViz()) { - UtilShader::ColoredLine::getInstance()->use(); - glBindVertexArray(UtilShader::ColoredLine::getInstance()->vao); - glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::getInstance()->vbo); - UtilShader::ColoredLine::getInstance()->setUniforms(SColor(255, 255, 0, 0)); + Shaders::ColoredLine *line = Shaders::ColoredLine::getInstance(); + line->use(); + line->bindVertexArray(); + line->bindBuffer(); + line->setUniforms(SColor(255, 255, 0, 0)); const float *tmp = BoundingBoxes.data(); for (unsigned int i = 0; i < BoundingBoxes.size(); i += 1024 * 6) { @@ -221,12 +222,13 @@ void IrrDriver::renderGLSL(float dt) const std::map >& lines = debug_drawer->getLines(); std::map >::const_iterator it; - UtilShader::ColoredLine::getInstance()->use(); - glBindVertexArray(UtilShader::ColoredLine::getInstance()->vao); - glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::getInstance()->vbo); + Shaders::ColoredLine *line = Shaders::ColoredLine::getInstance(); + line->use(); + line->bindVertexArray(); + line->bindBuffer(); for (it = lines.begin(); it != lines.end(); it++) { - UtilShader::ColoredLine::getInstance()->setUniforms(it->first); + line->setUniforms(it->first); const std::vector &vertex = it->second; const float *tmp = vertex.data(); for (unsigned int i = 0; i < vertex.size(); i += 1024 * 6) diff --git a/src/graphics/render_skybox.cpp b/src/graphics/render_skybox.cpp index b722f6a65..53e43c713 100644 --- a/src/graphics/render_skybox.cpp +++ b/src/graphics/render_skybox.cpp @@ -373,7 +373,7 @@ void IrrDriver::generateDiffuseCoefficients() } } - SphericalHarmonics(FloatTexCube, sh_w, blueSHCoeff, greenSHCoeff, redSHCoeff); + generateSphericalHarmonics(FloatTexCube, sh_w, blueSHCoeff, greenSHCoeff, redSHCoeff); for (unsigned i = 0; i < 6; i++) { diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 349e933a0..d0318f41a 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -225,6 +225,26 @@ GLuint LoadShader(const char * file, unsigned type) +Shaders::ColoredLine::ColoredLine() +{ + loadProgram(OBJECT, GL_VERTEX_SHADER, "object_pass.vert", + GL_FRAGMENT_SHADER, "coloredquad.frag"); + + assignUniforms("color"); + + glGenVertexArrays(1, &m_vao); + glBindVertexArray(m_vao); + glGenBuffers(1, &m_vbo); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferData(GL_ARRAY_BUFFER, 6 * 1024 * sizeof(float), 0, GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} // Shaders::ColoredLine + + + GLuint quad_vbo, tri_vbo; GLuint SharedObject::FullScreenQuadVAO = 0; @@ -508,24 +528,6 @@ void bypassUBO(GLuint Program) namespace UtilShader { - ColoredLine::ColoredLine() - { - loadProgram(OBJECT, - GL_VERTEX_SHADER, "object_pass.vert", - GL_FRAGMENT_SHADER, "coloredquad.frag"); - - assignUniforms("color"); - - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, 6 * 1024 * sizeof(float), 0, GL_DYNAMIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } } @@ -539,20 +541,6 @@ unsigned getGLSLVersion() return CVS->getGLSLVersion(); } -namespace UtilShader -{ - SpecularIBLGenerator::SpecularIBLGenerator() - { - loadProgram(OBJECT, - GL_VERTEX_SHADER, "screenquad.vert", - GL_FRAGMENT_SHADER, "importance_sampling_specular.frag"); - assignUniforms("PermutationMatrix", "ViewportSize"); - TU_Samples = 1; - assignSamplerNames(m_program, 0, "tex", ST_TRILINEAR_CUBEMAP); - assignTextureUnit(TU_Samples, "samples"); - } -} - namespace MeshShader { // Solid Normal and depth pass shaders diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index c4aa21cdd..5cb2d458a 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -40,25 +40,6 @@ public: static GLuint UIVAO; }; -namespace UtilShader -{ -class ColoredLine : public Shader -{ -public: - GLuint vao, vbo; - - ColoredLine(); -}; - -class SpecularIBLGenerator : public Shader, - public TextureReadNew -{ -public: - GLuint TU_Samples; - SpecularIBLGenerator(); -}; -} - namespace MeshShader { @@ -861,8 +842,32 @@ public: void killShaders(); -private: -}; + + // ======================================================================== + /** Shader to draw a colored line. + */ + class ColoredLine : public Shader + { + private: + GLuint m_vao, m_vbo; + public: + ColoredLine(); + + // -------------------------------------------------------------------- + /** Bind the vertex array of this shader. */ + void bindVertexArray() + { + glBindVertexArray(m_vao); + } // bindVertexArray + // -------------------------------------------------------------------- + /** Binds the vbo of this shader. */ + void bindBuffer() + { + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + } // bindBuffer + }; // class ColoredLine + +}; // class Shaders #undef ENUM #undef STR