Commit b446e097 authored by Sylvain Thery's avatar Sylvain Thery

ajout vertex attributes dans rendu VBO GLSL 2.1

parent 7d8cee23
......@@ -118,7 +118,7 @@ void myGlutWin::init()
glClearColor(0.1f,0.1f,0.1f,0.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
// glEnable(GL_NORMALIZE);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
......
......@@ -55,9 +55,12 @@ target_link_libraries( tp_master
add_executable( tuto_mt tuto_mt.cpp)
target_link_libraries( tuto_mt
container topology utils algo ${COMMON_LIBS} boost_thread)
container topology utils algo ${COMMON_LIBS} boost_thread-mt)
add_executable( tuto_ogl3 tuto_ogl3.cpp)
target_link_libraries( tuto_ogl3
container topology utils algo ${COMMON_LIBS} )
add_executable( tuto_ogl2 tuto_ogl2.cpp)
target_link_libraries( tuto_ogl2
container topology utils algo ${COMMON_LIBS} )
......@@ -268,6 +268,14 @@ public:
int main(int argc, char **argv)
{
if (argc < 2)
{
std::cerr << argv[0] << " mesh"<< std::endl;
exit(1);
}
// declaration of the map
PFP::MAP myMap;
......@@ -279,8 +287,7 @@ int main(int argc, char **argv)
MyGlutWin mgw(&argc, argv, 800, 800);
glewInit();
// release context (leave it for thread 0);
mgw.releaseContext();
std::vector<std::string> attrNames ;
if(!Algo::Import::importMesh<PFP>(myMap, argv[1], attrNames))
......@@ -295,8 +302,6 @@ int main(int argc, char **argv)
// cree un handler d'attribut pour la position des points (créé lors de l'import)
position = myMap.getAttribute<PFP::VEC3>(VERTEX_ORBIT, attrNames[0]) ;
std::cout << "Sommets:"<< position.end()<< std::endl;
// cree un handler pour les normales aux sommets
AttributeHandler<PFP::VEC3> normal = myMap.addAttribute<PFP::VEC3>(VERTEX_ORBIT, "normal");
AttributeHandler<PFP::VEC3> normal2 = myMap.addAttribute<PFP::VEC3>(VERTEX_ORBIT, "normal2");
......@@ -332,8 +337,6 @@ int main(int argc, char **argv)
std::cout << "length :" <<le.first/le.second<< std::endl;
// on enleve les markers ajoutes
myMap.removeThreadMarker(4);
......
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009, 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: https://iggservis.u-strasbg.fr/CGoGN/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#include <iostream>
#include "Utils/glutwin.h"
#include "Topology/generic/parameters.h"
#include "Topology/map/map2.h"
#include "Topology/generic/embeddedMap2.h"
#include "Algo/Geometry/boundingbox.h"
#include "Algo/Render/vbo_MapRender.h"
#include "Algo/Modelisation/polyhedron.h"
#include "Geometry/vector_gen.h"
#include "Algo/Geometry/normal.h"
using namespace CGoGN ;
/**
* Struct that contains some informations about the types of the manipulated objects
* Mainly here to be used by the algorithms that are parameterized by it
*/
struct PFP: public PFP_STANDARD
{
// definition of the type of the map
typedef EmbeddedMap2<Map2> MAP;
};
/**
* A class for a little interface and rendering
*/
class MyGlutWin: public Utils::SimpleGlutWin
{
public:
void myRedraw();
PFP::REAL gWidthObj;
PFP::VEC3 gPosObj;
Algo::Render::VBO::MapRender_VBO* m_render;
Utils::GLSLShader shaders[4];
Geom::Vec4f colSpec;
float shininess;
int rt;
MyGlutWin(int* argc, char **argv, int winX, int winY) : SimpleGlutWin(argc, argv, winX, winY),rt(0)
{
shaders[0].loadShaders("phong_gl2.vert","phong_gl2.frag");
colSpec = Geom::Vec4f(0.9f, 0.9f, 0.9f, 1.0f) ;
shininess = 80.0f ;
}
~MyGlutWin()
{
delete m_render ;
}
};
void MyGlutWin::myRedraw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
// center the scene
float sc = 50./gWidthObj;
glScalef(sc,sc,sc);
glTranslatef(-gPosObj[0],-gPosObj[1],-gPosObj[2]);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
// some materials
glMaterialfv(GL_FRONT, GL_SPECULAR, colSpec.data()) ;
glMaterialf(GL_FRONT, GL_SHININESS, shininess) ;
// bin shader
shaders[0].bind();
// draw triangles
m_render->draw(Algo::Render::VBO::TRIANGLES) ;
// unbind (in case of other rendering wihtout shader)
shaders[0].unbind();
glPopMatrix();
}
int main(int argc, char **argv)
{
// instanciation of the interface
MyGlutWin mgw(&argc, argv, 800, 800);
// declaration of the map
PFP::MAP myMap;
AttributeHandler<PFP::VEC3> position = myMap.addAttribute<PFP::VEC3>(VERTEX_ORBIT, "position");
AttributeHandler<PFP::VEC3> normal = myMap.addAttribute<PFP::VEC3>(VERTEX_ORBIT, "normal");
Algo::Modelisation::Polyhedron<PFP> prim3(myMap, position);
prim3.tore_topo(16, 32);
prim3.embedTore(30.0f,10.0f);
// compute the normal of mesh
Algo::Geometry::computeNormalVertices<PFP>(myMap,position,normal);
mgw.init();
glClearColor(0.1,0.1,0.1,0.0);
glEnable(GL_DEPTH_TEST);
// computation of the bounding box
Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position);
mgw.gWidthObj = std::max<PFP::REAL>(std::max<PFP::REAL>(bb.size(0), bb.size(1)), bb.size(2));
mgw.gPosObj = (bb.min() + bb.max()) / PFP::REAL(2);
// instanciation of the vbo renderer
mgw.m_render = new Algo::Render::VBO::MapRender_VBO();
// vertex attribute declaration (max 12)
mgw.m_render->useVertexAttributeName("ColorPerVertex",mgw.shaders[0]);
// must relink the shader after binding attributes
mgw.shaders[0].link();
// copy data from map attributes to vbo for vertex attribute
mgw.m_render->updateVAData("ColorPerVertex", normal);
// copy data from map attributes to vbo
mgw.m_render->updateData(Algo::Render::VBO::POSITIONS, position);
mgw.m_render->updateData(Algo::Render::VBO::NORMALS, normal);
// update the renderer (primitives)
SelectorTrue allDarts;
mgw.m_render->initPrimitives<PFP>(myMap, allDarts,Algo::Render::VBO::TRIANGLES);
// mgw.m_render->initPrimitives<PFP>(myMap, allDarts,Algo::Render::VBO::LINES);
// mgw.m_render->initPrimitives<PFP>(myMap, allDarts,Algo::Render::VBO::POINTS);
mgw.mainLoop();
return 0;
}
......@@ -35,6 +35,8 @@
#include "Container/convert.h"
#include "Geometry/vector_gen.h"
#include "Utils/GLSLShader.h"
namespace CGoGN
{
......@@ -71,13 +73,26 @@ enum bufferIndex {
FLAT_BUFFER = 3,
POSITIONS_BUFFER = 4,
NORMALS_BUFFER = 5,
COLORS_BUFFER = 6
COLORS_BUFFER = 6,
FIRST_ATTRIBUTE_BUFFER = 7
} ;
const unsigned int NB_BUFFERS = 7 ;
const unsigned int NB_BUFFERS = 20 ;
// Warning using attributes forbid using the following buildin attributes
// gl_SecondaryColor
// gl_FogCoord
// gl_MultiTexCoord0
// gl_MultiTexCoord1
// gl_MultiTexCoord2
// gl_MultiTexCoord3
// gl_MultiTexCoord4
// gl_MultiTexCoord5
// gl_MultiTexCoord6
// gl_MultiTexCoord7
const unsigned int FIRST_VERTEX_ATTRIB = 4 ;
const unsigned int NB_ATTRIBUTES = 12 ;
class MapRender_VBO
{
......@@ -90,6 +105,15 @@ protected:
bool m_allocatedBuffers[NB_BUFFERS] ;
bool m_usedBuffers[NB_BUFFERS] ;
bool m_allocatedAttributes[NB_ATTRIBUTES] ;
bool m_usedAttributes[NB_ATTRIBUTES] ;
unsigned int m_AttributesDataSize[NB_ATTRIBUTES];
unsigned int m_nbVertexAttrib;
std::map<std::string,GLuint> m_attributebyName;
/**
* number of indices of triangles
*/
......@@ -136,7 +160,59 @@ public:
void enableBuffers(int buffersMask) ;
void disableBuffers(int buffersMask) ;
/**
* update the data for vertex attributes
* @param vertex_attrib vertex attrib id
* @param attrib attribute where data is stored
* @param conv Callback of attribute conversion (NULL if direct copy, default value)
*/
template <typename ATTR_HANDLER>
void updateVAData(unsigned int vertex_attrib, const ATTR_HANDLER& attrib, ConvertAttrib* conv = NULL) ;
/**
* update the data for vertex attributes
* @param va_name vertex attrib name (in shader)
* @param attrib attribute where data is stored
* @param conv Callback of attribute conversion (NULL if direct copy, default value)
*/
template <typename ATTR_HANDLER>
void updateVAData(const std::string& name, const ATTR_HANDLER& attrib, ConvertAttrib* conv = NULL) ;
/**
* enable a vertex attribute for rendering (updateDate automatically enable attrib)
*/
void enableVertexAttrib(const std::string& name);
/**
* disable a vertex attribute for rendering
*/
void disableVertexAttrib(const std::string& name);
/**
* associate a name to a vertex attribute
* @param name the name in shader
* @param sh the shader
* @return the id to use with update (if not using name)
*/
unsigned int useVertexAttributeName(const std::string& name, const Utils::GLSLShader& sh);
protected:
unsigned int vbo_index_attribute( unsigned int att) { return att + FIRST_ATTRIBUTE_BUFFER - FIRST_VERTEX_ATTRIB;}
/**
* enable a vertex attribute for rendering (updateDate automatically enable attrib)
*/
void enableVertexAttrib(unsigned int index);
/**
* disable a vertex attribute for rendering
*/
void disableVertexAttrib(unsigned int index);
/**
* fill buffer directly from attribute
*/
......
......@@ -37,6 +37,111 @@ namespace VBO
{
// inline functions:
inline void MapRender_VBO::enableVertexAttrib(unsigned int index)
{
m_usedAttributes[index] = true ;
}
inline void MapRender_VBO::disableVertexAttrib(unsigned int index)
{
m_usedAttributes[index] = false ;
}
/**
* enable a vertex attribute for rendering (updateDate automatically enable attrib)
*/
inline void MapRender_VBO::enableVertexAttrib(const std::string& name)
{
std::map<std::string,unsigned int>::iterator it = m_attributebyName.find(name);
if (it != m_attributebyName.end())
enableVertexAttrib(it->second);
else
std::cerr <<"enableVertexAttrib: unknown attribute "<< name << std::endl;
}
inline void MapRender_VBO::disableVertexAttrib(const std::string& name)
{
std::map<std::string,unsigned int>::iterator it = m_attributebyName.find(name);
if (it != m_attributebyName.end())
disableVertexAttrib(it->second);
else
std::cerr <<"disableVertexAttrib: unknown attribute "<< name << std::endl;
}
inline unsigned int MapRender_VBO::useVertexAttributeName(const std::string& name, const Utils::GLSLShader& sh)
{
unsigned int vertex_attrib =0;
std::map<std::string,unsigned int>::iterator it = m_attributebyName.find(name);
if (it == m_attributebyName.end())
{
vertex_attrib = m_nbVertexAttrib++;
m_attributebyName.insert(std::pair<std::string,unsigned int>(name,vertex_attrib));
}
else
vertex_attrib = it->second;
sh.bindAttrib(vertex_attrib+FIRST_VERTEX_ATTRIB,name.c_str());
return vertex_attrib;
}
template <typename ATTR_HANDLER>
void MapRender_VBO::updateVAData(unsigned int vertex_attrib, const ATTR_HANDLER& attrib, ConvertAttrib* conv)
{
// choisit le bon buffer en fonction du paramètre upType
unsigned int indexVBO = vertex_attrib + FIRST_ATTRIBUTE_BUFFER;
if (! m_allocatedAttributes[vertex_attrib] )
{
glGenBuffersARB(1, &(m_VBOBuffers[indexVBO])) ;
m_allocatedAttributes[vertex_attrib] = true ;
}
m_usedAttributes[vertex_attrib] = true ;
m_AttributesDataSize[vertex_attrib]= sizeof(typename ATTR_HANDLER::DATA_TYPE) / sizeof(float);
if (conv)
fillBufferConvert(indexVBO, attrib, conv) ;
else
fillBufferDirect(indexVBO, attrib) ;
}
template <typename ATTR_HANDLER>
void MapRender_VBO::updateVAData(const std::string& name, const ATTR_HANDLER& attrib, ConvertAttrib* conv)
{
unsigned int vertex_attrib = 0;
std::map<std::string,unsigned int>::iterator it = m_attributebyName.find(name);
if (it == m_attributebyName.end())
{
vertex_attrib = m_nbVertexAttrib++;
m_attributebyName.insert(std::pair<std::string,unsigned int>(name,vertex_attrib));
std::cerr << "warning update data with unknown name, adding vertex attribute"<< std::endl;
}
else
{
vertex_attrib = it->second;
}
updateVAData<ATTR_HANDLER>(vertex_attrib,attrib,conv);
}
template <typename ATTR_HANDLER>
void MapRender_VBO::updateData(int upType, const ATTR_HANDLER& attrib, ConvertAttrib* conv)
......@@ -323,14 +428,6 @@ void MapRender_VBO::initPrimitives(typename PFP::MAP& map, const FunctorSelect&
initLines<PFP>(map,good,tableIndices,thread) ;
m_nbIndicesLines = tableIndices.size();
vbo_ind = m_VBOBuffers[LINE_INDICES];
for (unsigned int i=0; i< tableIndices.size(); ++i)
{
std::cout << tableIndices[i]<< "/";
if (i%2 == 1) std::cout << std::endl;
}
std::cout << std::endl;
break;
case POINTS:
initPoints<PFP>(map,good,tableIndices,thread);
......
......@@ -196,6 +196,11 @@ public:
bool loadShaders(const std::string& vs, const std::string& fs, const std::string& gs, GLint inputGeometryPrimitive=GL_TRIANGLES,GLint outputGeometryPrimitive=GL_TRIANGLES);
/**
* Link the shader do it just after binding the attributes
*/
bool link();
inline bool isCreated();
bool isBinded();
......
//Pixel_Shader
varying vec3 normal, lightDir, eyeVec;
varying vec3 vcolor;
void main (void)
{
vec4 final_color = vec4(0.0,0.0,0.0,0.0);
vec3 N = normalize(normal);
vec3 L = normalize(lightDir);
float lambertTerm = dot(N,L);
if(lambertTerm > 0.0)
{
final_color += vec4(vcolor,1.0) * lambertTerm;
vec3 E = normalize(eyeVec);
vec3 R = reflect(-L, N);
float specular = pow( max(dot(R, E), 0.0),
gl_FrontMaterial.shininess );
final_color += gl_FrontMaterial.specular *
specular;
}
gl_FragColor = final_color;
}
//Vertex_Shader
attribute vec3 ColorPerVertex;
varying vec3 normal, lightDir, eyeVec;
varying vec3 vcolor;
void main()
{
normal = gl_NormalMatrix * gl_Normal;
vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
lightDir = vec3(gl_LightSource[0].position.xyz - vVertex);
eyeVec = -vVertex;
vcolor = ColorPerVertex;
gl_Position = ftransform();
}
......@@ -37,6 +37,7 @@ namespace VBO
{
MapRender_VBO::MapRender_VBO():
m_nbVertexAttrib(0),
m_nbIndicesTri(0),
m_nbIndicesLines(0)
{
......@@ -46,6 +47,14 @@ MapRender_VBO::MapRender_VBO():
m_allocatedBuffers[i] = false ;
m_usedBuffers[i] = false ;
}
for(unsigned int i = 0; i < NB_ATTRIBUTES; ++i)
{
m_allocatedAttributes[i] = false ;
m_usedAttributes[i] = false ;
m_AttributesDataSize[i]=0;
}
}
MapRender_VBO::~MapRender_VBO()
......@@ -56,6 +65,7 @@ MapRender_VBO::~MapRender_VBO()
MapRender_VBO::MapRender_VBO(const MapRender_VBO& mrvbo):
m_nbVertexAttrib(mrvbo.m_nbVertexAttrib),
m_nbIndicesTri(0),
m_nbIndicesLines(0)
{
......@@ -73,6 +83,16 @@ MapRender_VBO::MapRender_VBO(const MapRender_VBO& mrvbo):
m_allocatedBuffers[i] = mrvbo.m_allocatedBuffers[i] ;
m_usedBuffers[i] = mrvbo.m_usedBuffers[i] ;
}
for(unsigned int i = 0; i < NB_ATTRIBUTES; ++i)
{
m_allocatedAttributes[i] = mrvbo.m_allocatedAttributes[i] ;
m_usedAttributes[i] = mrvbo.m_usedAttributes[i] ;
m_AttributesDataSize[i] = mrvbo.m_AttributesDataSize[i];
}
}
......@@ -163,6 +183,15 @@ void MapRender_VBO::drawTriangles(bool bindColors)
}
}
for(unsigned int j = 0; j < m_nbVertexAttrib; ++j)
if(m_usedAttributes[j])
{
glBindBufferARB(GL_ARRAY_BUFFER, m_VBOBuffers[j+ FIRST_ATTRIBUTE_BUFFER]);
glEnableVertexAttribArray(j+FIRST_VERTEX_ATTRIB);
glVertexAttribPointer(j+FIRST_VERTEX_ATTRIB, m_AttributesDataSize[j], GL_FLOAT, false, 0, 0);
}
glDrawElements(GL_TRIANGLES, m_nbIndicesTri, GL_UNSIGNED_INT, 0);
glDisableClientState(GL_INDEX_ARRAY);
......@@ -186,6 +215,12 @@ void MapRender_VBO::drawTriangles(bool bindColors)
}
}
}
for(unsigned int j = 0; j < m_nbVertexAttrib; ++j)
if(m_usedAttributes[j])
glDisableVertexAttribArray(j+FIRST_VERTEX_ATTRIB);
}
void MapRender_VBO::drawLines(bool bindColors)
......@@ -218,6 +253,14 @@ void MapRender_VBO::drawLines(bool bindColors)
}
}
for(unsigned int j = 0; j < m_nbVertexAttrib; ++j)
if(m_usedAttributes[j])
{
glBindBufferARB(GL_ARRAY_BUFFER, m_VBOBuffers[j+ FIRST_ATTRIBUTE_BUFFER]);
glEnableVertexAttribArray(j+FIRST_VERTEX_ATTRIB);
glVertexAttribPointer(j+FIRST_VERTEX_ATTRIB, m_AttributesDataSize[j], GL_FLOAT, false, 0, 0);
}
glDrawElements(GL_LINES, m_nbIndicesLines, GL_UNSIGNED_INT, 0);
glDisableClientState(GL_INDEX_ARRAY);
......@@ -240,6 +283,11 @@ void MapRender_VBO::drawLines(bool bindColors)
}
}
}
for(unsigned int j = 0; j < m_nbVertexAttrib; ++j)
if(m_usedAttributes[j])
glDisableVertexAttribArray(j+FIRST_VERTEX_ATTRIB);
}
void MapRender_VBO::drawPoints(bool bindColors)
......@@ -272,6 +320,14 @@ void MapRender_VBO::drawPoints(bool bindColors)
}
}
for(unsigned int j = 0; j < m_nbVertexAttrib; ++j)
if(m_usedAttributes[j])
{
glBindBufferARB(GL_ARRAY_BUFFER, m_VBOBuffers[j+ FIRST_ATTRIBUTE_BUFFER]);
glEnableVertexAttribArray(j+FIRST_VERTEX_ATTRIB);
glVertexAttribPointer(j+FIRST_VERTEX_ATTRIB, m_AttributesDataSize[j], GL_FLOAT, false, 0, 0);
}
glDrawElements(GL_POINTS, m_nbIndicesPoints, GL_UNSIGNED_INT, 0) ;
glDisableClientState(GL_INDEX_ARRAY);
......@@ -296,6 +352,11 @@ void MapRender_VBO::drawPoints(bool bindColors)
}
}
}
for(unsigned int j = 0; j < m_nbVertexAttrib; ++j)
if(m_usedAttributes[j])
glDisableVertexAttribArray(j+FIRST_VERTEX_ATTRIB);
}
......
......@@ -428,6 +428,39 @@ bool GLSLShader::create(GLint inputGeometryPrimitive,GLint outputGeometryPrimiti
}
bool GLSLShader::link()
{
int status;
char *info_log;
/*** link program object ***/
glLinkProgramARB( m_program_object );
glGetObjectParameterivARB( m_program_object, GL_OBJECT_LINK_STATUS_ARB, &status );
if( !status )
{
std::cerr << "ERROR - GLSLShader::create() - error occured while linking shader program." << std::endl;
info_log = getInfoLog( m_program_object );
std::cerr << " LINK " << info_log << std::endl;
delete [] info_log;
glDetachObjectARB( m_program_object, m_vertex_shader_object );
glDetachObjectARB( m_program_object, m_fragment_shader_object );
if (m_geom_shader_object)
glDetachObjectARB( m_program_object, m_geom_shader_object );
glDeleteObjectARB( m_program_object );
m_program_object = 0;
return false;
}
return true;
}
bool GLSLShader::bind()
{
if( m_program_object )
......
......@@ -125,6 +125,10 @@ SimpleGlutWinGL3::SimpleGlutWinGL3(int* argc, char **argv, int winX, int winY)
std::cout << "OpenGL v"<<MajorVersionContext<<"."<<MinorVersionContext<<std::endl;
std::cout << glGetString(GL_VERSION)<<std::endl;
int nbatt;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nbatt);
std::cout << "Attribute max: "<< nbatt << std::endl;
shaderOk = Utils::GLSLShader::init();
......