]> Pileus Git - ~andy/spades/blob - src/org/pileus/spades/Cards.java
Full card texture loading plus some cleanup
[~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
18 public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
19 {
20         /* Shader data */
21         private final String vertSource
22                 = "attribute vec4 a_position;"
23                 + "attribute vec2 a_mapping;"
24                 + "varying   vec2 v_mapping;"
25                 + "void main() {"
26                 + "  gl_Position = a_position;"
27                 + "  v_mapping   = a_mapping;"
28                 + "}";
29
30         private final String fragSource
31                 = "precision mediump   float;"
32                 + "uniform   sampler2D u_texture;"
33                 + "uniform   vec4      u_color;"
34                 + "varying   vec2      v_mapping;"
35                 + "void main() {"
36                 + "  gl_FragColor = texture2D("
37                 + "    u_texture, v_mapping);"
38                 + "}";
39
40         /* Drawing data */
41         private final float  vertCoords[] = {
42                 -0.5f,  0.5f, 0.0f,
43                 -0.5f, -0.5f, 0.0f,
44                  0.5f, -0.5f, 0.0f,
45                  0.5f,  0.5f, 0.0f,
46         };
47
48         private final float  mapCoords[] = {
49                 0.0f, 0.0f,
50                 0.0f, 1.0f,
51                 1.0f, 1.0f,
52                 1.0f, 0.0f,
53         };
54
55         private final float  color[] = {
56                 1, 0, 0, 1
57         };
58
59         /* Cards data */
60         private final String cards[] = {
61                 "As", "Ks", "Qs", "Js", "10s", "9s", "8s", "7s", "6s", "5s", "4s", "3s", "2s",
62                 "Ah", "Kh", "Qh", "Jh", "10h", "9h", "8h", "7h", "6h", "5h", "4h", "3h", "2h",
63                 "Ac", "Kc", "Qc", "Jc", "10c", "9c", "8c", "7c", "6c", "5c", "4c", "3c", "2c",
64                 "Ad", "Kd", "Qd", "Jd", "10d", "9d", "8d", "7d", "6d", "5d", "4d", "3d", "2d",
65         };
66
67         /* Private data */
68         private Resources    res;         // app resources
69         private int          program;     // opengl program
70
71         private FloatBuffer  vertBuf;     // vertex position buffer
72         private FloatBuffer  mapBuf;      // texture mapping coord buffer
73
74         private int          vertHandle;  // vertex positions
75         private int          mapHandle;   // texture mapping coords
76         private int          texHandle;   // texture data
77         private int          colorHandle; // color data
78
79         private int          face[];      // card face textures
80         private int          red;         // red card back
81         private int          blue;        // blue card back
82
83         /* Private methods */
84         private int loadShader(int type, String code)
85         {
86                 Os.debug("Cards: loadShader");
87
88                 int shader = GLES20.glCreateShader(type);
89                 GLES20.glShaderSource(shader, code);
90                 GLES20.glCompileShader(shader);
91                 return shader;
92         }
93
94         private int loadTexture(String name)
95         {
96                 Os.debug("Cards: loadTexture - " + name);
97
98                 final int[] tex = new int[1];
99
100                 /* Lookup the resource ID */
101                 int id = 0;
102                 try {
103                         id = R.drawable.class.getField(name).getInt(null);
104                 } catch(Exception e) {
105                         Os.debug("Cards: lookup failed for '" + name + "'", e);
106                         return 0;
107                 }
108
109                 /* Load the bitmap */
110                 Bitmap bitmap = BitmapFactory.decodeResource(this.res, id);
111
112                 /* Copy into OpenGL */
113                 GLES20.glGenTextures(1, tex, 0);
114                 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex[0]);
115                 GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
116                 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
117                 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
118
119                 return tex[0];
120         }
121
122         private FloatBuffer loadBuffer(float[] data)
123         {
124                 ByteBuffer bytes = ByteBuffer.allocateDirect(data.length * 4);
125                 bytes.order(ByteOrder.nativeOrder());
126
127                 FloatBuffer buf = bytes.asFloatBuffer();
128                 buf.put(data);
129                 buf.position(0);
130
131                 return buf;
132         }
133
134         /* GLSurfaceView Methods */
135         public Cards(Context context)
136         {
137                 super(context);
138                 Os.debug("Cards: create");
139
140                 this.res = context.getResources();
141
142                 this.face  = new int[52];
143
144                 this.setEGLContextClientVersion(2);
145                 this.setRenderer(this);
146                 this.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
147         }
148
149         /* Renderer methods */
150         @Override
151         public void onSurfaceCreated(GL10 unused, EGLConfig config)
152         {
153                 Os.debug("Cards: onSurfaceCreate");
154
155                 /* Initialize shaders */
156                 int vertShader = this.loadShader(GLES20.GL_VERTEX_SHADER,   vertSource);
157                 int fragShader = this.loadShader(GLES20.GL_FRAGMENT_SHADER, fragSource);
158
159                 /* Link shaders into an OpenGL program */
160                 this.program = GLES20.glCreateProgram();
161                 GLES20.glAttachShader(program, vertShader);
162                 GLES20.glAttachShader(program, fragShader);
163                 GLES20.glLinkProgram(program);
164
165                 /* Get shaders attributes */
166                 this.vertHandle  = GLES20.glGetAttribLocation(program, "a_position");
167                 this.mapHandle   = GLES20.glGetAttribLocation(program, "a_mapping");
168                 this.texHandle   = GLES20.glGetUniformLocation(program, "u_texture");
169                 this.colorHandle = GLES20.glGetUniformLocation(program, "u_color");
170
171                 /* Create vertex array  */
172                 this.vertBuf = this.loadBuffer(this.vertCoords);
173                 this.mapBuf  = this.loadBuffer(this.mapCoords);
174
175                 /* Load textures */
176                 for (int i = 0; i < 52; i++) {
177                         String name = "card_" + this.cards[i].toLowerCase();
178                         this.face[i] = this.loadTexture(name);
179                 }
180                 this.red  = this.loadTexture("card_red");
181                 this.blue = this.loadTexture("card_blue");
182
183                 /* Debug */
184                 Os.debug("Cards: onSurfaceCreate");
185         }
186
187         @Override
188         public void onDrawFrame(GL10 unused)
189         {
190                 Os.debug("Cards: onDrawFrame");
191
192                 /* Turn on the program */
193                 GLES20.glUseProgram(program);
194
195                 /* Draw */
196                 GLES20.glClearColor(0, 0, 0, 1);
197                 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
198
199                 GLES20.glEnableVertexAttribArray(this.vertHandle);
200                 GLES20.glEnableVertexAttribArray(this.mapHandle);
201                 GLES20.glVertexAttribPointer(this.vertHandle,  3, GLES20.GL_FLOAT, false, 3*4, this.vertBuf);
202                 GLES20.glVertexAttribPointer(this.mapHandle, 2, GLES20.GL_FLOAT, false, 2*4, this.mapBuf);
203
204                 GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
205                 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.red);
206                 GLES20.glUniform1i(this.texHandle, 0);
207
208                 GLES20.glUniform4fv(this.colorHandle, 1, this.color, 0);
209
210                 GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
211                 GLES20.glDisableVertexAttribArray(this.mapHandle);
212         }
213
214         @Override
215         public void onSurfaceChanged(GL10 unused, int width, int height)
216         {
217                 Os.debug("Cards: onSurfaceChanged");
218
219                 GLES20.glViewport(0, 0, width, height);
220         }
221 }