Project

General

Profile

« Previous | Next » 

Revision 1942537e

Added by Leszek Koltunski over 7 years ago

Major restructuring with DistortedTexture. One now is able to create Textures anywhere, even from a thread which does not hold the OpenGL context. Same for DistortedFramebuffers.

View differences:

src/main/java/org/distorted/library/Distorted.java
351 351
    GLES20.glEnableVertexAttribArray(mNormalH);
352 352
    GLES20.glEnableVertexAttribArray(mTextureCoordH);
353 353
   
354
    DistortedTexture.reset();
355 354
    DistortedObjectTree.reset();
356 355
    EffectMessageSender.startSending();
357 356
    }
......
380 379
    DistortedFramebuffer.release();
381 380
    DistortedObjectTree.release();
382 381
    EffectQueue.release();
382
    DistortedEffectQueues.release();
383 383
    EffectMessageSender.stopSending();
384 384
   
385 385
    mInitialized = false;
src/main/java/org/distorted/library/DistortedEffectQueues.java
88 88
   
89 89
  void drawPriv(long currTime, DistortedTexture tex, GridObject grid, DistortedFramebuffer df)
90 90
    {
91
    DistortedFramebuffer.deleteAllMarked();
92

  
93 91
    GLES20.glViewport(0, 0, df.mWidth, df.mHeight);
94 92

  
95 93
    float halfZ = tex.mHalfX*grid.zFactor;
......
132 130
    mF = null;
133 131
    }
134 132

  
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

  
135
  static void release()
136
    {
137
    mNextID = 0;
138
    }
139

  
135 140
///////////////////////////////////////////////////////////////////////////////////////////////////
136 141
// PUBLIC API
137 142
///////////////////////////////////////////////////////////////////////////////////////////////////
......
172 177
 */
173 178
  public void draw(long currTime, DistortedTexture tex, GridObject grid)
174 179
    {
180
    tex.createTexture();
175 181
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
176 182
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex.mTextureDataH[0]);
177 183
    drawPriv(currTime, tex, grid, Distorted.mFramebuffer);
184
    DistortedFramebuffer.deleteAllMarked();
185
    DistortedTexture.deleteAllMarked();
178 186
    }
179 187

  
180 188
///////////////////////////////////////////////////////////////////////////////////////////////////
......
186 194
 */
187 195
  public void draw(long currTime, DistortedTexture tex, GridObject grid, DistortedFramebuffer df)
188 196
    {
197
    tex.createTexture();
189 198
    df.setAsOutput();
190 199
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex.mTextureDataH[0]);
191 200
    drawPriv(currTime, tex, grid, df);
201
    DistortedFramebuffer.deleteAllMarked();
202
    DistortedTexture.deleteAllMarked();
192 203
    }
193 204

  
194 205
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/DistortedFramebuffer.java
48 48
  private static boolean mListMarked = false;
49 49
  private static LinkedList<DistortedFramebuffer> mList = new LinkedList<>();
50 50

  
51
  private float mX, mY;
52
  private float mFOV;
51
  private float mX, mY, mFOV;
53 52

  
54 53
  private int[] texIds = new int[1];
55 54
  private int[] fboIds = new int[1];
......
153 152

  
154 153
  void reset()
155 154
    {
156
    texIds[0] = TEXTURE_NOT_CREATED_YET;
155
    if( texIds[0]!=TEXTURE_DONT_CREATE)
156
      texIds[0] = TEXTURE_NOT_CREATED_YET;
157 157
    }
158 158

  
159 159
///////////////////////////////////////////////////////////////////////////////////////////////////
......
198 198
 * @param width Width of the COLOR attachment.
199 199
 * @param height Height of the COLOR attachment.
200 200
 */
201
  @SuppressWarnings("unused")
201 202
  public DistortedFramebuffer(int width, int height)
