Commit 1915119d authored by Maire Nicolas's avatar Maire Nicolas

Gestion dans le code du clipping à n plans avec des std::vector.

Codage et rajout du shader de clipping à n plans.
parent 4e10917d
...@@ -233,7 +233,7 @@ void StageShader::cb_initGL() ...@@ -233,7 +233,7 @@ void StageShader::cb_initGL()
registerShader(m_shader); registerShader(m_shader);
m_shader->addPlaneClippingToShaderSource(); m_shader->setPlaneClipping(1);
} }
void StageShader::updateVBOprimitives(int upType) void StageShader::updateVBOprimitives(int upType)
......
...@@ -123,7 +123,7 @@ void Stage_shader_number_two::cb_initGL() ...@@ -123,7 +123,7 @@ void Stage_shader_number_two::cb_initGL()
registerShader(m_simpleColorShader) ; registerShader(m_simpleColorShader) ;
registerShader(m_pointSprite) ; registerShader(m_pointSprite) ;
m_phongShader->addPlaneClippingToShaderSource(); m_phongShader->setPlaneClipping(1);
} }
void Stage_shader_number_two::cb_redraw() void Stage_shader_number_two::cb_redraw()
...@@ -200,8 +200,8 @@ void Stage_shader_number_two::cb_mouseMove(int button, int x, int y) ...@@ -200,8 +200,8 @@ void Stage_shader_number_two::cb_mouseMove(int button, int x, int y)
if (button == Qt::LeftButton) if (button == Qt::LeftButton)
{ {
Geom::Vec4f clipPlane = m_phongShader->getClippingPlaneEquation(); Geom::Vec4f clipPlane = m_phongShader->getClippingPlaneEquation();
clipPlane[0] += (m_mouseLastX - x)/20.0; clipPlane[0] += (m_mouseLastX - x)/40.0;
clipPlane[1] += (m_mouseLastY - y)/20.0; clipPlane[1] += (m_mouseLastY - y)/40.0;
m_phongShader->setClippingPlaneEquation(clipPlane); m_phongShader->setClippingPlaneEquation(clipPlane);
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include "Utils/shaderMutator.h" #include "Utils/shaderMutator.h"
#include "Utils/drawer.h" #include "Utils/drawer.h"
#include <string> #include <string>
#include <sstream>
#include <vector>
namespace CGoGN namespace CGoGN
{ {
...@@ -57,25 +59,29 @@ public: ...@@ -57,25 +59,29 @@ public:
/** /**
* set the plane equation for plane clipping * set the plane equation for plane clipping
* @warning planeIndex starts at 0
* @param clipPlane plane equation * @param clipPlane plane equation
* @param planeIndex index of plane to modify
*/ */
void setClippingPlaneEquation(Geom::Vec4f clipPlane); void setClippingPlaneEquation(Geom::Vec4f clipPlane, int planeIndex = 0);
/** /**
* get the plane equation for plane clipping * get the plane equation for plane clipping
* @warning planeIndex starts at 0
* @param planeIndex index of plane to get
*/ */
Geom::Vec4f getClippingPlaneEquation(); Geom::Vec4f getClippingPlaneEquation(int planeIndex = 0);
/** /**
* set the plane quaternion for plane clipping * set the plane quaternion for plane clipping
* @param quat plane quaternion * @param quat plane quaternion
*/ */
void setClippingPlaneQuaternion(float quat[4]); //void setClippingPlaneQuaternion(float quat[4]);
/** /**
* get the plane quaternion for plane clipping * get the plane quaternion for plane clipping
*/ */
Geom::Vec4f getClippingPlaneQuaternion(); //Geom::Vec4f getClippingPlaneQuaternion();
/** /**
* set the color attenuation factor for clipping * set the color attenuation factor for clipping
...@@ -91,10 +97,16 @@ public: ...@@ -91,10 +97,16 @@ public:
/** /**
* insert plane clipping instructions into vertex and fragment shader source code * insert plane clipping instructions into vertex and fragment shader source code
* - does not modify the geometry shader source code * - does not modify the geometry shader source code
* @warning this function is designed for shaders which do not use a geometry shader * @param planesCount the clipping planes count to use
* @warning this function is designed for shaders which *do not* use a geometry shader
*/ */
void addPlaneClippingToShaderSource(); void setPlaneClipping(int planesCount);
/**
* get the clipping planes count used for plane clipping
*/
int getClippingPlanesCount() { return (int)m_clipPlanesEquations.size(); }
/** /**
* update uniforms (get their locations and resend their values) for clipping * update uniforms (get their locations and resend their values) for clipping
*/ */
...@@ -109,19 +121,29 @@ public: ...@@ -109,19 +121,29 @@ public:
private: private:
/** /**
* clip plane vector (a, b, c, d) * sends the clipping planes uniform to shader
*/
void sendClippingPlanesUniform();
/**
* sends the color attenuation factor uniform to shader
*/
void sendColorAttenuationFactorUniform();
/**
* clip planes equations (a, b, c, d)*planes count
*/ */
Geom::Vec4f m_clipPlaneEquation; std::vector<float> m_clipPlanesEquations;
/** /**
* clip plane quaternion * clip plane quaternion
*/ */
float m_clipPlaneQuaternion[4]; //float m_clipPlaneQuaternion[4];
/** /**
* clip plane vector uniform id * clip planes vector uniform id
*/ */
GLint m_unif_clipPlane; GLint m_unif_clipPlanes;
/** /**
* color attenuation factor * color attenuation factor
......
...@@ -32,15 +32,14 @@ namespace Utils ...@@ -32,15 +32,14 @@ namespace Utils
ClippingShader::ClippingShader() ClippingShader::ClippingShader()
{ {
// Default values for plane clipping // Initialize clipping planes variables
m_clipPlaneEquation = Geom::Vec4f(0.0, 0.0, 1.0, 0.0); m_unif_clipPlanes = 0;
m_unif_clipPlane = 0; /*m_clipPlaneQuaternion[0] = 1.0;
m_clipPlaneQuaternion[0] = 1.0;
m_clipPlaneQuaternion[1] = 0.0; m_clipPlaneQuaternion[1] = 0.0;
m_clipPlaneQuaternion[2] = 0.0; m_clipPlaneQuaternion[2] = 0.0;
m_clipPlaneQuaternion[3] = 0.0; m_clipPlaneQuaternion[3] = 0.0;*/
// Default values for color attenuation // Initialize color attenuation variables
m_colorAttenuationFactor = 0.0; m_colorAttenuationFactor = 0.0;
m_unif_colorAttenuationFactor = 0; m_unif_colorAttenuationFactor = 0;
...@@ -63,51 +62,83 @@ ClippingShader::~ClippingShader() ...@@ -63,51 +62,83 @@ ClippingShader::~ClippingShader()
delete m_planeDrawer; delete m_planeDrawer;
} }
void ClippingShader::setClippingPlaneEquation(Geom::Vec4f clipPlane) void ClippingShader::setClippingPlaneEquation(Geom::Vec4f clipPlane, int planeIndex)
{ {
m_clipPlaneEquation = clipPlane; // Check if the given index is not out of range
if ((planeIndex < 0) || ((4*planeIndex) > ((int)m_clipPlanesEquations.size() - 1)))
{
CGoGNerr
<< "ERROR - "
<< "ClippingShader::setClippingPlaneEquation"
<< " - Given plane index is out of range"
<< CGoGNendl;
return;
}
// Copy the given clipPlane
int i;
for (i = 0; i < 4; i++)
m_clipPlanesEquations[4*planeIndex + i] = clipPlane[i];
// Recalculate quaternion rotation // Recalculate quaternion rotation
float m[4][4]; /*float m[4][4];
build_rotmatrix(m, m_clipPlaneQuaternion); build_rotmatrix(m, m_clipPlaneQuaternion);
Geom::Matrix44f rotMat; Geom::Matrix44f rotMat;
int i, j; int i, j;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
rotMat(i, j) = m[i][j]; rotMat(i, j) = m[i][j];
Geom::Vec4f rotatedVec = /*rotMat * */m_clipPlaneEquation; Geom::Vec4f rotatedVec = rotMat * m_clipPlaneEquation;*/
// Send the resulting plane equation to shader // Send again the whole planes equations array to shader
bind(); sendClippingPlanesUniform();
glUniform4fv(m_unif_clipPlane, 1, rotatedVec.data());
} }
Geom::Vec4f ClippingShader::getClippingPlaneEquation() Geom::Vec4f ClippingShader::getClippingPlaneEquation(int planeIndex)
{ {
return m_clipPlaneEquation; // Check if the given index is not out of range
if ((planeIndex < 0) || (4*planeIndex > ((int)m_clipPlanesEquations.size() - 1)))
{
CGoGNerr
<< "ERROR - "
<< "ClippingShader::setClippingPlaneEquation"
<< " - Given plane index is out of range"
<< CGoGNendl;
return Geom::Vec4f(0.0, 0.0, 0.0, 0.0);
}
else
{
return Geom::Vec4f(
m_clipPlanesEquations[4*planeIndex + 0],
m_clipPlanesEquations[4*planeIndex + 1],
m_clipPlanesEquations[4*planeIndex + 2],
m_clipPlanesEquations[4*planeIndex + 3]);
}
} }
void ClippingShader::setClippingPlaneQuaternion(float quat[4]) /*void ClippingShader::setClippingPlaneQuaternion(float quat[4])
{ {
m_clipPlaneQuaternion[0] = quat[0]; m_clipPlaneQuaternion[0] = quat[0];
m_clipPlaneQuaternion[1] = quat[1]; m_clipPlaneQuaternion[1] = quat[1];
m_clipPlaneQuaternion[2] = quat[2]; m_clipPlaneQuaternion[2] = quat[2];
m_clipPlaneQuaternion[3] = quat[3]; m_clipPlaneQuaternion[3] = quat[3];
// Recalculate and resend the clipping plane equation // Recalculate and send again the clipping plane equation
setClippingPlaneEquation(m_clipPlaneEquation); setClippingPlaneEquation(m_clipPlaneEquation);
} }
Geom::Vec4f ClippingShader::getClippingPlaneQuaternion() Geom::Vec4f ClippingShader::getClippingPlaneQuaternion()
{ {
return Geom::Vec4f (m_clipPlaneQuaternion[0], m_clipPlaneQuaternion[1], m_clipPlaneQuaternion[2], m_clipPlaneQuaternion[3]); return Geom::Vec4f (m_clipPlaneQuaternion[0], m_clipPlaneQuaternion[1], m_clipPlaneQuaternion[2], m_clipPlaneQuaternion[3]);
} }*/
void ClippingShader::setClippingColorAttenuationFactor(float colorAttenuationFactor) void ClippingShader::setClippingColorAttenuationFactor(float colorAttenuationFactor)
{ {
// Copy the given value
m_colorAttenuationFactor = colorAttenuationFactor; m_colorAttenuationFactor = colorAttenuationFactor;
bind();
glUniform1f(m_unif_colorAttenuationFactor, m_colorAttenuationFactor); // Send again the uniform to shader
sendColorAttenuationFactorUniform();
} }
float ClippingShader::getClippingColorAttenuationFactor() float ClippingShader::getClippingColorAttenuationFactor()
...@@ -115,17 +146,23 @@ float ClippingShader::getClippingColorAttenuationFactor() ...@@ -115,17 +146,23 @@ float ClippingShader::getClippingColorAttenuationFactor()
return m_colorAttenuationFactor; return m_colorAttenuationFactor;
} }
void ClippingShader::addPlaneClippingToShaderSource() void ClippingShader::setPlaneClipping(int planesCount)
{ {
// Shader name // Shader name
std::string shaderName = m_nameVS + "/" + m_nameFS + "/" + m_nameGS; std::string shaderName = m_nameVS + "/" + m_nameFS + "/" + m_nameGS;
// String for clipping planes count
std::string planesCountStr;
std::stringstream ss;
ss << planesCount;
planesCountStr = ss.str();
// Verify that the shader has been well created // Verify that the shader has been well created
if (!isCreated()) if (!isCreated())
{ {
CGoGNerr CGoGNerr
<< "ERROR - " << "ERROR - "
<< "ClippingShader::addPlaneClippingToShaderSource" << "ClippingShader::setPlaneClipping"
<< " - Could not process shader " << " - Could not process shader "
<< shaderName << shaderName
<< " source code : shader has not been created or has failed to compile" << " source code : shader has not been created or has failed to compile"
...@@ -138,7 +175,7 @@ void ClippingShader::addPlaneClippingToShaderSource() ...@@ -138,7 +175,7 @@ void ClippingShader::addPlaneClippingToShaderSource()
{ {
CGoGNerr CGoGNerr
<< "ERROR - " << "ERROR - "
<< "ClippingShader::addPlaneClippingToShaderSource" << "ClippingShader::setPlaneClipping"
<< " - Could not process shader " << " - Could not process shader "
<< shaderName << shaderName
<< " source code : unable to add clipping to a shader which uses a geometry shader" << " source code : unable to add clipping to a shader which uses a geometry shader"
...@@ -146,6 +183,17 @@ void ClippingShader::addPlaneClippingToShaderSource() ...@@ -146,6 +183,17 @@ void ClippingShader::addPlaneClippingToShaderSource()
return; return;
} }
// Verify that the given clipping planes count is valid
if (planesCount < 0)
{
CGoGNerr
<< "ERROR - "
<< "ClippingShader::setPlanesClipping"
<< " - Given clipping planes count given is not positive !"
<< CGoGNendl;
return;
}
// Strings that will be inserted into the source code // Strings that will be inserted into the source code
std::string VS_head_insertion = std::string VS_head_insertion =
...@@ -160,8 +208,9 @@ void ClippingShader::addPlaneClippingToShaderSource() ...@@ -160,8 +208,9 @@ void ClippingShader::addPlaneClippingToShaderSource()
std::string FS_head_insertion = std::string FS_head_insertion =
"\n" "\n"
"uniform vec4 clip_ClipPlane;\n" "#define CLIP_PLANES_COUNT " + planesCountStr + "\n"
"\n" "\n"
"uniform vec4 clip_ClipPlanes[CLIP_PLANES_COUNT];\n"
"uniform float clip_ColorAttenuationFactor;\n" "uniform float clip_ColorAttenuationFactor;\n"
"\n" "\n"
"VARYING_FRAG vec3 clip_NonTransformedPos;\n" "VARYING_FRAG vec3 clip_NonTransformedPos;\n"
...@@ -169,25 +218,46 @@ void ClippingShader::addPlaneClippingToShaderSource() ...@@ -169,25 +218,46 @@ void ClippingShader::addPlaneClippingToShaderSource()
std::string FS_mainBegin_insertion = std::string FS_mainBegin_insertion =
"\n" "\n"
" // Signed distance between the point and the plane\n" " // Distance to the nearest plane, stored for color attenuation\n"
" float clip_DistanceToPlane = dot(clip_NonTransformedPos, clip_ClipPlane.xyz) + clip_ClipPlane.w;\n" " float clip_MinDistanceToPlanes = -1.0;\n"
" float clip_NPlane = length(clip_ClipPlane.xyz);\n" "\n"
" if (clip_NPlane != 0.0)\n" " // Do clipping for each plane\n"
" int i;\n"
" for (i = 0; i < CLIP_PLANES_COUNT; i++)\n"
" {\n"
" // Copy the plane to make it modifiable\n"
" vec4 clip_CurrClipPlane = clip_ClipPlanes[i];\n"
"\n"
" // If the plane normal is zero, use a default normal vector (0.0, 0.0, 1.0)\n"
" float clip_NPlane = length(clip_CurrClipPlane.xyz);\n"
" if (clip_NPlane == 0.0)\n"
" {\n"
" clip_CurrClipPlane.z = 1.0;\n"
" clip_NPlane = 1.0;\n"
" }\n"
"\n"
" // Signed distance between the point and the plane\n"
" float clip_DistanceToPlane = dot(clip_NonTransformedPos, clip_CurrClipPlane.xyz) + clip_CurrClipPlane.w;\n"
" clip_DistanceToPlane /= clip_NPlane;\n" " clip_DistanceToPlane /= clip_NPlane;\n"
"\n" "\n"
" // Keep the fragment only if it is 'above' the plane\n" " // Keep the fragment only if it is 'above' the plane\n"
" if (clip_DistanceToPlane < 0.0)\n" " if (clip_DistanceToPlane < 0.0)\n"
" discard;\n" " discard;\n"
" else\n" " // Else keep the positive distance to the nearest plane\n"
" {\n"; " else\n"
" {\n"
" if (clip_MinDistanceToPlanes < 0.0)\n"
" clip_MinDistanceToPlanes = clip_DistanceToPlane;\n"
" else\n"
" clip_MinDistanceToPlanes = min(clip_MinDistanceToPlanes, clip_DistanceToPlane);\n"
" }\n"
" }\n";
std::string FS_mainEnd_insertion = std::string FS_mainEnd_insertion =
"\n" "\n"
" }\n" " // Attenuate the final fragment color depending on its distance to the nearest plane\n"
"\n" " if (clip_MinDistanceToPlanes > 0.0)\n"
" // Attenuate the final fragment color depending on its distance to the plane\n" " gl_FragColor.rgb /= (1.0 + clip_MinDistanceToPlanes*clip_ColorAttenuationFactor);\n";
" if (clip_DistanceToPlane > 0.0)\n"
" gl_FragColor.rgb /= (1.0 + clip_DistanceToPlane*clip_ColorAttenuationFactor);\n";
// Use a shader mutator // Use a shader mutator
...@@ -198,7 +268,7 @@ void ClippingShader::addPlaneClippingToShaderSource() ...@@ -198,7 +268,7 @@ void ClippingShader::addPlaneClippingToShaderSource()
{ {
CGoGNerr CGoGNerr
<< "ERROR - " << "ERROR - "
<< "ClippingShader::addPlaneClippingToShaderSource" << "ClippingShader::setPlaneClipping"
<< " - Could not process shader " << " - Could not process shader "
<< m_nameVS << m_nameVS
<< " source code : no VertexPosition attribute found" << " source code : no VertexPosition attribute found"
...@@ -210,7 +280,7 @@ void ClippingShader::addPlaneClippingToShaderSource() ...@@ -210,7 +280,7 @@ void ClippingShader::addPlaneClippingToShaderSource()
SM.VS_insertCodeBeforeMainFunction(VS_head_insertion); SM.VS_insertCodeBeforeMainFunction(VS_head_insertion);
SM.VS_insertCodeAtMainFunctionBeginning(VS_mainBegin_insertion); SM.VS_insertCodeAtMainFunctionBeginning(VS_mainBegin_insertion);
// Following code insertions need shading language 120 at least (GLSL arrays) // Following code insertions need at least shading language 120 (GLSL arrays)
SM.VS_FS_GS_setMinShadingLanguageVersion(120); SM.VS_FS_GS_setMinShadingLanguageVersion(120);
// Modify fragment shader source code // Modify fragment shader source code
...@@ -222,6 +292,9 @@ void ClippingShader::addPlaneClippingToShaderSource() ...@@ -222,6 +292,9 @@ void ClippingShader::addPlaneClippingToShaderSource()
reloadVertexShaderFromMemory(SM.getModifiedVertexShaderSrc().c_str()); reloadVertexShaderFromMemory(SM.getModifiedVertexShaderSrc().c_str());
reloadFragmentShaderFromMemory(SM.getModifiedFragmentShaderSrc().c_str()); reloadFragmentShaderFromMemory(SM.getModifiedFragmentShaderSrc().c_str());
// Resize the planes equations uniform to the right size
m_clipPlanesEquations.resize(4*(size_t)planesCount, 0.0);
// Recompile shaders (automatically calls updateClippingUniforms) // Recompile shaders (automatically calls updateClippingUniforms)
recompile(); recompile();
} }
...@@ -232,12 +305,12 @@ void ClippingShader::updateClippingUniforms() ...@@ -232,12 +305,12 @@ void ClippingShader::updateClippingUniforms()
std::string shaderName = m_nameVS + "/" + m_nameFS + "/" + m_nameGS; std::string shaderName = m_nameVS + "/" + m_nameFS + "/" + m_nameGS;
// Get uniforms locations // Get uniforms locations
m_unif_clipPlane = glGetUniformLocation(program_handler(), "clip_ClipPlane"); m_unif_clipPlanes = glGetUniformLocation(program_handler(), "clip_ClipPlanes");
if (m_unif_clipPlane == -1) if (m_unif_clipPlanes == -1)
{ {
CGoGNerr CGoGNerr
<< "ERROR - " << "ERROR - "
<< "ClippingShader::addPlaneClippingToShaderSource" << "ClippingShader::updateClippingUniforms"
<< " - uniform 'clip_ClipPlane' not found in shader " << " - uniform 'clip_ClipPlane' not found in shader "
<< shaderName << shaderName
<< CGoGNendl; << CGoGNendl;
...@@ -247,16 +320,15 @@ void ClippingShader::updateClippingUniforms() ...@@ -247,16 +320,15 @@ void ClippingShader::updateClippingUniforms()
{ {
CGoGNerr CGoGNerr
<< "ERROR - " << "ERROR - "
<< "ClippingShader::addPlaneClippingToShaderSource" << "ClippingShader::updateClippingUniforms"
<< " - uniform 'clip_ColorAttenuationFactor' not found in shader " << " - uniform 'clip_ColorAttenuationFactor' not found in shader "
<< shaderName << shaderName
<< CGoGNendl; << CGoGNendl;
} }
// Set uniforms values // Send again uniforms values
setClippingPlaneEquation(m_clipPlaneEquation); sendClippingPlanesUniform();
setClippingPlaneQuaternion(m_clipPlaneQuaternion); sendColorAttenuationFactorUniform();
setClippingColorAttenuationFactor(m_colorAttenuationFactor);
} }
void ClippingShader::displayClippingPlane() void ClippingShader::displayClippingPlane()
...@@ -264,6 +336,18 @@ void ClippingShader::displayClippingPlane() ...@@ -264,6 +336,18 @@ void ClippingShader::displayClippingPlane()
m_planeDrawer->callList(); m_planeDrawer->callList();
} }
void ClippingShader::sendClippingPlanesUniform()
{
bind();
glUniform4fv(m_unif_clipPlanes, m_clipPlanesEquations.size()/4, &m_clipPlanesEquations.front());
}
void ClippingShader::sendColorAttenuationFactorUniform()
{
bind();
glUniform1f(m_unif_colorAttenuationFactor, m_colorAttenuationFactor);
}
} // namespace Utils } // namespace Utils
} // namespace CGoGN } // namespace CGoGN
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment