xref: /aosp_15_r20/external/replicaisland/src/com/replica/replicaisland/TiledVertexGrid.java (revision 5eae8ebb3c5756e41e77a1f7201fcf94b0eade1f)
1*5eae8ebbSCole Faust /*
2*5eae8ebbSCole Faust  * Copyright (C) 2010 The Android Open Source Project
3*5eae8ebbSCole Faust  *
4*5eae8ebbSCole Faust  * Licensed under the Apache License, Version 2.0 (the "License");
5*5eae8ebbSCole Faust  * you may not use this file except in compliance with the License.
6*5eae8ebbSCole Faust  * You may obtain a copy of the License at
7*5eae8ebbSCole Faust  *
8*5eae8ebbSCole Faust  *      http://www.apache.org/licenses/LICENSE-2.0
9*5eae8ebbSCole Faust  *
10*5eae8ebbSCole Faust  * Unless required by applicable law or agreed to in writing, software
11*5eae8ebbSCole Faust  * distributed under the License is distributed on an "AS IS" BASIS,
12*5eae8ebbSCole Faust  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5eae8ebbSCole Faust  * See the License for the specific language governing permissions and
14*5eae8ebbSCole Faust  * limitations under the License.
15*5eae8ebbSCole Faust  */
16*5eae8ebbSCole Faust 
17*5eae8ebbSCole Faust package com.replica.replicaisland;
18*5eae8ebbSCole Faust 
19*5eae8ebbSCole Faust import javax.microedition.khronos.opengles.GL10;
20*5eae8ebbSCole Faust 
21*5eae8ebbSCole Faust public class TiledVertexGrid extends BaseObject {
22*5eae8ebbSCole Faust 	private static final float GL_MAGIC_OFFSET = 0.375f;
23*5eae8ebbSCole Faust     private Grid mTileMap;
24*5eae8ebbSCole Faust     private TiledWorld mWorld;
25*5eae8ebbSCole Faust     private int mTileWidth;
26*5eae8ebbSCole Faust     private int mTileHeight;
27*5eae8ebbSCole Faust 
28*5eae8ebbSCole Faust     private int mWidth;
29*5eae8ebbSCole Faust     private int mHeight;
30*5eae8ebbSCole Faust     private Texture mTexture;
31*5eae8ebbSCole Faust 
32*5eae8ebbSCole Faust     private float mWorldPixelWidth;
33*5eae8ebbSCole Faust     private float mWorldPixelHeight;
34*5eae8ebbSCole Faust 
35*5eae8ebbSCole Faust     private int mTilesPerRow;
36*5eae8ebbSCole Faust     private int mTilesPerColumn;
37*5eae8ebbSCole Faust 
38*5eae8ebbSCole Faust     private Boolean mGenerated;
39*5eae8ebbSCole Faust 
TiledVertexGrid(Texture texture, int width, int height, int tileWidth, int tileHeight)40*5eae8ebbSCole Faust     public TiledVertexGrid(Texture texture, int width, int height, int tileWidth, int tileHeight) {
41*5eae8ebbSCole Faust         super();
42*5eae8ebbSCole Faust         mTileWidth = tileWidth;
43*5eae8ebbSCole Faust         mTileHeight = tileHeight;
44*5eae8ebbSCole Faust         mWidth = width;
45*5eae8ebbSCole Faust         mHeight = height;
46*5eae8ebbSCole Faust         mTexture = texture;
47*5eae8ebbSCole Faust         mGenerated = false;
48*5eae8ebbSCole Faust     }
49*5eae8ebbSCole Faust 
50*5eae8ebbSCole Faust     @Override
reset()51*5eae8ebbSCole Faust     public void reset() {
52*5eae8ebbSCole Faust     }
53*5eae8ebbSCole Faust 
setWorld(TiledWorld world)54*5eae8ebbSCole Faust     public void setWorld(TiledWorld world) {
55*5eae8ebbSCole Faust         mWorld = world;
56*5eae8ebbSCole Faust 
57*5eae8ebbSCole Faust     }
58*5eae8ebbSCole Faust 
generateGrid(int width, int height, int startTileX, int startTileY)59*5eae8ebbSCole Faust     private Grid generateGrid(int width, int height, int startTileX, int startTileY) {
60*5eae8ebbSCole Faust         final int tileWidth = mTileWidth;
61*5eae8ebbSCole Faust         final int tileHeight = mTileHeight;
62*5eae8ebbSCole Faust         final int tilesAcross = width / tileWidth;
63*5eae8ebbSCole Faust         final int tilesDown = height / tileHeight;
64*5eae8ebbSCole Faust         final Texture texture = mTexture;
65*5eae8ebbSCole Faust         final float texelWidth = 1.0f / texture.width;
66*5eae8ebbSCole Faust         final float texelHeight = 1.0f / texture.height;
67*5eae8ebbSCole Faust         final int textureTilesAcross = texture.width / tileWidth;
68*5eae8ebbSCole Faust         final int textureTilesDown = texture.height / tileHeight;
69*5eae8ebbSCole Faust         final int tilesPerWorldColumn = mWorld.getHeight();
70*5eae8ebbSCole Faust         final int totalTextureTiles = textureTilesAcross * textureTilesDown;
71*5eae8ebbSCole Faust         // Check to see if this entire grid is empty tiles.  If so, we don't need to do anything.
72*5eae8ebbSCole Faust         boolean entirelyEmpty = true;
73*5eae8ebbSCole Faust         for (int tileY = 0; tileY < tilesDown && entirelyEmpty; tileY++) {
74*5eae8ebbSCole Faust             for (int tileX = 0; tileX < tilesAcross && entirelyEmpty; tileX++) {
75*5eae8ebbSCole Faust                 int tileIndex = mWorld.getTile(startTileX + tileX,
76*5eae8ebbSCole Faust                         (tilesPerWorldColumn - 1 - (startTileY + tileY)));
77*5eae8ebbSCole Faust                 if (tileIndex >= 0) {
78*5eae8ebbSCole Faust                     entirelyEmpty = false;
79*5eae8ebbSCole Faust                     break;
80*5eae8ebbSCole Faust                 }
81*5eae8ebbSCole Faust             }
82*5eae8ebbSCole Faust         }
83*5eae8ebbSCole Faust 
84*5eae8ebbSCole Faust         Grid grid = null;
85*5eae8ebbSCole Faust         if (!entirelyEmpty) {
86*5eae8ebbSCole Faust             grid = new Grid(tilesAcross, tilesDown, false);
87*5eae8ebbSCole Faust             for (int tileY = 0; tileY < tilesDown; tileY++) {
88*5eae8ebbSCole Faust                 for (int tileX = 0; tileX < tilesAcross; tileX++) {
89*5eae8ebbSCole Faust                     final float offsetX = tileX * tileWidth;
90*5eae8ebbSCole Faust                     final float offsetY = tileY * tileHeight;
91*5eae8ebbSCole Faust                     int tileIndex = mWorld.getTile(startTileX + tileX,
92*5eae8ebbSCole Faust                             (tilesPerWorldColumn - 1 - (startTileY + tileY)));
93*5eae8ebbSCole Faust                     if (tileIndex < 0) {
94*5eae8ebbSCole Faust                         tileIndex = totalTextureTiles - 1; // Assume that the last tile is empty.
95*5eae8ebbSCole Faust                     }
96*5eae8ebbSCole Faust                     int textureOffsetX = (tileIndex % textureTilesAcross) * tileWidth;
97*5eae8ebbSCole Faust                     int textureOffsetY = (tileIndex / textureTilesAcross) * tileHeight;
98*5eae8ebbSCole Faust                     if (textureOffsetX < 0 ||
99*5eae8ebbSCole Faust                             textureOffsetX > texture.width - tileWidth ||
100*5eae8ebbSCole Faust                             textureOffsetY < 0 ||
101*5eae8ebbSCole Faust                             textureOffsetY > texture.height - tileHeight) {
102*5eae8ebbSCole Faust                         textureOffsetX = 0;
103*5eae8ebbSCole Faust                         textureOffsetY = 0;
104*5eae8ebbSCole Faust                     }
105*5eae8ebbSCole Faust                     final float u = (textureOffsetX + GL_MAGIC_OFFSET) * texelWidth;
106*5eae8ebbSCole Faust                     final float v = (textureOffsetY + GL_MAGIC_OFFSET) * texelHeight;
107*5eae8ebbSCole Faust                     final float u2 = ((textureOffsetX + tileWidth - GL_MAGIC_OFFSET) * texelWidth);
108*5eae8ebbSCole Faust                     final float v2 = ((textureOffsetY + tileHeight - GL_MAGIC_OFFSET) * texelHeight);
109*5eae8ebbSCole Faust 
110*5eae8ebbSCole Faust                     final float[] p0 = { offsetX, offsetY, 0.0f };
111*5eae8ebbSCole Faust                     final float[] p1 = { offsetX + tileWidth, offsetY, 0.0f };
112*5eae8ebbSCole Faust                     final float[] p2 = { offsetX, offsetY + tileHeight, 0.0f };
113*5eae8ebbSCole Faust                     final float[] p3 = { offsetX + tileWidth, offsetY + tileHeight, 0.0f };
114*5eae8ebbSCole Faust                     final float[] uv0 = { u, v2 };
115*5eae8ebbSCole Faust                     final float[] uv1 = { u2, v2 };
116*5eae8ebbSCole Faust                     final float[] uv2 = { u, v };
117*5eae8ebbSCole Faust                     final float[] uv3 = { u2, v };
118*5eae8ebbSCole Faust 
119*5eae8ebbSCole Faust                     final float[][] positions = { p0, p1, p2, p3 };
120*5eae8ebbSCole Faust                     final float[][] uvs = { uv0, uv1, uv2, uv3 };
121*5eae8ebbSCole Faust 
122*5eae8ebbSCole Faust                     grid.set(tileX, tileY, positions, uvs);
123*5eae8ebbSCole Faust 
124*5eae8ebbSCole Faust                 }
125*5eae8ebbSCole Faust             }
126*5eae8ebbSCole Faust         }
127*5eae8ebbSCole Faust         return grid;
128*5eae8ebbSCole Faust     }
129*5eae8ebbSCole Faust 
draw(float x, float y, float scrollOriginX, float scrollOriginY)130*5eae8ebbSCole Faust     public void draw(float x, float y, float scrollOriginX, float scrollOriginY) {
131*5eae8ebbSCole Faust         TiledWorld world = mWorld;
132*5eae8ebbSCole Faust         GL10 gl = OpenGLSystem.getGL();
133*5eae8ebbSCole Faust         if (!mGenerated && world != null && gl != null && mTexture != null) {
134*5eae8ebbSCole Faust             final int tilesAcross = mWorld.getWidth();
135*5eae8ebbSCole Faust             final int tilesDown = mWorld.getHeight();
136*5eae8ebbSCole Faust 
137*5eae8ebbSCole Faust             mWorldPixelWidth = mWorld.getWidth() * mTileWidth;
138*5eae8ebbSCole Faust             mWorldPixelHeight = mWorld.getHeight() * mTileHeight;
139*5eae8ebbSCole Faust             mTilesPerRow = tilesAcross;
140*5eae8ebbSCole Faust             mTilesPerColumn = tilesDown;
141*5eae8ebbSCole Faust 
142*5eae8ebbSCole Faust 
143*5eae8ebbSCole Faust             BufferLibrary bufferLibrary = sSystemRegistry.bufferLibrary;
144*5eae8ebbSCole Faust 
145*5eae8ebbSCole Faust             Grid grid = generateGrid((int)mWorldPixelWidth, (int)mWorldPixelHeight, 0, 0);
146*5eae8ebbSCole Faust             mTileMap = grid;
147*5eae8ebbSCole Faust             mGenerated = true;
148*5eae8ebbSCole Faust             if (grid != null) {
149*5eae8ebbSCole Faust                 bufferLibrary.add(grid);
150*5eae8ebbSCole Faust                 if (sSystemRegistry.contextParameters.supportsVBOs) {
151*5eae8ebbSCole Faust                 	grid.generateHardwareBuffers(gl);
152*5eae8ebbSCole Faust                 }
153*5eae8ebbSCole Faust             }
154*5eae8ebbSCole Faust 
155*5eae8ebbSCole Faust         }
156*5eae8ebbSCole Faust 
157*5eae8ebbSCole Faust         final Grid tileMap = mTileMap;
158*5eae8ebbSCole Faust         if (tileMap != null) {
159*5eae8ebbSCole Faust             final Texture texture = mTexture;
160*5eae8ebbSCole Faust             if (gl != null && texture != null) {
161*5eae8ebbSCole Faust 
162*5eae8ebbSCole Faust                 int originX = (int) (x - scrollOriginX);
163*5eae8ebbSCole Faust                 int originY = (int) (y - scrollOriginY);
164*5eae8ebbSCole Faust 
165*5eae8ebbSCole Faust 
166*5eae8ebbSCole Faust                 final float worldPixelWidth = mWorldPixelWidth;
167*5eae8ebbSCole Faust 
168*5eae8ebbSCole Faust                 final float percentageScrollRight =
169*5eae8ebbSCole Faust                     scrollOriginX != 0.0f ? scrollOriginX / worldPixelWidth : 0.0f;
170*5eae8ebbSCole Faust                 final float tileSpaceX = percentageScrollRight * mTilesPerRow;
171*5eae8ebbSCole Faust                 final int leftTile = (int)tileSpaceX;
172*5eae8ebbSCole Faust 
173*5eae8ebbSCole Faust                 // calculate the top tile index
174*5eae8ebbSCole Faust                 final float worldPixelHeight = mWorldPixelHeight;
175*5eae8ebbSCole Faust 
176*5eae8ebbSCole Faust                 final float percentageScrollUp =
177*5eae8ebbSCole Faust                     scrollOriginY != 0.0f ? scrollOriginY / worldPixelHeight : 0.0f;
178*5eae8ebbSCole Faust                 final float tileSpaceY = percentageScrollUp * mTilesPerColumn;
179*5eae8ebbSCole Faust                 final int bottomTile = (int)tileSpaceY;
180*5eae8ebbSCole Faust 
181*5eae8ebbSCole Faust                 // calculate any sub-tile slop that our scroll position may require.
182*5eae8ebbSCole Faust                 final int horizontalSlop = ((tileSpaceX - leftTile) * mTileWidth) > 0 ? 1 : 0;
183*5eae8ebbSCole Faust                 final int verticalSlop = ((tileSpaceY - bottomTile) * mTileHeight) > 0 ? 1 : 0;
184*5eae8ebbSCole Faust 
185*5eae8ebbSCole Faust 
186*5eae8ebbSCole Faust                 OpenGLSystem.bindTexture(GL10.GL_TEXTURE_2D, texture.name);
187*5eae8ebbSCole Faust                 tileMap.beginDrawingStrips(gl, true);
188*5eae8ebbSCole Faust 
189*5eae8ebbSCole Faust                 final int horzTileCount = (int)Math.ceil((float)mWidth / mTileWidth);
190*5eae8ebbSCole Faust                 final int vertTileCount = (int)Math.ceil((float)mHeight / mTileHeight);
191*5eae8ebbSCole Faust                 // draw vertex strips
192*5eae8ebbSCole Faust                 final int startX = leftTile;
193*5eae8ebbSCole Faust                 final int startY = bottomTile;
194*5eae8ebbSCole Faust                 final int endX = startX + horizontalSlop + horzTileCount;
195*5eae8ebbSCole Faust                 final int endY = startY + verticalSlop +  vertTileCount;
196*5eae8ebbSCole Faust 
197*5eae8ebbSCole Faust                 gl.glPushMatrix();
198*5eae8ebbSCole Faust                 gl.glLoadIdentity();
199*5eae8ebbSCole Faust                 gl.glTranslatef(
200*5eae8ebbSCole Faust                         originX,
201*5eae8ebbSCole Faust                         originY,
202*5eae8ebbSCole Faust                         0.0f);
203*5eae8ebbSCole Faust 
204*5eae8ebbSCole Faust 
205*5eae8ebbSCole Faust                 final int indexesPerTile = 6;
206*5eae8ebbSCole Faust                 final int indexesPerRow = mTilesPerRow * indexesPerTile;
207*5eae8ebbSCole Faust                 final int startOffset = (startX * indexesPerTile);
208*5eae8ebbSCole Faust                 final int count = (endX - startX) * indexesPerTile;
209*5eae8ebbSCole Faust                 for (int tileY = startY; tileY < endY && tileY < mTilesPerColumn; tileY++) {
210*5eae8ebbSCole Faust                 	final int row = tileY * indexesPerRow;
211*5eae8ebbSCole Faust                 	tileMap.drawStrip(gl, true, row + startOffset, count);
212*5eae8ebbSCole Faust                 }
213*5eae8ebbSCole Faust 
214*5eae8ebbSCole Faust                 gl.glPopMatrix();
215*5eae8ebbSCole Faust 
216*5eae8ebbSCole Faust                 Grid.endDrawing(gl);
217*5eae8ebbSCole Faust 
218*5eae8ebbSCole Faust             }
219*5eae8ebbSCole Faust         }
220*5eae8ebbSCole Faust     }
221*5eae8ebbSCole Faust 
222*5eae8ebbSCole Faust }
223