在游戏中,有时需要对一张矩形图片进行切割,绘制成圆角矩形。
circelrect.vert
attribute vec4 a_position; attribute vec4 a_normal; attribute vec4 a_color; attribute vec2 a_texCoord0; uniform mat4 u_projTrans; varying vec4 v_color; varying vec2 v_texCoords; void main() { v_color = vec4(0, 0, 0, 0); v_texCoords = a_texCoord0; gl_Position = u_projTrans * a_position; }
circlerect.frag
#ifdef GL_ES precision mediump float; #endif varying vec2 v_texCoords; uniform sampler2D u_texture; varying vec4 v_color; uniform float r; bool isOut(float x, float y, float cx, float cy, float r){ bool flag1 = (cx<0.5f && x<cx) || (cx>0.5f && x>cx); bool flag2 = (cy<0.5f && y<cy) || (cy>0.5f && y>cy); float dis = (x-cx)*(x-cx) + (y-cy)*(y-cy); if(flag1 && flag2 && dis>r*r){ return true; } return false; } void main() { vec4 texColor = texture2D(u_texture, v_texCoords); float x = v_texCoords.x; float y = v_texCoords.y; float rate = 1f; if(isOut(x, y, r, r, r)) rate = 0f; if(isOut(x, y, r, 1-r, r)) rate = 0f; if(isOut(x, y, 1-r, r, r)) rate = 0f; if(isOut(x, y, 1-r, 1-r, r)) rate = 0f; gl_FragColor = vec4(texColor.rgb, rate*texColor.a); }
gdx程序
package com.fxb.gdx.example; import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.InputAdapter; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShaderProgram; public class Test014_MaskShader extends ApplicationAdapter{ SpriteBatch batch; Texture texture; ShaderProgram shader; int[][] maskss; int[] masks; public void create() { super.create(); batch = new SpriteBatch(); texture = new Texture(Gdx.files.internal("data/pic.jpg")); // shader = new ShaderProgram( Gdx.files.internal("shader/mask.vert").readString(), // Gdx.files.internal("shader/mask.frag").readString() ); shader = new ShaderProgram( Gdx.files.internal("shader/circlerect.vert").readString(), Gdx.files.internal("shader/circlerect.frag").readString() ); batch.setShader(shader); maskss = new int[10][10]; for(int i=0; i<maskss.length; ++i){ for(int j=0; j<maskss[i].length; ++j){ maskss[i][j] = 0; } } maskss[1][2] = 1; maskss[5][6] = 1; masks = new int[100]; setMask(1, 2); setMask(5, 6); // shader.setUniformf("maskX", 0.2f); // shader.setUniformf("maskY", 0.3f); Gdx.input.setInputProcessor(adapter); } private void setMask(int xIndex, int yIndex){ maskss[xIndex][yIndex] = 1; masks[yIndex*10+xIndex] = 1; } // float maskX = 0.3f, maskY = 0.4f; // float[] maskXs = {0.3f, 0.9f}; // float[] maskYs = {0.4f, 0.9f}; float[] maskXs = new float[10]; float[] maskYs = new float[10]; float r = 0.05f; float step = 0.01f; float rate = 1f; public void render() { super.render(); // Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1f); Gdx.gl.glClearColor(0f, 0f, 0f, 1f); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // uniform float maskX; // uniform float maskY; batch.setShader(shader); batch.begin(); // shader.setUniformf("maskX", maskX); // shader.setUniformf("maskY", maskY); // shader.setUniform1fv("maskXs", maskXs, 0, 10); // shader.setUniform1fv("maskYs", maskYs, 0, 10); shader.setUniformf("r", r); batch.draw(texture, 100, 100); batch.end(); r += step*rate; if(r >=0.45f){ rate = -1f; } else if(r <= 0f){ rate = 1f; } } public void dispose() { super.dispose(); // uniform float[] maskXs; // uniform float[] maskYs; // // void main() { // vec4 texColor = texture2D(u_texture, v_texCoords); // // float x = v_texCoords.x; // float y = 1f - v_texCoords.y; // // float rate = 1f; // for(GLint i=0; i<2; ++i){ // float maskX = maskXs[i]; // float maskY = maskYs[i]; // if(x>maskX-0.02f && x<maskX+0.02f && y>maskY-0.02f && y<maskY+0.02f){ // rate = 0f; // } // } // // // gl_FragColor = vec4(texColor.rgb, texColor.a*rate); // } } private InputAdapter adapter = new InputAdapter(){ public int changeY(int screenY){ return 480-screenY; } public boolean touchDown(int screenX, int screenY, int pointer,int button) { screenY = changeY(screenY); float curX = screenX-100, curY = screenY-100; if(curX>0 && curX<texture.getWidth() && curY>0 && curY<texture.getHeight()){ // maskX = curX/texture.getWidth(); // maskY = curY/texture.getHeight(); // maskXs[0] = maskXs[1]; // maskYs[0] = maskYs[1]; for(int i=0; i<maskXs.length-1; ++i){ maskXs[i] = maskXs[i+1]; maskYs[i] = maskYs[i+1]; } maskXs[maskXs.length-1] = curX/texture.getWidth(); maskYs[maskYs.length-1] = curY/texture.getHeight(); } return super.touchDown(screenX, screenY, pointer, button); } public boolean touchUp(int screenX, int screenY, int pointer, int button) { return super.touchUp(screenX, screenY, pointer, button); } public boolean touchDragged(int screenX, int screenY, int pointer) { return super.touchDragged(screenX, screenY, pointer); } }; }
运行结果: