OpenGL(二十一) glPolygonOffset设置深度偏移解决z-fighting闪烁问题
开启深度测试后OpenGL就不会再去绘制模型被遮挡的部分,这样实现的显示画面更为真实,但是由于深度缓冲区精度的限制,对于深度相差非常小的情况(例如在同一平面上进行两次绘制),OpenGL就不能正确判定两者的深度值,会导致深度测试的结果不可预测,显示出来的现象时交错闪烁的前后两个画面,这种情况称为z-fighting。
在旋转(深度值发生变化)的情况下表现的更为明显,如下图所示:
应对这种情况的办法是使用glPolygonOffset给当前绘制对象设置一个深度偏移,函数原型是:
void APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
设置后深度偏移量的计算公式是Offset=DZ*factor+r*units,DZ和r是当前系统跟深度测试相关的系数,其中r是两个深度缓冲区间的最小间隔,一般情况下,factor和units都设置为1.0(或-1.0)个单位,基本上是一个比较稳妥的设定。
设置正数表示当前的深度更深一些,显示的时候会被前景覆盖,设为负数表示深度较浅,会被绘制到屏幕上去。
使用glPolygonOffset之前需要用glEnable(GL_POLYGON_OFFSET_FILL)开启深度偏移功能。
#include"freeglut.h"
#include<math.h>
GLfloat angle=0.0f;
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glDisable(GL_POLYGON_OFFSET_FILL);
glRotatef(angle,0,1,0);
glColor3f(1,0,0);
glRectf(-1.5,-1.5,0.5,0.5);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0,-1.0);
glColor3f(0,1,0);
glRectf(-0.5,-0.5,1.5,1.5);
glPolygonOffset(-2.0f,-2.0f);
glColor3f(0,0,1);
glLineWidth(3);
glBegin(GL_TRIANGLES);
glVertex3f(-1.5,-1.5,0);
glVertex3f(-1.5,-0.5,0);
glVertex3f(0.5,0.5,0);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void Init()
{
glEnable(GL_DEPTH_TEST);
glClearColor(1,1,1,1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70,1,1,20);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,3,0,0,0,0,1,0);
}
void SpecialKey(GLint key,GLint x,GLint y)
{
if(key==GLUT_KEY_UP||key==GLUT_KEY_LEFT)
{
angle-=0.8f;
}
if(key==GLUT_KEY_DOWN||key==GLUT_KEY_RIGHT)
{
angle+=0.8f;
}
myDisplay();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv); //初始化GLUT
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(500, 200);
glutInitWindowSize(400, 400);
glutCreateWindow("OpenGL");
Init();
glutDisplayFunc(&myDisplay); //回调函数
glutSpecialFunc(&SpecialKey);
glutMainLoop(); //持续显示,当窗口改变会重新绘制图形
return 0;
}
控制键盘的上下方向键可以控制模型绕y轴旋转。设置之后在模型旋转的时候没有了闪烁的z-fighting现象,并且不管从正面还是反面看,模型相对的深度值都是固定的,正反面绘制的都是设定的深度值较小的那面模型:
OpenGL(二十一) glPolygonOffset设置深度偏移解决z-fighting闪烁问题的更多相关文章
- Nginx详解二十一:Nginx深度学习篇之配置苹果要求的openssl后台HTTPS服务
配置苹果要求的证书: 1.服务器所有的连接使用TLS1.2以上的版本(openssl 1.0.2) 2.HTTPS证书必须使用SHA256以上哈希算法签名 3.HTTPS证书必须使用RSA2048位或 ...
- 2DToolkit官方文档中文版打地鼠教程(二):设置摄像机
这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...
- Citrix 服务器虚拟化之二十一 桌面虚拟化之部署Provisioning Services
Citrix 服务器虚拟化之二十一 桌面虚拟化之部署Provisioning Services Provisioning Services 是Citrix 出品的一系列虚拟化产品中最核心的一个组件, ...
- 中介者模式 调停者 Mediator 行为型 设计模式(二十一)
中介者模式(Mediator) 调度.调停 意图 用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散 而且可以独立地改变它们之间的交互. ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(二十一):在小程序中使用 WebSocket (.NET Core)
本文将介绍如何在 .NET Core 环境下,借助 SignalR 在小程序内使用 WebSocket.关于 WebSocket 和 SignalR 的基础理论知识不在这里展开,已经有足够的参考资料, ...
- 二十一世纪计算 | John Hopcroft:AI革命
编者按:信息革命的浪潮浩浩汤汤,越来越多的人将注意力转向人工智能,想探索它对人类生产生活所产生的可能影响.人工智能的下一步发展将主要来自深度学习,在这个领域中,更多令人兴奋的话题在等待我们探讨:神经网 ...
- 无废话ExtJs 入门教程二十一[继承:Extend]
无废话ExtJs 入门教程二十一[继承:Extend] extjs技术交流,欢迎加群(201926085) 在开发中,我们在使用视图组件时,经常要设置宽度,高度,标题等属性.而这些属性可以通过“继承” ...
- Vs2015 win10虚拟机启动问题:无法设置UDP端口 解决方法 合集(转载)
刚装的vs2015 社区版 出现这个问题,wp8.1和win10m模拟器都无法启动,找了好久找到的解决方案,放这儿供大家参考,免得大家像我一样走弯路: Windows Phone emulator n ...
- WCF技术剖析之二十一:WCF基本异常处理模式[下篇]
原文:WCF技术剖析之二十一:WCF基本异常处理模式[下篇] 从FaultContractAttribute的定义我们可以看出,该特性可以在同一个目标对象上面多次应用(AllowMultiple = ...
随机推荐
- POJ 题目2506Tiling(大数)
Tiling Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8128 Accepted: 3941 Descriptio ...
- 《SPA设计与架构》之客户端路由
原文 简书原文:https://www.jianshu.com/p/4d83475f71da 大纲 1.传统路由 2.SPA导航 3.客户端路由器的工作机制 1.传统路由 在传统Web应用程序中,导航 ...
- js课程 2-6 js如何进行类型转换及js运算符有哪些
js课程 2-6 js如何进行类型转换及js运算符有哪些 一.总结 一句话总结: 1.所有类型->布尔类型(为假的情况)有哪些(6种)? 1)字符串('')2)整型(0)3)浮点型(0.0)4) ...
- Momentum(动量/冲量)的理解及应用
1. 基本概念(Momentum vs SGD) Momentum 用于加速 SGD(随机梯度下降)在某一方向上的搜索以及抑制震荡的发生. GD(gradient descent) θt=θt−1−η ...
- 30行js rem弹性布局适配所有分辨率
<script> /* # 按照宽高比例设定html字体, width=device-width initial-scale=1版 # @pargam win 窗口window对象 # @ ...
- [Angular] Reactive Form -- FormControl & formControlName, FormGroup, formGroup & formGroupName
First time dealing with Reactive form might be a little bit hard to understand. I have used Angular- ...
- Using Eredis, Redis With Erlang
http://no-fucking-idea.com/blog/2012/03/23/using-eredis-in-erlang/ Using Eredis, Redis With Erlang M ...
- Erlang Process input queue
http://www.cnblogs.com/me-sa/archive/2011/11/05/erlang0012.html Erlang进程有自己的消息队列来保存接收到的消息,新接收到的消息放在队 ...
- 【t051】图书管理
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 图书管理是一件十分繁杂的工作,在一个图书馆中每天都会有许多新书加入.为了更方便的管理图书(以便于帮助想 ...
- 【codeforces 782A】Andryusha and Socks
[题目链接]:http://codeforces.com/contest/782/problem/A [题意] 如果手套没有成一双,那么其中的一只就会被放在桌子上; 问你桌子上手套的只数最多的时候有几 ...