Project

General

Profile

Download (9.45 KB) Statistics
| Branch: | Revision:

library / src / main / java / org / distorted / library / DistortedTexture.java @ 7b8086eb

1 4e2382f3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.library;
21
22
import android.graphics.Bitmap;
23
import android.graphics.Matrix;
24
import android.opengl.GLES20;
25
import android.opengl.GLUtils;
26
27 1942537e Leszek Koltunski
import java.util.Iterator;
28
import java.util.LinkedList;
29 4e2382f3 Leszek Koltunski
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31
32
public class DistortedTexture
33
  {
34 1942537e Leszek Koltunski
  private static boolean mListMarked = false;
35
  private static LinkedList<DistortedTexture> mList = new LinkedList<>();
36 4e2382f3 Leszek Koltunski
37 3ef3364d Leszek Koltunski
  private int mSizeX, mSizeY;  // in screen space
38
  float mHalfX, mHalfY;        // halves of the above
39 4e2382f3 Leszek Koltunski
  private long mID;
40 1942537e Leszek Koltunski
  private boolean mMarked;
41 4e2382f3 Leszek Koltunski
42
  private Bitmap[] mBmp= null; //
43
  int[] mTextureDataH;         // have to be shared among all the cloned Objects
44
  boolean[] mBitmapSet;        //
45
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47
// We have to flip vertically every single Bitmap that we get fed with.
48
//
49
// Reason: textures read from files are the only objects in OpenGL which have their origins at the
50
// upper-left corner. Everywhere else the origin is in the lower-left corner. Thus we have to flip.
51
// The alternative solution, namely inverting the y-coordinate of the TexCoord does not really work-
52
// i.e. it works only in case of rendering directly to the screen, but if we render to an FBO and
53
// then take the FBO and render to screen, (DistortedObjectTree does so!) things get inverted as textures
54
// created from FBO have their origins in the lower-left... Mindfuck!
55
56
  private static Bitmap flipBitmap(Bitmap src)
57
    {
58
    Matrix matrix = new Matrix();
59
    matrix.preScale(1.0f,-1.0f);
60
61
    return Bitmap.createBitmap(src,0,0,src.getWidth(),src.getHeight(), matrix,true);
62
    }
63
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65 1942537e Leszek Koltunski
// must be called from a thread holding OpenGL Context
66 4e2382f3 Leszek Koltunski
67 1942537e Leszek Koltunski
  void createTexture()
68 4e2382f3 Leszek Koltunski
    {
69 1942537e Leszek Koltunski
    if( mBmp[0]!=null && mTextureDataH!=null )
70 4e2382f3 Leszek Koltunski
      {
71 1942537e Leszek Koltunski
      //android.util.Log.e("Texture", "creating "+mID);
72
73 4e2382f3 Leszek Koltunski
      if( mTextureDataH[0]==0 ) GLES20.glGenTextures(1, mTextureDataH, 0);
74
75
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataH[0]);
76
      GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR );
77
      GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
78
      GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
79
      GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );
80
81 1942537e Leszek Koltunski
      GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, flipBitmap(mBmp[0]), 0);
82
      mBmp[0] = null;
83 4e2382f3 Leszek Koltunski
      }
84
    }
85
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87 1942537e Leszek Koltunski
// must be called from a thread holding OpenGL Context
88 4e2382f3 Leszek Koltunski
89 1942537e Leszek Koltunski
  private void deleteTexture()
90 4e2382f3 Leszek Koltunski
    {
91 1942537e Leszek Koltunski
    if( mTextureDataH!=null && mTextureDataH[0]>0 )
92
      {
93
      //android.util.Log.e("Texture", "deleting "+mID);
94 4e2382f3 Leszek Koltunski
95 1942537e Leszek Koltunski
      GLES20.glDeleteTextures(1, mTextureDataH, 0);
96 4e2382f3 Leszek Koltunski
97 1942537e Leszek Koltunski
      mTextureDataH[0] = 0;
98
      mBitmapSet[0] = false;
99
      }
100
101
    mMarked = false;
102 4e2382f3 Leszek Koltunski
    }
103
104 d558d9bd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
105
106
  long getID()
107 1942537e Leszek Koltunski
    {
108
    return mID;
109
    }
110 d558d9bd Leszek Koltunski
111 4e2382f3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
112
113 7b8086eb Leszek Koltunski
  static synchronized void onDestroy()
114 4e2382f3 Leszek Koltunski
    {
115 1942537e Leszek Koltunski
    mListMarked = false;
116
    mList.clear();
117 4e2382f3 Leszek Koltunski
    }
118
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120 1942537e Leszek Koltunski
// must be called form a thread holding OpenGL Context
121 4e2382f3 Leszek Koltunski
122 1942537e Leszek Koltunski
  static synchronized void deleteAllMarked()
123 4e2382f3 Leszek Koltunski
    {
124 1942537e Leszek Koltunski
    if( mListMarked )
125 4e2382f3 Leszek Koltunski
      {
126 1942537e Leszek Koltunski
      DistortedTexture tmp;
127
      Iterator<DistortedTexture> iterator = mList.iterator();
128
129
      while(iterator.hasNext())
130
        {
131
        tmp = iterator.next();
132
133
        if( tmp.mMarked )
134
          {
135
          tmp.deleteTexture();
136
          iterator.remove();
137
          }
138
        }
139 4e2382f3 Leszek Koltunski
140 1942537e Leszek Koltunski
      mListMarked = false;
141
      }
142 4e2382f3 Leszek Koltunski
    }
143
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
// PUBLIC API
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147
/**
148
 * Create empty texture of given dimensions.
149
 */
150 3ef3364d Leszek Koltunski
  public DistortedTexture(int width, int height)
151 4e2382f3 Leszek Koltunski
    {
152 3ef3364d Leszek Koltunski
    mSizeX= width ; mHalfX = mSizeX/2.0f;
153
    mSizeY= height; mHalfY = mSizeY/2.0f;
154
155 4e2382f3 Leszek Koltunski
    mTextureDataH   = new int[1];
156
    mTextureDataH[0]= 0;
157
    mBmp            = new Bitmap[1];
158
    mBmp[0]         = null;
159
    mBitmapSet      = new boolean[1];
160
    mBitmapSet[0]   = false;
161 1942537e Leszek Koltunski
    mID             = 0;
162
    mMarked         = false;
163 4e2382f3 Leszek Koltunski
164 1942537e Leszek Koltunski
    mList.add(this);
165 4e2382f3 Leszek Koltunski
    }
166
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
169
/**
170
 * Copy constructor.
171
 * <p>
172
 * Whatever we do not clone gets created just like in the default constructor.
173
 *
174
 * @param dt    Source object to create our object from
175
 * @param flags A bitmask of values specifying what to copy.
176 d558d9bd Leszek Koltunski
 *              Only possibilities: CLONE_BITMAP or CLONE_NOTHING.
177 4e2382f3 Leszek Koltunski
 */
178 d558d9bd Leszek Koltunski
179 4e2382f3 Leszek Koltunski
  public DistortedTexture(DistortedTexture dt, int flags)
180
    {
181 3ef3364d Leszek Koltunski
    mSizeX= dt.mSizeX ; mHalfX = mSizeX/2.0f;
182
    mSizeY= dt.mSizeY ; mHalfY = mSizeY/2.0f;
183 4e2382f3 Leszek Koltunski
184
    if( (flags & Distorted.CLONE_BITMAP) != 0 )
185
      {
186
      mTextureDataH = dt.mTextureDataH;
187
      mBmp          = dt.mBmp;
188
      mBitmapSet    = dt.mBitmapSet;
189 1942537e Leszek Koltunski
      mID           = dt.getID();
190 4e2382f3 Leszek Koltunski
      }
191
    else
192
      {
193
      mTextureDataH   = new int[1];
194
      mTextureDataH[0]= 0;
195
      mBitmapSet      = new boolean[1];
196
      mBitmapSet[0]   = false;
197
      mBmp            = new Bitmap[1];
198
      mBmp[0]         = null;
199 1942537e Leszek Koltunski
      mID             = 0;
200 4e2382f3 Leszek Koltunski
      }
201 1942537e Leszek Koltunski
202
    mMarked = false;
203
204
    mList.add(this);
205 4e2382f3 Leszek Koltunski
    }
206
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208
/**
209 1942537e Leszek Koltunski
 * Mark the underlying OpenGL object for deletion. Actual deletion will take place on the next render.
210 4e2382f3 Leszek Koltunski
 */
211 1942537e Leszek Koltunski
  public void markForDeletion()
212 4e2382f3 Leszek Koltunski
    {
213 1942537e Leszek Koltunski
    //android.util.Log.e("Texture", "marking for deletion "+mID);
214
215
    mListMarked = true;
216
    mMarked     = true;
217 4e2382f3 Leszek Koltunski
    }
218
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220
/**
221 1942537e Leszek Koltunski
 * Sets the underlying android.graphics.Bitmap object.
222 4e2382f3 Leszek Koltunski
 * <p>
223
 * You can only recycle() the passed Bitmap once the OpenGL context gets created (i.e. after call
224
 * to onSurfaceCreated) because only after this point can the Library upload it to the GPU!
225
 *
226
 * @param bmp The android.graphics.Bitmap object to apply effects to and display.
227
 */
228
229
  public void setTexture(Bitmap bmp)
230
    {
231
    mBitmapSet[0] = true;
232 1942537e Leszek Koltunski
    mBmp[0]       = bmp;
233
    mID           = bmp.hashCode();
234 4e2382f3 Leszek Koltunski
235 1942537e Leszek Koltunski
    //android.util.Log.e("Texture", "setting new bitmap "+mID);
236 4e2382f3 Leszek Koltunski
    }
237
238
///////////////////////////////////////////////////////////////////////////////////////////////////
239
/**
240 46e25345 Leszek Koltunski
 * Returns the height of the Texture.
241 4e2382f3 Leszek Koltunski
 *
242
 * @return height of the object, in pixels.
243
 */
244
  public int getWidth()
245 1942537e Leszek Koltunski
    {
246
    return mSizeX;
247
    }
248 4e2382f3 Leszek Koltunski
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250
/**
251 46e25345 Leszek Koltunski
 * Returns the width of the Texture.
252 4e2382f3 Leszek Koltunski
 *
253
 * @return width of the Object, in pixels.
254
 */
255
  public int getHeight()
256 1942537e Leszek Koltunski
    {
257
    return mSizeY;
258
    }
259 4e2382f3 Leszek Koltunski
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261
/**
262 46e25345 Leszek Koltunski
 * Returns the depth of the Texture.
263 3ef3364d Leszek Koltunski
 * <p>
264
 * Admittedly quite a strange method. Why do we need to pass a Grid to it? Because one cannot determine
265
 * 'depth' of a texture when rendered based only on the texture itself, that depends on the Grid it is
266
 * rendered with.
267 4e2382f3 Leszek Koltunski
 *
268
 * @return depth of the Object, in pixels.
269
 */
270 3ef3364d Leszek Koltunski
  public int getDepth(GridObject grid)
271 1942537e Leszek Koltunski
    {
272
    return grid==null ? 0 : (int)(mSizeX*grid.zFactor);
273
    }
274 4e2382f3 Leszek Koltunski
  }