Back to project page touchgloid.
The source code is released under:
MIT License
If you think the Android project touchgloid listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package rucamzu.touchgloid; //w ww. j ava 2 s . c o m import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT; import static android.opengl.GLES20.GL_LINE_LOOP; import static android.opengl.GLES20.GL_TRIANGLE_FAN; import static android.opengl.GLES20.GL_UNSIGNED_SHORT; import static android.opengl.GLES20.glClear; import static android.opengl.GLES20.glClearColor; import static android.opengl.GLES20.glDrawElements; import static android.opengl.GLES20.glFlush; import static android.opengl.GLES20.glViewport; import static java.lang.Math.sin; import static java.lang.Math.cos; import static java.lang.Math.PI; import android.content.Context; import android.content.res.Resources; import android.opengl.GLSurfaceView; import android.util.Log; import com.rucamzu.touchgloid.R; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import rucamzu.opengl.FragmentShader; import rucamzu.opengl.IndexBuffer; import rucamzu.opengl.Program; import rucamzu.opengl.Transform; import rucamzu.opengl.VertexBuffer; import rucamzu.opengl.VertexShader; public class TouchgloidRenderer implements GLSurfaceView.Renderer { public static final class Touch { public final float x, y, size; public Touch(float x, float y, float size) { this.x = x; this.y = y; this.size = size; } } private final Context context; public volatile Touch touches[]; private final static int MARKER_VERTEX_COMPONENTS = 2; private final static int MARKER_VERTICES = 50; private VertexBuffer markerVertexBuffer; private IndexBuffer markerIndexBuffer; private VertexShader vertexShader; private FragmentShader fragmentShader; private Program program; private Transform projection; public TouchgloidRenderer(Context context) { this.context = context; } @Override public void onSurfaceCreated(GL10 unused, EGLConfig config) { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); markerVertexBuffer = VertexBuffer.create(buildCircleVertices(MARKER_VERTICES)); markerIndexBuffer = IndexBuffer.create(buildCircleIndices(MARKER_VERTICES)); // markerVertexBuffer = VertexBuffer.create(buildSquareVertices()); // markerIndexBuffer = IndexBuffer.create(buildSquareIndices()); vertexShader = (VertexShader) VertexShader .create() .source(readTextFileFromResource(R.raw.vertex_shader)) .compile(); if (!vertexShader.ok()) Log.w("touchgloid", "Failed to create vertex shader"); else if (vertexShader.status() == 0) Log.w("touchgloid", "Failed to compile vertex shader"); fragmentShader = (FragmentShader) FragmentShader.create() .source(readTextFileFromResource(R.raw.fragment_shader)) .compile(); if (!fragmentShader.ok()) Log.w("touchgloid", "Failed to create fragment shader"); else if (fragmentShader.status() == 0) Log.w("touchgloid", "Failed to compile fragment shader"); program = Program.create().attach(vertexShader).attach(fragmentShader) .link(); if (!program.ok()) Log.w("touchgloid", "Failed to create program"); else if (program.status() == 0) Log.w("touchgloid", "Failed to link program"); } @Override public void onSurfaceChanged(GL10 unused, int width, int height) { glViewport(0, 0, width, height); projection = Transform.createProjectionOrtho((float) width, (float) height); } @Override public void onDrawFrame(GL10 unused) { draw(); } public void draw() { glClear(GL_COLOR_BUFFER_BIT); program.use(); program.getUniform("u_projection").set(projection); drawMarker(new Touch( 0.0f, 0.0f, 0.1f), GL_LINE_LOOP); drawMarker(new Touch(-1.0f, -1.0f, 0.1f), GL_LINE_LOOP); drawMarker(new Touch(-1.0f, 1.0f, 0.1f), GL_LINE_LOOP); drawMarker(new Touch( 1.0f, -1.0f, 0.1f), GL_LINE_LOOP); drawMarker(new Touch( 1.0f, 1.0f, 0.1f), GL_LINE_LOOP); if (touches != null) { for (int i = 0; i < touches.length; ++i) { drawMarker(touches[i], GL_TRIANGLE_FAN); } } glFlush(); } private void drawMarker(Touch touch, int mode) { Transform scale = Transform.createScale(touch.size, touch.size, 1.0f); Transform translation = Transform.createTranslation(touch.x, touch.y, 0.0f); Transform modelview = Transform.compose(translation, scale); program.getUniform("u_modelview").set(modelview); markerVertexBuffer.bind(); markerIndexBuffer.bind(); program.getAttribute("a_position").enable().set(MARKER_VERTEX_COMPONENTS); glDrawElements(mode, markerIndexBuffer.capacity(), GL_UNSIGNED_SHORT, 0); program.getAttribute("a_position").disable(); markerVertexBuffer.unbind(); markerIndexBuffer.unbind(); } private static float[] buildSquareVertices() { final float vertices[] = { 0.0f, 0.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f }; return vertices; } private static short[] buildSquareIndices() { final short indices[] = { 1, 2, 3, 4, 5, 2 }; return indices; } private static float[] buildCircleVertices(int nVertices) { float[] vertices = new float[nVertices * 2]; vertices[0] = 0.0f; vertices[1] = 0.0f; for (int i = 0; i < nVertices - 1; ++i) { vertices[2 * i + 1] = (float) cos(i * 2.0 * PI / (nVertices - 1)); vertices[2 * i + 2] = (float) sin(i * 2.0 * PI / (nVertices - 1)); } return vertices; } private static short[] buildCircleIndices(int nVertices) { short[] indices = new short[nVertices + 1]; for (int i = 0; i < nVertices; ++i) { indices[i] = (short) (i + 1); } indices[nVertices] = 2; return indices; } public String readTextFileFromResource(int resourceId) { StringBuilder body = new StringBuilder(); try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(resourceId))); for (String line; (line = bufferedReader.readLine()) != null;) { body.append(line).append('\n'); } } catch (IOException e) { throw new RuntimeException("Could not open resource: " + resourceId, e); } catch (Resources.NotFoundException nfe) { throw new RuntimeException("Resource not found: " + resourceId, nfe); } return body.toString(); } }