1 package org.pileus.spades;
3 import java.nio.ByteBuffer;
4 import java.nio.ByteOrder;
5 import java.nio.FloatBuffer;
7 import javax.microedition.khronos.egl.EGLConfig;
8 import javax.microedition.khronos.opengles.GL10;
10 import android.content.Context;
11 import android.content.res.Resources;
12 import android.graphics.Bitmap;
13 import android.graphics.BitmapFactory;
14 import android.opengl.GLES20;
15 import android.opengl.GLSurfaceView;
16 import android.opengl.GLUtils;
17 import android.opengl.Matrix;
19 public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
22 private final String vertSource
23 = "uniform mat4 u_model;"
24 + "uniform mat4 u_view;"
25 + "uniform mat4 u_proj;"
26 + "attribute vec4 a_position;"
27 + "attribute vec2 a_mapping;"
28 + "varying vec2 v_mapping;"
30 + " gl_Position = u_proj"
34 + " v_mapping = a_mapping;"
37 private final String fragSource
38 = "precision mediump float;"
39 + "uniform sampler2D u_texture;"
40 + "uniform vec4 u_color;"
41 + "varying vec2 v_mapping;"
43 + " gl_FragColor = texture2D("
44 + " u_texture, v_mapping);"
48 private final float vertCoords[] = {
49 -0.063f, 0.088f, 0f, // Standard poker size:
50 -0.063f, -0.088f, 0f, // 2.5in x 3.5in
51 0.063f, -0.088f, 0f, // 63mm x 88mm
52 0.063f, 0.088f, 0f, //
55 private final float mapCoords[] = {
62 private final float color[] = {
67 private final String cards[] = {
68 "As", "Ks", "Qs", "Js", "10s", "9s", "8s", "7s", "6s", "5s", "4s", "3s", "2s",
69 "Ah", "Kh", "Qh", "Jh", "10h", "9h", "8h", "7h", "6h", "5h", "4h", "3h", "2h",
70 "Ac", "Kc", "Qc", "Jc", "10c", "9c", "8c", "7c", "6c", "5c", "4c", "3c", "2c",
71 "Ad", "Kd", "Qd", "Jd", "10d", "9d", "8d", "7d", "6d", "5d", "4d", "3d", "2d",
75 private Resources res; // app resources
76 private int program; // opengl program
78 private float model[]; // model matrix
79 private float view[]; // view matrix
80 private float proj[]; // projection matrix
82 private FloatBuffer vertBuf; // vertex position buffer
83 private FloatBuffer mapBuf; // texture mapping coord buffer
85 private int modelHandle; // model matrix
86 private int viewHandle; // view matrix
87 private int projHandle; // projection matrix
88 private int vertHandle; // vertex positions
89 private int mapHandle; // texture mapping coords
90 private int texHandle; // texture data
91 private int colorHandle; // color data
93 private int face[]; // card face textures
94 private int red; // red card back
95 private int blue; // blue card back
97 /* GLSurfaceView Methods */
98 public Cards(Context context)
101 Os.debug("Cards: create");
103 this.res = context.getResources();
105 this.model = new float[4*4];
106 this.view = new float[4*4];
107 this.proj = new float[4*4];
109 this.face = new int[52];
111 this.setEGLContextClientVersion(2);
112 this.setRenderer(this);
113 this.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
116 /* Renderer methods */
118 public void onSurfaceCreated(GL10 unused, EGLConfig config)
120 Os.debug("Cards: onSurfaceCreate");
122 /* Initialize shaders */
123 int vertShader = this.loadShader(GLES20.GL_VERTEX_SHADER, vertSource);
124 int fragShader = this.loadShader(GLES20.GL_FRAGMENT_SHADER, fragSource);
126 /* Link shaders into an OpenGL program */
127 this.program = GLES20.glCreateProgram();
128 GLES20.glAttachShader(program, vertShader);
129 GLES20.glAttachShader(program, fragShader);
130 GLES20.glLinkProgram(program);
132 /* Get shaders attributes */
133 this.modelHandle = GLES20.glGetUniformLocation(program, "u_model");
134 this.viewHandle = GLES20.glGetUniformLocation(program, "u_view");
135 this.projHandle = GLES20.glGetUniformLocation(program, "u_proj");
136 this.vertHandle = GLES20.glGetAttribLocation(program, "a_position");
137 this.mapHandle = GLES20.glGetAttribLocation(program, "a_mapping");
138 this.texHandle = GLES20.glGetUniformLocation(program, "u_texture");
139 this.colorHandle = GLES20.glGetUniformLocation(program, "u_color");
141 /* Create vertex array */
142 this.vertBuf = this.loadBuffer(this.vertCoords);
143 this.mapBuf = this.loadBuffer(this.mapCoords);
146 for (int i = 0; i < 52; i++) {
147 String name = "card_" + this.cards[i].toLowerCase();
148 this.face[i] = this.loadTexture(name);
150 this.red = this.loadTexture("card_red");
151 this.blue = this.loadTexture("card_blue");
154 Os.debug("Cards: onSurfaceCreate");
158 public void onDrawFrame(GL10 unused)
160 Os.debug("Cards: onDrawFrame");
162 /* Turn on the program */
163 GLES20.glUseProgram(program);
166 GLES20.glClearColor(0, 0, 0, 1);
167 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
169 GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
170 GLES20.glUniformMatrix4fv(this.viewHandle, 1, false, this.view, 0);
171 GLES20.glUniformMatrix4fv(this.projHandle, 1, false, this.proj, 0);
173 GLES20.glEnableVertexAttribArray(this.vertHandle);
174 GLES20.glEnableVertexAttribArray(this.mapHandle);
175 GLES20.glVertexAttribPointer(this.vertHandle, 3, GLES20.GL_FLOAT, false, 3*4, this.vertBuf);
176 GLES20.glVertexAttribPointer(this.mapHandle, 2, GLES20.GL_FLOAT, false, 2*4, this.mapBuf);
178 GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
179 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.red);
180 GLES20.glUniform1i(this.texHandle, 0);
182 GLES20.glUniform4fv(this.colorHandle, 1, this.color, 0);
184 GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
185 GLES20.glDisableVertexAttribArray(this.mapHandle);
189 public void onSurfaceChanged(GL10 unused, int width, int height)
191 Os.debug("Cards: onSurfaceChanged");
193 GLES20.glViewport(0, 0, width, height);
195 Matrix.setIdentityM(this.model, 0);
196 Matrix.setIdentityM(this.view, 0);
197 Matrix.setIdentityM(this.proj, 0);
201 float yang = xang * ((float)height / (float)width);
203 Matrix.frustumM(this.proj, 0,
204 -1E-6f * xang, // left
205 1E-6f * xang, // right
206 -1E-6f * yang, // bottom
211 Matrix.translateM(this.view, 0,
213 Matrix.rotateM(this.view, 0,
217 Matrix.rotateM(this.view, 0,
219 Matrix.translateM(this.model, 0,
223 /* Private methods */
224 private int loadShader(int type, String code)
226 Os.debug("Cards: loadShader");
228 int shader = GLES20.glCreateShader(type);
229 GLES20.glShaderSource(shader, code);
230 GLES20.glCompileShader(shader);
234 private int loadTexture(String name)
236 Os.debug("Cards: loadTexture - " + name);
238 final int[] tex = new int[1];
240 /* Lookup the resource ID */
243 id = R.drawable.class.getField(name).getInt(null);
244 } catch(Exception e) {
245 Os.debug("Cards: lookup failed for '" + name + "'", e);
249 /* Load the bitmap */
250 Bitmap bitmap = BitmapFactory.decodeResource(this.res, id);
252 /* Copy into OpenGL */
253 GLES20.glGenTextures(1, tex, 0);
254 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex[0]);
255 GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
256 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
257 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
262 private FloatBuffer loadBuffer(float[] data)
264 ByteBuffer bytes = ByteBuffer.allocateDirect(data.length * 4);
265 bytes.order(ByteOrder.nativeOrder());
267 FloatBuffer buf = bytes.asFloatBuffer();