OpenGL---PBO

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

  1. #include <iostream>  
  2. #include <gl/glew.h>  
  3. #include <gl/glut.h>  
  4. using namespace std;  
  5.   
  6.   
  7. GLuint pboIds[2];      
  8. GLuint textureId;   // Storage For 6 face Textures   
  9.   
  10. //camera  
  11. float cameraAngleX;  
  12. float cameraAngleY;  
  13. float cameraDistance = -5.0;  
  14.   
  15. //mouse  
  16. bool mouseLeftDown;  
  17. bool mouseRightDown;  
  18. float LastXPos;  
  19. float LastYPos;  
  20.   
  21. const int    IMAGE_WIDTH = 1024;  
  22. const int    IMAGE_HEIGHT = 1024;  
  23. const int    CHANNEL_COUNT = 4;  
  24. const int    DATA_SIZE = IMAGE_WIDTH * IMAGE_HEIGHT * CHANNEL_COUNT;  
  25.   
  26. GLubyte* imageData = 0;   
  27.   
  28.   
  29. void initGL()  
  30. {  
  31.   
  32.     glEnable(GL_TEXTURE_2D);       // Enable Texture Mapping  
  33.     glShadeModel(GL_SMOOTH);       // Enable Smooth Shading  
  34.     glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    // Black Background  
  35.   
  36.     glGenTextures(1, &textureId);  
  37.     glBindTexture(GL_TEXTURE_2D, textureId);  
  38.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);  
  39.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);  
  40.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);  
  41.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);  
  42.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, IMAGE_WIDTH, IMAGE_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)imageData);  
  43.     glBindTexture(GL_TEXTURE_2D, 0);  
  44.   
  45.     glGenBuffers(2, pboIds);  
  46.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[0]);  
  47.     glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0, GL_STREAM_DRAW);  
  48.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[1]);  
  49.     glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0, GL_STREAM_DRAW);  
  50.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);  
  51. }  
  52.   
  53. void updatePixels(GLubyte* dst, int size)  
  54. {  
  55.     static int color = 0;  
  56.   
  57.     if(!dst)  
  58.         return;  
  59.   
  60.     int* ptr = (int*)dst;  
  61.   
  62.     // copy 4 bytes at once  
  63.     for(int i = 0; i < IMAGE_HEIGHT; ++i)  
  64.     {  
  65.         for(int j = 0; j < IMAGE_WIDTH; ++j)  
  66.         {  
  67.             *ptr = color;  
  68.             ptr++;  
  69.         }  
  70.         color += 257;   // add an arbitary number (no meaning)  
  71.     }  
  72.     ++color;            // scroll down  
  73. }  
  74.   
  75. void display()  
  76. {  
  77.     static int index = 0;  
  78.     int nextIndex = 0;       
  79.       
  80.     index = (index + 1) % 2;  
  81.     nextIndex = (index + 1) % 2;  
  82.   
  83.     glBindTexture(GL_TEXTURE_2D, textureId);  
  84.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[index]);  
  85.   
  86.     // copy pixels from PBO to texture object  
  87.     // Use offset instead of ponter.  
  88.     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, GL_BGRA, GL_UNSIGNED_BYTE, 0);  
  89.   
  90.     // bind PBO to update pixel values  
  91.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[nextIndex]);  
  92.   
  93.     glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0, GL_STREAM_DRAW);  
  94.     GLubyte* ptr = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);  
  95.     if(ptr)  
  96.     {  
  97.         // update data directly on the mapped buffer  
  98.         updatePixels(ptr, DATA_SIZE);  
  99.         glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // release pointer to mapping buffer  
  100.     }  
  101.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);  
  102.   
  103.     glClear(GL_COLOR_BUFFER_BIT);  
  104.   
  105.     glPushMatrix();  
  106.   
  107.     // tramsform camera  
  108.     glTranslatef(0, 0, cameraDistance);  
  109.     glRotatef(cameraAngleX, 1, 0, 0);   // pitch  
  110.     glRotatef(cameraAngleY, 0, 1, 0);   // heading  
  111.   
  112.     glBindTexture(GL_TEXTURE_2D, textureId);  
  113.     glColor4f(1, 1, 1, 1);  
  114.     glBegin(GL_QUADS);  
  115.     glNormal3f(0, 0, 1);  
  116.     glTexCoord2f(0.0f, 0.0f);   glVertex3f(-1.0f, -1.0f, 0.0f);  
  117.     glTexCoord2f(1.0f, 0.0f);   glVertex3f( 1.0f, -1.0f, 0.0f);  
  118.     glTexCoord2f(1.0f, 1.0f);   glVertex3f( 1.0f,  1.0f, 0.0f);  
  119.     glTexCoord2f(0.0f, 1.0f);   glVertex3f(-1.0f,  1.0f, 0.0f);  
  120.     glEnd();  
  121.   
  122.     glBindTexture(GL_TEXTURE_2D, 0);  
  123.   
  124.     glPopMatrix();  
  125.   
  126.     glutSwapBuffers();  
  127. }  
  128.   
  129. void reshape(int w, int h)  
  130. {  
  131.     glViewport(0, 0, w, h);  
  132.       
  133.     glMatrixMode(GL_PROJECTION);  
  134.     glLoadIdentity();  
  135.   
  136.     gluPerspective(60.0f, (GLfloat)w/(GLfloat)h, 0.01f, 100.0f);  
  137.       
  138.   
  139.     glMatrixMode(GL_MODELVIEW);  
  140.     glLoadIdentity();  
  141. }  
  142.   
  143.   
  144. void mouse(int button, int state, int x, int y)  
  145. {  
  146.   
  147.     if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)  
  148.     {  
  149.         mouseLeftDown = true;  
  150.   
  151.         LastXPos = x;  
  152.         LastYPos = y;  
  153.     }  
  154.   
  155.     if (button == GLUT_RIGHT_BUTTON && state == GLUT_UP)  
  156.     {  
  157.         mouseRightDown = true;  
  158.     }  
  159. }  
  160.   
  161.   
  162. void mouseMotion(int x, int y)  
  163. {  
  164.     if (mouseLeftDown)  
  165.     {  
  166.         cameraAngleX += GLfloat(y - LastYPos)/GLfloat(20.0);  
  167.         cameraAngleY += GLfloat(x - LastXPos)/GLfloat(20.0);  
  168.   
  169.         LastYPos = y;  
  170.         LastXPos = x;  
  171.     }  
  172. }  
  173.   
  174. int main(int argc, char **argv)  
  175. {  
  176.     imageData = new GLubyte[DATA_SIZE];  
  177.     memset(imageData, 0, DATA_SIZE);  
  178.       
  179.     glutInit(&argc, argv);  
  180.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);  
  181.     glutInitWindowSize(480, 640);  
  182.     glutInitWindowPosition(100, 100);  
  183.     glutCreateWindow("PBO");  
  184.   
  185.     glewInit();  
  186.     if(!glewIsSupported("GL_VERSION_2_0"))  
  187.     {  
  188.         fprintf(stderr, "ERROR: Support for necessary OpengGL extensions missing.");  
  189.     }  
  190.   
  191.     initGL();  
  192.   
  193.     glutDisplayFunc(display);  
  194.     glutIdleFunc(display);    
  195.     glutReshapeFunc(reshape);  
  196.     glutMouseFunc(mouse);  
  197.     glutMotionFunc(mouseMotion);  
  198.   
  199.     glutMainLoop();  
  200.       
  201.     glDeleteBuffers(2, pboIds);  
  202.     glDeleteTextures(1, &textureId);  
  203.   
  204.     delete []imageData;  
  205.   
  206.     return 0;  
  207. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值