update basic viewer to allow to draw mono and color faces

This commit is contained in:
Guillaume Damiand 2017-11-14 19:12:10 +01:00
parent 877e8783f5
commit f0a44e2483
1 changed files with 333 additions and 302 deletions

View File

@ -67,7 +67,7 @@ const char vertex_source_mono[] =
"}" "}"
}; };
const char vertex_source_multi[] = const char vertex_source_color[] =
{ {
"#version 120 \n" "#version 120 \n"
"attribute highp vec4 vertex;\n" "attribute highp vec4 vertex;\n"
@ -120,7 +120,7 @@ const char fragment_source_mono[] =
"\n" "\n"
}; };
const char fragment_source_multi[] = const char fragment_source_color[] =
{ {
"#version 120 \n" "#version 120 \n"
"varying highp vec4 fP; \n" "varying highp vec4 fP; \n"
@ -237,6 +237,7 @@ public:
m_flatShading(true), m_flatShading(true),
m_use_mono_color(false), m_use_mono_color(false),
m_inverse_normal(false), m_inverse_normal(false),
m_empty(true),
m_size_points(7.), m_size_points(7.),
m_size_edges(3.1), m_size_edges(3.1),
m_vertices_mono_color(51, 51, 178), m_vertices_mono_color(51, 51, 178),
@ -271,53 +272,63 @@ public:
void clear() void clear()
{ {
pos_points.clear(); for (unsigned int i=0; i<LAST_INDEX; ++i)
pos_segments.clear(); { arrays[i].clear(); }
pos_faces.clear();
smooth_normals.clear();
flat_normals.clear();
colors.clear();
} }
bool is_empty() bool is_empty() const
{ return pos_points.empty() && pos_segments.empty() && pos_faces.empty(); } { return m_empty; }
void add_point(const Local_point& p) void add_point(const Local_point& p, std::vector<float>& point_vector)
{ {
pos_points.push_back(p.x()); point_vector.push_back(p.x());
pos_points.push_back(p.y()); point_vector.push_back(p.y());
pos_points.push_back(p.z()); point_vector.push_back(p.z());
if (is_empty()) if (is_empty())
{ bb=p.bbox(); } { bb=p.bbox(); m_empty=false; }
else else
{ bb=bb+p.bbox(); } { bb=bb+p.bbox(); }
} }
void add_segment(const Local_point& p1, const Local_point& p2) void add_color(const CGAL::Color& acolor, std::vector<float>& color_vector)
{ {
pos_segments.push_back(p1.x()); color_vector.push_back((double)color_of_face.red()/(double)255);
pos_segments.push_back(p1.y()); color_vector.push_back((double)color_of_face.green()/(double)255);
pos_segments.push_back(p1.z()); color_vector.push_back((double)color_of_face.blue()/(double)255);
pos_segments.push_back(p2.x());
pos_segments.push_back(p2.y());
pos_segments.push_back(p2.z());
if (is_empty())
{ bb=p1.bbox(); }
else
{ bb=bb+p1.bbox(); }
bb=bb+p2.bbox();
} }
/// Start a new face. Its color will be the m_faces_mono_color. void add_normal(const Local_vector& n, std::vector<float>& normal_vector)
void face_begin() {
{ face_begin(m_faces_mono_color); } normal_vector.push_back(n.x());
normal_vector.push_back(n.y());
normal_vector.push_back(n.z());
}
void add_mono_point(const Local_point& p)
{ add_point(p, arrays[POS_MONO_POINTS]); }
/// Start a new face, with a given color. void add_colored_point(const Local_point& p, const CGAL::Color& acolor)
void face_begin(const CGAL::Color& acolor) {
add_point(p, arrays[POS_COLORED_POINTS]);
add_color(acolor, arrays[COLOR_POINTS]);
}
void add_mono_segment(const Local_point& p1, const Local_point& p2)
{
add_point(p1, arrays[POS_MONO_SEGMENTS]);
add_point(p2, arrays[POS_MONO_SEGMENTS]);
}
void add_colored_segment(const Local_point& p1, const Local_point& p2,
const CGAL::Color& acolor)
{
add_point(p1, arrays[POS_COLORED_SEGMENTS]);
add_point(p2, arrays[POS_COLORED_SEGMENTS]);
add_color(acolor, arrays[COLOR_SEGMENTS]);
}
void face_begin()
{ {
if (m_face_started) if (m_face_started)
{ {
@ -325,10 +336,23 @@ public:
return; return;
} }
color_of_face=acolor;
m_face_started=true; m_face_started=true;
} }
void mono_face_begin()
{
m_started_face_is_colored=false;
face_begin();
}
/// Start a new face, with a given color.
void colored_face_begin(const CGAL::Color& acolor)
{
color_of_face=acolor;
m_started_face_is_colored=true;
face_begin();
}
/// Add a point at the end of the current face /// Add a point at the end of the current face
/// With this method, it is not possible to use the Gourod shading. /// With this method, it is not possible to use the Gourod shading.
/// @param p the point to add /// @param p the point to add
@ -339,12 +363,6 @@ public:
if (points_of_face.empty() || points_of_face.back()!=p) if (points_of_face.empty() || points_of_face.back()!=p)
{ {
points_of_face.push_back(p); points_of_face.push_back(p);
if (is_empty())
{ bb=p.bbox(); }
else
{ bb=bb+p.bbox(); }
return true; return true;
} }
return false; return false;
@ -380,43 +398,42 @@ public:
Local_vector normal=compute_normal_of_face<Local_kernel>(points_of_face); Local_vector normal=compute_normal_of_face<Local_kernel>(points_of_face);
double r=(double)color_of_face.red()/(double)255;
double g=(double)color_of_face.green()/(double)255;
double b=(double)color_of_face.blue()/(double)255;
if (points_of_face.size()==3) // Triangle: no need to triangulate if (points_of_face.size()==3) // Triangle: no need to triangulate
{ {
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
{ {
// The point // The point
pos_faces.push_back(points_of_face[i].x()); add_point(points_of_face[i], arrays[m_started_face_is_colored?
pos_faces.push_back(points_of_face[i].y()); POS_COLORED_FACES:
pos_faces.push_back(points_of_face[i].z()); POS_MONO_FACES]);
// Its color // Its color
colors.push_back(r); colors.push_back(g); colors.push_back(b); if (m_started_face_is_colored)
{ add_color(color_of_face, arrays[COLOR_FACES]); }
// Its flat normal // Its flat normal
flat_normals.push_back(normal.x()); add_normal(normal, arrays[m_started_face_is_colored?
flat_normals.push_back(normal.y()); FLAT_NORMAL_COLORED_FACES:
flat_normals.push_back(normal.z()); FLAT_NORMAL_MONO_FACES]);
// Its smoth normal (if given by the user) // Its smoth normal (if given by the user)
if (vertex_normals_for_face.size()==3) if (vertex_normals_for_face.size()==3)
{ // Here we have 3 vertex normals; we can use Gourod { // Here we have 3 vertex normals; we can use Gourod
smooth_normals.push_back(vertex_normals_for_face[i].x()); add_normal(vertex_normals_for_face[i], arrays[m_started_face_is_colored?
smooth_normals.push_back(vertex_normals_for_face[i].y()); SMOOTH_NORMAL_COLORED_FACES:
smooth_normals.push_back(vertex_normals_for_face[i].z()); SMOOTH_NORMAL_MONO_FACES]);
} }
else else
{ // Here user does not provide all vertex normals: we use face normal istead { // Here user does not provide all vertex normals: we use face normal istead
// and thus we will not be able to use Gourod // and thus we will not be able to use Gourod
smooth_normals.push_back(normal.x()); add_normal(normal, arrays[m_started_face_is_colored?
smooth_normals.push_back(normal.y()); SMOOTH_NORMAL_COLORED_FACES:
smooth_normals.push_back(normal.z()); SMOOTH_NORMAL_MONO_FACES]);
} }
} }
} }
// TODO CASE OF 4 POINTS ? PB HOW TO FIND (EASILY) THE TWO POINTS TO LINK ?
// else if (points_of_face.size()==4)
else else
{ // More than 3 points: we triangulate { // More than 3 points: we triangulate
try try
@ -514,22 +531,23 @@ public:
for(int i=0; i<3; ++i) for(int i=0; i<3; ++i)
{ {
// The point // The point
pos_faces.push_back(ffit->vertex(i)->point().x()); add_point(ffit->vertex(i)->point(), arrays[m_started_face_is_colored?
pos_faces.push_back(ffit->vertex(i)->point().y()); POS_COLORED_FACES:
pos_faces.push_back(ffit->vertex(i)->point().z()); POS_MONO_FACES]);
// Its color // Its color
colors.push_back(r);colors.push_back(g);colors.push_back(b); if (m_started_face_is_colored)
{ add_color(color_of_face, arrays[COLOR_FACES]); }
// Its flat normal // Its flat normal
flat_normals.push_back(normal.x()); add_normal(normal, arrays[m_started_face_is_colored?
flat_normals.push_back(normal.y()); FLAT_NORMAL_COLORED_FACES:
flat_normals.push_back(normal.z()); FLAT_NORMAL_MONO_FACES]);
// Its smoth normal (if given by the user) // Its smoth normal (if given by the user)
smooth_normals.push_back(ffit->vertex(i)->info().v.x()); add_normal(ffit->vertex(i)->info().v, arrays[m_started_face_is_colored?
smooth_normals.push_back(ffit->vertex(i)->info().v.y()); SMOOTH_NORMAL_COLORED_FACES:
smooth_normals.push_back(ffit->vertex(i)->info().v.z()); SMOOTH_NORMAL_MONO_FACES]);
} }
} }
} }
@ -549,241 +567,211 @@ protected:
void compile_shaders() void compile_shaders()
{ {
rendering_program.removeAllShaders(); rendering_program_mono.removeAllShaders();
rendering_program_p_l.removeAllShaders(); rendering_program_color.removeAllShaders();
/*rendering_program_p_l_mono.removeAllShaders();
rendering_program_p_l_color.removeAllShaders(); */
// Create the buffers // Create the buffers
for (int i=0; i<NB_VBO_BUFFERS; ++i) for (int i=0; i<NB_VBO_BUFFERS; ++i)
{
if(!buffers[i].isCreated() && !buffers[i].create()) if(!buffers[i].isCreated() && !buffers[i].create())
{ { std::cerr<<"VBO Creation number "<<i<<" FAILED"<<std::endl; }
std::cerr<<"VBO Creation number "<<i<<" FAILED"<<std::endl; }
}
for (int i=0; i<NB_VAO_BUFFERS; ++i) for (int i=0; i<NB_VAO_BUFFERS; ++i)
{
if(!vao[i].isCreated() && !vao[i].create()) if(!vao[i].isCreated() && !vao[i].create())
{ { std::cerr<<"VAO Creation number "<<i<<" FAILED"<<std::endl; }
std::cerr<<"VAO Creation number "<<i<<" FAILED"<<std::endl; }
}
//The Facets //The Facets
QOpenGLShader *vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex); QOpenGLShader *vertex_shader_mono = new QOpenGLShader(QOpenGLShader::Vertex);
if (m_use_mono_color) if(!vertex_shader_mono->compileSourceCode(vertex_source_mono))
{ { std::cerr<<"Compiling vertex source FAILED"<<std::endl; }
if(!vertex_shader->compileSourceCode(vertex_source_mono)) QOpenGLShader *fragment_shader_mono= new QOpenGLShader(QOpenGLShader::Fragment);
{ if(!fragment_shader_mono->compileSourceCode(fragment_source_mono))
std::cerr<<"Compiling vertex source FAILED"<<std::endl; { std::cerr<<"Compiling fragmentsource FAILED"<<std::endl; }
}
}
else
{
if(!vertex_shader->compileSourceCode(vertex_source_multi))
{
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
}
}
QOpenGLShader *fragment_shader= new QOpenGLShader(QOpenGLShader::Fragment);
if (m_use_mono_color)
{
if(!fragment_shader->compileSourceCode(fragment_source_mono))
{
std::cerr<<"Compiling fragmentsource FAILED"<<std::endl;
}
}
else
{
if(!fragment_shader->compileSourceCode(fragment_source_multi))
{
std::cerr<<"Compiling fragmentsource FAILED"<<std::endl;
}
}
if(!rendering_program.addShader(vertex_shader))
{
std::cerr<<"adding vertex shader FAILED"<<std::endl;
}
if(!rendering_program.addShader(fragment_shader))
{
std::cerr<<"adding fragment shader FAILED"<<std::endl;
}
if(!rendering_program.link())
{
std::cerr<<"linking Program FAILED"<<std::endl;
}
rendering_program.bind();
vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex); if(!rendering_program_mono.addShader(vertex_shader_mono))
if(!vertex_shader->compileSourceCode(vertex_source_p_l)) { std::cerr<<"adding vertex shader FAILED"<<std::endl; }
if(!rendering_program_mono.addShader(fragment_shader_mono))
{ std::cerr<<"adding fragment shader FAILED"<<std::endl; }
if(!rendering_program_mono.link())
{ std::cerr<<"linking Program FAILED"<<std::endl; }
rendering_program_mono.bind();
QOpenGLShader *vertex_shader_color = new QOpenGLShader(QOpenGLShader::Vertex);
QOpenGLShader *fragment_shader_color= new QOpenGLShader(QOpenGLShader::Fragment);
if (m_use_mono_color)
{ {
std::cerr<<"Compiling vertex source FAILED"<<std::endl; if(!vertex_shader_color->compileSourceCode(vertex_source_mono))
{ std::cerr<<"Compiling vertex source FAILED"<<std::endl; }
if(!fragment_shader_color->compileSourceCode(fragment_source_mono))
{ std::cerr<<"Compiling fragmentsource FAILED"<<std::endl; }
} }
else
{
if(!vertex_shader_color->compileSourceCode(vertex_source_color))
{ std::cerr<<"Compiling vertex source FAILED"<<std::endl; }
if(!fragment_shader_color->compileSourceCode(fragment_source_color))
{ std::cerr<<"Compiling fragmentsource FAILED"<<std::endl; }
}
if(!rendering_program_color.addShader(vertex_shader_color))
{ std::cerr<<"adding vertex shader FAILED"<<std::endl; }
if(!rendering_program_color.addShader(fragment_shader_color))
{ std::cerr<<"adding fragment shader FAILED"<<std::endl; }
if(!rendering_program_color.link())
{ std::cerr<<"linking Program FAILED"<<std::endl; }
rendering_program_color.bind();
/* vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex);
if(!vertex_shader->compileSourceCode(vertex_source_p_l))
{ std::cerr<<"Compiling vertex source FAILED"<<std::endl; }
fragment_shader= new QOpenGLShader(QOpenGLShader::Fragment); fragment_shader= new QOpenGLShader(QOpenGLShader::Fragment);
if(!fragment_shader->compileSourceCode(fragment_source_p_l)) if(!fragment_shader->compileSourceCode(fragment_source_p_l))
{ { std::cerr<<"Compiling fragmentsource FAILED"<<std::endl; }
std::cerr<<"Compiling fragmentsource FAILED"<<std::endl;
}
if(!rendering_program_p_l.addShader(vertex_shader)) if(!rendering_program_p_l.addShader(vertex_shader))
{ { std::cerr<<"adding vertex shader FAILED"<<std::endl; }
std::cerr<<"adding vertex shader FAILED"<<std::endl;
}
if(!rendering_program_p_l.addShader(fragment_shader)) if(!rendering_program_p_l.addShader(fragment_shader))
{ { std::cerr<<"adding fragment shader FAILED"<<std::endl; }
std::cerr<<"adding fragment shader FAILED"<<std::endl;
}
if(!rendering_program_p_l.link()) if(!rendering_program_p_l.link())
{ { std::cerr<<"linking Program FAILED"<<std::endl; }
std::cerr<<"linking Program FAILED"<<std::endl; rendering_program_p_l.bind();*/
}
rendering_program_p_l.bind();
} }
void initialize_buffers() void initialize_buffers()
{ {
int bufn = 0; int bufn = 0;
int vaon = 0; int vaon = 0;
// 1) POINT SHADER
// 1.1) Mono points
// 1.2) Color points
// 2) SEGMENT SHADER
// 2.1) Mono segments
// 2.2) Color segments
//points of the facets // 3) FACE SHADER
assert(vaon<NB_VAO_BUFFERS); assert(vaon<NB_VAO_BUFFERS);
vao[vaon].bind(); vao[vaon].bind();
// 3.1) Mono faces
// 3.1.1) points of the mono faces
assert(bufn<NB_VBO_BUFFERS); assert(bufn<NB_VBO_BUFFERS);
buffers[bufn].bind(); buffers[bufn].bind();
buffers[bufn].allocate(pos_faces.data(), buffers[bufn].allocate(arrays[POS_MONO_FACES].data(),
static_cast<int>(pos_faces.size()*sizeof(float))); static_cast<int>(arrays[POS_MONO_FACES].size()*sizeof(float)));
vertexLocation[vaon] = rendering_program.attributeLocation("vertex"); vertexLocation[vaon] = rendering_program_mono.attributeLocation("vertex");
rendering_program.bind(); rendering_program_mono.bind();
rendering_program.enableAttributeArray(vertexLocation[vaon]); rendering_program_mono.enableAttributeArray(vertexLocation[vaon]);
rendering_program.setAttributeBuffer(vertexLocation[vaon],GL_FLOAT,0,3); rendering_program_mono.setAttributeBuffer(vertexLocation[vaon],GL_FLOAT,0,3);
rendering_program.release(); rendering_program_mono.release();
buffers[bufn].release(); buffers[bufn].release();
++bufn; ++bufn;
//normals of the facets // 3.1.2) normals of the mono faces
assert(bufn<NB_VBO_BUFFERS); assert(bufn<NB_VBO_BUFFERS);
buffers[bufn].bind(); buffers[bufn].bind();
buffers[bufn].allocate(flat_normals.data(), if (m_flatShading)
static_cast<int>(flat_normals.size()*sizeof(float)));
normalsLocation = rendering_program.attributeLocation("normal");
rendering_program.bind();
rendering_program.enableAttributeArray(normalsLocation);
rendering_program.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3);
rendering_program.release();
buffers[bufn].release();
++bufn;
if (!m_use_mono_color)
{ {
//colors of the facets buffers[bufn].allocate(arrays[FLAT_NORMAL_MONO_FACES].data(),
assert(bufn<NB_VBO_BUFFERS); static_cast<int>(arrays[FLAT_NORMAL_MONO_FACES].size()*
buffers[bufn].bind(); sizeof(float)));
buffers[bufn].allocate(colors.data(),
static_cast<int>(colors.size()*sizeof(float)));
colorsLocation = rendering_program.attributeLocation("color");
rendering_program.bind();
rendering_program.enableAttributeArray(colorsLocation);
rendering_program.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3);
rendering_program.release();
buffers[bufn].release();
++bufn;
} }
else
{
buffers[bufn].allocate(arrays[SMOOTH_NORMAL_MONO_FACES].data(),
static_cast<int>(arrays[SMOOTH_NORMAL_MONO_FACES].size()*
sizeof(float)));
}
normalsLocation = rendering_program_mono.attributeLocation("normal");
rendering_program_mono.bind();
rendering_program_mono.enableAttributeArray(normalsLocation);
rendering_program_mono.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3);
rendering_program_mono.release();
buffers[bufn].release();
++bufn;
vao[vaon].release(); vao[vaon].release();
++vaon; ++vaon;
// 3.2) Color faces
assert(vaon<NB_VAO_BUFFERS); assert(vaon<NB_VAO_BUFFERS);
vao[vaon].bind(); vao[vaon].bind();
//points of the facets // 3.2.1) points of the color faces
assert(bufn<NB_VBO_BUFFERS); assert(bufn<NB_VBO_BUFFERS);
buffers[bufn].bind(); buffers[bufn].bind();
buffers[bufn].allocate(pos_faces.data(), buffers[bufn].allocate(arrays[POS_COLORED_FACES].data(),
static_cast<int>(pos_faces.size()*sizeof(float))); static_cast<int>(arrays[POS_COLORED_FACES].size()*sizeof(float)));
vertexLocation[vaon] = rendering_program.attributeLocation("vertex"); vertexLocation[vaon] = rendering_program_color.attributeLocation("vertex");
rendering_program.bind(); rendering_program_color.bind();
rendering_program.enableAttributeArray(vertexLocation[vaon]); rendering_program_color.enableAttributeArray(vertexLocation[vaon]);
rendering_program.setAttributeBuffer(vertexLocation[vaon],GL_FLOAT,0,3); rendering_program_color.setAttributeBuffer(vertexLocation[vaon],GL_FLOAT,0,3);
rendering_program.release(); rendering_program_color.release();
buffers[bufn].release(); buffers[bufn].release();
++bufn; ++bufn;
//normals of the facets // 3.2.2) normals of the color faces
assert(bufn<NB_VBO_BUFFERS); assert(bufn<NB_VBO_BUFFERS);
buffers[bufn].bind(); buffers[bufn].bind();
buffers[bufn].allocate(smooth_normals.data(), if (m_flatShading)
static_cast<int>(smooth_normals.size()*sizeof(float))); {
normalsLocation = rendering_program.attributeLocation("normal"); buffers[bufn].allocate(arrays[FLAT_NORMAL_COLORED_FACES].data(),
rendering_program.bind(); static_cast<int>(arrays[FLAT_NORMAL_COLORED_FACES].size()*
rendering_program.enableAttributeArray(normalsLocation); sizeof(float)));
rendering_program.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3); }
rendering_program.release(); else
{
buffers[bufn].allocate(arrays[SMOOTH_NORMAL_COLORED_FACES].data(),
static_cast<int>(arrays[SMOOTH_NORMAL_COLORED_FACES].size()*
sizeof(float)));
}
normalsLocation = rendering_program_color.attributeLocation("normal");
rendering_program_color.bind();
rendering_program_color.enableAttributeArray(normalsLocation);
rendering_program_color.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3);
rendering_program_color.release();
buffers[bufn].release(); buffers[bufn].release();
++bufn; ++bufn;
// 3.2.3) colors of the faces
if (!m_use_mono_color) if (!m_use_mono_color)
{ {
//colors of the facets
assert(bufn<NB_VBO_BUFFERS); assert(bufn<NB_VBO_BUFFERS);
buffers[bufn].bind(); buffers[bufn].bind();
buffers[bufn].allocate(colors.data(), static_cast<int>(colors.size()*sizeof(float))); buffers[bufn].allocate(arrays[COLOR_FACES].data(),
colorsLocation = rendering_program.attributeLocation("color"); static_cast<int>(arrays[COLOR_FACES].size()*sizeof(float)));
rendering_program.bind(); colorsLocation = rendering_program_color.attributeLocation("color");
rendering_program.enableAttributeArray(colorsLocation); rendering_program_color.bind();
rendering_program.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3); rendering_program_color.enableAttributeArray(colorsLocation);
rendering_program_color.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3);
rendering_program_color.release();
buffers[bufn].release(); buffers[bufn].release();
rendering_program.release();
++bufn; ++bufn;
} }
vao[vaon].release();
++vaon;
//The segments
assert(vaon<NB_VAO_BUFFERS);
vao[vaon].bind();
assert(bufn<NB_VBO_BUFFERS);
buffers[bufn].bind();
buffers[bufn].allocate(pos_segments.data(), static_cast<int>(pos_segments.size()*sizeof(float)));
vertexLocation[vaon] = rendering_program_p_l.attributeLocation("vertex");
rendering_program_p_l.bind();
rendering_program_p_l.enableAttributeArray(vertexLocation[vaon]);
rendering_program_p_l.setAttributeBuffer(vertexLocation[vaon],GL_FLOAT,0,3);
rendering_program_p_l.release();
buffers[bufn].release();
++bufn;
vao[vaon].release();
++vaon;
//The points
assert(vaon<NB_VAO_BUFFERS);
vao[vaon].bind();
assert(bufn<NB_VBO_BUFFERS);
buffers[bufn].bind();
buffers[bufn].allocate(pos_points.data(), static_cast<int>(pos_points.size()*sizeof(float)));
vertexLocation[vaon] = rendering_program_p_l.attributeLocation("vertex");
rendering_program_p_l.bind();
rendering_program_p_l.enableAttributeArray(vertexLocation[vaon]);
rendering_program_p_l.setAttributeBuffer(vertexLocation[vaon],GL_FLOAT,0,3);
rendering_program_p_l.release();
buffers[bufn].release();
++bufn;
vao[vaon].release(); vao[vaon].release();
++vaon; ++vaon;
m_are_buffers_initialized = true; m_are_buffers_initialized = true;
} }
@ -816,33 +804,52 @@ protected:
QVector4D position((bb.xmax()-bb.xmin())/2, (bb.ymax()-bb.ymin())/2,bb.zmax(), 0.0 ); QVector4D position((bb.xmax()-bb.xmin())/2, (bb.ymax()-bb.ymin())/2,bb.zmax(), 0.0 );
GLfloat shininess = 1.0f; GLfloat shininess = 1.0f;
rendering_program.bind(); rendering_program_mono.bind();
mvpLocation[0] = rendering_program.uniformLocation("mvp_matrix"); mvpLocation[0] = rendering_program_mono.uniformLocation("mvp_matrix");
mvLocation = rendering_program.uniformLocation("mv_matrix"); mvLocation = rendering_program_mono.uniformLocation("mv_matrix");
lightLocation[0] = rendering_program.uniformLocation("light_pos"); lightLocation[0] = rendering_program_mono.uniformLocation("light_pos");
lightLocation[1] = rendering_program.uniformLocation("light_diff"); lightLocation[1] = rendering_program_mono.uniformLocation("light_diff");
lightLocation[2] = rendering_program.uniformLocation("light_spec"); lightLocation[2] = rendering_program_mono.uniformLocation("light_spec");
lightLocation[3] = rendering_program.uniformLocation("light_amb"); lightLocation[3] = rendering_program_mono.uniformLocation("light_amb");
lightLocation[4] = rendering_program.uniformLocation("spec_power"); lightLocation[4] = rendering_program_mono.uniformLocation("spec_power");
rendering_program.setUniformValue(lightLocation[0], position); rendering_program_mono.setUniformValue(lightLocation[0], position);
rendering_program.setUniformValue(lightLocation[1], diffuse); rendering_program_mono.setUniformValue(lightLocation[1], diffuse);
rendering_program.setUniformValue(lightLocation[2], specular); rendering_program_mono.setUniformValue(lightLocation[2], specular);
rendering_program.setUniformValue(lightLocation[3], m_ambient_color); rendering_program_mono.setUniformValue(lightLocation[3], m_ambient_color);
rendering_program.setUniformValue(lightLocation[4], shininess); rendering_program_mono.setUniformValue(lightLocation[4], shininess);
rendering_program.setUniformValue(mvpLocation[0], mvpMatrix); rendering_program_mono.setUniformValue(mvpLocation[0], mvpMatrix);
rendering_program.setUniformValue(mvLocation, mvMatrix); rendering_program_mono.setUniformValue(mvLocation, mvMatrix);
colorLocation1 = rendering_program_mono.uniformLocation("color");
rendering_program_mono.release();
rendering_program_color.bind();
mvpLocation[0] = rendering_program_color.uniformLocation("mvp_matrix");
mvLocation = rendering_program_color.uniformLocation("mv_matrix");
lightLocation[0] = rendering_program_color.uniformLocation("light_pos");
lightLocation[1] = rendering_program_color.uniformLocation("light_diff");
lightLocation[2] = rendering_program_color.uniformLocation("light_spec");
lightLocation[3] = rendering_program_color.uniformLocation("light_amb");
lightLocation[4] = rendering_program_color.uniformLocation("spec_power");
rendering_program_color.setUniformValue(lightLocation[0], position);
rendering_program_color.setUniformValue(lightLocation[1], diffuse);
rendering_program_color.setUniformValue(lightLocation[2], specular);
rendering_program_color.setUniformValue(lightLocation[3], m_ambient_color);
rendering_program_color.setUniformValue(lightLocation[4], shininess);
rendering_program_color.setUniformValue(mvpLocation[0], mvpMatrix);
rendering_program_color.setUniformValue(mvLocation, mvMatrix);
if (m_use_mono_color) if (m_use_mono_color)
colorLocation2 = rendering_program.uniformLocation("color"); { colorLocation2 = rendering_program_color.uniformLocation("color"); }
rendering_program_color.release();
rendering_program.release();
rendering_program_p_l.bind(); /* rendering_program_p_l_.bind();
mvpLocation[1] = rendering_program_p_l.uniformLocation("mvp_matrix"); mvpLocation[1] = rendering_program_p_l.uniformLocation("mvp_matrix");
colorLocation = rendering_program_p_l.uniformLocation("color"); colorLocation = rendering_program_p_l.uniformLocation("color");
rendering_program.setUniformValue(mvpLocation[1], mvpMatrix); rendering_program.setUniformValue(mvpLocation[1], mvpMatrix);
rendering_program_p_l.release(); rendering_program_p_l.release();*/
} }
virtual void draw() virtual void draw()
@ -853,7 +860,7 @@ protected:
QColor color; QColor color;
if(m_draw_vertices) /* if(m_draw_vertices)
{ {
::glPointSize(m_size_points); ::glPointSize(m_size_points);
vao[3].bind(); vao[3].bind();
@ -863,7 +870,7 @@ protected:
(double)m_vertices_mono_color.blue()/(double)255); (double)m_vertices_mono_color.blue()/(double)255);
rendering_program_p_l.bind(); rendering_program_p_l.bind();
rendering_program_p_l.setAttributeValue(colorLocation,color); rendering_program_p_l.setAttributeValue(colorLocation,color);
glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(pos_points.size()/3)); // glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(pos_points.size()/3));
rendering_program_p_l.release(); rendering_program_p_l.release();
vao[3].release(); vao[3].release();
} }
@ -878,34 +885,37 @@ protected:
rendering_program_p_l.bind(); rendering_program_p_l.bind();
rendering_program_p_l.setAttributeValue(colorLocation,color); rendering_program_p_l.setAttributeValue(colorLocation,color);
::glLineWidth(m_size_edges); ::glLineWidth(m_size_edges);
glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(pos_segments.size()/3)); // glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(pos_segments.size()/3));
rendering_program_p_l.release(); rendering_program_p_l.release();
vao[2].release(); vao[2].release();
} }*/
if (m_draw_faces) if (m_draw_faces)
{ {
if(m_flatShading) vao[0].bind();
{ vao[0].bind(); }
else
{ vao[1].bind(); }
attrib_buffers(this); attrib_buffers(this);
rendering_program.bind(); rendering_program_mono.bind();
color.setRgbF((double)m_faces_mono_color.red()/(double)255,
(double)m_faces_mono_color.green()/(double)255,
(double)m_faces_mono_color.blue()/(double)255);
rendering_program_mono.setUniformValue(colorLocation1,color);
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(arrays[POS_MONO_FACES].size()/3));
rendering_program_mono.release();
vao[0].release();
vao[1].bind();
attrib_buffers(this);
rendering_program_color.bind();
if (m_use_mono_color) if (m_use_mono_color)
{ {
color.setRgbF((double)m_faces_mono_color.red()/(double)255, color.setRgbF((double)m_faces_mono_color.red()/(double)255,
(double)m_faces_mono_color.green()/(double)255, (double)m_faces_mono_color.green()/(double)255,
(double)m_faces_mono_color.blue()/(double)255); (double)m_faces_mono_color.blue()/(double)255);
rendering_program.setUniformValue(colorLocation2,color); rendering_program_color.setUniformValue(colorLocation2,color);
} }
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(pos_faces.size()/3)); glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(arrays[POS_COLORED_FACES].size()/3));
rendering_program.release(); rendering_program_color.release();
vao[1].release();
if(m_flatShading)
{ vao[0].release(); }
else
{ vao[1].release(); }
} }
} }
@ -962,11 +972,11 @@ protected:
void negate_all_normals() void negate_all_normals()
{ {
for (std::size_t i=0; i<smooth_normals.size(); ++i) for (unsigned int k=BEGIN_NORMAL; k<END_NORMAL; ++k)
{ smooth_normals[i]=-smooth_normals[i]; } {
for (std::size_t i=0; i<arrays[k].size(); ++i)
for (std::size_t i=0; i<flat_normals.size(); ++i) { arrays[k][i]=-arrays[k][i]; }
{ flat_normals[i]=-flat_normals[i]; } }
} }
virtual void keyPressEvent(QKeyEvent *e) virtual void keyPressEvent(QKeyEvent *e)
@ -992,22 +1002,24 @@ protected:
displayMessage("Flat shading."); displayMessage("Flat shading.");
else else
displayMessage("Gouraud shading."); displayMessage("Gouraud shading.");
compile_shaders();
initialize_buffers();
updateGL(); updateGL();
} }
else if ((e->key()==Qt::Key_M) && (modifiers==Qt::NoButton)) else if ((e->key()==Qt::Key_M) && (modifiers==Qt::NoButton))
{ {
m_use_mono_color=!m_use_mono_color; m_use_mono_color=!m_use_mono_color;
initialize_buffers();
compile_shaders();
displayMessage(QString("Mono color=%1.").arg(m_use_mono_color?"true":"false")); displayMessage(QString("Mono color=%1.").arg(m_use_mono_color?"true":"false"));
compile_shaders();
initialize_buffers();
updateGL(); updateGL();
} }
else if ((e->key()==Qt::Key_N) && (modifiers==Qt::NoButton)) else if ((e->key()==Qt::Key_N) && (modifiers==Qt::NoButton))
{ {
m_inverse_normal=!m_inverse_normal; m_inverse_normal=!m_inverse_normal;
negate_all_normals(); negate_all_normals();
initialize_buffers();
compile_shaders(); compile_shaders();
initialize_buffers();
displayMessage(QString("Inverse normal=%1.").arg(m_inverse_normal?"true":"false")); displayMessage(QString("Inverse normal=%1.").arg(m_inverse_normal?"true":"false"));
updateGL(); updateGL();
} }
@ -1156,7 +1168,8 @@ private:
bool m_flatShading; bool m_flatShading;
bool m_use_mono_color; bool m_use_mono_color;
bool m_inverse_normal; bool m_inverse_normal;
bool m_empty;
double m_size_points; double m_size_points;
double m_size_edges; double m_size_edges;
@ -1173,25 +1186,43 @@ private:
int normalsLocation; int normalsLocation;
int mvpLocation[2]; int mvpLocation[2];
int mvLocation; int mvLocation;
int colorLocation; int colorLocation1;
int colorLocation2; int colorLocation2;
int lightLocation[5]; int lightLocation[5];
std::vector<float> pos_points; enum
std::vector<float> pos_segments; { POS_MONO_POINTS=0,
std::vector<float> pos_faces; POS_COLORED_POINTS,
std::vector<float> smooth_normals; POS_MONO_SEGMENTS,
std::vector<float> flat_normals; POS_COLORED_SEGMENTS,
std::vector<float> colors; POS_MONO_FACES,
POS_COLORED_FACES,
BEGIN_NORMAL,
SMOOTH_NORMAL_MONO_FACES=BEGIN_NORMAL,
FLAT_NORMAL_MONO_FACES,
SMOOTH_NORMAL_COLORED_FACES,
FLAT_NORMAL_COLORED_FACES,
END_NORMAL,
COLOR_POINTS=END_NORMAL,
COLOR_SEGMENTS,
COLOR_FACES,
LAST_INDEX
};
std::vector<float> arrays[LAST_INDEX];
QGLBuffer buffers[NB_VBO_BUFFERS]; QGLBuffer buffers[NB_VBO_BUFFERS];
QOpenGLVertexArrayObject vao[NB_VAO_BUFFERS]; QOpenGLVertexArrayObject vao[NB_VAO_BUFFERS];
int colorsLocation; int colorsLocation;
QOpenGLShaderProgram rendering_program; QOpenGLShaderProgram rendering_program_mono;
QOpenGLShaderProgram rendering_program_p_l; QOpenGLShaderProgram rendering_program_color;
QOpenGLShaderProgram rendering_program_p_l_mono;
QOpenGLShaderProgram rendering_program_p_l_color;
// Local variables, used when we started a new face.
bool m_face_started; bool m_face_started;
bool m_started_face_is_colored;
std::vector<Local_point> points_of_face; std::vector<Local_point> points_of_face;
std::vector<Local_vector> vertex_normals_for_face; std::vector<Local_vector> vertex_normals_for_face;
CGAL::Color color_of_face; CGAL::Color color_of_face;