ofVbo & ofVbo::operator=(const ofVbo& mom){ if(&mom==this) return *this; clear(); bUsingVerts = mom.bUsingVerts; bUsingTexCoords = mom.bUsingTexCoords; bUsingColors = mom.bUsingColors; bUsingNormals = mom.bUsingNormals; bUsingIndices = mom.bUsingIndices; positionAttribute = mom.positionAttribute; colorAttribute = mom.colorAttribute; texCoordAttribute = mom.texCoordAttribute; normalAttribute = mom.normalAttribute; customAttributes = mom.customAttributes; totalVerts = mom.totalVerts; totalIndices = mom.totalIndices; indexAttribute = mom.indexAttribute; vaoChanged = mom.vaoChanged; vaoID = mom.vaoID; if(ofIsGLProgrammableRenderer()){ retainVAO(vaoID); } return *this; }
ofVbo::ofVbo(const ofVbo & mom){ bUsingVerts = mom.bUsingVerts; bUsingTexCoords = mom.bUsingTexCoords; bUsingColors = mom.bUsingColors; bUsingNormals = mom.bUsingNormals; bUsingIndices = mom.bUsingIndices; vertSize = mom.vertSize; vertStride = mom.vertStride; colorStride = mom.colorStride; normalStride = mom.normalStride; texCoordStride = mom.texCoordStride; vertUsage = mom.vertUsage; colorUsage = mom.colorUsage; normUsage = mom.normUsage; texUsage = mom.texUsage; vertId = mom.vertId; retain(vertId); normalId = mom.normalId; retain(normalId); colorId = mom.colorId; retain(colorId); texCoordId = mom.texCoordId; retain(texCoordId); indexId = mom.indexId; retain(indexId); if(supportVAOs){ vaoID = mom.vaoID; retainVAO(vaoID); vaoChanged = mom.vaoChanged; } attributeIds = mom.attributeIds; for (map<int, GLuint>::iterator it = attributeIds.begin(); it != attributeIds.end(); it++){ retain(it->second); } attributeNumCoords = mom.attributeNumCoords; attributeStrides = mom.attributeStrides; attributeSize = mom.attributeSize; totalVerts = mom.totalVerts; totalIndices = mom.totalIndices; texCoordStride = sizeof(ofVec2f); normalStride = sizeof(ofVec3f); colorStride = sizeof(ofFloatColor); bAllocated = mom.bAllocated; bBound = mom.bBound; }
ofVbo::ofVbo(const ofVbo & mom){ bUsingVerts = mom.bUsingVerts; bUsingTexCoords = mom.bUsingTexCoords; bUsingColors = mom.bUsingColors; bUsingNormals = mom.bUsingNormals; bUsingIndices = mom.bUsingIndices; vertSize = mom.vertSize; vertStride = mom.vertStride; colorStride = mom.colorStride; normalStride = mom.normalStride; texCoordStride = mom.texCoordStride; vertUsage = mom.vertUsage; colorUsage = mom.colorUsage; normUsage = mom.normUsage; texUsage = mom.texUsage; vertId = mom.vertId; retain(vertId); normalId = mom.normalId; retain(normalId); colorId = mom.colorId; retain(colorId); texCoordId = mom.texCoordId; retain(texCoordId); indexId = mom.indexId; retain(indexId); if(supportVAOs){ vaoID = mom.vaoID; retainVAO(vaoID); vaoChanged = mom.vaoChanged; } totalVerts = mom.totalVerts; totalIndices = mom.totalIndices; texCoordStride = sizeof(ofVec2f); normalStride = sizeof(ofVec3f); colorStride = sizeof(ofFloatColor); bAllocated = mom.bAllocated; bBound = mom.bBound; }
ofVbo & ofVbo::operator=(const ofVbo& mom){ if(&mom==this) return *this; clear(); bUsingVerts = mom.bUsingVerts; bUsingTexCoords = mom.bUsingTexCoords; bUsingColors = mom.bUsingColors; bUsingNormals = mom.bUsingNormals; bUsingIndices = mom.bUsingIndices; vertSize = mom.vertSize; vertStride = mom.vertStride; colorStride = mom.colorStride; normalStride = mom.normalStride; texCoordStride = mom.texCoordStride; vertUsage = mom.vertUsage; colorUsage = mom.colorUsage; normUsage = mom.normUsage; texUsage = mom.texUsage; vertId = mom.vertId; retain(vertId); normalId = mom.normalId; retain(normalId); colorId = mom.colorId; retain(colorId); texCoordId = mom.texCoordId; retain(texCoordId); indexId = mom.indexId; retain(indexId); if(supportVAOs){ vaoID = mom.vaoID; retainVAO(vaoID); vaoChanged = mom.vaoChanged; } totalVerts = mom.totalVerts; totalIndices = mom.totalIndices; bAllocated = mom.bAllocated; bBound = mom.bBound; return *this; }
ofVbo::ofVbo(const ofVbo & mom){ bUsingVerts = mom.bUsingVerts; bUsingTexCoords = mom.bUsingTexCoords; bUsingColors = mom.bUsingColors; bUsingNormals = mom.bUsingNormals; bUsingIndices = mom.bUsingIndices; positionAttribute = mom.positionAttribute; colorAttribute = mom.colorAttribute; texCoordAttribute = mom.texCoordAttribute; normalAttribute = mom.normalAttribute; customAttributes = mom.customAttributes; totalVerts = mom.totalVerts; totalIndices = mom.totalIndices; indexAttribute = mom.indexAttribute; if(ofIsGLProgrammableRenderer()){ vaoID = mom.vaoID; retainVAO(vaoID); vaoChanged = mom.vaoChanged; } }
//-------------------------------------------------------------- void ofVbo::bind(){ if(supportVAOs){ if(vaoID==0){ glGenVertexArrays(1, &vaoID); if(vaoID!=0){ retainVAO(vaoID); }else{ supportVAOs = false; ofLogVerbose("ofVbo") << "bind(): error allocating VAO, disabling VAO support"; } } glBindVertexArray(vaoID); } if(vaoChanged || !supportVAOs){ bool programmable = ofIsGLProgrammableRenderer(); if(bUsingVerts){ glBindBuffer(GL_ARRAY_BUFFER, vertId); if(!programmable){ glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(vertSize, GL_FLOAT, vertStride, 0); }else{ glEnableVertexAttribArray(ofShader::POSITION_ATTRIBUTE); glVertexAttribPointer(ofShader::POSITION_ATTRIBUTE, vertSize, GL_FLOAT, GL_FALSE, vertStride, 0); } }else if(supportVAOs){ if(!programmable){ glDisableClientState(GL_VERTEX_ARRAY); }else{ glDisableVertexAttribArray(ofShader::POSITION_ATTRIBUTE); } } if(bUsingColors) { glBindBuffer(GL_ARRAY_BUFFER, colorId); if(!programmable){ glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_FLOAT, colorStride, 0); }else{ glEnableVertexAttribArray(ofShader::COLOR_ATTRIBUTE); glVertexAttribPointer(ofShader::COLOR_ATTRIBUTE, 4, GL_FLOAT, GL_FALSE, colorStride, 0); } }else if(supportVAOs){ if(!programmable){ glDisableClientState(GL_COLOR_ARRAY); }else{ glDisableVertexAttribArray(ofShader::COLOR_ATTRIBUTE); } } if(bUsingNormals) { glBindBuffer(GL_ARRAY_BUFFER, normalId); if(!programmable){ glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, normalStride, 0); }else{ // tig: note that we set the 'Normalize' flag to true here, assuming that mesh normals need to be // normalized while being uploaded to GPU memory. // http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml // Normalizing the normals on the shader is probably faster, but sending non-normalized normals is // more prone to lead to artifacts difficult to diagnose, especially with the built-in 3D primitives. // If you need to optimise this, and you've dug this far through the code, you are most probably // able to roll your own client code for binding & rendering vbos anyway... glEnableVertexAttribArray(ofShader::NORMAL_ATTRIBUTE); glVertexAttribPointer(ofShader::NORMAL_ATTRIBUTE, 3, GL_FLOAT, GL_TRUE, normalStride, 0); } }else if(supportVAOs){ if(!programmable){ glDisableClientState(GL_NORMAL_ARRAY); }else{ glDisableVertexAttribArray(ofShader::NORMAL_ATTRIBUTE); } } if(bUsingTexCoords) { glBindBuffer(GL_ARRAY_BUFFER, texCoordId); if(!programmable){ glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, texCoordStride, 0); }else{ glEnableVertexAttribArray(ofShader::TEXCOORD_ATTRIBUTE); glVertexAttribPointer(ofShader::TEXCOORD_ATTRIBUTE, 2, GL_FLOAT, GL_FALSE, texCoordStride, 0); } }else if(supportVAOs){ if(!programmable){ glDisableClientState(GL_TEXTURE_COORD_ARRAY); }else{ glDisableVertexAttribArray(ofShader::TEXCOORD_ATTRIBUTE); } } map<int,GLuint>::iterator it; for(it=attributeIds.begin();it!=attributeIds.end();it++){ glBindBuffer(GL_ARRAY_BUFFER, attributeIds[it->first]); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, attributeNumCoords[it->first], GL_FLOAT, GL_FALSE, attributeStrides[it->first], 0); } vaoChanged=false; } ofPtr<ofGLProgrammableRenderer> renderer = ofGetGLProgrammableRenderer(); if(renderer){ renderer->setAttributes(bUsingVerts,bUsingColors,bUsingTexCoords,bUsingNormals); } bBound = true; }
//-------------------------------------------------------------- void ofVbo::bind() const{ bool programmable = ofIsGLProgrammableRenderer(); if(programmable && (vaoSupported || !vaoChecked)){ if(vaoID==0){ #ifdef TARGET_OPENGLES if(glGenVertexArrays==0 && !vaoChecked){ glGenVertexArrays = (glGenVertexArraysType)dlsym(RTLD_DEFAULT, "glGenVertexArrays"); glDeleteVertexArrays = (glDeleteVertexArraysType)dlsym(RTLD_DEFAULT, "glDeleteVertexArrays"); glBindVertexArray = (glBindVertexArrayType)dlsym(RTLD_DEFAULT, "glBindVertexArray"); vaoChecked = true; vaoSupported = glGenVertexArrays; } #else vaoChecked = true; vaoSupported = true; #endif if(vaoSupported) glGenVertexArrays(1, &const_cast<ofVbo*>(this)->vaoID); if(vaoID!=0){ retainVAO(vaoID); vaoChanged = true; } } if(vaoSupported) glBindVertexArray(vaoID); }else{ vaoSupported = false; } if(vaoChanged || !vaoSupported){ if(bUsingVerts){ if(!programmable){ positionAttribute.bind(); #ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(positionAttribute.numCoords, GL_FLOAT, positionAttribute.stride, (void*)positionAttribute.offset); #endif }else{ positionAttribute.enable(); } }else if(programmable){ positionAttribute.disable(); } if(bUsingColors) { if(!programmable){ colorAttribute.bind(); #ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_COLOR_ARRAY); glColorPointer(colorAttribute.numCoords, GL_FLOAT, colorAttribute.stride, (void*)colorAttribute.offset); #endif }else{ colorAttribute.enable(); } }else if(programmable){ colorAttribute.disable(); } if(bUsingNormals) { if(!programmable){ normalAttribute.bind(); #ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, normalAttribute.stride, (void*)normalAttribute.offset); #endif }else{ normalAttribute.enable(); } }else if(programmable){ normalAttribute.disable(); } if(bUsingTexCoords) { if(!programmable){ texCoordAttribute.bind(); #ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(texCoordAttribute.numCoords, GL_FLOAT, texCoordAttribute.stride, (void*)texCoordAttribute.offset); #endif }else{ texCoordAttribute.enable(); } }else if(programmable){ texCoordAttribute.disable(); } if (bUsingIndices) { indexAttribute.bind(); } map<int,VertexAttribute>::const_iterator it; for(it = customAttributes.begin();it!=customAttributes.end();it++){ it->second.enable(); } vaoChanged=false; } }
//-------------------------------------------------------------- void ofVbo::bind() const{ bool programmable = ofIsGLProgrammableRenderer(); if(programmable){ if(vaoID==0){ glGenVertexArrays(1, &const_cast<ofVbo*>(this)->vaoID); if(vaoID!=0){ retainVAO(vaoID); vaoChanged = true; } } glBindVertexArray(vaoID); } if(vaoChanged || !programmable){ if(bUsingVerts){ if(!programmable){ positionAttribute.bind(); #ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(positionAttribute.numCoords, GL_FLOAT, positionAttribute.stride, (void*)positionAttribute.offset); #endif }else{ positionAttribute.enable(); } }else if(programmable){ positionAttribute.disable(); } if(bUsingColors) { if(!programmable){ colorAttribute.bind(); #ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_COLOR_ARRAY); glColorPointer(colorAttribute.numCoords, GL_FLOAT, colorAttribute.stride, (void*)colorAttribute.offset); #endif }else{ colorAttribute.enable(); } }else if(programmable){ colorAttribute.disable(); } if(bUsingNormals) { if(!programmable){ normalAttribute.bind(); #ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, normalAttribute.stride, (void*)normalAttribute.offset); #endif }else{ normalAttribute.enable(); } }else if(programmable){ normalAttribute.disable(); } if(bUsingTexCoords) { if(!programmable){ texCoordAttribute.bind(); #ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(texCoordAttribute.numCoords, GL_FLOAT, texCoordAttribute.stride, (void*)texCoordAttribute.offset); #endif }else{ texCoordAttribute.enable(); } }else if(programmable){ texCoordAttribute.disable(); } if (bUsingIndices) { indexAttribute.bind(); } map<int,VertexAttribute>::const_iterator it; for(it = customAttributes.begin();it!=customAttributes.end();it++){ it->second.enable(); } vaoChanged=false; } if(programmable){ ofGetGLProgrammableRenderer()->setAttributes(true,getUsingColors(),getUsingTexCoords(),getUsingNormals()); } }