视频教程请关注 http://edu.csdn.net/lecturer/lecturer_detail?lecturer_id=440

一个朋友在问(我也曾经遇到过这样的事情),尤其是在地理信息上面,地图上的一些矢量数据,以及

影像数据,在地图没有变化(比如,缩放,平移,编辑)都是不需要绘制的,只有需要绘制的时候,在去绘制

背景,想必,这个道理大家一定都很明白,但是OpenGL每次在绘制的时候是必须都要进入渲染管线进行绘制

于是很多人就在想,是否可以把一些不需要变化的数据绘制到图片上,需要绘制的时候在进行重新绘制,就像

windows DC一样呢?在OpenGL早期的版本中是没有把数据绘制到图片上这个功能的,当然在创建OpenGL

的时候有这个选项,本人亲身试验过,那个效率,那个差呀,OpenGL初始化代码如下所示:

PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
,
PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_SUPPORT_DIRECTDRAW | PFD_SWAP_EXCHANGE,
PFD_TYPE_RGBA,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
PFD_MAIN_PLANE,
,
,
, };

红色的部分就是绘制到图片的选项。

这种方案是不可取的,且不说他的效率问题,也满足不了目前的需求,在OpenGL1.1版本中,我们可以操作颜色缓冲区,或者

叫帧缓冲区,在OpenGL中,至少存在两个缓冲区(当我们选择双缓冲绘制的时候),我们可以把数据绘制到缓冲区以后,在将

缓冲区的数据直接的生成到纹理上,这样在把纹理绘制到背景中,这样,就可以有选择的去更新背景,而不是实时的去绘制背景

数据,流程如下图所示:

代码如下所示:

        glClearColor(, , , );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushAttrib(GL_COLOR_BUFFER_BIT | GL_PIXEL_MODE_BIT); // for GL_DRAW_BUFFER and GL_READ_BUFFER
glDrawBuffer(GL_BACK);
glReadBuffer(GL_BACK); //! 绘制数据到GL_BACK缓冲区
//! 绘制完成,将缓冲区内容cpopy到纹理 glBindTexture(GL_TEXTURE_2D, textureId);
glCopyTexSubImage2D(GL_TEXTURE_2D, , , , , , TEXTURE_WIDTH, TEXTURE_HEIGHT);
glBindTexture(GL_TEXTURE_2D, );
glPopAttrib(); // GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT //! 其他实时绘制内容

当然,这个方式比较老土,但能实现我们想要的功能,而且效率也不赖。在新的OpenGL版本中实现这个过程有很多方式

例如比较流行的就是FBO( Fram buffer object),帧缓冲区对象,其实就是我们上面的过程,所不同的是:上面我们用到

的缓冲区是OpenGL给我们创建的,我们没有办法干预创建的过程,而后者则可以干预这个过程,我们可以自己去创建帧

缓冲区,并使用它,当然这个需要更高的OpenGL版本,你需要做更多的事情。

下面是创建Frame Buffer Object 的代码:

        glGenFramebuffersEXT(, &targetId._FBOID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, targetId._FBOID); glGenRenderbuffersEXT(, &targetId._RBOID);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, targetId._RBOID);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ); //glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, targetId._RBOID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, );

创建了以后,为了把数据绘制到上面,我们还需要给他绑定一个纹理,这个过程就像我们创建一个内存DC一样,如果没有和图片绑定

绘制是没有任何意义的;

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, targetId._FBOID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId._texture, );

绑定纹理以后,以后的绘制,则是将数据绘制到纹理上了;代码中可以这样使用:

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, targetId->_FBOID);
glBegin()
...
glEnd()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

在一种方式就是PBuffer:像素缓冲区,过程和这个相似。每一种方式都有自己的优点与缺点,在不同的场合用不同的方式

做到最大化利用就对了。

后续会专门对离屏渲染做专门的例程。感谢大家阅读,本人能力有限,错误,误导之处请指教。

