OpenGL利用模板测试实现不规则裁剪
本文是原创文章,如需转载,请注明文章出处
在游戏开发中,经常会有这样的需求:给定一张64x64的卡牌素材,要求只显示以图片中心为圆点、直径为64的圆形区域,这就要用到模板测试来进行不规则裁剪。
实现不规则裁剪的主要思路如下:
1.准备好素材:要显示的64x64图片一张
,不规则形状的遮罩图一张(本例中为圆形图)。
2.打开alpha测试,将测试通过条件设置成>0.5,使遮罩图中心的圆形区域可以通过测试,周围的透明像素无法通过测试。
3.打开模板测试,将测试通过条件设置成GL_NEVER,并将测试失败的模板值设置成参考值。
4.清除模板缓冲区,设置成0。
5.绘制遮罩图,首先alpha测试只允许遮罩图中心的圆形区域通过,随后进行模板测试,全部失败后,圆形区域的模板缓冲区的值被替换成参考值。
6.关闭alpha测试,重新设置模板测试通过条件成GL_EQUAL,值为之前替换的参考值。
7.绘制64x64的原图,此时只有圆形区域的模板缓冲区的值是参考值能通过模板测试,其他的都是0无法通过测试,实现了裁剪。
最终效果:
以下代码使用以上思路实现了矩形裁剪:
#include "stdafx.h"
#include <glut.h> #define viewWidth 800
#define viewHeight 800
GLubyte quad[viewWidth][viewHeight][];
GLuint quadTexName;
const GLint stencilRef = 0x01;
const GLint stencilClear = 0x00; void createQuad(void)
{
int i, j;
for (i = ; i < viewWidth; ++i){
for (j = ; j < viewHeight; ++j){
quad[i][j][] = (GLubyte);
quad[i][j][] = (GLubyte);
quad[i][j][] = (GLubyte);
if (i < (viewWidth / + ) && i >(viewWidth / - ) && j < (viewHeight / + ) && j >(viewHeight / - )){
quad[i][j][] = (GLubyte);
}
else{
quad[i][j][] = (GLubyte);
}
}
}
} void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearStencil(stencilClear);
glShadeModel(GL_FLAT); createQuad(); glPixelStorei(GL_UNPACK_ALIGNMENT, ); glGenTextures(, &quadTexName);
glBindTexture(GL_TEXTURE_2D, quadTexName); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D(GL_TEXTURE_2D, , GL_RGBA, (GLsizei)viewWidth, (GLsizei)viewHeight, , GL_RGBA, GL_UNSIGNED_BYTE, quad);
} void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glStencilFunc(GL_NEVER, stencilRef, 0xFF);
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
glAlphaFunc(GL_GREATER, 0.5); glEnable(GL_STENCIL_TEST);
glEnable(GL_ALPHA_TEST);
glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, quadTexName); glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(-10.0, -10.0);
glTexCoord2f(0.0, 1.0); glVertex2f(-10.0, 10.0);
glTexCoord2f(1.0, 1.0); glVertex2f(10.0, 10.0);
glTexCoord2f(1.0, 0.0); glVertex2f(10.0, -10.0);
glEnd(); glDisable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST); glStencilFunc(GL_EQUAL, stencilRef, 0xFF);
glBegin(GL_QUADS);
glColor3f(0.5, 0.5, 0.5);
glVertex2f(-10.0, -10.0);
glVertex2f(-10.0, 10.0);
glVertex2f(10.0, 10.0);
glVertex2f(10.0, -10.0);
glEnd();
glFlush();
} void reshape(int w, int h)
{
glViewport(, , (GLsizei)w, (GLsizei)h);
gluOrtho2D(-, , -, );
} int _tmain(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition(, );
glutInitWindowSize(viewWidth, viewHeight);
glutCreateWindow("Stencil Test");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return ;
}
最终效果:
OpenGL利用模板测试实现不规则裁剪的更多相关文章
- opengl学习-利用模板测试勾画物体轮廓中出现的一个问题
我在学习OpenGL模板测试勾画物体轮廓的时候,出现了这个问题: 这个出现的原因就是,改变摄像机的时候,每次绘制,上次绘制中模板缓冲区的数据没有清除的原因.也就是在while循环开始的时候,glCle ...
- OpenGL ES 中的模板测试
模板测试的主要功能是丢弃一部分片元,相对于深度检测来说,模板测试提出的片元数量相对较少.模板测试发生在剪裁测试之后,深度测试之前. 使用模板测试时很重要的代码提示: 1.glClear( GL_STE ...
- OpenGL(十四) 模板测试
启用模板测试时,OpenGL会在内存中开辟一块空间作为模板缓冲区,里边保存了每个像素的"模板值",模板测试的过程就是把每一个像素的模板值与一个设定的模板参考值进行比较,符合设定条件 ...
- OpenGL模板缓冲区与模板测试
原文地址:http://www.blogjava.net/qileilove/archive/2014/01/23/409269.html 帧缓冲区有许多缓冲区构成,这些缓冲区大致分为: 颜色缓冲区: ...
- OpenGL-----深度测试,剪裁测试、Alpha测试和模板测试
片断测试其实就是测试每一个像素,只有通过测试的像素才会被绘制,没有通过测试的像素则不进行绘制.OpenGL提供了多种测试操作,利用这些操作可以实现一些特殊的效果.我们在前面的课程中,曾经提到了“深度测 ...
- itextsharp利用模板生成pdf文件笔记
iTextSharp是一款开源的PDF操作类库,使用它可以快速的创建PDF文件. 中文参考网站:http://hardrock.cnblogs.com/ http://pdfhome.hope.com ...
- Java利用模板生成pdf并导出
1.准备工作 (1)Adobe Acrobat pro软件:用来制作导出模板 (2)itext的jar包 2.开始制作pdf模板 (1)先用word做出模板界面 (2)文件另存为pdf格式文件 (3) ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十一章:模板测试
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十一章:模板测试 代码工程地址: https://github.co ...
- 利用模板将HTML从JavaScript中抽离
利用模板将HTML从JavaScript中抽离 一.当需要注入大段的HTML标签到页面中时,应该使用服务器渲染(从服务器加载HTML标签) 该方法将模板放置于服务器中使用XMLHttpRequest对 ...
随机推荐
- 自动刷新页面为了session不过期
为了保证在打开页面期间session不过期,估做了一个隐藏Iframe每隔若干秒来刷新一下页面,在隐藏页面给session赋值. <script type="text/javascri ...
- linux虚拟机上不了网--桥接方式--问题一直未解决
转载的:可是自己的虚拟机就是上不了网,无线网卡该配的也配了还是不行,如果真有台物理机器就行了,省了好多事:但是模拟性能时肯定不行了:有人知道是什么原因不? 虚拟机网络模式 无论是vmware,virt ...
- sql逻辑执行顺序
要知道SQL语句,我想我们有必要知道SQL Server查询分析器怎么执行我们的SQL语句的,我们很多人会看执行计划,或者用Profiler来监视和调优查询语句或者存储过程慢的原因,但是如果我们知道查 ...
- 修改tnsnames.ora文件中配置内容中的连接别名后,连接超时解决办法
1.tnsnames.ora文件中配置内容中的连接别名:由upaydb修改为IP地址 2.连接超时 定位原因: PLSQL登录界面的数据库列表就是读的tnsname.ora中连接的别名,这个文件中连接 ...
- ecshop二次开发之常用函数及汇总
lib_time.php gmtime()说明:获得当前格林威治时间的时间戳 server_timezone()说明:获得服务器的时区 local_mktime($hour = NULL , $min ...
- mongoose操作汇总。嘻嘻
MongoDb 命令查询所有数据库列表 CODE: > show dbs 如果想查看当前连接在哪个数据库下面,可以直接输入db CODE: > db Admin 想切换到test数 ...
- 工作队列(workqueue) create_workqueue/schedule_work/queue_work
--- 项目需要,在驱动模块里用内核计时器timer_list实现了一个状态机.郁闷的是,运行时总报错"Scheduling while atomic",网上搜了一下:" ...
- Java读取Level-1行情dbf文件极致优化(1)
最近架构一个项目,实现行情的接入和分发,需要达到极致的低时延特性,这对于证券系统是非常重要的.接入的行情源是可以配置,既可以是Level-1,也可以是Level-2或其他第三方的源.虽然Level-1 ...
- MATLAB地图工具箱学习总结(二)大圆和恒向线
MATLAB地图工具箱学习总结(二)大圆和恒向线 今天要和大家谈一谈大圆.恒向线航道的画法.还是先从案例开始说起,再分别介绍相关的函数. 1 作业案例:地图投影作 ...
- cygwin安装
我安装的是cygwin2.5.2,相关下载:https://cygwin.com/setup-x86_64.exe 先安装cygwin,x86_64版本,安装时选择库(gcc-core.gcc-c++ ...