void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const { GLenum mode = _mode; #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN; if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; #endif if (useVertexBufferObjects) { GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID()); state.bindElementBufferObject(ebo); if (ebo) { if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances); else glDrawElements(mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex()))); } else { if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, &front(), _numInstances); else glDrawElements(mode, size(), GL_UNSIGNED_INT, &front()); } } else { if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, &front(), _numInstances); else glDrawElements(mode, size(), GL_UNSIGNED_INT, &front()); } }
void AtomicCounterBufferBinding::readData(osg::State & state, osg::UIntArray & uintArray) const { if (!_bufferObject) return; GLBufferObject* bo = _bufferObject->getOrCreateGLBufferObject( state.getContextID() ); if (!bo) return; GLint previousID = 0; glGetIntegerv(GL_ATOMIC_COUNTER_BUFFER_BINDING, &previousID); if (static_cast<GLuint>(previousID) != bo->getGLObjectID()) bo->_extensions->glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, bo->getGLObjectID()); GLubyte* src = (GLubyte*)bo->_extensions->glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY_ARB); if(src) { size_t size = osg::minimum<int>(_size, uintArray.getTotalDataSize()); memcpy((void*) &(uintArray.front()), src+_offset, size); bo->_extensions->glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); } if (static_cast<GLuint>(previousID) != bo->getGLObjectID()) bo->_extensions->glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, static_cast<GLuint>(previousID)); }
void GLBufferObject::Copy( GLBufferObject& writetarget, int readoffset, int writeoffset, int size ) { Bind(); writetarget.Bind(); glCopyBufferSubData(target, writetarget.Target(), readoffset, writeoffset, size); writetarget.Unbind(); Unbind(); }
void Test1Shader::drawElementsP(GLenum mode,const GLBufferObject &vertexBuf,const GLBufferObject &indexBuf) { if(!vertexBuf.bind())FAIL("vertexBuf.bind"); if(!indexBuf.bind())FAIL("indexBuf.bind"); glEnableVertexAttribArray(ATTR_POS); glVertexAttribPointer(ATTR_POS,3,GL_FLOAT,GL_FALSE,0,0); glDrawElements(mode,indexBuf.m_DataNum,GL_UNSIGNED_INT,NULL); glDisableVertexAttribArray(ATTR_POS); if(!indexBuf.unbind())FAIL("indexBuf.unbind"); if(!vertexBuf.unbind())FAIL("vertexBuf.unbind"); }
//-------------------------------------------------------------------------------- void PixelDataBufferObject::compileBuffer(State& state) const { unsigned int contextID = state.getContextID(); if ( _profile._size == 0) return; GLBufferObject* bo = getOrCreateGLBufferObject(contextID); if (!bo || !bo->isDirty()) return; bo->_extensions->glBindBuffer(_profile._target, bo->getGLObjectID()); bo->_extensions->glBufferData(_profile._target, _profile._size, NULL, _profile._usage); bo->_extensions->glBindBuffer(_profile._target, 0); }
//-------------------------------------------------------------------------------- void PixelDataBufferObject::bindBufferInWriteMode(State& state) { unsigned int contextID = state.getContextID(); GLBufferObject* bo = getOrCreateGLBufferObject(contextID); if (!bo) return; if (bo->isDirty()) compileBuffer(state); bo->_extensions->glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, bo->getGLObjectID()); _mode[contextID] = WRITE; }
void BufferIndexBinding::apply(State& state) const { if (_bufferObject.valid()) { GLBufferObject* glObject = _bufferObject->getOrCreateGLBufferObject(state.getContextID()); if (!glObject->_extensions->isUniformBufferObjectSupported) return; if (glObject->isDirty()) glObject->compileBuffer(); glObject->_extensions->glBindBufferRange(_target, _index, glObject->getGLObjectID(), _offset, _size); } }
void GLVertexArrayObject::attribPointer(int idx, GLBufferObject& obj){ glBindVertexArray(this->handle_); glEnableVertexAttribArray(idx); // Map index 0 to the position buffer ???? glBindBuffer(GL_ARRAY_BUFFER, obj.handle()); glVertexAttribPointer(idx, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL); }
void bindRange(GLenum target, GLuint index, size_t offset, size_t size) const { glBindBufferRange(target, index, glId(), offset * sizeof(T), size * sizeof(T)); }
void bindBase(GLenum target, GLuint index) const { glBindBufferBase(target, index, glId()); }
void bind(GLenum target) const { glBindBuffer(target, glId()); }
void setSubData(uint32_t offset, size_t count, const T* data) { assert(offset + count <= m_Size); glNamedBufferSubDataEXT(glId(), offset * sizeof(T), count * sizeof(T), data); }
T* mapRange(GLintptr offset, GLsizei length, GLbitfield access) { assert(offset + length <= GLBufferBase<T>::size()); return (T*) glMapNamedBufferRangeEXT(glId(), offset, length, access); }
GLBufferStorage(size_t size, const T* data, GLbitfield flags = 0): GLBufferBase<T>(size) { glNamedBufferStorageEXT(glId(), GLBufferBase<T>::size() * sizeof(T), data, flags); }
GLBufferObject* GLBufferObjectSet::takeOrGenerate(BufferObject* bufferObject) { // see if we can recyle GLBufferObject from the orphane list if (!_pendingOrphanedGLBufferObjects.empty()) { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); handlePendingOrphandedGLBufferObjects(); return takeFromOrphans(bufferObject); } else if (!_orphanedGLBufferObjects.empty()) { return takeFromOrphans(bufferObject); } unsigned int minFrameNumber = _parent->getFrameNumber(); // see if we can reuse GLBufferObject by taking the least recently used active GLBufferObject if ((_parent->getMaxGLBufferObjectPoolSize()!=0) && (!_parent->hasSpace(_profile._size)) && (_numOfGLBufferObjects>1) && (_head != 0) && (_head->_frameLastUsed<minFrameNumber)) { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); ref_ptr<GLBufferObject> glbo = _head; ref_ptr<BufferObject> original_BufferObject = glbo->getBufferObject(); if (original_BufferObject.valid()) { original_BufferObject->setGLBufferObject(_contextID,0); // OSG_NOTIFY(osg::NOTICE)<<"GLBufferObjectSet="<<this<<": Reusing an active GLBufferObject "<<glbo.get()<<" _numOfGLBufferObjects="<<_numOfGLBufferObjects<<" size="<<_profile._size<<std::endl; } else { // OSG_NOTIFY(osg::NOTICE)<<"Reusing a recently orphaned active GLBufferObject "<<glbo.get()<<std::endl; } moveToBack(glbo.get()); // assign to new texture glbo->setBufferObject(bufferObject); glbo->setProfile(_profile); return glbo.release(); } // GLBufferObject* glbo = new GLBufferObject(_contextID, const_cast<BufferObject*>(bufferObject)); glbo->setProfile(_profile); glbo->_set = this; ++_numOfGLBufferObjects; // update the current texture pool size _parent->getCurrGLBufferObjectPoolSize() += _profile._size; _parent->getNumberActiveGLBufferObjects() += 1; addToBack(glbo); // OSG_NOTIFY(osg::NOTICE)<<"Created new GLBufferObject, _numOfGLBufferObjects "<<_numOfGLBufferObjects<<std::endl; return glbo; }
void unmap() const { glUnmapNamedBufferEXT(glId()); }
T* map(GLenum access) { return (T*) glMapNamedBufferEXT(glId(), access); }
T* mapReadOnly() const { return (T*) glMapNamedBufferEXT(glId(), GL_READ_ONLY); }
void setSize(size_t count, GLenum usage) { m_Size = count; glNamedBufferDataEXT(glId(), m_Size * sizeof(T), nullptr, usage); }
void getData(size_t offset, size_t count, T* data) { glGetNamedBufferSubDataEXT(glId(), offset * sizeof(T), count * sizeof(T), data); }
void setData(size_t count, const T* data, GLenum usage) { m_Size = count; glNamedBufferDataEXT(glId(), m_Size * sizeof(T), data, usage); }