202 203
    {
203 204
    mProjectionMatrix = new float[16];
src/main/java/org/distorted/library/DistortedObjectTree.java
86 86
  
87 87
  private void drawRecursive(long currTime, DistortedFramebuffer df)
88 88
    {
89
    mTexture.createTexture();
90

  
89 91
    if( mNumChildren[0]<=0 )
90 92
      {
91 93
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture.mTextureDataH[0]);
......
147 149
    {
148 150
    ArrayList<Long> ret = new ArrayList<>();
149 151
     
150
    ret.add( mNumChildren[0]>0 ? mTexture.getBitmapID() : mTexture.getID() );
152
    ret.add( mTexture.getID() );
151 153
    DistortedObjectTree node;
152 154
   
153 155
    for(int i=0; i<mNumChildren[0]; i++)
......
167 169

  
168 170
    if( otherNodesPoint ) mData.numPointingNodes--;
169 171
    else                  mMapNodeID.remove(oldList);
170
   
172

  
171 173
    NodeData newData = mMapNodeID.get(newList);
172 174
    
173 175
    if( newData==null )
......
224 226

  
225 227
///////////////////////////////////////////////////////////////////////////////////////////////////
226 228
// Debug - print all the Node IDs
227
/*
229

  
228 230
  void debug(int depth)
229 231
    {
230 232
    String tmp="";
231 233
    int i;
232 234

  
233 235
    for(i=0; i<depth; i++) tmp +="   ";
234
    tmp += (""+mData.ID);
236
    tmp += (mData.ID+" (nodes: "+mData.numPointingNodes+")");
235 237

  
236
    android.util.Log.e("node", tmp);
238
    android.util.Log.e("NODE", tmp);
237 239

  
238 240
    for(i=0; i<mNumChildren[0]; i++)
239 241
      mChildren.get(i).debug(depth+1);
......
253 255
      android.util.Log.e("NODE", "key="+key+" NodeID: "+tmp.ID);
254 256
      }
255 257
    }
256
*/
258

  
257 259
///////////////////////////////////////////////////////////////////////////////////////////////////
258 260
// PUBLIC API
259 261
///////////////////////////////////////////////////////////////////////////////////////////////////
......
275 277
    mNumChildren[0] = 0;
276 278
   
277 279
    ArrayList<Long> list = new ArrayList<>();
278
    list.add(queues.getID());   // TODO: this should depend on both texture and queues! Maybe even on grid as well
279
      
280
    list.add(mTexture.getID());
281

  
280 282
    mData = mMapNodeID.get(list);
281 283
   
282 284
    if( mData!=null )
......
286 288
    else
287 289
      {
288 290
      mData = new NodeData(++mNextNodeID);   
289
      mMapNodeID.put(list, mData);  
291
      mMapNodeID.put(list, mData);
290 292
      }
291 293
    }
292 294

  
......
469 471
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
470 472
    markRecursive();
471 473
    drawRecursive(currTime,Distorted.mFramebuffer);
474
    DistortedFramebuffer.deleteAllMarked();
475
    DistortedTexture.deleteAllMarked();
472 476
    }
473 477

  
474 478
///////////////////////////////////////////////////////////////////////////////////////////////////
......
483 487
    df.setAsOutput();
484 488
    markRecursive();
485 489
    drawRecursive(currTime,df);
490
    DistortedFramebuffer.deleteAllMarked();
491
    DistortedTexture.deleteAllMarked();
486 492
    }
487 493

  
488 494
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/DistortedTexture.java
24 24
import android.opengl.GLES20;
25 25
import android.opengl.GLUtils;
26 26

  
27
import java.util.Arrays;
28
import java.util.HashMap;
27
import java.util.Iterator;
28
import java.util.LinkedList;
29 29

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

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

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

  
40 39
  private long mID;
41
  private long mBitmapID=0;
40
  private boolean mMarked;
42 41

  
43 42
  private Bitmap[] mBmp= null; //
44 43
  int[] mTextureDataH;         // have to be shared among all the cloned Objects
......
63 62
    }
64 63

  
65 64
///////////////////////////////////////////////////////////////////////////////////////////////////
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.
65
// must be called from a thread holding OpenGL Context
68 66

  
69
  private void resetTexture()
67
  void createTexture()
70 68
    {
71
    if( mTextureDataH!=null )
69
    if( mBmp[0]!=null && mTextureDataH!=null )
72 70
      {
71
      //android.util.Log.e("Texture", "creating "+mID);
72

  
73 73
      if( mTextureDataH[0]==0 ) GLES20.glGenTextures(1, mTextureDataH, 0);
74 74

  
75 75
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataH[0]);
......
78 78
      GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
79 79
      GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );
80 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
        }
81
      GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, flipBitmap(mBmp[0]), 0);
82
      mBmp[0] = null;
86 83
      }
87 84
    }
88 85

  
89 86
///////////////////////////////////////////////////////////////////////////////////////////////////
87
// must be called from a thread holding OpenGL Context
90 88

  
91
  private void releasePriv()
89
  private void deleteTexture()
92 90
    {
93
    mBmp          = null;
94
    mTextureDataH = null;
95
    }
91
    if( mTextureDataH!=null && mTextureDataH[0]>0 )
92
      {
93
      //android.util.Log.e("Texture", "deleting "+mID);
96 94

  
97
///////////////////////////////////////////////////////////////////////////////////////////////////
95
      GLES20.glDeleteTextures(1, mTextureDataH, 0);
98 96

  
99
  long getBitmapID()
100
    {
101
    if( mBmp!=null && mBitmapID==0 ) mBitmapID = Arrays.hashCode(mBmp);
102
    return mBitmapID;
97
      mTextureDataH[0] = 0;
98
      mBitmapSet[0] = false;
99
      }
100

  
101
    mMarked = false;
103 102
    }
104 103

  
105 104
///////////////////////////////////////////////////////////////////////////////////////////////////
106 105

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

  
112 111
///////////////////////////////////////////////////////////////////////////////////////////////////
113 112

  
114
  static synchronized void reset()
113
  static synchronized void release()
115 114
    {
116
    for(long id: mTextures.keySet())
117
      {
118
      mTextures.get(id).resetTexture();
119
      }
115
    mListMarked = false;
116
    mList.clear();
120 117
    }
