Project

General

Profile

« Previous | Next » 

Revision 42571056

Added by Leszek Koltunski over 7 years ago

Preparation for Transfer Feedback: Convert the meshes from client-side to VBOs.

View differences:

src/main/java/org/distorted/library/Distorted.java
132 132
    {
133 133
    DistortedSurface.onPause();
134 134
    DistortedNode.onPause();
135
    MeshObject.onPause();
135 136
    }
136 137

  
137 138
///////////////////////////////////////////////////////////////////////////////////////////////////
......
143 144
    {
144 145
    DistortedSurface.onDestroy();
145 146
    DistortedNode.onDestroy();
146
    EffectQueue.onDestroy();
147 147
    DistortedEffects.onDestroy();
148 148
    DistortedEffectsPostprocess.onDestroy();
149 149
    DistortedMaster.onDestroy();
150
    EffectQueue.onDestroy();
151
    MeshObject.onDestroy();
150 152
    EffectMessageSender.stopSending();
151 153

  
152 154
    mInitialized = false;
src/main/java/org/distorted/library/DistortedEffects.java
303 303
    mM.send(surface,halfW,halfH,halfZ);
304 304
    mV.send(halfW,halfH,halfZ);
305 305
    mF.send(halfW,halfH);
306
    GLES30.glVertexAttribPointer(mMainProgram.mAttribute[0], POSITION_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mesh.mMeshPositions);
307
    GLES30.glVertexAttribPointer(mMainProgram.mAttribute[1], NORMAL_DATA_SIZE  , GLES30.GL_FLOAT, false, 0, mesh.mMeshNormals);
308
    GLES30.glVertexAttribPointer(mMainProgram.mAttribute[2], TEX_DATA_SIZE     , GLES30.GL_FLOAT, false, 0, mesh.mMeshTexture);
306

  
307
    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mPosVBO[0]);
308
    GLES30.glVertexAttribPointer(mMainProgram.mAttribute[0], POSITION_DATA_SIZE, GLES30.GL_FLOAT, false, 0, 0);
309
    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mNorVBO[0]);
310
    GLES30.glVertexAttribPointer(mMainProgram.mAttribute[1], NORMAL_DATA_SIZE  , GLES30.GL_FLOAT, false, 0, 0);
311
    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mTexVBO[0]);
312
    GLES30.glVertexAttribPointer(mMainProgram.mAttribute[2], TEX_DATA_SIZE     , GLES30.GL_FLOAT, false, 0, 0);
309 313
    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mesh.dataLength);
314
    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0 );
310 315

  
311 316
    /// DEBUG ONLY //////
312 317
    // displayBoundingRect(halfInputW, halfInputH, halfZ, df, mM.getMVP(), mesh.getBoundingVertices() );
src/main/java/org/distorted/library/DistortedOutputSurface.java
234 234
    {
235 235
    // change tree topology (attach and detach children)
236 236
/*
237
    boolean changed =
237
    boolean changed1 =
238 238
*/
239 239
    DistortedMaster.toDo();
240 240
/*
241
    // debugging only
242
    if( changed )
241
    if( changed1 )
243 242
      {
244 243
      for(int i=0; i<mNumChildren; i++)
245 244
        {
......
254 253
    // with OpenGL resources. That's because changing Tree
255 254
    // can result in additional Framebuffers that would need
256 255
    // to be created immediately, before the calls to drawRecursive()
256
/*
257
    boolean changed2 =
258
*/
257 259
    toDo();
258 260
/*
259
    // debugging only
260
    if( changed )
261
    if( changed2 )
261 262
      {
262 263
      DistortedSurface.debugLists();
263 264
      }
265
*/
266
    // create and delete all Meshes (we need to create Vertex Buffer Objects)
267
/*
268
    boolean changed3 =
269
*/
270
    MeshObject.toDo();
271
/*
272
    if( changed3 )
273
      {
274
      MeshObject.debugLists();
275
      }
264 276
*/
265 277
    // mark OpenGL state as unknown
266 278
    DistortedRenderState.reset();
src/main/java/org/distorted/library/DistortedSurface.java
77 77
///////////////////////////////////////////////////////////////////////////////////////////////////
78 78
// must be called from a thread holding OpenGL Context
79 79

  
80
  static synchronized void toDo()
80
  static synchronized boolean toDo()
81 81
    {
82 82
    if( mToDo )
83 83
      {
......
104 104

  
105 105
      mToDoMap.clear();
106 106
      mToDo = false;
107
      return true;
107 108
      }
109

  
110
    return false;
108 111
    }
109 112

  
110 113
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/MeshObject.java
19 19

  
20 20
package org.distorted.library;
21 21

  
22
import android.opengl.GLES30;
23

  
22 24
import java.nio.FloatBuffer;
25
import java.util.HashMap;
26
import java.util.LinkedList;
23 27

  
24 28
///////////////////////////////////////////////////////////////////////////////////////////////////
25 29
/**
......
36 40
   static final int NORMAL_DATA_SIZE  = 3; // Size of the normal data in elements.
37 41
   static final int TEX_DATA_SIZE     = 2; // Size of the texture coordinate data in elements.
38 42

  
43
   ///// CREATING/DELETING Vertex Buffer Objects ///////////////////////////
44
   private static final int JOB_CREATE = 0;
45
   private static final int JOB_DELETE = 1;
46

  
47
   private class Job
48
     {
49
     MeshObject mesh;
50
     int action;
51

  
52
     Job(MeshObject o, int a)
53
       {
54
       mesh   = o;
55
       action = a;
56
       }
57
     }
58

  
59
   private static boolean mToDo = false;
60
   private static LinkedList<MeshObject> mDoneList = new LinkedList<>();
61
   private static HashMap<Long,Job> mToDoMap = new HashMap<>();
62
   /////////////////////////////////////////////////////////////////////////
63

  
64
   private static long mNextID = 0;
65
   private long mID;
66

  
39 67
   int dataLength;
40 68
   FloatBuffer mMeshPositions, mMeshNormals, mMeshTexture;
69
   int[] mPosVBO = new int[1];
70
   int[] mNorVBO = new int[1];
71
   int[] mTexVBO = new int[1];
41 72

  
42 73
   final float zFactor; // strange workaround for the fact that we need to somehow store the 'depth'
43 74
                        // of the Mesh. Used in DistortedEffects. See DistortedTexture.getDepth().
......
47 78
   MeshObject(float factor)
48 79
     {
49 80
     zFactor = factor;
81
     mID     = mNextID++;
82

  
83
     recreate();
84

  
85
     mToDoMap.put(mID, new Job(this,JOB_CREATE) );
86
     mToDo = true;
50 87
     }
51 88

  
52 89
///////////////////////////////////////////////////////////////////////////////////////////////////
90
// must be called from a thread holding OpenGL Context
91

  
92
   static synchronized boolean toDo()
93
     {
94
     if( mToDo )
95
       {
96
       Job job;
97
       MeshObject mesh;
98

  
99
       for(Long key: mToDoMap.keySet())
100
         {
101
         job = mToDoMap.get(key);
102
         mesh = job.mesh;
103

  
104
         //android.util.Log.d("MESH", "  ---> need to "+(job.action==JOB_CREATE ? "create":"delete") );
105

  
106
         if( job.action==JOB_CREATE )
107
           {
108
           mesh.create();
109
           mDoneList.add(mesh);
110
           }
111
         else if( job.action==JOB_DELETE )
112
           {
113
           mesh.delete();
114
           }
115
         }
116

  
117
       mToDoMap.clear();
118
       mToDo = false;
119
       return true;
120
       }
121

  
122
     return false;
123
     }
124

  
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126
// must be called from a thread holding OpenGL Context
127
//
128
// Do NOT release mMeshPositions etc as we will need them when we need to re-create the buffers after
129
// a loss of OpenGL context!
130

  
131
   private void create()
132
     {
133
     if( mPosVBO[0]<0 )
134
       {
135
       GLES30.glGenBuffers(1, mPosVBO, 0);
136
       GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mPosVBO[0]);
137
       GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, dataLength*POSITION_DATA_SIZE*BYTES_PER_FLOAT, mMeshPositions, GLES30.GL_STATIC_READ);
138
       }
139
     if( mNorVBO[0]<0 )
140
       {
141
       GLES30.glGenBuffers(1, mNorVBO, 0);
142
       GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mNorVBO[0]);
143
       GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, dataLength*  NORMAL_DATA_SIZE*BYTES_PER_FLOAT, mMeshNormals  , GLES30.GL_STATIC_READ);
144
       }
145
     if( mTexVBO[0]<0 )
146
       {
147
       GLES30.glGenBuffers(1, mTexVBO, 0);
148
       GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mTexVBO[0]);
149
       GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, dataLength*    TEX_DATA_SIZE*BYTES_PER_FLOAT, mMeshTexture  , GLES30.GL_STATIC_READ);
150
       }
151

  
152
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
153
     }
154

  
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156
// must be called from a thread holding OpenGL Context
157

  
158
   private void delete()
159
     {
160
     if( mPosVBO[0]>=0 )
161
       {
162
       GLES30.glDeleteBuffers(1, mPosVBO, 0);
163
       mPosVBO[0] = -1;
164
       }
165
     if( mNorVBO[0]>=0 )
166
       {
167
       GLES30.glDeleteBuffers(1, mNorVBO, 0);
168
       mNorVBO[0] = -1;
169
       }
170
     if( mTexVBO[0]>=0 )
171
       {
172
       GLES30.glDeleteBuffers(1, mTexVBO, 0);
173
       mTexVBO[0] = -1;
174
       }
175
     }
176

  
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

  
179
   private void recreate()
180
     {
181
     mPosVBO[0] = -1;
182
     mNorVBO[0] = -1;
183
     mTexVBO[0] = -1;
184
     }
185

  
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187

  
188
  static synchronized void onPause()
189
    {
190
    MeshObject mesh;
191
    int num = mDoneList.size();
192

  
193
    for(int i=0; i<num; i++)
194
      {
195
      mesh = mDoneList.removeFirst();
196
      mToDoMap.put(mesh.getID(), mesh.new Job(mesh,JOB_CREATE) );
197
      mesh.recreate();
198
      }
199

  
200
    mToDo = true;
201
    }
202

  
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204

  
205
  static synchronized void onDestroy()
206
    {
207
    mToDoMap.clear();
208
    mDoneList.clear();
209

  
210
    mToDo = true;
211
    mNextID = 0;
212
    }
213

  
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

  
216
  @SuppressWarnings("unused")
217
  static void debugLists()
218
    {
219
    android.util.Log.e("Mesh", "Done list:");
220

  
221
    MeshObject mesh;
222
    int num = mDoneList.size();
223

  
224
    for(int i=0; i<num; i++)
225
      {
226
      mesh = mDoneList.get(i);
227
      mesh.print(i, "");
228
      }
229

  
230
    android.util.Log.e("Mesh", "ToDo list:");
231

  
232
    Job job;
233
    int i=0;
234

  
235
    for(Long key: mToDoMap.keySet())
236
      {
237
      job = mToDoMap.get(key);
238
      job.mesh.print(i++, job.action==JOB_CREATE ? " create":" delete");
239
      }
240
    }
241

  
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243

  
244
  private void print(int i, String extra)
245
    {
246
    String str;
247

  
248
         if( this instanceof MeshFlat ) str = (i+": MeshFlat  ");
249
    else if( this instanceof MeshCubes) str = (i+": MeshCubes ");
250
    else                                str = (i+": UNKNOWN   ");
251

  
252
    str += ( "dataLength: "+dataLength+" meshID:"+getID());
253

  
254
    android.util.Log.e("Mesh", str+extra);
255
    }
256
///////////////////////////////////////////////////////////////////////////////////////////////////
53 257
/**
54 258
 * Get the minimal set of Vertices which have the same convex hull as the whole set.
55 259
 * <p>
......
59 263
 * This is used to be able to quickly compute, in window coordinates, the Mesh'es bounding rectangle.
60 264
 */
61 265
   abstract float[] getBoundingVertices();
266

  
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

  
269
   synchronized void markForCreation()
270
     {
271
     mDoneList.remove(this);
272
     mToDoMap.put(mID, new Job(this,JOB_CREATE) );
273
     mToDo = true;
274
     }
275

  
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277
// PUBLIC API
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279
/**
280
 * Mark the underlying OpenGL object for deletion. Actual deletion will take place on the next render.
281
 */
282
   synchronized public void markForDeletion()
283
     {
284
     mDoneList.remove(this);
285
     mToDoMap.put(mID, new Job(this,JOB_DELETE) );
286
     mToDo = true;
287
     }
288

  
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290
/**
291
 * Return unique ID of this Mesh.
292
 */
293
   public long getID()
294
    {
295
    return mID;
296
    }
62 297
   }

Also available in: Unified diff