Add depth-peeling to the scene.

This commit is contained in:
Maxime Gimeno 2018-05-02 11:05:05 +02:00
parent 7ac433c388
commit 1882658a94
16 changed files with 900 additions and 153 deletions

View File

@ -807,8 +807,9 @@ private Q_SLOTS:
this, SLOT(erase_group()));
group_map.remove(img_item);
QList<int> deletion;
Q_FOREACH(Scene_item* child, group->getChildren())
Q_FOREACH(Scene_interface::Item_id id, group->getChildren())
{
Scene_item* child = group->getChild(id);
group->unlockChild(child);
deletion.append(scene->item_id(child));
}

View File

@ -24,6 +24,7 @@
#include <QList>
#include <QAbstractProxyModel>
#include <QMimeData>
#include <QOpenGLFramebufferObject>
Scene::Scene(QObject* parent)
@ -37,6 +38,8 @@ Scene::Scene(QObject* parent)
double, double, double)),
this, SLOT(setSelectionRay(double, double, double,
double, double, double)));
connect(this, SIGNAL(indexErased(Scene_interface::Item_id)),
this, SLOT(adjustIds(Scene_interface::Item_id)));
picked = false;
gl_init = false;
@ -46,6 +49,7 @@ Scene::addItem(CGAL::Three::Scene_item* item)
{
Bbox bbox_before = bbox();
m_entries.push_back(item);
Item_id id = m_entries.size() - 1;
connect(item, SIGNAL(itemChanged()),
this, SLOT(itemChanged()));
connect(item, SIGNAL(itemVisibilityChanged()),
@ -70,7 +74,7 @@ Scene::addItem(CGAL::Three::Scene_item* item)
index_map[list.at(i)->index()] = m_entries.size() -1;
}
Q_EMIT updated();
Item_id id = m_entries.size() - 1;
children.push_back(id);
Q_EMIT newItem(id);
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item);
@ -95,13 +99,14 @@ Scene::replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emi
qobject_cast<CGAL::Three::Scene_group_item*>(m_entries[index]);
if(group)
{
QList<int> children;
Q_FOREACH(CGAL::Three::Scene_item* child, group->getChildren())
QList<int> group_children;
Q_FOREACH(Item_id id, group->getChildren())
{
CGAL::Three::Scene_item* child = group->getChild(id);
group->unlockChild(child);
children << item_id(child);
group_children << item_id(child);
}
erase(children);
erase(group_children);
}
CGAL::Three::Scene_group_item* parent = m_entries[index]->parentGroup();
bool is_locked = false;
@ -166,7 +171,10 @@ Scene::erase(Scene::Item_id index)
item->parentGroup()->removeChild(item);
//removes the item from all groups that contain it
m_entries.removeAll(item);
Item_id removed_item = item_id(item);
children.removeAll(removed_item);
indexErased(removed_item);
m_entries.removeAll(item);
Q_EMIT itemAboutToBeDestroyed(item);
item->aboutToBeDestroyed();
item->deleteLater();
@ -207,8 +215,9 @@ Scene::erase(QList<int> indices)
Scene_group_item* group = qobject_cast<Scene_group_item*>(item);
if(group)
{
Q_FOREACH(Scene_item* child, group->getChildren())
Q_FOREACH(Item_id id, group->getChildren())
{
CGAL::Three::Scene_item* child = group->getChild(id);
if(!to_be_removed.contains(child))
to_be_removed.push_back(child);
}
@ -220,7 +229,11 @@ Scene::erase(QList<int> indices)
Q_FOREACH(Scene_item* item, to_be_removed) {
if(item->parentGroup())
item->parentGroup()->removeChild(item);
m_entries.removeAll(item);
Item_id removed_item = item_id(item);
children.removeAll(removed_item);
indexErased(removed_item);
m_entries.removeAll(item);
Q_EMIT itemAboutToBeDestroyed(item);
item->aboutToBeDestroyed();
item->deleteLater();
@ -255,6 +268,7 @@ void Scene::remove_item_from_groups(Scene_item* item)
if(group)
{
group->removeChild(item);
children.push_back(item_id(item));
}
}
Scene::~Scene()
@ -309,21 +323,95 @@ Scene::duplicate(Item_id index)
void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer)
{
//Setting the light options
//Vertex source code
const char vertex_source[] =
{
"#version 120 \n"
"attribute highp vec4 vertex; \n"
"attribute highp vec2 v_texCoord; \n"
"uniform highp mat4 projection_matrix; \n"
"varying highp vec2 f_texCoord; \n"
"void main(void) \n"
"{ \n"
" f_texCoord = v_texCoord; \n"
" gl_Position = projection_matrix * vertex; \n"
"} \n"
// Create light components
GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f };
GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0, 1.0f };
GLfloat specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat position[] = { 0.0f, 0.0f, 1.0f, 1.0f };
};
//Fragment source code
const char fragment_source[] =
{
"#version 120 \n"
"varying highp vec2 f_texCoord; \n"
"uniform sampler2D texture; \n"
"void main(void) \n"
"{ \n"
" gl_FragColor = texture2D(texture, f_texCoord); \n"
"} \n"
};
// Assign created components to GL_LIGHT0
viewer->glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
viewer->glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
viewer->glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
viewer->glLightfv(GL_LIGHT0, GL_POSITION, position);
gl_init = true;
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(!program.addShader(vertex_shader))
{
std::cerr<<"adding vertex shader FAILED"<<std::endl;
}
if(!program.addShader(fragment_shader))
{
std::cerr<<"adding fragment shader FAILED"<<std::endl;
}
if(!program.link())
{
//std::cerr<<"linking Program FAILED"<<std::endl;
qDebug() << program.log();
}
points[0] = -1.0f; points[1] = -1.0f; points[2] = 0.0f;
points[3] = 1.0f; points[4] = 1.0f; points[5] = 0.0f;
points[6] = 1.0f; points[7] = -1.0f; points[8] = 0.0f;
points[9] = -1.0f; points[10] = -1.0f; points[11] = 0.0f;
points[12] = -1.0f; points[13] = 1.0f; points[14] = 0.0f;
points[15] = 1.0f; points[16] = 1.0f; points[17] = 0.0f;
uvs[0] = 0.0f; uvs[1] = 0.0f;
uvs[2] = 1.0f; uvs[3] = 1.0f;
uvs[4] = 1.0f; uvs[5] = 0.0f;
uvs[6] = 0.0f; uvs[7] = 0.0f;
uvs[8] = 0.0f; uvs[9] = 1.0f;
uvs[10] = 1.0f; uvs[11] = 1.0f;
vbo[0].create();
vbo[1].create();
viewer->makeCurrent();
vao = new QOpenGLVertexArrayObject();
vao->create();
program.bind();
vao->bind();
vbo[0].bind();
vbo[0].allocate(points, 18 * sizeof(float));
program.enableAttributeArray("vertex");
program.setAttributeArray("vertex", GL_FLOAT, 0, 3);
vbo[0].release();
vbo[1].bind();
vbo[1].allocate(uvs, 12 * sizeof(float));
program.enableAttributeArray("v_texCoord");
program.setAttributeArray("v_texCoord", GL_FLOAT, 0, 2);
vbo[1].release();
vao->release();
program.release();
gl_init = true;
}
void Scene::s_itemAboutToBeDestroyed(CGAL::Three::Scene_item *rmv_itm)
@ -368,14 +456,320 @@ bool item_should_be_skipped_in_draw(Scene_item* item) {
return true;
}
void Scene::renderScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
bool with_names,
int pass,
bool writing_depth,
QOpenGLFramebufferObject *fbo)
{
viewer->makeCurrent();
viewer->setCurrentPass(pass);
viewer->setDepthWriting(writing_depth);
viewer->setDepthPeelingFbo(fbo);
Q_FOREACH(Scene_interface::Item_id index, items)
{
CGAL::Three::Scene_item& item = *m_entries[index];
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(&item);
if(index == selected_item || selected_items_list.contains(index))
{
item.selection_changed(true);
}
else
{
item.selection_changed(false);
}
if(group ||item.visible())
{
if( group || item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud)
{
if(with_names) {
viewer->glClearDepth(1.0);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
if(item.renderingMode() == Gouraud)
viewer->glShadeModel(GL_SMOOTH);
else
viewer->glShadeModel(GL_FLAT);
item.draw(viewer);
}
if(with_names) {
// read depth buffer at pick location;
float depth = 1.0;
viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
if (depth != 1.0)
{
//add object to list of picked objects;
picked_item_IDs[depth] = index;
}
}
if(group)
group->renderChildren(viewer, picked_item_IDs, picked_pixel, with_names);
}
}
}
void Scene::renderWireScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
bool with_names)
{
Q_FOREACH(Scene_interface::Item_id index, items)
{
CGAL::Three::Scene_item& item = *m_entries[index];
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(&item);
if(index == selected_item || selected_items_list.contains(index))
{
item.selection_changed(true);
}
else
{
item.selection_changed(false);
}
if(group ||item.visible())
{
if( group || (!with_names && item.renderingMode() == FlatPlusEdges )
|| item.renderingMode() == Wireframe
|| item.renderingMode() == PointsPlusNormals)
{
viewer->glDisable(GL_LIGHTING);
viewer->glPointSize(2.f);
viewer->glLineWidth(1.0f);
item.drawEdges(viewer);
}
else{
if( item.renderingMode() == PointsPlusNormals ){
viewer->glDisable(GL_LIGHTING);
viewer->glPointSize(2.f);
viewer->glLineWidth(1.0f);
if(index == selected_item || selected_items_list.contains(index))
{
item.selection_changed(true);
}
else
{
item.selection_changed(false);
}
item.drawEdges(viewer);
}
}
if((item.renderingMode() == Wireframe || item.renderingMode() == PointsPlusNormals )
&& with_names)
{
// read depth buffer at pick location;
float depth = 1.0;
viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
if (depth != 1.0)
{
//add object to list of picked objects;
picked_item_IDs[depth] = index;
}
}
}
}
}
void Scene::renderPointScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
bool with_names)
{
Q_FOREACH(Scene_interface::Item_id index, items)
{
CGAL::Three::Scene_item& item = *m_entries[index];
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(&item);
if(group ||item.visible())
{
if(item.renderingMode() == Points && with_names) {
viewer->glClearDepth(1.0);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
if(group || item.renderingMode() == Points ||
(item.renderingMode() == PointsPlusNormals) ||
(item.renderingMode() == ShadedPoints))
{
viewer->glDisable(GL_LIGHTING);
viewer->glPointSize(3.0f);
viewer->glLineWidth(1.0f);
item.drawPoints(viewer);
}
if(item.renderingMode() == Points && with_names) {
// read depth buffer at pick location;
float depth = 1.0;
viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
if (depth != 1.0)
{
//add object to list of picked objects;
picked_item_IDs[depth] = index;
}
}
}
}
}
bool Scene::has_alpha()
{
Q_FOREACH(Scene_item* item, m_entries)
if(item->alpha() != 1.0f)
return true;
return false;
}
void
Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
{
viewer->makeCurrent();
QMap<float, int> picked_item_IDs;
if(with_names)
viewer->glEnable(GL_DEPTH_TEST);
if(!gl_init)
initializeGL(viewer);
renderScene(children, viewer, picked_item_IDs, with_names, -1, false, NULL);
if(!with_names && has_alpha())
{
std::vector<QOpenGLFramebufferObject*> fbos;
std::vector<QOpenGLFramebufferObject*> depth_test;
QColor background = viewer->backgroundColor();
fbos.resize((int)viewer->total_pass());
depth_test.resize((int)viewer->total_pass()-1);
//first pass
fbos[0] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F);
fbos[0]->bind();
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
viewer->glDepthFunc(GL_LESS);
viewer->glEnable(GL_ALPHA_TEST);
viewer->glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
viewer->glClearDepth(1);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderScene(children, viewer, picked_item_IDs, false, 0,false, NULL);
fbos[0]->release();
depth_test[0] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F);
depth_test[0]->bind();
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
viewer->glDepthFunc(GL_LESS);
viewer->glEnable(GL_ALPHA_TEST);
viewer->glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
viewer->glClearDepth(1);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderScene(children, viewer, picked_item_IDs, false, 0,true, NULL);
depth_test[0]->release();
//other passes
for(int i=1; i<viewer->total_pass()-1; ++i)
{
fbos[i] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F);
fbos[i]->bind();
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
viewer->glDepthFunc(GL_LESS);
viewer->glEnable(GL_ALPHA_TEST);
viewer->glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
viewer->glClearDepth(1);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderWireScene(children, viewer, picked_item_IDs, false);
renderPointScene(children, viewer, picked_item_IDs, false);
renderScene(children, viewer, picked_item_IDs, false, i, false, depth_test[i-1]);
fbos[i]->release();
depth_test[i] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F);
depth_test[i]->bind();
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
viewer->glDepthFunc(GL_LESS);
viewer->glEnable(GL_ALPHA_TEST);
viewer->glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
viewer->glClearDepth(1);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderScene(children, viewer, picked_item_IDs, false, i, true, depth_test[i-1]);
depth_test[i]->release();
}
//last pass
fbos[(int)viewer->total_pass()-1] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F);
fbos[(int)viewer->total_pass()-1]->bind();
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
viewer->glDepthFunc(GL_LESS);
viewer->glEnable(GL_ALPHA_TEST);
viewer->glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
viewer->glClearDepth(1);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderScene(children, viewer, picked_item_IDs, false, (int)viewer->total_pass()-1, false, depth_test[(int)viewer->total_pass()-2]);
fbos[(int)viewer->total_pass()-1]->release();
//blending
program.bind();
vao->bind();
viewer->glClearColor(background.redF(),
background.greenF(),
background.blueF(),
1.0f);
viewer->glDisable(GL_DEPTH_TEST);
viewer->glClear(GL_COLOR_BUFFER_BIT);
viewer->glEnable(GL_BLEND);
viewer->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
QMatrix4x4 proj_mat;
proj_mat.setToIdentity();
proj_mat.ortho(-1,1,-1,1,0,1);
program.setUniformValue("projection_matrix", proj_mat);
for(int i=0; i< (int)viewer->total_pass()-1; ++i)
delete depth_test[i];
for(int i = (int)viewer->total_pass()-1; i>=0; --i)
{
viewer->glBindTexture(GL_TEXTURE_2D, fbos[i]->texture());
viewer->glDrawArrays(GL_TRIANGLES,0,static_cast<GLsizei>(6));
delete fbos[i];
}
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
vao->release();
program.release();
}
viewer->glDepthFunc(GL_LEQUAL);
// Wireframe OpenGL drawing
renderWireScene(children, viewer, picked_item_IDs, with_names);
// Points OpenGL drawing
renderPointScene(children, viewer, picked_item_IDs, with_names);
/*{
// Flat/Gouraud OpenGL drawing
for(int index = 0; index < m_entries.size(); ++index)
{
@ -575,7 +969,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
}
}
}
//}*/
if(with_names)
{
QList<float> depths = picked_item_IDs.keys();
@ -784,8 +1178,11 @@ bool Scene::dropMimeData(const QMimeData * /*data*/,
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item(i));
if(group)
Q_FOREACH(Scene_item* child, group->getChildren())
Q_FOREACH(Item_id id, group->getChildren())
{
CGAL::Three::Scene_item* child = item(id);
groups_children << item_id(child);
}
}
// Insure that children of selected groups will not be added twice
Q_FOREACH(int i, selected_items_list)
@ -803,7 +1200,7 @@ bool Scene::dropMimeData(const QMimeData * /*data*/,
if(group)
{
Q_FOREACH(int id, selected_items_list)
if(group->getChildren().contains(item(id)))
if(group->getChildren().contains(id))
{
one_contained = true;
break;
@ -821,6 +1218,7 @@ bool Scene::dropMimeData(const QMimeData * /*data*/,
if(item->parentGroup())
{
item->parentGroup()->removeChild(item);
children.push_back(item_id(item));
}
}
redraw_model();
@ -844,7 +1242,7 @@ void Scene::moveRowUp()
Scene_group_item* group = selected_item->parentGroup();
if(group)
{
int id = group->getChildren().indexOf(selected_item);
int id = group->getChildren().indexOf(item_id(selected_item));
group->moveUp(id);
}
}
@ -852,8 +1250,9 @@ void Scene::moveRowUp()
{
//if not in group
QModelIndex baseId = index_map.key(mainSelectionIndex());
int newId = index_map.value(index(baseId.row()-1, baseId.column(),baseId.parent())) ;
m_entries.move(mainSelectionIndex(), newId);
int newId = children.indexOf(
index_map.value(index(baseId.row()-1, baseId.column(),baseId.parent()))) ;
children.move(children.indexOf(item_id(selected_item)), newId);
}
redraw_model();
setSelectedItem(m_entries.indexOf(selected_item));
@ -869,7 +1268,7 @@ void Scene::moveRowDown()
Scene_group_item* group = selected_item->parentGroup();
if(group)
{
int id = group->getChildren().indexOf(selected_item);
int id = group->getChildren().indexOf(item_id(selected_item));
group->moveDown(id);
}
}
@ -877,7 +1276,8 @@ void Scene::moveRowDown()
{
//if not in group
QModelIndex baseId = index_map.key(mainSelectionIndex());
int newId = index_map.value(index(baseId.row()+1, baseId.column(),baseId.parent())) ;
int newId = children.indexOf(
index_map.value(index(baseId.row()+1, baseId.column(),baseId.parent()))) ;
m_entries.move(mainSelectionIndex(), newId);
}
redraw_model();
@ -1158,9 +1558,10 @@ void Scene::redraw_model()
clear();
index_map.clear();
//fills the model
Q_FOREACH(Scene_item* item, m_entries)
Q_FOREACH(Item_id id, children)
{
organize_items(item, invisibleRootItem(), 0);
organize_items(m_entries[id], invisibleRootItem(), 0);
}
Q_EMIT restoreCollapsedState();
}
@ -1172,7 +1573,12 @@ void Scene::changeGroup(Scene_item *item, CGAL::Three::Scene_group_item *target_
if(item->parentGroup()->isChildLocked(item))
return;
item->parentGroup()->removeChild(item);
children.push_back(item_id(item));
}
else
{
children.removeAll(item_id(item));
}
//add the item to the target group
target_group->addChild(item);
item->moveToGroup(target_group);
@ -1292,8 +1698,9 @@ void Scene::organize_items(Scene_item* item, QStandardItem* root, int loop)
qobject_cast<CGAL::Three::Scene_group_item*>(item);
if(group)
{
Q_FOREACH(Scene_item*child, group->getChildren())
{
Q_FOREACH(Item_id id, group->getChildren())
{
CGAL::Three::Scene_item* child = group->getChild(id);
organize_items(child, list.first(), loop+1);
}
}
@ -1332,6 +1739,8 @@ QList<QModelIndex> Scene::getModelIndexFromId(int id) const
void Scene::addGroup(Scene_group_item* group)
{
connect(this, SIGNAL(drawFinished()), group, SLOT(resetDraw()));
connect(this, SIGNAL(indexErased(Scene_interface::Item_id)),
group, SLOT(adjustIds(Scene_interface::Item_id)));
group->setScene(this);
}
@ -1387,3 +1796,16 @@ void Scene::zoomToPosition(QPoint point, Viewer_interface *viewer)
}
}
}
void Scene::adjustIds(Item_id removed_id)
{
for(int i = 0; i < children.size(); ++i)
{
if(children[i] >= removed_id)
--children[i];
}
for(int i = removed_id; i < numberOfEntries(); ++i)
{
m_entries[i]->setId(i-1);//the signal is emitted before m_entries is amputed from the item, so new id is current id -1.
}
}

View File

@ -24,6 +24,7 @@
#include <CGAL/Three/Scene_group_item.h>
class QEvent;
class QMouseEvent;
class QOpenGLFramebufferObject;
namespace CGAL { namespace Three{ class Viewer_interface;}}
//! This class is not supposed to be used by Plugins, but sometimes you may need access to
@ -190,8 +191,8 @@ public Q_SLOTS:
if(group)
{
QList<int> list;
Q_FOREACH(CGAL::Three::Scene_item* child, group->getChildrenForSelection())
list<<m_entries.indexOf(child);
Q_FOREACH(Item_id id, group->getChildrenForSelection())
list<<id;
l << setSelectedItemsList(list);
}
@ -210,6 +211,8 @@ public Q_SLOTS:
Q_SIGNALS:
//generated automatically by moc
//!Is emitted when the ids of the items are changed.
void indexErased(Scene_interface::Item_id id);
//! Emit this to mark `modelindex` as selected in the Geometric Objects view.
void itemPicked(const QModelIndex& modelindex);
//! Is emitted when a new item is added to the scene.
@ -233,6 +236,7 @@ Q_SIGNALS:
void drawFinished();
private Q_SLOTS:
// Casts a selection ray and calls the item function select.
void adjustIds(Scene_interface::Item_id removed_id);
void setSelectionRay(double, double, double, double, double, double);
void callDraw(){ CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->update();}
void s_itemAboutToBeDestroyed(CGAL::Three::Scene_item *);
@ -241,12 +245,24 @@ private:
* to its current renderingMode. If with_names is true, uses
* the OpenGL mode GL_WITH_NAMES, essentially used for the picking.*/
void draw_aux(bool with_names, CGAL::Three::Viewer_interface*);
bool has_alpha();
void renderScene(const QList<Scene_interface::Item_id > &items,
CGAL::Three::Viewer_interface* viewer, QMap<float, int> &picked_item_IDs, bool with_names,
int pass, bool writing_depth,
QOpenGLFramebufferObject* fbo);
void renderWireScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer, QMap<float, int> &picked_item_IDs, bool with_names);
void renderPointScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
bool with_names);
// Re-draw the hierarchy of the view.
void organize_items(CGAL::Three::Scene_item* item, QStandardItem *root, int loop);
// List of Scene_items.
typedef QList<CGAL::Three::Scene_item*> Entries;
//List containing all the scene_items.
Entries m_entries;
QList<Item_id> children;
// Index of the currently selected item.
int selected_item;
//List of indices of the currently selected items.
@ -259,6 +275,11 @@ private:
QPoint picked_pixel;
bool gl_init;
QMap<QModelIndex, int> index_map;
float points[18];
float uvs[12];
QOpenGLShaderProgram program;
QOpenGLVertexArrayObject* vao;
mutable QOpenGLBuffer vbo[2];
}; // end class Scene

View File

@ -119,7 +119,7 @@ public:
void drawEdges(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE;
void drawPoints(CGAL::Three::Viewer_interface * viewer) const Q_DECL_OVERRIDE;
//When selecting a c3t3 item, we don't want to select its children, so we can still apply Operations to it
QList<Scene_item*> getChildrenForSelection() const Q_DECL_OVERRIDE { return QList<Scene_item*>(); }
QList<Scene_interface::Item_id> getChildrenForSelection() const Q_DECL_OVERRIDE { return QList<Scene_interface::Item_id>(); }
public:
QMenu* contextMenu() Q_DECL_OVERRIDE;
void copyProperties(Scene_item *) Q_DECL_OVERRIDE;

View File

@ -14,16 +14,16 @@ Scene_group_item::Scene_group_item(QString name, int nb_vbos, int nb_vaos )
bool Scene_group_item::isFinite() const
{
Q_FOREACH(Scene_item *item, children)
if(!item->isFinite()){
return false;
}
return true;
Q_FOREACH(Scene_interface::Item_id id, children)
if(!getChild(id)->isFinite()){
return false;
}
return true;
}
bool Scene_group_item::isEmpty() const {
Q_FOREACH(Scene_item *item, children)
if(!item->isEmpty()){
Q_FOREACH(Scene_interface::Item_id id, children)
if(!getChild(id)->isEmpty()){
return true;
}
return true;
@ -37,8 +37,8 @@ Scene_group_item::Bbox Scene_group_item::bbox() const
bool Scene_group_item::supportsRenderingMode(RenderingMode m) const {
Q_FOREACH(Scene_item* item, children)
if(!item->supportsRenderingMode(m))
Q_FOREACH(Scene_interface::Item_id id, children)
if(!getChild(id)->supportsRenderingMode(m))
return false;
return true;
@ -53,38 +53,50 @@ QString Scene_group_item::toolTip() const {
void Scene_group_item::addChild(Scene_item* new_item)
{
if(!children.contains(new_item))
if(!children.contains(scene->item_id(new_item)))
{
children.append(new_item);
children.append(scene->item_id(new_item));
update_group_number(new_item, has_group+1);
}
}
void Scene_group_item::addChild(Scene_interface::Item_id new_id)
{
if(!children.contains(new_id))
{
children.append(new_id);
update_group_number(getChild(new_id), has_group+1);
}
}
void Scene_group_item::update_group_number(Scene_item * new_item, int n)
{
Scene_group_item* group =
qobject_cast<Scene_group_item*>(new_item);
if(group)
Q_FOREACH(Scene_item* child, group->getChildren())
update_group_number(child,n+1);
Q_FOREACH(Scene_interface::Item_id id, group->getChildren()){
update_group_number(getChild(id),n+1);
}
new_item->has_group = n;
}
void Scene_group_item::setColor(QColor c)
{
Scene_item::setColor(c);
Q_FOREACH(Scene_item* child, children)
Q_FOREACH(Scene_interface::Item_id id, children)
{
child->setColor(c);
getChild(id)->setColor(c);
}
}
void Scene_group_item::setRenderingMode(RenderingMode m)
{
Scene_item::setRenderingMode(m);
Q_FOREACH(Scene_item* child, children)
Q_FOREACH(Scene_interface::Item_id id, children)
{
Scene_item* child = getChild(id);
if(child->supportsRenderingMode(m))
child->setRenderingMode(m);
}
@ -93,8 +105,9 @@ void Scene_group_item::setRenderingMode(RenderingMode m)
void Scene_group_item::setVisible(bool b)
{
Scene_item::setVisible(b);
Q_FOREACH(Scene_item* child, children)
Q_FOREACH(Scene_interface::Item_id id, children)
{
Scene_item* child = getChild(id);
child->setVisible(b);
child->itemChanged();
}
@ -123,7 +136,9 @@ void Scene_group_item::moveUp(int i)
void Scene_group_item::draw(CGAL::Three::Viewer_interface* viewer) const {
if(viewer->inDrawWithNames() || already_drawn ) return;
Q_FOREACH(Scene_item* child, children) {
Q_FOREACH(Scene_interface::Item_id id, children)
{
Scene_item* child = getChild(id);
if(!child->visible()) continue;
switch(child->renderingMode()) {
case Flat:
@ -153,7 +168,9 @@ void Scene_group_item::draw(CGAL::Three::Viewer_interface* viewer) const {
void Scene_group_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const
{
if(viewer->inDrawWithNames() || already_drawn ) return;
Q_FOREACH(Scene_item* child, children) {
Q_FOREACH(Scene_interface::Item_id id, children)
{
Scene_item* child = getChild(id);
if(!child->visible()) continue;
switch(child->renderingMode()) {
case FlatPlusEdges:
@ -183,7 +200,9 @@ void Scene_group_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const
void Scene_group_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const
{
if(viewer->inDrawWithNames() || already_drawn ) return;
Q_FOREACH(Scene_item* child, children) {
Q_FOREACH(Scene_interface::Item_id id, children)
{
Scene_item* child = getChild(id);
if(!child->visible()) continue;
switch(child->renderingMode()) {
case Points:
@ -210,22 +229,101 @@ void Scene_group_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const
already_drawn = true;
}
void Scene_group_item::renderChildren(Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
const QPoint& picked_pixel,
bool with_names)
{
Q_FOREACH(Scene_interface::Item_id id, children){
if(with_names) {
viewer->glClearDepth(1.0);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
if(id == scene->mainSelectionIndex()|| scene->selectionIndices().contains(id))
{
getChild(id)->selection_changed(true);
}
else
{
getChild(id)->selection_changed(false);
}
if(getChild(id)->visible() &&
(getChild(id)->renderingMode() == Flat ||
getChild(id)->renderingMode() == FlatPlusEdges ||
getChild(id)->renderingMode() == Gouraud))
{
getChild(id)->draw(viewer);
}
if(getChild(id)->visible() &&
(getChild(id)->renderingMode() == FlatPlusEdges
|| getChild(id)->renderingMode() == Wireframe
|| getChild(id)->renderingMode() == PointsPlusNormals))
{
getChild(id)->drawEdges(viewer);
}
if(getChild(id)->visible() &&
(getChild(id)->renderingMode() == Points ||
(getChild(id)->renderingMode() == PointsPlusNormals) ||
(getChild(id)->renderingMode() == ShadedPoints)))
{
getChild(id)->drawPoints(viewer);
}
if(with_names) {
// read depth buffer at pick location;
float depth = 1.0;
viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
if (depth != 1.0)
{
//add object to list of picked objects;
picked_item_IDs[depth] = id;
}
}
}
}
void Scene_group_item::lockChild(Scene_item *child)
{
if(!children.contains(child))
lockChild(scene->item_id(child));
}
void Scene_group_item::lockChild(Scene_interface::Item_id id)
{
if(!children.contains(id))
return;
child->setProperty("lock", true);
getChild(id)->setProperty("lock", true);
}
void Scene_group_item::unlockChild(Scene_interface::Item_id id)
{
if(!children.contains(id))
return;
getChild(id)->setProperty("lock", false);
}
void Scene_group_item::unlockChild(Scene_item *child)
{
if(!children.contains(child))
return;
child->setProperty("lock", false);
unlockChild(scene->item_id(child));
}
bool Scene_group_item::isChildLocked(Scene_interface::Item_id id)
{
if(!children.contains(id)
|| (!getChild(id)->property("lock").toBool()) )
return false;
return true;
}
bool Scene_group_item::isChildLocked(Scene_item *child)
{
if(!children.contains(child)
|| (!child->property("lock").toBool()) )
return false;
return true;
return isChildLocked(scene->item_id(child));
}
void Scene_group_item::setAlpha(int )
{
Q_FOREACH(Scene_interface::Item_id id, children)
{
scene->item(id)->setAlpha(static_cast<int>(alpha()*255));
}
}

View File

@ -229,3 +229,15 @@ void CGAL::Three::Scene_item::compute_diag_bbox()const
);
}
void Scene_item::setId(int id) {cur_id = id; }
int Scene_item::getId() const { return cur_id; }
float Scene_item::alpha() const
{
return 1.0f;
}
void Scene_item::setAlpha(int )
{
}

View File

@ -64,7 +64,7 @@ public:
void smooth(std::vector<Point_3>& polyline);
//When selecting a polylineitem, we don't want to select its children, so we can still apply Operations to it
QList<Scene_item*> getChildrenForSelection() const { return QList<Scene_item*>(); }
QList<Scene_interface::Item_id> getChildrenForSelection() const { return QList<Scene_interface::Item_id>(); }
public Q_SLOTS:
virtual void invalidateOpenGLBuffers();

View File

@ -11,6 +11,9 @@
#include <QVariant>
#include <QMessageBox>
#include <QMenu>
#include <QWidgetAction>
#include <QSlider>
#include <QOpenGLFramebufferObject>
//#include <CGAL/boost/graph/properties_Surface_mesh.h>
#include <CGAL/Surface_mesh.h>
@ -91,6 +94,7 @@ struct Scene_surface_mesh_item_priv{
vertices_displayed = false;
edges_displayed = false;
faces_displayed = false;
alphaSlider = NULL;
}
Scene_surface_mesh_item_priv(SMesh* sm, Scene_surface_mesh_item *parent):
@ -102,10 +106,13 @@ struct Scene_surface_mesh_item_priv{
vertices_displayed = false;
edges_displayed = false;
faces_displayed = false;
alphaSlider = NULL;
}
~Scene_surface_mesh_item_priv()
{
if(alphaSlider)
delete alphaSlider;
if(smesh_)
{
delete smesh_;
@ -199,6 +206,7 @@ struct Scene_surface_mesh_item_priv{
unsigned int number_of_degenerated_faces;
int genus;
bool self_intersect;
QSlider* alphaSlider;
};
const char* aabb_property_name = "Scene_surface_mesh_item aabb tree";
@ -313,7 +321,13 @@ void Scene_surface_mesh_item_priv::addFlatData(Point p, EPICK::Vector_3 n, CGAL:
void Scene_surface_mesh_item_priv::compute_elements()
{
QApplication::setOverrideCursor(Qt::WaitCursor);
if(!alphaSlider)
{
alphaSlider = new QSlider(::Qt::Horizontal);
alphaSlider->setMinimum(0);
alphaSlider->setMaximum(255);
alphaSlider->setValue(255);
}
smooth_vertices.clear();
smooth_normals.clear();
flat_vertices.clear();
@ -652,6 +666,7 @@ void Scene_surface_mesh_item_priv::initializeBuffers(CGAL::Three::Viewer_interfa
void Scene_surface_mesh_item::draw(CGAL::Three::Viewer_interface *viewer) const
{
viewer->glShadeModel(GL_SMOOTH);
QOpenGLFramebufferObject* fbo = viewer->depthPeelingFbo();
if(!are_buffers_filled)
{
d->compute_elements();
@ -664,10 +679,16 @@ void Scene_surface_mesh_item::draw(CGAL::Three::Viewer_interface *viewer) const
if(renderingMode() == Gouraud)
{
vaos[Scene_surface_mesh_item_priv::Smooth_facets]->bind();
if(is_selected)
d->program->setAttributeValue("is_selected", true);
else
d->program->setAttributeValue("is_selected", false);
d->program->setAttributeValue("is_selected", is_selected);
d->program->setUniformValue("comparing", viewer->currentPass() > 0);;
d->program->setUniformValue("width", viewer->width()*1.0f);
d->program->setUniformValue("height", viewer->height()*1.0f);
d->program->setUniformValue("near", (float)viewer->camera()->zNear());
d->program->setUniformValue("far", (float)viewer->camera()->zFar());
d->program->setUniformValue("writing", viewer->isDepthWriting());
d->program->setUniformValue("alpha", alpha());
if( fbo)
viewer->glBindTexture(GL_TEXTURE_2D, fbo->texture());
if(!d->has_vcolors)
d->program->setAttributeValue("colors", this->color());
viewer->glDrawElements(GL_TRIANGLES, static_cast<GLuint>(d->idx_data_.size()),
@ -683,6 +704,15 @@ void Scene_surface_mesh_item::draw(CGAL::Three::Viewer_interface *viewer) const
d->program->setAttributeValue("is_selected", false);
if(!d->has_fcolors)
d->program->setAttributeValue("colors", this->color());
d->program->setUniformValue("comparing", viewer->currentPass() > 0);
d->program->setUniformValue("width", viewer->width()*1.0f);
d->program->setUniformValue("height", viewer->height()*1.0f);
d->program->setUniformValue("near", (float)viewer->camera()->zNear());
d->program->setUniformValue("far", (float)viewer->camera()->zFar());
d->program->setUniformValue("writing", viewer->isDepthWriting());
d->program->setUniformValue("alpha", alpha());
if( fbo)
viewer->glBindTexture(GL_TEXTURE_2D, fbo->texture());
viewer->glDrawArrays(GL_TRIANGLES,0,static_cast<GLsizei>(d->nb_flat/3));
vaos[Scene_surface_mesh_item_priv::Flat_facets]->release();
}
@ -1719,6 +1749,15 @@ QMenu* Scene_surface_mesh_item::contextMenu()
actionZoomToId->setObjectName("actionZoomToId");
connect(actionZoomToId, &QAction::triggered,
this, &Scene_surface_mesh_item::zoomToId);
QMenu *container = new QMenu(tr("Alpha value"));
QWidgetAction *sliderAction = new QWidgetAction(0);
sliderAction->setDefaultWidget(d->alphaSlider);
connect(d->alphaSlider, &QSlider::valueChanged,
[this](){redraw();});
container->addAction(sliderAction);
menu->addMenu(container);
setProperty("menu_changed", true);
menu->setProperty(prop_name, true);
}
@ -1970,4 +2009,19 @@ bool Scene_surface_mesh_item::shouldDisplayIds(CGAL::Three::Scene_item *current_
return this == current_item;
}
float Scene_surface_mesh_item::alpha() const
{
if(!d->alphaSlider)
return 1.0f;
return (float)d->alphaSlider->value() / 255.0f;
}
void Scene_surface_mesh_item::setAlpha(int alpha)
{
if(!d->alphaSlider)
d->compute_elements();
d->alphaSlider->setValue(alpha);
redraw();
}
QSlider* Scene_surface_mesh_item::alphaSlider() { return d->alphaSlider; }

View File

@ -20,8 +20,8 @@
#include "properties.h"
class QSlider;
struct Scene_surface_mesh_item_priv;
class SCENE_SURFACE_MESH_ITEM_EXPORT Scene_surface_mesh_item
: public CGAL::Three::Scene_item,
public CGAL::Three::Scene_zoomable_item_interface,
@ -129,6 +129,9 @@ public:
void printAllIds(CGAL::Three::Viewer_interface*) Q_DECL_OVERRIDE;
bool shouldDisplayIds(CGAL::Three::Scene_item *current_item) const Q_DECL_OVERRIDE;
bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface*)const Q_DECL_OVERRIDE;
float alpha() const Q_DECL_OVERRIDE;
void setAlpha(int alpha) Q_DECL_OVERRIDE;
QSlider* alphaSlider();
Q_SIGNALS:
void item_is_about_to_be_changed();

View File

@ -38,6 +38,18 @@ public:
QTimer messageTimer;
QOpenGLFunctions_4_3_Compatibility* _recentFunctions;
bool is_2d_selection_mode;
// D e p t h P e e l i n g
// \param pass the current pass in the Depth Peeling (transparency) algorithm.
// -1 means that no depth peeling is applied.
// \param writing_depth means that the color of the faces will be drawn in a grayscale
// according to the depth of the fragment in the shader. It is used by the transparency.
// \param fbo contains the texture used by the Depth Peeling algorithm.
// Should be NULL if pass <= 0;
int current_pass;
bool writing_depth;
int total_pass;
int current_total_pass;
QOpenGLFramebufferObject* dp_fbo;
//! The buffers used to draw the axis system
QOpenGLBuffer buffer;
@ -88,6 +100,7 @@ Viewer::Viewer(QWidget* parent, bool antialiasing)
d->shader_programs.resize(NB_OF_PROGRAMS);
d->textRenderer = new TextRenderer();
d->is_2d_selection_mode = false;
d->total_pass = 4;
connect( d->textRenderer, SIGNAL(sendMessage(QString,int)),
this, SLOT(printMessage(QString,int)) );
connect(&d->messageTimer, SIGNAL(timeout()), SLOT(hideMessage()));
@ -434,6 +447,7 @@ void Viewer_impl::draw_aux(bool with_names, Viewer* viewer)
{
if(scene == 0)
return;
current_total_pass = viewer->inFastDrawing() ? total_pass/2 : total_pass;
viewer->glLineWidth(1.0f);
viewer->glPointSize(2.f);
viewer->glEnable(GL_POLYGON_OFFSET_FILL);
@ -1025,3 +1039,18 @@ void Viewer::setStaticImage(QImage image) { d->static_image = image; }
const QImage& Viewer:: staticImage() const { return d->static_image; }
void Viewer::setCurrentPass(int pass) { d->current_pass = pass; }
void Viewer::setDepthWriting(bool writing_depth) { d->writing_depth = writing_depth; }
void Viewer::setDepthPeelingFbo(QOpenGLFramebufferObject* fbo) { d->dp_fbo = fbo; }
int Viewer::currentPass()const{ return d->current_pass; }
bool Viewer::isDepthWriting()const{ return d->writing_depth; }
QOpenGLFramebufferObject *Viewer::depthPeelingFbo(){ return d->dp_fbo; }
float Viewer::total_pass()
{
return d->current_total_pass * 1.0f;
}
#include "Viewer.moc"

View File

@ -139,7 +139,13 @@ protected:
public:
QOpenGLFunctions_4_3_Compatibility* openGL_4_3_functions() Q_DECL_OVERRIDE;
void setCurrentPass(int pass) Q_DECL_OVERRIDE;
void setDepthWriting(bool writing_depth) Q_DECL_OVERRIDE;
void setDepthPeelingFbo(QOpenGLFramebufferObject *fbo) Q_DECL_OVERRIDE;
int currentPass()const Q_DECL_OVERRIDE;
bool isDepthWriting()const Q_DECL_OVERRIDE;
QOpenGLFramebufferObject* depthPeelingFbo()Q_DECL_OVERRIDE;
float total_pass()Q_DECL_OVERRIDE;
}; // end class Viewer

View File

@ -7,42 +7,64 @@ uniform highp vec4 light_pos;
uniform highp vec4 light_diff;
uniform highp vec4 light_spec;
uniform highp vec4 light_amb;
uniform highp float spec_power ;
uniform highp float spec_power;
uniform int is_two_side;
uniform bool is_selected;
uniform bool is_clipbox_on;
void main(void) {
uniform highp float near;
uniform highp float far;
uniform highp float width;
uniform highp float height;
uniform bool comparing;
uniform bool writing;
uniform sampler2D sampler;
if(is_clipbox_on)
if(dist[0]>0 ||
dist[1]>0 ||
dist[2]>0 ||
dist[3]>0 ||
dist[4]>0 ||
dist[5]>0)
discard;
highp vec3 L = light_pos.xyz - fP.xyz;
highp vec3 V = -fP.xyz;
highp vec3 N;
if(fN == highp vec3(0.0,0.0,0.0))
N = highp vec3(0.0,0.0,0.0);
else
N = normalize(fN);
L = normalize(L);
V = normalize(V);
highp vec3 R = reflect(-L, N);
vec4 diffuse;
if(is_two_side == 1)
diffuse = abs(dot(N,L)) * light_diff * color;
else
diffuse = max(dot(N,L), 0.0) * light_diff * color;
highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec;
vec4 ret_color = vec4((color*light_amb).xyz + diffuse.xyz + specular.xyz,1);
if(is_selected)
gl_FragColor = vec4(ret_color.r+70.0/255.0, ret_color.g+70.0/255.0, ret_color.b+70.0/255.0, 1.0);
else
gl_FragColor = ret_color;
highp float depth(float z)
{
return (2 * near) / (far + near - z * (far - near));
}
void main(void) {
if(is_clipbox_on)
if(dist[0]>0 ||
dist[1]>0 ||
dist[2]>0 ||
dist[3]>0 ||
dist[4]>0 ||
dist[5]>0)
discard;
float alpha = color.a;
float d = depth(gl_FragCoord.z);
float test = texture2D(sampler, vec2(gl_FragCoord.x/width, gl_FragCoord.y/height)).r;
if(comparing && d <= test)
discard;
if(writing)
gl_FragColor = vec4(d,d,d,1.0);
else
{
vec4 my_color = vec4(color.xyz, 1.0);
highp vec3 L = light_pos.xyz - fP.xyz;
highp vec3 V = -fP.xyz;
highp vec3 N;
if(fN == highp vec3(0.0,0.0,0.0))
N = highp vec3(0.0,0.0,0.0);
else
N = normalize(fN);
L = normalize(L);
V = normalize(V);
highp vec3 R = reflect(-L, N);
vec4 diffuse;
if(is_two_side == 1)
diffuse = abs(dot(N,L)) * light_diff * color;
else
diffuse = max(dot(N,L), 0.0) * light_diff * my_color;
highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec;
vec4 ret_color = vec4((my_color*light_amb).xyz + diffuse.xyz + specular.xyz,1);
if(is_selected)
gl_FragColor = vec4(ret_color.r+70.0/255.0, ret_color.g+70.0/255.0, ret_color.b+70.0/255.0, alpha);
else
gl_FragColor = vec4(ret_color.xyz, alpha);
}
}

View File

@ -1,7 +1,7 @@
#version 120
attribute highp vec4 vertex;
attribute highp vec3 normals;
attribute highp vec3 colors;
attribute highp vec4 colors;
uniform highp mat4 mvp_matrix;
uniform highp mat4 mv_matrix;
varying highp vec4 fP;
@ -11,6 +11,7 @@ varying highp float dist[6];
uniform bool is_clipbox_on;
uniform highp mat4x4 clipbox1;
uniform highp mat4x4 clipbox2;
uniform highp float alpha;
void compute_distances(void)
{
@ -32,8 +33,8 @@ void compute_distances(void)
void main(void)
{
color = vec4(colors, 1.0);
color = vec4(colors.xyz, alpha);
//
if(is_clipbox_on)
compute_distances();
fP = mv_matrix * vertex;

View File

@ -52,28 +52,48 @@ public :
//!Sets the scene;
void setScene(Scene_interface* s) { scene = s; }
//!Returns false to avoid disturbing the BBox of the scene.
bool isFinite() const;
bool isFinite() const Q_DECL_OVERRIDE;
//!Returns true to avoid disturbing the BBox of the scene.
bool isEmpty() const ;
bool isEmpty() const Q_DECL_OVERRIDE;
/*!
* \brief Locks a child
*
* A locked child cannot be moved out of the group nor can it be deleted.
* Use it to prevent a child to be destroyed without its parent.
*/
void lockChild(CGAL::Three::Scene_item*);
/*!
* \brief Unlocks a child
*
* @see lockChild()
*/
void unlockChild(CGAL::Three::Scene_item*);
/*!
* \brief Tells if a child is locked.
* \return true if the child is locked.
* @see lockChild()
*/
bool isChildLocked(CGAL::Three::Scene_item*);
* \brief Locks a child
*
* A locked child cannot be moved out of the group nor can it be deleted.
* Use it to prevent a child to be destroyed without its parent.
*/
void lockChild(CGAL::Three::Scene_item*);
/*!
* \brief Locks a child
*
* A locked child cannot be moved out of the group nor can it be deleted.
* Use it to prevent a child to be destroyed without its parent.
*/
void lockChild(Scene_interface::Item_id id);
/*!
* \brief Unlocks a child
*
* @see lockChild()
*/
void unlockChild(CGAL::Three::Scene_item*);
/*!
* \brief Unlocks a child
*
* @see lockChild()
*/
void unlockChild(Scene_interface::Item_id id);
/*!
* \brief Tells if a child is locked.
* \return true if the child is locked.
* @see lockChild()
*/
bool isChildLocked(CGAL::Three::Scene_item*);
/*!
* \brief Tells if a child is locked.
* \return true if the child is locked.
* @see lockChild()
*/
bool isChildLocked(Scene_interface::Item_id id);
//!Returns if the group_item is currently expanded or collapsed in the Geometric Objects list.
//! True means expanded, false means collapsed.
//! @see isExpanded().
@ -83,15 +103,15 @@ public :
//! @see isExpanded().
void setExpanded(bool);
//!Returns an empty Bbox to avoid disturbing the Bbox of the scene.
Bbox bbox() const;
Bbox bbox() const Q_DECL_OVERRIDE;
//!Not supported.
Scene_item* clone() const {return 0;}
Scene_item* clone() const Q_DECL_OVERRIDE {return 0;}
//! Indicates if the rendering mode is supported.
//! \returns true for all rendering modes that are shared by
//! all of the children.
bool supportsRenderingMode(RenderingMode m) const;
bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE;
//!\returns a string containing the number of children.
QString toolTip() const;
QString toolTip() const Q_DECL_OVERRIDE;
/// Draw functions
/// Scene_group_item's children are not drawn by the scene, they are drawn by the group.
@ -102,32 +122,52 @@ public :
//! and `Scene_item::drawPoints` for each child if its current
//! rendering mode is adequat.
//! @see #RenderingMode
virtual void draw(CGAL::Three::Viewer_interface*) const;
virtual void draw(CGAL::Three::Viewer_interface*) const Q_DECL_OVERRIDE;
//!\brief draws all the children
//!
//! Calls `Scene_item::drawEdges()`, then calls `Scene_item::draw()`
//! and `Scene_item::drawPoints` for each child if its current
//! rendering mode is adequat.
//! @see #RenderingMode
virtual void drawEdges(CGAL::Three::Viewer_interface*) const;
virtual void drawEdges(CGAL::Three::Viewer_interface*) const Q_DECL_OVERRIDE;
//!\brief draws all the children
//!
//! Calls `Scene_item::drawPoints()`, then calls `Scene_item::draw()`
//! and `Scene_item::drawEdges()` for each child if its current
//! rendering mode is adequat.
//! @see #RenderingMode
virtual void drawPoints(CGAL::Three::Viewer_interface*) const;
virtual void drawPoints(CGAL::Three::Viewer_interface*) const Q_DECL_OVERRIDE;
//!
//! \brief deals with the rendering, selecting and picking of
//! the group's children.
//!
//! \param picked_item_IDs the depth-index map
//! \param picked_pixel the screen point that has been picked.
//! \param with_names should be `true` if a picking is being performed.
//!
virtual void renderChildren(Viewer_interface *,
QMap<float, int>& picked_item_IDs, const QPoint &picked_pixel,
bool with_names);
///@}
//!Adds a CGAL::Three::Scene_item* to the list of children.
//!@see getChildren() @see removeChild()
void addChild(Scene_item* new_item);
//!Adds a CGAL::Three::Scene_item* to the list of children from its id.
//! //!@see getChildren() @see removeChild()
void addChild(Scene_interface::Item_id new_id);
//! \brief getChild gives access to the Scene_item of the wanted index.
//! \returns the `CGAL::Three::Scene_item` which index is `id`.
//!
Scene_item* getChild(Scene_interface::Item_id id) { return scene->item(id);}
Scene_item* getChild(Scene_interface::Item_id id) const{ return scene->item(id);}
//!Sets all the children to the specified color.
void setColor(QColor c);
void setColor(QColor c) Q_DECL_OVERRIDE;
//!Sets all the children in the specified rendering mode.
void setRenderingMode(RenderingMode m);
void setRenderingMode(RenderingMode m) Q_DECL_OVERRIDE;
//!Sets all the children to the specified visibility.
void setVisible(bool b);
void setVisible(bool b) Q_DECL_OVERRIDE;
//!Sets all the children in points mode.
void setPointsMode() {
setRenderingMode(Points);
@ -160,11 +200,14 @@ public :
void setPointsPlusNormalsMode(){
setRenderingMode(PointsPlusNormals);
}
//!Sets the alpha value for the froup and all its children.
virtual void setAlpha(int) Q_DECL_OVERRIDE;
//! \brief Returns a list of all the direct children.
//!
//! Only returns children that have this item as a parent.
//! Children of these children are not returned.
QList<Scene_item*> getChildren() const {return children;}
QList<Scene_interface::Item_id> getChildren() const {return children;}
//! \brief getChildrenForSelection returns the list of
//! children to select along with the group.
@ -173,7 +216,7 @@ public :
//! this function defines which of its children will be added too.
//! Typically overriden to allow applying an operation from the
//! Operation menu only to the parent item and not to its children.
virtual QList<Scene_item*> getChildrenForSelection() const {return children;}
virtual QList<Scene_interface::Item_id> getChildrenForSelection() const {return children;}
//!Removes a Scene_item from the list of children.
//!@see getChildren() @see addChild()
void removeChild( Scene_item* item)
@ -182,7 +225,13 @@ public :
return;
update_group_number(item,0);
item->moveToGroup(0);
children.removeOne(item);
children.removeOne(scene->item_id(item));
}
//!Removes a Scene_item from the list of children using its index.
//!@see getChildren() @see addChild()
void removeChild( Scene_interface::Item_id id)
{
removeChild(scene->item(id));
}
//!Moves a child up in the list.
void moveUp(int);
@ -199,13 +248,13 @@ public Q_SLOTS:
//! `draw()` function.
void resetDraw() { already_drawn = false;}
private:
void update_group_number(Scene_item*new_item, int n);
void update_group_number(Scene_item* new_item, int n);
bool expanded;
mutable bool already_drawn;
protected:
Scene_interface *scene;
//!Contains a reference to all the children of this group.
QList<Scene_item*> children;
QList<Scene_interface::Item_id> children;
}; //end of class Scene_group_item

View File

@ -235,6 +235,15 @@ public:
//! the Operations menu, actions to save or clone the item if it is supported
//! and any contextual action for the item.
virtual QMenu* contextMenu();
//!
//! \brief setId informs the item of its current index in the scene entries.
//!
void setId(int id);
//!
//! \brief getId returns the current index of this item in the scene entries.
//!
int getId()const;
//!Handles key press events.
virtual bool keyPressEvent(QKeyEvent*){return false;}
@ -354,7 +363,15 @@ public Q_SLOTS:
//!This might be needed as items are not always deleted right away by Qt and this behaviour may cause a simily
//!memory leak, for example when multiple items are created at the same time.
virtual void itemAboutToBeDestroyed(Scene_item*);
//!Returns the alpha value for the item.
//! Must be called within a valid openGl context.
virtual float alpha() const;
//! Sets the value of the aplha Slider for this item.
//!
//! Must be overriden;
//! \param alpha must be between 0 and 255
virtual void setAlpha(int alpha);
//!Selects a point through raycasting.
virtual void select(double orig_x,
double orig_y,
@ -432,6 +449,7 @@ protected:
/*! Contains the VAOs.
*/
std::vector<QOpenGLVertexArrayObject*> vaos;
int cur_id;
//!Adds a VAO to the Map.
void addVaos(int i)
{

View File

@ -37,6 +37,7 @@ class QImage;
class QMouseEvent;
class QKeyEvent;
class QOpenGLShaderProgram;
class QOpenGLFramebufferObject;
class TextRenderer;
class TextListItem;
@ -213,6 +214,9 @@ public:
//! Returns the static image to be displayed in 2D selection mode.
virtual const QImage& staticImage() const = 0;
//!The number of passes that are performed for the scene transparency.
//! Customizable from the MainWindow or the SubViewer menu.
virtual float total_pass() = 0;
Q_SIGNALS:
//!Emit this to signal that the `id`th item has been picked.
void selected(int id);
@ -255,6 +259,13 @@ public:
//! @returns a pointer to an initialized QOpenGLFunctions_4_3_Compatibility if `isOpenGL_4_3()` is `true`
//! @returns NULL if `isOpenGL_4_3()` is `false`
virtual QOpenGLFunctions_4_3_Compatibility* openGL_4_3_functions() = 0;
virtual void setCurrentPass(int pass) = 0;
virtual void setDepthWriting(bool writing_depth) = 0;
virtual void setDepthPeelingFbo(QOpenGLFramebufferObject* fbo) = 0;
virtual int currentPass()const = 0;
virtual bool isDepthWriting()const = 0;
virtual QOpenGLFramebufferObject* depthPeelingFbo() = 0;
}; // end class Viewer_interface
}
}