OpenGL中关于模板缓冲区的详细解释

opengl使用帧缓冲区及模板缓存记录 opengl使用帧缓冲区及模板缓存记录 这篇文章用于记录学习帧缓存区过程中的一些知识点,由于大部分文章所涉及的知识点都是相似的,所以只能自己在摸索的过程中记录一二,目前只是初学,可能还有很多地方理解出现偏差,请各位大佬批评指正。 创建帧缓存区 glGenBuffers(1,&fbo); 创建帧缓存区的步骤比较简单,只需在创建好后绑定到合适的绑定点上。 接下来需要创建深度、模板和颜色缓冲区,用于添加到帧缓存区 glGenRenderbuffers(1,&depthbuffer);//创建 阅读详情

模板缓冲区的概念,至今依然不是特别理解,这篇博客写的很好,相信对大家的理解也有帮助。

模板缓存是深度缓存的扩充,当你需要控制哪一个像素需要被渲染,哪一个像素需要被忽略时,模板缓存能够为你提供更多的方法。和深度缓存一样,模板缓存存储了所有像素的模板值,但是这次你必须手动控制这些值如何改变。记住,如果一个像素深度测试失败了的话,模板测试将不会再决定该像素是否绘制,而像素会反过来影响模板缓存中的值。

为了让大家对模板缓存有一个直观的认识,让我们来分析一下下面这个例子:

模板缓存实例

如上图所示:模板缓存首先被清0,我们的立方体将正常显示,然后我们将模板缓存中的一个矩形区域设置为1,我们的立方体在绘制时,我们将只绘制模板值为1的像素区域,从而达到控制像素绘制与否的目的。现在你对模板缓存的作用有了一个初步了解了,让我们来看看OpenGL中是如何使用它的:

和深度缓存一样,首先你要启动模板测试来让模板缓存生效,

启动模板测试

设置模板值

然后需要设置缓存中各个像素的模板值, 我们在确定模板的形状后,我们通常只需要调用一次绘制命令就可以达到利用模板裁剪画面的效果,如果你想像上面的例子那样创建一个矩形的裁剪区域,只需要绘制一个2D的矩形区域就行了。只不过在你绘制之前需要使用以下几个API来控制一下模板缓存的值:

首先是glStencilFunc,这个api是用来模板测试使用的比较函数以及参数的,参数如下:

func:比较函数

ref: 比较函数用来比较的参数值。

mask: 掩码,如果模板缓存包含了s个位平面,那么mask参数中较低的s个位数据将分别于模板缓存中的值,以及ref值进行位与操作,然后再进行具体的比较。

第一个参数中的比较函数可以是以下任意一种:

GL_NEVER:无论模板值为何值,都不能通过模板测试

GL_LESS:测试模板值是否小于ref值

GL_LEQUAL:测试模板值是否小于等于ref值

GL_GREATER:测试模板值是否大于ref值

GL_GEQUAL:测试模板值是否大于等于ref值

GL_EQUAL:测试模板值是否等于ref值

GL_NOTEQUAL:测试模板值是否不等于ref值

GL_ALWAYS:无论模板值为何值,总是能通过模板测试。

例如:如果你不想让小于2的模板值通过模板测试,你只需要这样调用:

glStencilFunc调用示例

然后是glStencilOp,这个api是用来指定深度测试以及模板测试以后对模板值的操作,参数如下:

sfail: 模板测试失败后执行的操作

dpfail: 模板测试通过但深度测试不通过时候执行的操作。

dppass: 模板测试和深度测试都通过后,或者深度测试未开启时执行的操作。

以上三个参数的值可以是以下任意一种:

GL_KEEP: 保持当前值

GL_ZERO: 将模板值清0

GL_REPLACE: 模板值将会被替换为glStencilFunc中的ref参数值。

GL_INCR: 如果模板值小于最大值,模板值将会+1

GL_INCR_WRAP: 和GL_INCR一样,只是遇到最大值时,模板值会清0。

GL_DECR:如果模板值大于0,模板值将会-1。

GL_DECR_WRAP: 和GL_DECR一样,只是当模板值减到0时,会变为最大值。

GL_INVERT: 将模板值按位取反。

最后,glStencilMask可以为模板缓存设置掩码,由于模板缓存中每个模板值是一个无符号的整形数,因此我们的掩码也是一个0-0xFFFFFFFF范围内的数,每个模板值都会与掩码做与运算后再使用,默认掩码为0xFFFFFFFF。

现在回到我们的例子,我们要把一个矩形区域的模板值设置为1,我们需要进行如下操作:

模板缓存使用示例

这里我们可以看到,我们通过glStencilFunc函数让任意模板值都能通过模板测试,这样如果深度测试也通过的话就会根据glStencilOp的第三个参数设置的GL_REPLACE将模板值都替换为ref参数值1,从而达到了将所有模板值设置为1的目的。而图中的矩形区域并不需要真正的绘制,它只需要用来指定哪些像素的模板值生效,这样就不需要我们去逐像素的去设置模板缓存值了。

屏蔽颜色和深度缓存

glColorMask函数允许你指定哪些数据输入颜色缓存,4个参数分别对应RGBA值,这里我们将4个参数都置为GL_FALSE,意味着所有颜色数据都不会输入到颜色缓存中。而深度缓存需要另外调用glDepthMask并传入GL_FALSE参数来屏蔽深度值。这样我们矩形区域外的所有像素的颜色和深度都被屏蔽了,所以我们的绘制就不会影响到这些像素。这样操作操作比调用glClear来清除颜色和深度缓存要干净得多。

绘制中使用模板值

在了解了如何设置模板缓存后,使用模板缓存变得非常简单。你只需要通过一个测试函数来决定哪些像素需要绘制,然后将之前禁用的深度和颜色重新启用就可以了。

模板测试函数

如果你调用这个方法来设置了测试函数,只有模板缓存中值为1的像素能通过这个测试。一个像素只有在通过深度测试和模板测试后才能绘制,所以没有必要去设置glStencilOp。在例子中,只有那个矩形区域中的模板值被设置为1,所以只有在这个区域中的像素会被绘制。

设置掩码

一个小细节需要注意的是,我们在绘制我们的立方体时,仍会影响到模板缓存中的值,为了避免这种影响,我们将模板缓存的掩码设置为0。这样一来,我们以后的任何写入操作都会被屏蔽掉。

镜面反射的例子

现在我们在我们绘制的立方体下方加入一个反射镜面,首先在立方体的顶点数组中添加如下数据:

顶点数组

然后,在绘制立方体过后单独绘制这个镜面:

绘制镜面

现在我们创建一个反射效果,只需要将原有的立方体向下平移并相对Z轴翻转就行了:

创建反射

这里将反射面的颜色设置为黑色,这样就不会有纹理图片能够通过这个反射面。绘制效果如下:

平移旋转后的立方体

有两个值得一提的地方:

1:下方的立方体被反射面遮住是因为未能通过上一章我们提到的深度测试。

2:超出反射面范围的立方体依然能够被看见

第一个问题很好解决,只需要临时屏蔽掉向深度缓存写入值就可以了:

屏蔽深度缓存

第二个问题通过控制深度缓存似乎不好解决,我们需要屏蔽掉反射面范围之外的那些像素,所以我们的模板缓存就可以一展身手了!

我们可以将整个绘制过程细分为以下几个阶段,以便我们分析每个阶段应该做什么:

1.绘制上方的立方体

2.打开模板测试,再将我们需要绘制区域的模板值写成1。

3.绘制反射面

4.设置模板函数,让模板值为1的像素通过模板测试。

5.绘制一个颠倒的立方体。

6.关闭模板测试。

绘制代码如下:

镜面反射绘制代码

最后我们只需要将反射面上的图像灰化,这需要在我们的片段着色器中实现,overrideColor是用来灰化图案的颜色:

灰化反射图案

然后在绘制我们的反射立方体时传入一个灰度值,uniColor是glGetUniformLocation的返回值:

传入灰度值

大功告成!我们只用最基本的OpenGL的API就可以实现一个看似很复杂的效果,很神奇吧!

最终结果

作者:猿基地 链接:http://www.jianshu.com/p/bed926e53517 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

使用OpenGL实现模板缓冲区和剪切平面 综上所述,我们可以通过使用模板缓冲区和剪切平面来实现更高级的图形处理和控制。在上述代码示例中,我们展示了如何初始化OpenGL环境、清除模板缓冲区、设置模板缓冲区的值以及使用剪切平面来裁剪场景中的图形。在OpenGL中,模板缓冲区和剪切平面是两个重要的功能,它们能够在渲染过程中提供更高级的图形处理和控制。本文将介绍如何在OpenGL中使用模板缓冲区和剪切平面,并提供相应的代码示例。在渲染场景之前,我们需要启用剪切平面,并设置剪切平面的参数。在需要使用模板缓冲区的地方,我们可以设置模板缓冲区的值。 阅读详情

相关推荐

OpenGL使用模板缓冲区和剪切平面

OpenGL使用模板缓冲区和剪切平面先上图,再解答。完整主要的源代码源代码剖析 先上图,再解答。 完整主要的源代码 #include <stdio.h> #include "GL/glus.h" struct LightProperties { GLfloat direction[3]; GLfloat ambientColor[4]; GLfloat diffuseColor[4]; GLfloat specularColor[4]; }; struct M

希望我的博客,能帮上你解决学习中工作中所遇到的问题 553

OpenGL模板缓冲区---StencilBuffer

前言

Frank的专栏 2万+

在Windows上安装Fortran编程环境「0 错误」|编程一对一教学文章

通过以上步骤,你已经成功在 Windows 系统上配置了 Fortran 编程环境。现在,你可以开始 Fortran 语言的学习和开发工作了。记得定期检查更新你的编译器和编辑器,以获得最佳的支持和新功能。

AI悦创·编程私教1v1 1673

入门图形学:模板缓冲区/模板测试

最近因为家庭原因回老家了,在家里办了两三周杂七杂八的事情后,考虑是否继续去北上广深漂着(不得不说码农就是这个命啊)。家人和朋友让我在老家先呆着再说,于是准备了尝试找下工作。 前两天碰到面试官问了一个问题,就是关于模板缓冲区的原理,我只说了个大概而在细节上就卡壳了,因为我自己项目中实在很少用到这个,所以基本都搞忘了,今天晚上有点时间就回顾一下。 首先贴上这个以...

羊羊的博客 2828

手把手教你用CH582的USB0/1双接口玩转CherryUSB协议栈(附完整代码)

本文深入解析CH582双USB接口硬件架构,详细讲解如何通过CherryUSB协议栈实现双接口协同工作,包括中断处理设计、端点资源分配和复合设备描述符配置。提供HID+CDC复合设备实战案例,并分享高级调试技巧与性能优化方法,帮助开发者充分利用CH582的USB0/1双接口潜力。

weixin_42525637的博客 264

信捷CODESYS平台伺服电机转矩控制模式应用与切换

信捷CODESYS二次开发软件:XS Studio 在运动控制中的转矩控制案例

weixin_64614866的博客 1万+

十二、D3D12学习笔记——模板缓冲

我们认识了一下模板这个面具,你可以理解为他试图遮蔽什么,又或者是试图体现什么,重要的主要是分析首先逻辑,然后才是参数设置,剩下的就交给硬件自己实现了。

weixin_44212242的博客 803

ANSYS APDL 异类单元连接实战:MPC方法在壳-实体装配中的应用

本文详细介绍了在ANSYS APDL中使用MPC方法实现壳单元与实体单元高效连接的技术要点。通过分析工程仿真中的常见需求,阐述了MPC方法在解决异类单元连接问题上的优势,包括网格独立性、自由度耦合和载荷传递等特性,并提供了具体的APDL命令流操作示例和实用经验技巧。

weixin_33391446的博客 178

对OpenGL中模板缓冲区解释

前段时间转载了一篇关于OpenGL的博客,但是并没有对里面的内容理解的很透彻,今天通过实例重新讲解一下。关于模板 缓冲区的基础知识参考上篇博客http://blog.youkuaiyun.com/yangyong0717/article/details/78313725。 对于模板缓冲区的值是如何设置的是一个关键问题,主要是借助于glStencilFuncSeparate()和glStencilOpSep

yangyongUestc的博客 667

CKA-题库-简洁参考答案-反复练习20遍-必过!!!

