热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

OpenGLPBO

PBO(PixelBufferObject),将像素数据存储在显存中。优点:1、快速的像素数据传递,它采用了一种叫DMA(DirectM

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   
  2. #include   
  3. #include   
  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 &#61; 0; i < IMAGE_HEIGHT; &#43;&#43;i)  
  64.     {  
  65.         for(int j &#61; 0; j < IMAGE_WIDTH; &#43;&#43;j)  
  66.         {  
  67.             *ptr &#61; color;  
  68.             ptr&#43;&#43;;  
  69.         }  
  70.         color &#43;&#61; 257;   // add an arbitary number (no meaning)  
  71.     }  
  72.     &#43;&#43;color;            // scroll down  
  73. }  
  74.   
  75. void display()  
  76. {  
  77.     static int index &#61; 0;  
  78.     int nextIndex &#61; 0;       
  79.       
  80.     index &#61; (index &#43; 1) % 2;  
  81.     nextIndex &#61; (index &#43; 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 &#61; (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 &#61;&#61; GLUT_LEFT_BUTTON && state &#61;&#61; GLUT_DOWN)  
  148.     {  
  149.         mouseLeftDown &#61; true;  
  150.   
  151.         LastXPos &#61; x;  
  152.         LastYPos &#61; y;  
  153.     }  
  154.   
  155.     if (button &#61;&#61; GLUT_RIGHT_BUTTON && state &#61;&#61; GLUT_UP)  
  156.     {  
  157.         mouseRightDown &#61; true;  
  158.     }  
  159. }  
  160.   
  161.   
  162. void mouseMotion(int x, int y)  
  163. {  
  164.     if (mouseLeftDown)  
  165.     {  
  166.         cameraAngleX &#43;&#61; GLfloat(y - LastYPos)/GLfloat(20.0);  
  167.         cameraAngleY &#43;&#61; GLfloat(x - LastXPos)/GLfloat(20.0);  
  168.   
  169.         LastYPos &#61; y;  
  170.         LastXPos &#61; x;  
  171.     }  
  172. }  
  173.   
  174. int main(int argc, char **argv)  
  175. {  
  176.     imageData &#61; 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. }  

推荐阅读
  • 主调|大侠_重温C++ ... [详细]
  • 本文详细介绍了钩子(hook)的概念、原理及其在编程中的实际应用。通过对比回调函数和注册函数,解释了钩子的工作机制,并提供了具体的Python示例代码,帮助读者更好地理解和掌握这一重要编程工具。 ... [详细]
  • 深入解析 Android IPC 中的 Messenger 机制
    本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • ListView简单使用
    先上效果:主要实现了Listview的绑定和点击事件。项目资源结构如下:先创建一个动物类,用来装载数据:Animal类如下:packagecom.example.simplelis ... [详细]
  • 本文详细介绍了get和set方法的作用及其在编程中的实现方式,同时探讨了点语法的使用场景。通过具体示例,解释了属性声明与合成存取方法的概念,并补充了相关操作的最佳实践。 ... [详细]
  • 由二叉树到贪心算法
    二叉树很重要树是数据结构中的重中之重,尤其以各类二叉树为学习的难点。单就面试而言,在 ... [详细]
  • Python自动化测试入门:Selenium环境搭建
    本文详细介绍如何在Python环境中安装和配置Selenium,包括开发工具PyCharm的安装、Python环境的设置以及Selenium包的安装方法。此外,还提供了编写和运行第一个自动化测试脚本的步骤。 ... [详细]
  • 本文探讨了如何在Classic ASP中实现与PHP的hash_hmac('SHA256', $message, pack('H*', $secret))函数等效的哈希生成方法。通过分析不同实现方式及其产生的差异,提供了一种使用Microsoft .NET Framework的解决方案。 ... [详细]
  • Java多线程实现:从1到100分段求和并汇总结果
    本文介绍如何使用Java编写一个程序,通过10个线程分别计算不同区间的和,并最终汇总所有线程的结果。每个线程负责计算一段连续的整数之和,最后将所有线程的结果相加。 ... [详细]
  • 本文介绍了如何通过Java代码计算一个整数的位数,并展示了多个基础编程示例,包括求和、平均分计算、条件判断等。 ... [详细]
  • 本文将详细探讨 Java 中提供的不可变集合(如 `Collections.unmodifiableXXX`)和同步集合(如 `Collections.synchronizedXXX`)的实现原理及使用方法,帮助开发者更好地理解和应用这些工具。 ... [详细]
  • 本文详细探讨了Java中的ClassLoader类加载器的工作原理,包括其如何将class文件加载至JVM中,以及JVM启动时的动态加载策略。文章还介绍了JVM内置的三种类加载器及其工作方式,并解释了类加载器的继承关系和双亲委托机制。 ... [详细]
  • Python notes
    6.1.1.执行模块当你用下面的方式运行一个Python模块pythonfibo.py模块中的代码将会被执行,就像导入它一样,不过此时__name__被设置为__main__。 ... [详细]
  • 为了解决不同服务器间共享图片的需求,我们最初考虑建立一个FTP图片服务器。然而,考虑到项目是一个简单的CMS系统,为了简化流程,团队决定探索七牛云存储的解决方案。本文将详细介绍使用七牛云存储的过程和心得。 ... [详细]
author-avatar
UUUUUUUUUU8
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有