- updated version of the gl_mesh_attributes_feeder class

- class has been cleaned up
- still strange "don't update" bug
This commit is contained in:
granzuglia 2015-10-09 03:05:57 +00:00
parent 8fab7af2c6
commit 4403fb04d1
1 changed files with 1401 additions and 1362 deletions

View File

@ -40,8 +40,8 @@
namespace vcg namespace vcg
{ {
struct GLFeederInfo struct GLFeederInfo
{ {
struct GLFeederException : public std::exception struct GLFeederException : public std::exception
{ {
GLFeederException(const char* text) GLFeederException(const char* text)
@ -184,18 +184,49 @@ struct GLFeederInfo
return res; return res;
} }
static bool isReplicatedPipeline(const ReqAtts& rqatt)
{
return (rqatt[ATT_FACENORMAL] || rqatt[ATT_FACECOLOR] || rqatt[ATT_WEDGETEXTURE]);
}
static bool isVertexIndexingRequired(const ReqAtts& rqatt)
{
PRIMITIVE_MODALITY pm = rqatt.primitiveModality();
return (!isReplicatedPipeline(rqatt) && (pm != PR_POINTS) && (pm != PR_NONE));
}
template<typename MESHTYPE>
static void computeARequestedAttributesSetCompatibleWithMesh(ReqAtts& rqatt,const MESHTYPE& mesh)
{
if (mesh.VN() == 0)
{
rqatt.reset();
return;
}
rqatt[ATT_VERTPOSITION] = true;
rqatt[ATT_VERTNORMAL] = rqatt[ATT_VERTNORMAL] && vcg::tri::HasPerVertexNormal(mesh);
rqatt[ATT_FACENORMAL] = rqatt[ATT_FACENORMAL] && vcg::tri::HasPerFaceNormal(mesh);
rqatt[ATT_VERTCOLOR] = rqatt[ATT_VERTCOLOR] && vcg::tri::HasPerVertexColor(mesh);
rqatt[ATT_FACECOLOR] = rqatt[ATT_FACECOLOR] && vcg::tri::HasPerFaceColor(mesh);
rqatt[ATT_MESHCOLOR] = rqatt[ATT_MESHCOLOR];
rqatt[ATT_VERTTEXTURE] = rqatt[ATT_VERTTEXTURE] && vcg::tri::HasPerVertexTexCoord(mesh);
rqatt[ATT_WEDGETEXTURE] = rqatt[ATT_WEDGETEXTURE] && vcg::tri::HasPerWedgeTexCoord(mesh);
rqatt[ATT_VERTINDEX] = isVertexIndexingRequired(rqatt);
}
protected: protected:
static const size_t _attssize = ATT_NAMES_ARITY; static const size_t _attssize = ATT_NAMES_ARITY;
bool _atts[_attssize]; bool _atts[_attssize];
PRIMITIVE_MODALITY _pm; PRIMITIVE_MODALITY _pm;
}; };
}; };
//WARNING! member functions of this class should be called by the host application using concurrency //WARNING! member functions of this class should be called by the host application using concurrency
template <typename MESHTYPE> template <typename MESHTYPE>
class GLMeshAttributesFeeder : public GLFeederInfo class GLMeshAttributesFeeder : public GLFeederInfo
{ {
public: public:
GLMeshAttributesFeeder(/*const*/ MESHTYPE& mesh,MemoryInfo& meminfo, size_t perbatchprimitives) GLMeshAttributesFeeder(/*const*/ MESHTYPE& mesh,MemoryInfo& meminfo, size_t perbatchprimitives)
:_mesh(mesh),_gpumeminfo(meminfo),_bo(ATT_NAMES_ARITY,NULL),_currallocatedboatt(),_lastfeedingusedreplicatedpipeline(false),_perbatchprim(perbatchprimitives),_chunkmap(),_borendering(false),_rendermodinitialized(false) :_mesh(mesh),_gpumeminfo(meminfo),_bo(ATT_NAMES_ARITY,NULL),_currallocatedboatt(),_lastfeedingusedreplicatedpipeline(false),_perbatchprim(perbatchprimitives),_chunkmap(),_borendering(false),_rendermodinitialized(false)
{ {
@ -218,73 +249,73 @@ public:
_bo.clear(); _bo.clear();
} }
void meshAttributesUpdated(int mask) //void meshAttributesUpdated(int mask)
{ //{
if ((_mesh.VN() != _mesh.vert.size()) || (_mesh.FN() != _mesh.face.size())) // if ((_mesh.VN() != _mesh.vert.size()) || (_mesh.FN() != _mesh.face.size()))
{ // {
throw GLFeederException("The current mesh contains vertices/faces marked as deleted!\nPlease, call the compact vectors function in order to properly remove them\n"); // throw GLFeederException("The current mesh contains vertices/faces marked as deleted!\nPlease, call the compact vectors function in order to properly remove them\n");
return; // return;
} // }
if (!_rendermodinitialized) // if (!_rendermodinitialized)
{ // {
throw GLFeederException("Required attributes for rendering were not properly initialized\nInvokation of setAttributesToBeRendered function is strictly required!\n"); // throw GLFeederException("Required attributes for rendering were not properly initialized\nInvokation of setAttributesToBeRendered function is strictly required!\n");
return; // return;
} // }
bool boupdatedrequired = false; // bool boupdatedrequired = false;
if (((mask & attBitMask(GLFeederInfo::ATT_VERTPOSITION)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_VERTPOSITION])) // if (((mask & attBitMask(GLFeederInfo::ATT_VERTPOSITION)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_VERTPOSITION]))
{ // {
boupdatedrequired = true; // boupdatedrequired = true;
_bo[GLFeederInfo::ATT_VERTPOSITION]->_isvalid = false; // _bo[GLFeederInfo::ATT_VERTPOSITION]->_isvalid = false;
} // }
if (((mask & attBitMask(GLFeederInfo::ATT_VERTNORMAL)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_VERTNORMAL] && vcg::tri::HasPerVertexNormal(_mesh))) // if (((mask & attBitMask(GLFeederInfo::ATT_VERTNORMAL)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_VERTNORMAL] && vcg::tri::HasPerVertexNormal(_mesh)))
{ // {
boupdatedrequired = true; // boupdatedrequired = true;
_bo[GLFeederInfo::ATT_VERTNORMAL]->_isvalid = false; // _bo[GLFeederInfo::ATT_VERTNORMAL]->_isvalid = false;
} // }
if (((mask & attBitMask(GLFeederInfo::ATT_FACENORMAL)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_FACENORMAL] && vcg::tri::HasPerFaceNormal(_mesh))) // if (((mask & attBitMask(GLFeederInfo::ATT_FACENORMAL)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_FACENORMAL] && vcg::tri::HasPerFaceNormal(_mesh)))
{ // {
boupdatedrequired = true; // boupdatedrequired = true;
_bo[GLFeederInfo::ATT_FACENORMAL]->_isvalid = false; // _bo[GLFeederInfo::ATT_FACENORMAL]->_isvalid = false;
} // }
if (((mask & attBitMask(GLFeederInfo::ATT_VERTCOLOR)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_VERTCOLOR] && vcg::tri::HasPerVertexColor(_mesh))) // if (((mask & attBitMask(GLFeederInfo::ATT_VERTCOLOR)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_VERTCOLOR] && vcg::tri::HasPerVertexColor(_mesh)))
{ // {
boupdatedrequired = true; // boupdatedrequired = true;
_bo[GLFeederInfo::ATT_VERTCOLOR]->_isvalid = false; // _bo[GLFeederInfo::ATT_VERTCOLOR]->_isvalid = false;
} // }
if (((mask & attBitMask(GLFeederInfo::ATT_FACECOLOR)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_FACECOLOR] && vcg::tri::HasPerFaceColor(_mesh))) // if (((mask & attBitMask(GLFeederInfo::ATT_FACECOLOR)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_FACECOLOR] && vcg::tri::HasPerFaceColor(_mesh)))
{ // {
boupdatedrequired = true; // boupdatedrequired = true;
_bo[GLFeederInfo::ATT_FACECOLOR]->_isvalid = false; // _bo[GLFeederInfo::ATT_FACECOLOR]->_isvalid = false;
} // }
if (((mask & attBitMask(GLFeederInfo::ATT_VERTTEXTURE)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_VERTTEXTURE] && vcg::tri::HasPerVertexTexCoord(_mesh))) // if (((mask & attBitMask(GLFeederInfo::ATT_VERTTEXTURE)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_VERTTEXTURE] && vcg::tri::HasPerVertexTexCoord(_mesh)))
{ // {
boupdatedrequired = true; // boupdatedrequired = true;
_bo[GLFeederInfo::ATT_VERTTEXTURE]->_isvalid = false; // _bo[GLFeederInfo::ATT_VERTTEXTURE]->_isvalid = false;
} // }
if (((mask & attBitMask(GLFeederInfo::ATT_WEDGETEXTURE)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_WEDGETEXTURE] && vcg::tri::HasPerWedgeTexCoord(_mesh))) // if (((mask & attBitMask(GLFeederInfo::ATT_WEDGETEXTURE)) || (mask & attBitMask(ATT_ALL))) && (_currallocatedboatt[ATT_WEDGETEXTURE] && vcg::tri::HasPerWedgeTexCoord(_mesh)))
{ // {
boupdatedrequired = true; // boupdatedrequired = true;
_bo[GLFeederInfo::ATT_WEDGETEXTURE]->_isvalid = false; // _bo[GLFeederInfo::ATT_WEDGETEXTURE]->_isvalid = false;
} // }
if (mask & attBitMask(ATT_ALL)) // if (mask & attBitMask(ATT_ALL))
{ // {
boupdatedrequired = true; // boupdatedrequired = true;
_bo[GLFeederInfo::ATT_VERTINDEX]->_isvalid = false; // _bo[GLFeederInfo::ATT_VERTINDEX]->_isvalid = false;
} // }
if (boupdatedrequired) // if (boupdatedrequired)
tryToAllocateAttributesInBO(); // tryToAllocateAndCopyAttributesInBO();
} //}
ReqAtts setupRequestedAttributes(const ReqAtts& rq,bool& allocated) ReqAtts setupRequestedAttributes(const ReqAtts& rq,bool& allocated)
{ {
@ -294,9 +325,9 @@ public:
try try
{ {
ReqAtts tmp = rq; ReqAtts tmp = rq;
computeARequestedAttributesSetCompatibleWithMesh(tmp,_mesh); ReqAtts::computeARequestedAttributesSetCompatibleWithMesh(tmp,_mesh);
_currallocatedboatt = ReqAtts::setUnion(_currallocatedboatt,tmp); tmp = ReqAtts::setUnion(_currallocatedboatt,tmp);
allocated = tryToAllocateAttributesInBO(); allocated = tryToAllocateAndCopyAttributesInBO(tmp);
return tmp; return tmp;
} }
catch (GLFeederException& e) catch (GLFeederException& e)
@ -311,17 +342,40 @@ public:
return _currallocatedboatt = ReqAtts::setComplement(rq,_currallocatedboatt); return _currallocatedboatt = ReqAtts::setComplement(rq,_currallocatedboatt);
} }
void buffersDeAllocationRequested() void invalidateRequestedAttributes(const ReqAtts& rq)
{ {
size_t ii = 0;
for(typename std::vector<GLBufferObject*>::iterator it = _bo.begin();it != _bo.end();++it) for(typename std::vector<GLBufferObject*>::iterator it = _bo.begin();it != _bo.end();++it)
{ {
if ((*it != NULL) && ((*it)->_isvalid)) ATT_NAMES boname = static_cast<ATT_NAMES>(ii);
{ if ((*it != NULL) && (rq[boname]))
glDeleteBuffers(1,&((*it)->_bohandle));
(*it)->_isvalid = false; (*it)->_isvalid = false;
(*it)->_bohandle = 0; ++ii;
} }
} }
void buffersDeAllocationRequested()
{
size_t ii = 0;
for(typename std::vector<GLBufferObject*>::iterator it = _bo.begin();it != _bo.end();++it)
{
ATT_NAMES boname = static_cast<ATT_NAMES>(ii);
if (*it != NULL)
bufferDeAllocationRequested(boname);
++ii;
}
}
void buffersDeAllocationRequested(const ReqAtts& rq)
{
size_t ii = 0;
for(typename std::vector<GLBufferObject*>::iterator it = _bo.begin();it != _bo.end();++it)
{
ATT_NAMES boname = static_cast<ATT_NAMES>(ii);
if ((*it != NULL) && (rq[boname]))
bufferDeAllocationRequested(boname);
++ii;
}
} }
void draw(const ReqAtts& rq,const std::vector<GLuint> textid = std::vector<GLuint>()) void draw(const ReqAtts& rq,const std::vector<GLuint> textid = std::vector<GLuint>())
@ -362,26 +416,22 @@ public:
return _borendering; return _borendering;
} }
static bool isVertexIndexingRequired(const ReqAtts& rqatt)
{
PRIMITIVE_MODALITY pm = rqatt.primitiveModality();
return (!isReplicatedPipeline(rqatt) && (pm != PR_POINTS) && (pm != PR_NONE));
}
void invalidateRequestedAttributes(ReqAtts& rq)
{
size_t ii = 0;
for(typename std::vector<GLBufferObject*>::iterator it = _bo.begin();it != _bo.end();++it)
{
ATT_NAMES boname = static_cast<ATT_NAMES>(ii);
if (((*it) != NULL) && (rq[boname]))
(*it)->_isvalid = false;
++ii;
}
_currallocatedboatt = vcg::GLFeederInfo::ReqAtts::setComplement(_currallocatedboatt,rq);
}
protected: //void invalidateRequestedAttributes(ReqAtts& rq)
//{
// size_t ii = 0;
// for(typename std::vector<GLBufferObject*>::iterator it = _bo.begin();it != _bo.end();++it)
// {
// ATT_NAMES boname = static_cast<ATT_NAMES>(ii);
// if (((*it) != NULL) && (rq[boname]))
// (*it)->_isvalid = false;
// ++ii;
// }
// //_currallocatedboatt = vcg::GLFeederInfo::ReqAtts::setComplement(_currallocatedboatt,rq);
//}
protected:
struct GLBufferObject struct GLBufferObject
{ {
GLBufferObject(size_t components,GLenum gltype,GLenum clientstatetag,GLenum target) GLBufferObject(size_t components,GLenum gltype,GLenum clientstatetag,GLenum target)
@ -429,37 +479,39 @@ protected:
return _bo[boname]; return _bo[boname];
} }
static void computeARequestedAttributesSetCompatibleWithMesh(ReqAtts& rqatt,const MESHTYPE& mesh) void bufferDeAllocationRequested(const ATT_NAMES att)
{ {
if (mesh.VN() == 0) size_t ind = static_cast<size_t>(att);
{ if ((ind < 0) || (ind >= _bo.size()))
rqatt.reset();
return; return;
GLBufferObject* bobj = _bo[att];
if (bobj == NULL)
return;
GLenum err = glGetError();
assert(err == GL_NO_ERROR);
if ((att != ATT_VERTINDEX ) && (ATT_MESHCOLOR))
glDisableClientState(bobj->_clientstatetag);
err = glGetError();
assert(err == GL_NO_ERROR);
glDeleteBuffers(1,&(bobj->_bohandle));
err = glGetError();
assert(err == GL_NO_ERROR);
bobj->_bohandle = 0;
if (bobj->_size > 0)
//we don't use dim cause dim is the value that is going to be allocated, instead use (*it)->_size * (*it)->getSizeOfGLType() is the value already in the buffer
_gpumeminfo.releasedMemory(bobj->_size * bobj->getSizeOfGLType());
bobj->_isvalid = false;
bobj->_size = 0;
_currallocatedboatt[att] = false;
} }
rqatt[ATT_VERTPOSITION] = true; bool buffersAllocationFunction(const ReqAtts& req,std::vector<bool>& attributestobeupdated)
rqatt[ATT_VERTNORMAL] = rqatt[ATT_VERTNORMAL] && vcg::tri::HasPerVertexNormal(mesh);
rqatt[ATT_FACENORMAL] = rqatt[ATT_FACENORMAL] && vcg::tri::HasPerFaceNormal(mesh);
rqatt[ATT_VERTCOLOR] = rqatt[ATT_VERTCOLOR] && vcg::tri::HasPerVertexColor(mesh);
rqatt[ATT_FACECOLOR] = rqatt[ATT_FACECOLOR] && vcg::tri::HasPerFaceColor(mesh);
rqatt[ATT_MESHCOLOR] = rqatt[ATT_MESHCOLOR];
rqatt[ATT_VERTTEXTURE] = rqatt[ATT_VERTTEXTURE] && vcg::tri::HasPerVertexTexCoord(mesh);
rqatt[ATT_WEDGETEXTURE] = rqatt[ATT_WEDGETEXTURE] && vcg::tri::HasPerWedgeTexCoord(mesh);
rqatt[ATT_VERTINDEX] = isVertexIndexingRequired(rqatt);
}
static bool isReplicatedPipeline(const ReqAtts& rqatt)
{ {
return (rqatt[ATT_FACENORMAL] || rqatt[ATT_FACECOLOR] || rqatt[ATT_WEDGETEXTURE]); bool replicated = ReqAtts::isReplicatedPipeline(req);
}
bool buffersAllocationFunction(std::vector<bool>& attributestobeupdated)
{
bool replicated = isReplicatedPipeline(_currallocatedboatt);
attributestobeupdated.clear(); attributestobeupdated.clear();
attributestobeupdated.resize(_bo.size()); attributestobeupdated.resize(_bo.size());
std::ptrdiff_t bomemoryrequiredbymesh = bufferObjectsMemoryRequired(_currallocatedboatt); std::ptrdiff_t bomemoryrequiredbymesh = bufferObjectsMemoryRequired(req);
bool generateindex = isVertexIndexingRequired(_currallocatedboatt); bool generateindex = ReqAtts::isVertexIndexingRequired(req);
unsigned int ii = 0; unsigned int ii = 0;
for(typename std::vector<GLBufferObject*>::iterator it = _bo.begin();it != _bo.end();++it) for(typename std::vector<GLBufferObject*>::iterator it = _bo.begin();it != _bo.end();++it)
@ -474,7 +526,7 @@ protected:
((!(*it)->_isvalid) && (sz != (*it)->_size)) || ((!(*it)->_isvalid) && (sz != (*it)->_size)) ||
/*if _lastfeedingusedreplicatedpipeline == false means that maybe there are valid per vertex attribute buffer objects that MUST be reallocated anyway cause we have to switch to the replicated attributes pipeline*/ /*if _lastfeedingusedreplicatedpipeline == false means that maybe there are valid per vertex attribute buffer objects that MUST be reallocated anyway cause we have to switch to the replicated attributes pipeline*/
(replicated && !_lastfeedingusedreplicatedpipeline && (isPerVertexAttribute(boname) || (boname == GLFeederInfo::ATT_VERTINDEX))) || (replicated && !_lastfeedingusedreplicatedpipeline && (isPerVertexAttribute(boname) || (boname == GLFeederInfo::ATT_VERTINDEX))) ||
/*we switched back from the replicated pipeline to the normal one. All the bos have to be regenerated*/ /*we switched back from the replicated pipeline to the indexed one. All the bos have to be regenerated*/
(!replicated && _lastfeedingusedreplicatedpipeline) || (!replicated && _lastfeedingusedreplicatedpipeline) ||
/*the buffer object is valid but for same reason the number of cells of the bo don't suit anymore the required size. we have to reallocate the buffer object*/ /*the buffer object is valid but for same reason the number of cells of the bo don't suit anymore the required size. we have to reallocate the buffer object*/
(((*it)->_isvalid) && (sz != (*it)->_size)) (((*it)->_isvalid) && (sz != (*it)->_size))
@ -483,19 +535,7 @@ protected:
/*(((*it)->_isvalid) && !isAttributeRequiredToBeDisplayed(boname)))*/ /*(((*it)->_isvalid) && !isAttributeRequiredToBeDisplayed(boname)))*/
)) ))
{ {
bufferDeAllocationRequested(boname);
//disableClientState(boname,importattribute);
/*WARNING! THIS CODE MUST BE INCAPSULATED INTO A DEALLOCATE FUNCTION IN A PROPER MADE BUFFER OBJECT CLASS
I DON'T INSERT IT INTO THE GLBufferObjectInfo CLASS CAUSE I CONSIDER IT A TEMPORARY PRIVATE STRUCT*/
glDeleteBuffers(1,&((*it)->_bohandle));
(*it)->_bohandle = 0;
if ((*it)->_size > 0)
//we don't use dim cause dim is the value that is going to be allocated, instead use (*it)->_size * (*it)->getSizeOfGLType() is the value already in the buffer
_gpumeminfo.releasedMemory((*it)->_size * (*it)->getSizeOfGLType());
(*it)->_isvalid = false;
(*it)->_size = 0;
/**********************************************************************************************************/
} }
/*there are already mesh attributes properly allocated in memory, we don't need to allocate them again. there could be invalid values attributes but with properly memory space already allocated in memory /*there are already mesh attributes properly allocated in memory, we don't need to allocate them again. there could be invalid values attributes but with properly memory space already allocated in memory
(i.e. i changed the pervertex colors but the vertex numbers remained constant)*/ (i.e. i changed the pervertex colors but the vertex numbers remained constant)*/
@ -516,21 +556,24 @@ protected:
//we have to deallocate the previously allocated mesh attributes //we have to deallocate the previously allocated mesh attributes
if ((*it != NULL) && ((sz == (*it)->_size))) if ((*it != NULL) && ((sz == (*it)->_size)))
{ {
std::ptrdiff_t dim(boExpectedDimension(boname,replicated,_currallocatedboatt[GLFeederInfo::ATT_VERTINDEX])); ////std::ptrdiff_t dim(boExpectedDimension(boname,replicated,_currallocatedboatt[GLFeederInfo::ATT_VERTINDEX]));
//disableClientState(boname,importattribute); //std::ptrdiff_t dim(boExpectedDimension(boname,replicated,generateindex));
if ((*it)->_size > 0) ////disableClientState(boname,importattribute);
{ //if ((*it)->_size > 0)
//{
/*WARNING! THIS CODE MUST BE INCAPSULATED INTO A DEALLOCATE FUNCTION IN A PROPER MADE BUFFER OBJECT CLASS // /*WARNING! THIS CODE MUST BE INCAPSULATED INTO A DEALLOCATE FUNCTION IN A PROPER MADE BUFFER OBJECT CLASS
I DON'T INSERT IT INTO THE GLBufferObjectInfo CLASS CAUSE I CONSIDER IT A TEMPORARY PRIVATE STRUCT*/ // I DON'T INSERT IT INTO THE GLBufferObjectInfo CLASS CAUSE I CONSIDER IT A TEMPORARY PRIVATE STRUCT*/
glDeleteBuffers(1,&(*it)->_bohandle); // glDeleteBuffers(1,&(*it)->_bohandle);
(*it)->_bohandle = 0; // (*it)->_bohandle = 0;
_gpumeminfo.releasedMemory(dim); // _gpumeminfo.releasedMemory(dim);
} //}
(*it)->_isvalid = false; //(*it)->_isvalid = false;
(*it)->_size = 0; //(*it)->_size = 0;
/*********************************************************************************************************/ ///*********************************************************************************************************/
//_currallocatedboatt[boname] = false;
bufferDeAllocationRequested(boname);
} }
++ii; ++ii;
} }
@ -540,25 +583,26 @@ protected:
} }
else else
{ {
unsigned int ii = 0;
//I have to update the invalid buffers requested to be imported //I have to update the invalid buffers requested to be imported
for(size_t kk = 0;kk < attributestobeupdated.size();++kk) for(size_t kk = 0;kk < attributestobeupdated.size();++kk)
attributestobeupdated[kk] = _currallocatedboatt[static_cast<ATT_NAMES>(kk)]; attributestobeupdated[kk] = req[static_cast<ATT_NAMES>(kk)];
bool failedallocation = false; bool failedallocation = false;
size_t ii = 0;
typename std::vector<GLBufferObject*>::iterator it = _bo.begin(); typename std::vector<GLBufferObject*>::iterator it = _bo.begin();
while((it != _bo.end()) && (!failedallocation)) while((it != _bo.end()) && (!failedallocation))
{ {
ATT_NAMES boname = static_cast<ATT_NAMES>(ii); ATT_NAMES boname = static_cast<ATT_NAMES>(ii);
GLBufferObject* cbo = _bo.at(boname); GLBufferObject* cbo = _bo.at(boname);
bool importatt = _currallocatedboatt[boname]; bool importatt = req[boname];
//glBindVertexArray(vaohandlespecificperopenglcontext); //glBindVertexArray(vaohandlespecificperopenglcontext);
/*if a bo is not valid but at this point has a valid handle means that attribute values have been updated but the arity of the vertices/faces didn't change. i can use the already allocated space*/ /*if a bo is not valid but at this point has a valid handle means that attribute values have been updated but the arity of the vertices/faces didn't change. i can use the already allocated space*/
bool notvalidbuttoberegenerated = (cbo != NULL) && (!cbo->_isvalid) && (cbo->_bohandle == 0) && (importatt); bool notvalidandtoberegenerated = (cbo != NULL) && (!cbo->_isvalid) && (cbo->_bohandle == 0) && (importatt);
if (notvalidbuttoberegenerated) if (notvalidandtoberegenerated)
{ {
cbo->_size = boExpectedSize(boname,replicated,_currallocatedboatt[GLFeederInfo::ATT_VERTINDEX]); cbo->_size = boExpectedSize(boname,replicated,generateindex);
std::ptrdiff_t dim = boExpectedDimension(boname,replicated,_currallocatedboatt[GLFeederInfo::ATT_VERTINDEX]); std::ptrdiff_t dim = boExpectedDimension(boname,replicated,generateindex);
glGenBuffers(1, &cbo->_bohandle); glGenBuffers(1, &cbo->_bohandle);
glBindBuffer(cbo->_target, cbo->_bohandle); glBindBuffer(cbo->_target, cbo->_bohandle);
@ -579,17 +623,23 @@ protected:
cbo->_isvalid = !failedallocation; cbo->_isvalid = !failedallocation;
_borendering = !failedallocation; _borendering = !failedallocation;
glBindBuffer(cbo->_target, 0); glBindBuffer(cbo->_target, 0);
_currallocatedboatt[boname] = !failedallocation;
} }
else else
{ {
attributestobeupdated[boname] = false; attributestobeupdated[boname] = false;
//values in the bo have to be updated but the arity of the attribute doesn't change. i can use the already allocated space without reallocating it
if ((cbo != NULL) && (!cbo->_isvalid) && (cbo->_bohandle != 0) && (importatt)) if ((cbo != NULL) && (!cbo->_isvalid) && (cbo->_bohandle != 0) && (importatt))
{ {
attributestobeupdated[boname] = true; attributestobeupdated[boname] = true;
cbo->_isvalid = true; cbo->_isvalid = true;
_currallocatedboatt[boname] = true;
} }
if ((cbo != NULL) && (!importatt)) if ((cbo != NULL) && (!importatt))
{
cbo->_isvalid = false; cbo->_isvalid = false;
_currallocatedboatt[boname] = false;
}
} }
//if ((cbo == NULL) || (!cbo->_isvalid)) //if ((cbo == NULL) || (!cbo->_isvalid))
@ -603,29 +653,18 @@ protected:
//glBindVertexArray(0); //glBindVertexArray(0);
} }
if (failedallocation) if (failedallocation)
{ buffersDeAllocationRequested();
for(typename std::vector<GLBufferObject*>::iterator boit = _bo.begin();boit != _bo.end();++boit) _borendering = !failedallocation;
{
glDeleteBuffers(1,&((*it)->_bohandle));
(*it)->_bohandle = 0;
if ((*it)->_size > 0)
//we don't use dim cause dim is the value that is going to be allocated, instead use (*it)->_size * (*it)->getSizeOfGLType() is the value already in the buffer
_gpumeminfo.releasedMemory((*it)->_size * (*it)->getSizeOfGLType());
(*it)->_isvalid = false;
(*it)->_size = 0;
}
}
_borendering = true;
_lastfeedingusedreplicatedpipeline = replicated; _lastfeedingusedreplicatedpipeline = replicated;
return true; return _borendering;
} }
} }
bool tryToAllocateAttributesInBO() bool tryToAllocateAndCopyAttributesInBO(const ReqAtts& req)
{ {
std::vector<bool> attributestobeupdated; std::vector<bool> attributestobeupdated;
bool replicated = isReplicatedPipeline(_currallocatedboatt); bool immediatemode = !(buffersAllocationFunction(req,attributestobeupdated));
bool immediatemode = !(buffersAllocationFunction(attributestobeupdated)); bool replicated = ReqAtts::isReplicatedPipeline(_currallocatedboatt);
if (immediatemode) if (immediatemode)
return false; return false;
@ -1123,11 +1162,11 @@ protected:
if((!isPossibleToUseBORendering()) || (_mesh.VN() == 0)) if((!isPossibleToUseBORendering()) || (_mesh.VN() == 0))
return; return;
updateClientState(req); updateClientState(req);
bool replicated = isReplicatedPipeline(_currallocatedboatt); bool replicated = ReqAtts::isReplicatedPipeline(_currallocatedboatt);
if (replicated) if (replicated)
{ {
qDebug("Replicated drawing"); //qDebug("Replicated drawing");
int firsttriangleoffset = 0; int firsttriangleoffset = 0;
if(!req[ATT_VERTTEXTURE] && !req[ATT_WEDGETEXTURE]) if(!req[ATT_VERTTEXTURE] && !req[ATT_WEDGETEXTURE])
{ {
@ -1168,7 +1207,7 @@ protected:
if (_bo[ATT_VERTINDEX]->_isvalid) if (_bo[ATT_VERTINDEX]->_isvalid)
{ {
qDebug("Indexed drawing"); //qDebug("Indexed drawing");
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,_bo[ATT_VERTINDEX]->_bohandle); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,_bo[ATT_VERTINDEX]->_bohandle);
glDrawElements( GL_TRIANGLES, _mesh.fn * _bo[ATT_VERTINDEX]->_components,GL_UNSIGNED_INT ,NULL); glDrawElements( GL_TRIANGLES, _mesh.fn * _bo[ATT_VERTINDEX]->_components,GL_UNSIGNED_INT ,NULL);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@ -1201,7 +1240,7 @@ protected:
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _bo[GLFeederInfo::ATT_VERTINDEX]->_bohandle); //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _bo[GLFeederInfo::ATT_VERTINDEX]->_bohandle);
size_t pointsnum = _mesh.vn; size_t pointsnum = _mesh.vn;
if (isReplicatedPipeline(_currallocatedboatt)) if (ReqAtts::isReplicatedPipeline(_currallocatedboatt))
pointsnum = _mesh.fn * 3; pointsnum = _mesh.fn * 3;
glDrawArrays(GL_POINTS,0,pointsnum); glDrawArrays(GL_POINTS,0,pointsnum);
@ -1324,11 +1363,11 @@ protected:
} }
} }
std::ptrdiff_t bufferObjectsMemoryRequired(ReqAtts& rqatt) const std::ptrdiff_t bufferObjectsMemoryRequired(const ReqAtts& rqatt) const
{ {
bool replicated = isReplicatedPipeline(rqatt); bool replicated = ReqAtts::isReplicatedPipeline(rqatt);
std::ptrdiff_t result(0); std::ptrdiff_t result(0);
bool generateindex = isVertexIndexingRequired(rqatt); bool generateindex = ReqAtts::isVertexIndexingRequired(rqatt);
for(unsigned int ii = 0;ii < (unsigned int)ATT_NAMES_ARITY;++ii) for(unsigned int ii = 0;ii < (unsigned int)ATT_NAMES_ARITY;++ii)
{ {
@ -1469,7 +1508,7 @@ protected:
size_t _perbatchprim; size_t _perbatchprim;
bool _rendermodinitialized; bool _rendermodinitialized;
ChunkMap _chunkmap; ChunkMap _chunkmap;
}; };
} }
#endif #endif