OpenGL中的深度、深度缓存、深度测试及保存成图片
1、深度
所谓深度,就是在openGL坐标系中,像素点Z坐标距离摄像机的距离。摄像机可能放在坐标系的任何位置,那么,就不能简单的说Z数值越大或越小,就是越靠近摄像机。
2、深度缓冲区
深度缓冲区原理就是把一个距离观察平面(近裁剪面)的深度值(或距离)与窗口中的每个像素相关联。
首先,使用glClear(GL_DEPTH_BUFFER_BIT),把所有像素的深度值设置为最大值(一般是远裁剪面)。
然后,在场景中以任意次序绘制所有物体。硬件或者软件所执行的图形计算把每一个绘制表面转换为窗口上一些像素的集合,此时并不考虑是否被其他物体遮挡。
其次,OpenGL会计算这些表面和观察平面的距离。如果启用了深度缓冲区,在绘制每个像素之前,OpenGL会把它的深度值和已经存储在这个像素的深度值进行比较。新像素深度值<原先像素深度值,则新像素值会取代原先的;反之,新像素值被遮挡,他颜色值和深度将被丢弃。
为了启动深度缓冲区,必须先启动它,即glEnable(GL_DEPTH_TEST)。每次绘制场景之前,需要先清除深度缓冲区,即glClear(GL_DEPTH_BUFFER_BIT),然后以任意次序绘制场景中的物体。
数学基础:
待渲染的照相机空间中的深度经常定义为近距 near 到远距 far 之间的 z 值,Z坐标和X、Y坐标一样。在变换、裁减和透视除法后,Z的范围为-1.0~1.0。DepthRange映射指定Z坐标的变换,这与用于将X和Y映射到窗口坐标的视口变换类似,在透视变换之后,得到新的 z' 值:

其中
是照相机空间的值,它有时候也表示为 w 或者 w'。
结果 z' 是在 -1 到 1 之间归一化之后的值,其中近距 near 平面位于 -1 处,远距 far 平面位于 1 处。在这个范围之外的相应点在视图体之外,不需要进行渲染。
为了实现深度缓冲,在整个屏幕空间上的对当前多边形顶点之间进行插值来计算 z' 的值,通常这些中间数值在深度缓冲区中用定点数格式保存。距离近距 near 平面越近,z' 值越密;距离越远,z' 值越稀。这样距离照相机越近精度越高。near 平面距离照相机越近,则远距离位置的精度越低。near 平面距离照相机太近是在远距离物体产生人为误差的一个常见因素。
3、深度测试
OpenGL中的深度测试是采用深度缓存器算法,消除场景中的不可见面。在默认情况下,深度缓存中深度值的范围在0.0到1.0之间,这个范围值可以通过函数:
glDepthRange (nearNormDepth, farNormalDepth);
将深度值的范围变为nearNormDepth到farNormalDepth之间。这里nearNormDepth和farNormalDepth可以取0.0到1.0范围内的任意值,甚至可以让nearNormDepth > farNormalDepth。这样,通过glDepthRange函数可以在透视投影有限观察空间中的任意区域进行深度测试。
另一个非常有用的函数是:
glClearDepth (maxDepth);
参数maxDepth可以是0.0到1.0范围内的任意值。glClearDepth用maxDepth对深度缓存进行初始化,而默认情况下,深度缓存用1.0进行初始化。由于在进行深度测试中,大于深度缓存初始值的多边形都不会被绘制,因此glClearDepth函数可以用来加速深度测试处理。这里需要注意的是指定了深度缓存的初始化值之后,应调用:
glClear(GL_DEPTH_BUFFER_BIT); 完成深度缓存的初始化。
在深度测试中,默认情况是将需要绘制的新像素的z值与深度缓冲区中对应位置的z值进行比较,如果比深度缓存中的值小,那么用新像素的颜色值更新帧缓存中对应像素的颜色值。这种比较测试的方式可以通过函数:
glDepthFunc(func);
进行修改。其中参数func的值可以为GL_NEVER(没有处理)、GL_ALWAYS(处理所有)、GL_LESS(小于)、GL_LEQUAL(小于等于)、GL_EQUAL(等于)、GL_GEQUAL(大于等于)、GL_GREATER(大于)或GL_NOTEQUAL(不等于),其中默认值是GL_LESS。这些测试可以在各种应用中减少深度缓存处理的的计算。
opengl中有一个非常有用的函数:glReadPixels(),可以读取各种缓冲区(深度、颜色,etc)的数值。要将opengl的绘制场景保存成图片,也需要使用这个函数。
OpenGL中的深度、深度缓存、深度测试及保存成图片的更多相关文章
- 如何把Excel中的单元格等对象保存成图片
对于Excel中的很多对象,比如单元格(Cell),图形(shape),图表(chart)等等,有时需要将它们保存成一张图片.就像截图一样. 最近做一个Excel相关的项目,项目中遇到一个很变态的需求 ...
- BitmapUtil【缩放bitmap以及将bitmap保存成图片到SD卡中】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 用于缩放bitmap以及将bitmap保存成图片到SD卡中 效果图 代码分析 bitmapZoomByHeight(Bitmap s ...
- javacpp-opencv图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体、位置、大小、粗度、翻转、平滑等操作
欢迎大家积极开心的加入讨论群 群号:371249677 (点击这里进群) javaCV图像处理系列: javaCV图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体.位置. ...
- 修改css的(屏蔽)overflow: hidden;实现浏览器能把网页全图保存成图片
摘要: 1.项目需要,需要对网页内容“下载”保存成全图片 2.QQ浏览器等主流浏览器都支持这种下载保存功能 3.项目需要场景:编写好的项目维护文档,放在服务器上.如果是txt不能带图片可视化,如果wo ...
- Java 将 PPT 形状(表格、文本框、心形、图表等)保存成图片
MS PowerPoint中的表格.文本框.心形.图表.图片等均可以称为形状,将这些形状保存成图片,便可分类储存,方便日后查找,再利用. 本文将介绍如何使用 Spire.Presentation fo ...
- c# 将byte数组保存成图片
将byte数组保存成图片: 方式一:System.IO.File.WriteAllBytes(@"c:\test.jpg", bytes); 方式二:MemoryStream ms ...
- 如何实现批量截取整个网页完整长截图,批量将网页保存成图片web2pic/webshot/screencapture/html2picture
如何实现批量截取整个网页完整长截图,批量将网页保存成图片web2pic/webshot/screencapture [困扰?疑问?]: 您是否正受到:如何将网页保存为图片的困扰?网页很高很长截图截不全 ...
- Unity3D中调用外接摄像头,并保存为图片文件
http://bbs.9ria.com/thread-170539-1-1.html 项目要求调用摄像头,并且把图像保存下来,上传到服务器. 这里有几个难点,调用摄像头是很简单的,unity已经提供好 ...
- js中保存成图片并下载
1.保存canvas中绘制的内容为图片 HTML代码: <canvas id="canvas" width="400" height="400& ...
随机推荐
- weka 集成学习
import java.io.*;import weka.classifiers.*;import weka.classifiers.meta.Vote;import weka.core.Instan ...
- 【转】解决Cannot change version of project facet Dynamic web module to 2.5
http://blog.csdn.net/steveguoshao/article/details/38414145 我们用Eclipse创建Maven结构的web项目的时候选择了Artifact I ...
- jQuery获取Select选中的Text和Value,根据Value值动态添加属性
语法解释:1. $("#select_id").change(function(){//code...}); //为Select添加事件,当选择其中一项时触发2. var chec ...
- int 0x13中断的參数传递
int 0x13中断向量所指向的中断服务程序实质上就是磁盘服务程序. 用途:将指定扇区的代码载入到内存的指定位置. 因此,在使用int 0x13中断时要将參数传递给服务程序: 比如:将指定扇区和载入的 ...
- Windows Mobile 6.0 SDK和中文模拟器下载
[转] Windows Mobile 6.0 SDK和中文模拟器下载 Windows Mobile 6.5 模拟器 2010年12月06日 星期一 07:48 转载自 zhangyanle86 终于编 ...
- 5 Things They Never Tell You About Making iPhone Apps
http://blog.teamtreehouse.com/5-things-they-never-tell-you-about-making-iphone-apps So, you've decid ...
- Android和Java的轻巧Wire协议缓冲器
Wire协议缓冲器 一个人必须有一个代码! -奥马尔小 由于我们的团队和项目增长,数据的种类和数量也随之增加. 成功将您简单的数据模型转换为复杂的! 无论您的应用程序将数据存储到磁盘或网络传送信号,该 ...
- 转:通过API获取和创建 Oracle GL Account Code Combination ID’s (CCID’s)的几种方法汇总
1] FND_FLEX_EXT.GET_COMBINATION_ID: This API Finds combination_id for given set of key flexfield seg ...
- 让你一分钟认识电子身份验证系统EID
什么是EID eID是英文"Electronic Identity"的英文简称,中文名为"电子身份证"或"网络电子身份证",由公安部第三研究 ...
- Extjs combobox设置默认值
转载:http://www.54mask.com/extjs-combobox-default-value.html 相信很多人都遇到了在ExtJS框架中设置combo组件默认值的需求,ExtJS框架 ...