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