-
-
Save IanByun/e9c2d27ea74a27bdfa7c535fb4e513d0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ofPBO.cpp | |
* | |
* Created on: 08/04/2012 | |
* Author: arturo | |
* Revised on: 2016-08-27 | |
* Reviser: ofIan, Ian Byun | |
* updated to match deletion and renaming of ofTextureData members | |
*/ | |
#include "ofPBO.h" | |
ofPBO::ofPBO() { | |
// TODO Auto-generated constructor stub | |
} | |
ofPBO::~ofPBO() { | |
if(!pboIds.empty()){ | |
glDeleteBuffersARB(pboIds.size(), &pboIds[0]); | |
} | |
} | |
void ofPBO::allocate(ofTexture & tex, int numPBOs) { | |
pboIds.resize(numPBOs); | |
glGenBuffersARB(numPBOs, &pboIds[0]); | |
int numChannels=1; | |
switch(tex.getTextureData().glInternalFormat) { | |
case GL_LUMINANCE: | |
numChannels = 1; | |
break; | |
case GL_RGB: case GL_RGB8: | |
numChannels = 3; | |
break; | |
case GL_RGBA: case GL_RGBA8: | |
numChannels = 4; | |
break; | |
} | |
dataSize = tex.getWidth()*tex.getHeight()*numChannels; | |
for(int i=0; i<(int)pboIds.size(); i++){ | |
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboIds[i]); | |
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, dataSize, 0, GL_STREAM_DRAW_ARB); | |
} | |
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); | |
texture = tex; | |
glInternalFormat = tex.getTextureData().glInternalFormat; //GL_RGB8 | |
glFormat = ofGetGLFormatFromInternal(glInternalFormat); //GL_RGB | |
glType = ofGetGlTypeFromInternal(glInternalFormat); //GL_UNSIGNED_BYTE | |
ofLogNotice() << "glInternalFormat: " << ofGetGlInternalFormatName(glInternalFormat); | |
ofLogNotice() << "glFormat: " << ofGetGlInternalFormatName(glFormat); | |
ofLogNotice() << "glType: " << (glType == GL_UNSIGNED_BYTE? "GL_UNSIGNED_BYTE" : ofToString(glType)) << endl; | |
} | |
void ofPBO::updateData(const ofPixels & pixels) { | |
if(pboIds.empty()){ | |
ofLogError() << "pbo not allocated"; | |
return; | |
} | |
//this is from http://www.songho.ca/opengl/gl_pbo.html | |
// "index" is used to copy pixels from a PBO to a texture object | |
// "nextIndex" is used to update pixels in the other PBO | |
index = (index + 1) % pboIds.size(); // 오버플로우를 감안한 ++index | |
int nextIndex = (index + 1) % pboIds.size(); | |
// bind PBO to update pixel values | |
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboIds[nextIndex]); | |
// map the buffer object into client's memory | |
// Note that glMapBufferARB() causes sync issue. | |
// If GPU is working with this buffer, glMapBufferARB() will wait(stall) | |
// for GPU to finish its job. To avoid waiting (stall), you can call | |
// first glBufferDataARB() with NULL pointer before glMapBufferARB(). | |
// If you do that, the previous data in PBO will be discarded and | |
// glMapBufferARB() returns a new allocated pointer immediately | |
// even if GPU is still working with the previous data. | |
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, dataSize, 0, GL_STREAM_DRAW_ARB); | |
GLubyte* ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); | |
if(ptr) { | |
// update data directly on the mapped buffer | |
memcpy(ptr, pixels.getPixels(), dataSize); | |
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); // release pointer to mapping buffer | |
} | |
// it is good idea to release PBOs with ID 0 after use. | |
// Once bound with 0, all pixel operations behave normal ways. | |
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); | |
} | |
void ofPBO::updateTexture() { | |
// bind the texture and PBO | |
texture.bind(); | |
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboIds[index]); | |
//http://stackoverflow.com/questions/2405734/difference-between-gltexsubimage-and-glteximage-function-in-opengl | |
//https://www.opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads | |
//https://www.opengl.org/sdk/docs/man/html/glTexSubImage2D.xhtml | |
glTexSubImage2D(texture.getTextureData().textureTarget, 0, 0, 0, texture.getWidth(), texture.getHeight(), glFormat, glType, 0); | |
texture.unbind(); | |
// it is good idea to release PBOs with ID 0 after use. | |
// Once bound with 0, all pixel operations behave normal ways. | |
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment