OpenGL ES 学习教程(十三) Stencil_TEST(模板缓冲测试)

模板缓冲测试,是指 将模版缓冲区中的值 与 一个参考值 进行比较,根据比较的结果,来对缓冲区中的值进行修改。进而决定该片段是否有效。

在应用中的体现就比如:Unity中的Mask 。

大致的工作流程:

1、第一次Draw的时候,将所有的片段都设置为不通过模版测试。然后修改模版缓冲区的值,比如+1.

2、第二次Draw的时候,给定一个值 与 模版缓冲区中的值进行比较,比如用 1 与模版缓冲区中的值进行比较 。 因为第一步中,已经+1,所以模版缓冲区中值已经是1,然后用相等 作为条件判定 模版测试通过。那么这个片段就可以绘制。

3、这样做的最终效果是,只有第一次绘制的区域,第二次绘制才可以显示。就如同Unity中的Mask,用一张图,Mask掉第二张图。

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

在不使用模版测试的情况下,画了两个三角形。

首先 就如同深度测试一样,也要申请模版缓冲区。

bool initDevice()
{

	const EGLint attribs[] =
	{
		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
		EGL_BLUE_SIZE, 8,
		EGL_GREEN_SIZE, 8,
		EGL_RED_SIZE, 8,
		EGL_ALPHA_SIZE,8,
		EGL_DEPTH_SIZE, 24, //请求深度缓冲区
		EGL_STENCIL_SIZE, 8,//请求模版缓冲区
		EGL_NONE
	};
	EGLint 	format(0);
	EGLint	numConfigs(0);
	EGLint  major;
	EGLint  minor;

	//! 1
	m_EGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);

	......
}

然后要开启模版测试

//重写初始化函数;
virtual void onInit()
{
	Light3dWinAPP::onInit();

	m_program.Initialize();

	glEnable(GL_STENCIL_TEST);//开启模版测试

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS); //基准设置为 1.0,那么GL_LESS 则深度小余 1.0 的通过测试
}

然后要设置默认模版值

//重写Render;
virtual void render()
{
	glClearColor(0, 0, 0, 1.0);
	glClearDepthf(1.0f);//深度测试的基准,注意1.0代表从近裁剪面到远裁剪面 这一段范围!!并不是指Z轴的1个单位
	glClearStencil(0);

	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT |GL_STENCIL_BUFFER_BIT);
	

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

然后在第一次绘制的时候,指定所有的都不通过模版测试,并且模版值 +1 。

m_program.begin();
{
	glStencilFunc(GL_NEVER, 0x0, 0xFF);//第一次绘制,通通不通过模版测试。
	glStencilOp(GL_INCR, GL_INCR, GL_INCR);//第一次绘制的像素的模版值 0+1 = 1

然后在第二次绘制的时候,比较深度缓冲区中的值,值为 1 的通过测试。

{
	glStencilFunc(GL_EQUAL, 0x1, 0xFF);//等于1 通过测试 ,就是上次绘制的图 的范围 才通过测试。
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);//没有通过测试的,保留原来的,也就是保留上一次的值。

	glm::vec4 pos[] =
	{
		glm::vec4(0.0f, -2.0f, 1.5f, 1.0f),
		glm::vec4(4.0f, -2.0f, 1.5f, 1.0f),
		glm::vec4(2.0f, 2.0f, 1.5f, 1.0f),
	};

	glm::vec4 color[] =
	{
		glm::vec4(1, 1, 0, 1),
		glm::vec4(1, 1, 0, 1),
		glm::vec4(1, 1, 0, 1),
	};

	glUniformMatrix4fv(m_program.m_mvp, 1, false, &proj[0][0]);

	glVertexAttribPointer(m_program.m_position, 4, GL_FLOAT, false, sizeof(glm::vec4), pos);
	glVertexAttribPointer(m_program.m_color, 4, GL_FLOAT, false, sizeof(glm::vec4), color);

	glDrawArrays(GL_TRIANGLES, 0, 3);
}

这样我们得到的效果就是Mask的效果,只有第一次绘制的范围里,才能显示第二次绘制。

如果将比较修改为 不等于 1 的通过测试,那么效果就是第一次绘制的区域被抹除掉。

{
	glStencilFunc(GL_EQUAL, 0x1, 0xFF);//等于1 通过测试 ,就是上次绘制的图 的范围 才通过测试。
	glStencilFunc(GL_NOTEQUAL, 0x1, 0xFF);//不等于1 通过测试 就是除了上次绘制的图案之外的像素通过测试,所以上次绘制的像素之外的像素才可以进行第二幅图的绘制。
	//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);//没有通过测试的,保留原来的,也就是保留上一次的值。

	glm::vec4 pos[] =
	{
		glm::vec4(0.0f, -2.0f, 1.5f, 1.0f),
		glm::vec4(4.0f, -2.0f, 1.5f, 1.0f),
		glm::vec4(2.0f, 2.0f, 1.5f, 1.0f),
	};

	glm::vec4 color[] =
	{
		glm::vec4(1, 1, 0, 1),
		glm::vec4(1, 1, 0, 1),
		glm::vec4(1, 1, 0, 1),
	};

	glUniformMatrix4fv(m_program.m_mvp, 1, false, &proj[0][0]);

	glVertexAttribPointer(m_program.m_position, 4, GL_FLOAT, false, sizeof(glm::vec4), pos);
	glVertexAttribPointer(m_program.m_color, 4, GL_FLOAT, false, sizeof(glm::vec4), color);

	glDrawArrays(GL_TRIANGLES, 0, 3);
}

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

示例项目下载:

链接: http://pan.baidu.com/s/1mhMlVAg 密码: 77cg
时间: 2024-11-03 00:44:16

OpenGL ES 学习教程(十三) Stencil_TEST(模板缓冲测试)的相关文章

Android OpenGL ES 开发教程 从入门到精通

From:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ES 简明开发教程一:概述 Android OpenGL ES 简明开发教程二:构造OpenGL ES View Android OpenGL ES 简明开发教程三:3D绘图基本概念 Android OpenGL ES 简明开发教程四:3D 坐标变换 Android OpenGL ES 简明开发教程五

[转]Android OpenGL ES 开发教程 从入门到精通

本文转自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ES 简明开发教程一:概述 Android OpenGL ES 简明开发教程二:构造OpenGL ES View Android OpenGL ES 简明开发教程三:3D绘图基本概念 Android OpenGL ES 简明开发教程四:3D 坐标变换 Android OpenGL ES 简明开发教程五

iOS开发-OpenGL ES入门教程1

http://www.jianshu.com/p/750fde1d8b6a 这里是一篇新手教程,环境是Xcode7+OpenGL ES 2.0,目标写一个OpenGL ES的hello world.OpenGL ES系列教程在这里.OpenGL ES系列教程的代码地址 你的star和fork是我的源动力,你的意见能让我走得更远. 核心思路 通过GLKit,尽量简单地实现把一张图片绘制到屏幕. 效果展示 具体细节 1.新建OpenGL ES上下文 - (void)setupConfig { //新

OpenGL ES学习资料总结

从今年春节后开始学习OpenGL ES,发现网上资料很有限,而且良莠不齐,所以整理了一下我学习时用到的资料和一些心得. 1. OpenGL ES1.x参考资料 把NEHE的教程移植到了Android上,当然用的是ES1 http://insanitydesign.com/wp/projects/nehe-android-ports/ 2. OpenGL ES2.x参考资料 有很多Android上ES2应用的文章 http://tangzm.com/blog/?p=20 特别好的书,网上有英文版p

Android OpenGL ES绘图教程之二 : 定义形状

在OpenGL ES view中可以定义要绘制图形的形状,是你创建高端图形杰作的第一步.在不知道一些基础的情况下来绘制会有点棘手,比如OpenGL ES是如何定义图形对象的. 本教程解释了OpenGL ES坐标系统与Android设备屏幕的关系,如果定义基础的形状,比如三角形和四边形. 1. 定义一个三角形 OpenGL ES允许你在三维坐标系统中定义绘制对象,所以在绘制三角形之前,必须定义它的坐标.在OpenGL里面,定义坐标的典型方式是定义一个浮点型的顶点坐标数组,为了最大化效率,将这些坐标

Android OpenGL ES绘图教程之一 : 构建OpenGL ES 环境

为了在Android应用中使用OpenGL ES绘图,首先必须要创建一个view容器.一个最简单的方法是实现GLSurfaceView和GLSurfaceView.Renderer.GLSurfaceView一个view容器,用来显示OpenGL绘制的图形,GLSurfaceView.Renderer用来控制GLSurfaceView里面图形的绘制.更多的信息,请参考 OpenGL ES 开发向导. GLSurfaceView是将OpenGL ES图形用到应用的一种方式,对于全屏或者接近全屏的图

OpenGL ES 简单教程

什么是OpenGL ES? OpenGL ES (为OpenGL for Embedded System的缩写) 为适用于嵌入式系统的一个免费二维和三维图形库. 为桌面版本号OpenGL 的一个子集. OpenGL ES 定义了一个在移动平台上可以支持OpenGL最基本功能的精简标准.以适应如手机.PDA或其他消费者移动终端的显示系统. Khronos Group 定义和管理了OpenGL ES标准. OpenGL 与 OpenGL ES的关系OpenGL ES 是基于桌面版本号OpenGL 的

OpenGL ES学习笔记(二)——平滑着色、自适应宽高及三维图像生成

首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <Android学习笔记--OpenGL ES的基本用法.绘制流程与着色器编译>中实现了OpenGL ES的Android版HelloWorld,并且阐明了OpenGL ES的绘制流程,以及编译着色器的流程及注意事项.本文将从现实世界中图形显示的角度,说明OpenGL ES如何使得图像在移动设备上显示的更加真实.首先,物体有各种颜色

Android OpenGL ES绘图教程之六 :响应触摸事件

使对象根据预设的程序进行运动,比如旋转三角形,可以吸引人的注意力.但是如果你想让用户同你的OpenGL ES图形进行交互会怎么样呢?使你的OpenGL ES应用程序触摸互动的关键是要扩展GLSurfaceView,复写onTouchEvent()方法,来监听touch事件.本教程展示了,如何监听透出事件,让用户旋转一个OpenGL ES对象. 1.   设置一个Touch Listener 为了使你的OpenGL ES应用响应touch事件,你必须在GLSurfaceView类中实现OnTouc