44 #define ACG_DRAW_MESH_TCC 48 #include "DrawMesh.hh" 50 #include <ACG/GL/gl.hh> 51 #include <ACG/Geometry/GPUCacheOptimizer.hh> 52 #include <ACG/GL/VertexDeclaration.hh> 53 #include <ACG/GL/ShaderCache.hh> 75 DrawMeshT<Mesh>::DrawMeshT(
Mesh& _mesh)
77 rebuild_(REBUILD_NONE),
78 prevNumFaces_(0), prevNumVerts_(0),
81 flatMode_(0), bVBOinFlatMode_(0),
82 textureMode_(1), bVBOinHalfedgeTexMode_(1),
83 halfedgeNormalMode_(0), bVBOinHalfedgeNormalMode_(0),
85 offsetPos_(0), offsetNormal_(20), offsetTexc_(12), offsetColor_(32),
86 textureIndexPropertyName_(
"Not Set"),
87 perFaceTextureCoordinatePropertyName_(
"h:texcoords2D"),
89 updatePerEdgeBuffers_(1),
90 updatePerHalfedgeBuffers_(1)
96 pickVertexShader_ = 0;
101 createVertexDeclaration();
110 const void* dataPtr = 0;
119 const Prop1* p1 =
dynamic_cast<const Prop1*
>(_prop);
120 const PropVec1* pv1 =
dynamic_cast<const PropVec1*
>(_prop);
121 const PropVec2* pv2 =
dynamic_cast<const PropVec2*
>(_prop);
122 const PropVec3* pv3 =
dynamic_cast<const PropVec3*
>(_prop);
123 const PropVec4* pv4 =
dynamic_cast<const PropVec4*
>(_prop);
130 dataPtr = p1->
data();
132 dataPtr = pv1->data();
138 dataPtr = pv2->data();
144 dataPtr = pv3->data();
150 dataPtr = pv4->data();
160 const void* dataPtr = 0;
163 dataPtr = testMeshPropertyTypeT<float>(_prop, _outSize);
166 if (_outType) *_outType = GL_FLOAT;
171 dataPtr = testMeshPropertyTypeT<char>(_prop, _outSize);
174 if (_outType) *_outType = GL_BYTE;
179 dataPtr = testMeshPropertyTypeT<unsigned char>(_prop, _outSize);
182 if (_outType) *_outType = GL_UNSIGNED_BYTE;
187 dataPtr = testMeshPropertyTypeT<double>(_prop, _outSize);
191 if (_outType) *_outType = GL_DOUBLE;
196 dataPtr = testMeshPropertyTypeT<int>(_prop, _outSize);
200 if (_outType) *_outType = GL_INT;
205 dataPtr = testMeshPropertyTypeT<unsigned int>(_prop, _outSize);
209 if (_outType) *_outType = GL_UNSIGNED_INT;
214 dataPtr = testMeshPropertyTypeT<short>(_prop, _outSize);
218 if (_outType) *_outType = GL_SHORT;
223 dataPtr = testMeshPropertyTypeT<unsigned short>(_prop, _outSize);
227 if (_outType) *_outType = GL_UNSIGNED_SHORT;
256 std::vector<int> attributeStoredPerHalfedge_;
259 int getNumFaces()
const {
return mesh_.n_faces(); }
269 return mesh_.valence( mesh_.face_handle(_faceID) );
281 const typename Mesh::FaceHandle fh = mesh_.face_handle(_faceID);
289 if ( attributeStoredPerHalfedge_[_attrID] != 0 ) {
290 switch (_faceCorner) {
291 case 0 :
return fh_it->idx();
293 case 1 :
return (mesh_.next_halfedge_handle(*fh_it)).idx();
295 case 2 :
return (mesh_.prev_halfedge_handle(*fh_it)).idx();
297 default : std::cerr <<
" Index error!" << _faceCorner << std::endl;
return -1;
301 switch (_faceCorner) {
302 case 0 :
return mesh_.to_vertex_handle(*fh_it).idx();
304 case 1 :
return (mesh_.to_vertex_handle(mesh_.next_halfedge_handle(*fh_it))).idx();
306 case 2 :
return (mesh_.to_vertex_handle(mesh_.prev_halfedge_handle(*fh_it))).idx();
308 default : std::cerr <<
" Index error!" << _faceCorner << std::endl;
return -1;
317 if ( attributeStoredPerHalfedge_[_attrID] != 0 ) {
319 for (
int i = 0; fh_it.is_valid() && i <= _faceCorner; ++fh_it, ++i )
320 if (i == _faceCorner)
325 for (
int i = 0; fh_it.is_valid() && i <= _faceCorner; ++fh_it, ++i )
326 if (i == _faceCorner)
327 return mesh_.to_vertex_handle(*fh_it).idx();
341 bool getFaceAttr(
const int _faceID,
const int _attrID,
int* _out)
const 343 const typename Mesh::FaceHandle fh = mesh_.face_handle(_faceID);
345 const bool usePerHalfedge = (attributeStoredPerHalfedge_[_attrID] != 0);
349 for (
int i = 0; hh_it.is_valid(); ++hh_it, ++i )
351 _out[i] = usePerHalfedge ? hh_it->idx() : mesh_.to_vertex_handle(*hh_it).idx();
378 for (;adj_it.is_valid(); ++adj_it)
390 for (
int i = 0; adj_it.is_valid() && i < _k; ++adj_it, ++i);
392 return adj_it->idx();
401 template <
class Mesh>
405 if (rebuild_ == REBUILD_NONE)
return;
407 if (!mesh_.n_vertices())
437 createVertexDeclaration();
440 if (mesh_.n_vertices() && mesh_.n_faces() == 0)
442 if (mesh_.n_vertices() > numVerts_)
444 delete [] invVertexMap_;
447 numVerts_ = mesh_.n_vertices();
448 vertices_.resize(numVerts_ * vertexDecl_->getVertexStride());
451 for (
size_t i = 0; i < numVerts_; ++i)
453 mesh_.vertex_handle(static_cast<unsigned int>(i)),
454 (
typename Mesh::HalfedgeHandle)(-1),
455 (
typename Mesh::FaceHandle)(-1));
458 rebuild_ = REBUILD_NONE;
465 unsigned int maxFaceVertCount = 0;
466 unsigned int numIndices = 0;
467 unsigned int newTriCount = countTris(&maxFaceVertCount, &numIndices);
469 int bTriangleRebuild = 0;
470 int bVertexRebuild = 0;
472 if (newTriCount > numTris_)
477 numTris_ = newTriCount;
479 bTriangleRebuild = 1;
482 if (prevNumFaces_ != mesh_.n_faces())
484 bTriangleRebuild = 1;
485 prevNumFaces_ = mesh_.n_faces();
488 if (prevNumVerts_ != mesh_.n_vertices())
490 if (prevNumVerts_ < mesh_.n_vertices())
493 delete [] invVertexMap_;
494 invVertexMap_ =
new unsigned int[mesh_.n_vertices()];
498 bTriangleRebuild = 1;
499 prevNumVerts_ = mesh_.n_vertices();
503 if (!bTriangleRebuild && !bVertexRebuild && (rebuild_ & REBUILD_GEOMETRY) && !(rebuild_ & REBUILD_TEXTURES))
509 #pragma omp parallel for 512 for (
size_t i = 0; i < numVerts_; ++i)
515 const typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
517 typename Mesh::FaceHandle fh(-1);
521 vh = mesh_.to_vertex_handle(hh);
522 fh = mesh_.face_handle(hh);
527 int posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
528 vh = mesh_.vertex_handle(posID);
531 readVertex(i, vh, hh, fh);
536 rebuild_ = REBUILD_NONE;
547 int attrIDNorm = -1, attrIDPos = -1, attrIDTexC = -1;
549 for (
int i = 0; i < (int)meshComp_->getVertexDeclaration()->getNumElements(); ++i)
551 const VertexElement* e = meshComp_->getVertexDeclaration()->getElement(i);
565 faceInput->attributeStoredPerHalfedge_.resize(meshComp_->getVertexDeclaration()->getNumElements(), 0);
566 faceInput->attributeStoredPerHalfedge_[attrIDPos] = 0;
567 faceInput->attributeStoredPerHalfedge_[attrIDNorm] = ( (halfedgeNormalMode_ && mesh_.has_halfedge_normals()) ? 1 : 0 );
568 faceInput->attributeStoredPerHalfedge_[attrIDTexC] = ( mesh_.has_halfedge_texcoords2D() ? 1 : 0);
571 for (
size_t i = 0; i < additionalElements_.size(); ++i)
573 const VertexProperty* prop = &additionalElements_[i];
575 if (prop->declElementID_ >= 0)
576 faceInput->attributeStoredPerHalfedge_[prop->declElementID_] = (prop->source_ == PROPERTY_SOURCE_HALFEDGE) ? 1 : 0;
579 meshComp_->setFaceInput(faceInput);
582 for (
unsigned int i = 0; i < mesh_.n_faces(); ++i)
583 meshComp_->setFaceGroup(i, getTextureIDofFace(i));
589 meshComp_->setVertices(mesh_.n_vertices(), mesh_.points(), 24,
false, GL_DOUBLE, 3);
592 if (halfedgeNormalMode_ && mesh_.has_halfedge_normals())
593 meshComp_->setNormals(mesh_.n_halfedges(), mesh_.property(mesh_.halfedge_normals_pph()).data(), 24,
false, GL_DOUBLE, 3);
594 else if (mesh_.has_vertex_normals())
595 meshComp_->setNormals(mesh_.n_vertices(), mesh_.vertex_normals(), 24,
false, GL_DOUBLE, 3);
597 if (mesh_.has_halfedge_texcoords2D())
598 meshComp_->setTexCoords(mesh_.n_halfedges(), mesh_.htexcoords2D(), 8,
false, GL_FLOAT, 2);
602 for (
size_t i = 0; i < additionalElements_.size(); ++i)
604 VertexProperty* propDesc = &additionalElements_[i];
606 if (propDesc->declElementID_ >= 0)
608 const VertexElement* el = vertexDecl_->getElement((
unsigned int)propDesc->declElementID_);
615 switch (propDesc->source_)
617 case PROPERTY_SOURCE_VERTEX: baseProp = mesh_._get_vprop(propDesc->name_);
break;
618 case PROPERTY_SOURCE_FACE: baseProp = mesh_._get_fprop(propDesc->name_);
break;
619 case PROPERTY_SOURCE_HALFEDGE: baseProp = mesh_._get_hprop(propDesc->name_);
break;
620 default: baseProp = mesh_._get_vprop(propDesc->name_);
break;
626 const void* attribData = propDesc->propDataPtr_;
628 meshComp_->setAttribVec( propDesc->declElementID_, numAttribs, attribData );
640 meshComp_->build(
true,
true,
true,
true);
644 for (
int i = 0; i < (int)mesh_.n_faces(); ++i)
646 typename Mesh::FaceHandle fh = mesh_.face_handle(i);
652 int vertexId = mesh_.to_vertex_handle(*hh_it).idx();
653 invVertexMap_[vertexId] = meshComp_->mapToDrawVertexID(i, corner++);
659 numTris_ = meshComp_->getNumTriangles();
660 numVerts_ = meshComp_->getNumVertices();
662 vertices_.resize(numVerts_ * vertexDecl_->getVertexStride());
663 meshComp_->getVertexBuffer(&vertices_[0]);
666 for (
int i = 0; i < (int)numVerts_; ++i)
668 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
670 unsigned int col = 0;
673 col = getVertexColor(mesh_.to_vertex_handle(hh));
678 int posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
679 col = getVertexColor( mesh_.vertex_handle(posID) );
686 curVBOColorMode_ = 1;
691 const int provokingId = meshComp_->getProvokingVertex();
692 assert(provokingId >= 0 && provokingId < 3);
694 for (
int i = 0; i < (int)numTris_; ++i)
696 int idx = meshComp_->getIndex(i*3+provokingId);
698 int faceId = meshComp_->mapToOriginalFaceID(i);
699 unsigned int fcolor = getFaceColor(mesh_.face_handle(faceId));
701 writeColor(idx, fcolor);
707 for (
int i = 0; i < (int)numTris_; ++i)
709 int idx = meshComp_->getIndex(i*3+provokingId);
711 int faceId = meshComp_->mapToOriginalFaceID(i);
712 unsigned int fcolor = getFaceColor(mesh_.face_handle(faceId));
714 unsigned int storedColor = *(
unsigned int*)(&vertices_[idx * vertexDecl_->getVertexStride() + offsetColor_]);
716 if (storedColor != fcolor)
718 std::cout <<
"warning: possibly found provoking vertex shared by more than one face, writing report to ../../meshcomp_provoking.txt" << std::endl;
724 meshComp_->dbgVerify(
"../../meshcomp_provoking.txt");
731 curVBOColorMode_ = colorMode_;
743 bVBOinHalfedgeNormalMode_ = halfedgeNormalMode_;
745 rebuild_ = REBUILD_NONE;
749 template <
class Mesh>
753 const typename Mesh::HalfedgeHandle& _hh,
754 const typename Mesh::FaceHandle& _fh)
756 static const typename Mesh::HalfedgeHandle invalidHEH(-1);
757 static const typename Mesh::FaceHandle invalidFH(-1);
765 if (halfedgeNormalMode_ == 0 && mesh_.has_vertex_normals())
766 n = mesh_.normal(_vh);
767 else if (halfedgeNormalMode_ && mesh_.has_halfedge_normals() && _hh != invalidHEH)
768 n = mesh_.normal(_hh);
771 if (mesh_.has_halfedge_texcoords2D())
773 if (_hh != invalidHEH && textureMode_ == 1)
774 texc = mesh_.texcoord2D(_hh);
775 else if (mesh_.has_vertex_texcoords2D())
776 texc = mesh_.texcoord2D(_vh);
778 else if (mesh_.has_vertex_texcoords2D())
779 texc = mesh_.texcoord2D(_vh);
782 unsigned int byteCol[2];
783 for (
int col = 0; col < 2; ++col)
785 Vec4uc vecCol(255, 255, 255, 255);
787 if (col == 0 && mesh_.has_vertex_colors())
788 vecCol = OpenMesh::color_cast<Vec4uc, typename Mesh::Color>(mesh_.color(_vh));
789 if (_fh != invalidFH)
791 if (col == 1 && mesh_.has_face_colors() && _fh.idx() >= 0)
792 vecCol = OpenMesh::color_cast<Vec4uc,typename Mesh::Color>(mesh_.color(_fh));
796 byteCol[col] = (
unsigned char)(vecCol[0]);
797 byteCol[col] |= ((
unsigned char)(vecCol[1])) << 8;
798 byteCol[col] |= ((
unsigned char)(vecCol[2])) << 16;
799 byteCol[col] |= ((
unsigned char)(vecCol[3])) << 24;
810 writePosition(_vertex, mesh_.point(_vh));
811 writeNormal(_vertex, n);
812 writeTexcoord(_vertex, texc);
813 writeColor(_vertex, col);
818 for (
size_t i = 0; i < additionalElements_.size(); ++i)
820 std::cout <<
"not implemented!" << std::endl;
828 template <
class Mesh>
834 unsigned int byteCol;
836 Vec4uc vecCol(255, 255, 255, 255);
838 if ( _vh != invalidVH && mesh_.has_vertex_colors() )
839 vecCol = OpenMesh::color_cast<Vec4uc, typename Mesh::Color>(mesh_.color(_vh));
842 byteCol = (
unsigned char)(vecCol[0]);
843 byteCol |= ((
unsigned char)(vecCol[1])) << 8;
844 byteCol |= ((
unsigned char)(vecCol[2])) << 16;
845 byteCol |= ((
unsigned char)(vecCol[3])) << 24;
850 template <
class Mesh>
854 static const typename Mesh::FaceHandle invalidFH(-1);
856 unsigned int byteCol;
857 Vec4uc vecCol(255, 255, 255, 255);
859 if ( _fh != invalidFH && mesh_.has_face_colors() && _fh.idx() >= 0 )
860 vecCol = OpenMesh::color_cast<Vec4uc,typename Mesh::Color>(mesh_.color(_fh));
863 byteCol = (
unsigned char)(vecCol[0]);
864 byteCol |= ((
unsigned char)(vecCol[1])) << 8;
865 byteCol |= ((
unsigned char)(vecCol[2])) << 16;
866 byteCol |= ((
unsigned char)(vecCol[3])) << 24;
872 template <
class Mesh>
877 if (mesh_.get_property_handle(textureIndexProperty, textureIndexPropertyName_))
878 return mesh_.property(textureIndexProperty, mesh_.face_handle(_face));
880 if (mesh_.has_face_texture_index())
881 return mesh_.texture_index(mesh_.face_handle(_face));
886 template <
class Mesh>
890 return getTextureIDofFace(meshComp_->mapToOriginalFaceID(_tri));
894 template <
class Mesh>
903 if (flatMode_ && meshComp_)
905 for (
unsigned int i = 0; i < numTris_; ++i)
907 int faceId = meshComp_->mapToOriginalFaceID(i);
910 ACG::Vec3d n = mesh_.normal(mesh_.face_handle(faceId));
915 int idx = meshComp_->getIndex(i*3 + meshComp_->getProvokingVertex());
925 for (
unsigned int i = 0; i < numVerts_; ++i)
927 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
934 if (halfedgeNormalMode_ == 1 && mesh_.has_halfedge_normals())
935 n = mesh_.normal( hh );
937 n = mesh_.normal( mesh_.to_vertex_handle(hh) );
951 posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
956 writeNormal(i, mesh_.normal( mesh_.vertex_handle(posID) ));
963 if (textureMode_ == 0)
966 if (mesh_.has_vertex_texcoords2D())
968 for (
unsigned int i = 0; i < numVerts_; ++i)
970 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
978 writeTexcoord(i, mesh_.texcoord2D( mesh_.to_vertex_handle(hh) ) );
987 posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
993 writeTexcoord(i, mesh_.texcoord2D( mesh_.vertex_handle(posID) ) );
999 bVBOinHalfedgeTexMode_ = 0;
1003 if (mesh_.has_vertex_texcoords2D() || mesh_.has_halfedge_texcoords2D())
1006 for (
unsigned int i = 0; i < numVerts_; ++i)
1008 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
1013 if (mesh_.has_halfedge_texcoords2D())
1018 writeTexcoord(i, mesh_.texcoord2D( hh ) );
1022 else if (mesh_.has_vertex_texcoords2D())
1030 posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
1036 writeTexcoord(i, mesh_.texcoord2D( mesh_.vertex_handle(posID) ) );
1042 bVBOinHalfedgeTexMode_ = 1;
1045 if (colorMode_ && colorMode_ != curVBOColorMode_)
1047 if (colorMode_ == 1)
1051 for (
int i = 0; i < (int)numVerts_; ++i)
1053 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
1058 col = getVertexColor(mesh_.to_vertex_handle(hh));
1063 int posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
1064 col = getVertexColor( mesh_.vertex_handle(posID) );
1070 else if (colorMode_ == 2)
1074 const int provokingId = meshComp_->getProvokingVertex();
1075 assert(provokingId >= 0 && provokingId < 3);
1077 for (
int i = 0; i < (int)numTris_; ++i)
1079 int idx = meshComp_->getIndex(i*3+provokingId);
1081 int faceId = meshComp_->mapToOriginalFaceID(i);
1082 unsigned int fcolor = getFaceColor(mesh_.face_handle(faceId));
1085 writeColor(idx, fcolor);
1090 curVBOColorMode_ = colorMode_;
1098 invalidateFullVBO();
1101 template <
class Mesh>
1109 indexType_ = GL_UNSIGNED_INT;
1122 createIndexBuffer();
1126 if (mesh_.n_edges())
1128 std::vector<unsigned int> lineBuffer(mesh_.n_edges() * 2);
1130 for (
unsigned int i = 0; i < mesh_.n_edges(); ++i)
1134 if (indexType_ == GL_UNSIGNED_SHORT)
1137 unsigned int combinedIdx = invVertexMap_[mesh_.from_vertex_handle(hh).idx()] | (invVertexMap_[mesh_.to_vertex_handle(hh).idx()] << 16);
1138 lineBuffer[i] = combinedIdx;
1142 lineBuffer[2 * i] = invVertexMap_[mesh_.from_vertex_handle(hh).idx()];
1143 lineBuffer[2 * i + 1] = invVertexMap_[mesh_.to_vertex_handle(hh).idx()];
1149 fillLineBuffer(mesh_.n_edges(), &lineBuffer[0]);
1155 template <
class Mesh>
1158 delete [] invVertexMap_;
1163 template <
class Mesh>
1166 unsigned int res = 0;
1167 unsigned int sysBufSize = 0;
1172 if (!vertices_.empty())
1173 sysBufSize += vertexDecl_->getVertexStride() * numVerts_;
1180 unsigned int mapsSize = 0;
1183 res += mesh_.n_vertices() * 4;
1189 unsigned int pickBufSize = 0;
1191 pickBufSize += pickVertBuf_.capacity() *
sizeof(
ACG::Vec3f);
1192 pickBufSize += pickVertColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1194 pickBufSize += pickEdgeBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1196 pickBufSize += pickFaceVertexBuf_.capacity() *
sizeof(
ACG::Vec3f);
1197 pickBufSize += pickFaceColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1200 pickBufSize += pickAnyFaceColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1201 pickBufSize += pickAnyEdgeColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1202 pickBufSize += pickAnyVertexColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1208 unsigned int edgeBufSize = 0;
1210 edgeBufSize += perEdgeVertexBuf_.capacity() *
sizeof(
ACG::Vec3f);
1211 edgeBufSize += perEdgeColorBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1213 edgeBufSize += perHalfedgeVertexBuf_.capacity() *
sizeof(
ACG::Vec3f);
1214 edgeBufSize += perHalfedgeColorBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1220 unsigned int gpuBufSize = 0;
1223 gpuBufSize += numTris_ * 3 * (indexType_ == GL_UNSIGNED_INT ? 4 : 2);
1226 gpuBufSize += numVerts_ * vertexDecl_->getVertexStride();
1230 std::cout <<
"\nDrawMesh memory usage in MB:\n";
1231 std::cout <<
"Vertex+IndexBuffer (SYSMEM only): " << float(sysBufSize) / (1024 * 1024);
1232 std::cout <<
"\nMappings: " << float(mapsSize) / (1024 * 1024);
1233 std::cout <<
"\nPicking Buffers: " << float(pickBufSize) / (1024 * 1024);
1234 std::cout <<
"\nEdge Buffers: " << float(edgeBufSize) / (1024 * 1024);
1235 std::cout <<
"\nTotal SYSMEM: " << float(res) / (1024 * 1024);
1236 std::cout <<
"\nTotal GPU: " << float(gpuBufSize) / (1024 * 1024) << std::endl;
1243 template <
class Mesh>
1247 if ((!numTris_ && mesh_.n_faces())|| ! numVerts_ || (!meshComp_ && mesh_.n_faces()))
1249 rebuild_ = REBUILD_FULL;
1252 if (bVBOinHalfedgeNormalMode_ != halfedgeNormalMode_) rebuild_ = REBUILD_FULL;
1256 if (rebuild_ == REBUILD_NONE)
1258 if (bVBOinFlatMode_ != flatMode_ || bVBOinHalfedgeTexMode_ != textureMode_ || (colorMode_ && curVBOColorMode_ != colorMode_))
1268 template <
class Mesh>
1275 template <
class Mesh>
1282 template <
class Mesh>
1285 if (_v < mesh_.n_vertices())
1288 return invVertexMap_[_v];
1293 return (
unsigned int)-1;
1296 template <
class Mesh>
1314 glClientActiveTexture(GL_TEXTURE0);
1326 template <
class Mesh>
1340 template <
class Mesh>
1354 template <
class Mesh>
1363 vertexDecl_->activateFixedFunction();
1366 #ifdef DEBUG_MEM_USAGE 1367 getMemoryUsage(
true);
1376 for (
int i = 0; i < meshComp_->getNumSubsets(); ++i)
1380 if ( _textureMap->find(sub->id) == _textureMap->end() ) {
1381 std::cerr <<
"Illegal texture index ... trying to access " << sub->id << std::endl;
1388 glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(sub->numTris * 3), indexType_,
1389 (GLvoid*)( (
size_t)sub->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2)));
1391 glDrawArrays(GL_TRIANGLES, sub->startIndex, static_cast<GLsizei>(sub->numTris * 3));
1397 glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(numTris_ * 3), indexType_, 0);
1399 glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(numTris_ * 3));
1407 template <
class Mesh>
1414 bindBuffersToRenderObject(&ro);
1427 for (
int i = 0; i < meshComp_->getNumSubsets(); ++i)
1433 if ( _textureMap->find(sub->id) == _textureMap->end() ) {
1434 std::cerr <<
"Illegal texture index ... trying to access " << sub->id << std::endl;
1439 tex.type = GL_TEXTURE_2D;
1440 tex.id = (*_textureMap)[sub->id];
1446 GLState::activeTexture(GL_TEXTURE0);
1447 GLint textureID = 0;
1448 glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureID);
1451 tex.type = GL_TEXTURE_2D;
1459 ro.glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(sub->numTris * 3), indexType_,
1460 (GLvoid*)((
size_t)sub->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2)));
1462 ro.glDrawArrays(GL_TRIANGLES, sub->startIndex, static_cast<GLsizei>(sub->numTris * 3) );
1470 ro.glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(numTris_ * 3), indexType_, 0);
1472 ro.glDrawArrays(GL_TRIANGLES,0, static_cast<GLsizei>(numTris_ * 3));
1479 template <
class Mesh>
1484 if (mesh_.n_edges())
1488 glDrawElements(GL_LINES, static_cast<GLsizei>(mesh_.n_edges() * 2), indexType_, 0);
1495 template <
class Mesh>
1499 bindBuffersToRenderObject(&ro);
1501 if (mesh_.n_edges())
1504 ro.glDrawElements(GL_LINES, static_cast<GLsizei>(mesh_.n_edges() * 2), indexType_, 0);
1510 template <
class Mesh>
1517 glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(numVerts_));
1522 template <
class Mesh>
1526 bindBuffersToRenderObject(&ro);
1530 ro.glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(numVerts_));
1538 template <
class Mesh>
1541 unsigned int triCounter = 0;
1543 if (pMaxVertsOut) *pMaxVertsOut = 0;
1544 if (_pOutNumIndices) *_pOutNumIndices = 0;
1546 for (
unsigned int i = 0; i < mesh_.n_faces(); ++i)
1548 typename Mesh::FaceHandle fh = mesh_.face_handle(i);
1551 unsigned int nPolyVerts = 0;
1553 for (
typename Mesh::FaceHalfedgeIter hh_it = mesh_.fh_iter(fh); hh_it.is_valid(); ++hh_it ) ++nPolyVerts;
1555 triCounter += (nPolyVerts - 2);
1559 if (*pMaxVertsOut < nPolyVerts)
1560 *pMaxVertsOut = nPolyVerts;
1563 if (_pOutNumIndices) *_pOutNumIndices += nPolyVerts;
1571 template <
class Mesh>
1575 if (updatePerEdgeBuffers_)
1576 updatePerEdgeBuffers();
1577 return perEdgeVertexBuf_.empty() ? 0 : &(perEdgeVertexBuf_[0]);
1580 template <
class Mesh>
1584 if (updatePerEdgeBuffers_)
1585 updatePerEdgeBuffers();
1586 return perEdgeColorBuf_.empty() ? 0 : &(perEdgeColorBuf_[0]);
1590 template <
class Mesh>
1594 unsigned int idx = 0;
1597 pickVertColBuf_.resize( mesh_.n_vertices() );
1598 pickVertBuf_.resize( mesh_.n_vertices() );
1601 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end());
1602 for (; v_it!=v_end; ++v_it, ++idx)
1605 pickVertBuf_[idx] = mesh_.point(mesh_.vertex_handle(idx));
1610 template <
class Mesh>
1614 if (!numVerts_ && mesh_.n_vertices())
1616 rebuild_ = REBUILD_FULL;
1624 if (pickVertexMethod_ == 0)
1626 std::vector<int> forwardMap(numVerts_, 0);
1628 for (
int i = 0; i < (int)numVerts_; ++i)
1630 int vboIdx = mapVertexToVBOIndex(i);
1632 forwardMap[vboIdx] = i;
1634 pickVertexMapTBO_.setBufferData(
sizeof(
int) * numVerts_, &forwardMap[0], GL_R32I, GL_STATIC_DRAW);
1644 bindPickVertexIbo();
1645 fillInvVertexMap(mesh_.n_vertices(), invVertexMap_);
1654 template <
class Mesh>
1661 if (pickVertexMethod_ == 0)
1663 desc.fragmentTemplateFile =
"Picking/pick_vertices_fs.glsl";
1664 desc.vertexTemplateFile =
"Picking/pick_vertices_vs.glsl";
1668 desc.fragmentTemplateFile =
"Picking/pick_vertices_fs2.glsl";
1669 desc.vertexTemplateFile =
"Picking/vertex.glsl";
1671 pickVertexShader_ = ShaderCache::getInstance()->getProgram(&desc,
nullptr);
1674 return pickVertexShader_ && pickVertexShader_->isLinked();
1678 template <
class Mesh>
1702 if (!supportsPickingVertices_opt())
1707 if (pickVertexMethod_ == 1 && invVertexMap_)
1708 bindPickVertexIbo();
1711 pickVertexShader_->use();
1712 getVertexDeclaration()->activateShaderPipeline(pickVertexShader_);
1714 pickVertexShader_->setUniform(
"pickVertexOffset", static_cast<GLint>(_pickOffset) );
1716 if (pickVertexMethod_ == 0)
1718 pickVertexShader_->setUniform(
"vboToInputMap", 0);
1719 pickVertexMap_opt()->bind(GL_TEXTURE0);
1722 pickVertexShader_->setUniform(
"mWVP", _mvp);
1725 if (pickVertexMethod_ == 0)
1726 glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(getNumVerts()));
1729 if (pickVertexIBO_opt() && invVertexMap_)
1730 glDrawElements(GL_POINTS, static_cast<GLsizei>(mesh_.n_vertices()), GL_UNSIGNED_INT, 0);
1732 glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(mesh_.n_vertices()));
1736 getVertexDeclaration()->deactivateShaderPipeline(pickVertexShader_);
1737 pickVertexShader_->disable();
1742 if (pickVertexMethod_ == 1)
1748 template <
class Mesh>
1752 if (!updatePerEdgeBuffers_)
1755 perEdgeVertexBuf_.resize(mesh_.n_edges() * 2);
1757 if ( mesh_.has_edge_colors() ) {
1758 perEdgeColorBuf_.resize(mesh_.n_edges() * 2);
1760 perEdgeColorBuf_.clear();
1762 unsigned int idx = 0;
1764 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
1765 for (; e_it!=e_end; ++e_it) {
1767 perEdgeVertexBuf_[idx] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0)));
1768 perEdgeVertexBuf_[idx+1] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1)));
1770 if ( mesh_.has_edge_colors() ) {
1771 const Vec4f color = OpenMesh::color_cast<
Vec4f>( mesh_.color(*e_it) ) ;
1772 perEdgeColorBuf_[ idx ] = color;
1773 perEdgeColorBuf_[ idx + 1 ] = color;
1780 updatePerEdgeBuffers_ = 0;
1782 updateEdgeHalfedgeVertexDeclarations();
1785 template <
class Mesh>
1786 template<
typename Mesh::Normal (DrawMeshT<Mesh>::*NormalLookup)(
typename Mesh::FaceHandle)>
1790 if (!updatePerHalfedgeBuffers_)
1793 perHalfedgeVertexBuf_.resize(mesh_.n_halfedges() * 2);
1795 if ( mesh_.has_halfedge_colors() ) {
1796 perHalfedgeColorBuf_.resize(mesh_.n_halfedges() * 2);
1798 perHalfedgeColorBuf_.clear();
1800 unsigned int idx = 0;
1802 for (
typename Mesh::ConstHalfedgeIter he_it(mesh_.halfedges_sbegin()), he_end(mesh_.halfedges_end());
1803 he_it != he_end; ++he_it) {
1805 typename Mesh::HalfedgeHandle next_heh = mesh_.next_halfedge_handle(*he_it);
1806 typename Mesh::HalfedgeHandle previous_heh = mesh_.prev_halfedge_handle(*he_it);
1808 if (mesh_.is_valid_handle(next_heh) && mesh_.is_valid_handle(previous_heh))
1810 perHalfedgeVertexBuf_[idx] = halfedge_point<NormalLookup>(*he_it);
1811 perHalfedgeVertexBuf_[idx+1] = halfedge_point<NormalLookup>(previous_heh);
1816 perHalfedgeVertexBuf_[idx ] = mesh_.point(mesh_.to_vertex_handle(*he_it));
1817 perHalfedgeVertexBuf_[idx+1] = mesh_.point(mesh_.from_vertex_handle(*he_it));
1820 if ( mesh_.has_halfedge_colors() ) {
1821 const Vec4f color = OpenMesh::color_cast<
Vec4f>( mesh_.color(*he_it) ) ;
1822 perHalfedgeColorBuf_[ idx ] = color;
1823 perHalfedgeColorBuf_[ idx + 1 ] = color;
1828 if(perHalfedgeVertexBuf_.size() > 0)
1833 fillHEVBO(perHalfedgeVertexBuf_.size(),
sizeof(perHalfedgeVertexBuf_[0]), perHalfedgeVertexBuf_.data());
1838 updatePerHalfedgeBuffers_ = 0;
1840 updateEdgeHalfedgeVertexDeclarations();
1843 template<
class Mesh>
1844 template<
typename Mesh::Normal (DrawMeshT<Mesh>::*NormalLookup)(
typename Mesh::FaceHandle)>
1847 typename Mesh::Point p = mesh_.point(mesh_.to_vertex_handle (_heh));
1848 typename Mesh::Point pp = mesh_.point(mesh_.from_vertex_handle(_heh));
1849 typename Mesh::Point pn = mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(_heh)));
1853 if( !mesh_.is_boundary(_heh))
1855 fn = (this->*NormalLookup)(mesh_.face_handle(_heh));
1858 fn = (this->*NormalLookup)(mesh_.face_handle(mesh_.opposite_halfedge_handle(_heh)));
1860 typename Mesh::Point upd = ((fn%(pn-p)).normalize() + (fn%(p-pp)).normalize()).normalize();
1862 upd *= ((pn-p).norm()+(p-pp).norm())*0.08;
1873 template <
class Mesh>
1877 if (updatePerHalfedgeBuffers_) {
1878 if (mesh_.has_face_normals())
1879 updatePerHalfedgeBuffers<&DrawMeshT::cachedNormalLookup>();
1881 updatePerHalfedgeBuffers<&DrawMeshT::computedTriMeshNormal>();
1883 updatePerHalfedgeBuffers<&DrawMeshT::computedNormal>();
1885 return perHalfedgeVertexBuf_.empty() ? 0 : &(perHalfedgeVertexBuf_[0]);
1888 template <
class Mesh>
1892 if (updatePerHalfedgeBuffers_) {
1893 if (mesh_.has_face_normals())
1894 updatePerHalfedgeBuffers<&DrawMeshT::cachedNormalLookup>();
1896 updatePerHalfedgeBuffers<&DrawMeshT::computedTriMeshNormal>();
1898 updatePerHalfedgeBuffers<&DrawMeshT::computedNormal>();
1900 return perHalfedgeColorBuf_.empty() ? 0 : &(perHalfedgeColorBuf_[0]);
1906 template <
class Mesh>
1908 unsigned int _offset)
1910 updatePerEdgeBuffers();
1912 pickEdgeBuf_.resize(mesh_.n_edges() * 2);
1917 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
1918 for (; e_it!=e_end; ++e_it) {
1922 pickEdgeBuf_[idx] = pickColor;
1923 pickEdgeBuf_[idx+1] = pickColor;
1931 template <
class Mesh>
1935 if (!numTris_ && mesh_.n_faces())
1937 rebuild_ = REBUILD_FULL;
1945 template <
class Mesh>
1950 desc.vertexTemplateFile =
"Picking/vertex.glsl" ;
1951 desc.fragmentTemplateFile =
"Picking/pick_vertices_fs2.glsl" ;
1952 pickEdgeShader_ = ShaderCache::getInstance()->getProgram(&desc,
nullptr);
1955 return pickEdgeShader_ && pickEdgeShader_->isLinked();
1959 template <
class Mesh>
1978 if (!supportsPickingEdges_opt())
1985 pickEdgeShader_->use();
1986 getVertexDeclaration()->activateShaderPipeline(pickEdgeShader_);
1988 pickEdgeShader_->setUniform(
"pickVertexOffset", static_cast<GLint>(_pickOffset) );
1989 pickEdgeShader_->setUniform(
"mWVP", _mvp);
1992 glDrawElements(GL_LINES, static_cast<GLsizei>(mesh_.n_edges() * 2), indexType_, 0);
1995 getVertexDeclaration()->deactivateShaderPipeline(pickEdgeShader_);
1996 pickEdgeShader_->disable();
2010 template <
class Mesh>
2014 if (!numTris_ && mesh_.n_faces())
2016 rebuild_ = REBUILD_FULL;
2020 pickFaceVertexBuf_.resize(3 * numTris_);
2021 pickFaceColBuf_.resize(3 * numTris_);
2023 for (
unsigned int i = 0; i < numTris_; ++i)
2025 unsigned int faceId = (
unsigned int)meshComp_->mapToOriginalFaceID((
int)i);
2028 for (
unsigned int k = 0; k < 3; ++k)
2030 int idx = meshComp_->getIndex(i*3 + k);
2032 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(idx);
2036 vh = mesh_.to_vertex_handle( hh );
2040 int posID = meshComp_->mapToOriginalVertexID(idx, f_id, c_id);
2041 vh = mesh_.vertex_handle(posID);
2044 pickFaceVertexBuf_[i * 3 + k] = mesh_.point( vh );
2046 pickFaceColBuf_[i * 3 + k] = pickColor;
2055 template <
class Mesh>
2059 if (!numTris_ && mesh_.n_faces())
2061 rebuild_ = REBUILD_FULL;
2065 if (meshComp_ && meshComp_->getNumTriangles())
2068 pickFaceTriToFaceMapTBO_.setBufferData(
sizeof(
int) * meshComp_->getNumTriangles(), meshComp_->mapToOriginalFaceIDPtr(), GL_R32I, GL_STATIC_DRAW);
2074 template <
class Mesh>
2077 if (!ACG::Texture::supportsTextureBuffer())
2082 desc.vertexTemplateFile =
"Picking/vertex.glsl";
2083 desc.fragmentTemplateFile =
"Picking/pick_face.glsl";
2084 pickFaceShader_ = ShaderCache::getInstance()->getProgram(&desc,
nullptr);
2087 return pickFaceShader_ && pickFaceShader_->isLinked();
2091 template <
class Mesh>
2127 if (!supportsPickingFaces_opt())
2135 pickFaceShader_->use();
2136 getVertexDeclaration()->activateShaderPipeline(pickFaceShader_);
2138 pickFaceShader_->setUniform(
"pickFaceOffset", static_cast<GLint>(_pickOffset));
2139 pickFaceShader_->setUniform(
"triToFaceMap", 0);
2141 pickFaceTriangleMap_opt()->bind(GL_TEXTURE0);
2143 pickFaceShader_->setUniform(
"mWVP", _mvp);
2146 glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(getNumTris() * 3), getIndexType(), 0);
2149 getVertexDeclaration()->deactivateShaderPipeline(pickFaceShader_);
2150 pickFaceShader_->disable();
2160 template <
class Mesh>
2163 if (!numTris_ && mesh_.n_faces())
2165 rebuild_ = REBUILD_FULL;
2169 pickFaceVertexBuf_.resize(3 * numTris_);
2170 pickAnyFaceColBuf_.resize(3 * numTris_);
2172 for (
unsigned int i = 0; i < numTris_; ++i)
2174 int faceId = meshComp_->mapToOriginalFaceID(i);
2176 for (
unsigned int k = 0; k < 3; ++k)
2178 int idx = meshComp_->getIndex(i*3 + k);
2181 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(idx);
2185 vh = mesh_.to_vertex_handle( hh );
2189 int posID = meshComp_->mapToOriginalVertexID(idx, f_id, c_id);
2190 vh = mesh_.vertex_handle(posID);
2193 pickFaceVertexBuf_[i * 3 + k] = mesh_.point( vh );
2195 pickAnyFaceColBuf_[i * 3 + k] = pickColor;
2201 updatePerEdgeBuffers();
2203 pickAnyEdgeColBuf_.resize(mesh_.n_edges() * 2);
2205 unsigned int idx = 0;
2206 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
2207 for (; e_it!=e_end; ++e_it) {
2211 pickAnyEdgeColBuf_[idx] = pickColor;
2212 pickAnyEdgeColBuf_[idx+1] = pickColor;
2222 pickAnyVertexColBuf_.resize( mesh_.n_vertices() );
2223 pickVertBuf_.resize( mesh_.n_vertices() );
2226 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end());
2227 for (; v_it!=v_end; ++v_it, ++idx)
2229 pickAnyVertexColBuf_[idx] = _state.
pick_get_name_color(idx + mesh_.n_faces() + mesh_.n_edges());
2230 pickVertBuf_[idx] = mesh_.point(mesh_.vertex_handle(idx));
2236 template <
class Mesh>
2239 updatePickingFaces_opt(_state);
2240 updatePickingEdges_opt(_state);
2241 updatePickingVertices_opt(_state);
2246 template <
class Mesh>
2249 return supportsPickingFaces_opt() && supportsPickingEdges_opt() && supportsPickingVertices_opt();
2253 template <
class Mesh>
2263 if (!supportsPickingAny_opt())
2266 drawPickingFaces_opt(_mvp, _pickOffset);
2270 drawPickingEdges_opt(_mvp, _pickOffset + mesh_.n_faces());
2272 drawPickingVertices_opt(_mvp, _pickOffset + mesh_.n_faces() + mesh_.n_edges());
2275 template <
class Mesh>
2282 if ( !mesh_.get_property_handle(textureIndexProperty,_indexPropertyName) ) {
2283 if ( _indexPropertyName !=
"No Texture Index" )
2284 std::cerr <<
"DrawMeshT: Unable to get per face texture Index property named " << _indexPropertyName << std::endl;
2289 textureIndexPropertyName_ = _indexPropertyName;
2296 rebuild_ |= REBUILD_TOPOLOGY;
2299 template <
class Mesh>
2306 if ( !mesh_.get_property_handle(perFaceTextureCoordinateProperty,_perFaceTextureCoordinatePropertyName) ) {
2307 if ( _perFaceTextureCoordinatePropertyName !=
"No Texture" )
2308 std::cerr <<
"DrawMeshT: Unable to get per face texture coordinate property named " << _perFaceTextureCoordinatePropertyName << std::endl;
2313 perFaceTextureCoordinatePropertyName_ = _perFaceTextureCoordinatePropertyName;
2317 rebuild_ |= REBUILD_GEOMETRY;
2321 template <
class Mesh>
2325 for (
unsigned int i = 0; i < meshComp_->getNumSubsets(); ++i)
2327 if (meshComp_->getSubset(i)->id > 0) ++n;
2332 template <
class Mesh>
2338 if ( !mesh_.get_property_handle(perFaceTextureCoordinateProperty, perFaceTextureCoordinatePropertyName_) ) {
2348 template <
class Mesh>
2354 if ( !mesh_.get_property_handle(textureIndexProperty, textureIndexPropertyName_) ) {
2367 template <
class Mesh>
2370 vertexDecl_->clear();
2377 for (
size_t i = 0; i < additionalElements_.size(); ++i)
2379 VertexProperty* prop = &additionalElements_[i];
2382 prop->sourceType_.numElements_ = 0;
2383 prop->sourceType_.pointer_ = 0;
2384 prop->sourceType_.type_ = 0;
2385 prop->sourceType_.shaderInputName_ = 0;
2387 prop->propDataPtr_ = 0;
2388 prop->declElementID_ = -1;
2393 switch (prop->source_)
2395 case PROPERTY_SOURCE_VERTEX: baseProp = mesh_._get_vprop(prop->name_);
break;
2396 case PROPERTY_SOURCE_FACE: baseProp = mesh_._get_fprop(prop->name_);
break;
2397 case PROPERTY_SOURCE_HALFEDGE: baseProp = mesh_._get_hprop(prop->name_);
break;
2398 default: baseProp = mesh_._get_vprop(prop->name_);
break;
2402 prop->propDataPtr_ = getMeshPropertyType(baseProp, &prop->sourceType_.type_, &prop->sourceType_.numElements_);
2405 if (prop->propDataPtr_)
2407 prop->sourceType_.shaderInputName_ = prop->name_.c_str();
2410 prop->destType_ = prop->sourceType_;
2412 prop->destType_.shaderInputName_ = prop->vertexShaderInputName_.c_str();
2414 prop->declElementID_ = int(vertexDecl_->getNumElements());
2416 vertexDecl_->addElement(&prop->destType_);
2419 std::cerr <<
"Could not detect data type of property " << prop->name_ << std::endl;
2424 template <
class Mesh>
2427 vertexDeclEdgeCol_->clear();
2429 vertexDeclEdgeCol_->addElement(GL_FLOAT, 4,
VERTEX_USAGE_COLOR, perEdgeColorBuffer());
2431 vertexDeclHalfedgeCol_->clear();
2433 vertexDeclHalfedgeCol_->addElement(GL_FLOAT, 4,
VERTEX_USAGE_COLOR, perHalfedgeColorBuffer());
2435 vertexDeclHalfedgePos_->clear();
2438 vertexDeclEdgeCol_->setVertexStride(0);
2439 vertexDeclHalfedgeCol_->setVertexStride(0);
2440 vertexDeclHalfedgePos_->setVertexStride(0);
2443 template <
class Mesh>
2450 template<
class Mesh>
2453 int faceId = -1, cornerId = -1;
2457 meshComp_->mapToOriginalVertexID(_vertexId, faceId, cornerId);
2461 typename Mesh::FaceHandle fh = mesh_.face_handle(faceId);
2465 for (
int k = 0; k < cornerId && hh_it.is_valid(); ++k )
2471 return typename Mesh::HalfedgeHandle(-1);
2475 template <
class Mesh>
2479 size_t offset = _vertex * _stride + _elementOffset;
2482 char* dst =
static_cast<char*
>(_dstBuf) + offset;
2485 memcpy(dst, _elementData, _elementSize);
2488 template <
class Mesh>
2492 float f3[3] = {float(_n[0]), float(_n[1]), float(_n[2])};
2494 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), 0, 12, f3);
2497 template <
class Mesh>
2501 float f3[3] = {float(_n[0]), float(_n[1]), float(_n[2])};
2503 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetNormal_, 12, f3);
2507 template <
class Mesh>
2510 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetTexc_, 8, _uv.
data());
2513 template <
class Mesh>
2516 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetColor_, 4, &_color);
2520 template <
class Mesh>
2523 const size_t elementSize = VertexDeclaration::getElementSize(_elementDesc);
2525 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), _elementDesc->
getByteOffset(), elementSize, _propf.
data());
2530 template <
class Mesh>
2535 for (
size_t i = 0; i < additionalElements_.size(); ++i)
2537 if (additionalElements_[i].name_ == _propertyName)
2539 additionalElements_[i].source_ = _source;
2547 VertexProperty prop;
2549 prop.name_ = _propertyName;
2550 prop.source_ = _source;
2551 prop.vertexShaderInputName_ = _propertyName;
2554 additionalElements_.push_back(prop);
2560 template <
class Mesh>
2563 bool success =
true;
2567 file.open(_vertexShaderFile.c_str(), std::ios_base::in);
2575 file.getline(line, 0xff);
2578 QString strLine = line;
2579 strLine = strLine.simplified();
2582 if (!strLine.startsWith(
"//") && !strLine.startsWith(
"*/"))
2585 if (strLine.startsWith(
"in ") || strLine.contains(
" in "))
2588 int semIdx = strLine.indexOf(
';');
2596 QString strName = strLine;
2597 strName.remove(semIdx, strName.length());
2599 strName = strName.simplified();
2602 int lastWhite = strName.lastIndexOf(
' ');
2606 strName.remove(0, lastWhite);
2608 strName = strName.simplified();
2611 if (strName !=
"inPosition" &&
2612 strName !=
"inTexCoord" &&
2613 strName !=
"inNormal" &&
2614 strName !=
"inColor")
2618 std::string propName = strName.toStdString();
2621 PropertySource src = PROPERTY_SOURCE_VERTEX;
2623 if (strLine.contains(
"flat "))
2626 src = PROPERTY_SOURCE_FACE;
2628 if (!mesh_._get_fprop(propName))
2629 src = PROPERTY_SOURCE_VERTEX;
2632 if (src == PROPERTY_SOURCE_VERTEX)
2634 if (!mesh_._get_vprop(propName))
2635 src = PROPERTY_SOURCE_HALFEDGE;
2639 if (src == PROPERTY_SOURCE_VERTEX)
2641 if ( mesh_._get_hprop(propName) && src == PROPERTY_SOURCE_VERTEX)
2642 src = PROPERTY_SOURCE_HALFEDGE;
2646 if (src == PROPERTY_SOURCE_HALFEDGE && !mesh_._get_hprop(propName))
2648 std::cerr <<
"DrawMesh error - requested property " << propName <<
" does not exist" << std::endl;
2653 addVertexElement(propName, src);
2674 template<
class Mesh>
2678 file.open(_filename);
2682 for (
int attrId = 0; attrId < 3; ++attrId)
2684 for (
int i = 0; i < numVerts_; ++i)
2687 const char* v = &vertices_[i * vertexDecl_->getVertexStride()];
2689 const float* pos =
reinterpret_cast<const float*
>((
const void*)(v + offsetPos_));
2690 const float* n =
reinterpret_cast<const float*
>((
const void*)(v + offsetNormal_));
2691 const float* texc =
reinterpret_cast<const float*
>((
const void*)(v + offsetTexc_));
2696 case 0: file <<
"v "<<pos[0]<<
" "<<pos[1]<<
" "<<pos[2]<<
"\n";
break;
2697 case 1: file <<
"vt "<<texc[0]<<
" "<<texc[1]<<
"\n";
break;
2698 case 2: file <<
"vn "<<n[0]<<
" "<<n[1]<<
" "<<n[2]<<
"\n";
break;
2705 for (
int i = 0; i < numTris_; ++i)
2708 const int* tri = meshComp_->getIndexBuffer() + i*3;
2710 file <<
"f "<<tri[0]+1<<
"/"<<tri[0]+1<<
"/"<<tri[0]+1<<
" "<<tri[1]+1<<
"/"<<tri[1]+1<<
"/"<<tri[1]+1<<
" "<<tri[2]+1<<
"/"<<tri[2]+1<<
"/"<<tri[2]+1<<
"\n";
2719 template <
class Mesh>
2724 unsigned int stride = vertexDecl_->getVertexStride();
2727 unsigned int offset = _vertex * stride;
2730 memcpy(_dst, &vertices_[offset], stride);
2737 template <
class Mesh>
2740 updateFullVBO_ =
true;
2744 template <
class Mesh>
2759 int numVerts = 3 * numTris;
2761 std::vector<char> fullBuf(numVerts * stride);
2764 for (
int i = 0; i < numTris; ++i)
2766 for (
int k = 0; k < 3; ++k)
2768 int idx = i * 3 + k;
2770 readVertexFromVBO(vertexID, &fullBuf[idx * stride]);
2772 if (colorMode_ == 2)
2776 int faceId = meshComp_->mapToOriginalFaceID(i);
2777 unsigned int fcolor = getFaceColor(mesh_.face_handle(faceId));
2780 writeVertexElement(&fullBuf[0], idx, vertexDecl_->getVertexStride(), offsetColor_, 4, &fcolor);
2786 if (!fullBuf.empty())
2787 vboFull_.upload(fullBuf.size(), &fullBuf[0], GL_STATIC_DRAW);
2790 updateFullVBO_ =
false;
Namespace providing different geometric functions concerning angles.
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
Class to define the vertex input layout.
void addTexture(const Texture &_t)
adds a texture to stage RenderObjects::numTextures()
unsigned int getMemoryUsage(bool _printReport=false)
measures the size in bytes of allocated memory. eventually prints a report to std::cout ...
void invalidateFullVBO()
the mesh has been changed
void addVertexElement(const std::string &_propertyName, PropertySource _source=PROPERTY_SOURCE_VERTEX)
Add custom elements to the vertex layout.
void addTriRenderObjects(IRenderer *_renderer, const RenderObject *_baseObj, std::map< int, GLuint > *_textureMap, bool _nonindexed=false)
adds RenderObjects to a deferred draw call renderer
bool supportsPickingFaces_opt()
Check if optimized face picking is supported.
Vec4uc pick_get_name_color(size_t _idx)
Kernel::Point Point
Coordinate type.
VectorT< unsigned char, 4 > Vec4uc
VectorT< float, 3 > Vec3f
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
void readVertexFromVBO(unsigned int _vertex, void *_dst)
Read one vertex from the rendering vbo.
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
VertexDeclaration * getVertexDeclaration()
get vertex declaration of the current vbo layout
defined by user via VertexElement::shaderInputName_
void drawPickingEdges_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of edge picking ids with a shader.
Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter
Circulator.
bool supportsPickingVertices_opt()
Check if optimized vertex picking is supported.
Handle for a halfedge entity.
virtual size_t n_elements() const =0
Number of elements in property.
Kernel::ConstVertexFaceIter ConstVertexFaceIter
Circulator.
const VertexDeclaration * getVertexDeclaration() const
Scalar * data()
access to Scalar array
Interface class between scenegraph and renderer.
unsigned int getVertexStride(unsigned int i=0) const
void updateFullVBO()
update the full mesh vbo
void drawPickingAny_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of any picking ids with a shader.
bool scanVertexShaderForInput(const std::string &_vertexShaderFile)
Scan vertex layout from vertex shader.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
static constexpr bool is_trimesh()
Determine whether this is a PolyMeshT or TriMeshT (This function does not check the per face vertex c...
void drawPickingFaces_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of face picking ids with a shader.
int getNumTriangles() const
int * getFaceAttr(const int _faceID, const int _attrID) const
void drawPickingVertices_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of vertex picking ids with a shader.
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
void createVertexDeclaration()
creates all vertex declarations needed for deferred draw call renderer
VERTEX_USAGE usage_
position, normal, shader input ..
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
Default property class for any type T.
bool getFaceAttr(const int _faceID, const int _attrID, int *_out) const
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking
bool ACGDLLEXPORT openGLVersionTest(const int _major, const int _minor)
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
Description of one vertex element.
int getIndex(int _i) const
const T * data() const
Get pointer to array (does not work for T==bool)
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
int getVertexAdjCount(const int _vertexID) const
ShaderGenDesc shaderDesc
Drawmode and other shader params.
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
int getSingleFaceAttr(const int _faceID, const int _faceCorner, const int _attrID) const
GLuint indexBuffer
Use vertex array object.
GLenum indexType
Index element type.
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
void updateEdgeHalfedgeVertexDeclarations()
updates per edge and halfedge vertex declarations
bool supportsPickingEdges_opt()
Check if optimized face picking is supported.
unsigned int getByteOffset() const
int getFaceSize(const int _faceID) const
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
int getVertexAdjFace(const int _vertexID, const int _k) const
int getNumIndices() const
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
bool supportsPickingAny_opt()
Check if optimized any picking is supported.