From c07aed260aa253085d2e846f4727025007cd35eb Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 9 Aug 2014 21:09:31 +0200 Subject: [PATCH] Visualize vertex normals in normal view. --- data/shaders/normal_visualizer.geom | 20 +++++++++++++++++ src/graphics/irr_driver.hpp | 1 + src/graphics/render.cpp | 7 ++++++ src/graphics/render_geometry.cpp | 35 +++++++++++++++++++++++++++++ src/graphics/shaders.cpp | 17 ++++++++++++++ src/graphics/shaders.hpp | 14 ++++++++++++ 6 files changed, 94 insertions(+) create mode 100644 data/shaders/normal_visualizer.geom diff --git a/data/shaders/normal_visualizer.geom b/data/shaders/normal_visualizer.geom new file mode 100644 index 000000000..ea4ea08c9 --- /dev/null +++ b/data/shaders/normal_visualizer.geom @@ -0,0 +1,20 @@ +layout(triangles) in; +layout(line_strip, max_vertices = 6) out; + +in vec3 nor[]; + +void main() +{ + for(int i=0; i < gl_in.length(); i++) + { + vec4 pos = gl_in[i].gl_Position; + gl_Position = pos; + EmitVertex(); + + vec3 normal = nor[i]; + gl_Position = pos + .2 * vec4(normal, 0.); + EmitVertex(); + + EndPrimitive(); + } +} \ No newline at end of file diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 3c96f0caa..689d6b007 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -362,6 +362,7 @@ private: void renderGLSL(float dt); void renderSolidFirstPass(); void renderSolidSecondPass(); + void renderNormalsVisualisation(); void renderTransparent(); void renderParticles(); void computeSunVisibility(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 2017972c6..fdaaa84d7 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -318,6 +318,13 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po renderSolidSecondPass(); PROFILER_POP_CPU_MARKER(); + if (getNormals()) + { + m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind(); + renderNormalsVisualisation(); + m_rtts->getFBO(FBO_COLORS).Bind(); + } + if (UserConfigParams::m_dynamic_lights && World::getWorld() != NULL && World::getWorld()->isFogEnabled()) { diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index 001dcc486..1876f5368 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -332,6 +332,41 @@ void IrrDriver::renderSolidSecondPass() } } +template +static void renderMeshNormals(std::vector > &meshes) +{ + glUseProgram(MeshShader::NormalVisualizer::getInstance()->Program); + glBindVertexArray(getVAO(VertexType)); + for (unsigned i = 0; i < meshes.size(); i++) + { + GLMesh &mesh = *(STK::tuple_get<0>(meshes[i])); + + if (mesh.VAOType != VertexType) + { +#ifdef DEBUG + Log::error("Materials", "Wrong vertex Type associed to pass 2 (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str()); +#endif + continue; + } + draw(MeshShader::NormalVisualizer::getInstance(), STK::tuple_get<0>(meshes[i]), STK::tuple_get<1>(meshes[i]), STK::tuple_get<2>(meshes[i]), video::SColor(255, 0, 255, 0)); + } +} + +void IrrDriver::renderNormalsVisualisation() +{ + renderMeshNormals(ListMatDefault::Arguments); + renderMeshNormals(ListMatAlphaRef::Arguments); + renderMeshNormals(ListMatSphereMap::Arguments); + renderMeshNormals(ListMatGrass::Arguments); + renderMeshNormals(ListMatDetails::Arguments); + renderMeshNormals(ListMatUnlit::Arguments); + renderMeshNormals(ListMatSplatting::Arguments); + renderMeshNormals(ListMatNormalMap::Arguments); + +} + + + static video::ITexture *displaceTex = 0; void IrrDriver::renderTransparent() diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index beef0086b..7c698cd12 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -572,6 +572,11 @@ void glUniform3fWraper(GLuint a, float b, float c, float d) glUniform3f(a, b, c, d); } +void glUniform4iWraper(GLuint a, int b, int c, int d, int e) +{ + glUniform4i(a, b, c, d, e); +} + void glUniform2fWraper(GLuint a, float b, float c) { glUniform2f(a, b, c); @@ -1229,6 +1234,18 @@ namespace MeshShader glUniform1i(uniform_tex, TU_tex); } + NormalVisualizer::NormalVisualizer() + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), + GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/normal_visualizer.geom").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/coloredquad.frag").c_str()); + AssignUniforms("ModelMatrix", "InverseModelMatrix", "color"); + + GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); + glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); + } + GLuint ViewFrustrumShader::Program; GLuint ViewFrustrumShader::attrib_position; GLuint ViewFrustrumShader::uniform_color; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 491ab2f38..d0c9096f0 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -51,6 +51,7 @@ public: void glUniformMatrix4fvWraper(GLuint, size_t, unsigned, const float *mat); void glUniform3fWraper(GLuint, float, float, float); +void glUniform4iWraper(GLuint, int, int, int, int); void glUniform2fWraper(GLuint a, float b, float c); void glUniform1fWrapper(GLuint, float); bool needsUBO(); @@ -79,6 +80,13 @@ struct UniformHelper setUniformsHelper(uniforms, arg...); } + template + static void setUniformsHelper(const std::vector &uniforms, const video::SColor &col, Args... arg) + { + glUniform4iWraper(uniforms[N], col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha()); + setUniformsHelper(uniforms, arg...); + } + template static void setUniformsHelper(const std::vector &uniforms, const core::vector3df &v, Args... arg) { @@ -407,6 +415,12 @@ public: static void setUniforms(const core::matrix4 &ModelMatrix, const core::vector2df &screen, unsigned TU_tex); }; +class NormalVisualizer : public ShaderHelperSingleton +{ +public: + NormalVisualizer(); +}; + class ViewFrustrumShader { public: