Commit 6de0fa92 authored by Sylvain Thery's avatar Sylvain Thery

add rendering of volume exploding shader (now work only in Map, no GMap)

parent e4d76eeb
......@@ -33,6 +33,9 @@
#include "Topology/generic/dart.h"
#include "Topology/generic/attributeHandler.h"
#include "Topology/generic/functor.h"
#include "Utils/vbo.h"
#include "Utils/Shaders/shaderExplodeVolumes.h"
#include "Utils/Shaders/shaderExplodeVolumesLines.h"
namespace CGoGN
{
......@@ -47,23 +50,27 @@ namespace GL2
{
class explodeVolume_VBORender
class ExplodeVolumeRender
{
protected:
Utils::ShaderExplodeVolumes* m_shader;
/**
* vbo buffers
* 0: vertices
* 1: normals
*/
GLuint m_VBOBuffers[2];
Utils::ShaderExplodeVolumesLines* m_shaderL;
Utils::VBO* m_vboPos;
Utils::VBO* m_vboPosLine;
/**
*number of triangles to draw
*/
GLuint m_nbTris;
GLuint m_nbLines;
public:
/**
* Constructor
......@@ -71,28 +78,49 @@ public:
* @param good functor that return true for darts of part to draw
* @param type_vbo vbo to alloc ( VBO_P, VBO_PN, VBO_PNC, VBO_PC ..)
*/
explodeVolume_VBORender();
ExplodeVolumeRender();
/**
* Destructor
*/
~explodeVolume_VBORender();
~ExplodeVolumeRender();
/**
* return a ptr on used shader do not forgot to register
*/
Utils::GLSLShader* shaderFaces() { return m_shader;}
/**
* return a ptr on used shader do not forgot to register
*/
Utils::GLSLShader* shaderLines() { return m_shaderL;}
/**
* update all drawing buffers
* @param map the map
* @param good selector
* @param positions attribute of position vertices
* @param kf exploding coef for face
* @param kv exploding coef for face
* @param good selector
*/
template<typename PFP>
void updateData(typename PFP::MAP& map, const FunctorSelect& good, const typename PFP::TVEC3& positions, float kf, float kv);
void updateData(typename PFP::MAP& map, typename PFP::TVEC3& positions, const FunctorSelect& good = allDarts);
/**
* draw all topo
* draw
*/
void drawEdges();
void drawFaces();
void setExplodeVolumes(float explode) { m_shader->setExplodeVolumes(explode);m_shaderL->setExplodeVolumes(explode);}
void setAmbiant(const Geom::Vec4f& ambiant) { m_shader->setAmbiant(ambiant);}
void setDiffuse(const Geom::Vec4f& diffuse) { m_shader->setDiffuse(diffuse);}
void setLightPosition(const Geom::Vec3f& lp) { m_shader->setLightPosition(lp);}
};
}//end namespace GL2
......
......@@ -26,6 +26,7 @@
#include "Geometry/vector_gen.h"
#include "Topology/generic/dartmarker.h"
#include "Topology/generic/cellmarker.h"
#include "Algo/Geometry/centroid.h"
namespace CGoGN
{
......@@ -39,178 +40,140 @@ namespace Render
namespace GL2
{
inline explodeVolume_VBORender::explodeVolume_VBORender()
inline ExplodeVolumeRender::ExplodeVolumeRender()
{
glGenBuffersARB(2, m_VBOBuffers);
}
m_vboPos = new Utils::VBO();
m_vboPos->setDataSize(3);
m_vboPosLine = new Utils::VBO();
m_vboPosLine->setDataSize(3);
m_shader = new Utils::ShaderExplodeVolumes();
m_shaderL = new Utils::ShaderExplodeVolumesLines();
// m_shader->setAmbiant(Geom::Vec4f(0.1f,0.1f,0.1f,0.0f));
// m_shader->setDiffuse(Geom::Vec4f(1.0f,1.0f,0.1f,0.0f));
m_shaderL->setColor(Geom::Vec4f(1.0f,1.0f,1.0f,0.0f));
explodeVolume_VBORender::~explodeVolume_VBORender()
}
inline ExplodeVolumeRender::~ExplodeVolumeRender()
{
glDeleteBuffersARB(2, m_VBOBuffers);
delete m_vboPos;
delete m_vboPosLine;
delete m_shader;
delete m_shaderL;
}
template<typename PFP>
void explodeVolume_VBORender::updateData(typename PFP::MAP& map, const FunctorSelect& good, const typename PFP::TVEC3& positions,float kf, float kv)
void ExplodeVolumeRender::updateData(typename PFP::MAP& map, typename PFP::TVEC3& positions, const FunctorSelect& good)
{
typedef typename PFP::VEC3 VEC3;
typedef typename PFP::REAL REAL;
m_nbTris = 0;
CellMarker cmv(map,VOLUME);
AutoAttributeHandler<VEC3> centerVolumes(map,VOLUME,"centerVolumes");
TraversorW<typename PFP::MAP> traVol(map,good);
for (Dart d=traVol.begin(); d!=traVol.end(); d=traVol.next())
{
centerVolumes[d] = Algo::Geometry::volumeCentroid<PFP>(map, d, positions);
}
// table of center of volume
std::vector<VEC3> vecCenters;
vecCenters.reserve(1000);
// table of nbfaces per volume
std::vector<unsigned int> vecNbFaces;
vecNbFaces.reserve(1000);
// table of face (one dart of each)
std::vector<Dart> vecDartFaces;
vecDartFaces.reserve(map.getNbDarts()/4);
std::vector<VEC3> buffer;
buffer.reserve(16384);
DartMarker mark(map); // marker for darts
for (Dart d = map.begin(); d != map.end(); map.next(d))
{
if (good(d))
TraversorOF<typename PFP::MAP> traFace(map,good);
for (Dart d=traFace.begin(); d!=traFace.end(); d=traFace.next())
{
CellMarkerStore markVert(map, VERTEX); //marker for vertices
VEC3 center(0, 0, 0);
unsigned int nbv = 0;
unsigned int nbf = 0;
std::list<Dart> visitedFaces; // Faces that are traversed
visitedFaces.push_back(d); // Start with the face of d
// For every face added to the list
for (std::list<Dart>::iterator face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
{
if (!mark.isMarked(*face)) // Face has not been visited yet
{
// store a dart of face
vecDartFaces.push_back(*face);
nbf++;
Dart dNext = *face ;
unsigned int nbe=0;
Dart a = d;
Dart b = map.phi1(a);
Dart c = map.phi1(b);
// loop to cut a polygon in triangle on the fly (works only with convex faces)
do
{
if (!markVert.isMarked(dNext))
{
markVert.mark(dNext);
center += positions[dNext];
nbv++;
}
mark.mark(dNext); // Mark
nbe++;
Dart adj = map.phi2(dNext); // Get adjacent face
if (adj != dNext && !mark.isMarked(adj))
visitedFaces.push_back(adj); // Add it
dNext = map.phi1(dNext);
} while(dNext != *face);
m_nbTris += nbe-2;
}
}
center /= typename PFP::REAL(nbv);
vecCenters.push_back(center);
vecNbFaces.push_back(nbf);
}
buffer.push_back(centerVolumes[d]);
buffer.push_back(positions[d]);
buffer.push_back(positions[b]);
buffer.push_back(positions[c]);
b = c;
c = map.phi1(b);
} while (c != d);
}
glBindBufferARB(GL_ARRAY_BUFFER, m_VBOBuffers[0]);
glBufferDataARB(GL_ARRAY_BUFFER, m_nbTris*3*3*sizeof(GLfloat), 0, GL_STREAM_DRAW);
GLvoid* PositionBuffer = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);
VEC3* positionBuf = reinterpret_cast<VEC3*>(PositionBuffer);
m_nbTris = buffer.size()/4;
glBindBufferARB(GL_ARRAY_BUFFER, m_VBOBuffers[1]);
glBufferDataARB(GL_ARRAY_BUFFER, m_nbTris*3*3*sizeof(GLfloat), 0, GL_STREAM_DRAW);
GLvoid* NormalBuffer = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);
VEC3* normalBuf = reinterpret_cast<VEC3*>(NormalBuffer);
m_vboPos->allocate(buffer.size());
VEC3* ptrPos = reinterpret_cast<VEC3*>(m_vboPos->lockPtr());
memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));
std::vector<Dart>::iterator face = vecDartFaces.begin();
for (unsigned int iVol=0; iVol<vecNbFaces.size(); ++iVol)
{
for (unsigned int iFace = 0; iFace < vecNbFaces[iVol]; ++iFace)
{
Dart d = *face++;
m_vboPos->releasePtr();
m_shader->setAttributePosition(m_vboPos);
std::vector<VEC3> vecPos;
vecPos.reserve(16);
// store the face & center
VEC3 center(0, 0, 0);
Dart dd = d;
do
{
const VEC3& P = positions[d];
vecPos.push_back(P);
center += P;
d = map.phi1(d);
} while (d != dd);
center /= REAL(vecPos.size());
//shrink the face
unsigned int nb = vecPos.size();
float okf = 1.0f - kf;
float okv = 1.0f - kv;
for (unsigned int i = 0; i < nb; ++i)
buffer.clear();
// TraversorE<typename PFP::MAP> traEdge(map,good);
// for (Dart d=traEdge.begin(); d!=traEdge.end(); d=traEdge.next())
// {
// buffer.push_back(centerVolumes[d]);
// buffer.push_back(positions[d]);
// buffer.push_back(positions[ map.phi1(d)]);
// }
// TO A REFAIRE AVEC LE BON TRAVERSOR DE LA BONNE ORBITE QUAND ELLE EXISTERA
DartMarker dm(map);
for (Dart d=map.begin(); d!=map.end(); map.next(d))
{
vecPos[i] = vecCenters[iVol]*okv + vecPos[i]*kv;
vecPos[i] = center*okf + vecPos[i]*kf;
}
vecPos.push_back(vecPos.front()); // copy the first for easy computation on next loop
// compute Normal
unsigned int angle = 1;
VEC3 N;
do{
VEC3 V = vecPos[angle+1] - vecPos[angle];
VEC3 U = vecPos[angle] - vecPos[angle-1];
N = U^V;
angle++;
}while (std::isnan(N[0]) && (angle < nb));
N.normalize();
// compute position of points to use for drawing topo
for (unsigned int i = 2; i < nb; ++i)
if (good(d) && !dm.isMarked(d))
{
*positionBuf++ = vecPos[0];
*normalBuf++ = N;
*positionBuf++ = vecPos[i-1];
*normalBuf++ = N;
*positionBuf++ = vecPos[i];
*normalBuf++ = N;
d = map.phi1(d);
}
buffer.push_back(centerVolumes[d]);
buffer.push_back(positions[d]);
buffer.push_back(positions[ map.phi1(d)]);
dm.mark(d);
dm.mark(map.phi2(d));
}
}
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, m_VBOBuffers[0]);
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, m_VBOBuffers[1]);
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER);
m_nbLines = buffer.size()/3;
m_vboPosLine->allocate(buffer.size());
ptrPos = reinterpret_cast<VEC3*>(m_vboPosLine->lockPtr());
memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));
m_vboPosLine->releasePtr();
m_shaderL->setAttributePosition(m_vboPosLine);
}
inline void explodeVolume_VBORender::drawFaces()
inline void ExplodeVolumeRender::drawFaces()
{
glBindBufferARB(GL_ARRAY_BUFFER, m_VBOBuffers[0]);
glVertexPointer(3, GL_FLOAT, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
m_shader->enableVertexAttribs();
glDrawArrays(GL_LINES_ADJACENCY_EXT , 0 , m_nbTris*4 );
m_shader->disableVertexAttribs();
}
glBindBufferARB(GL_ARRAY_BUFFER, m_VBOBuffers[1]);
glNormalPointer(GL_FLOAT, 0, 0);
glEnableClientState(GL_NORMAL_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, m_nbTris*3);
inline void ExplodeVolumeRender::drawEdges()
{
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
m_shaderL->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES , 0 , m_nbLines*3 );
m_shaderL->disableVertexAttribs();
}
}//end namespace VBO
}//end namespace Algo
......
// ShaderExplodeVolumes::fragmentShaderText
VARYING_FRAG vec4 ColorFS;
void main()
{
gl_FragColor = ColorFS;
}
// ShaderExplodeVolumes::geometryShaderText
uniform float explodeV;
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 NormalMatrix;
uniform mat4 ModelViewMatrix;
uniform vec3 lightPosition;
uniform vec4 diffuse;
uniform vec4 ambient;
VARYING_OUT vec4 ColorFS;
void main(void)
{
vec3 v1 = POSITION_IN(2).xyz - POSITION_IN(1).xyz;
vec3 v2 = POSITION_IN(3).xyz - POSITION_IN(1).xyz;
vec3 N = cross(v1,v2);
N = normalize (vec3(NormalMatrix*vec4(N,0.0)));
// compute face center & lighting informations
vec4 newPos = ModelViewMatrix * POSITION_IN(1);
vec3 L = normalize (lightPosition - newPos.xyz);
float lambertTerm = dot(N,L);
ColorFS = ambient;
if (lambertTerm > 0.0)
ColorFS += diffuse * lambertTerm;
// Explode in face
for (int i=1; i<NBVERTS_IN; i++)
{
vec4 P = explodeV * POSITION_IN(i) + (1.0-explodeV)* POSITION_IN(0);
gl_Position = ModelViewProjectionMatrix * P;
EmitVertex();
}
EndPrimitive();
}
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.u-strasbg.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __CGOGN_SHADER_EXPLODE_VOLUMES__
#define __CGOGN_SHADER_EXPLODE_VOLUMES__
#include "Utils/GLSLShader.h"
#include "Geometry/vector_gen.h"
namespace CGoGN
{
namespace Utils
{
class ShaderExplodeVolumes : public GLSLShader
{
protected:
// shader sources
static std::string vertexShaderText;
static std::string fragmentShaderText;
static std::string geometryShaderText;
// uniform locations
GLuint m_unif_ambiant;
GLuint m_unif_diffuse;
GLuint m_unif_lightPos;
GLuint m_unif_explodeV;
float m_explodeV;
Geom::Vec4f m_ambiant;
Geom::Vec4f m_diffuse;
Geom::Vec3f m_light_pos;
VBO* m_vboPos;
void getLocations();
void restoreUniformsAttribs();
public:
ShaderExplodeVolumes();
void setExplodeVolumes(float explode);
void setAmbiant(const Geom::Vec4f& ambiant);
void setDiffuse(const Geom::Vec4f& diffuse);
void setLightPosition(const Geom::Vec3f& lp);
void setParams(float explodeV, const Geom::Vec4f& ambiant, const Geom::Vec4f& diffuse, const Geom::Vec3f& lightPos);
void setAttributePosition(VBO* vbo);
};
} // namespace Utils
} // namespace CGoGN
#endif
// ShaderExplodeVolumes::vertexShaderText
ATTRIBUTE vec3 VertexPosition;
void main()
{
gl_Position = vec4(VertexPosition, 1.0);
}
// ShaderExplodeVolumesLines::fragmentShaderText
VARYING_FRAG vec4 ColorFS;
void main()
{
gl_FragColor = ColorFS;
}
// ShaderExplodeVolumesLines::geometryShaderText
uniform float explodeV;
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 NormalMatrix;
uniform mat4 ModelViewMatrix;
uniform vec4 color;
VARYING_OUT vec4 ColorFS;
void main(void)
{
ColorFS = color;
for (int i=1; i<NBVERTS_IN; i++)
{
vec4 P = explodeV * POSITION_IN(i) + (1.0-explodeV)* POSITION_IN(0);
gl_Position = ModelViewProjectionMatrix * P;
EmitVertex();
}
EndPrimitive();
}
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.u-strasbg.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __CGOGN_SHADER_EXPLODE_VOLUMES_LINES__
#define __CGOGN_SHADER_EXPLODE_VOLUMES_LINES__
#include "Utils/GLSLShader.h"
#include "Geometry/vector_gen.h"
namespace CGoGN
{
namespace Utils
{
class ShaderExplodeVolumesLines : public GLSLShader
{
protected:
// shader sources
static std::string vertexShaderText;
static std::string fragmentShaderText;
static std::string geometryShaderText;
// uniform locations
GLuint m_unif_color;
GLuint m_unif_explodeV;
float m_explodeV;
Geom::Vec4f m_color;
VBO* m_vboPos;
void getLocations();
void restoreUniformsAttribs();
public:
ShaderExplodeVolumesLines();
void setExplodeVolumes(float explode);
void setColor(const Geom::Vec4f& color);
void setParams(float explodeV, const Geom::Vec4f& color);
void setAttributePosition(VBO* vbo);
};
} // namespace Utils
} // namespace CGoGN
#endif
// ShaderExplodeVolumesLines::vertexShaderText
ATTRIBUTE vec3 VertexPosition;
void main()
{
gl_Position = vec4(VertexPosition, 1.0);
}