学习模板缓存,模板测试
1、新建 MyStencilRenderer.java 文件
/*
*
(glStencilFunc)常量
GL_NEVER 从不通过模板测试
GL_ALWAYS 总是通过模板测试
GL_LESS 只有参考值<(模板缓存区的值&mask)时才通过
GL_LEQUAL 只有参考值<=(模板缓存区的值&mask)时才通过
GL_EQUAL 只有参考值=(模板缓存区的值&mask)时才通过
GL_GEQUAL 只有参考值>=(模板缓存区的值&mask)时才通过
GL_GREATER 只有参考值>(模板缓存区的值&mask)时才通过
GL_NOTEQUAL 只有参考值!=(模板缓存区的值&mask)时才通过
(glStencilOp)常量
GL_KEEP 保持当前的模板缓存区值
GL_ZERO 把当前的模板缓存区值设为0
GL_REPLACE 用glStencilFunc函数所指定的参考值替换模板参数值
GL_INCR 增加当前的模板缓存区值,但限制在允许的范围内
GL_DECR 减少当前的模板缓存区值,但限制在允许的范围内
GL_INVERT 将当前的模板缓存区值进行逐位的翻转
*/
public class MyStencilRenderer extends MyAbstractRenderer {
private float left =0;
private float up =0;
float rWidth =0.2f;
float rHeight =0.2f;
private boolean isDown =true;
private boolean isRight =true;
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
//设置清屏色(背景)
gl.glClearColor(0, 0, 1, 1);
//模板清除值
gl.glClearStencil(0);
//启用顶点缓冲区
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
//模板测试
gl.glEnable(GL10.GL_STENCIL_TEST);
//单调模式 没有过度
gl.glShadeModel(GL10.GL_FLAT);
}
protected void drawBefore(GL10 gl) {
//清除 颜色 深度 模板缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT
|GL10.GL_DEPTH_BUFFER_BIT
|GL10.GL_STENCIL_BUFFER_BIT);
}
protected void draw(GL10 gl) {
//绘制白色螺旋线
List<Float> points =new ArrayList<Float>();
float x =0f;
float y =0.8f;
float z =0f;
float yStep =0.005f;
float r =0.7f;
for(float angle =0f;angle<(Math.PI *6);angle +=(Math.PI/40)){
x =(float) (r *Math.cos(angle));
z =-(float) (r *Math.sin(angle));
y =y -yStep;
points.add(x);
points.add(y);
points.add(z);
}
//绘制白色直线,设置模板函数,所有操作都不能通过测试,但是对模板缓冲区的值进行增加
//模板缓存区 中的值与参考值ref进行比较,比较标准是func所指定的比较函数。
//参考值和模板缓存区的值都可以与掩码进行为AND操作。
//模板测试的结果还导致模板缓存区值根据glStencilOp函数所指定的行为进行修改。
gl.glStencilFunc(GL10.GL_NEVER, 0, 0);
//glStencilOp 三个参数的意思
//当模板测试失败时所执行的操作
//当模板测试通过,深度测试失败时所执行的操作
//当模板测试通过,深度测试通过时所执行的操作
gl.glStencilOp(GL10.GL_INCR, GL10.GL_INCR, GL10.GL_INCR);
gl.glColor4f(1f, 1f, 1f, 1f);
ByteBuffer pBB =BufferUtil.list2ByteBuffer(points);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, pBB);
gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, points.size()/3);
//画正方形
//正方形的移动
if(isRight){
left +=0.01f;
}else{
left -=0.01f;
}
if(left <= -ratio){
isRight =true;
}
if(left >=(ratio -rWidth)){
isRight =false;
}
if(isRight){
up +=0.01f;
}else{
up -=0.01f;
}
if(up >=1){
isDown =true;
}
if(up >=(1 -rHeight)){
isDown =false;
}
//正方形的坐标
float []rectPoints={
left,up-rHeight,1.9f,
left,up,1.9f,
left+rWidth,up-rHeight,1.9f,
left+rWidth,up,1.9f,
};
gl.glStencilFunc(GL10.GL_EQUAL, 1, 1);
gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_KEEP);
gl.glColor4f(1f, 0f, 0f, 1f);
ByteBuffer rBB =BufferUtil.arr2ByteBuffer(rectPoints);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, rBB);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, rectPoints.length/3);
}
}
2、修改 MainActivity.java onCreate函数
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MySurfaceView view=new MySurfaceView(this);
renderer=new MyStencilRenderer();
//真机才能看出模板的效果
//置颜色缓存为RGBA,位数都为5650 depth缓存位数为16 stencil缓存位数为8
view.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
view.setRenderer(renderer);
setContentView(view);
}
如果 没有设置
view.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
将看到
否则会看到
红色矩形透过白色曲线模板在底板上映出了红色红色的线条