121 118

  
122 119
///////////////////////////////////////////////////////////////////////////////////////////////////
120
// must be called form a thread holding OpenGL Context
123 121

  
124
  static synchronized void release()
122
  static synchronized void deleteAllMarked()
125 123
    {
126
    for(long id: mTextures.keySet())
124
    if( mListMarked )
127 125
      {
128
      mTextures.get(id).releasePriv();
129
      }
126
      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
        }
130 139

  
131
    mTextures.clear();
132
    mNextID = 0;
140
      mListMarked = false;
141
      }
133 142
    }
134 143

  
135 144
///////////////////////////////////////////////////////////////////////////////////////////////////
......
140 149
 */
141 150
  public DistortedTexture(int width, int height)
142 151
    {
143
    mID = mNextID++;
144
    mTextures.put(mID,this);
145

  
146 152
    mSizeX= width ; mHalfX = mSizeX/2.0f;
147 153
    mSizeY= height; mHalfY = mSizeY/2.0f;
148 154

  
......
152 158
    mBmp[0]         = null;
153 159
    mBitmapSet      = new boolean[1];
154 160
    mBitmapSet[0]   = false;
161
    mID             = 0;
162
    mMarked         = false;
155 163

  
156
    if( Distorted.isInitialized() ) resetTexture();
164
    mList.add(this);
157 165
    }
158 166

  
159 167
///////////////////////////////////////////////////////////////////////////////////////////////////
......
170 178

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

  
176 181
    mSizeX= dt.mSizeX ; mHalfX = mSizeX/2.0f;
177 182
    mSizeY= dt.mSizeY ; mHalfY = mSizeY/2.0f;
178 183

  
......
181 186
      mTextureDataH = dt.mTextureDataH;
182 187
      mBmp          = dt.mBmp;
183 188
      mBitmapSet    = dt.mBitmapSet;
189
      mID           = dt.getID();
184 190
      }
185 191
    else
186 192
      {
......
190 196
      mBitmapSet[0]   = false;
191 197
      mBmp            = new Bitmap[1];
192 198
      mBmp[0]         = null;
193

  
194
      if( Distorted.isInitialized() ) resetTexture();
199
      mID             = 0;
195 200
      }
201

  
202
    mMarked = false;
203

  
204
    mList.add(this);
196 205
    }
197 206

  
198 207
///////////////////////////////////////////////////////////////////////////////////////////////////
199 208
/**
200
 * Releases all resources.
209
 * Mark the underlying OpenGL object for deletion. Actual deletion will take place on the next render.
201 210
 */
202
  public synchronized void delete()
211
  public void markForDeletion()
203 212
    {
204
    releasePriv();
205
    mTextures.remove(this);
213
    //android.util.Log.e("Texture", "marking for deletion "+mID);
214

  
215
    mListMarked = true;
216
    mMarked     = true;
206 217
    }
207 218

  
208 219
///////////////////////////////////////////////////////////////////////////////////////////////////
209 220
/**
210
 * Sets the underlying android.graphics.Bitmap object and uploads it to the GPU.
221
 * Sets the underlying android.graphics.Bitmap object.
211 222
 * <p>
212 223
 * You can only recycle() the passed Bitmap once the OpenGL context gets created (i.e. after call
213 224
 * to onSurfaceCreated) because only after this point can the Library upload it to the GPU!
......
218 229
  public void setTexture(Bitmap bmp)
219 230
    {
220 231
    mBitmapSet[0] = true;
232
    mBmp[0]       = bmp;
233
    mID           = bmp.hashCode();
221 234

  
222
    if( Distorted.isInitialized() )
223
      {
224
      GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
225
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataH[0]);
226
      GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, flipBitmap(bmp), 0);
227
      }
228
    else
229
      {
230
      mBmp[0] = bmp;
231
      }
235
    //android.util.Log.e("Texture", "setting new bitmap "+mID);
232 236
    }
233 237

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

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

  
256 260
///////////////////////////////////////////////////////////////////////////////////////////////////
257 261
/**
......
264 268
 * @return depth of the Object, in pixels.
265 269
 */
266 270
  public int getDepth(GridObject grid)
267
      {
268
      return grid==null ? 0 : (int)(mSizeX*grid.zFactor);
269
      }
271
    {
272
    return grid==null ? 0 : (int)(mSizeX*grid.zFactor);
273
    }
270 274
  }
src/main/java/org/distorted/library/GridObject.java
35 35
   protected int dataLength;
36 36
   protected FloatBuffer mGridPositions,mGridNormals,mGridTexture;
37 37

  
38
   final float zFactor; // strange workaround the fact that we need to somehow store the 'depth'
38
   final float zFactor; // strange workaround for the fact that we need to somehow store the 'depth'
39 39
                        // of the Grid. Used in DistortedEffectQueues. See DistortedTexture.getDepth().
40 40

  
41 41
///////////////////////////////////////////////////////////////////////////////////////////////////

Also available in: Unified diff