mirror of https://github.com/CGAL/cgal
320 lines
10 KiB
C++
320 lines
10 KiB
C++
#include "Viewer.h"
|
|
#include <vector>
|
|
#include <CGAL/bounding_box.h>
|
|
#include <QGLViewer/vec.h>
|
|
|
|
|
|
void
|
|
Viewer::init()
|
|
{
|
|
initializeOpenGLFunctions();
|
|
setBackgroundColor(::Qt::white);
|
|
this->camera()->setSceneBoundingBox(
|
|
qglviewer::Vec(-1.,-1.,-1.),
|
|
qglviewer::Vec( 1., 1., 1.));
|
|
glEnable(GL_LINE_SMOOTH);
|
|
compile_shaders();
|
|
are_buffers_initialized = false;
|
|
}
|
|
|
|
void
|
|
Viewer::sceneChanged()
|
|
{
|
|
changed();
|
|
this->showEntireScene();
|
|
}
|
|
|
|
void
|
|
Viewer::draw()
|
|
{
|
|
glEnable(GL_DEPTH_TEST);
|
|
if(!are_buffers_initialized)
|
|
initialize_buffers();
|
|
QColor color;
|
|
//the points
|
|
::glEnable(GL_BLEND);
|
|
::glEnable(GL_POINT_SMOOTH);
|
|
::glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
|
::glEnable(GL_LINE_SMOOTH);
|
|
::glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
|
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
::glPointSize(5);
|
|
|
|
::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
|
::glColor3f(0.2f, 0.2f, 1.f);
|
|
::glEnable(GL_POLYGON_OFFSET_FILL);
|
|
::glPolygonOffset(3.0f,-3.0f);
|
|
|
|
|
|
attrib_buffers(this);
|
|
vao[0].bind();
|
|
color.setRgbF(1.0f, 0.72f, 0.06f);
|
|
rendering_program.bind();
|
|
rendering_program.setUniformValue(colorLocation[0], color);
|
|
glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(pos_points.size()/3));
|
|
rendering_program.release();
|
|
vao[0].release();
|
|
|
|
//The Lines
|
|
::glLineWidth(1.);
|
|
::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
|
::glColor3ub(0,0,0);
|
|
::glDisable(GL_POLYGON_OFFSET_FILL);
|
|
|
|
vao[1].bind();
|
|
color.setRgbF(0.27f, 0.51f, 0.7f);
|
|
rendering_program.bind();
|
|
rendering_program.setUniformValue(colorLocation[0], color);
|
|
glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(pos_lines.size()/3));
|
|
rendering_program.release();
|
|
vao[1].release();
|
|
|
|
if (scene->eight_copies) {
|
|
vao[2].bind();
|
|
color.setRgbF(0.69f, 0.77f, 0.87f);
|
|
rendering_program.bind();
|
|
rendering_program.setUniformValue(colorLocation[0], color);
|
|
glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(pos_8lines2D.size()/3));
|
|
rendering_program.release();
|
|
vao[2].release();
|
|
|
|
|
|
if (!scene->two_dimensional) {
|
|
vao[3].bind();
|
|
color.setRgbF(0.69f, 0.77f, 0.87f);
|
|
rendering_program.bind();
|
|
rendering_program.setUniformValue(colorLocation[0], color);
|
|
glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(pos_8lines.size()/3));
|
|
rendering_program.release();
|
|
vao[3].release();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Viewer::Vec
|
|
Viewer::next_around_circle(const float& phi, const Vec& pos, const Vec& ori) {
|
|
Vec cam = pos-ori;
|
|
Vec cam_norm = cam/cam.norm();
|
|
|
|
Vec y(cam_norm.z, 0, -cam_norm.x);
|
|
Vec y_norm = y/y.norm();
|
|
|
|
Vec new_cam = ori + (cam_norm*cos(phi) + y_norm*sin(phi)) * cam.norm();
|
|
return new_cam;
|
|
}
|
|
|
|
void
|
|
Viewer::render_video()
|
|
{
|
|
setSnapshotFormat("PNG");
|
|
for (int alpha=0 ; alpha <= 100 ; alpha++ ) {
|
|
emit (valueChanged(alpha));
|
|
std::cout<<alpha<<std::endl;
|
|
QString alpha_str;
|
|
alpha_str.setNum(alpha);
|
|
displayMessage(QString("alpha: ") + alpha_str + QString("%"),10000);
|
|
|
|
for (int fr=0 ; fr < 50 ; fr++) {
|
|
Vec cam = camera()->position();
|
|
Vec ori = sceneCenter();
|
|
Vec new_cam = next_around_circle(0.01f,cam,ori);
|
|
camera()->setPosition(new_cam);
|
|
camera()->lookAt(ori);
|
|
this->showEntireScene();
|
|
saveSnapshot(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Viewer::initialize_buffers()
|
|
{
|
|
rendering_program.bind();
|
|
|
|
vao[0].bind();
|
|
buffers[0].bind();
|
|
buffers[0].allocate(pos_points.data(), static_cast<int>(pos_points.size()*sizeof(float)));
|
|
vertexLocation[0] = rendering_program.attributeLocation("vertex");
|
|
rendering_program.enableAttributeArray(vertexLocation[0]);
|
|
rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3);
|
|
buffers[0].release();
|
|
|
|
vao[0].release();
|
|
|
|
vao[1].bind();
|
|
buffers[1].bind();
|
|
buffers[1].allocate(pos_lines.data(), static_cast<int>(pos_lines.size()*sizeof(float)));
|
|
vertexLocation[0] = rendering_program.attributeLocation("vertex");
|
|
rendering_program.enableAttributeArray(vertexLocation[0]);
|
|
rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3);
|
|
buffers[1].release();
|
|
vao[1].release();
|
|
|
|
vao[2].bind();
|
|
buffers[2].bind();
|
|
buffers[2].allocate(pos_8lines2D.data(), static_cast<int>(pos_8lines2D.size()*sizeof(float)));
|
|
vertexLocation[0] = rendering_program.attributeLocation("vertex");
|
|
rendering_program.enableAttributeArray(vertexLocation[0]);
|
|
rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3);
|
|
buffers[2].release();
|
|
vao[2].release();
|
|
|
|
vao[3].bind();
|
|
buffers[3].bind();
|
|
buffers[3].allocate(pos_8lines.data(), static_cast<int>(pos_8lines.size()*sizeof(float)));
|
|
vertexLocation[0] = rendering_program.attributeLocation("vertex");
|
|
rendering_program.enableAttributeArray(vertexLocation[0]);
|
|
rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3);
|
|
buffers[3].release();
|
|
vao[3].release();
|
|
rendering_program.release();
|
|
are_buffers_initialized = true;
|
|
}
|
|
|
|
void Viewer::compute_elements()
|
|
{
|
|
//::glColor3f(1.0f, 0.72f, 0.06f);
|
|
pos_points.resize(0);
|
|
pos_lines.resize(0);
|
|
pos_8lines.resize(0);
|
|
pos_8lines2D.resize(0);
|
|
|
|
for(Periodic_point_iterator ppit
|
|
= scene->periodic_triangulation.periodic_points_begin(
|
|
P3DT3::UNIQUE) ;
|
|
ppit != scene->periodic_triangulation.periodic_points_end(P3DT3::UNIQUE);
|
|
++ppit){
|
|
Point_3 p(scene->periodic_triangulation.point(*ppit));
|
|
pos_points.push_back(p.x()); pos_points.push_back(p.y()); pos_points.push_back(p.z());
|
|
}
|
|
|
|
//::glColor3f(0.27f, 0.51f, 0.7f);
|
|
for (Periodic_triangle_iterator ptit
|
|
= scene->periodic_triangulation.periodic_triangles_begin(
|
|
P3DT3::UNIQUE);
|
|
ptit != scene->periodic_triangulation.periodic_triangles_end(
|
|
P3DT3::UNIQUE);
|
|
++ptit) {
|
|
for (int i=0 ; i<4 ; i++) {
|
|
Segment_3 dual = scene->periodic_triangulation.segment(
|
|
scene->periodic_triangulation.dual(*(ptit.get_facet())));
|
|
|
|
FT sz = dual.source().z();
|
|
FT tz = dual.target().z();
|
|
|
|
if (scene->two_dimensional && ((sz-tz > 0.5) || (sz-tz < -0.5))) continue;
|
|
|
|
if (scene->two_dimensional) { sz = 0.; tz = 0.; }
|
|
FT sx = dual.source().x();
|
|
FT tx = dual.target().x();
|
|
FT sy = dual.source().y();
|
|
FT ty = dual.target().y();
|
|
pos_lines.push_back(sx); pos_lines.push_back(sy); pos_lines.push_back(sz);
|
|
pos_lines.push_back(tx); pos_lines.push_back(ty); pos_lines.push_back(tz);
|
|
Iso_cuboid_3 d = scene->periodic_triangulation.domain();
|
|
|
|
pos_8lines2D.push_back(sx+0.); pos_8lines2D.push_back(sy+d.ymax()-d.ymin()); pos_8lines2D.push_back(sz+0.);
|
|
pos_8lines2D.push_back(tx+0.); pos_8lines2D.push_back(ty+d.ymax()-d.ymin()); pos_8lines2D.push_back(tz+0.);
|
|
pos_8lines2D.push_back(sx+d.xmax()-d.xmin()); pos_8lines2D.push_back(sy+0.); pos_8lines2D.push_back(sz+0.);
|
|
pos_8lines2D.push_back(tx+d.xmax()-d.xmin()); pos_8lines2D.push_back(ty+0.); pos_8lines2D.push_back(tz+0.);
|
|
pos_8lines2D.push_back(sx+d.xmax()-d.xmin()); pos_8lines2D.push_back(sy+d.ymax()-d.ymin()); pos_8lines2D.push_back(sz+0.);
|
|
pos_8lines2D.push_back(tx+d.xmax()-d.xmin()); pos_8lines2D.push_back(ty+d.ymax()-d.ymin()); pos_8lines2D.push_back(tz+0.);
|
|
|
|
pos_8lines.push_back(sx+0.); pos_8lines.push_back(sy+0.); pos_8lines.push_back(sz+d.zmax()-d.zmin());
|
|
pos_8lines.push_back(tx+0.); pos_8lines.push_back(ty+0.); pos_8lines.push_back(tz+d.zmax()-d.zmin());
|
|
pos_8lines.push_back(sx+0.); pos_8lines.push_back(sy+d.ymax()-d.ymin()); pos_8lines.push_back(sz+d.zmax()-d.zmin());
|
|
pos_8lines.push_back(tx+0.); pos_8lines.push_back(ty+d.ymax()-d.ymin()); pos_8lines.push_back(tz+d.zmax()-d.zmin());
|
|
pos_8lines.push_back(sx+d.xmax()-d.xmin()); pos_8lines.push_back(sy+0.); pos_8lines.push_back(sz+d.zmax()-d.zmin());
|
|
pos_8lines.push_back(tx+d.xmax()-d.xmin()); pos_8lines.push_back(ty+0.); pos_8lines.push_back(tz+d.zmax()-d.zmin());
|
|
pos_8lines.push_back(sx+d.xmax()-d.xmin()); pos_8lines.push_back(sy+d.ymax()-d.ymin()); pos_8lines.push_back(sz+d.zmax()-d.zmin());
|
|
pos_8lines.push_back(tx+d.xmax()-d.xmin()); pos_8lines.push_back(ty+d.ymax()-d.ymin()); pos_8lines.push_back(tz+d.zmax()-d.zmin());
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void Viewer::attrib_buffers(QGLViewer* viewer)
|
|
{
|
|
QMatrix4x4 mvpMatrix;
|
|
double mat[16];
|
|
viewer->camera()->getModelViewProjectionMatrix(mat);
|
|
for(int i=0; i < 16; i++)
|
|
{
|
|
mvpMatrix.data()[i] = (float)mat[i];
|
|
}
|
|
|
|
rendering_program.bind();
|
|
mvpLocation[0] = rendering_program.uniformLocation("mvp_matrix");
|
|
colorLocation[0] = rendering_program.uniformLocation("color");
|
|
rendering_program.setUniformValue(mvpLocation[0], mvpMatrix);
|
|
|
|
rendering_program.release();
|
|
}
|
|
|
|
void Viewer::compile_shaders()
|
|
{
|
|
if(! buffers[0].create() || !buffers[1].create() || !buffers[2].create() || !buffers[3].create())
|
|
{
|
|
std::cerr<<"VBO Creation FAILED"<<std::endl;
|
|
}
|
|
|
|
if(!vao[0].create() || !vao[1].create() || !vao[2].create() || !vao[3].create())
|
|
{
|
|
std::cerr<<"VAO Creation FAILED"<<std::endl;
|
|
}
|
|
|
|
//Vertex source code
|
|
const char vertex_source[] =
|
|
{
|
|
"#version 120 \n"
|
|
"attribute highp vec4 vertex;\n"
|
|
"uniform highp mat4 mvp_matrix;\n"
|
|
"void main(void)\n"
|
|
"{\n"
|
|
" gl_Position = mvp_matrix * vertex; \n"
|
|
"}"
|
|
};
|
|
//Fragment source code
|
|
const char fragment_source[] =
|
|
{
|
|
"#version 120 \n"
|
|
"uniform highp vec4 color; \n"
|
|
"void main(void) { \n"
|
|
"gl_FragColor = color; \n"
|
|
"} \n"
|
|
"\n"
|
|
};
|
|
QOpenGLShader *vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex);
|
|
if(!vertex_shader->compileSourceCode(vertex_source))
|
|
{
|
|
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
|
|
}
|
|
|
|
QOpenGLShader *fragment_shader= new QOpenGLShader(QOpenGLShader::Fragment);
|
|
if(!fragment_shader->compileSourceCode(fragment_source))
|
|
{
|
|
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();
|
|
|
|
}
|
|
|
|
void Viewer::changed()
|
|
{
|
|
compute_elements();
|
|
are_buffers_initialized = false;
|
|
}
|