Skip to content

Instantly share code, notes, and snippets.

@JuanDiegoMontoya
Last active June 22, 2022 08:34
Show Gist options
  • Save JuanDiegoMontoya/e0d9b2e4dc4ae1464a515414dc2ba7b4 to your computer and use it in GitHub Desktop.
Save JuanDiegoMontoya/e0d9b2e4dc4ae1464a515414dc2ba7b4 to your computer and use it in GitHub Desktop.
glCopyBufferSubData (ancient edition)
/*
* This snippet demonstrates how to copy the contents of a buffer to another buffer without CPU readback
* using only features available in OpenGL 2.1.
* I use DSA for brevity, but hopefully it should be obvious how to convert this to ancient GL if needed :)
* The method involves creating a temporary texture and framebuffer, copying the source buffer's contents
* to the texture (via pixel unpack), then copying the texture's contents to the destination buffer using pixel pack.
*/
// convenience
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
// create source and destination buffers
GLubyte someData[8]{ 0, 1, 2, 3, 4, 5, 6, 7 };
GLuint myBuffers[2];
glCreateBuffers(2, myBuffers);
glNamedBufferStorage(myBuffers[0], sizeof(someData), someData, 0);
glNamedBufferStorage(myBuffers[1], sizeof(someData), nullptr, 0);
// create intermediate objects
GLuint tempTex;
glCreateTextures(GL_TEXTURE_2D, 1, &tempTex);
glTextureStorage2D(tempTex, 1, GL_R8, sizeof(someData), 1);
GLuint tempFbo;
glCreateFramebuffers(1, &tempFbo);
glNamedFramebufferTexture(tempFbo, GL_COLOR_ATTACHMENT0, tempTex, 0);
// upload buffer contents to texture
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, myBuffers[0]);
glTextureSubImage2D(tempTex, 0, 0, 0, sizeof(someData), 1, GL_RED, GL_UNSIGNED_BYTE, 0);
// download buffer contents from texture
glBindFramebuffer(GL_READ_FRAMEBUFFER, tempFbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, myBuffers[1]);
glReadnPixels(0, 0, sizeof(someData), 1, GL_RED, GL_UNSIGNED_BYTE, sizeof(someData), 0);
// free intermediate objects
glDeleteFramebuffers(1, &tempFbo);
glDeleteTextures(1, &tempTex);
// download the data to ensure the second buffer received it
GLubyte someData2[sizeof(someData)];
glGetNamedBufferSubData(myBuffers[1], 0, sizeof(someData), someData2);
for (int i = 0; i < sizeof(someData); i++)
{
printf("%d ", someData2[i]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment