Commit fea7090e authored by Pierre Kraemer's avatar Pierre Kraemer
Browse files

Merge branch 'develop' into 'develop'

add missing files for polynomial radiance per vertex rendering



See merge request !79
parents 4a11dd11 6d4cf546
// ShaderRadiancePerVertex_P::fragmentShaderText
PRECISION;
VARYING_FRAG vec3 vxColor;
FRAG_OUT_DEF;
void main (void)
{
FRAG_OUT = vec4(vxColor,1.0) ;
}
/*******************************************************************************
* 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 *
* 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.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __CGOGN_SHADER_RADIANCEPERVERTEX_P__
#define __CGOGN_SHADER_RADIANCEPERVERTEX_P__
#include "Utils/GLSLShader.h"
#include "Utils/clippingShader.h"
#include "Utils/textures.h"
#include "Geometry/vector_gen.h"
#include "Utils/dll.h"
namespace CGoGN
{
namespace Utils
{
class CGoGN_UTILS_API ShaderRadiancePerVertex_P : public ClippingShader
{
protected:
// shader sources
static std::string vertexShaderText;
static std::string geometryShaderText;
static std::string fragmentShaderText;
CGoGNGLuint m_uniform_tex;
CGoGNGLuint m_uniform_cam;
VBO* m_vboPos;
VBO* m_vboTang;
VBO* m_vboNorm;
VBO* m_vboBiNorm;
VBO* m_vboParam;
Utils::Texture<2, Geom::Vec3f>* m_tex_ptr;
unsigned int m_tex_unit;
Geom::Vec3f m_camera;
static int index (int l, int m) { return l*(l+1)+m; } // compute indices in K_tab
public:
ShaderRadiancePerVertex_P();
~ShaderRadiancePerVertex_P();
void compile();
void setCamera(const Geom::Vec3f& camera);
unsigned int setAttributePosition(VBO* vbo);
unsigned int setAttributeTangent(VBO* vbo);
unsigned int setAttributeNormal(VBO* vbo);
unsigned int setAttributeBiNormal(VBO* vbo);
unsigned int setAttributeRadiance(VBO* vbo, Utils::Texture<2, Geom::Vec3f>* texture, GLenum texunit = GL_TEXTURE0);
};
} // namespace Utils
} // namespace CGoGN
#endif
// ShaderRadiancePerVertex_P::vertexShaderText
ATTRIBUTE vec3 VertexPosition;
ATTRIBUTE vec3 VertexTangent;
ATTRIBUTE vec3 VertexNormal;
ATTRIBUTE vec3 VertexBiNormal;
ATTRIBUTE ivec2 VertexParam;
uniform mat4 ModelViewProjectionMatrix ;
uniform sampler2D texture;
uniform vec3 camera;
VARYING_VERT vec3 vxColor;
INVARIANT_POS;
float evaluate(float u, float v, int i)
{
switch(i)
{
case 0 :
return 1;
case 1 :
return u;
case 2 :
return v;
case 3 :
return u*u;
case 4 :
return u*v;
case 5 :
return v*v;
case 6 :
return u*u*u;
case 7 :
return u*u*v;
case 8 :
return u*v*v;
case 9 :
return v*v*v;
case 10 :
return u*u*u*u;
case 11 :
return u*u*u*v;
case 12 :
return u*u*v*v;
case 13 :
return u*v*v*v;
case 14 :
return v*v*v*v;
default:
return 0;
}
}
void main ()
{
int size = (textureSize(texture,0)).x; // supposed square matrix
vec3 eyeV = normalize(camera - VertexPosition); // normalized outgoing line-of-sight vector
// eyeV = 2*dot(VertexNormal,eyeV)*VertexNormal-eyeV ; // symmetrize
vec2 uv = -1. * vec2(dot(eyeV,VertexTangent), dot(eyeV,VertexBiNormal));
if (dot(eyeV,VertexNormal) < 0.)
{
uv = normalize(uv);
}
vxColor = vec3(0.,0.,0.) ;
// evaluate function
ivec2 param = VertexParam ;
for(int l=0; l<15; l++)
{
// compute texture index
if (param.y >= size) // if texture newline
{
param.y -= size ;
param.x += 1 ;
}
// get corresponding coef
vec3 coefLM = (texelFetch(texture,param,0)).rgb;
// multiply by basis function
vxColor += coefLM * evaluate(uv.x, uv.y, l);
param.y ++ ;
}
// vxColor = eyeV ; // Debug camera position
// vxColor = VertexNormal ; // Debug normals
// vxColor = (VertexPosition+vec3(1.,1.,1.))/2.0 ; // Debug positions
gl_Position = ModelViewProjectionMatrix * vec4 (VertexPosition, 1.0);
}
/*******************************************************************************
* 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 *
* 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.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#define CGoGN_UTILS_DLL_EXPORT 1
#include "Utils/Shaders/shaderRadiancePerVertex_P.h"
namespace CGoGN
{
namespace Utils
{
#include "shaderRadiancePerVertex_P.vert"
#include "shaderRadiancePerVertex_P.frag"
ShaderRadiancePerVertex_P::ShaderRadiancePerVertex_P() :
m_vboPos(NULL),
m_vboTang(NULL),
m_vboNorm(NULL),
m_vboBiNorm(NULL),
m_vboParam(NULL),
m_tex_ptr(NULL),
m_tex_unit(-1)
{
compile();
}
ShaderRadiancePerVertex_P::~ShaderRadiancePerVertex_P()
{
}
void ShaderRadiancePerVertex_P::compile()
{
m_nameVS = "ShaderRadiancePerVertex_P_vs";
m_nameFS = "ShaderRadiancePerVertex_P_fs";
m_nameGS = "ShaderRadiancePerVertex_P_gs";
const int nb_coefs = 15;
std::stringstream s ;
s << "#define NB_COEFS " << nb_coefs << std::endl ;
std::string glxvert(GLSLShader::defines_gl());
glxvert.append(s.str()) ;
glxvert.append(vertexShaderText);
std::string glxfrag(GLSLShader::defines_gl());
glxfrag.append(fragmentShaderText) ;
loadShadersFromMemory(glxvert.c_str(), glxfrag.c_str());
bind();
*m_uniform_cam = glGetUniformLocation(this->program_handler(), "camera");
*m_uniform_tex = glGetUniformLocation(this->program_handler(), "texture");
unbind();
}
void ShaderRadiancePerVertex_P::setCamera(const Geom::Vec3f& camera)
{
m_camera = camera;
bind();
glUniform3fv(*m_uniform_cam, 1, m_camera.data()) ;
unbind();
}
unsigned int ShaderRadiancePerVertex_P::setAttributePosition(VBO* vbo)
{
m_vboPos = vbo;
bind();
unsigned int id = bindVA_VBO("VertexPosition", vbo);
unbind();
return id;
}
unsigned int ShaderRadiancePerVertex_P::setAttributeTangent(VBO* vbo)
{
m_vboTang = vbo;
bind();
unsigned int id = bindVA_VBO("VertexTangent", vbo);
unbind();
return id;
}
unsigned int ShaderRadiancePerVertex_P::setAttributeNormal(VBO* vbo)
{
m_vboNorm = vbo;
bind();
unsigned int id = bindVA_VBO("VertexNormal", vbo);
unbind();
return id;
}
unsigned int ShaderRadiancePerVertex_P::setAttributeBiNormal(VBO* vbo)
{
m_vboBiNorm = vbo;
bind();
unsigned int id = bindVA_VBO("VertexBiNormal", vbo);
unbind();
return id;
}
unsigned int ShaderRadiancePerVertex_P::setAttributeRadiance(VBO* vbo, Utils::Texture<2, Geom::Vec3f>* texture, GLenum tex_unit)
{
m_vboParam = vbo;
m_tex_ptr = texture;
m_tex_unit = tex_unit - GL_TEXTURE0;
bind();
unsigned int id = bindVA_VBO("VertexParam", vbo);
glUniform1iARB(*m_uniform_tex, m_tex_unit);
glActiveTexture(tex_unit);
if (m_tex_ptr)
m_tex_ptr->bind() ;
unbind();
return id;
}
} // namespace Utils
} // namespace CGoGN
#ifndef _MESHTABLESURFACE_RADIANCE_P_H_
#define _MESHTABLESURFACE_RADIANCE_P_H_
#include "Algo/Import/import.h"
#include "Algo/Import/import2tables.h"
namespace CGoGN
{
namespace SCHNApps
{
class MeshTablesSurface_Radiance_P : public CGoGN::Algo::Surface::Import::MeshTablesSurface<PFP2>
{
public:
MeshTablesSurface_Radiance_P(MAP& m) : MeshTablesSurface<PFP2>(m)
{}
/**
* @brief importPLY
* @param filename: the ply file to be imported. This file is supposed to have a three position, nine frame and at least three radiance scalars per vertex.
* @return succeeded
*/
template <typename P_TYPE>
bool importPLY(const std::string& filename);
private:
/**
* \brief reads the list of vertices in a radiance PLY file. The function is template of the type of arithmetic (float, double) used in the file to be read
* \param fp IN: the file pointer descriptor
* \param binary IN: binary mode for reading fp
* \param nbVertices IN: the number of vertices to read
* \param nbProps IN: the number of properties according to the header
* \param positions IN/OUT: the positions container
* \param normals IN/OUT: the normals container
* \param radiances IN/OUT: the radiances container
* \param verticesID IN/OUT: the vector of vertex IDs
* \return number of vertices readVerticesPLY
*/
template <typename REAL, typename P_TYPE>
unsigned int readVerticesPLY(
std::ifstream& fp, bool binary,
const unsigned int& nbVertices, const unsigned int& nbProps, const unsigned int& propSize,
VertexAttribute<PFP2::VEC3, PFP2::MAP>& positions,
VertexAttribute<PFP2::VEC3, PFP2::MAP>& tangents,
VertexAttribute<PFP2::VEC3, PFP2::MAP>& normals,
VertexAttribute<PFP2::VEC3, PFP2::MAP>& binormals,
VertexAttribute<P_TYPE, PFP2::MAP>& radiances,
std::vector<unsigned int>& verticesID
);
};
} // namespace SCHNApps
} // namespace CGoGN
#include "meshTableSurfaceRadiance_P.hpp"
#endif
namespace CGoGN
{
namespace SCHNApps
{
template <typename P_TYPE>
bool MeshTablesSurface_Radiance_P::importPLY(const std::string& filename)
{
// Open file
std::ifstream fp(filename, std::ios::in | std::ios::binary) ;
if (!fp.good())
{
CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
return false ;
}
// Read quantities : #vertices, #faces, #properties, degree of polynomials
std::string tag ;
fp >> tag;
if (tag != std::string("ply")) // verify file type
{
CGoGNerr << filename << " is not a ply file !" << CGoGNout ;
return false ;
}
do // go to "format"
{
fp >> tag ;
} while (tag != std::string("format")) ;
fp >> tag ;
bool binary = (tag != "ascii") ;
do // go to #vertices
{
fp >> tag ;
} while (tag != std::string("vertex")) ;
unsigned int nbVertices ;
fp >> nbVertices ; // Read #vertices
bool position = false ;
bool frame = false ;
bool radiance = false ;
unsigned int propSize = 0 ; // for binary read
unsigned int nbProps = 0 ; // # properties
unsigned int nbCoefs = 0 ; // # coefficients
do // go to #faces and count #properties
{
fp >> tag ;
if (tag == std::string("property"))
{
++nbProps ;
}
else if (tag == std::string("int8") || tag == std::string("uint8"))
{
if (propSize < 2)
{
propSize = 1 ;
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
else
{
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
}
else if (tag == std::string("int16") || tag == std::string("uint16"))
{
if (propSize == 0 || propSize == 2)
{
propSize = 2 ;
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
else
{
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
}
else if (tag == std::string("int32") || tag == std::string("float32") || tag == std::string("uint32"))
{
if (propSize == 0 || propSize == 4)
{
propSize = 4 ;
}
else
{
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
}
else if (tag == std::string("int64") || tag == std::string("float64"))
{
if (propSize == 0 || propSize == 8)
{
propSize = 8 ;
}
else
{
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
}
else if (tag == std::string("x"))
position = true ;
else if (tag == std::string("frameT_0"))
frame = true ;
else if (tag.substr(0,6) == std::string("PBcoef"))
{
radiance = true ;
++nbCoefs ;
}
} while (tag != std::string("face")) ;
assert((nbCoefs % 3) == 0 || !"Import only supports RGB Polynomials (i.e. Tcoef==VEC3)") ;
nbCoefs /= 3 ;
assert(nbCoefs == 15 || !"Import only supports bi-degree 4 polynomials");
fp >> this->m_nbFaces ; // Read #vertices
do // go to end of header
{
fp >> tag ;
} while (tag != std::string("end_header")) ;
if (binary)
{
char* endline = new char[1] ;
fp.read(endline, sizeof(char)) ;
if (*endline == '\r') // for windows
fp.read(endline, sizeof(char)) ;
assert(*endline == '\n') ;
delete[] endline ;
}
// Define containers
assert((position && frame && radiance) || !"Import: position, normal and radiance attributes should be provided") ;
if (!(position && frame && radiance))
return false ;
VertexAttribute<VEC3, MAP> positions = this->m_map.template checkAttribute<VEC3, VERTEX, MAP>("position") ;
VertexAttribute<VEC3, MAP> tangents = this->m_map.template checkAttribute<VEC3, VERTEX, MAP>("tangent") ;
VertexAttribute<VEC3, MAP> normals = this->m_map.template checkAttribute<VEC3, VERTEX, MAP>("normal") ;
VertexAttribute<VEC3, MAP> binormals = this->m_map.template checkAttribute<VEC3, VERTEX, MAP>("binormal") ;
VertexAttribute<P_TYPE, MAP> radiances = this->m_map.template checkAttribute<P_TYPE, VERTEX, MAP>("radiance") ;
// Read vertices
std::vector<unsigned int> verticesID ;
if (propSize == 4)
{
this->m_nbVertices = readVerticesPLY<float, P_TYPE>(fp, binary, nbVertices, nbProps, propSize, positions, tangents, normals, binormals, radiances, verticesID) ;
}
else if (propSize == 8)
{
this->m_nbVertices = readVerticesPLY<double, P_TYPE>(fp, binary, nbVertices, nbProps, propSize, positions, tangents, normals, binormals, radiances, verticesID) ;
}
// Read faces index
this->m_nbEdges.reserve(this->m_nbFaces) ;
this->m_emb.reserve(3 * this->m_nbFaces) ;
for (unsigned int i = 0 ; i < this->m_nbFaces ; ++i)
{
// read the indices of vertices for current face
unsigned int nbEdgesForFace ;
if (binary)
{
unsigned char tmp ;
fp.read((char*)&(tmp), sizeof(unsigned char)) ;
nbEdgesForFace = tmp ;
}
else
fp >> nbEdgesForFace ;
this->m_nbEdges.push_back(nbEdgesForFace);
unsigned int vertexID ;
if (binary)
{
for (unsigned int j=0 ; j < nbEdgesForFace ; ++j)
{
fp.read((char*)&vertexID, sizeof(unsigned int)) ;
this->m_emb.push_back(verticesID[vertexID]);
}
}
else
{
for (unsigned int j=0 ; j < nbEdgesForFace ; ++j)
{
fp >> vertexID ;
this->m_emb.push_back(verticesID[vertexID]);
}
}
}