新版CKA考试已于2020年9月1日正式上线! 考试模式:线上考试 考试时间:2小时 认证有效期:3年 软件版本:Kubernetes v1.19 重考政策:可接受1次重考 经验水平:中級 题目数量:17题 题库量小:随机的题目重复率极高 考试时可打开两个浏览器Tab,一个是考试窗口,一个用来查阅官方文档](https://kubernetes.io/docs/) 01 Task - 英文 Create a new ClusterRole named deployment-clusterrole tha.

随笔记录-分享&记忆 7318

【蓝牙协议栈】【BLE】详解蓝牙BLE连接建立过程

advertiser。发出广播的设备observer或者scanner。可以扫描广播的设备initiator。能发起连接的设备master或者central。连接成功后的主设备,即主动发起packet的设备slave或者peripheral。连接成功后的从设备,即被动回传packet的设备图11通过时间把observer,initiator和central串起来了,其实这三个角色是相互独立的,也就是说一个设备可以只支持observer角色,而不支持initiator和central角色。

风云说通信 2521

OpenGL: 模板缓冲区的理解

引用:http://blog.163.com/danshiming@126/blog/static/109412748201632895137788/ 这几天看《OPenGL 编程指南》中的模板缓冲区,一头雾水,根本就没怎么理解,然后网上找了一些例子,先将自己理解的记录如下: 模板缓冲区(Stencil Buffer):与颜色缓冲区和深度缓冲区类似,模板缓冲区可以为屏幕上的每个像素点保

lizhen37031的博客 1219

大模型角色提示词写得再严密,也能被绕过?我用攻击者思维把自己吓了一跳!

很多人以为提示词是“只要写清楚了,模型就能理解”,但实际上——模型并不具备严格的规则意识,它只是在预测下一句话。所以我们必须从“攻防”角度出发,设计更强的防护机制。我这次就是亲身踩坑,用红队思维模拟攻击,才意识到原来提示词注入这么容易中招。你如果也在做 AI 应用、角色系统、提示词驱动的功能,建议你也用类似方式测试一下,不然被绕了都不知道。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1026

OpenGL缓冲区总结

帧缓冲区   几乎每个图形程序的重要目标之一都是在屏幕上绘制图形。屏幕是由一个矩形像素数组组成的,每个像素都可以在图像的某一个点上显示一个某种颜色的微小方块。在光栅化阶段(包括纹理和雾)之后,数据就不再是像素,而是片段。每个片段都具有与像素对应的坐标数据以及颜色值和深度值。   如果顺利通过了这些测试和操作,片段值便可以转换为像素。 如果顺利通过了这些测试和操作,片段值便可以转换为像素。为了绘

愿世界和平的IT劝退师 2630

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

WebGL 模板缓冲区

本文非原创,转载自 http://www.cnblogs.com/aokman/archive/2010/12/13/1904723.html 与颜色缓冲区和深度缓冲区类似,模板缓冲区可以为屏幕上的每个像素点保存一个无符号整数值。这个值的具体意义视程序的具体应用而定。在渲染的过程中,可以用这个值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新相应的像素点的颜色值。这个比较的过程被称

程序员小站 3336

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

OpenGL模板缓冲区与模板测试

原文地址:http://www.blogjava.net/qileilove/archive/2014/01/23/409269.html 帧缓冲区有许多缓冲区构成,这些缓冲区大致分为:     颜色缓冲区:用于绘图的缓冲区,它包含了颜色索引或者RGBA颜色数据。      深度缓冲区:存储每个像素的深度值,当启动深度测试时,片段像素深度值和深度缓冲区深度值进行比较,决定片段哪些像素点数据可

蚂蚁的坚持 478

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

OpenGL学习二十九:模板缓冲区与模板测试

帧缓冲区有许多缓冲区构成,这些缓冲区大致分为:颜色缓冲区:用于绘图的缓冲区,它包含了颜色索引或者RGBA颜色数据。深度缓冲区:存储每个像素的深度值,当启动深度测试时,片段像素深度值和深度缓冲区深度值进行比较,决定片段哪些像素点数据可以替换到颜色缓冲区中。模板缓冲区:就像使用纸板和喷漆一样精确的混图一样,当启动模板测试时,通过模板测试的片段像素点会被替换到颜色缓冲区中,从而显示出来,未通过的则不...

Star 159

OpenGL: 模板缓冲区

相信大家有些人对OpenGL的模板缓冲区不是很理解,包括我最开始也是,OpenGL的模板缓冲区其实就是采用过滤的技术来控制那些颜色可以绘制,那些不能进行绘制。这里的过滤技术也就是我们的一个控制方法,主要体现在如下两个函数glStencilFunc(GLenum func,GLint ref,GLuint mask)和glStencilOp(GLenum fail,GLenum zfail, G

能搬的绝不自己写 819

计算机图形学理论(4):缓冲区

缓冲区是保存某些数据的临时存储空间。为什么我们需要缓冲区?原因很简单,当数据量很大时,因为计算机无法同时处理整个数据,因此在处理当前数据集时需要额外的空间来存储其余数据。在计算机图形学中,缓冲区有多种定义方式。分辨率:宽度(n) x 高度(m)深度(或精度):k位数/像素例如,如果我们想要每个像素使用 RGB 通道,则一个通道需要 8 位,总共 24 位(3 x 8 位)。

1774

【OpenGL】glClear函数的使用

函数原型:       void glClear(GLbitfield mask); 参数说明:       GLbitfield:可以使用 | 运算符组合不同的缓冲标志位,表明需要清除的缓冲,例如glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)表示要清除颜色缓冲以及深度缓冲,可以使用以下标志位       GL_COLO

四月晴 1万+

OpenGL函数思考-glClear

函数原型:       void glClear(GLbitfield mask); 参数说明:       GLbitfield:可以使用 | 运算符组合不同的缓冲标志位,表明需要清除的缓冲,例如glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)表示要清除颜色缓冲以及深度缓冲,可以使用以下标志位       GL_COLO

... 890

初学opengl

1、void  glclearColor(GLclampf )

u010626702的专栏 639

用OpenSceneGraph实现的NeHe OpenGL教程 - 第二十六课

简介 这节课主要介绍了如何使用OpenGL中的模板缓冲区和裁剪平面来

Frank的专栏 2384
上一篇: 20分钟让你了解OpenGL——OpenGL全流程详细解读
下一篇: [osgearth]OE地形平整代码解读
pplander
博客等级 码龄20年 111粉丝 12原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值