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”。
[cpp] view plaincopy
- #include
- #include
- #include
- using namespace std;
- GLuint pboIds[2];
- GLuint textureId; // Storage For 6 face Textures
- //camera
- float cameraAngleX;
- float cameraAngleY;
- float cameraDistance = -5.0;
- //mouse
- bool 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 Mapping
- glShadeModel(GL_SMOOTH); // Enable Smooth Shading
- glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
- glGenTextures(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 once
- for(int i = 0; i
关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?