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;
void drawPickingFaces_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of face picking ids with a shader.
GLenum indexType
Index element type.
bool supportsPickingAny_opt()
Check if optimized any picking is supported.
void drawPickingVertices_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of vertex picking ids with a shader.
virtual size_t n_elements() const =0
Number of elements in property.
Kernel::ConstVertexFaceIter ConstVertexFaceIter
Circulator.
unsigned int getMemoryUsage(bool _printReport=false)
measures the size in bytes of allocated memory. eventually prints a report to std::cout ...
defined by user via VertexElement::shaderInputName_
void updateEdgeHalfedgeVertexDeclarations()
updates per edge and halfedge vertex declarations
void addTexture(const Texture &_t)
adds a texture to stage RenderObjects::numTextures()
Namespace providing different geometric functions concerning angles.
Handle for a halfedge entity.
Kernel::Point Point
Coordinate type.
void readVertexFromVBO(unsigned int _vertex, void *_dst)
Read one vertex from the rendering vbo.
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
Class to define the vertex input layout.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
static constexpr bool is_trimesh()
Determine whether this is a PolyMeshT or TriMeshT (This function does not check the per face vertex c...
bool supportsPickingFaces_opt()
Check if optimized face picking is supported.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
VERTEX_USAGE usage_
position, normal, shader input ..
Vec4uc pick_get_name_color(size_t _idx)
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
Scalar * data()
access to Scalar array
bool ACGDLLEXPORT openGLVersionTest(const int _major, const int _minor)
void addTriRenderObjects(IRenderer *_renderer, const RenderObject *_baseObj, std::map< int, GLuint > *_textureMap, bool _nonindexed=false)
adds RenderObjects to a deferred draw call renderer
unsigned int getVertexStride(unsigned int i=0) const
Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter
Circulator.
VectorT< float, 3 > Vec3f
Description of one vertex element.
void addVertexElement(const std::string &_propertyName, PropertySource _source=PROPERTY_SOURCE_VERTEX)
Add custom elements to the vertex layout.
Default property class for any type T.
void createVertexDeclaration()
creates all vertex declarations needed for deferred draw call renderer
void invalidateFullVBO()
the mesh has been changed
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
const T * data() const
Get pointer to array (does not work for T==bool)
GLuint indexBuffer
Use vertex array object.
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
unsigned int getByteOffset() const
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
bool supportsPickingVertices_opt()
Check if optimized vertex picking is supported.
VertexDeclaration * getVertexDeclaration()
get vertex declaration of the current vbo layout
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
void drawPickingAny_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of any picking ids with a shader.
void updateFullVBO()
update the full mesh vbo
bool supportsPickingEdges_opt()
Check if optimized face picking is supported.
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
int getNumTriangles() const
bool scanVertexShaderForInput(const std::string &_vertexShaderFile)
Scan vertex layout from vertex shader.
const VertexDeclaration * getVertexDeclaration() const
VectorT< unsigned char, 4 > Vec4uc
Interface class between scenegraph and renderer.
void drawPickingEdges_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of edge picking ids with a shader.
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
int getIndex(int _i) const
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking