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
17package com.replica.replicaisland;
18
19import javax.microedition.khronos.opengles.GL10;
20import javax.microedition.khronos.opengles.GL11Ext;
21
22/**
23 * Draws a screen-aligned bitmap to the screen.
24 */
25public class DrawableBitmap extends DrawableObject {
26
27    private Texture mTexture;
28    private int mWidth;
29    private int mHeight;
30    private int mCrop[];
31    private int mViewWidth;
32    private int mViewHeight;
33    private float mOpacity;
34
35    DrawableBitmap(Texture texture, int width, int height) {
36        super();
37        mTexture = texture;
38        mWidth = width;
39        mHeight = height;
40        mCrop = new int[4];
41        mViewWidth = 0;
42        mViewHeight = 0;
43        mOpacity = 1.0f;
44        setCrop(0, height, width, height);
45    }
46
47    public void reset() {
48        mTexture = null;
49        mViewWidth = 0;
50        mViewHeight = 0;
51        mOpacity = 1.0f;
52
53    }
54
55    public void setViewSize(int width, int height) {
56        mViewHeight = height;
57        mViewWidth = width;
58    }
59
60    public void setOpacity(float opacity) {
61        mOpacity = opacity;
62    }
63
64    /**
65     * Begins drawing bitmaps. Sets the OpenGL state for rapid drawing.
66     *
67     * @param gl  A pointer to the OpenGL context.
68     * @param viewWidth  The width of the screen.
69     * @param viewHeight  The height of the screen.
70     */
71    public static void beginDrawing(GL10 gl, float viewWidth, float viewHeight) {
72        gl.glShadeModel(GL10.GL_FLAT);
73        gl.glEnable(GL10.GL_BLEND);
74        gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
75        gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
76
77        gl.glMatrixMode(GL10.GL_PROJECTION);
78        gl.glPushMatrix();
79        gl.glLoadIdentity();
80        gl.glOrthof(0.0f, viewWidth, 0.0f, viewHeight, 0.0f, 1.0f);
81        gl.glMatrixMode(GL10.GL_MODELVIEW);
82        gl.glPushMatrix();
83        gl.glLoadIdentity();
84
85        gl.glEnable(GL10.GL_TEXTURE_2D);
86
87    }
88
89    /**
90     * Draw the bitmap at a given x,y position, expressed in pixels, with the
91     * lower-left-hand-corner of the view being (0,0).
92     *
93     * @param gl  A pointer to the OpenGL context
94     * @param x  The number of pixels to offset this drawable's origin in the x-axis.
95     * @param y  The number of pixels to offset this drawable's origin in the y-axis
96     * @param scaleX The horizontal scale factor between the bitmap resolution and the display resolution.
97     * @param scaleY The vertical scale factor between the bitmap resolution and the display resolution.
98     */
99    @Override
100    public void draw(float x, float y, float scaleX, float scaleY) {
101        GL10 gl = OpenGLSystem.getGL();
102        final Texture texture = mTexture;
103
104        if (gl != null && texture != null) {
105            assert texture.loaded;
106
107            final float snappedX = (int) x;
108            final float snappedY = (int) y;
109
110            final float opacity = mOpacity;
111            final float width = mWidth;
112            final float height = mHeight;
113            final float viewWidth = mViewWidth;
114            final float viewHeight = mViewHeight;
115
116            boolean cull = false;
117            if (viewWidth > 0) {
118                if (snappedX + width < 0.0f
119                		|| snappedX > viewWidth
120                        || snappedY + height < 0.0f
121                        || snappedY > viewHeight
122                        || opacity == 0.0f
123                        || !texture.loaded) {
124                    cull = true;
125                }
126            }
127            if (!cull) {
128                OpenGLSystem.bindTexture(GL10.GL_TEXTURE_2D, texture.name);
129
130                // This is necessary because we could be drawing the same texture with different
131                // crop (say, flipped horizontally) on the same frame.
132                OpenGLSystem.setTextureCrop(mCrop);
133
134                if (opacity < 1.0f) {
135                    gl.glColor4f(opacity, opacity, opacity, opacity);
136                }
137
138                ((GL11Ext) gl).glDrawTexfOES(snappedX * scaleX, snappedY * scaleY,
139                		getPriority(), width * scaleX, height * scaleY);
140
141                if (opacity < 1.0f) {
142                    gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
143                }
144            }
145        }
146    }
147
148    /**
149     * Ends the drawing and restores the OpenGL state.
150     *
151     * @param gl  A pointer to the OpenGL context.
152     */
153    public static void endDrawing(GL10 gl) {
154        gl.glDisable(GL10.GL_BLEND);
155        gl.glMatrixMode(GL10.GL_PROJECTION);
156        gl.glPopMatrix();
157        gl.glMatrixMode(GL10.GL_MODELVIEW);
158        gl.glPopMatrix();
159    }
160
161    public void resize(int width, int height) {
162        mWidth = width;
163        mHeight = height;
164        setCrop(0, height, width, height);
165    }
166
167    public int getWidth() {
168        return mWidth;
169    }
170
171    public void setWidth(int width) {
172        mWidth = width;
173    }
174
175    public int getHeight() {
176        return mHeight;
177    }
178
179    public void setHeight(int height) {
180        mHeight = height;
181    }
182
183    /**
184     * Changes the crop parameters of this bitmap.  Note that the underlying OpenGL texture's
185     * parameters are not changed immediately The crop is updated on the
186     * next call to draw().  Note that the image may be flipped by providing a negative width or
187     * height.
188     *
189     * @param left
190     * @param bottom
191     * @param width
192     * @param height
193     */
194    public void setCrop(int left, int bottom, int width, int height) {
195        // Negative width and height values will flip the image.
196        mCrop[0] = left;
197        mCrop[1] = bottom;
198        mCrop[2] = width;
199        mCrop[3] = -height;
200    }
201
202    public int[] getCrop() {
203        return mCrop;
204    }
205
206    public void setTexture(Texture texture) {
207        mTexture = texture;
208    }
209
210    @Override
211    public Texture getTexture() {
212        return mTexture;
213    }
214
215   @Override
216   public boolean visibleAtPosition(Vector2 position) {
217       boolean cull = false;
218       if (mViewWidth > 0) {
219           if (position.x + mWidth < 0 || position.x > mViewWidth
220                   || position.y + mHeight < 0 || position.y > mViewHeight) {
221               cull = true;
222           }
223       }
224       return !cull;
225   }
226
227   protected final void setFlip(boolean horzFlip, boolean vertFlip) {
228       setCrop(horzFlip ? mWidth : 0,
229               vertFlip ? 0 : mHeight,
230               horzFlip ? -mWidth : mWidth,
231               vertFlip ? -mHeight : mHeight);
232   }
233}
234