diff --git a/Apps/Tuto/tuto5.cpp b/Apps/Tuto/tuto5.cpp index 525a30c0392df81436d85f9e1353a16ac8dbcbf9..4fe795005d632561842deaadc28c6c282e48fedc 100644 --- a/Apps/Tuto/tuto5.cpp +++ b/Apps/Tuto/tuto5.cpp @@ -44,6 +44,7 @@ #include "Algo/Render/topo3_vboRender.h" #include "Topology/generic/cellmarker.h" +#include "Utils/text3d.h" //#include "testMaps.h" @@ -66,6 +67,10 @@ Dart dglobal; unsigned int idNorm; unsigned int idCol; + + + + class myGlutWin: public Utils::SimpleGlutWin { public: @@ -83,8 +88,12 @@ public: Algo::Render::VBO::MapRender_VBO* m_render; Algo::Render::VBO::topo3_VBORenderMapD* m_render_topo; + Utils::Strings3D m_strings; + void updateVBO(); + void storeVerticesInfo(); + myGlutWin( int* argc, char **argv, int winX, int winY):SimpleGlutWin(argc,argv,winX,winY) { aff_help = false; @@ -97,6 +106,22 @@ public: void myKeyboard(unsigned char keycode, int x, int y); }; +void myGlutWin::storeVerticesInfo() +{ + + CellMarker mv(myMap,VERTEX_CELL); + for (Dart d=myMap.begin(); d!=myMap.end(); myMap.next(d)) + { + if (!mv.isMarked(d)) + { + mv.mark(d); + std::stringstream ss; + ss << d << " : "<< position[d]; + m_strings.addString(ss.str(),position[d]); + } + } +} + void myGlutWin::myRedraw(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -161,6 +186,15 @@ void myGlutWin::myRedraw(void) } +// m_strings.predraw(Geom::Vec3f(0.0,1.0,1.0)); +// m_strings.draw(0,Geom::Vec3f(0.5,0.5,0.5)); +// m_strings.draw(1,Geom::Vec3f(-0.5,0.5,0.5)); +// m_strings.draw(2,Geom::Vec3f(-0.5,-0.5,0.5)); +// m_strings.postdraw(); + + + m_strings.drawAll(Geom::Vec3f(0.0,1.0,1.0)); + //affichage de l'aide if (aff_help) { glColor3f(1.0f,1.0f,1.0f); @@ -503,10 +537,11 @@ int main(int argc, char **argv) mgw.m_render = new Algo::Render::VBO::MapRender_VBO(); mgw.m_render_topo = new Algo::Render::VBO::topo3_VBORenderMapD(); - mgw.updateVBO(); - + mgw.m_strings.init(); + mgw.storeVerticesInfo(); + mgw.m_strings.sendToVBO(); mgw.mainLoop(); diff --git a/include/Utils/GLSLShader.h b/include/Utils/GLSLShader.h index f3f8943a6bdba6d8050e2763a3d980a4d93f00cc..d5fb14dc6801cc1f6f4899ec8ad2006ac9ff08ac 100644 --- a/include/Utils/GLSLShader.h +++ b/include/Utils/GLSLShader.h @@ -39,6 +39,7 @@ #include #include #include +#include namespace CGoGN { @@ -128,10 +129,7 @@ protected: */ bool create(GLint inputGeometryPrimitive=GL_TRIANGLES,GLint outputGeometryPrimitive=GL_TRIANGLES); - /* - * search file in different path - */ - std::string findFile(const std::string filename); + /** * get log after compiling @@ -141,6 +139,8 @@ protected: char* getInfoLog( GLhandleARB obj ); + static std::vector m_pathes; + public: /** * constructor @@ -153,6 +153,11 @@ public: */ virtual ~GLSLShader(); + /* + * search file in different path + */ + static std::string findFile(const std::string filename); + /** * test support of shader @@ -210,6 +215,9 @@ public: virtual void unbind(); + /** + * + */ GLuint getAttribIndex( char* attribName ); @@ -225,20 +233,49 @@ public: void bindAttrib(unsigned int att, const char* name) const; + /** + * check shader validity width official GLSL syntax + */ bool validateProgram(); + /** + * check program link status + */ bool checkProgram(); + /** + * check shader compile status + */ bool checkShader(int shaderType); public: - + /** + * set uniform shader float variable + * @warning practical but less efficient that storing id (get with glGetUniformLocation) and use glUniform*fvARB + * @param NB template size of variable to set + * @param name name in shader + * @param pointer on data to copy + */ template void setuniformf( const char* name , float* val); + /** + * set uniform shader int variable + * @warning practical but less efficient that storing id (get with glGetUniformLocation) and use glUniform*ivARB + * @param NB template size of variable to set + * @param name name in shader + * @param pointer on data to copy + */ template void setuniformi( const char* name , int* val); + + /** + * add search path for file + * @param path to add + */ + void addPathFileSeach(const std::string& path); + }; @@ -289,13 +326,13 @@ void GLSLShader::setuniformi( const char* name , int* val) glUniform1ivARB( uni, 1, val) ; break; case 2: - glUniform2ivARB( uni, 2, val) ; + glUniform2ivARB( uni, 1, val) ; break; case 3: - glUniform3ivARB( uni, 3, val) ; + glUniform3ivARB( uni, 1, val) ; break; case 4: - glUniform4ivARB( uni, 4, val) ; + glUniform4ivARB( uni, 1, val) ; break; } } @@ -305,6 +342,7 @@ void GLSLShader::setuniformi( const char* name , int* val) + } //namespace Utils } //namespace CGoGN diff --git a/include/Utils/text3d.h b/include/Utils/text3d.h new file mode 100644 index 0000000000000000000000000000000000000000..39b6b71b55863430c6d47587927ce2c7e1746853 --- /dev/null +++ b/include/Utils/text3d.h @@ -0,0 +1,149 @@ +/******************************************************************************* +* 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 * +* * +*******************************************************************************/ + +#ifndef __TEXT_3D__ +#define __TEXT_3D__ + +#include "Utils/GLSLShader.h" +#include "Geometry/vector_gen.h" +#include +#include + +namespace CGoGN +{ +namespace Utils +{ + +class Strings3D +{ +protected: + static const unsigned int WIDTHFONT = 32; + + static const unsigned int REALWIDTHFONT = 18; + + static const unsigned int WIDTHTEXTURE = 512; + + static const unsigned int HEIGHTTEXTURE = 256; + + static const unsigned int CHARSPERLINE = WIDTHTEXTURE/WIDTHFONT; + + static const unsigned int CHARSPERCOL = HEIGHTTEXTURE/WIDTHFONT; + + ILuint m_imgName; + + std::vector m_strings; + + unsigned int m_nbChars; + + std::vector< std::pair > m_strpos; + + std::vector< Geom::Vec3f > m_strTranslate; + + /** + * VBO (4f: x,y,u,v) + */ + GLuint m_vbo1; + + unsigned int sendOneStringToVBO(const std::string& str, float **buffer); + + + GLuint m_idTexture; + + GLuint m_uniform_texture; + + GLuint m_uniform_scale; + + GLuint m_uniform_position; + + GLuint m_uniform_color; + + Utils::GLSLShader m_shader; + + +public: + Strings3D(); + + ~Strings3D(); + + /** + * initialization step + * OpenGL context must be opened + * @param scale factor for font rendering + */ + void init(float scale=1.0f); + + /** + * add astring + * @param string to add to pool of string + * @return the id of string for rendering + */ + unsigned int addString(const std::string& str); + + /** + * add astring with its position + * @param string to add to pool of string + * @param pos the position of text + * @return the id of string (future use:updating data) + */ + unsigned int addString(const std::string& str, const Geom::Vec3f& pos); + + /** + * once all string are stored, we must send it to the gracphic card + */ + void sendToVBO(); + + /** + * draw on string + * @param idSt the id of string + * @param pos the position of text + */ + void draw(unsigned int idSt, const Geom::Vec3f& pos); + + /** + * Draw all text stored with their position + * @param color the color of text + */ + void drawAll(const Geom::Vec3f& color); + + /** + * call once before several draw(id,pos) + * @param color the color of text + */ + void predraw(const Geom::Vec3f& color); + + /** + * call once after several draw(id,pos) + */ + void postdraw(); + + /** + * set the scale for font rendering + * @param scale + */ + void setScale(float scale); + +}; +} +} +#endif diff --git a/lib/Shaders/font_cgogn.png b/lib/Shaders/font_cgogn.png new file mode 100644 index 0000000000000000000000000000000000000000..6e4fa40c24c1358dbccfe41db096926a2d9938e3 Binary files /dev/null and b/lib/Shaders/font_cgogn.png differ diff --git a/lib/Shaders/text.frag b/lib/Shaders/text.frag new file mode 100644 index 0000000000000000000000000000000000000000..8455a51205d1e45be12cbd75886317f556366f18 --- /dev/null +++ b/lib/Shaders/text.frag @@ -0,0 +1,9 @@ +varying vec2 tex_coord; +uniform sampler2D FontTexture; +uniform vec3 color; + +void main (void) +{ + float lum = texture2D(FontTexture, tex_coord).s; + gl_FragColor = vec4(color,0.0)*lum; +} diff --git a/lib/Shaders/text.vert b/lib/Shaders/text.vert new file mode 100644 index 0000000000000000000000000000000000000000..b1787a978237db5e7cb8597c1c208e6f3670141a --- /dev/null +++ b/lib/Shaders/text.vert @@ -0,0 +1,12 @@ +uniform vec3 strPos; +uniform float scale; + +varying vec2 tex_coord; + +void main() +{ + + vec4 pos = gl_ModelViewMatrix * vec4(strPos,1.0) + vec4(gl_Vertex[0]*scale,gl_Vertex[1]*scale,0.0,0.0); + tex_coord = vec2(gl_Vertex[2],gl_Vertex[3]); + gl_Position = gl_ProjectionMatrix * pos; +} diff --git a/src/Utils/GLSLShader.cpp b/src/Utils/GLSLShader.cpp index 219caf8bb3fd1747f593a7bef30a036a3134cf56..ac5f49c9da5773c7799f231e05a27efa1b247563 100644 --- a/src/Utils/GLSLShader.cpp +++ b/src/Utils/GLSLShader.cpp @@ -35,6 +35,9 @@ namespace CGoGN namespace Utils { + +std::vector GLSLShader::m_pathes; + GLSLShader::GLSLShader() { m_vertex_shader_object = 0; @@ -527,6 +530,20 @@ std::string GLSLShader::findFile(const std::string filename) } file.close(); + for (std::vector::const_iterator ipath = m_pathes.begin(); ipath != m_pathes.end(); ++ipath) + { + std::string st(*ipath); + st.append(filename); + + std::ifstream file2; + file2.open(st.c_str(),std::ios::in); + if (!file2.fail()) + { + file2.close(); + return st; + } + } + // LA MACRO SHADERPATH contient le chemin du repertoire qui contient les fichiers textes std::string st(SHADERPATH); st.append(filename); @@ -684,6 +701,11 @@ void GLSLShader::bindAttrib(unsigned int att, const char* name) const } +void GLSLShader::addPathFileSeach(const std::string& path) +{ + m_pathes.push_back(path); +} + } // namespace Utils diff --git a/src/Utils/glutwin.cpp b/src/Utils/glutwin.cpp index 0aa2e9050df55ea918b22c049eae6fab553dbd36..d2c24375f0797f530d59b64781a03cffdbf313a1 100644 --- a/src/Utils/glutwin.cpp +++ b/src/Utils/glutwin.cpp @@ -69,7 +69,7 @@ SimpleGlutWin::SimpleGlutWin(int* argc, char **argv, int winX, int winY) scalefactor = 1.0f; trans_x=0.; trans_y=0.; - trans_z=-50.0f; + trans_z=-200.0f; std::cout << "Initialisation Glut" << std::endl; @@ -160,14 +160,11 @@ void SimpleGlutWin::recalcModelView(void) glPopMatrix(); glPushMatrix(); - glTranslatef(trans_x,trans_y,trans_z+foc); + glTranslatef(trans_x,trans_y,trans_z); build_rotmatrix(m, curquat); glMultMatrixf(&m[0][0]); - float sc = getScale(); - glScalef(sc,sc,sc); - newModel = 0; } @@ -215,12 +212,13 @@ void SimpleGlutWin::motion(int x, int y) { if (scaling) { - scalefactor = scalefactor * (1.0f + (((float) (beginy - y)) / H)); + trans_z -= 0.1f*(x - beginx); + trans_z -= 0.1f*(y - beginy); } else if (translating) { - trans_x += 0.01f*(x - beginx); - trans_y += 0.01f*(beginy - y); + trans_x += 0.05f*(x - beginx); + trans_y += 0.05f*(beginy - y); } beginx = x; beginy = y; diff --git a/src/Utils/glutwin_atb.cpp b/src/Utils/glutwin_atb.cpp index 22fa996c9f32fa8fbcf87bbdee78766a686aa9a7..2340c85a624ae18cceb6c0efd08f669d9b20c36f 100644 --- a/src/Utils/glutwin_atb.cpp +++ b/src/Utils/glutwin_atb.cpp @@ -65,7 +65,7 @@ GlutWin_ATB::GlutWin_ATB(int* argc, char **argv, int winX, int winY) scalefactor = 1.0f ; trans_x = 0.0f ; trans_y = 0.0f ; - trans_z = -50.0f ; + trans_z = -200.0f ; std::cout << "Initialisation Glut" << std::endl ; glutInit(argc, argv) ; @@ -155,14 +155,11 @@ void GlutWin_ATB::recalcModelView() glPopMatrix() ; glPushMatrix() ; - glTranslatef(trans_x, trans_y, trans_z+focal) ; + glTranslatef(trans_x, trans_y, trans_z) ; build_rotmatrix(m, curquat) ; glMultMatrixf(&m[0][0]) ; - float sc = getScale() ; - glScalef(sc, sc, sc) ; - newModel = 0 ; } @@ -185,14 +182,15 @@ void GlutWin_ATB::motion(int x, int y) } else if(scaling) { - scalefactor = scalefactor * (1.0f + (((float) (beginy - y)) / H)) ; + trans_z -= 0.1f*(x - beginx); + trans_z -= 0.1f*(y - beginy); newModel = 1 ; glutPostRedisplay() ; } else if(translating) { - trans_x += 0.01f * (x - beginx) ; - trans_y += 0.01f * (beginy - y) ; + trans_x += 0.05f * (x - beginx) ; + trans_y += 0.05f * (beginy - y) ; newModel = 1 ; glutPostRedisplay() ; } diff --git a/src/Utils/text3d.cpp b/src/Utils/text3d.cpp new file mode 100644 index 0000000000000000000000000000000000000000..43360f18407dbb325b08e7f2eb168e0dd94acafd --- /dev/null +++ b/src/Utils/text3d.cpp @@ -0,0 +1,221 @@ +/******************************************************************************* +* 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 "Utils/text3d.h" + +namespace CGoGN +{ +namespace Utils +{ + +Strings3D::Strings3D(): + m_nbChars(0) +{ } + +void Strings3D::init(float scale) +{ + glGenBuffersARB(1, &m_vbo1); + m_shader.loadShaders("text.vert", "text.frag"); + m_shader.bind(); + m_uniform_position = glGetUniformLocationARB(m_shader.program_handler(),"strPos"); + m_uniform_color = glGetUniformLocationARB(m_shader.program_handler(),"color"); + m_uniform_scale = glGetUniformLocationARB(m_shader.program_handler(),"scale"); + glUniform1f(m_uniform_scale, scale); + m_shader.unbind(); + + // load texture + std::string font_finename = Utils::GLSLShader::findFile("font_cgogn.png"); + ilInit(); + ilOriginFunc(IL_ORIGIN_UPPER_LEFT); + ilEnable(IL_ORIGIN_SET); + + ilGenImages(1,&m_imgName); + ilBindImage(m_imgName); + ilLoadImage(font_finename.c_str()); + + glGenTextures( 1, &m_idTexture); + glBindTexture(GL_TEXTURE_2D, m_idTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, WIDTHTEXTURE, HEIGHTTEXTURE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, (GLvoid*)(ilGetData())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + m_uniform_texture = glGetUniformLocationARB(m_shader.program_handler(),"FontTexture"); +} + + +void Strings3D::setScale(float scale) +{ + m_shader.bind(); + glUniform1f(m_uniform_scale, scale); + m_shader.unbind(); +} + +Strings3D::~Strings3D() +{ + ilDeleteImages(1,&m_imgName); + glDeleteBuffers(1, &m_vbo1); +} + +unsigned int Strings3D::addString(const std::string& str) +{ + unsigned int id=m_strings.size(); + m_strings.push_back(str); + m_nbChars += str.length(); + return id; +} + +unsigned int Strings3D::addString(const std::string& str, const Geom::Vec3f& pos) +{ + unsigned int id=m_strings.size(); + m_strings.push_back(str); + m_nbChars += str.length(); + m_strTranslate.push_back(pos); + return id; +} + +unsigned int Strings3D::sendOneStringToVBO(const std::string& str, float **buffervbo) +{ + unsigned int nbc = str.length(); + + float x=0.0f; + + float* buffer = *buffervbo; + + for(unsigned int j=0; j< nbc;++j) + { + unsigned int ci = str[j]-32; + float u = float(ci%CHARSPERLINE)/float(CHARSPERLINE); + float v = float(ci/CHARSPERLINE)/float(CHARSPERCOL)+ 1.0f/HEIGHTTEXTURE; + float u2 = u + float(REALWIDTHFONT)/float(WIDTHTEXTURE); + float v2 = v + float(WIDTHFONT-1)/float(HEIGHTTEXTURE); + + *buffer++ = x; + *buffer++ = 0; + *buffer++ = u; + *buffer++ = v2; + + float xf = x+float(REALWIDTHFONT)/25.f; + + *buffer++ = xf; + *buffer++ = 0; + *buffer++ = u2; + *buffer++ = v2; + + *buffer++ = xf; + *buffer++ = float(WIDTHFONT)/25.f; + *buffer++ = u2; + *buffer++ = v; + + *buffer++ = x; + *buffer++ = float(WIDTHFONT)/25.f; + *buffer++ = u; + *buffer++ = v; + + x = xf; // + space ? + } + + *buffervbo = buffer; + + return 4*nbc; +} + +void Strings3D::sendToVBO() +{ + // send coord / texcoord of strings + + // alloc buffer + glBindBufferARB(GL_ARRAY_BUFFER, m_vbo1); + glBufferDataARB(GL_ARRAY_BUFFER, m_nbChars*16*sizeof(float), 0, GL_STREAM_DRAW); + float* buffer = reinterpret_cast(glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE)); + + // fill buffer + unsigned int pos=0; // pos of first index in vbo for current string + unsigned int nbw = m_strings.size(); + for (unsigned int i=0; i(pos,nb)); + pos += nb; + } + + glUnmapBufferARB(GL_ARRAY_BUFFER); +} + + + +void Strings3D::predraw(const Geom::Vec3f& color) +{ + m_shader.bind(); + glUniform1iARB(m_uniform_texture,0); + + glUniform3fvARB(m_uniform_color,1,color.data()); + + glActiveTextureARB(GL_TEXTURE0_ARB); + glBindTexture(GL_TEXTURE_2D, m_idTexture); + glEnable(GL_TEXTURE_2D); + + glDisable(GL_LIGHTING); + + glBindBufferARB(GL_ARRAY_BUFFER, m_vbo1); + glVertexPointer(4, GL_FLOAT, 0, 0); + glEnableClientState(GL_VERTEX_ARRAY); +} + +void Strings3D::postdraw() +{ + glDisableClientState(GL_VERTEX_ARRAY); + glDisable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + m_shader.unbind(); +} + + +void Strings3D::draw(unsigned int idSt, const Geom::Vec3f& pos) +{ + glUniform3fv(m_uniform_position, 1, pos.data()); + glDrawArrays(GL_QUADS, m_strpos[idSt].first , m_strpos[idSt].second ); +} + + +void Strings3D::drawAll(const Geom::Vec3f& color) +{ + predraw(color); + if (m_strpos.size() != m_strTranslate.size()) + { + std::cerr << "Strings3D: for drawAll use exclusively addString with position"<< std::endl; + return; + } + + unsigned int nb = m_strpos.size(); + for (unsigned int idSt=0; idSt