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 @@ ...@@ -33,6 +33,9 @@
#include "Topology/generic/dart.h" #include "Topology/generic/dart.h"
#include "Topology/generic/attributeHandler.h" #include "Topology/generic/attributeHandler.h"
#include "Topology/generic/functor.h" #include "Topology/generic/functor.h"
#include "Utils/vbo.h"
#include "Utils/Shaders/shaderExplodeVolumes.h"
#include "Utils/Shaders/shaderExplodeVolumesLines.h"
namespace CGoGN namespace CGoGN
{ {
...@@ -47,23 +50,27 @@ namespace GL2 ...@@ -47,23 +50,27 @@ namespace GL2
{ {
class explodeVolume_VBORender class ExplodeVolumeRender
{ {
protected: protected:
Utils::ShaderExplodeVolumes* m_shader;
/** Utils::ShaderExplodeVolumesLines* m_shaderL;
* vbo buffers
* 0: vertices Utils::VBO* m_vboPos;
* 1: normals
*/ Utils::VBO* m_vboPosLine;
GLuint m_VBOBuffers[2];
/** /**
*number of triangles to draw *number of triangles to draw
*/ */
GLuint m_nbTris; GLuint m_nbTris;
GLuint m_nbLines;
public: public:
/** /**
* Constructor * Constructor
...@@ -71,28 +78,49 @@ public: ...@@ -71,28 +78,49 @@ public:
* @param good functor that return true for darts of part to draw * @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 ..) * @param type_vbo vbo to alloc ( VBO_P, VBO_PN, VBO_PNC, VBO_PC ..)
*/ */
explodeVolume_VBORender(); ExplodeVolumeRender();
/** /**
* Destructor * 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 * update all drawing buffers
* @param map the map * @param map the map
* @param good selector
* @param positions attribute of position vertices * @param positions attribute of position vertices
* @param kf exploding coef for face * @param good selector
* @param kv exploding coef for face
*/ */
template<typename PFP> 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 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 }//end namespace GL2
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "Geometry/vector_gen.h" #include "Geometry/vector_gen.h"
#include "Topology/generic/dartmarker.h" #include "Topology/generic/dartmarker.h"
#include "Topology/generic/cellmarker.h" #include "Topology/generic/cellmarker.h"
#include "Algo/Geometry/centroid.h"
namespace CGoGN namespace CGoGN
{ {
...@@ -39,178 +40,140 @@ namespace Render ...@@ -39,178 +40,140 @@ namespace Render
namespace GL2 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> 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::VEC3 VEC3;
typedef typename PFP::REAL REAL; 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> buffer;
std::vector<VEC3> vecCenters; buffer.reserve(16384);
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);
DartMarker mark(map); // marker for darts TraversorOF<typename PFP::MAP> traFace(map,good);
for (Dart d = map.begin(); d != map.end(); map.next(d)) for (Dart d=traFace.begin(); d!=traFace.end(); d=traFace.next())
{
if (good(d))
{ {
CellMarkerStore markVert(map, VERTEX); //marker for vertices Dart a = d;
VEC3 center(0, 0, 0); Dart b = map.phi1(a);
unsigned int nbv = 0; Dart c = map.phi1(b);
unsigned int nbf = 0;
std::list<Dart> visitedFaces; // Faces that are traversed // loop to cut a polygon in triangle on the fly (works only with convex faces)
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;
do do
{ {
if (!markVert.isMarked(dNext)) buffer.push_back(centerVolumes[d]);
{ buffer.push_back(positions[d]);
markVert.mark(dNext); buffer.push_back(positions[b]);
center += positions[dNext]; buffer.push_back(positions[c]);
nbv++; b = c;
} c = map.phi1(b);
mark.mark(dNext); // Mark
nbe++; } while (c != d);
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);
}
} }
glBindBufferARB(GL_ARRAY_BUFFER, m_VBOBuffers[0]); m_nbTris = buffer.size()/4;
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);
glBindBufferARB(GL_ARRAY_BUFFER, m_VBOBuffers[1]); m_vboPos->allocate(buffer.size());
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);
VEC3* ptrPos = reinterpret_cast<VEC3*>(m_vboPos->lockPtr());
memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));
std::vector<Dart>::iterator face = vecDartFaces.begin(); m_vboPos->releasePtr();
for (unsigned int iVol=0; iVol<vecNbFaces.size(); ++iVol) m_shader->setAttributePosition(m_vboPos);
{
for (unsigned int iFace = 0; iFace < vecNbFaces[iVol]; ++iFace)
{
Dart d = *face++;
std::vector<VEC3> vecPos;
vecPos.reserve(16);
// store the face & center buffer.clear();
VEC3 center(0, 0, 0); // TraversorE<typename PFP::MAP> traEdge(map,good);
Dart dd = d; // for (Dart d=traEdge.begin(); d!=traEdge.end(); d=traEdge.next())
do // {
{ // buffer.push_back(centerVolumes[d]);
const VEC3& P = positions[d]; // buffer.push_back(positions[d]);
vecPos.push_back(P); // buffer.push_back(positions[ map.phi1(d)]);
center += P; // }
d = map.phi1(d);
} while (d != dd); // TO A REFAIRE AVEC LE BON TRAVERSOR DE LA BONNE ORBITE QUAND ELLE EXISTERA
center /= REAL(vecPos.size());
DartMarker dm(map);
//shrink the face for (Dart d=map.begin(); d!=map.end(); map.next(d))
unsigned int nb = vecPos.size();
float okf = 1.0f - kf;
float okv = 1.0f - kv;
for (unsigned int i = 0; i < nb; ++i)
{ {
vecPos[i] = vecCenters[iVol]*okv + vecPos[i]*kv; if (good(d) && !dm.isMarked(d))
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)
{ {
*positionBuf++ = vecPos[0]; buffer.push_back(centerVolumes[d]);
*normalBuf++ = N; buffer.push_back(positions[d]);
*positionBuf++ = vecPos[i-1]; buffer.push_back(positions[ map.phi1(d)]);
*normalBuf++ = N; dm.mark(d);
*positionBuf++ = vecPos[i]; dm.mark(map.phi2(d));
*normalBuf++ = N;
d = map.phi1(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]); m_shader->enableVertexAttribs();
glVertexPointer(3, GL_FLOAT, 0, 0); glDrawArrays(GL_LINES_ADJACENCY_EXT , 0 , m_nbTris*4 );
glEnableClientState(GL_VERTEX_ARRAY); 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); m_shaderL->enableVertexAttribs();
glDisableClientState(GL_NORMAL_ARRAY); glDrawArrays(GL_TRIANGLES , 0 , m_nbLines*3 );
m_shaderL->disableVertexAttribs();
} }
}//end namespace VBO }//end namespace VBO
}//end namespace Algo }//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 *