const BufferData MLConnection::peekElements(uint elements) { #ifdef EDEBUG if (!theReader) { qWarning("*** WARNING: peekElements() cannot be called on an MLConnection object after\n" " killReader() has been called. Ignoring this call.\n"); return BufferData(); } #endif while (1) { BufferData ret = theReader->readElements(elements, false); theSink->checkExit(); if (!ret.plunger()) { if (type().isA<Mark>()) if (!Mark::isEndOfTime(ret)) m_latestTime = Mark::timestamp(ret); else{} else m_latestPeeked = m_samplesRead + elements / theType->size(); return ret; } m_samplesRead = 0; m_latestPeeked = 0; m_latestTime = 0.0; theReader->haveRead(ret); theSink->plunged(theSinkIndex); } }
int nme_buffer_create(int inLength) { BufferData *data = new BufferData(); data->setDataSize(inLength, true); //data->verify("nme_buffer_create"); return (int)data; }
BufferData *BufferData::fromStream(class ObjectStreamIn &inStream) { int len = inStream.getInt(); BufferData *buf = new BufferData(); buf->setDataSize(len,false); if (len) memcpy(buf->data, inStream.getBytes(len), len); return buf; }
unsigned int BufferObject::computeRequiredBufferSize() const { unsigned int newTotalSize = 0; for(BufferDataList::const_iterator itr = _bufferDataList.begin(); itr != _bufferDataList.end(); ++itr) { BufferData* bd = *itr; newTotalSize += bd->getTotalDataSize(); } return newTotalSize; }
unsigned int BufferObject::computeRequiredBufferSize() const { unsigned int newTotalSize = 0; for(BufferDataList::const_iterator itr = _bufferDataList.begin(); itr != _bufferDataList.end(); ++itr) { BufferData* bd = *itr; if (bd) newTotalSize += bd->getTotalDataSize(); else { OSG_NOTICE<<"BufferObject::"<<this<<":"<<className()<<"::BufferObject::computeRequiredBufferSize() error, BufferData is 0x0"<<std::endl; } } //OSG_NOTICE<<"BufferObject::"<<this<<":"<<className()<<"::BufferObject::computeRequiredBufferSize() size="<<newTotalSize<<std::endl; return newTotalSize; }
void Storage( const BufferData& data, Bitfield<BufferStorageBit> flags ) const { OGLPLUS_GLFUNC(NamedBufferStorage)( _name, GLsizeiptr(data.Size()), data.Data(), GLbitfield(flags) ); OGLPLUS_CHECK( NamedBufferStorage, ObjectError, Object(*this) ); }
/** * @see Data * @see CopySubData * @throws Error */ void SubData( BufferSize offset, const BufferData& data ) const { OGLPLUS_GLFUNC(NamedBufferSubData)( _name, GLintptr(offset.Get()), GLsizei(data.Size()), data.Data() ); OGLPLUS_CHECK( NamedBufferSubData, ObjectError, Object(*this) ); }
/** This member function uploads the specified @data to this buffer * using the @p usage as hint. * * @see SubData * @see CopySubData * @throws Error */ void Data( const BufferData& data, BufferUsage usage = BufferUsage::StaticDraw ) const { OGLPLUS_GLFUNC(NamedBufferData)( _name, GLsizei(data.Size()), data.Data(), GLenum(usage) ); OGLPLUS_CHECK( NamedBufferData, ObjectError, Object(*this). EnumParam(usage) ); }
void GeometryProcessor::handleGeometry( RenderBackend::Mesh *geo ) { OSRE_ASSERT( nullptr != geo ); if ( nullptr == geo ) { return; } ui32 offsetPos( 0 ), stride( 0 ); switch ( geo->m_vertextype ) { case VertexType::RenderVertex: offsetPos = 0; stride = sizeof( RenderVert ); break; case VertexType::ColorVertex: offsetPos = 0; stride = sizeof( ColorVert ); break; default: break; } BufferData *data = geo->m_vb; if ( nullptr == data || 0 == data->getSize() ) { return; } ui32 offset( 0 ); const ui32 numVertices = (ui32) data->getSize() / stride; for ( ui32 i = 0; i < numVertices; i++ ) { glm::vec3 pos; uc8 *ptr = (uc8*) data->getData(); ::memcpy( &pos.x, &ptr[offset], sizeof( glm::vec3 ) ); offset += stride; m_aabb.merge( pos.x, pos.y, pos.z ); } }
bool MLConnection::plungeSync(uint samples) const { #ifdef EDEBUG if (!theReader) { qWarning("*** WARNING: plungeSync() cannot be called on an MLConnection object after\n" " killReader() has been called. Ignoring this call.\n"); return false; } #endif BufferData ret = theReader->readElements(theType->size() * samples, false); theSink->checkExit(); if (ret.plunger()) { m_samplesRead = 0; m_latestPeeked = 0; m_latestTime = 0.0; theReader->haveRead(ret); theSink->plunged(theSinkIndex); return false; } return true; }
const BufferData MLConnection::readElements(uint _elements) { #ifdef EDEBUG if (!theReader) { qWarning("*** WARNING: readElements() cannot be called on an MLConnection object after\n" " killReader() has been called. Ignoring this call.\n"); return BufferData(); } #endif while (1) { BufferData ret = theReader->readElements(_elements, true); theSink->checkExit(); if (!ret.plunger()) { if (type().isA<Mark>()) if (!Mark::isEndOfTime(ret)) m_latestTime = Mark::timestamp(ret); else{} else { m_samplesRead += _elements / theType->size(); m_latestPeeked = max(m_latestPeeked, m_samplesRead); } return ret; } m_samplesRead = 0; m_latestPeeked = 0; m_latestTime = 0.0; // This is a workaround for a buggy gcc (3.2.2). // If it wasn't here stuff wouldn't get freed up in the buffer. // As it is, there are deallocation problems, since the last instance of ret // will never get destroyed. ret.nullify(); theSink->plunged(theSinkIndex); } }
void LRConnection::transport(const BufferData &data) { if (MESSAGES) qDebug("> LRC::transport() (L=%s, size=%d)", qPrintable(dynamic_cast<Processor *>(theSource)->name()), data.elements()); // TODO: Currently this silently discards the data. // It should really block until the connection is remade or until it's stopped. // But I dont need to implement that until i want dynamic connections sorted. if (theSink.isOpen()) { theSink.sendByte(Transfer); // FIXME: thread could block here if opposite processor is stopped; trapdoor wouldn't work then. theSink.safeSendWord(data.elements()); if (data.rollsOver()) { theSink.safeSendWordArray((int *)data.firstPart(), data.sizeFirstPart()); theSink.safeSendWordArray((int *)data.secondPart(), data.sizeSecondPart()); } else theSink.safeSendWordArray((int *)data.firstPart(), data.sizeOnlyPart()); if (MESSAGES) qDebug("= LRC::transport(): Transport completed."); } theSource->checkExit(); if (MESSAGES) qDebug("< LRC::transport()"); }
void nme_buffer_resize(int inPtr, int inNewSize) { BufferData *data = (BufferData *)inPtr; data->setDataSize(inNewSize, true); //data->verify("nme_buffer_resize"); }
int nme_buffer_length(int inPtr) { BufferData *data = (BufferData *)inPtr; //data->verify("nme_buffer_length"); return data->getDataSize(); }
int nme_buffer_offset(int inPtr) { BufferData *data = (BufferData *)inPtr; //data->verify("nme_buffer_offset"); return (int)data->getData(); }
void GLBufferObject::compileBuffer() { _dirty = false; _bufferEntries.reserve(_bufferObject->getNumBufferData()); bool compileAll = false; bool offsetChanged = false; unsigned int bufferAlignment = 4; unsigned int newTotalSize = 0; unsigned int i=0; for(; i<_bufferObject->getNumBufferData(); ++i) { BufferData* bd = _bufferObject->getBufferData(i); if (i<_bufferEntries.size()) { BufferEntry& entry = _bufferEntries[i]; if (offsetChanged || entry.dataSource != bd || entry.dataSize != bd->getTotalDataSize()) { unsigned int previousEndOfBufferDataMarker = computeBufferAlignment(entry.offset + entry.dataSize, bufferAlignment); // OSG_NOTICE<<"GLBufferObject::compileBuffer(..) updating BufferEntry"<<std::endl; entry.numRead = 0; entry.modifiedCount = 0xffffff; entry.offset = newTotalSize; entry.dataSize = bd->getTotalDataSize(); entry.dataSource = bd; newTotalSize += entry.dataSize; if (previousEndOfBufferDataMarker!=newTotalSize) { offsetChanged = true; } } else { newTotalSize = computeBufferAlignment(newTotalSize + entry.dataSize, bufferAlignment); } } else { BufferEntry entry; entry.offset = newTotalSize; entry.modifiedCount = 0xffffff; entry.dataSize = bd ? bd->getTotalDataSize() : 0; entry.dataSource = bd; #if 0 OSG_NOTICE<<"entry"<<std::endl; OSG_NOTICE<<" offset "<<entry.offset<<std::endl; OSG_NOTICE<<" dataSize "<<entry.dataSize<<std::endl; OSG_NOTICE<<" dataSource "<<entry.dataSource<<std::endl; OSG_NOTICE<<" modifiedCount "<<entry.modifiedCount<<std::endl; #endif newTotalSize = computeBufferAlignment(newTotalSize + entry.dataSize, bufferAlignment); _bufferEntries.push_back(entry); } } if (i<_bufferEntries.size()) { // triming end of bufferEntries as the source data is has less entries than the originally held. _bufferEntries.erase(_bufferEntries.begin()+i, _bufferEntries.end()); } _extensions->glBindBuffer(_profile._target, _glObjectID); _extensions->debugObjectLabel(GL_BUFFER, _glObjectID, _bufferObject->getName()); if (newTotalSize > _profile._size) { OSG_INFO<<"newTotalSize="<<newTotalSize<<", _profile._size="<<_profile._size<<std::endl; unsigned int sizeDifference = newTotalSize - _profile._size; _profile._size = newTotalSize; if (_set) { _set->moveToSet(this, _set->getParent()->getGLBufferObjectSet(_profile)); _set->getParent()->getCurrGLBufferObjectPoolSize() += sizeDifference; } } if (_allocatedSize != _profile._size) { _allocatedSize = _profile._size; OSG_INFO<<" Allocating new glBufferData(), _allocatedSize="<<_allocatedSize<<std::endl; _extensions->glBufferData(_profile._target, _profile._size, NULL, _profile._usage); compileAll = true; } for(BufferEntries::iterator itr = _bufferEntries.begin(); itr != _bufferEntries.end(); ++itr) { BufferEntry& entry = *itr; if (entry.dataSource && (compileAll || entry.modifiedCount != entry.dataSource->getModifiedCount())) { // OSG_NOTICE<<"GLBufferObject::compileBuffer(..) downloading BufferEntry "<<&entry<<std::endl; entry.numRead = 0; entry.modifiedCount = entry.dataSource->getModifiedCount(); const osg::Image* image = entry.dataSource->asImage(); if (image && !(image->isDataContiguous())) { unsigned int offset = entry.offset; for(osg::Image::DataIterator img_itr(image); img_itr.valid(); ++img_itr) { _extensions->glBufferSubData(_profile._target, (GLintptr)offset, (GLsizeiptr)img_itr.size(), img_itr.data()); offset += img_itr.size(); } } else { _extensions->glBufferSubData(_profile._target, (GLintptr)entry.offset, (GLsizeiptr)entry.dataSize, entry.dataSource->getDataPointer()); } } } }
int PeakTracker::process() { if (m_tracks.count() != m_maxTracks) { qSort(m_tracks.begin(), m_tracks.end(), byConfidence); m_tracks.resize(m_maxTracks); // qSort(m_tracks.begin(), m_tracks.end(), byFrequency); } QList<Track> tin; float total = 0; while (input(0).samplesReady()) { const BufferData in = input(0).readSample(); if (Mark::isEndOfTime(in)) break; total += in[SpectralPeak::Value]; tin.append(Track(in[SpectralPeak::Frequency], in[SpectralPeak::Value])); } for (int i = 0; i < tin.count(); i++) tin[i].confidence /= total; // Sort by frequency... // qSort(tin.begin(), tin.end(), byFrequency); QList<int> ordered; for (int b = 0; b < m_tracks.count(); b++) for (int c = 0; c <= b; c++) if (c == b || m_tracks[b].confidence > m_tracks[ordered[c]].confidence) { ordered.insert(c, b); break; } int nout = 0; //for (int b = 0; b < m_tracks.count(); b++) foreach (int b, ordered) { if (tin.count()) { int bestPeak = -1; // float tunnelVision = pow(m_tracks[b].confidence, m_searchiness); float factor = 0; if (m_tracks[b].confidence > 0) { for (int i = 0; i < tin.count(); i++) { //float f = lerp(tin[i].confidence, tin[i].confidence / fabsf(tin[i].frequency - m_tracks[b].frequency), m_inertiaFactor); float f = abs(m_tracks[b].frequency - tin[i].frequency) / min(m_tracks[b].frequency, tin[i].frequency); if (f < factor || bestPeak == -1) { bestPeak = i; factor = f; } } float df = abs(m_tracks[b].frequency - tin[bestPeak].frequency) / min(m_tracks[b].frequency, tin[bestPeak].frequency); if (df < 0.05) { // Small - perhaps 0.05? m_tracks[b].frequency = tin[bestPeak].frequency; m_tracks[b].confidence += tin[bestPeak].confidence * (1 - (df * 20)); tin.removeAt(bestPeak); } m_tracks[b].confidence /= 2; } else { for (int i = 0; i < tin.count(); i++) { float f = tin[i].confidence; if (f > factor || bestPeak == -1) { bestPeak = i; factor = f; } } m_tracks[b].frequency = tin[bestPeak].frequency; m_tracks[b].confidence = 0.001; tin.removeAt(bestPeak); } } else { m_tracks[b].confidence *= .9f; } if (m_tracks[b].confidence < 0.001f) m_tracks[b].confidence = 0.f; nout++; } // Write our state to the output. BufferData out = output(0).makeScratchSamples(nout + 1); for (int i = 0; i < nout; i++) { out(i, SpectralPeak::Frequency) = m_tracks.value(i).frequency; out(i, SpectralPeak::Value) = m_tracks.value(i).confidence; } Mark::setEndOfTime(out.sample(nout)); output(0) << out; return DidWork; }
static void ExportSection(ExportContext& Context, const CBaseMeshLod& Lod, const CMeshVertex* Verts, int SectonIndex, FArchive& Ar) { guard(ExportSection); int VertexSize = Context.IsSkeletal() ? sizeof(CSkelMeshVertex) : sizeof(CStaticMeshVertex); const CMeshSection& S = Lod.Sections[SectonIndex]; bool bLast = (SectonIndex == Lod.Sections.Num()-1); // Remap section indices to local indices CIndexBuffer::IndexAccessor_t GetIndex = Lod.Indices.GetAccessor(); TArray<int> indexRemap; // old vertex index -> new vertex index indexRemap.Init(-1, Lod.NumVerts); int numLocalVerts = 0; int numLocalIndices = S.NumFaces * 3; for (int idx = 0; idx < numLocalIndices; idx++) { int vertIndex = GetIndex(S.FirstIndex + idx); if (indexRemap[vertIndex] == -1) { indexRemap[vertIndex] = numLocalVerts++; } } // Prepare buffers int IndexBufIndex = Context.Data.AddZeroed(); int PositionBufIndex = Context.Data.AddZeroed(); int NormalBufIndex = Context.Data.AddZeroed(); int TangentBufIndex = Context.Data.AddZeroed(); int BonesBufIndex = -1; int WeightsBufIndex = -1; if (Context.IsSkeletal()) { BonesBufIndex = Context.Data.AddZeroed(); WeightsBufIndex = Context.Data.AddZeroed(); } int UVBufIndex[MAX_MESH_UV_SETS]; for (int i = 0; i < Lod.NumTexCoords; i++) { UVBufIndex[i] = Context.Data.AddZeroed(); } BufferData& IndexBuf = Context.Data[IndexBufIndex]; BufferData& PositionBuf = Context.Data[PositionBufIndex]; BufferData& NormalBuf = Context.Data[NormalBufIndex]; BufferData& TangentBuf = Context.Data[TangentBufIndex]; BufferData* UVBuf[MAX_MESH_UV_SETS]; BufferData* BonesBuf = NULL; BufferData* WeightsBuf = NULL; PositionBuf.Setup(numLocalVerts, "VEC3", BufferData::FLOAT, sizeof(CVec3)); NormalBuf.Setup(numLocalVerts, "VEC3", BufferData::FLOAT, sizeof(CVec3)); TangentBuf.Setup(numLocalVerts, "VEC4", BufferData::FLOAT, sizeof(CVec4)); for (int i = 0; i < Lod.NumTexCoords; i++) { UVBuf[i] = &Context.Data[UVBufIndex[i]]; UVBuf[i]->Setup(numLocalVerts, "VEC2", BufferData::FLOAT, sizeof(CMeshUVFloat)); } if (Context.IsSkeletal()) { BonesBuf = &Context.Data[BonesBufIndex]; WeightsBuf = &Context.Data[WeightsBufIndex]; BonesBuf->Setup(numLocalVerts, "VEC4", BufferData::UNSIGNED_SHORT, sizeof(uint16)*4); WeightsBuf->Setup(numLocalVerts, "VEC4", BufferData::UNSIGNED_BYTE, sizeof(uint32), /*InNormalized=*/ true); } // Prepare and build indices TArray<int> localIndices; localIndices.AddUninitialized(numLocalIndices); int* pIndex = localIndices.GetData(); for (int i = 0; i < numLocalIndices; i++) { *pIndex++ = GetIndex(S.FirstIndex + i); } if (numLocalVerts <= 65536) { IndexBuf.Setup(numLocalIndices, "SCALAR", BufferData::UNSIGNED_SHORT, sizeof(uint16)); for (int idx = 0; idx < numLocalIndices; idx++) { IndexBuf.Put<uint16>(indexRemap[localIndices[idx]]); } } else { IndexBuf.Setup(numLocalIndices, "SCALAR", BufferData::UNSIGNED_INT, sizeof(uint32)); for (int idx = 0; idx < numLocalIndices; idx++) { IndexBuf.Put<uint32>(indexRemap[localIndices[idx]]); } } // Build reverse index map for fast lookup of vertex by its new index. // It maps new vertex index to old vertex index. TArray<int> revIndexMap; revIndexMap.AddUninitialized(numLocalVerts); for (int i = 0; i < indexRemap.Num(); i++) { int newIndex = indexRemap[i]; if (newIndex != -1) { revIndexMap[newIndex] = i; } } // Build vertices for (int i = 0; i < numLocalVerts; i++) { int vertIndex = revIndexMap[i]; const CMeshVertex& V = VERT(vertIndex); CVec3 Position = V.Position; CVec4 Normal, Tangent; Unpack(Normal, V.Normal); Unpack(Tangent, V.Tangent); // Unreal (and we are) using normal.w for computing binormal. glTF // uses tangent.w for that. Make this value exactly 1.0 of -1.0 to make glTF // validator happy. #if 0 // There's some problem: V.Normal.W == 0x80 -> -1.008 instead of -1.0 if (Normal.w > 1.001 || Normal.w < -1.001) { appError("%X -> %g\n", V.Normal.Data, Normal.w); } #endif Tangent.w = (Normal.w < 0) ? -1 : 1; TransformPosition(Position); TransformDirection(Normal); TransformDirection(Tangent); Normal.Normalize(); Tangent.Normalize(); // Fill buffers PositionBuf.Put(Position); NormalBuf.Put(Normal.xyz); TangentBuf.Put(Tangent); UVBuf[0]->Put(V.UV); } // Compute bounds for PositionBuf CVec3 Mins, Maxs; ComputeBounds((CVec3*)PositionBuf.Data, numLocalVerts, sizeof(CVec3), Mins, Maxs); char buf[256]; appSprintf(ARRAY_ARG(buf), "[ %g, %g, %g ]", VECTOR_ARG(Mins)); PositionBuf.BoundsMin = buf; appSprintf(ARRAY_ARG(buf), "[ %g, %g, %g ]", VECTOR_ARG(Maxs)); PositionBuf.BoundsMax = buf; if (Context.IsSkeletal()) { for (int i = 0; i < numLocalVerts; i++) { int vertIndex = revIndexMap[i]; const CMeshVertex& V0 = VERT(vertIndex); const CSkelMeshVertex& V = static_cast<const CSkelMeshVertex&>(V0); int16 Bones[NUM_INFLUENCES]; static_assert(NUM_INFLUENCES == 4, "Code designed for 4 influences"); static_assert(sizeof(Bones) == sizeof(V.Bone), "Unexpected V.Bones size"); memcpy(Bones, V.Bone, sizeof(Bones)); for (int j = 0; j < NUM_INFLUENCES; j++) { // We have INDEX_NONE as list terminator, should replace with something else for glTF if (Bones[j] == INDEX_NONE) { Bones[j] = 0; } } BonesBuf->Put(*(uint64*)&Bones); WeightsBuf->Put(V.PackedWeights); } } // Secondary UVs for (int uvIndex = 1; uvIndex < Lod.NumTexCoords; uvIndex++) { BufferData* pBuf = UVBuf[uvIndex]; const CMeshUVFloat* srcUV = Lod.ExtraUV[uvIndex-1]; for (int i = 0; i < numLocalVerts; i++) { int vertIndex = revIndexMap[i]; pBuf->Put(srcUV[vertIndex]); } } // Write primitive information to json Ar.Printf( " {\n" " \"attributes\" : {\n" " \"POSITION\" : %d,\n" " \"NORMAL\" : %d,\n" " \"TANGENT\" : %d,\n", PositionBufIndex, NormalBufIndex, TangentBufIndex ); if (Context.IsSkeletal()) { Ar.Printf( " \"JOINTS_0\" : %d,\n" " \"WEIGHTS_0\" : %d,\n", BonesBufIndex, WeightsBufIndex ); } for (int i = 0; i < Lod.NumTexCoords; i++) { Ar.Printf( " \"TEXCOORD_%d\" : %d%s\n", i, UVBufIndex[i], i < (Lod.NumTexCoords-1) ? "," : "" ); } Ar.Printf( " },\n" " \"indices\" : %d,\n" " \"material\" : %d\n" " }%s\n", IndexBufIndex, SectonIndex, SectonIndex < (Lod.Sections.Num()-1) ? "," : "" ); unguard; }
void Splitter::pushScratch(const BufferData &data) { data.ignoreDeath(); push(data); data.invalidate(); }
void Splitter::forgetScratch(const BufferData &data) { data.ignoreDeath(); data.invalidate(); }
void GLBufferObject::compileBuffer() { _dirty = false; _bufferEntries.reserve(_bufferObject->getNumBufferData()); bool compileAll = false; bool offsetChanged = false; unsigned int newTotalSize = 0; unsigned int i=0; for(; i<_bufferObject->getNumBufferData(); ++i) { BufferData* bd = _bufferObject->getBufferData(i); if (i<_bufferEntries.size()) { BufferEntry& entry = _bufferEntries[i]; if (offsetChanged || entry.dataSource != bd || entry.dataSize != bd->getTotalDataSize()) { unsigned int previousEndOfBufferDataMarker = entry.offset + entry.dataSize; // OSG_NOTIFY(osg::NOTICE)<<"GLBufferObject::compileBuffer(..) updating BufferEntry"<<std::endl; entry.offset = newTotalSize; entry.modifiedCount = 0xffffff; entry.dataSize = bd->getTotalDataSize(); entry.dataSource = bd; newTotalSize += entry.dataSize; if (previousEndOfBufferDataMarker==newTotalSize) { offsetChanged = true; } } } else { BufferEntry entry; entry.offset = newTotalSize; entry.modifiedCount = 0xffffff; entry.dataSize = bd->getTotalDataSize(); entry.dataSource = bd; #if 0 OSG_NOTIFY(osg::NOTICE)<<"entry"<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" offset "<<entry.offset<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" dataSize "<<entry.dataSize<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" dataSource "<<entry.dataSource<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" modifiedCount "<<entry.modifiedCount<<std::endl; #endif newTotalSize += entry.dataSize; _bufferEntries.push_back(entry); } } if (i<_bufferEntries.size()) { // triming end of bufferEntries as the source data is has less entries than the originally held. _bufferEntries.erase(_bufferEntries.begin()+i, _bufferEntries.end()); } _extensions->glBindBuffer(_profile._target, _glObjectID); if (newTotalSize > _profile._size) { OSG_NOTIFY(osg::INFO)<<"newTotalSize="<<newTotalSize<<", _profile._size="<<_profile._size<<std::endl; _profile._size = newTotalSize; if (_set) { _set->moveToSet(this, _set->getParent()->getGLBufferObjectSet(_profile)); } } if (_allocatedSize != _profile._size) { _allocatedSize = _profile._size; _extensions->glBufferData(_profile._target, _profile._size, NULL, _profile._usage); } char* vboMemory = 0; #if 0 vboMemory = extensions->glMapBuffer(_target, GL_WRITE_ONLY_ARB); #endif for(BufferEntries::iterator itr = _bufferEntries.begin(); itr != _bufferEntries.end(); ++itr) { BufferEntry& entry = *itr; if (compileAll || entry.modifiedCount != entry.dataSource->getModifiedCount()) { // OSG_NOTIFY(osg::NOTICE)<<"GLBufferObject::compileBuffer(..) downloading BufferEntry "<<&entry<<std::endl; entry.modifiedCount = entry.dataSource->getModifiedCount(); if (vboMemory) memcpy(vboMemory + (GLsizeiptrARB)entry.offset, entry.dataSource->getDataPointer(), entry.dataSize); else _extensions->glBufferSubData(_profile._target, (GLintptrARB)entry.offset, (GLsizeiptrARB)entry.dataSize, entry.dataSource->getDataPointer()); } } // Unmap the texture image buffer if (vboMemory) _extensions->glUnmapBuffer(_profile._target); }