Project

General

Profile

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

library / src / main / java / org / distorted / library / mesh / MeshBase.java @ 2aeb75aa

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.mesh;
21

    
22
import android.opengl.GLES30;
23
import android.util.Log;
24

    
25
import org.distorted.library.effect.VertexEffect;
26
import org.distorted.library.effectqueue.EffectQueue;
27
import org.distorted.library.main.InternalBuffer;
28
import org.distorted.library.program.DistortedProgram;
29
import org.distorted.library.type.Static4D;
30

    
31
import java.nio.ByteBuffer;
32
import java.nio.ByteOrder;
33
import java.nio.FloatBuffer;
34
import java.util.ArrayList;
35

    
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37
/**
38
 * Abstract class which represents a Mesh, ie an array of vertices (rendered as a TRIANGLE_STRIP).
39
 * <p>
40
 * If you want to render to a particular shape, extend from here, construct a float array
41
 * containing per-vertex attributes, and call back setAttribs().
42
 */
43
public abstract class MeshBase
44
   {
45
   private static final int MAX_COMPONENTS= 100;
46
   private static final int DEFAULT_ASSOCIATION = 0xffffffff;
47

    
48
   // sizes of attributes of an individual vertex.
49
   private static final int POS_DATA_SIZE= 3; // vertex coordinates: x,y,z
50
   private static final int NOR_DATA_SIZE= 3; // normal vector: x,y,z
51
   private static final int INF_DATA_SIZE= 3; // 'inflate' vector: x,y,z
52
   private static final int TEX_DATA_SIZE= 2; // texture coordinates: s,t
53
   private static final int COM_DATA_SIZE= 1; // component number, a single float
54

    
55
   static final int POS_ATTRIB   = 0;
56
   static final int NOR_ATTRIB   = POS_DATA_SIZE;
57
   static final int INF_ATTRIB   = POS_DATA_SIZE + NOR_DATA_SIZE;
58
   static final int TEX_ATTRIB   = 0;
59
   static final int COM_ATTRIB   = TEX_DATA_SIZE;
60

    
61
   static final int VERT1_ATTRIBS= POS_DATA_SIZE + NOR_DATA_SIZE + INF_DATA_SIZE;  // number of attributes of a vertex (the part changed by preapply)
62
   static final int VERT2_ATTRIBS= TEX_DATA_SIZE + COM_DATA_SIZE;                  // number of attributes of a vertex (the 'preapply invariant' part)
63
   static final int TRAN_ATTRIBS = POS_DATA_SIZE + NOR_DATA_SIZE + INF_DATA_SIZE;  // number of attributes of a transform feedback vertex
64

    
65
   private static final int BYTES_PER_FLOAT = 4;
66

    
67
   private static final int OFFSET_POS = POS_ATTRIB*BYTES_PER_FLOAT;
68
   private static final int OFFSET_NOR = NOR_ATTRIB*BYTES_PER_FLOAT;
69
   private static final int OFFSET_INF = INF_ATTRIB*BYTES_PER_FLOAT;
70
   private static final int OFFSET_TEX = TEX_ATTRIB*BYTES_PER_FLOAT;
71
   private static final int OFFSET_COM = COM_ATTRIB*BYTES_PER_FLOAT;
72

    
73
   private static final int TRAN_SIZE  = TRAN_ATTRIBS*BYTES_PER_FLOAT;
74
   private static final int VERT1_SIZE = VERT1_ATTRIBS*BYTES_PER_FLOAT;
75
   private static final int VERT2_SIZE = VERT2_ATTRIBS*BYTES_PER_FLOAT;
76

    
77
   private boolean mShowNormals;              // when rendering this mesh, draw normal vectors?
78
   private InternalBuffer mVBO1, mVBO2, mTFO; // main vertex buffer and transform feedback buffer
79
   private int mNumVertices;
80
   private float[] mVertAttribs1;             // packed: PosX,PosY,PosZ, NorX,NorY,NorZ, InfX,InfY,InfZ
81
   private float[] mVertAttribs2;             // packed: TexS,TexT, Component
82
   private float mInflate;
83
   private int[] mEquAssociation;
84
   private int[] mAndAssociation;
85

    
86
   DeferredJobs.JobNode[] mJobNode;
87

    
88
   private static int[] mEquAssociationH = new int[EffectQueue.MAIN_VARIANTS];
89
   private static int[] mAndAssociationH = new int[EffectQueue.MAIN_VARIANTS];
90

    
91
   private static class Component
92
     {
93
     private int mEndIndex;
94
     private Static4D mTextureMap;
95

    
96
     Component(int end)
97
       {
98
       mEndIndex  = end;
99
       mTextureMap= new Static4D(0,0,1,1);
100
       }
101
     Component(Component original)
102
       {
103
       mEndIndex = original.mEndIndex;
104

    
105
       float x = original.mTextureMap.get0();
106
       float y = original.mTextureMap.get1();
107
       float z = original.mTextureMap.get2();
108
       float w = original.mTextureMap.get3();
109
       mTextureMap = new Static4D(x,y,z,w);
110
       }
111

    
112
     void setMap(Static4D map)
113
       {
114
       mTextureMap.set(map.get0(),map.get1(),map.get2(),map.get3());
115
       }
116
     }
117

    
118
   private ArrayList<Component> mComponent;
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
   MeshBase()
123
     {
124
     mShowNormals= false;
125
     mInflate    = 0.0f;
126
     mComponent  = new ArrayList<>();
127
     mEquAssociation= new int[MAX_COMPONENTS];
128
     mAndAssociation= new int[MAX_COMPONENTS];
129

    
130
     mJobNode = new DeferredJobs.JobNode[1];
131

    
132
     for(int i=0; i<MAX_COMPONENTS; i++)
133
       {
134
       mAndAssociation[i] = DEFAULT_ASSOCIATION;
135
       mEquAssociation[i] = i;
136
       }
137

    
138
     mVBO1= new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
139
     mVBO2= new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
140
     mTFO = new InternalBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, GLES30.GL_STATIC_READ);
141
     }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144
// copy constructor
145

    
146
   MeshBase(MeshBase original, boolean deep)
147
     {
148
     mShowNormals= original.mShowNormals;
149
     mInflate    = original.mInflate;
150
     mNumVertices= original.mNumVertices;
151

    
152
     mAndAssociation= new int[MAX_COMPONENTS];
153
     System.arraycopy(original.mAndAssociation, 0, mAndAssociation, 0, MAX_COMPONENTS);
154
     mEquAssociation= new int[MAX_COMPONENTS];
155
     System.arraycopy(original.mEquAssociation, 0, mEquAssociation, 0, MAX_COMPONENTS);
156

    
157
     if( deep )
158
       {
159
       mJobNode = new DeferredJobs.JobNode[1];
160
       if( original.mJobNode[0]==null ) copy(original);
161
       else mJobNode[0] = DeferredJobs.copy(this,original);
162
       }
163
     else
164
       {
165
       mJobNode      = original.mJobNode;
166
       mVBO1         = original.mVBO1;
167
       mVertAttribs1 = original.mVertAttribs1;
168
       shallowCopy(original);
169
       }
170

    
171
     mTFO = new InternalBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, GLES30.GL_STATIC_READ);
172
     mTFO.invalidate();
173
     }
174

    
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176

    
177
   void copy(MeshBase original)
178
     {
179
     shallowCopy(original);
180

    
181
     mVBO1= new InternalBuffer(GLES30.GL_ARRAY_BUFFER, GLES30.GL_STATIC_READ);
182
     mVertAttribs1= new float[mNumVertices*VERT1_ATTRIBS];
183
     System.arraycopy(original.mVertAttribs1,0,mVertAttribs1,0,mNumVertices*VERT1_ATTRIBS);
184
     mVBO1.invalidate();
185
     }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
   private void shallowCopy(MeshBase original)
190
     {
191
     int size = original.mComponent.size();
192
     mComponent = new ArrayList<>();
193

    
194
     for(int i=0; i<size; i++)
195
       {
196
       Component comp = new Component(original.mComponent.get(i));
197
       mComponent.add(comp);
198
       }
199

    
200
     mVBO2= new InternalBuffer(GLES30.GL_ARRAY_BUFFER, GLES30.GL_STATIC_READ);
201
     mVertAttribs2= new float[mNumVertices*VERT2_ATTRIBS];
202
     System.arraycopy(original.mVertAttribs2,0,mVertAttribs2,0,mNumVertices*VERT2_ATTRIBS);
203
     mVBO2.invalidate();
204
     }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
   void merge()
209
     {
210
     int num = mComponent.size();
211

    
212
     if( num>1 )
213
       {
214
       mComponent.clear();
215
       mComponent.add(new Component(mNumVertices-1));
216

    
217
       for(int index=0; index<mNumVertices; index++)
218
         {
219
         mVertAttribs2[VERT2_ATTRIBS*index+COM_ATTRIB] = 0;
220
         }
221

    
222
       mVBO2.invalidate();
223
       }
224
     }
225

    
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227

    
228
   int numComponents()
229
     {
230
     return mComponent.size();
231
     }
232

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234
// when a derived class is done computing its mesh, it has to call this method.
235

    
236
   void setAttribs(float[] vert1Attribs, float[] vert2Attribs)
237
     {
238
     mNumVertices = vert1Attribs.length/VERT1_ATTRIBS;
239
     mVertAttribs1= vert1Attribs;
240
     mVertAttribs2= vert2Attribs;
241

    
242
     mComponent.add(new Component(mNumVertices-1));
243

    
244
     mVBO1.invalidate();
245
     mVBO2.invalidate();
246
     }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249

    
250
   void joinAttribs(MeshBase[] meshes)
251
     {
252
     MeshBase mesh;
253
     Component comp;
254
     int numMeshes = meshes.length;
255
     int origVertices = mNumVertices;
256
     int origComponents=0,numComponents,numVertices;
257

    
258
     if( origVertices>0 )
259
       {
260
       origComponents = mComponent.size();
261
       mNumVertices+= ( mNumVertices%2==1 ? 2:1 );
262
       mComponent.get(origComponents-1).mEndIndex = mNumVertices-1;
263
       }
264

    
265
     for(int i=0; i<numMeshes; i++)
266
       {
267
       mesh = meshes[i];
268
       numComponents = mesh.mComponent.size();
269
       numVertices = mesh.mNumVertices;
270

    
271
       int extraVerticesBefore = mNumVertices==0 ? 0:1;
272
       int extraVerticesAfter  = (i==numMeshes-1) ? 0 : (numVertices%2==1 ? 2:1);
273

    
274
       for(int j=0; j<numComponents; j++)
275
         {
276
         comp = new Component(mesh.mComponent.get(j));
277
         comp.mEndIndex += (extraVerticesBefore+mNumVertices+extraVerticesAfter);
278
         mComponent.add(comp);
279

    
280
         if( origComponents<MAX_COMPONENTS )
281
           {
282
           mAndAssociation[origComponents] = mesh.mAndAssociation[j];
283
           mEquAssociation[origComponents] = mesh.mEquAssociation[j];
284
           origComponents++;
285
           }
286
         }
287

    
288
       mNumVertices += (extraVerticesBefore+numVertices+extraVerticesAfter);
289
       }
290

    
291
     float[] newAttribs1 = new float[VERT1_ATTRIBS*mNumVertices];
292
     float[] newAttribs2 = new float[VERT2_ATTRIBS*mNumVertices];
293
     numVertices = origVertices;
294

    
295
     if( origVertices>0 )
296
       {
297
       System.arraycopy(mVertAttribs1,                              0, newAttribs1,                         0, VERT1_ATTRIBS*numVertices);
298
       System.arraycopy(mVertAttribs1, VERT1_ATTRIBS*(origVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS    );
299
       System.arraycopy(mVertAttribs2,                              0, newAttribs2,                         0, VERT2_ATTRIBS*numVertices);
300
       System.arraycopy(mVertAttribs2, VERT2_ATTRIBS*(origVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS    );
301
       origVertices++;
302

    
303
       if( numVertices%2==1 )
304
         {
305
         System.arraycopy(mVertAttribs1, VERT1_ATTRIBS*(origVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS);
306
         System.arraycopy(mVertAttribs2, VERT2_ATTRIBS*(origVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS);
307
         origVertices++;
308
         }
309
       }
310

    
311
     for(int i=0; i<numMeshes; i++)
312
       {
313
       mesh = meshes[i];
314
       numVertices = mesh.mNumVertices;
315

    
316
       if( origVertices>0 )
317
         {
318
         System.arraycopy(mesh.mVertAttribs1, 0, newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS    );
319
         System.arraycopy(mesh.mVertAttribs2, 0, newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS    );
320
         origVertices++;
321
         }
322
       System.arraycopy(mesh.mVertAttribs1, 0, newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS*numVertices);
323
       System.arraycopy(mesh.mVertAttribs2, 0, newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS*numVertices);
324
       origVertices+=numVertices;
325

    
326
       if( i<numMeshes-1 )
327
         {
328
         System.arraycopy(mesh.mVertAttribs1, VERT1_ATTRIBS*(numVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS);
329
         System.arraycopy(mesh.mVertAttribs2, VERT2_ATTRIBS*(numVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS);
330
         origVertices++;
331

    
332
         if( numVertices%2==1 )
333
           {
334
           System.arraycopy(mesh.mVertAttribs1, VERT1_ATTRIBS*(numVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS);
335
           System.arraycopy(mesh.mVertAttribs2, VERT2_ATTRIBS*(numVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS);
336
           origVertices++;
337
           }
338
         }
339
       }
340

    
341
     if( origVertices!=mNumVertices )
342
       {
343
       android.util.Log.e("mesh", "join: origVertices: "+origVertices+" numVertices: "+mNumVertices);
344
       }
345

    
346
     int endIndex, index=0, numComp = mComponent.size();
347

    
348
     for(int component=0; component<numComp; component++)
349
       {
350
       endIndex = mComponent.get(component).mEndIndex;
351

    
352
       for( ; index<=endIndex; index++) newAttribs2[VERT2_ATTRIBS*index+COM_ATTRIB] = component;
353
       }
354

    
355
     mVertAttribs1 = newAttribs1;
356
     mVertAttribs2 = newAttribs2;
357
     mVBO1.invalidate();
358
     mVBO2.invalidate();
359
     }
360

    
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362
// called from MeshJoined
363

    
364
   void join(MeshBase[] meshes)
365
     {
366
     boolean immediateJoin = true;
367

    
368
     for (MeshBase mesh : meshes)
369
       {
370
       if (mesh.mJobNode[0] != null)
371
         {
372
         immediateJoin = false;
373
         break;
374
         }
375
       }
376

    
377
     if( immediateJoin ) joinAttribs(meshes);
378
     else                mJobNode[0] = DeferredJobs.join(this,meshes);
379
     }
380

    
381
///////////////////////////////////////////////////////////////////////////////////////////////////
382

    
383
   void textureMap(Static4D[] maps)
384
     {
385
     int num_comp = mComponent.size();
386
     int num_maps = maps.length;
387
     int min = Math.min(num_comp, num_maps);
388
     int vertex = 0;
389
     Static4D newMap, oldMap;
390
     Component comp;
391
     float newW, newH, ratW, ratH, movX, movY;
392

    
393
     for(int i=0; i<min; i++)
394
       {
395
       newMap = maps[i];
396
       comp = mComponent.get(i);
397

    
398
       if( newMap!=null )
399
         {
400
         newW = newMap.get2();
401
         newH = newMap.get3();
402

    
403
         if( newW!=0.0f && newH!=0.0f )
404
           {
405
           oldMap = comp.mTextureMap;
406
           ratW = newW/oldMap.get2();
407
           ratH = newH/oldMap.get3();
408
           movX = newMap.get0() - ratW*oldMap.get0();
409
           movY = newMap.get1() - ratH*oldMap.get1();
410

    
411
           for( int index=vertex*VERT2_ATTRIBS+TEX_ATTRIB ; vertex<=comp.mEndIndex; vertex++, index+=VERT2_ATTRIBS)
412
             {
413
             mVertAttribs2[index  ] = ratW*mVertAttribs2[index  ] + movX;
414
             mVertAttribs2[index+1] = ratH*mVertAttribs2[index+1] + movY;
415
             }
416
           comp.setMap(newMap);
417
           }
418
         }
419

    
420
       vertex= comp.mEndIndex+1;
421
       }
422

    
423
     mVBO2.invalidate();
424
     }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

    
428
   public static int getMaxComponents()
429
     {
430
     return MAX_COMPONENTS;
431
     }
432

    
433
///////////////////////////////////////////////////////////////////////////////////////////////////
434

    
435
   public static void getUniforms(int mProgramH, int variant)
436
     {
437
     mEquAssociationH[variant] = GLES30.glGetUniformLocation( mProgramH, "vComEquAssoc");
438
     mAndAssociationH[variant] = GLES30.glGetUniformLocation( mProgramH, "vComAndAssoc");
439
     }
440

    
441
///////////////////////////////////////////////////////////////////////////////////////////////////
442
/**
443
 * Not part of public API, do not document (public only because has to be used from the main package)
444
 *
445
 * @y.exclude
446
 */
447
   public void copyTransformToVertex()
448
     {
449
     ByteBuffer buffer = (ByteBuffer)GLES30.glMapBufferRange( GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0,
450
                                                              TRAN_SIZE*mNumVertices, GLES30.GL_MAP_READ_BIT);
451
     if( buffer!=null )
452
       {
453
       FloatBuffer feedback = buffer.order(ByteOrder.nativeOrder()).asFloatBuffer();
454
       feedback.get(mVertAttribs1,0,VERT1_ATTRIBS*mNumVertices);
455
       mVBO1.update(mVertAttribs1);
456
       }
457
     else
458
       {
459
       int error = GLES30.glGetError();
460
       Log.e("mesh", "failed to map tf buffer, error="+error);
461
       }
462

    
463
     GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK);
464
     }
465

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467
/**
468
 * Not part of public API, do not document (public only because has to be used from the main package)
469
 *
470
 * @y.exclude
471
 */
472
   public void debug()
473
     {
474
     if( mJobNode[0]!=null )
475
       {
476
       mJobNode[0].print(0);
477
       }
478
     else
479
       {
480
       android.util.Log.e("mesh", "JobNode null");
481
       }
482
     }
483

    
484
///////////////////////////////////////////////////////////////////////////////////////////////////
485
/**
486
 * Not part of public API, do not document (public only because has to be used from the main package)
487
 *
488
 * @y.exclude
489
 */
490
   public void print()
491
     {
492
     StringBuffer sb = new StringBuffer();
493

    
494
     for(int i=0; i<mNumVertices; i++)
495
       {
496
       sb.append('(');
497
       sb.append(mVertAttribs1[VERT1_ATTRIBS*i+POS_ATTRIB  ]);
498
       sb.append(',');
499
       sb.append(mVertAttribs1[VERT1_ATTRIBS*i+POS_ATTRIB+1]);
500
       sb.append(',');
501
       sb.append(mVertAttribs1[VERT1_ATTRIBS*i+POS_ATTRIB+2]);
502
       sb.append(") ");
503
       }
504

    
505
     StringBuffer sb2 = new StringBuffer();
506

    
507
     for(int i=0; i<mNumVertices; i++)
508
       {
509
       sb2.append(mVertAttribs2[VERT2_ATTRIBS*i+COM_ATTRIB]);
510
       sb2.append(' ');
511
       }
512

    
513
     Log.d("mesh", sb.toString()+"\n"+sb2.toString());
514
     }
515

    
516
///////////////////////////////////////////////////////////////////////////////////////////////////
517
/**
518
 * Not part of public API, do not document (public only because has to be used from the main package)
519
 *
520
 * @y.exclude
521
 */
522
   public int getTFO()
523
     {
524
     return mTFO.createImmediately(mNumVertices*TRAN_SIZE, null);
525
     }
526

    
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528
/**
529
 * Not part of public API, do not document (public only because has to be used from the main package)
530
 *
531
 * @y.exclude
532
 */
533
   public int getNumVertices()
534
     {
535
     return mNumVertices;
536
     }
537

    
538
///////////////////////////////////////////////////////////////////////////////////////////////////
539
/**
540
 * Not part of public API, do not document (public only because has to be used from the main package)
541
 *
542
 * @y.exclude
543
 */
544
   public void send(int variant)
545
     {
546
     GLES30.glUniform1iv( mEquAssociationH[variant], MAX_COMPONENTS, mEquAssociation, 0);
547
     GLES30.glUniform1iv( mAndAssociationH[variant], MAX_COMPONENTS, mAndAssociation, 0);
548
     }
549

    
550
///////////////////////////////////////////////////////////////////////////////////////////////////
551
/**
552
 * Not part of public API, do not document (public only because has to be used from the main package)
553
 *
554
 * @y.exclude
555
 */
556
   public void bindVertexAttribs(DistortedProgram program)
557
     {
558
     if( mJobNode[0]!=null )
559
       {
560
       mJobNode[0].execute();  // this will set itself to null
561
       }
562

    
563
     int index1 = mVBO1.createImmediately(mNumVertices*VERT1_SIZE, mVertAttribs1);
564
     int index2 = mVBO2.createImmediately(mNumVertices*VERT2_SIZE, mVertAttribs2);
565

    
566
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, index1 );
567
     GLES30.glVertexAttribPointer(program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, VERT1_SIZE, OFFSET_POS);
568
     GLES30.glVertexAttribPointer(program.mAttribute[1], NOR_DATA_SIZE, GLES30.GL_FLOAT, false, VERT1_SIZE, OFFSET_NOR);
569
     GLES30.glVertexAttribPointer(program.mAttribute[2], INF_DATA_SIZE, GLES30.GL_FLOAT, false, VERT1_SIZE, OFFSET_INF);
570
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, index2 );
571
     GLES30.glVertexAttribPointer(program.mAttribute[3], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, VERT2_SIZE, OFFSET_TEX);
572
     GLES30.glVertexAttribPointer(program.mAttribute[4], COM_DATA_SIZE, GLES30.GL_FLOAT, false, VERT2_SIZE, OFFSET_COM);
573
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
574
     }
575

    
576
///////////////////////////////////////////////////////////////////////////////////////////////////
577
/**
578
 * Not part of public API, do not document (public only because has to be used from the main package)
579
 *
580
 * @y.exclude
581
 */
582
   public void bindTransformAttribs(DistortedProgram program)
583
     {
584
     int index = mTFO.createImmediately(mNumVertices*TRAN_SIZE, null);
585

    
586
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, index );
587
     GLES30.glVertexAttribPointer(program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, 0);
588
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
589
     }
590

    
591
///////////////////////////////////////////////////////////////////////////////////////////////////
592
/**
593
 * Not part of public API, do not document (public only because has to be used from the main package)
594
 *
595
 * @y.exclude
596
 */
597
   public void setInflate(float inflate)
598
     {
599
     mInflate = inflate;
600
     }
601

    
602
///////////////////////////////////////////////////////////////////////////////////////////////////
603
/**
604
 * Not part of public API, do not document (public only because has to be used from the main package)
605
 *
606
 * @y.exclude
607
 */
608
   public float getInflate()
609
     {
610
     return mInflate;
611
     }
612

    
613
///////////////////////////////////////////////////////////////////////////////////////////////////
614
// PUBLIC API
615
///////////////////////////////////////////////////////////////////////////////////////////////////
616
/**
617
 * When rendering this Mesh, do we want to render the Normal vectors as well?
618
 * <p>
619
 * Will work only on OpenGL ES >= 3.0 devices.
620
 *
621
 * @param show Controls if we render the Normal vectors or not.
622
 */
623
   public void setShowNormals(boolean show)
624
     {
625
     mShowNormals = show;
626
     }
627

    
628
///////////////////////////////////////////////////////////////////////////////////////////////////
629
/**
630
 * When rendering this mesh, should we also draw the normal vectors?
631
 *
632
 * @return <i>true</i> if we do render normal vectors
633
 */
634
   public boolean getShowNormals()
635
     {
636
     return mShowNormals;
637
     }
638

    
639
///////////////////////////////////////////////////////////////////////////////////////////////////
640
/**
641
 * Merge all components of this Mesh into a single one.
642
 */
643
   public void mergeComponents()
644
     {
645
     if( mJobNode[0]==null )
646
       {
647
       merge();
648
       }
649
     else
650
       {
651
       mJobNode[0] = DeferredJobs.merge(this);
652
       }
653
     }
654

    
655
///////////////////////////////////////////////////////////////////////////////////////////////////
656
/**
657
 * Release all internal resources.
658
 */
659
   public void markForDeletion()
660
     {
661
     mVertAttribs1 = null;
662
     mVertAttribs2 = null;
663

    
664
     mVBO1.markForDeletion();
665
     mVBO2.markForDeletion();
666
     mTFO.markForDeletion();
667
     }
668

    
669
///////////////////////////////////////////////////////////////////////////////////////////////////
670
/**
671
 * Apply a Vertex Effect to the vertex mesh.
672
 * <p>
673
 * This is a static, permanent modification of the vertices contained in this Mesh. If the effects
674
 * contain any Dynamics, the Dynamics will be evaluated at 0.
675
 *
676
 * We would call this several times building up a list of Effects to do. This list of effects gets
677
 * lazily executed only when the Mesh is used for rendering for the first time.
678
 *
679
 * @param effect Vertex Effect to apply to the Mesh.
680
 */
681
   public void apply(VertexEffect effect)
682
     {
683
     mJobNode[0] = DeferredJobs.vertex(this,effect);
684
     }
685

    
686
///////////////////////////////////////////////////////////////////////////////////////////////////
687
/**
688
 * Sets texture maps for (some of) the components of this mesh.
689
 * <p>
690
 * Format: ( x of lower-left corner, y of lower-left corner, width, height ).
691
 * For example maps[0] = new Static4D( 0.0, 0.5, 0.5, 0.5 ) sets the 0th component texture map to the
692
 * upper-left quadrant of the texture.
693
 * <p>
694
 * Probably the most common user case would be sending as many maps as there are components in this
695
 * Mesh. One can also send less, or more (the extraneous ones will be ignored) and set some of them
696
 * to null (those will be ignored as well). So if there are 5 components, and we want to set the map
697
 * of the 2nd and 4rd one, call this with
698
 * maps = new Static4D[4]
699
 * maps[0] = null
700
 * maps[1] = the map for the 2nd component
701
 * maps[2] = null
702
 * maps[3] = the map for the 4th component
703
 *
704
 * A map's width and height have to be non-zero (but can be negative!)
705
 *
706
 * @param maps List of texture maps to apply to the texture's components.
707
 */
708
   public void setTextureMap(Static4D[] maps)
709
     {
710
     if( mJobNode[0]==null )
711
       {
712
       textureMap(maps);
713
       }
714
     else
715
       {
716
       mJobNode[0] = DeferredJobs.textureMap(this,maps);
717
       }
718
     }
719

    
720
///////////////////////////////////////////////////////////////////////////////////////////////////
721
/**
722
 * Return the texture map of one of the components.
723
 *
724
 * @param component The component number whose texture map we want to retrieve.
725
 */
726
   public Static4D getTextureMap(int component)
727
     {
728
     return (component>=0 && component<mComponent.size()) ? mComponent.get(component).mTextureMap : null;
729
     }
730

    
731
///////////////////////////////////////////////////////////////////////////////////////////////////
732
/**
733
 * Set Effect association.
734
 *
735
 * This creates an association between a Component of this Mesh and a Vertex Effect.
736
 * One can set two types of associations - an 'logical and' and a 'equal' associations and the Effect
737
 * will only be active on vertices of Components such that
738
 *
739
 * (effect andAssoc) & (component andAssoc) != 0 || (effect equAssoc) == (mesh equAssoc)
740
 *
741
 * (see main_vertex_shader)
742
 *
743
 * The point: this way we can configure the system so that each Vertex Effect acts only on a certain
744
 * subset of a Mesh, thus potentially significantly reducing the number of render calls.
745
 */
746
  public void setEffectAssociation(int component, int andAssociation, int equAssociation)
747
    {
748
    if( component>=0 && component<MAX_COMPONENTS )
749
      {
750
      mAndAssociation[component] = andAssociation;
751
      mEquAssociation[component] = equAssociation;
752
      }
753
    }
754

    
755
///////////////////////////////////////////////////////////////////////////////////////////////////
756
/**
757
 * Copy the Mesh.
758
 *
759
 * @param deep If to be a deep or shallow copy of mVertAttribs1, i.e. the array holding vertices,
760
 *             normals and inflates (the rest, in particular the mVertAttribs2 containing texture
761
 *             coordinates and effect associations, is always deep copied)
762
 */
763
   public abstract MeshBase copy(boolean deep);
764
   }
(2-2/8)