]> Pileus Git - ~andy/spades/blob - src/org/pileus/spades/Cards.java
4149b9d721428152a155a7324673794aaf715060
[~andy/spades] / src / org / pileus / spades / Cards.java
1 package org.pileus.spades;
2
3 import java.nio.ByteBuffer;
4 import java.nio.ByteOrder;
5 import java.nio.FloatBuffer;
6
7 import javax.microedition.khronos.egl.EGLConfig;
8 import javax.microedition.khronos.opengles.GL10;
9
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;
18
19 public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
20 {
21         /* Shader data */
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;"
29                 + "void main() {"
30                 + "  gl_Position = u_proj"
31                 + "              * u_model"
32                 + "              * u_view"
33                 + "              * a_position;"
34                 + "  v_mapping   = a_mapping;"
35                 + "}";
36
37         private final String fragSource
38                 = "precision mediump   float;"
39                 + "uniform   sampler2D u_texture;"
40                 + "uniform   vec4      u_color;"
41                 + "varying   vec2      v_mapping;"
42                 + "void main() {"
43                 + "  gl_FragColor = texture2D("
44                 + "    u_texture, v_mapping);"
45                 + "}";
46
47         /* Drawing data */
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, //
53         };
54
55         private final float  mapCoords[] = {
56                 0.0f, 0.0f,
57                 0.0f, 1.0f,
58                 1.0f, 1.0f,
59                 1.0f, 0.0f,
60         };
61
62         private final float  color[] = {
63                 1, 0, 0, 1
64         };
65
66         /* Cards data */
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",
72         };
73
74         /* Private data */
75         private Resources    res;         // app resources
76         private int          program;     // opengl program
77
78         private float        model[];     // model matrix
79         private float        view[];      // view matrix
80         private float        proj[];      // projection matrix
81
82         private FloatBuffer  vertBuf;     // vertex position buffer
83         private FloatBuffer  mapBuf;      // texture mapping coord buffer
84
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
92
93         private int          face[];      // card face textures
94         private int          red;         // red card back
95         private int          blue;        // blue card back
96
97         /* Private methods */
98         private int loadShader(int type, String code)
99         {
100                 Os.debug("Cards: loadShader");
101
102                 int shader = GLES20.glCreateShader(type);
103                 GLES20.glShaderSource(shader, code);
104                 GLES20.glCompileShader(shader);
105                 return shader;
106         }
107
108         private int loadTexture(String name)
109         {
110                 Os.debug("Cards: loadTexture - " + name);
111
112                 final int[] tex = new int[1];
113
114                 /* Lookup the resource ID */
115                 int id = 0;
116                 try {
117                         id = R.drawable.class.getField(name).getInt(null);
118                 } catch(Exception e) {
119                         Os.debug("Cards: lookup failed for '" + name + "'", e);
120                         return 0;
121                 }
122
123                 /* Load the bitmap */
124                 Bitmap bitmap = BitmapFactory.decodeResource(this.res, id);
125
126                 /* Copy into OpenGL */
127                 GLES20.glGenTextures(1, tex, 0);
128                 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex[0]);
129                 GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
130                 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
131                 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
132
133                 return tex[0];
134         }
135
136         private FloatBuffer loadBuffer(float[] data)
137         {
138                 ByteBuffer bytes = ByteBuffer.allocateDirect(data.length * 4);
139                 bytes.order(ByteOrder.nativeOrder());
140
141                 FloatBuffer buf = bytes.asFloatBuffer();
142                 buf.put(data);
143                 buf.position(0);
144
145                 return buf;
146         }
147
148         /* GLSurfaceView Methods */
149         public Cards(Context context)
150         {
151                 super(context);
152                 Os.debug("Cards: create");
153
154                 this.res = context.getResources();
155
156                 this.model = new float[4*4];
157                 this.view  = new float[4*4];
158                 this.proj  = new float[4*4];
159
160                 this.face  = new int[52];
161
162                 this.setEGLContextClientVersion(2);
163                 this.setRenderer(this);
164                 this.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
165         }
166
167         /* Renderer methods */
168         @Override
169         public void onSurfaceCreated(GL10 unused, EGLConfig config)
170         {
171                 Os.debug("Cards: onSurfaceCreate");
172
173                 /* Initialize shaders */
174                 int vertShader = this.loadShader(GLES20.GL_VERTEX_SHADER,   vertSource);
175                 int fragShader = this.loadShader(GLES20.GL_FRAGMENT_SHADER, fragSource);
176
177                 /* Link shaders into an OpenGL program */
178                 this.program = GLES20.glCreateProgram();
179                 GLES20.glAttachShader(program, vertShader);
180                 GLES20.glAttachShader(program, fragShader);
181                 GLES20.glLinkProgram(program);
182
183                 /* Get shaders attributes */
184                 this.modelHandle = GLES20.glGetUniformLocation(program, "u_model");
185                 this.viewHandle  = GLES20.glGetUniformLocation(program, "u_view");
186                 this.projHandle  = GLES20.glGetUniformLocation(program, "u_proj");
187                 this.vertHandle  = GLES20.glGetAttribLocation(program, "a_position");
188                 this.mapHandle   = GLES20.glGetAttribLocation(program, "a_mapping");
189                 this.texHandle   = GLES20.glGetUniformLocation(program, "u_texture");
190                 this.colorHandle = GLES20.glGetUniformLocation(program, "u_color");
191
192                 /* Create vertex array  */
193                 this.vertBuf = this.loadBuffer(this.vertCoords);
194                 this.mapBuf  = this.loadBuffer(this.mapCoords);
195
196                 /* Load textures */
197                 for (int i = 0; i < 52; i++) {
198                         String name = "card_" + this.cards[i].toLowerCase();
199                         this.face[i] = this.loadTexture(name);
200                 }
201                 this.red  = this.loadTexture("card_red");
202                 this.blue = this.loadTexture("card_blue");
203
204                 /* Debug */
205                 Os.debug("Cards: onSurfaceCreate");
206         }
207
208         @Override
209         public void onDrawFrame(GL10 unused)
210         {
211                 Os.debug("Cards: onDrawFrame");
212
213                 /* Turn on the program */
214                 GLES20.glUseProgram(program);
215
216                 /* Draw */
217                 GLES20.glClearColor(0, 0, 0, 1);
218                 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
219
220                 GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
221                 GLES20.glUniformMatrix4fv(this.viewHandle, 1, false, this.view, 0);
222                 GLES20.glUniformMatrix4fv(this.projHandle, 1, false, this.proj, 0);
223
224                 GLES20.glEnableVertexAttribArray(this.vertHandle);
225                 GLES20.glEnableVertexAttribArray(this.mapHandle);
226                 GLES20.glVertexAttribPointer(this.vertHandle,  3, GLES20.GL_FLOAT, false, 3*4, this.vertBuf);
227                 GLES20.glVertexAttribPointer(this.mapHandle, 2, GLES20.GL_FLOAT, false, 2*4, this.mapBuf);
228
229                 GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
230                 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.red);
231                 GLES20.glUniform1i(this.texHandle, 0);
232
233                 GLES20.glUniform4fv(this.colorHandle, 1, this.color, 0);
234
235                 GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
236                 GLES20.glDisableVertexAttribArray(this.mapHandle);
237         }
238
239         @Override
240         public void onSurfaceChanged(GL10 unused, int width, int height)
241         {
242                 Os.debug("Cards: onSurfaceChanged");
243
244                 GLES20.glViewport(0, 0, width, height);
245
246                 Matrix.setIdentityM(this.model, 0);
247                 Matrix.setIdentityM(this.view, 0);
248                 Matrix.setIdentityM(this.proj, 0);
249
250                 // Setup camera
251                 float xang = 0.5f;
252                 float yang = xang * ((float)height / (float)width);
253
254                 Matrix.frustumM(this.proj, 0,
255                                 -1E-6f * xang, // left
256                                 1E-6f  * xang, // right
257                                 -1E-6f * yang, // bottom
258                                 1E-6f  * yang, // top
259                                 1E-6f,         // near
260                                 10f);          // far
261
262                 Matrix.translateM(this.view, 0,
263                                 0, 0, -2.0f);
264                 Matrix.rotateM(this.view, 0,
265                                 90f, 1, 0, 0);
266
267                 // Set card position
268                 Matrix.rotateM(this.view, 0,
269                                 -90f, 1, 0, 0);
270                 Matrix.translateM(this.model, 0,
271                                 0, 0, 1.5f);
272         }
273 }