An instance of GLBuffer represents an OpenGL resource, or it contains a pointer to system memory. In either case, one thing is certain: if you want "a copy of a GLBuffer instance", you cannot simply make another copy of the struct- bad things will happen as the underlying image data either won't be duplicated.
It is strongly recommended that you use GLBufferRef instead of GLBuffer if you just want to share a given GLBuffer instance with another object (displaying the same texture in two different views, for example). As long as you use GLBufferRef and ensure that you set any GLBufferRefs you maintain to nullptr as soon as you no longer use them, all the underlying GPU/CPU resources will be freed/pooled and you'll have plenty of VRAM available. Remember, GLBuffers come from and are returned to pools: obtaining a new buffer and setting a buffer to nil are typically very fast and very cheap (within reason).
cout << "origTex is " << orgTex->name << ", srcRect is " << origTex->srcRect << endl;
sameGLBufferNewVar->srcRect =
VVGL::Rect(10,10,1900,1060);
cout << "sameGLBufferNewVar is " << sameGLBufferNewVar->name;
cout << ", srcRect is " << sameGLBufferNewVar->srcRect << endl;
cout << "origTex srcRect is now " << origTex->srcRect << endl;
GLBufferRef is great, but if you're working with it and you modify a property- like 'srcRect', for example- then every other GLBufferRef for that same GLBuffer will immediately inherit that change. This is not always desirable- for example, you may want to crop a GLBufferRef for use in one particular scene, or use a larger texture-based GLBuffer as the source of many smaller texture-based GLBuffers that all share the same GL resource (texture atlas). The function GLBufferCopy() accepts a GLBufferRef, makes a new GLBuffer instance that has a strong reference to the GLBuffer instance you passed in, and returns a GLBufferRef for the new instance. Because it's an entirely different GLBuffer, you can modify the superficial properties without affecting the original GLBuffer or any of its refs- but because it's the same underlying GL resource, nothing was actually copied and the resource will automatically be retained as long as necessary. Copying buffers in this manner is quick and cheap because the actual image data isn't being duplicated.
cout << "origTex is " << orgTex->name << ", srcRect is " << origTex->srcRect << endl;
sameTexNewBufferNewVar->srcRect =
VVGL::Rect(10,10,1900,1060);
cout << "sameTexNewBufferNewVar is " << sameTexNewBufferNewVar->name;
cout << ", srcRect is " << sameTexNewBufferNewVar->srcRect << endl;
cout << "origTex srcRect is " << origTex->srcRect << endl;
Sometimes you actually want to copy the contents of a GLBuffer to another GLBuffer. For this, VVGL offers a couple different classes that specialize in the more commonly encountered types of copies so far:
- GLTexToTexCopier copies texture-type GLBuffers to other texture-type GLBuffers. Texture-to-texture copies are relatively fast, and resizing them is relatively easy.
GLBufferRef tmpDstTex = texToTexCopier->copyToNewBuffer(tmpSrcTex);
- GLTexToCPUCopier copies texture-type GLBuffers to CPU-type GLBuffers. It has two basic access points, one which is suitable for performing immediate one-shot texture downloads, and another asynchronous mode which has been optimized to be substantially more efficient.
GLBufferRef tmpBuffer = texToCPUCopier->downloadTexToCPU(tmpTexBuffer);
if (tmpBuffer!=nullptr && tmpBuffer->pboMapped) {
void *tmpBufferData = tmpBuffer->cpuBackingPtr;
uint32_t bytesPerRow = tmpBuffer->calculateBackingBytesPerRow();
uint32_t totalLength = tmpBuffer->calculateBackingLength();
}
GLBufferRef downloadedFrame = texToCPUCopier->streamTexToCPU(newFrameTexture);
if (downloadedFrame != nullptr) {
void *downloadedData = NULL;
uint32_t bytesPerRow = 0;
uint32_t totalLength = 0;
if ((downloadedFrame->desc.type == Type_PBO && downloadedFrame->pboMapped) ||
(downloadedFrame->desc.type == Type_CPU))
{
downloadedData = downloadedFrame->cpuBackingPtr;
bytesPerRow = downloadedFrame->calculateBackingBytesPerRow();
totalLength = downloadedFrame->calculateBackingLength();
}
}
- GLCPUToTexCopier copies CPU-type GLBuffers to texture-type GLBuffers. It also has two basic access modes, one which is optimized for immediate upload and another, more efficient/optimized mode for streaming data to textures.
GLBufferRef tmpBuffer = cpuToTexCopier->uploadCPUToTex(tmpCPUTypeBuffer);
GLBufferRef uploadedFrame = cpuToTexCopier->streamCPUToTex(newFrameCPUBuffer);
if (uploadedFrame != nullptr) {
}