1cfd74d65d832137e20e193c960802afba73b5d38sm/*
23c1e67e433728684b5f228c5d4f3e5b1457bb271sm * Copyright (C) 2010 The Android Open Source Project
3cfd74d65d832137e20e193c960802afba73b5d38sm *
4cfd74d65d832137e20e193c960802afba73b5d38sm * Licensed under the Apache License, Version 2.0 (the "License");
5cfd74d65d832137e20e193c960802afba73b5d38sm * you may not use this file except in compliance with the License.
6cfd74d65d832137e20e193c960802afba73b5d38sm * You may obtain a copy of the License at
7cfd74d65d832137e20e193c960802afba73b5d38sm *
8cfd74d65d832137e20e193c960802afba73b5d38sm *      http://www.apache.org/licenses/LICENSE-2.0
9cfd74d65d832137e20e193c960802afba73b5d38sm *
10cfd74d65d832137e20e193c960802afba73b5d38sm * Unless required by applicable law or agreed to in writing, software
11cfd74d65d832137e20e193c960802afba73b5d38sm * distributed under the License is distributed on an "AS IS" BASIS,
12cfd74d65d832137e20e193c960802afba73b5d38sm * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cfd74d65d832137e20e193c960802afba73b5d38sm * See the License for the specific language governing permissions and
14cfd74d65d832137e20e193c960802afba73b5d38sm * limitations under the License.
15cfd74d65d832137e20e193c960802afba73b5d38sm */
16cfd74d65d832137e20e193c960802afba73b5d38sm
17cfd74d65d832137e20e193c960802afba73b5d38smpackage com.replica.replicaisland;
18cfd74d65d832137e20e193c960802afba73b5d38sm
19cfd74d65d832137e20e193c960802afba73b5d38smimport java.nio.Buffer;
20cfd74d65d832137e20e193c960802afba73b5d38smimport java.nio.ByteBuffer;
21cfd74d65d832137e20e193c960802afba73b5d38smimport java.nio.ByteOrder;
22cfd74d65d832137e20e193c960802afba73b5d38smimport java.nio.CharBuffer;
23cfd74d65d832137e20e193c960802afba73b5d38smimport java.nio.FloatBuffer;
24cfd74d65d832137e20e193c960802afba73b5d38smimport java.nio.IntBuffer;
25cfd74d65d832137e20e193c960802afba73b5d38sm
26cfd74d65d832137e20e193c960802afba73b5d38smimport javax.microedition.khronos.opengles.GL10;
27cfd74d65d832137e20e193c960802afba73b5d38smimport javax.microedition.khronos.opengles.GL11;
28cfd74d65d832137e20e193c960802afba73b5d38sm
296cb78e547641bcab6f18ec34badca0840e000992Keun young Parkimport android.util.Log;
306cb78e547641bcab6f18ec34badca0840e000992Keun young Park
31cfd74d65d832137e20e193c960802afba73b5d38sm/**
32cfd74d65d832137e20e193c960802afba73b5d38sm * A 2D rectangular mesh. Can be drawn textured or untextured.
33cfd74d65d832137e20e193c960802afba73b5d38sm * This version is modified from the original Grid.java (found in
34cfd74d65d832137e20e193c960802afba73b5d38sm * the SpriteText package in the APIDemos Android sample) to support hardware
35cfd74d65d832137e20e193c960802afba73b5d38sm * vertex buffers and to insert edges between grid squares for tiling.
36cfd74d65d832137e20e193c960802afba73b5d38sm */
37cfd74d65d832137e20e193c960802afba73b5d38smclass Grid {
38cfd74d65d832137e20e193c960802afba73b5d38sm	private static final int FLOAT_SIZE = 4;
39cfd74d65d832137e20e193c960802afba73b5d38sm	private static final int FIXED_SIZE = 4;
40cfd74d65d832137e20e193c960802afba73b5d38sm	private static final int CHAR_SIZE = 2;
41cfd74d65d832137e20e193c960802afba73b5d38sm
42cfd74d65d832137e20e193c960802afba73b5d38sm    private FloatBuffer mFloatVertexBuffer;
43cfd74d65d832137e20e193c960802afba73b5d38sm    private FloatBuffer mFloatTexCoordBuffer;
44cfd74d65d832137e20e193c960802afba73b5d38sm    private IntBuffer mFixedVertexBuffer;
45cfd74d65d832137e20e193c960802afba73b5d38sm    private IntBuffer mFixedTexCoordBuffer;
46cfd74d65d832137e20e193c960802afba73b5d38sm    private CharBuffer mIndexBuffer;
47cfd74d65d832137e20e193c960802afba73b5d38sm
48cfd74d65d832137e20e193c960802afba73b5d38sm    private Buffer mVertexBuffer;
49cfd74d65d832137e20e193c960802afba73b5d38sm    private Buffer mTexCoordBuffer;
50cfd74d65d832137e20e193c960802afba73b5d38sm    private int mCoordinateSize;
51cfd74d65d832137e20e193c960802afba73b5d38sm    private int mCoordinateType;
52cfd74d65d832137e20e193c960802afba73b5d38sm
53cfd74d65d832137e20e193c960802afba73b5d38sm    private int mVertsAcross;
54cfd74d65d832137e20e193c960802afba73b5d38sm    private int mVertsDown;
55cfd74d65d832137e20e193c960802afba73b5d38sm    private int mIndexCount;
56cfd74d65d832137e20e193c960802afba73b5d38sm    private boolean mUseHardwareBuffers;
57cfd74d65d832137e20e193c960802afba73b5d38sm    private int mVertBufferIndex;
58cfd74d65d832137e20e193c960802afba73b5d38sm    private int mIndexBufferIndex;
59cfd74d65d832137e20e193c960802afba73b5d38sm    private int mTextureCoordBufferIndex;
60cfd74d65d832137e20e193c960802afba73b5d38sm
61cfd74d65d832137e20e193c960802afba73b5d38sm    public Grid(int quadsAcross, int quadsDown, boolean useFixedPoint) {
62cfd74d65d832137e20e193c960802afba73b5d38sm    	final int vertsAcross = quadsAcross * 2;
63cfd74d65d832137e20e193c960802afba73b5d38sm    	final int vertsDown = quadsDown * 2;
64cfd74d65d832137e20e193c960802afba73b5d38sm        if (vertsAcross < 0 || vertsAcross >= 65536) {
65cfd74d65d832137e20e193c960802afba73b5d38sm            throw new IllegalArgumentException("quadsAcross");
66cfd74d65d832137e20e193c960802afba73b5d38sm        }
67cfd74d65d832137e20e193c960802afba73b5d38sm        if (vertsDown < 0 || vertsDown >= 65536) {
68cfd74d65d832137e20e193c960802afba73b5d38sm            throw new IllegalArgumentException("quadsDown");
69cfd74d65d832137e20e193c960802afba73b5d38sm        }
70cfd74d65d832137e20e193c960802afba73b5d38sm        if (vertsAcross * vertsDown >= 65536) {
71cfd74d65d832137e20e193c960802afba73b5d38sm            throw new IllegalArgumentException("quadsAcross * quadsDown >= 32768");
72cfd74d65d832137e20e193c960802afba73b5d38sm        }
73cfd74d65d832137e20e193c960802afba73b5d38sm
74cfd74d65d832137e20e193c960802afba73b5d38sm        mUseHardwareBuffers = false;
75cfd74d65d832137e20e193c960802afba73b5d38sm
76cfd74d65d832137e20e193c960802afba73b5d38sm        mVertsAcross = vertsAcross;
77cfd74d65d832137e20e193c960802afba73b5d38sm        mVertsDown = vertsDown;
78cfd74d65d832137e20e193c960802afba73b5d38sm        int size = vertsAcross * vertsDown;
79cfd74d65d832137e20e193c960802afba73b5d38sm
80cfd74d65d832137e20e193c960802afba73b5d38sm
81cfd74d65d832137e20e193c960802afba73b5d38sm        if (useFixedPoint) {
82cfd74d65d832137e20e193c960802afba73b5d38sm        	mFixedVertexBuffer = ByteBuffer.allocateDirect(FIXED_SIZE * size * 3)
83cfd74d65d832137e20e193c960802afba73b5d38sm            	.order(ByteOrder.nativeOrder()).asIntBuffer();
84cfd74d65d832137e20e193c960802afba73b5d38sm        	mFixedTexCoordBuffer = ByteBuffer.allocateDirect(FIXED_SIZE * size * 2)
85cfd74d65d832137e20e193c960802afba73b5d38sm            	.order(ByteOrder.nativeOrder()).asIntBuffer();
86cfd74d65d832137e20e193c960802afba73b5d38sm
87cfd74d65d832137e20e193c960802afba73b5d38sm        	mVertexBuffer = mFixedVertexBuffer;
88cfd74d65d832137e20e193c960802afba73b5d38sm        	mTexCoordBuffer = mFixedTexCoordBuffer;
89cfd74d65d832137e20e193c960802afba73b5d38sm        	mCoordinateSize = FIXED_SIZE;
90cfd74d65d832137e20e193c960802afba73b5d38sm        	mCoordinateType = GL10.GL_FIXED;
91cfd74d65d832137e20e193c960802afba73b5d38sm
92cfd74d65d832137e20e193c960802afba73b5d38sm        } else {
93cfd74d65d832137e20e193c960802afba73b5d38sm        	mFloatVertexBuffer = ByteBuffer.allocateDirect(FLOAT_SIZE * size * 3)
94cfd74d65d832137e20e193c960802afba73b5d38sm            	.order(ByteOrder.nativeOrder()).asFloatBuffer();
95cfd74d65d832137e20e193c960802afba73b5d38sm        	mFloatTexCoordBuffer = ByteBuffer.allocateDirect(FLOAT_SIZE * size * 2)
96cfd74d65d832137e20e193c960802afba73b5d38sm            	.order(ByteOrder.nativeOrder()).asFloatBuffer();
97cfd74d65d832137e20e193c960802afba73b5d38sm
98cfd74d65d832137e20e193c960802afba73b5d38sm        	mVertexBuffer = mFloatVertexBuffer;
99cfd74d65d832137e20e193c960802afba73b5d38sm        	mTexCoordBuffer = mFloatTexCoordBuffer;
100cfd74d65d832137e20e193c960802afba73b5d38sm        	mCoordinateSize = FLOAT_SIZE;
101cfd74d65d832137e20e193c960802afba73b5d38sm        	mCoordinateType = GL10.GL_FLOAT;
102cfd74d65d832137e20e193c960802afba73b5d38sm        }
103cfd74d65d832137e20e193c960802afba73b5d38sm
104cfd74d65d832137e20e193c960802afba73b5d38sm
105cfd74d65d832137e20e193c960802afba73b5d38sm
106cfd74d65d832137e20e193c960802afba73b5d38sm
107cfd74d65d832137e20e193c960802afba73b5d38sm        int quadCount = quadsAcross * quadsDown;
108cfd74d65d832137e20e193c960802afba73b5d38sm        int indexCount = quadCount * 6;
109cfd74d65d832137e20e193c960802afba73b5d38sm        mIndexCount = indexCount;
110cfd74d65d832137e20e193c960802afba73b5d38sm        mIndexBuffer = ByteBuffer.allocateDirect(CHAR_SIZE * indexCount)
111cfd74d65d832137e20e193c960802afba73b5d38sm            .order(ByteOrder.nativeOrder()).asCharBuffer();
112cfd74d65d832137e20e193c960802afba73b5d38sm
113cfd74d65d832137e20e193c960802afba73b5d38sm        /*
114cfd74d65d832137e20e193c960802afba73b5d38sm         * Initialize triangle list mesh.
115cfd74d65d832137e20e193c960802afba73b5d38sm         *
116cfd74d65d832137e20e193c960802afba73b5d38sm         *     [0]------[1]   [2]------[3] ...
117cfd74d65d832137e20e193c960802afba73b5d38sm         *      |    /   |     |    /   |
118cfd74d65d832137e20e193c960802afba73b5d38sm         *      |   /    |     |   /    |
119cfd74d65d832137e20e193c960802afba73b5d38sm         *      |  /     |     |  /     |
120cfd74d65d832137e20e193c960802afba73b5d38sm         *     [w]-----[w+1] [w+2]----[w+3]...
121cfd74d65d832137e20e193c960802afba73b5d38sm         *      |       |
122cfd74d65d832137e20e193c960802afba73b5d38sm         *
123cfd74d65d832137e20e193c960802afba73b5d38sm         */
124cfd74d65d832137e20e193c960802afba73b5d38sm
125cfd74d65d832137e20e193c960802afba73b5d38sm        {
126cfd74d65d832137e20e193c960802afba73b5d38sm            int i = 0;
127cfd74d65d832137e20e193c960802afba73b5d38sm            for (int y = 0; y < quadsDown; y++) {
128cfd74d65d832137e20e193c960802afba73b5d38sm            	final int indexY = y * 2;
129cfd74d65d832137e20e193c960802afba73b5d38sm                for (int x = 0; x < quadsAcross; x++) {
130cfd74d65d832137e20e193c960802afba73b5d38sm                	final int indexX = x * 2;
131cfd74d65d832137e20e193c960802afba73b5d38sm                    char a = (char) (indexY * mVertsAcross + indexX);
132cfd74d65d832137e20e193c960802afba73b5d38sm                    char b = (char) (indexY * mVertsAcross + indexX + 1);
133cfd74d65d832137e20e193c960802afba73b5d38sm                    char c = (char) ((indexY + 1) * mVertsAcross + indexX);
134cfd74d65d832137e20e193c960802afba73b5d38sm                    char d = (char) ((indexY + 1) * mVertsAcross + indexX + 1);
135cfd74d65d832137e20e193c960802afba73b5d38sm
136cfd74d65d832137e20e193c960802afba73b5d38sm                    mIndexBuffer.put(i++, a);
137cfd74d65d832137e20e193c960802afba73b5d38sm                    mIndexBuffer.put(i++, b);
138cfd74d65d832137e20e193c960802afba73b5d38sm                    mIndexBuffer.put(i++, c);
139cfd74d65d832137e20e193c960802afba73b5d38sm
140cfd74d65d832137e20e193c960802afba73b5d38sm                    mIndexBuffer.put(i++, b);
141cfd74d65d832137e20e193c960802afba73b5d38sm                    mIndexBuffer.put(i++, c);
142cfd74d65d832137e20e193c960802afba73b5d38sm                    mIndexBuffer.put(i++, d);
143cfd74d65d832137e20e193c960802afba73b5d38sm                }
144cfd74d65d832137e20e193c960802afba73b5d38sm            }
145cfd74d65d832137e20e193c960802afba73b5d38sm        }
146cfd74d65d832137e20e193c960802afba73b5d38sm
147cfd74d65d832137e20e193c960802afba73b5d38sm        mVertBufferIndex = 0;
148cfd74d65d832137e20e193c960802afba73b5d38sm    }
149cfd74d65d832137e20e193c960802afba73b5d38sm
150cfd74d65d832137e20e193c960802afba73b5d38sm    public void set(int quadX, int quadY, float[][] positions, float[][] uvs) {
151cfd74d65d832137e20e193c960802afba73b5d38sm        if (quadX < 0 || quadX * 2 >= mVertsAcross) {
152cfd74d65d832137e20e193c960802afba73b5d38sm            throw new IllegalArgumentException("quadX");
153cfd74d65d832137e20e193c960802afba73b5d38sm        }
154cfd74d65d832137e20e193c960802afba73b5d38sm        if (quadY < 0 || quadY * 2 >= mVertsDown) {
155cfd74d65d832137e20e193c960802afba73b5d38sm            throw new IllegalArgumentException("quadY");
156cfd74d65d832137e20e193c960802afba73b5d38sm        }
157cfd74d65d832137e20e193c960802afba73b5d38sm        if (positions.length < 4) {
158cfd74d65d832137e20e193c960802afba73b5d38sm            throw new IllegalArgumentException("positions");
159cfd74d65d832137e20e193c960802afba73b5d38sm        }
160cfd74d65d832137e20e193c960802afba73b5d38sm        if (uvs.length < 4) {
161cfd74d65d832137e20e193c960802afba73b5d38sm            throw new IllegalArgumentException("quadY");
162cfd74d65d832137e20e193c960802afba73b5d38sm        }
163cfd74d65d832137e20e193c960802afba73b5d38sm
164cfd74d65d832137e20e193c960802afba73b5d38sm        int i = quadX * 2;
165cfd74d65d832137e20e193c960802afba73b5d38sm        int j = quadY * 2;
166cfd74d65d832137e20e193c960802afba73b5d38sm
167cfd74d65d832137e20e193c960802afba73b5d38sm        setVertex(i, j, 		positions[0][0], positions[0][1], positions[0][2], uvs[0][0], uvs[0][1]);
168cfd74d65d832137e20e193c960802afba73b5d38sm        setVertex(i + 1, j, 	positions[1][0], positions[1][1], positions[1][2], uvs[1][0], uvs[1][1]);
169cfd74d65d832137e20e193c960802afba73b5d38sm        setVertex(i, j + 1, 	positions[2][0], positions[2][1], positions[2][2], uvs[2][0], uvs[2][1]);
170cfd74d65d832137e20e193c960802afba73b5d38sm        setVertex(i + 1, j + 1, positions[3][0], positions[3][1], positions[3][2], uvs[3][0], uvs[3][1]);
171cfd74d65d832137e20e193c960802afba73b5d38sm    }
172cfd74d65d832137e20e193c960802afba73b5d38sm
173cfd74d65d832137e20e193c960802afba73b5d38sm
174cfd74d65d832137e20e193c960802afba73b5d38sm    private void setVertex(int i, int j, float x, float y, float z, float u, float v) {
175cfd74d65d832137e20e193c960802afba73b5d38sm	  if (i < 0 || i >= mVertsAcross) {
176cfd74d65d832137e20e193c960802afba73b5d38sm	       throw new IllegalArgumentException("i");
177cfd74d65d832137e20e193c960802afba73b5d38sm	   }
178cfd74d65d832137e20e193c960802afba73b5d38sm	   if (j < 0 || j >= mVertsDown) {
179cfd74d65d832137e20e193c960802afba73b5d38sm	       throw new IllegalArgumentException("j");
180cfd74d65d832137e20e193c960802afba73b5d38sm	   }
181cfd74d65d832137e20e193c960802afba73b5d38sm
182cfd74d65d832137e20e193c960802afba73b5d38sm	   final int index = mVertsAcross * j + i;
183cfd74d65d832137e20e193c960802afba73b5d38sm
184cfd74d65d832137e20e193c960802afba73b5d38sm	   final int posIndex = index * 3;
185cfd74d65d832137e20e193c960802afba73b5d38sm	   final int texIndex = index * 2;
186cfd74d65d832137e20e193c960802afba73b5d38sm
187cfd74d65d832137e20e193c960802afba73b5d38sm
188cfd74d65d832137e20e193c960802afba73b5d38sm	   if (mCoordinateType == GL10.GL_FLOAT) {
189cfd74d65d832137e20e193c960802afba73b5d38sm	    mFloatVertexBuffer.put(posIndex, x);
190cfd74d65d832137e20e193c960802afba73b5d38sm	    mFloatVertexBuffer.put(posIndex + 1, y);
191cfd74d65d832137e20e193c960802afba73b5d38sm	    mFloatVertexBuffer.put(posIndex + 2, z);
192cfd74d65d832137e20e193c960802afba73b5d38sm
193cfd74d65d832137e20e193c960802afba73b5d38sm	    mFloatTexCoordBuffer.put(texIndex, u);
194cfd74d65d832137e20e193c960802afba73b5d38sm	    mFloatTexCoordBuffer.put(texIndex + 1, v);
195cfd74d65d832137e20e193c960802afba73b5d38sm	   } else {
196cfd74d65d832137e20e193c960802afba73b5d38sm	    mFixedVertexBuffer.put(posIndex, (int)(x * (1 << 16)));
197cfd74d65d832137e20e193c960802afba73b5d38sm	    mFixedVertexBuffer.put(posIndex + 1, (int)(y * (1 << 16)));
198cfd74d65d832137e20e193c960802afba73b5d38sm	    mFixedVertexBuffer.put(posIndex + 2, (int)(z * (1 << 16)));
199cfd74d65d832137e20e193c960802afba73b5d38sm
200cfd74d65d832137e20e193c960802afba73b5d38sm	    mFixedTexCoordBuffer.put(texIndex, (int)(u * (1 << 16)));
201cfd74d65d832137e20e193c960802afba73b5d38sm	    mFixedTexCoordBuffer.put(texIndex + 1, (int)(v * (1 << 16)));
202cfd74d65d832137e20e193c960802afba73b5d38sm	   }
203cfd74d65d832137e20e193c960802afba73b5d38sm	}
204cfd74d65d832137e20e193c960802afba73b5d38sm
205cfd74d65d832137e20e193c960802afba73b5d38sm    public static void beginDrawing(GL10 gl, boolean useTexture) {
206cfd74d65d832137e20e193c960802afba73b5d38sm        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
207cfd74d65d832137e20e193c960802afba73b5d38sm
208cfd74d65d832137e20e193c960802afba73b5d38sm        if (useTexture) {
209cfd74d65d832137e20e193c960802afba73b5d38sm            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
210cfd74d65d832137e20e193c960802afba73b5d38sm            gl.glEnable(GL10.GL_TEXTURE_2D);
211cfd74d65d832137e20e193c960802afba73b5d38sm        } else {
212cfd74d65d832137e20e193c960802afba73b5d38sm            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
213cfd74d65d832137e20e193c960802afba73b5d38sm            gl.glDisable(GL10.GL_TEXTURE_2D);
214cfd74d65d832137e20e193c960802afba73b5d38sm        }
215cfd74d65d832137e20e193c960802afba73b5d38sm    }
216cfd74d65d832137e20e193c960802afba73b5d38sm
217cfd74d65d832137e20e193c960802afba73b5d38sm    public void beginDrawingStrips(GL10 gl, boolean useTexture) {
218cfd74d65d832137e20e193c960802afba73b5d38sm        beginDrawing(gl, useTexture);
219cfd74d65d832137e20e193c960802afba73b5d38sm        if (!mUseHardwareBuffers) {
220cfd74d65d832137e20e193c960802afba73b5d38sm            gl.glVertexPointer(3, mCoordinateType, 0, mVertexBuffer);
221cfd74d65d832137e20e193c960802afba73b5d38sm
222cfd74d65d832137e20e193c960802afba73b5d38sm            if (useTexture) {
223cfd74d65d832137e20e193c960802afba73b5d38sm                gl.glTexCoordPointer(2, mCoordinateType, 0, mTexCoordBuffer);
224cfd74d65d832137e20e193c960802afba73b5d38sm            }
225cfd74d65d832137e20e193c960802afba73b5d38sm
226cfd74d65d832137e20e193c960802afba73b5d38sm        } else {
227cfd74d65d832137e20e193c960802afba73b5d38sm            GL11 gl11 = (GL11)gl;
228cfd74d65d832137e20e193c960802afba73b5d38sm            // draw using hardware buffers
229cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertBufferIndex);
230cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glVertexPointer(3, mCoordinateType, 0, 0);
231cfd74d65d832137e20e193c960802afba73b5d38sm
232cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mTextureCoordBufferIndex);
233cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glTexCoordPointer(2, mCoordinateType, 0, 0);
234cfd74d65d832137e20e193c960802afba73b5d38sm
235cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBufferIndex);
236cfd74d65d832137e20e193c960802afba73b5d38sm        }
237cfd74d65d832137e20e193c960802afba73b5d38sm    }
238cfd74d65d832137e20e193c960802afba73b5d38sm
239cfd74d65d832137e20e193c960802afba73b5d38sm    // Assumes beginDrawingStrips() has been called before this.
240cfd74d65d832137e20e193c960802afba73b5d38sm    public void drawStrip(GL10 gl, boolean useTexture, int startIndex, int indexCount) {
241cfd74d65d832137e20e193c960802afba73b5d38sm    	int count = indexCount;
242cfd74d65d832137e20e193c960802afba73b5d38sm    	if (startIndex + indexCount >= mIndexCount) {
243cfd74d65d832137e20e193c960802afba73b5d38sm    		count = mIndexCount - startIndex;
244cfd74d65d832137e20e193c960802afba73b5d38sm    	}
245cfd74d65d832137e20e193c960802afba73b5d38sm    	if (!mUseHardwareBuffers) {
246cfd74d65d832137e20e193c960802afba73b5d38sm            gl.glDrawElements(GL10.GL_TRIANGLES, count,
247cfd74d65d832137e20e193c960802afba73b5d38sm                    GL10.GL_UNSIGNED_SHORT, mIndexBuffer.position(startIndex));
248cfd74d65d832137e20e193c960802afba73b5d38sm        } else {
249cfd74d65d832137e20e193c960802afba73b5d38sm        	GL11 gl11 = (GL11)gl;
250cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glDrawElements(GL11.GL_TRIANGLES, count,
251cfd74d65d832137e20e193c960802afba73b5d38sm                    GL11.GL_UNSIGNED_SHORT, startIndex * CHAR_SIZE);
252cfd74d65d832137e20e193c960802afba73b5d38sm
253cfd74d65d832137e20e193c960802afba73b5d38sm        }
254cfd74d65d832137e20e193c960802afba73b5d38sm    }
255cfd74d65d832137e20e193c960802afba73b5d38sm
256cfd74d65d832137e20e193c960802afba73b5d38sm    public void draw(GL10 gl, boolean useTexture) {
257cfd74d65d832137e20e193c960802afba73b5d38sm        if (!mUseHardwareBuffers) {
258cfd74d65d832137e20e193c960802afba73b5d38sm            gl.glVertexPointer(3, mCoordinateType, 0, mVertexBuffer);
259cfd74d65d832137e20e193c960802afba73b5d38sm
260cfd74d65d832137e20e193c960802afba73b5d38sm            if (useTexture) {
261cfd74d65d832137e20e193c960802afba73b5d38sm                gl.glTexCoordPointer(2, mCoordinateType, 0, mTexCoordBuffer);
262cfd74d65d832137e20e193c960802afba73b5d38sm            }
263cfd74d65d832137e20e193c960802afba73b5d38sm
264cfd74d65d832137e20e193c960802afba73b5d38sm            gl.glDrawElements(GL10.GL_TRIANGLES, mIndexCount,
265cfd74d65d832137e20e193c960802afba73b5d38sm                    GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
266cfd74d65d832137e20e193c960802afba73b5d38sm        } else {
267cfd74d65d832137e20e193c960802afba73b5d38sm            GL11 gl11 = (GL11)gl;
268cfd74d65d832137e20e193c960802afba73b5d38sm            // draw using hardware buffers
269cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertBufferIndex);
270cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glVertexPointer(3, mCoordinateType, 0, 0);
271cfd74d65d832137e20e193c960802afba73b5d38sm
272cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mTextureCoordBufferIndex);
273cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glTexCoordPointer(2, mCoordinateType, 0, 0);
274cfd74d65d832137e20e193c960802afba73b5d38sm
275cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBufferIndex);
276cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glDrawElements(GL11.GL_TRIANGLES, mIndexCount,
277cfd74d65d832137e20e193c960802afba73b5d38sm                    GL11.GL_UNSIGNED_SHORT, 0);
278cfd74d65d832137e20e193c960802afba73b5d38sm
279cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
280cfd74d65d832137e20e193c960802afba73b5d38sm            gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);
281cfd74d65d832137e20e193c960802afba73b5d38sm
282cfd74d65d832137e20e193c960802afba73b5d38sm
283cfd74d65d832137e20e193c960802afba73b5d38sm        }
284cfd74d65d832137e20e193c960802afba73b5d38sm    }
285cfd74d65d832137e20e193c960802afba73b5d38sm
286cfd74d65d832137e20e193c960802afba73b5d38sm    public static void endDrawing(GL10 gl) {
287cfd74d65d832137e20e193c960802afba73b5d38sm        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
288cfd74d65d832137e20e193c960802afba73b5d38sm    }
289cfd74d65d832137e20e193c960802afba73b5d38sm
290cfd74d65d832137e20e193c960802afba73b5d38sm    public boolean usingHardwareBuffers() {
291cfd74d65d832137e20e193c960802afba73b5d38sm        return mUseHardwareBuffers;
292cfd74d65d832137e20e193c960802afba73b5d38sm    }
293cfd74d65d832137e20e193c960802afba73b5d38sm
294cfd74d65d832137e20e193c960802afba73b5d38sm    /**
295cfd74d65d832137e20e193c960802afba73b5d38sm     * When the OpenGL ES device is lost, GL handles become invalidated.
296cfd74d65d832137e20e193c960802afba73b5d38sm     * In that case, we just want to "forget" the old handles (without
297cfd74d65d832137e20e193c960802afba73b5d38sm     * explicitly deleting them) and make new ones.
298cfd74d65d832137e20e193c960802afba73b5d38sm     */
299cfd74d65d832137e20e193c960802afba73b5d38sm    public void invalidateHardwareBuffers() {
300cfd74d65d832137e20e193c960802afba73b5d38sm        mVertBufferIndex = 0;
301cfd74d65d832137e20e193c960802afba73b5d38sm        mIndexBufferIndex = 0;
302cfd74d65d832137e20e193c960802afba73b5d38sm        mTextureCoordBufferIndex = 0;
303cfd74d65d832137e20e193c960802afba73b5d38sm        mUseHardwareBuffers = false;
304cfd74d65d832137e20e193c960802afba73b5d38sm    }
305cfd74d65d832137e20e193c960802afba73b5d38sm
306cfd74d65d832137e20e193c960802afba73b5d38sm    /**
307cfd74d65d832137e20e193c960802afba73b5d38sm     * Deletes the hardware buffers allocated by this object (if any).
308cfd74d65d832137e20e193c960802afba73b5d38sm     */
309cfd74d65d832137e20e193c960802afba73b5d38sm    public void releaseHardwareBuffers(GL10 gl) {
310cfd74d65d832137e20e193c960802afba73b5d38sm        if (mUseHardwareBuffers) {
311cfd74d65d832137e20e193c960802afba73b5d38sm            if (gl instanceof GL11) {
312cfd74d65d832137e20e193c960802afba73b5d38sm                GL11 gl11 = (GL11)gl;
313cfd74d65d832137e20e193c960802afba73b5d38sm                int[] buffer = new int[1];
314cfd74d65d832137e20e193c960802afba73b5d38sm                buffer[0] = mVertBufferIndex;
315cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glDeleteBuffers(1, buffer, 0);
316cfd74d65d832137e20e193c960802afba73b5d38sm
317cfd74d65d832137e20e193c960802afba73b5d38sm                buffer[0] = mTextureCoordBufferIndex;
318cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glDeleteBuffers(1, buffer, 0);
319cfd74d65d832137e20e193c960802afba73b5d38sm
320cfd74d65d832137e20e193c960802afba73b5d38sm                buffer[0] = mIndexBufferIndex;
321cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glDeleteBuffers(1, buffer, 0);
322cfd74d65d832137e20e193c960802afba73b5d38sm            }
323cfd74d65d832137e20e193c960802afba73b5d38sm
324cfd74d65d832137e20e193c960802afba73b5d38sm            invalidateHardwareBuffers();
325cfd74d65d832137e20e193c960802afba73b5d38sm        }
326cfd74d65d832137e20e193c960802afba73b5d38sm    }
327cfd74d65d832137e20e193c960802afba73b5d38sm
328cfd74d65d832137e20e193c960802afba73b5d38sm    /**
329cfd74d65d832137e20e193c960802afba73b5d38sm     * Allocates hardware buffers on the graphics card and fills them with
330cfd74d65d832137e20e193c960802afba73b5d38sm     * data if a buffer has not already been previously allocated.  Note that
331cfd74d65d832137e20e193c960802afba73b5d38sm     * this function uses the GL_OES_vertex_buffer_object extension, which is
332cfd74d65d832137e20e193c960802afba73b5d38sm     * not guaranteed to be supported on every device.
333cfd74d65d832137e20e193c960802afba73b5d38sm     * @param gl  A pointer to the OpenGL ES context.
334cfd74d65d832137e20e193c960802afba73b5d38sm     */
335cfd74d65d832137e20e193c960802afba73b5d38sm    public void generateHardwareBuffers(GL10 gl) {
336cfd74d65d832137e20e193c960802afba73b5d38sm        if (!mUseHardwareBuffers) {
337cfd74d65d832137e20e193c960802afba73b5d38sm        	DebugLog.i("Grid", "Using Hardware Buffers");
338cfd74d65d832137e20e193c960802afba73b5d38sm            if (gl instanceof GL11) {
339cfd74d65d832137e20e193c960802afba73b5d38sm                GL11 gl11 = (GL11)gl;
340cfd74d65d832137e20e193c960802afba73b5d38sm                int[] buffer = new int[1];
341cfd74d65d832137e20e193c960802afba73b5d38sm
342cfd74d65d832137e20e193c960802afba73b5d38sm                // Allocate and fill the vertex buffer.
343cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glGenBuffers(1, buffer, 0);
344cfd74d65d832137e20e193c960802afba73b5d38sm                mVertBufferIndex = buffer[0];
345cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertBufferIndex);
3466cb78e547641bcab6f18ec34badca0840e000992Keun young Park                final int vertexSize = mVertexBuffer.capacity() * mCoordinateSize;
3476cb78e547641bcab6f18ec34badca0840e000992Keun young Park                // too fast task switching leaves buffers in the middle pos which
3486cb78e547641bcab6f18ec34badca0840e000992Keun young Park                // crashes app
3496cb78e547641bcab6f18ec34badca0840e000992Keun young Park                mVertexBuffer.position(0);
350cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glBufferData(GL11.GL_ARRAY_BUFFER, vertexSize,
351cfd74d65d832137e20e193c960802afba73b5d38sm                        mVertexBuffer, GL11.GL_STATIC_DRAW);
352cfd74d65d832137e20e193c960802afba73b5d38sm
353cfd74d65d832137e20e193c960802afba73b5d38sm                // Allocate and fill the texture coordinate buffer.
354cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glGenBuffers(1, buffer, 0);
355cfd74d65d832137e20e193c960802afba73b5d38sm                mTextureCoordBufferIndex = buffer[0];
356cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER,
357cfd74d65d832137e20e193c960802afba73b5d38sm                        mTextureCoordBufferIndex);
358cfd74d65d832137e20e193c960802afba73b5d38sm                final int texCoordSize =
359cfd74d65d832137e20e193c960802afba73b5d38sm                    mTexCoordBuffer.capacity() * mCoordinateSize;
3606cb78e547641bcab6f18ec34badca0840e000992Keun young Park                mTexCoordBuffer.position(0);
361cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glBufferData(GL11.GL_ARRAY_BUFFER, texCoordSize,
362cfd74d65d832137e20e193c960802afba73b5d38sm                        mTexCoordBuffer, GL11.GL_STATIC_DRAW);
363cfd74d65d832137e20e193c960802afba73b5d38sm
364cfd74d65d832137e20e193c960802afba73b5d38sm                // Unbind the array buffer.
365cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
366cfd74d65d832137e20e193c960802afba73b5d38sm
367cfd74d65d832137e20e193c960802afba73b5d38sm                // Allocate and fill the index buffer.
368cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glGenBuffers(1, buffer, 0);
369cfd74d65d832137e20e193c960802afba73b5d38sm                mIndexBufferIndex = buffer[0];
370cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER,
371cfd74d65d832137e20e193c960802afba73b5d38sm                        mIndexBufferIndex);
372cfd74d65d832137e20e193c960802afba73b5d38sm                // A char is 2 bytes.
373cfd74d65d832137e20e193c960802afba73b5d38sm                final int indexSize = mIndexBuffer.capacity() * 2;
3746cb78e547641bcab6f18ec34badca0840e000992Keun young Park
3756cb78e547641bcab6f18ec34badca0840e000992Keun young Park                mIndexBuffer.position(0);
376cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER, indexSize, mIndexBuffer,
377cfd74d65d832137e20e193c960802afba73b5d38sm                        GL11.GL_STATIC_DRAW);
378cfd74d65d832137e20e193c960802afba73b5d38sm
379cfd74d65d832137e20e193c960802afba73b5d38sm                // Unbind the element array buffer.
380cfd74d65d832137e20e193c960802afba73b5d38sm                gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);
381cfd74d65d832137e20e193c960802afba73b5d38sm
382cfd74d65d832137e20e193c960802afba73b5d38sm                mUseHardwareBuffers = true;
383cfd74d65d832137e20e193c960802afba73b5d38sm
384cfd74d65d832137e20e193c960802afba73b5d38sm                assert mVertBufferIndex != 0;
385cfd74d65d832137e20e193c960802afba73b5d38sm                assert mTextureCoordBufferIndex != 0;
386cfd74d65d832137e20e193c960802afba73b5d38sm                assert mIndexBufferIndex != 0;
387cfd74d65d832137e20e193c960802afba73b5d38sm                assert gl11.glGetError() == 0;
388cfd74d65d832137e20e193c960802afba73b5d38sm
389cfd74d65d832137e20e193c960802afba73b5d38sm
390cfd74d65d832137e20e193c960802afba73b5d38sm            }
391cfd74d65d832137e20e193c960802afba73b5d38sm        }
392cfd74d65d832137e20e193c960802afba73b5d38sm    }
393cfd74d65d832137e20e193c960802afba73b5d38sm
394cfd74d65d832137e20e193c960802afba73b5d38sm}
395