PBO
来源:互联网 发布:eviews怎么导入数据 编辑:程序博客网 时间:2024/05/22 05:12
PBO(Pixel Buffer Object),将像素数据存储在显存中。
优点:
1、快速的像素数据传递,它采用了一种叫DMA(Direct Memory Access)的技术,无需CPU介入2、 高效并不在于传输更快,而在于与硬件相关的异步调用方式,调用之后CPU即返回执行其它操作(使用DMA方式的传输、由OpenGL直接控制)
3、在单个PBO情况下并不能得到很好的效果,毕竟传输过程仍然存在(但速度可能变快,比如显存内部的数据传输),但其异步性就提供了双PBO实现的可能性,用双PBO来进行加速
左图是传统的加载一个纹理的示意图,可以看到,首先将纹理图像读到内存,然后再从内存拷贝到纹理对象中,这两个过程均需CPU的参与;而右图采用了PBO加载纹理,首先将像素数据加载到PBO中,然后通过DMA方式传送到纹理对象,最后一步不需要CPU参与。
创建PBO:
1. 用glGenBuffersARB()生成缓存对象;
2. 用glBindBufferARB()绑定缓存对象;
3. 用glBufferDataARB()将像素数据拷贝到缓存对象。
映射PBO:
void* glMapBufferARB(GLenum target, GLenum access);
GLboolean glUnmapBufferARB(GLenum target);
几个参数的释疑:
GL_PIXEL_PACK_BUFFER_ARB 将像素数据传给PBO
GL_PIXEL_UNPACK_BUFFER_ARB 从PBO得到像素数据
比如说,glReadPixel就是从帧缓存中读取数据,写到PBO中,可理解为“pack”;glDrawPixel是从PBO中读取数据,写到到帧缓存,可理解为“unpack”;glGetTexImage是从纹理对象到PBO,可理解为“pack”;glTexImage2d从PBO写到纹理对象(texture object),可理解为“unpack”。
#include <iostream>#include <gl/glew.h>#include <gl/glut.h>using namespace std;GLuint pboIds[2]; GLuint textureId; // Storage For 6 face Textures //camerafloat cameraAngleX;float cameraAngleY;float cameraDistance = -5.0;//mousebool mouseLeftDown;bool mouseRightDown;float LastXPos;float LastYPos;const int IMAGE_WIDTH = 1024;const int IMAGE_HEIGHT = 1024;const int CHANNEL_COUNT = 4;const int DATA_SIZE = IMAGE_WIDTH * IMAGE_HEIGHT * CHANNEL_COUNT;GLubyte* imageData = 0; void initGL(){glEnable(GL_TEXTURE_2D); // Enable Texture MappingglShadeModel(GL_SMOOTH); // Enable Smooth ShadingglClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black BackgroundglGenTextures(1, &textureId);glBindTexture(GL_TEXTURE_2D, textureId);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, IMAGE_WIDTH, IMAGE_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)imageData);glBindTexture(GL_TEXTURE_2D, 0);glGenBuffers(2, pboIds);glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[0]);glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0, GL_STREAM_DRAW);glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[1]);glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0, GL_STREAM_DRAW);glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);}void updatePixels(GLubyte* dst, int size){static int color = 0;if(!dst)return;int* ptr = (int*)dst;// copy 4 bytes at oncefor(int i = 0; i < IMAGE_HEIGHT; ++i){for(int j = 0; j < IMAGE_WIDTH; ++j){*ptr = color;ptr++;}color += 257; // add an arbitary number (no meaning)}++color; // scroll down}void display(){static int index = 0;int nextIndex = 0; index = (index + 1) % 2;nextIndex = (index + 1) % 2;glBindTexture(GL_TEXTURE_2D, textureId);glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[index]);// copy pixels from PBO to texture object// Use offset instead of ponter.glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, GL_BGRA, GL_UNSIGNED_BYTE, 0);// bind PBO to update pixel valuesglBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[nextIndex]);glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0, GL_STREAM_DRAW);GLubyte* ptr = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);if(ptr){// update data directly on the mapped bufferupdatePixels(ptr, DATA_SIZE);glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // release pointer to mapping buffer}glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);glClear(GL_COLOR_BUFFER_BIT);glPushMatrix();// tramsform cameraglTranslatef(0, 0, cameraDistance);glRotatef(cameraAngleX, 1, 0, 0); // pitchglRotatef(cameraAngleY, 0, 1, 0); // headingglBindTexture(GL_TEXTURE_2D, textureId);glColor4f(1, 1, 1, 1);glBegin(GL_QUADS);glNormal3f(0, 0, 1);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);glEnd();glBindTexture(GL_TEXTURE_2D, 0);glPopMatrix();glutSwapBuffers();}void reshape(int w, int h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(60.0f, (GLfloat)w/(GLfloat)h, 0.01f, 100.0f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void mouse(int button, int state, int x, int y){if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){mouseLeftDown = true;LastXPos = x;LastYPos = y;}if (button == GLUT_RIGHT_BUTTON && state == GLUT_UP){mouseRightDown = true;}}void mouseMotion(int x, int y){if (mouseLeftDown){cameraAngleX += GLfloat(y - LastYPos)/GLfloat(20.0);cameraAngleY += GLfloat(x - LastXPos)/GLfloat(20.0);LastYPos = y;LastXPos = x;}}int main(int argc, char **argv){imageData = new GLubyte[DATA_SIZE];memset(imageData, 0, DATA_SIZE);glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);glutInitWindowSize(480, 640);glutInitWindowPosition(100, 100);glutCreateWindow("PBO");glewInit();if(!glewIsSupported("GL_VERSION_2_0")){fprintf(stderr, "ERROR: Support for necessary OpengGL extensions missing.");}initGL();glutDisplayFunc(display);glutIdleFunc(display); glutReshapeFunc(reshape);glutMouseFunc(mouse);glutMotionFunc(mouseMotion);glutMainLoop();glDeleteBuffers(2, pboIds);glDeleteTextures(1, &textureId);delete []imageData;return 0;}
参考:http://www.songho.ca/opengl/gl_pbo.html
- PBO
- PBO
- OpenGL---PBO
- VBO,PBO,FBO
- VBO, PBO与FBO
- VAO, VBO, PBO, FBO
- VBO, PBO与FBO
- SAP ERP101 interface PBO definition
- OpenGL Pixel Buffer Object (PBO)
- OPENGL VBO,FBO和PBO
- OpenGL Pixel Buffer Object (PBO)
- OpenGL VBO, PBO与FBO
- OpenGL像素缓冲对象(PBO)
- 【SAP UI】PBO和PAI
- OpenGL VBO, PBO与FBO
- OpenGL Pixel Buffer Object (PBO)
- 使用Opengl PBO上传下载数据
- OpenGL VBO, PBO与FBO
- VIM使用技巧
- spring和hibernate整合
- Longest Ordered Subsequence
- wwdc 2013
- 最长公共子字符串
- PBO
- 不能移动的石子合并
- 【修炼十一】联调
- 最大长方体问题
- CArray类中GetAt()函数与ElementAt()函数的区别
- 区间相交问题
- MySQL学习记录(约束+语法+演示分析)三
- 可以移动的石子合并
- 删数问题