Commit e7cc45dd authored by Jan Möbius's avatar Jan Möbius

Merge branch 'fixOpenVolumeMeshCorePicking' into 'master'

Fix open volume mesh core picking

See merge request !12
parents 09343ea1 2e0db28f
......@@ -263,21 +263,21 @@ void VolumeMeshBufferManager<VolumeMesh>::calculateVertexDeclaration()
if (mPrimitiveMode != PM_NONE) //should always be the case
{
mVertexDeclaration.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_POSITION, reinterpret_cast<GLuint*>(currentOffset));
mVertexDeclaration.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_POSITION, reinterpret_cast<GLuint*>(currentOffset),0, 0, mBuffer);
currentOffset += 3*sizeof(float);
}
if (mNormalMode != NM_NONE)
{
mNormalOffset = currentOffset;
mVertexDeclaration.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_NORMAL, reinterpret_cast<GLuint*>(currentOffset));
mVertexDeclaration.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_NORMAL, reinterpret_cast<GLuint*>(currentOffset),0, 0, mBuffer);
currentOffset += 3*sizeof(float);
}
if ((mColorMode != CM_NO_COLORS) || mShowIrregularInnerEdges || mShowIrregularOuterValence2Edges)
{
mColorOffset = currentOffset;
mVertexDeclaration.addElement(GL_UNSIGNED_BYTE, 4, ACG::VERTEX_USAGE_COLOR, reinterpret_cast<GLuint*>(currentOffset));
mVertexDeclaration.addElement(GL_UNSIGNED_BYTE, 4, ACG::VERTEX_USAGE_COLOR, reinterpret_cast<GLuint*>(currentOffset),0, 0, mBuffer);
currentOffset += 4*sizeof(char);
}
......@@ -287,7 +287,7 @@ void VolumeMeshBufferManager<VolumeMesh>::calculateVertexDeclaration()
unsigned char numOfCoords = 0;
if (mTexCoordMode == TCM_SINGLE_2D)
numOfCoords = 2;
mVertexDeclaration.addElement(GL_FLOAT, numOfCoords, ACG::VERTEX_USAGE_TEXCOORD, reinterpret_cast<GLuint*>(currentOffset));
mVertexDeclaration.addElement(GL_FLOAT, numOfCoords, ACG::VERTEX_USAGE_TEXCOORD, reinterpret_cast<GLuint*>(currentOffset),0, 0, mBuffer);
currentOffset += numOfCoords * sizeof(float);
}
......
......@@ -214,6 +214,16 @@ private:
void pickFaces(GLState& _state, unsigned int _offset);
/// pick cells
void pickCells(GLState& _state, unsigned int _offset);
/// pick vertices using opengl compatibility profile
void pickVerticesCompat(GLState& _state);
/// pick edges using opengl compatibility profile
void pickEdgesCompat(GLState& _state, unsigned int _offset);
/// pick faces using opengl compatibility profile
void pickFacesCompat(GLState& _state, unsigned int _offset);
/// pick cells using opengl compatibility profile
void pickCellsCompat(GLState& _state, unsigned int _offset);
/// picking using opengl compatibility profile
void pickCompat(GLState& _state, PickTarget _target);
/// updates face normals
void update_face_normals();
......@@ -284,6 +294,7 @@ private:
//=============================================================================
#if defined(INCLUDE_TEMPLATES) && !defined(VOLUMEMESHNODET_CC)
#include "VolumeMeshNodeT.cc"
#include "VolumeMeshNodeGLCompatT.cc"
#endif
//=============================================================================
#endif // VOLUMEMESHNODE_HH
......
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openflipper.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenFlipper. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
\*===========================================================================*/
#include "VolumeMeshNode.hh"
//== NAMESPACES ===============================================================
namespace ACG {
namespace SceneGraph {
//== IMPLEMENTATION ==========================================================
template<class VolumeMeshT>
void VolumeMeshNodeT<VolumeMeshT>::pickCompat(GLState& _state, PickTarget _target) {
// save state
bool clientStateEnabledVertexArray = GLState::isClientStateEnabled(GL_VERTEX_ARRAY);
bool clientStateEnabledColorArray = GLState::isClientStateEnabled(GL_COLOR_ARRAY);
bool clientStateEnabledNormalArray = GLState::isClientStateEnabled(GL_NORMAL_ARRAY);
bool clientStateEnabledTexCoordArray = GLState::isClientStateEnabled(GL_TEXTURE_COORD_ARRAY);
GLState::depthRange(0.01, 1.0);
if (lastCellDrawMode_)
{
//draw cells so the user cannot pick invisible stuff
GLState::bindBuffer(GL_ARRAY_BUFFER, cellsBufferManager_.getBuffer());
GLState::enableClientState(GL_VERTEX_ARRAY);
GLState::vertexPointer(3, GL_FLOAT, cellsBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
GLState::disableClientState(GL_NORMAL_ARRAY);
GLState::disableClientState(GL_COLOR_ARRAY);
Vec4f bc = _state.specular_color();
_state.set_color(Vec4f(0.0,0.0,0.0,0.0));
glDrawArrays(GL_TRIANGLES, 0, cellsBufferManager_.getNumOfVertices());
_state.set_color(bc);
GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
}
if (lastFaceDrawMode_)
{
//draw faces so the user cannot pick invisible stuff
GLState::bindBuffer(GL_ARRAY_BUFFER, facesBufferManager_.getBuffer());
GLState::enableClientState(GL_VERTEX_ARRAY);
GLState::vertexPointer(3, GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
GLState::disableClientState(GL_NORMAL_ARRAY);
GLState::disableClientState(GL_COLOR_ARRAY);
Vec4f bc = _state.specular_color();
_state.set_color(Vec4f(0.0,0.0,0.0,0.0));
glDrawArrays(GL_TRIANGLES, 0, facesBufferManager_.getNumOfVertices());
_state.set_color(bc);
GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
}
GLenum oldDepthFunc = _state.depthFunc();
GLState::depthRange(0.0, 1.0);
_state.set_depthFunc(GL_LEQUAL);
switch (_target) {
case PICK_VERTEX: {
if (lastPickTarget_ != PICK_VERTEX)
vertexPickBufferManager_.invalidateColors();
_state.pick_set_maximum(mesh_.n_vertices());
pickVerticesCompat(_state);
break;
}
case PICK_EDGE: {
_state.pick_set_maximum(mesh_.n_edges());
pickEdgesCompat(_state, 0);
break;
}
case PICK_FACE: {
_state.pick_set_maximum(mesh_.n_faces());
pickFacesCompat(_state, 0);
break;
}
case PICK_CELL: {
_state.pick_set_maximum(mesh_.n_cells());
pickCellsCompat(_state, 0);
break;
}
case PICK_ANYTHING: {
if (lastPickTarget_ != PICK_ANYTHING)
vertexPickBufferManager_.invalidateColors();
int nv = mesh_.n_vertices();
int ne = mesh_.n_edges();
int nf = mesh_.n_faces();
int nc = mesh_.n_cells();
_state.pick_set_maximum(nv + ne + nf + nc);
pickVerticesCompat(_state);
pickEdgesCompat(_state, nv);
pickFacesCompat(_state, nv + ne);
pickCellsCompat(_state, nv + ne + nf);
break;
}
default:
break;
}
_state.set_depthFunc(oldDepthFunc);
lastPickTarget_ = _target;
// restore state
if (clientStateEnabledVertexArray)
GLState::enableClientState(GL_VERTEX_ARRAY);
else
GLState::disableClientState(GL_VERTEX_ARRAY);
if (clientStateEnabledColorArray)
GLState::enableClientState(GL_COLOR_ARRAY);
else
GLState::disableClientState(GL_COLOR_ARRAY);
if (clientStateEnabledNormalArray)
GLState::enableClientState(GL_NORMAL_ARRAY);
else
GLState::disableClientState(GL_NORMAL_ARRAY);
if (clientStateEnabledTexCoordArray)
GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
else
GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
}
//----------------------------------------------------------------------------
template<class VolumeMeshT>
void VolumeMeshNodeT<VolumeMeshT>::pickVerticesCompat(GLState& _state) {
if (lastDrawMode_ & drawModes_.vertexBasedDrawModes)
vertexPickBufferManager_.enableVertexPrimitives();
else if (lastDrawMode_ & drawModes_.cellBasedDrawModes)
vertexPickBufferManager_.enableVertexOnCellPrimitives();
else
vertexPickBufferManager_.enableVertexPrimitives();
vertexPickBufferManager_.disableNormals();
vertexPickBufferManager_.enablePickColors();
GLState::bindBuffer(GL_ARRAY_BUFFER, vertexPickBufferManager_.getPickBuffer(_state, 0));
GLState::enableClientState(GL_VERTEX_ARRAY);
GLState::vertexPointer(3, GL_FLOAT, vertexPickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
GLState::enableClientState(GL_COLOR_ARRAY);
GLState::colorPointer(4, GL_UNSIGNED_BYTE, vertexPickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(vertexPickBufferManager_.getColorOffset()));
GLState::shadeModel(GL_SMOOTH);
GLState::disable(GL_LIGHTING);
float oldPointSize = _state.point_size();
_state.set_point_size(1.5*_state.point_size());
glDrawArrays(GL_POINTS, 0, vertexPickBufferManager_.getNumOfVertices());
_state.set_point_size(oldPointSize);
GLState::disableClientState(GL_COLOR_ARRAY);
GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
}
//----------------------------------------------------------------------------
template<class VolumeMeshT>
void VolumeMeshNodeT<VolumeMeshT>::pickEdgesCompat(GLState& _state, unsigned int _offset) {
if ((lastDrawMode_ & (drawModes_.cellBasedDrawModes | drawModes_.edgesOnCells)) && !(lastDrawMode_ & (drawModes_.edgeBasedDrawModes & ~drawModes_.edgesOnCells)))
edgePickBufferManager_.enableEdgeOnCellPrimitives();
else
edgePickBufferManager_.enableEdgePrimitives();
edgePickBufferManager_.enablePickColors();
edgePickBufferManager_.disableNormals();
GLState::bindBuffer(GL_ARRAY_BUFFER, edgePickBufferManager_.getPickBuffer(_state, _offset));
GLState::enableClientState(GL_VERTEX_ARRAY);
GLState::vertexPointer(3, GL_FLOAT, edgePickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
GLState::enableClientState(GL_COLOR_ARRAY);
GLState::colorPointer(4, GL_UNSIGNED_BYTE, edgePickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(edgePickBufferManager_.getColorOffset()));
GLState::shadeModel(GL_SMOOTH);
GLState::disable(GL_LIGHTING);
float oldLineWidth = _state.line_width();
_state.set_line_width(4.0*_state.line_width());
glDrawArrays(GL_LINES, 0, edgePickBufferManager_.getNumOfVertices());
_state.set_line_width(oldLineWidth);
GLState::disableClientState(GL_COLOR_ARRAY);
GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
}
//----------------------------------------------------------------------------
template<class VolumeMeshT>
void VolumeMeshNodeT<VolumeMeshT>::pickFacesCompat(GLState& _state, unsigned int _offset) {
if (lastDrawMode_ & (drawModes_.faceBasedDrawModes | drawModes_.halffaceBasedDrawModes))
facePickBufferManager_.enableFacePrimitives();
else if (lastDrawMode_ & drawModes_.cellBasedDrawModes)
facePickBufferManager_.enableFaceOnCellPrimitives();
else
facePickBufferManager_.enableFacePrimitives();
facePickBufferManager_.disableNormals();
facePickBufferManager_.enablePickColors();
GLState::bindBuffer(GL_ARRAY_BUFFER, facePickBufferManager_.getPickBuffer(_state, _offset));
GLState::enableClientState(GL_VERTEX_ARRAY);
GLState::vertexPointer(3, GL_FLOAT, facePickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
GLState::enableClientState(GL_COLOR_ARRAY);
GLState::colorPointer(4, GL_UNSIGNED_BYTE, facePickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(facePickBufferManager_.getColorOffset()));
GLState::shadeModel(GL_SMOOTH);
GLState::disable(GL_LIGHTING);
glDrawArrays(GL_TRIANGLES, 0, facePickBufferManager_.getNumOfVertices());
GLState::disableClientState(GL_COLOR_ARRAY);
GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
}
//----------------------------------------------------------------------------
template<class VolumeMeshT>
void VolumeMeshNodeT<VolumeMeshT>::pickCellsCompat(GLState& _state, unsigned int _offset) {
cellPickBufferManager_.enablePickColors();
cellPickBufferManager_.disableNormals();
cellPickBufferManager_.enableCellPrimitives();
GLState::bindBuffer(GL_ARRAY_BUFFER, cellPickBufferManager_.getPickBuffer(_state, _offset));
GLState::enableClientState(GL_VERTEX_ARRAY);
GLState::vertexPointer(3, GL_FLOAT, cellPickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
GLState::enableClientState(GL_COLOR_ARRAY);
GLState::colorPointer(4, GL_UNSIGNED_BYTE, cellPickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(cellPickBufferManager_.getColorOffset()));
GLState::shadeModel(GL_SMOOTH);
GLState::disable(GL_LIGHTING);
glDrawArrays(GL_TRIANGLES, 0, cellPickBufferManager_.getNumOfVertices());
GLState::disableClientState(GL_COLOR_ARRAY);
GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
}
//=============================================================================
} // namespace SceneGraph
} // namespace ACG
//=============================================================================
......@@ -61,6 +61,8 @@
#include <ACG/GL/RenderObject.hh>
#include <ACG/GL/VertexDeclaration.hh>
#include <ACG/GL/IRenderer.hh>
#include <ACG/ShaderUtils/GLSLShader.hh>
#include <ACG/GL/ShaderCache.hh>
#include <OpenVolumeMesh/Mesh/HexahedralMesh.hh>
......@@ -1116,135 +1118,103 @@ void VolumeMeshNodeT<VolumeMeshT>::pick(GLState& _state, PickTarget _target) {
drawModeOverride = true;
}
// save state
bool clientStateEnabledVertexArray = GLState::isClientStateEnabled(GL_VERTEX_ARRAY);
bool clientStateEnabledColorArray = GLState::isClientStateEnabled(GL_COLOR_ARRAY);
bool clientStateEnabledNormalArray = GLState::isClientStateEnabled(GL_NORMAL_ARRAY);
bool clientStateEnabledTexCoordArray = GLState::isClientStateEnabled(GL_TEXTURE_COORD_ARRAY);
GLState::depthRange(0.01, 1.0);
if (lastCellDrawMode_)
{
//draw cells so the user cannot pick invisible stuff
GLState::bindBuffer(GL_ARRAY_BUFFER, cellsBufferManager_.getBuffer());
GLState::enableClientState(GL_VERTEX_ARRAY);
GLState::vertexPointer(3, GL_FLOAT, cellsBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
GLState::disableClientState(GL_NORMAL_ARRAY);
GLState::disableClientState(GL_COLOR_ARRAY);
Vec4f bc = _state.specular_color();
_state.set_color(Vec4f(0.0,0.0,0.0,0.0));
glDrawArrays(GL_TRIANGLES, 0, cellsBufferManager_.getNumOfVertices());
_state.set_color(bc);
GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
}
if (lastFaceDrawMode_)
{
//draw faces so the user cannot pick invisible stuff
GLState::bindBuffer(GL_ARRAY_BUFFER, facesBufferManager_.getBuffer());
GLState::enableClientState(GL_VERTEX_ARRAY);
GLState::vertexPointer(3, GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
GLState::disableClientState(GL_NORMAL_ARRAY);
GLState::disableClientState(GL_COLOR_ARRAY);
Vec4f bc = _state.specular_color();
_state.set_color(Vec4f(0.0,0.0,0.0,0.0));
glDrawArrays(GL_TRIANGLES, 0, facesBufferManager_.getNumOfVertices());
_state.set_color(bc);
GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
}
GLenum oldDepthFunc = _state.depthFunc();
GLState::depthRange(0.0, 1.0);
_state.set_depthFunc(GL_LEQUAL);
switch (_target) {
case PICK_VERTEX: {
if (lastPickTarget_ != PICK_VERTEX)
vertexPickBufferManager_.invalidateColors();
_state.pick_set_maximum(mesh_.n_vertices());
pickVertices(_state);
break;
}
case PICK_EDGE: {
_state.pick_set_maximum(mesh_.n_edges());
pickEdges(_state, 0);
break;
}
case PICK_FACE: {
_state.pick_set_maximum(mesh_.n_faces());
pickFaces(_state, 0);
break;
}
case PICK_CELL: {
_state.pick_set_maximum(mesh_.n_cells());
pickCells(_state, 0);
break;
}
case PICK_ANYTHING: {
if (lastPickTarget_ != PICK_ANYTHING)
vertexPickBufferManager_.invalidateColors();
int nv = mesh_.n_vertices();
int ne = mesh_.n_edges();
int nf = mesh_.n_faces();
int nc = mesh_.n_cells();
_state.pick_set_maximum(nv + ne + nf + nc);
pickVertices(_state);
pickEdges(_state, nv);
pickFaces(_state, nv + ne);
pickCells(_state, nv + ne + nf);
break;
}
default:
break;
}
_state.set_depthFunc(oldDepthFunc);
lastPickTarget_ = _target;
if(drawModeOverride)
lastDrawMode_ = DrawModes::NONE;
// restore state
if (clientStateEnabledVertexArray)
GLState::enableClientState(GL_VERTEX_ARRAY);
else
GLState::disableClientState(GL_VERTEX_ARRAY);
if (clientStateEnabledColorArray)
GLState::enableClientState(GL_COLOR_ARRAY);
else
GLState::disableClientState(GL_COLOR_ARRAY);
if (clientStateEnabledNormalArray)
GLState::enableClientState(GL_NORMAL_ARRAY);
else
GLState::disableClientState(GL_NORMAL_ARRAY);
if (clientStateEnabledTexCoordArray)
GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
else
GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
if(_state.compatibilityProfile())
pickCompat(_state, _target);
else
{
GLState::depthRange(0.01, 1.0);
if (lastCellDrawMode_)
{
//draw cells so the user cannot pick invisible stuff
GLState::bindBuffer(GL_ARRAY_BUFFER, cellsBufferManager_.getBuffer());
GLState::vertexPointer(3, GL_FLOAT, cellsBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
Vec4f bc = _state.specular_color();
_state.set_color(Vec4f(0.0,0.0,0.0,0.0));
glDrawArrays(GL_TRIANGLES, 0, cellsBufferManager_.getNumOfVertices());
_state.set_color(bc);
GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
}
if (lastFaceDrawMode_)
{
//draw faces so the user cannot pick invisible stuff
GLState::bindBuffer(GL_ARRAY_BUFFER, facesBufferManager_.getBuffer());
GLState::vertexPointer(3, GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
Vec4f bc = _state.specular_color();
_state.set_color(Vec4f(0.0,0.0,0.0,0.0));
glDrawArrays(GL_TRIANGLES, 0, facesBufferManager_.getNumOfVertices());
_state.set_color(bc);
GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
}
GLenum oldDepthFunc = _state.depthFunc();
GLState::depthRange(0.0, 1.0);
_state.set_depthFunc(GL_LEQUAL);
switch (_target) {
case PICK_VERTEX: {
if (lastPickTarget_ != PICK_VERTEX)
vertexPickBufferManager_.invalidateColors();
_state.pick_set_maximum(mesh_.n_vertices());
pickVertices(_state);
break;
}
case PICK_EDGE: {
_state.pick_set_maximum(mesh_.n_edges());
pickEdges(_state, 0);
break;
}
case PICK_FACE: {
_state.pick_set_maximum(mesh_.n_faces());
pickFaces(_state, 0);
break;
}
case PICK_CELL: {