Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedTexture.java @ 3f3bf7dc

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.Arrays;
28
import java.util.HashMap;
29

    
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31

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

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

    
40
  private long mID;
41
  private long mBitmapID=0;
42

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

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

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

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

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

    
69
  private void resetTexture()
70
    {
71
    if( mTextureDataH!=null )
72
      {
73
      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
      if( mBmp!=null && mBmp[0]!=null)
82
        {
83
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, flipBitmap(mBmp[0]), 0);
84
        mBmp[0] = null;
85
        }
86
      }
87
    }
88

    
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90

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

    
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98

    
99
  long getBitmapID()
100
    {
101
    if( mBmp!=null && mBitmapID==0 ) mBitmapID = Arrays.hashCode(mBmp);
102
    return mBitmapID;
103
    }
104

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

    
107
  long getID()
108
      {
109
      return mID;
110
      }
111

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

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

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

    
124
  static synchronized void release()
125
    {
126
    for(long id: mTextures.keySet())
127
      {
128
      mTextures.get(id).releasePriv();
129
      }
130

    
131
    mTextures.clear();
132
    mNextID = 0;
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136
// PUBLIC API
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138
/**
139
 * Create empty texture of given dimensions.
140
 */
141
  public DistortedTexture(int width, int height, int depth)
142
    {
143
    mSizeX= width ; mHalfX = mSizeX/2.0f;
144
    mSizeY= height; mHalfY = mSizeY/2.0f;
145
    mSizeZ= depth ; mHalfZ = mSizeZ/2.0f;
146

    
147
    mID = mNextID++;
148
    mTextures.put(mID,this);
149

    
150
    mTextureDataH   = new int[1];
151
    mTextureDataH[0]= 0;
152
    mBmp            = new Bitmap[1];
153
    mBmp[0]         = null;
154
    mBitmapSet      = new boolean[1];
155
    mBitmapSet[0]   = false;
156

    
157
    if( Distorted.isInitialized() ) resetTexture();
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
/**
163
 * Copy constructor.
164
 * <p>
165
 * Whatever we do not clone gets created just like in the default constructor.
166
 *
167
 * @param dt    Source object to create our object from
168
 * @param flags A bitmask of values specifying what to copy.
169
 *              Only possibilities: CLONE_BITMAP or CLONE_NOTHING.
170
 */
171

    
172
  public DistortedTexture(DistortedTexture dt, int flags)
173
    {
174
    mID = mNextID++;
175
    mTextures.put(mID,this);
176

    
177
    mSizeX = dt.mSizeX;
178
    mSizeY = dt.mSizeY;
179
    mSizeZ = dt.mSizeZ;
180
    mHalfX = dt.mHalfX;
181
    mHalfY = dt.mHalfY;
182
    mHalfZ = dt.mHalfZ;
183

    
184
    if( (flags & Distorted.CLONE_BITMAP) != 0 )
185
      {
186
      mTextureDataH = dt.mTextureDataH;
187
      mBmp          = dt.mBmp;
188
      mBitmapSet    = dt.mBitmapSet;
189
      }
190
    else
191
      {
192
      mTextureDataH   = new int[1];
193
      mTextureDataH[0]= 0;
194
      mBitmapSet      = new boolean[1];
195
      mBitmapSet[0]   = false;
196
      mBmp            = new Bitmap[1];
197
      mBmp[0]         = null;
198

    
199
      if( Distorted.isInitialized() ) resetTexture();
200
      }
201
    }
202

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204
/**
205
 * Releases all resources.
206
 */
207
  public synchronized void delete()
208
    {
209
    releasePriv();
210
    mTextures.remove(this);
211
    }
212

    
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214
/**
215
 * Sets the underlying android.graphics.Bitmap object and uploads it to the GPU.
216
 * <p>
217
 * You can only recycle() the passed Bitmap once the OpenGL context gets created (i.e. after call
218
 * to onSurfaceCreated) because only after this point can the Library upload it to the GPU!
219
 *
220
 * @param bmp The android.graphics.Bitmap object to apply effects to and display.
221
 */
222

    
223
  public void setTexture(Bitmap bmp)
224
    {
225
    mBitmapSet[0] = true;
226

    
227
    if( Distorted.isInitialized() )
228
      {
229
      GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
230
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataH[0]);
231
      GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, flipBitmap(bmp), 0);
232
      }
233
    else
234
      {
235
      mBmp[0] = bmp;
236
      }
237
    }
238

    
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240
/**
241
 * Returns the height of the DistortedObject.
242
 *
243
 * @return height of the object, in pixels.
244
 */
245
  public int getWidth()
246
     {
247
     return mSizeX;
248
     }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251
/**
252
 * Returns the width of the DistortedObject.
253
 *
254
 * @return width of the Object, in pixels.
255
 */
256
  public int getHeight()
257
      {
258
      return mSizeY;
259
      }
260

    
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262
/**
263
 * Returns the depth of the DistortedObject.
264
 *
265
 * @return depth of the Object, in pixels.
266
 */
267
  public int getDepth()
268
      {
269
      return mSizeZ;
270
      }
271

    
272
  }
(5-5/15)