热门标签 | 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. }  

推荐阅读
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 文件描述符、文件句柄与打开文件之间的关联解析
    本文详细探讨了文件描述符、文件句柄和打开文件之间的关系,通过具体示例解释了它们在操作系统中的作用及其相互影响。 ... [详细]
  • 探索1000以内的完美数:因数和等于自身
    本文探讨了如何在1000以内找到所有完美数,即一个数的因数(不包括自身)之和等于该数本身。例如,6是一个完美数,因为1 + 2 + 3 = 6。通过编程实现这一过程,可以更好地理解完美数的特性。 ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
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社区 版权所有