OpenGL-非实时渲染与实时混合使用(有图有真相)的更多相关文章

  1. 【实时渲染】实时3D渲染如何加速汽车线上体验应用推广

    在过去,一支优秀的广告片足以让消费者对一辆汽车产生兴趣.完美的底盘线条或引擎的轰鸣声便会让潜在买家跑到经销商那里试驾.现在,广告还是和往常一样,并没有失去其特性,但86%的买家在与销售交流之前会在网上 ...

  2. 【原】实时渲染中常用的几种Rendering Path

    [原]实时渲染中常用的几种Rendering Path 本文转载请注明出处 —— polobymulberry-博客园 本文为我的图形学大作业的论文部分,介绍了一些Rendering Path,比较简 ...

  3. 利用GPU实现无尽草地的实时渲染

    0x00 前言 在游戏中展现一个写实的田园场景时,草地的渲染是必不可少的,而一提到高效率的渲染草地,很多人都会想起GPU Gems第七章 <Chapter 7. Rendering Countl ...

  4. 画面渲染:实时渲染(Real-time Rendering)、离线渲染(Offline Rendering)[转]

    实时渲染(Real-time Rendering) 实时渲染的本质就是图形数据的实时计算和输出.最典型的图形数据源是顶点.顶点包括了位置.法向.颜色.纹理坐标.顶点的权重等.在第一代渲染技术中(198 ...

  5. 封装CIImage实现实时渲染

    封装CIImage实现实时渲染 CIImage属于CoreImage里面的东东,用来渲染图片的,为什么要封装它呢?其实很简单,封装好之后使用更加方便. 如果直接使用CIImage渲染图片,使用的流程如 ...

  6. 如何实现最佳的跨平台游戏体验?Unity成亮解密实时渲染

    7月31日,2018云创大会游戏论坛在杭州国际博览中心103B圆满举行.本场游戏论坛聚焦探讨了可能对游戏行业发展有重大推动的新技术.新实践,如AR.区块链.安全.大数据等. Unity大中华区技术经理 ...

  7. Unity Shader入门精要学习笔记 - 第14章非真实感渲染

    转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...

  8. 通过OpenGL理解前端渲染原理(1)

    一.OpenGL OpenGL,是一套绘制3D图形的API,当然它也可以用来绘制2D的物体.OpenGL有一大套可以用来操作模型和图片的函数,通常编写OpenGL库的人是显卡的制造者.我们买的显卡都支 ...

  9. 实时渲染基础(4)纹理(Texture)

    目录 纹理映射(Texture Mapping) 球形贴图(Spherical Map) 立方体贴图(Cube Map) 纹理走样问题 Mipmap 各向异性过滤(Ripmap) 纹理应用技术(Tex ...

随机推荐

  1. 使用idea,springboot,springsession,redis实现分布式微服务的session 共享

    本次开发环境:idea2016.3.4 +jdk1.8+maven3.3.9+redis+springboot+jedis 本文中的项目使用Maven来管理项目依赖,使用Spring Session和 ...

  2. Swift要点:从Objective-C开发者的角度看Swift

    代码环境是Xcode6.3-Beta3. Swift已经极大的改变了开发iOS应用的方式.本文中,我会列出Swift的几个重点,并且和Objective-C一一做出对比. 注意,本文不是Swift的入 ...

  3. hdu 5064 满足b2−b1≤b3−b2... 的最长子序列

    http://acm.hdu.edu.cn/showproblem.php?pid=5064 要找出一个数组中满足b2−b1≤b3−b2≤⋯≤bt−bt−1 的最大的t 直接引题解: 1003 Fin ...

  4. javascript 问题

    两个数组比较:a.sort().toString() == b.sort().toString() for循环内有异步方法时,需要闭包 JSON.parse(data)出错时(提示.[nodejs中] ...

  5. 网页程序 vs 桌面程序

    网页程序 vs 桌面程序 阅读:  评论:  作者:Rybby  日期:  来源:rybby.com 所谓的网页程序就是指以网页作为程序的操作界面,通过脚本语言“javascript”或其它客户端语言 ...

  6. [label][JavaScript]七个JavaScript技巧

    重点:http://www.javascriptkit.com/ create an object: var car = new Object(); car.colour = 'red'; car.w ...

  7. Linux服务器目录空间不足解决措施

      一般情况下工作环境中我们的服务或数据库文件都会存储在一个单独挂载的分区中,一般占空间比较大的大多就是服务的运行日志以及数据库文件,当我们分区的可用空间不足时就需要我们对分区进行扩容,或者找其它方法 ...

  8. c# WPF客户端调用WebAPI并转换成List

    利用HttpClient.JsonConvert实现. 引用Newtonsoft.Json.dll和System.Net.Http. 举个例子:从webapi中获取设备列表. public parti ...

  9. UE4随笔 二 第一印象

    打开UE4,短暂的兴奋过后,开始大概扫一扫UE4的编辑器,整个界面比UE3更有现代气息: 之前看其他人写的文章,虚幻4最重要的改动集中在下面几个方向上: 跨平台: WIN和MAC平台都能使用,这就意味 ...

  10. pageadmin CMS网站建设教程:模板中如何实现信息数据共享

    pageadmin CMS网站制作教程:模板中如何实现信息数据共享 很多时候信息数据需要共享,一个最常用的应用场景就是手机版(独立手机,非响应式)本共享pc版本数据,下面以这个场景为例讲解. 假设手机 ...