From 489dbfa9c7bb79f8b799fe7e85e9164929fb23c9 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Wed, 19 Nov 2014 10:09:32 +0000 Subject: [PATCH] Still working on the new rendering engine. more and more modes are working now... --- src/common/meshmodel.cpp | 230 +++++++++++++++++++++++++-------- src/common/meshmodel.h | 53 ++++++-- src/meshlab/glarea.cpp | 50 ++----- src/meshlab/glarea_setting.cpp | 2 - src/meshlab/glarea_setting.h | 2 - 5 files changed, 232 insertions(+), 105 deletions(-) diff --git a/src/common/meshmodel.cpp b/src/common/meshmodel.cpp index 9fc0ade09..d317f7e6c 100644 --- a/src/common/meshmodel.cpp +++ b/src/common/meshmodel.cpp @@ -757,20 +757,33 @@ BufferObjectsRendering::~BufferObjectsRendering() clearState(); } -void BufferObjectsRendering::DrawPoints(vcg::GLW::ColorMode colm, vcg::GLW::NormalMode nolm) +void BufferObjectsRendering::DrawEdges(vcg::GLW::ColorMode colm, vcg::GLW::NormalMode nolm) { - glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); + glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBO); + glVertexPointer(3, GL_FLOAT, 0, 0); // last param is offset, not ptr + glEnableClientState(GL_VERTEX_ARRAY); // activate vertex coords array + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexEdgeBufferObject); + glDrawElements( GL_LINES, en*2, GL_UNSIGNED_INT,0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glDisableClientState(GL_VERTEX_ARRAY); +} + + +void BufferObjectsRendering::DrawPoints(vcg::GLW::ColorMode colm, vcg::GLW::NormalMode nolm, TextureMode tm) +{ + glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBO); glVertexPointer(3, GL_FLOAT, 0, 0); // last param is offset, not ptr glEnableClientState(GL_VERTEX_ARRAY); // activate vertex coords array if(nolm==GLW::NMPerVert) { - glBindBuffer(GL_ARRAY_BUFFER, normalBufferObject); + glBindBuffer(GL_ARRAY_BUFFER, vertexNormalBO); glNormalPointer(GL_FLOAT, 0, 0); // last param is offset, not ptr glEnableClientState(GL_NORMAL_ARRAY); // activate vertex coords array } if(colm == GLW::CMPerVert){ - glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject); + glBindBuffer(GL_ARRAY_BUFFER, vertexColorBO); glColorPointer(4,GL_UNSIGNED_BYTE, 0, 0); // last param is offset, not ptr glEnableClientState(GL_COLOR_ARRAY); // activate vertex coords array } @@ -783,51 +796,73 @@ void BufferObjectsRendering::DrawPoints(vcg::GLW::ColorMode colm, vcg::GLW::Norm glDisableClientState(GL_COLOR_ARRAY); } -void BufferObjectsRendering::DrawTriangles(vcg::GLW::ColorMode colm, vcg::GLW::NormalMode nolm) -{ +/// Two main path of rendering: +/// Plain vertex attribute (normal, color, and texture must be absent or per vertex) +/// Duplicated Vertex rendering (all the other cases) - if(nolm!=GLW::NMPerFace && colm != GLW::CMPerFace) { - glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); +void BufferObjectsRendering::DrawTriangles(vcg::GLW::ColorMode cm, vcg::GLW::NormalMode nm, TextureMode tm) +{ + if(nm!=GLW::NMPerFace && cm != GLW::CMPerFace && tm != GLW::TMPerWedge) + { + glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBO); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, 0); - glBindBuffer(GL_ARRAY_BUFFER, normalBufferObject); - glNormalPointer(GL_FLOAT, 0, 0); - glEnableClientState(GL_NORMAL_ARRAY); + if(nm == GLW::NMPerVert){ + glBindBuffer(GL_ARRAY_BUFFER, vertexNormalBO); + glNormalPointer(GL_FLOAT, 0, 0); + glEnableClientState(GL_NORMAL_ARRAY); + } - if(colm == GLW::CMPerVert){ - glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject); + if(cm == GLW::CMPerVert){ + glBindBuffer(GL_ARRAY_BUFFER, vertexColorBO); glColorPointer(4,GL_UNSIGNED_BYTE, 0, 0); glEnableClientState(GL_COLOR_ARRAY); } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexTriBufferObject); - glDrawElements( GL_TRIANGLES, tn*3, GL_UNSIGNED_INT,0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + if(tm == GLW::TMPerVert){ + glBindBuffer(GL_ARRAY_BUFFER, vertexTextureBO); + glTexCoordPointer(2,GL_FLOAT, 0, 0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + for(size_t i=0;i &chunkMap, std::vector &chunkSizes ) +{ + if(tm==GLW::TMNone) + { + chunkMap.resize(mm.fn); + for(size_t i=0;i > tmpVV(mm.textures.size()); + for(size_t i=0;i nv(mm.vn); std::vector cv(mm.vn); // Per vertex Colors - std::vector rpv(mm.fn*3); - std::vector rnv(mm.fn*3); - std::vector rcv(mm.fn*3); - std::vector rnt(mm.fn*3); - std::vector rct(mm.fn*3); - vn = mm.vn; // In HighPrecisionMode each vertex is pretransformed in double in its final position. @@ -920,42 +976,100 @@ bool BufferObjectsRendering::update(CMeshO& mm, const int updateattributesmask) } } + if(tri::HasPerVertexTexCoord(mm)) + { + std::vector tv(mm.vn*2); // Per vertex Textures + for(size_t i=0;i ti(tn *3); + std::vector < std::vector > ti; + if(mm.textures.size()>1 && tri::HasPerVertexTexCoord(mm)) + { + ti.resize(mm.textures.size()); + for(size_t i=0;iT().n(); + ti[tid].push_back(tri::Index(mm,mm.face[i].V(0))); + ti[tid].push_back(tri::Index(mm,mm.face[i].V(1))); + ti[tid].push_back(tri::Index(mm,mm.face[i].V(2))); + } + } + else + { + ti.resize(1); + ti[0].resize(tn*3); + for(size_t i=0;i > ev; for(size_t i=0;i >::iterator newEnd = + std::unique(ev.begin(), ev.end()); + ev.resize(newEnd-ev.begin()); + en=ev.size(); + + + std::vector rpv(mm.fn*3); + std::vector rnv(mm.fn*3); + std::vector rcv(mm.fn*3); + std::vector rnt(mm.fn*3); + std::vector rct(mm.fn*3); + // Now doing the replicated stuff - for(size_t i=0;i &chunkMap, std::vector &chunkSizes ); //buffer objects update function. Info are collected from the mm and inserted inside the correspondent buffer objects bool update(CMeshO& mm, const int updateattributesmask); // bool requestUpdate(CMeshO& mm, Box3m bb, const int updateattributesmask); @@ -200,16 +208,36 @@ public: //function to clear/deallocate the buffer objects memory space void clearState(); + + std::vector TMId; + private: - bool updateRequested; - CMeshO *m; - int updateattributesmask; + enum BufferObjectType { + OTVertexPosition, + OTVertexNormal, + OTVertexColor, + OTVertexTexture, + OTTriangleIndex, + OTEdgeIndex, + OTFauxEdgeIndex, + OTVertexReplicatedPosition, + OTVertexReplicatedNormal, + OTVertexReplicatedColor, + OTFaceReplicatedNormal, + OTFaceReplicatedColor, + OTWedgeReplicatedTexture, + OTLast + } ; - GLuint positionBufferObject; - GLuint normalBufferObject; - GLuint colorBufferObject; - GLuint indexTriBufferObject; + GLuint bid[OTLast]; + + GLuint vertexPositionBO; + GLuint vertexNormalBO; + GLuint vertexTextureBO; + GLuint vertexColorBO; + std::vector indexTriBufferObject; + std::vector indexTriBufferObjectSz; GLuint indexEdgeBufferObject; GLuint positionDupBufferObject; @@ -217,6 +245,8 @@ private: GLuint colorDupBufferObject; GLuint normalFaceBufferObject; GLuint colorFaceBufferObject; + GLuint edgeBufferObject; + GLuint edgeFauxBufferObject; bool HighPrecisionMode; @@ -241,9 +271,10 @@ private: Matrix44m Tr; int vn; + int en; + int efn; int tn; - QReadWriteLock _lock; }; diff --git a/src/meshlab/glarea.cpp b/src/meshlab/glarea.cpp index 94876a66c..9885567ee 100644 --- a/src/meshlab/glarea.cpp +++ b/src/meshlab/glarea.cpp @@ -1275,40 +1275,22 @@ void GLArea::initTexture(bool reloadAllTexture) { foreach (MeshModel *mp,this->md()->meshList) { - if(!mp->glw.TMId.empty()) - { - glDeleteTextures(1,&(mp->glw.TMId[0])); - mp->glw.TMId.clear(); - } + if(!mp->bor.TMId.empty()) + glDeleteTextures(mp->bor.TMId.size(), &(mp->bor.TMId[0])); + mp->bor.TMId.clear(); } } - size_t totalTextureNum=0, toBeUpdatedNum=0; - foreach (MeshModel *mp, this->md()->meshList) - { - totalTextureNum+=mp->cm.textures.size(); - if(!mp->cm.textures.empty() && mp->glw.TMId.empty()) toBeUpdatedNum++; - } - - if(toBeUpdatedNum==0) return; - - int singleMaxTextureSizeMpx = int(glas.maxTextureMemory/totalTextureNum); - int singleMaxTextureSize = RoundUpToTheNextHighestPowerOf2(int(sqrt(float(singleMaxTextureSizeMpx))*1024.0))/2; glEnable(GL_TEXTURE_2D); GLint MaxTextureSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&MaxTextureSize); - if(singleMaxTextureSize < MaxTextureSize) - { - this->Logf(0,"There are too many textures (%i), reducing max texture size from %i to %i",totalTextureNum,MaxTextureSize,singleMaxTextureSize); - MaxTextureSize = singleMaxTextureSize; - } - foreach (MeshModel *mp, this->md()->meshList) { - if(!mp->cm.textures.empty() && mp->glw.TMId.empty()) + if(!mp->cm.textures.empty() && mp->bor.TMId.empty()) { QString unexistingtext = "In mesh file " + mp->fullName() + " : Failure loading textures:
"; bool sometextfailed = false; + Logf(GLLogStream::SYSTEM,"Loading textures"); for(unsigned int i =0; i< mp->cm.textures.size();++i) { QImage img, imgScaled, imgGL; @@ -1317,26 +1299,18 @@ void GLArea::initTexture(bool reloadAllTexture) sometextfailed = sometextfailed || !res; if(!res) { - // Note that sometimes (in collada) the texture names could have been encoded with a url-like style (e.g. replacing spaces with '%20') so making some other attempt could be harmless - QString ConvertedName = QString(mp->cm.textures[i].c_str()).replace(QString("%20"), QString(" ")); - res = img.load(ConvertedName); + res = img.load(mp->cm.textures[i].c_str()); if(!res) { this->Logf(0,"Failure of loading texture %s",mp->cm.textures[i].c_str()); unexistingtext += "" + QString(mp->cm.textures[i].c_str()) + "
"; } - else - this->Logf(0,"Warning, texture loading was successful only after replacing %%20 with spaces;\n Loaded texture %s instead of %s",qPrintable(ConvertedName),mp->cm.textures[i].c_str()); - /*mp->glw.TMId.push_back(0); - glGenTextures( 1, (GLuint*)&(mp->glw.TMId.back()) ); - glBindTexture( GL_TEXTURE_2D, mp->glw.TMId.back() ); - glTexImage2D( GL_TEXTURE_2D, 0, 3, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );*/ } if(!res && QString(mp->cm.textures[i].c_str()).endsWith("dds",Qt::CaseInsensitive)) { qDebug("DDS binding!"); int newTexId = bindTexture(QString(mp->cm.textures[i].c_str())); - mp->glw.TMId.push_back(newTexId); + mp->bor.TMId.push_back(newTexId); } if (!res) res = img.load(":/images/dummy.png"); @@ -1347,15 +1321,13 @@ void GLArea::initTexture(bool reloadAllTexture) int bestH=RoundUpToTheNextHighestPowerOf2(img.height() ); while(bestW>MaxTextureSize) bestW /=2; while(bestH>MaxTextureSize) bestH /=2; - - Logf(GLLogStream::SYSTEM,"Loading textures"); Logf(GLLogStream::SYSTEM," Texture[ %3i ] = '%s' ( %6i x %6i ) -> ( %6i x %6i )", i,mp->cm.textures[i].c_str(), img.width(), img.height(),bestW,bestH); imgScaled=img.scaled(bestW,bestH,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); imgGL=convertToGLFormat(imgScaled); - mp->glw.TMId.push_back(0); - glGenTextures( 1, (GLuint*)&(mp->glw.TMId.back()) ); - glBindTexture( GL_TEXTURE_2D, mp->glw.TMId.back() ); - qDebug(" will be loaded as GL texture id %i ( %i x %i )",mp->glw.TMId.back() ,imgGL.width(), imgGL.height()); + mp->bor.TMId.push_back(0); + glGenTextures( 1, (GLuint*)&(mp->bor.TMId.back()) ); + glBindTexture( GL_TEXTURE_2D, mp->bor.TMId.back() ); + qDebug(" will be loaded as GL texture id %i ( %i x %i )",mp->bor.TMId.back() ,imgGL.width(), imgGL.height()); glTexImage2D( GL_TEXTURE_2D, 0, 3, imgGL.width(), imgGL.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, imgGL.bits() ); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgGL.width(), imgGL.height(), GL_RGBA, GL_UNSIGNED_BYTE, imgGL.bits() ); } diff --git a/src/meshlab/glarea_setting.cpp b/src/meshlab/glarea_setting.cpp index 6a1bb1bec..e2c5daef6 100644 --- a/src/meshlab/glarea_setting.cpp +++ b/src/meshlab/glarea_setting.cpp @@ -24,7 +24,6 @@ void GLAreaSetting::initGlobalParameterSet( RichParameterSet * defaultGlobalPara defaultGlobalParamSet->addParam(new RichBool(pointDistanceAttenuationParam() , true,"Perspective Varying Point Size","If true the size of the points is drawn with a size proprtional to the distance from the observer.")); defaultGlobalParamSet->addParam(new RichBool(pointSmoothParam() , false,"Antialiased Point","If true the points are drawn with small circles instead of fast squared dots.")); defaultGlobalParamSet->addParam(new RichFloat(pointSizeParam() , 2.0, "Point Size","The base size of points when drawn")); - defaultGlobalParamSet->addParam(new RichInt(maxTextureMemoryParam() , 256, "Max Texture Memory (in MB)","The maximum quantity of texture memory allowed to load mesh textures")); } @@ -47,6 +46,5 @@ void GLAreaSetting::updateGlobalParameterSet( RichParameterSet& rps ) pointDistanceAttenuation = rps.getBool(this->pointDistanceAttenuationParam()); pointSmooth = rps.getBool(this->pointSmoothParam()); pointSize = rps.getFloat(this->pointSizeParam()); - maxTextureMemory = rps.getInt(this->maxTextureMemoryParam()); currentGlobalParamSet=&rps; } diff --git a/src/meshlab/glarea_setting.h b/src/meshlab/glarea_setting.h index f074c64f0..4eb4b6af4 100644 --- a/src/meshlab/glarea_setting.h +++ b/src/meshlab/glarea_setting.h @@ -39,8 +39,6 @@ public: inline static QString pointSmoothParam() {return "MeshLab::Appearance::pointSmooth";} float pointSize; inline static QString pointSizeParam() {return "MeshLab::Appearance::pointSize";} - inline static QString maxTextureMemoryParam() {return "MeshLab::Appearance::maxTextureMemory";} - int maxTextureMemory; void updateGlobalParameterSet( RichParameterSet& rps ); static void initGlobalParameterSet( RichParameterSet * defaultGlobalParamSet);