opengl模板测试实例

在opengl中, 可以开启模板测试功能,来限定某一部分是可画的,某一部分是不可画的。这可通过设置模板模式来控制哪部分是可画的, 有点类似在墙上喷字。 

虽说剪刀测试也可以限定蓝屏的某一部分可画,但不适用于不规则的区域,不如模板测试灵活。下面提供一个Android模板测试的实例代码:

 

public class MyRenderer implements Renderer {

	private Square square1 = null;
	
	private FloatBuffer vertices = null;
	
    // Step size in x and y directions
	// (number of pixels to move each time)
	private float x = 0;
	private float y = 0;
	private float xstep = 1.0f;
	private float ystep = 1.0f;

	// Keep track of windows changing width and height
	private float windowWidth;
	private float windowHeight;
	
	public MyRenderer(Context ctx) {
		square1 = new Square(ctx, false);

	}
	
	private void makeStencilPattern(GL10 gl) {
		
		float dRadius = 0.1f;
	    
	    ByteBuffer bb = ByteBuffer.allocateDirect(4000 * 4 * 2);
	    bb.order(ByteOrder.nativeOrder());
	    vertices = bb.asFloatBuffer();
	    vertices.position(0);
	    
        for(float dAngle = 0; dAngle < 400.0; dAngle += 0.1)
        {
        	vertices.put((float) (dRadius * Math.cos(dAngle)));
        	vertices.put((float) (dRadius * Math.sin(dAngle)));
            dRadius *= 1.002;
        }
 
        vertices.position(0);

	}
	
	@Override
	public void onDrawFrame(GL10 gl) {

		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_STENCIL_BUFFER_BIT);
		// Replace the current matrix with the identity matrix
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
		
	    gl.glStencilFunc(GL10.GL_NEVER, 0x0, 0x0);
	    gl.glStencilOp(GL10.GL_INCR, GL10.GL_INCR, GL10.GL_INCR);
		
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glVertexPointer(2, GL10.GL_FLOAT, 0, 
                vertices);
		gl.glColor4f(0, 1, 1, 1);
		gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, 4000 * 2);
		
	    gl.glStencilFunc(GL10.GL_NOTEQUAL, 0x1, 0x1);
	    gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_KEEP);
		gl.glColor4f(1, 0, 0, 1);
		
        // Reverse direction when you reach left or right edge
        if(x > windowWidth-20 || x < -windowWidth)
            xstep = -xstep;

        // Reverse direction when you reach top or bottom edge
        if(y > windowHeight || y < -windowHeight + 20)
            ystep = -ystep;


        // Check bounds. This is in case the window is made
        // smaller while the rectangle is bouncing and the 
    	// rectangle suddenly finds itself outside the new
        // clipping volume
        if(x > windowWidth-20)
            x = windowWidth-20-1;

        if(y > windowHeight)
            y = windowHeight-1; 

    	// Actually move the square
        x += xstep;
        y += ystep;
        
        gl.glTranslatef(x, y, 0);
		
		square1.draw(gl);

	}

	@Override
	public void onSurfaceChanged(GL10 gl, int w, int h) {
	    float aspectRatio;

	    // Prevent a divide by zero
	    if(h == 0)
	        h = 1;
			
	    // Set Viewport to window dimensions
	    gl.glViewport(0, 0, w, h);

	    // Reset coordinate system
	    gl.glMatrixMode(GL10.GL_PROJECTION);
	    gl.glLoadIdentity();

	    // Establish clipping volume (left, right, bottom, top, near, far)
	    aspectRatio = (float)w / (float)h;
	    if (w <= h) 
	        {
	        windowWidth = 100;
	        windowHeight = 100 / aspectRatio;
	        gl.glOrthof(-100.0f, 100.0f, -windowHeight, windowHeight, 1.0f, -1.0f);
	        }
	    else 
	        {
	        windowWidth = 100 * aspectRatio;
	        windowHeight = 100;
	        gl.glOrthof(-windowWidth, windowWidth, -100.0f, 100.0f, 1.0f, -1.0f);
	        }

	    gl.glMatrixMode(GL10.GL_MODELVIEW);
	    gl.glLoadIdentity();
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		// TODO Auto-generated method stub
		gl.glClearColor(0.0f, 0.0f, 1.0f, 0.0f);  
		// Enable Smooth Shading, default not really needed.
		gl.glShadeModel(GL10.GL_SMOOTH);
	
		gl.glEnable(GL10.GL_STENCIL_TEST);
		gl.glClearStencil(0);
		
		makeStencilPattern(gl);
	}

}


 

转载于:https://my.oschina.net/fuyajun1983cn/blog/263963

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值