Commit bac3af1b authored by Sylvain Thery's avatar Sylvain Thery

import & render of obj with tex (in texture example)

parent 2c3b7fb1
......@@ -28,18 +28,18 @@
#include "Utils/vbo.h"
TexView::TexView():
m_render(NULL),
m_obj(myMap),
m_positionVBO(NULL),
m_texcoordVBO(NULL),
m_nbIndices(0),
m_texture(NULL),
m_shader(NULL),
m_modeMask(false),
m_fileName("")
m_shader2(NULL),
m_phong(true)
{}
TexView::~TexView()
{
delete m_render;
delete m_shader;
delete m_positionVBO;
delete m_texcoordVBO;
......@@ -51,21 +51,21 @@ void TexView::cb_initGL()
// choose to use GL version 2
Utils::GLSLShader::setCurrentOGLVersion(2);
// create the render
m_render = new Algo::Render::GL2::MapRender();
// create VBO for position
m_positionVBO = new Utils::VBO;
m_texcoordVBO = new Utils::VBO;
m_normalVBO = new Utils::VBO;
m_texture = new Utils::Texture<2,Geom::Vec3uc>(GL_UNSIGNED_BYTE);
computeImage();
m_texture->update();
m_mask = new Utils::Texture<2,float>(GL_FLOAT);
m_mask->create(Geom::Vec2ui(256,256));
createMask(8);
m_mask->update();
if (m_texture->load(m_fileNameTex))
m_texture->update();
else
computeImage();
// CGoGNerr << "Problem loading image"<< CGoGNendl;
m_texture->setWrapping(GL_CLAMP_TO_EDGE);
m_texture->update();
m_shader = new Utils::ShaderSimpleTexture();
m_shader->setAttributePosition(m_positionVBO);
......@@ -74,125 +74,115 @@ void TexView::cb_initGL()
m_shader->setTexture(m_texture);
registerShader(m_shader);
m_shader2 = new Utils::ShaderTextureMask();
m_shader2 = new Utils::ShaderPhongTexture();
m_shader2->setAttributePosition(m_positionVBO);
m_shader2->setAttributeTexCoord(m_texcoordVBO);
m_shader2->setTextureUnits(GL_TEXTURE0,GL_TEXTURE1);
m_shader2->setTextures(m_texture,m_mask);
m_shader2->setAttributeNormal(m_normalVBO);
m_shader2->setTextureUnit(GL_TEXTURE1);
m_shader2->setTexture(m_texture);
m_shader2->setShininess(10.0f);
m_shader2->setAmbient(0.1f);
m_shader2->setSpecular(Geom::Vec4f(0.5));
registerShader(m_shader2);
glEnable(GL_TEXTURE_2D);
m_render->initPrimitives<PFP>(myMap, Algo::Render::GL2::TRIANGLES);
if (!m_obj.hasNormals())
{
VertexAttribute<Geom::Vec3f> normal = myMap.getAttribute<VEC3, VERTEX>("normal") ;
if(!normal.isValid())
normal = myMap.addAttribute<VEC3, VERTEX>("normal") ;
Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, m_obj.m_positions, normal) ;
m_obj.setNormalAttribute(normal);
}
m_nbIndices = m_obj.createSimpleVBO_PTN(m_positionVBO,m_texcoordVBO,m_normalVBO);
}
void TexView::cb_redraw()
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_LIGHTING);
if (m_shader)
if (m_phong)
{
if (m_modeMask)
{
m_shader2->activeTextures();
m_render->draw(m_shader2, Algo::Render::GL2::TRIANGLES);
}
else
{
m_shader->activeTexture();
m_render->draw(m_shader, Algo::Render::GL2::TRIANGLES);
}
m_shader2->activeTexture();
m_shader2->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES, 0, m_nbIndices);
m_shader2->disableVertexAttribs();
}
else
{
m_shader->activeTexture();
m_shader->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES, 0, m_nbIndices);
m_shader->disableVertexAttribs();
}
}
void TexView::cb_keyPress(int code)
{
switch(code)
{
case 'p':
m_phong = !m_phong;
case 'l':
m_texture->setFiltering(GL_LINEAR);
break;
case 'n':
m_texture->setFiltering(GL_NEAREST);
break;
case 'm':
m_modeMask = !m_modeMask;
if (m_modeMask)
{
createMask(16);
m_mask->update();
}
case '1':
m_shader2->setShininess(10.0f);
break;
case 'M':
m_modeMask = !m_modeMask;
if (m_modeMask)
{
createMask(8);
m_mask->update();
}
case '2':
m_shader2->setShininess(100.0f);
break;
case 's':
m_texture->subSample2<Geom::Vec3d>();
m_texture->update();
case '3':
m_shader2->setShininess(500.0f);
break;
case 't':
m_texture->rotate90(3);
m_texture->update();
case '4':
m_shader2->setShininess(25000.0f);
break;
case 'r':
m_texture->load(m_fileName);
m_texture->update();
case '5':
m_shader2->setShininess(1.0f);
m_shader2->setSpecular(Geom::Vec4f(0));
break;
}
updateGL();
}
void TexView::cb_Open()
void TexView::init(char *fnm, char* fnt)
{
std::string filename = selectFile("Open Image","/tmp");
if (!filename.empty())
if (fnm == NULL)
{
m_fileName = filename;
if (m_texture->load(filename))
{
m_texture->update();
updateGL();
}
else
CGoGNerr << "Problem loading image"<< CGoGNendl;
computeTore();
m_fileNameTex = std::string(fnt);
}
else
{
computeImage();
m_texture->update();
updateGL();
m_fileNameMesh = std::string(fnm);
m_fileNameTex = std::string(fnt);
std::vector<std::string> attrNames;
m_obj.import(m_fileNameMesh,attrNames);
}
}
void TexView::createMask(unsigned int nb)
{
if (nb ==0)
return;
Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, m_obj.m_positions);
float lWidthObj = std::max<PFP::REAL>(std::max<PFP::REAL>(bb.size(0), bb.size(1)), bb.size(2));
Geom::Vec3f lPosObj = (bb.min() + bb.max()) / PFP::REAL(2);
unsigned int sz0 = m_mask->size()[0]/nb;
unsigned int sz1 = m_mask->size()[1]/nb;
// send BB info to interface for centering on GL screen
setParamObject(lWidthObj, lPosObj.data());
for (unsigned int j=0; j<m_mask->size()[1]; ++j)
{
for (unsigned int i=0; i<m_mask->size()[0]; ++i)
{
bool b1 = (i/sz0)%2 ==0;
bool b2 = (j/sz1)%2 ==0;
if (b1!=b2)
(*m_mask)(i,j)=1.0f;
else
(*m_mask)(i,j)= 0.0f;
}
}
}
void TexView::computeImage()
{
std::vector<Geom::Vec3f> colorTable;
......@@ -219,23 +209,15 @@ void TexView::computeImage()
#undef WIDTHCHECKER
}
int main(int argc, char**argv)
void TexView::computeTore()
{
// interface:
QApplication app(argc, argv);
TexView tv;
PFP::MAP& m = tv.myMap;
VertexAttribute<VEC3> position = m.addAttribute<VEC3, VERTEX>("position");
VertexAttribute<Geom::Vec2f> texcoord = m.addAttribute<Geom::Vec2f, VERTEX>("texcoord");
#define NB 96
Algo::Surface::Modelisation::Polyhedron<PFP> prim(m, position);
VertexAttribute<VEC3> position = myMap.addAttribute<VEC3, VERTEX>("position");
VertexAttribute<Geom::Vec2f> texcoord = myMap.addAttribute<Geom::Vec2f, VERTEX>("texcoord");
Algo::Surface::Modelisation::Polyhedron<PFP> prim(myMap, position);
prim.tore_topo(NB, NB);
prim.embedTore(40.0f,20.0f);
Dart d = prim.getDart();
for(unsigned int i=0; i<NB; ++i)
{
......@@ -253,30 +235,42 @@ int main(int argc, char**argv)
b =(2.0f/NB)*(NB-j);
texcoord[d] = Geom::Vec2f(a,b);
d = m.phi<121>(d);
d = myMap.phi<121>(d);
}
d = m.phi<211>(d);
d = myMap.phi<211>(d);
}
#undef NB
// bounding box
Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(m, position);
float lWidthObj = std::max<PFP::REAL>(std::max<PFP::REAL>(bb.size(0), bb.size(1)), bb.size(2));
Geom::Vec3f lPosObj = (bb.min() + bb.max()) / PFP::REAL(2);
m_obj.setPositionAttribute(position);
m_obj.setTexCoordAttribute(texcoord);
}
// envoit info BB a l'interface
tv.setParamObject(lWidthObj, lPosObj.data());
// show 1 pour GL context
tv.show();
// update des VBO (position et texture coord)
tv.m_positionVBO->updateData(position);
tv.m_texcoordVBO->updateData(texcoord);
// show final pour premier redraw
int main(int argc, char**argv)
{
// interface:
QApplication app(argc, argv);
TexView tv;
if (argc == 3)
{
tv.init(argv[1], argv[2]);
}
else if (argc == 2)
{
tv.init(NULL, argv[1]);
}
else
{
tv.init(NULL,"x");
}
tv.show();
// et on attend la fin.
return app.exec();
}
......@@ -30,17 +30,17 @@
#include "Utils/Qt/qtSimple.h"
#include "Utils/textures.h"
#include "Utils/Shaders/shaderSimpleTexture.h"
#include "Utils/Shaders/shaderTextureMask.h"
#include "Utils/Shaders/shaderPhongTexture.h"
#include "Topology/generic/parameters.h"
#include "Topology/map/embeddedMap2.h"
#include "Algo/Render/GL2/mapRender.h"
#include "Algo/Import/importObjTex.h"
// forward definitions (minimize includes)
namespace CGoGN { namespace Algo { namespace Render { namespace GL2 { class MapRender; }}}}
namespace CGoGN { namespace Utils { class VBO; } }
using namespace CGoGN ;
struct PFP: public PFP_STANDARD
......@@ -59,36 +59,38 @@ class TexView: public Utils::QT::SimpleQT
{
Q_OBJECT
protected:
void createMask(unsigned int nb);
void computeImage();
void computeTore();
public:
MAP myMap ;
// render
Algo::Render::GL2::MapRender* m_render;
Algo::Surface::Import::OBJModel<PFP> m_obj;
// VBO
Utils::VBO* m_positionVBO;
Utils::VBO* m_texcoordVBO;
Utils::VBO* m_normalVBO;
unsigned int m_nbIndices;
Utils::Texture<2,Geom::Vec3uc>* m_texture;
Utils::Texture<2,float>* m_mask;
//2 shaders
// shader simple texture
Utils::ShaderSimpleTexture* m_shader;
Utils::ShaderTextureMask* m_shader2;
Utils::ShaderPhongTexture* m_shader2;
//with mask or not
bool m_modeMask;
bool m_phong;
/// filename of last loaded texture
std::string m_fileName;
/// filename of loaded mesh
std::string m_fileNameMesh;
/// filename of loaded texture
std::string m_fileNameTex;
TexView();
~TexView();
void init(char* fnm, char* fnt);
// callbacks of simpleQT to overdefine:
void cb_redraw();
......@@ -96,7 +98,6 @@ public:
void cb_keyPress(int code);
void cb_Open();
};
#endif
......@@ -70,6 +70,12 @@ protected:
/// read face line with different indices v v/t v//n v/t/n
short readObjLine(std::stringstream& oss, std::vector<unsigned int>& indices);
unsigned int m_tagV ;
unsigned int m_tagVT ;
unsigned int m_tagVN ;
unsigned int m_tagG ;
unsigned int m_tagF ;
public:
/// marker for special vertices (with several normals & tex coords)
......@@ -97,6 +103,31 @@ public:
*/
OBJModel(typename PFP::MAP& map);
/**
* @brief set position attribute
* @param position attribute
*/
void setPositionAttribute(VertexAttribute<Geom::Vec3f> position);
/**
* @brief set position attribute
* @param position attribute
*/
void setNormalAttribute(VertexAttribute<Geom::Vec3f> normal);
/**
* @brief set texture coordinate attribute
* @param texcoord attribute
*/
void setTexCoordAttribute(VertexAttribute<Geom::Vec2f>texcoord);
bool hasTexCoords() const { return m_tagVT!=0; }
bool hasNormals() const { return m_tagVN!=0; }
bool hasGroups() const { return m_tagG!=0; }
/**
* @brief import
* @param filename
......
......@@ -38,7 +38,9 @@ namespace Import
template <typename PFP>
OBJModel<PFP>::OBJModel(typename PFP::MAP& map):
m_map(map),m_specialVertices(map),m_dirtyEdges(map)
m_map(map),
m_tagV(0),m_tagVT(0),m_tagVN(0),m_tagG(0),m_tagF(0),
m_specialVertices(map),m_dirtyEdges(map)
{
}
......@@ -73,6 +75,25 @@ std::vector<std::string>& OBJModel<PFP>::getMaterialNames()
return m_materialNames;
}
template <typename PFP>
void OBJModel<PFP>::setPositionAttribute(VertexAttribute<Geom::Vec3f> position)
{
m_positions = position;
}
template <typename PFP>
void OBJModel<PFP>::setNormalAttribute(VertexAttribute<Geom::Vec3f> normal)
{
m_normals = normal;
}
template <typename PFP>
void OBJModel<PFP>::setTexCoordAttribute(VertexAttribute<Geom::Vec2f>texcoord)
{
m_texCoords = texcoord;
}
template <typename PFP>
......@@ -337,10 +358,22 @@ unsigned int OBJModel<PFP>::createSimpleVBO_PT(Utils::VBO* positionVBO, Utils::V
template <typename PFP>
unsigned int OBJModel<PFP>::createSimpleVBO_PTN(Utils::VBO* positionVBO, Utils::VBO* texcoordVBO, Utils::VBO* normalVBO )
{
if (!m_normals.isValid())
{
CGoGNerr << "no normal attribute "<< CGoGNendl;
return 0;
}
if (!m_texCoords.isValid())
{
CGoGNerr << "no tex coords attribute "<< CGoGNendl;
return 0;
}
TraversorF<typename PFP::MAP> traf(m_map);
std::vector<Geom::Vec3f> posBuff;
std::vector<Geom::Vec2f> TCBuff;
std::vector<Geom::Vec2f> normalBuff;
std::vector<Geom::Vec3f> normalBuff;
posBuff.reserve(16384);
TCBuff.reserve(16384);
normalBuff.reserve(16384);
......@@ -355,8 +388,14 @@ unsigned int OBJModel<PFP>::createSimpleVBO_PTN(Utils::VBO* positionVBO, Utils::
posBuff.push_back(m_positions[d]);
if (m_specialVertices.isMarked(d))
{
TCBuff.push_back(m_texCoordsF[d]);
normalBuff.push_back(m_normalsF[d]);
if (hasTexCoords())
TCBuff.push_back(m_texCoordsF[d]);
else
TCBuff.push_back(m_texCoords[d]);
if (hasNormals())
normalBuff.push_back(m_normalsF[d]);
else
normalBuff.push_back(m_normals[d]);
}
else
{
......@@ -367,8 +406,14 @@ unsigned int OBJModel<PFP>::createSimpleVBO_PTN(Utils::VBO* positionVBO, Utils::
posBuff.push_back(m_positions[e]);
if (m_specialVertices.isMarked(e))
{
TCBuff.push_back(m_texCoordsF[e]);
normalBuff.push_back(m_normalsF[e]);
if (hasTexCoords())
TCBuff.push_back(m_texCoordsF[e]);
else
TCBuff.push_back(m_texCoords[e]);
if (hasNormals())
normalBuff.push_back(m_normalsF[e]);
else
normalBuff.push_back(m_normals[e]);
}
else
{
......@@ -379,8 +424,14 @@ unsigned int OBJModel<PFP>::createSimpleVBO_PTN(Utils::VBO* positionVBO, Utils::
posBuff.push_back(m_positions[f]);
if (m_specialVertices.isMarked(f))
{
TCBuff.push_back(m_texCoordsF[f]);
normalBuff.push_back(m_normalsF[f]);
if (hasTexCoords())
TCBuff.push_back(m_texCoordsF[f]);
else
TCBuff.push_back(m_texCoords[f]);
if (hasNormals())
normalBuff.push_back(m_normalsF[f]);
else
normalBuff.push_back(m_normals[f]);
}
else
{
......@@ -504,12 +555,6 @@ bool OBJModel<PFP>::import( const std::string& filename, std::vector<std::string
return false;
}
unsigned int tagV = 0;
unsigned int tagVT = 0;
unsigned int tagVN = 0;
unsigned int tagG = 0;
unsigned int tagF = 0;
std::string ligne;
std::string tag;
do
......@@ -517,23 +562,23 @@ bool OBJModel<PFP>::import( const std::string& filename, std::vector<std::string
fp >> tag;
std::getline (fp, ligne);
if (tag == "v")
tagV++;
m_tagV++;
if (tag == "vn")
tagVN++;
m_tagVN++;
if (tag == "vt")
tagVT++;
m_tagVT++;
if (tag == "g")
tagG++;
m_tagG++;
if (tag == "f")
tagF++;
m_tagF++;
}while (!fp.eof());
std::cout << "Parsing OBJ"<< tagV<< std::endl;
std::cout << "Vertices:"<< tagV<< std::endl;
std::cout << "Normals:"<< tagVN<< std::endl;
std::cout << "TexCoords:"<< tagVT<< std::endl;
std::cout << "Groups:"<< tagG<< std::endl;
std::cout << "Faces:"<< tagF<< std::endl;
std::cout << "Parsing OBJ"<< m_tagV<< std::endl;
std::cout << "Vertices:"<< m_tagV<< std::endl;
std::cout << "Normals:"<< m_tagVN<< std::endl;
std::cout << "TexCoords:"<< m_tagVT<< std::endl;
std::cout << "Groups:"<< m_tagG<< std::endl;
std::cout << "Faces:"<< m_tagF<< std::endl;
m_positions = m_map.template getAttribute<typename PFP::VEC3, VERTEX>("position") ;
......@@ -541,7 +586,7 @@ bool OBJModel<PFP>::import( const std::string& filename, std::vector<std::string
m_positions = m_map.template addAttribute<VEC3, VERTEX>("position") ;
attrNames.push_back(m_positions.name()) ;
if (tagVT != 0)
if (m_tagVT != 0)
{
m_texCoords = m_map.template getAttribute<VEC2, VERTEX>("texCoord") ;
if (!m_texCoords.isValid())
......@@ -553,7 +598,7 @@ bool OBJModel<PFP>::import( const std::string& filename, std::vector<std::string
m_texCoordsF = m_map.template addAttribute<VEC2, VERTEX1>("texCoordF") ;
}
if (tagVN != 0)
if (m_tagVN != 0)
{
m_normals = m_map.template getAttribute<typename PFP::VEC3, VERTEX>("normal") ;
if (!m_normals.isValid())
......@@ -566,7 +611,7 @@ bool OBJModel<PFP>::import( const std::string& filename, std::vector<std::string
}
if (tagG != 0)
if (m_tagG != 0)
{
m_groups = m_map.template getAttribute<unsigned int, FACE>("groups") ;
if (!m_groups.isValid())
......@@ -582,18 +627,18 @@ bool OBJModel<PFP>::import( const std::string& filename, std::vector<std::string
fp.open(filename.c_str());
std::vector<VEC3> normalsBuffer;
normalsBuffer.reserve(tagVN);
normalsBuffer.reserve(m_tagVN);
std::vector<VEC2> texCoordsBuffer;
texCoordsBuffer.reserve(tagVT);
texCoordsBuffer.reserve(m_tagVT);
std::vector<unsigned int> verticesID;
verticesID.reserve(tagV);
verticesID.reserve(m_tagV);
std::vector<unsigned int> normalsID;
normalsID.reserve(tagV);
normalsID.reserve(m_tagV);
std::vector<unsigned int> texCoordsID;
texCoordsID.reserve(tagV);
texCoordsID.reserve(m_tagV);
......@@ -672,7 +717,7 @@ bool OBJModel<PFP>::import( const std::string& filename, std::vector<std::string
short nbe = readObjLine(oss,localIndices);
Dart d = m_map.newFace(nbe, false);
if (tagG!=0)
if (m_tagG!=0)
m_groups[d] = currentGroup;
for (short j = 0; j < nbe; ++j)
......@@ -748,9 +793,9 @@ bool OBJModel<PFP>::import( const std::string& filename, std::vector<std::string
for (unsigned int j=0; j<nb; ++j)
{
Dart e = vec[j];
if (tagVT)
if (m_tagVT)
m_texCoordsF[e] = texCoordsBuffer[ vecTCIndPerVertex[e][j] ];
if (tagVN)
if (m_tagVN)
m_normalsF[e] = normalsBuffer[ vecNormIndPerVertex[e][j] ];
}
m_specialVertices.mark(d);
......
// ShaderPhongTexture::fragmentShaderText
PRECISON;
VARYING_FRAG vec3 EyeVector, Normal, LightDir;
VARYING_FRAG vec2 texCoord;
uniform vec4 materialDiffuse;
uniform vec4 materialSpecular;
uniform float ambientCoef;
uniform float shininess;
uniform sampler2D textureUnit;
FRAG_OUT_DEF;
void main()
{
vec3 N = normalize (Normal);
vec3 L = normalize (LightDir);
float lambertTerm = dot(N,L);
vec4 finalColor = ambientCoef * texture2D(textureUnit,texCoord);
#ifdef DOUBLE_SIDED
if (lambertTerm < 0.0)
{
N = -1.0*N;
lambertTerm = -1.0*lambertTerm;
#else
if (lambertTerm > 0.0)
{
#endif
vec3 E = normalize(EyeVector);
vec3 R = reflect(-L, N);
float specular = pow( max(dot(R, E), 0.0), shininess );
vec3 diffuse = (1.0 - ambientCoef) * texture2D(textureUnit,texCoord).rgb;
finalColor += vec4(diffuse*lambertTerm,0.0) + materialSpecular*specular;
}
gl_FragColor=finalColor;
}
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, 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 *