EVE-20 模版测试

FT8xx的模版(Stencil)和OpenGL中的模版是一个概念,所以具体可以参考OpenGL中描述。下面是网上查找的一些关于模版的说明

首先解释一下什么是模版缓冲区(Stencil Buffer)。

模版缓冲区可以为屏幕上的每个像素点保存一个无符号整数值。这个值的具体意义视程序的具体应用而定。在渲染的过程中,可以用这个值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新相应的像素点的颜色值。这个比较的过程被称为模版测试。如果模版测试通过,则相应的像素点更新,否则不更新。就像使用纸板和喷漆一样精确的混图一样,当启动模版测试时,通过模版测试的片段像素点会被替换到颜色缓冲区中,从而显示出来,未通过的则不会保存到颜色缓冲区中,从而达到了过滤的功能。下图描述了模版缓冲区的原理:

EVE-20 模版测试_第1张图片

FT8xx的模版功能有3条指令相关:STENCIL_FUNCSTENCIL_MASKSTENCIL_OP

【STENCIL_FUNC】

设定模版测试的功能及参考值。

参数

         func: 指定测试功能,指定下列其中一项:NEVER, LESS, LEQUAL, GREATER,GEQUAL, EQUAL, NOTEQUAL或ALWAYS。初始值是ALWAYS。

NEVER

从来不能通过

LESS

小于参考值可以通过

LEQUAL

小于或者等于可以通过

GREATER

大于通过

GEQUAL

大于等于通过 

EQUAL

等于通过

NOTEQUAL

不等于通过

ALWAYS

永远可以通过(默认值) 

         ref: 参考值,初始值是0

         mask: 掩码值(会与参考值和模版缓冲区内的值先作与操作,再参考func中的参数测试是否通过测试) ,初始值是255

【STENCIL_OP】

设定模版测试的动作

参数

         sfail:指定模版测试失败后的动作。

         spass: 指定模版测试通过后的动作。

2个参数都指定模版测试失败后的动作,采用下面所列的其中一种:

ZERO

回零

KEEP

不改变,默认值

REPLACE

使用测试条件中的设定值来代替当前模版值

INCR

增加1,但如果已经是最大值,则保持不变

DECR

减少1,但如果已经是零,则保持不变

INVERT

按位取反

【STENCIL_MASK】

控制在模版平面里个别bits的写入

参数

         mask:用来启动写入模板bits的遮盖,初始值是255。

 

举例说明,画一个圆环(中心位置仍然保持背景的图案,背景采用Gradient例子的方式)

EVE-20 模版测试_第2张图片

代码:

     ftWrDispCmd(STENCIL_FUNC(NEVER, 0x00, 0x00));

     ftWrDispCmd(STENCIL_OP(INCR, INCR));

     ftWrDispCmd(BEGIN(FTPOINTS));

     ftWrDispCmd(POINT_SIZE(80 * 16));

     ftWrDispCmd(VERTEX2F((PANEL_WIDTH / 2) * 16, (PANEL_HEIGHT / 2) * 16));

     ftWrDispCmd(STENCIL_FUNC(NOTEQUAL, 0x01, 0x01));

     ftWrDispCmd(POINT_SIZE(90 * 16));

     ftWrDispCmd(VERTEX2F((PANEL_WIDTH / 2) * 16, (PANEL_HEIGHT / 2) * 16));

1) 第一个STENCIL_FUNC和STENCIL_OP对后面画圆(蓝色代码部分)的影响是:STENCIL_FUNC的第一个参数NEVER是让圆的所有像素点因为模版值不通过测试而不显示,因为是NEVER,所以后面2个参数无意义(开始时模版值都是0)。STENCIL_OP的参数设为INCR则表示圆的所有像素点所在位置对应模版位置的模版值都加1变为1,而其他没有像素的地方所对应模版位置的模版值保持原值0不变。

如果没有接下来的语句,运行程序是看不到任何圆的显示,所以目前只是做个一个模版。

2) 第二个STENCIL_FUNC对后面画圆的影响是:STENCIL_FUNC的3个参数表示模版中的模版值与第三个参数0x01做与运算并且将结果与第二个参数比较,不相等的就通过(也就是变透明),相等的不通过(即不透明)。所以接下来画圆部分如果像素所在位置对应模版位置的模版值为1的话就不显示,如果为0的话则显示。

这里并没有第二个STENCIL_OP,还是之前的参数INCR,后面的模版仍然是按照第一个STENCIL_OP生成新的模版,下面用图画的方式解释一下模版的变化。

EVE-20 模版测试_第3张图片

模版开始默认是全0,画了第一个圆后,画圆的地方模版的值变为1,即第二张图中的蓝色部分,画第二个圆时,可以想象中间的蓝色部分是一个挡板,然后喷漆一个大圆,这样就能喷出一个绿色部分的圆环了。

 

如果我们要在圆环上实现进度条的显示,可以将STENCIL_FUNC和STENCIL_OP设置如下:

ftWrDispCmd(STENCIL_FUNC(EQUAL, 0x01, 0x01));

ftWrDispCmd(STENCIL_OP(KEEP, KEEP));

当显示的图片在上图绿色圈部分时等于1,显示出来,其他位置不等于1则不显示。STENCIL_OP的参数都为KEEP,即模版不做改变。接下来的代码如下,在圆环上画POINT:

ftWrDispCmd(COLOR_RGB(246, 146, 30));

ftWrDispCmd(POINT_SIZE(10 * 16)); //1.5 * 16

for (degree = 0; degree < (gMenuParam.num / 10) * 10; degree += 10)

{

     int16_t posX, posY;

     posX = (PANEL_WIDTH / 2) * 16 + ((int32_t)170 * 16)* ftQcos((int32_t)degree * 65535 / 360) / 65536;

     posY = (PANEL_HEIGHT / 2) * 16 + ((int32_t)170 * 16) * ftQsin((int32_t)degree * 65535 / 360) / 65536;

     ftWrDispCmd(VERTEX2F(posX, posY));

}

定时做画点的动作,显示的效果如下:

EVE-20 模版测试_第4张图片

你可能感兴趣的:(EVE,TFT)