Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedTexture.java @ e6ab30eb

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
import java.util.HashMap;
28

    
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30

    
31
public class DistortedTexture
32
  {
33
  private static long mNextID =0;
34
  private static HashMap<Long,DistortedTexture> mTextures = new HashMap<>();
35

    
36
  private int mSizeX, mSizeY, mSizeZ;   // in screen space
37
  float mHalfX, mHalfY, mHalfZ;         // halves of the above
38

    
39
  private long mID;
40

    
41
  private Bitmap[] mBmp= null; //
42
  int[] mTextureDataH;         // have to be shared among all the cloned Objects
43
  boolean[] mBitmapSet;        //
44

    
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46
// We have to flip vertically every single Bitmap that we get fed with.
47
//
48
// Reason: textures read from files are the only objects in OpenGL which have their origins at the
49
// upper-left corner. Everywhere else the origin is in the lower-left corner. Thus we have to flip.
50
// The alternative solution, namely inverting the y-coordinate of the TexCoord does not really work-
51
// i.e. it works only in case of rendering directly to the screen, but if we render to an FBO and
52
// then take the FBO and render to screen, (DistortedObjectTree does so!) things get inverted as textures
53
// created from FBO have their origins in the lower-left... Mindfuck!
54

    
55
  private static Bitmap flipBitmap(Bitmap src)
56
    {
57
    Matrix matrix = new Matrix();
58
    matrix.preScale(1.0f,-1.0f);
59

    
60
    return Bitmap.createBitmap(src,0,0,src.getWidth(),src.getHeight(), matrix,true);
61
    }
62

    
63
///////////////////////////////////////////////////////////////////////////////////////////////////
64
// this will be called on startup and every time OpenGL context has been lost
65
// also call this from the constructor if the OpenGL context has been created already.
66

    
67
  private void resetTexture()
68
    {
69
    if( mTextureDataH!=null )
70
      {
71
      if( mTextureDataH[0]==0 ) GLES20.glGenTextures(1, mTextureDataH, 0);
72

    
73
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataH[0]);
74
      GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR );
75
      GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
76
      GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
77
      GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );
78

    
79
      if( mBmp!=null && mBmp[0]!=null)
80
        {
81
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, flipBitmap(mBmp[0]), 0);
82
        mBmp[0] = null;
83
        }
84
      }
85
    }
86

    
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88

    
89
  private void releasePriv()
90
    {
91
    mBmp          = null;
92
    mTextureDataH = null;
93
    }
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

    
97
  long getBitmapID()
98
    {
99
    return mBmp==null ? 0 : mBmp.hashCode();
100
    }
101

    
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

    
104
  static synchronized void reset()
105
    {
106
    for(long id: mTextures.keySet())
107
      {
108
      mTextures.get(id).resetTexture();
109
      }
110
    }
111

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

    
114
  static synchronized void release()
115
    {
116
    for(long id: mTextures.keySet())
117
      {
118
      mTextures.get(id).releasePriv();
119
      }
120

    
121
    mTextures.clear();
122
    mNextID = 0;
123
    }
124

    
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126
// PUBLIC API
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128
/**
129
 * Create empty texture of given dimensions.
130
 */
131
  public DistortedTexture(int width, int height, int depth)
132
    {
133
    mSizeX= width ; mHalfX = mSizeX/2.0f;
134
    mSizeY= height; mHalfY = mSizeY/2.0f;
135
    mSizeZ= depth ; mHalfZ = mSizeZ/2.0f;
136

    
137
    mID = mNextID++;
138
    mTextures.put(mID,this);
139

    
140
    mTextureDataH   = new int[1];
141
    mTextureDataH[0]= 0;
142
    mBmp            = new Bitmap[1];
143
    mBmp[0]         = null;
144
    mBitmapSet      = new boolean[1];
145
    mBitmapSet[0]   = false;
146

    
147
    if( Distorted.isInitialized() ) resetTexture();
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

    
152
/**
153
 * Copy constructor.
154
 * <p>
155
 * Whatever we do not clone gets created just like in the default constructor.
156
 *
157
 * @param dt    Source object to create our object from
158
 * @param flags A bitmask of values specifying what to copy.
159
 *              For example, CLONE_BITMAP.
160
 */
161
  public DistortedTexture(DistortedTexture dt, int flags)
162
    {
163
    mID = mNextID++;
164
    mTextures.put(mID,this);
165

    
166
    mSizeX = dt.mSizeX;
167
    mSizeY = dt.mSizeY;
168
    mSizeZ = dt.mSizeZ;
169
    mHalfX = dt.mHalfX;
170
    mHalfY = dt.mHalfY;
171
    mHalfZ = dt.mHalfZ;
172

    
173
    if( (flags & Distorted.CLONE_BITMAP) != 0 )
174
      {
175
      mTextureDataH = dt.mTextureDataH;
176
      mBmp          = dt.mBmp;
177
      mBitmapSet    = dt.mBitmapSet;
178
      }
179
    else
180
      {
181
      mTextureDataH   = new int[1];
182
      mTextureDataH[0]= 0;
183
      mBitmapSet      = new boolean[1];
184
      mBitmapSet[0]   = false;
185
      mBmp            = new Bitmap[1];
186
      mBmp[0]         = null;
187

    
188
      if( Distorted.isInitialized() ) resetTexture();
189
      }
190
    }
191

    
192

    
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194
/**
195
 * Releases all resources.
196
 */
197
  public synchronized void delete()
198
    {
199
    releasePriv();
200
    mTextures.remove(this);
201
    }
202

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204
/**
205
 * Sets the underlying android.graphics.Bitmap object and uploads it to the GPU.
206
 * <p>
207
 * You can only recycle() the passed Bitmap once the OpenGL context gets created (i.e. after call
208
 * to onSurfaceCreated) because only after this point can the Library upload it to the GPU!
209
 *
210
 * @param bmp The android.graphics.Bitmap object to apply effects to and display.
211
 */
212

    
213
  public void setTexture(Bitmap bmp)
214
    {
215
    mBitmapSet[0] = true;
216

    
217
    if( Distorted.isInitialized() )
218
      {
219
      GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
220
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataH[0]);
221
      GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, flipBitmap(bmp), 0);
222
      }
223
    else
224
      {
225
      mBmp[0] = bmp;
226
      }
227
    }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230
/**
231
 * Returns the height of the DistortedObject.
232
 *
233
 * @return height of the object, in pixels.
234
 */
235
  public int getWidth()
236
     {
237
     return mSizeX;
238
     }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241
/**
242
 * Returns the width of the DistortedObject.
243
 *
244
 * @return width of the Object, in pixels.
245
 */
246
  public int getHeight()
247
      {
248
      return mSizeY;
249
      }
250

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252
/**
253
 * Returns the depth of the DistortedObject.
254
 *
255
 * @return depth of the Object, in pixels.
256
 */
257
  public int getDepth()
258
      {
259
      return mSizeZ;
260
      }
261

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263
/**
264
 * Returns unique ID of this instance.
265
 *
266
 * @return ID of the object.
267
 */
268
  public long getID()
269
      {
270
      return mID;
271
      }
272

    
273
  }
(5-5/15)