Project

General

Profile

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

library / src / main / java / org / distorted / library / mesh / MeshBase.java @ c90aca24

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.GLES31;
23
import android.opengl.Matrix;
24

    
25
import org.distorted.library.effect.MatrixEffect;
26
import org.distorted.library.main.DistortedLibrary;
27
import org.distorted.library.main.InternalBuffer;
28
import org.distorted.library.program.DistortedProgram;
29

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

    
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36
/**
37
 * Abstract class which represents a Mesh, ie an array of vertices (rendered as a TRIANGLE_STRIP).
38
 * <p>
39
 * If you want to render to a particular shape, extend from here, construct a float array
40
 * containing per-vertex attributes, and call back setAttribs().
41
 */
42
public abstract class MeshBase
43
   {
44
   // sizes of attributes of an individual vertex.
45
   private static final int POS_DATA_SIZE= 3; // vertex coordinates: x,y,z
46
   private static final int NOR_DATA_SIZE= 3; // normal vector: x,y,z
47
   private static final int INF_DATA_SIZE= 3; // 'inflate' vector: x,y,z
48
   private static final int TEX_DATA_SIZE= 2; // texture coordinates: s,t
49

    
50
   static final int POS_ATTRIB   = 0;
51
   static final int NOR_ATTRIB   = POS_DATA_SIZE;
52
   static final int INF_ATTRIB   = POS_DATA_SIZE + NOR_DATA_SIZE;
53
   static final int TEX_ATTRIB   = POS_DATA_SIZE + NOR_DATA_SIZE + INF_DATA_SIZE;
54
   static final int VERT_ATTRIBS = POS_DATA_SIZE + NOR_DATA_SIZE + INF_DATA_SIZE + TEX_DATA_SIZE;  // number of attributes of a 'normal' vertex
55
   static final int TRAN_ATTRIBS = POS_DATA_SIZE + POS_DATA_SIZE;                                  // number of attributes of a transform feedback vertex
56

    
57
   private static final int BYTES_PER_FLOAT = 4;
58

    
59
   private static final int OFFSET_POS = POS_ATTRIB*BYTES_PER_FLOAT;
60
   private static final int OFFSET_NOR = NOR_ATTRIB*BYTES_PER_FLOAT;
61
   private static final int OFFSET_INF = INF_ATTRIB*BYTES_PER_FLOAT;
62
   private static final int OFFSET_TEX = TEX_ATTRIB*BYTES_PER_FLOAT;
63
   private static final int TRAN_SIZE  = TRAN_ATTRIBS*BYTES_PER_FLOAT;
64
   private static final int VERT_SIZE  = VERT_ATTRIBS*BYTES_PER_FLOAT;
65

    
66
   private boolean mShowNormals;      // when rendering this mesh, draw normal vectors?
67
   private InternalBuffer mVBO, mTFO; // main vertex buffer and transform feedback buffer
68
   private int mNumVertices;
69
   private float[] mVertAttribs;      // packed: PosX,PosY,PosZ, NorX,NorY,NorZ, InfX,InfY,InfZ, TexS,TexT
70
   private float mInflate;
71

    
72
   private class Component
73
     {
74
     private int mEndIndex;
75
     private float[] mTextureMap;
76

    
77
     Component()
78
       {
79
       mTextureMap = new float[8];
80

    
81
       mTextureMap[ 0] = 0.0f;  // LLX
82
       mTextureMap[ 1] = 0.0f;  // LLY
83
       mTextureMap[ 2] = 0.0f;  // ULX
84
       mTextureMap[ 3] = 1.0f;  // ULY
85
       mTextureMap[ 4] = 1.0f;  // URX
86
       mTextureMap[ 5] = 1.0f;  // URY
87
       mTextureMap[ 6] = 1.0f;  // LRX
88
       mTextureMap[ 7] = 0.0f;  // LRY
89
       }
90
     Component(Component original)
91
       {
92
       mEndIndex = original.mEndIndex;
93
       mTextureMap = new float[8];
94
       System.arraycopy(original.mTextureMap,0,mTextureMap,0,8);
95
       }
96

    
97
     }
98

    
99
   private ArrayList<Component> mComponent;
100

    
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102

    
103
   MeshBase()
104
     {
105
     mShowNormals = false;
106
     mInflate     = 0.0f;
107
     mComponent = new ArrayList<>();
108
     mComponent.add(new Component());
109

    
110
     mVBO = new InternalBuffer(GLES31.GL_ARRAY_BUFFER             , GLES31.GL_STATIC_READ);
111
     mTFO = new InternalBuffer(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, GLES31.GL_STATIC_READ);
112
     }
113

    
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115
// copy constructor
116

    
117
   MeshBase(MeshBase original)
118
     {
119
     mShowNormals = original.mShowNormals;
120
     mInflate     = original.mInflate;
121

    
122
     int size = original.mComponent.size();
123
     mComponent = new ArrayList<>();
124
     for(int i=0; i<size; i++)
125
       {
126
       Component comp = new Component(original.mComponent.get(i));
127
       mComponent.add(comp);
128
       }
129

    
130
     mVBO = new InternalBuffer(GLES31.GL_ARRAY_BUFFER             , GLES31.GL_STATIC_READ);
131
     mTFO = new InternalBuffer(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, GLES31.GL_STATIC_READ);
132

    
133
     System.arraycopy(original.mVertAttribs,0,mVertAttribs,0,original.mNumVertices*VERT_ATTRIBS);
134
     setAttribs(mVertAttribs);
135
     }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138
// when a derived class is done computing its mesh, it has to call this method.
139

    
140
   void setAttribs(float[] vertexAttribs)
141
     {
142
     mNumVertices = vertexAttribs.length/VERT_ATTRIBS;
143
     mVertAttribs = vertexAttribs;
144

    
145
     mComponent.get(0).mEndIndex = mNumVertices;
146

    
147
     FloatBuffer attribs = ByteBuffer.allocateDirect(mNumVertices*VERT_SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
148
     attribs.put(vertexAttribs).position(0);
149

    
150
     mVBO.setData(mNumVertices*VERT_SIZE, attribs);
151
     mTFO.setData(mNumVertices*TRAN_SIZE, null   );
152
     }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
/**
156
 * Not part of public API, do not document (public only because has to be used from the main package)
157
 *
158
 * @y.exclude
159
 */
160
   public int getTFO()
161
     {
162
     return mTFO.mIndex[0];
163
     }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166
/**
167
 * Not part of public API, do not document (public only because has to be used from the main package)
168
 *
169
 * @y.exclude
170
 */
171
   public int getNumVertices()
172
     {
173
     return mNumVertices;
174
     }
175

    
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177
/**
178
 * Not part of public API, do not document (public only because has to be used from the main package)
179
 *
180
 * @y.exclude
181
 */
182
   public void bindVertexAttribs(DistortedProgram program)
183
     {
184
     GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mVBO.mIndex[0] );
185
     GLES31.glVertexAttribPointer(program.mAttribute[0], POS_DATA_SIZE, GLES31.GL_FLOAT, false, VERT_SIZE, OFFSET_POS);
186
     GLES31.glVertexAttribPointer(program.mAttribute[1], NOR_DATA_SIZE, GLES31.GL_FLOAT, false, VERT_SIZE, OFFSET_NOR);
187
     GLES31.glVertexAttribPointer(program.mAttribute[2], INF_DATA_SIZE, GLES31.GL_FLOAT, false, VERT_SIZE, OFFSET_INF);
188
     GLES31.glVertexAttribPointer(program.mAttribute[3], TEX_DATA_SIZE, GLES31.GL_FLOAT, false, VERT_SIZE, OFFSET_TEX);
189
     GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, 0);
190
     }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193
/**
194
 * Not part of public API, do not document (public only because has to be used from the main package)
195
 *
196
 * @y.exclude
197
 */
198
   public void bindTransformAttribs(DistortedProgram program)
199
     {
200
     GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mTFO.mIndex[0] );
201
     GLES31.glVertexAttribPointer(program.mAttribute[0], POS_DATA_SIZE, GLES31.GL_FLOAT, false, 0, 0);
202
     GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, 0);
203
     }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206
/**
207
 * Not part of public API, do not document (public only because has to be used from the main package)
208
 *
209
 * @y.exclude
210
 */
211
   public void setInflate(float inflate)
212
     {
213
     mInflate = inflate;
214
     }
215

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217
/**
218
 * Not part of public API, do not document (public only because has to be used from the main package)
219
 *
220
 * @y.exclude
221
 */
222
   public float getInflate()
223
     {
224
     return mInflate;
225
     }
226

    
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228
// PUBLIC API
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230
/**
231
 * When rendering this Mesh, do we want to render the Normal vectors as well?
232
 * <p>
233
 * Will work only on OpenGL ES >= 3.0 devices.
234
 *
235
 * @param show Controls if we render the Normal vectors or not.
236
 */
237
   public void setShowNormals(boolean show)
238
     {
239
     mShowNormals = (DistortedLibrary.GLSL >= 300 && show);
240
     }
241

    
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243
/**
244
 * When rendering this mesh, should we also draw the normal vectors?
245
 *
246
 * @return <i>true</i> if we do render normal vectors
247
 */
248
   public boolean getShowNormals()
249
     {
250
     return mShowNormals;
251
     }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254
/**
255
 * Release all internal resources.
256
 */
257
   public void markForDeletion()
258
     {
259
     mVertAttribs = null;
260

    
261
     mVBO.markForDeletion();
262
     mTFO.markForDeletion();
263
     }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266
/**
267
 * Apply all Effects to the vertex mesh. Overwrite the mesh in place.
268
 * <p>
269
 * This is a static, permanent modification of the vertices contained in this Mesh. If the effects
270
 * contain any Dynamics, they will be evaluated at 0.
271
 *
272
 * Please note that calling this once with the complete list of Effects will be much faster than
273
 * calling it repeatedly with one Effect at a time, as we have to reallocate the array of vertices
274
 * each time.
275
 */
276
   public void apply(MatrixEffect[] effects)
277
     {
278
     float[][] matrix = new float[effects.length][16];
279
     float[] tmp;
280
     float[] array = new float[4];
281
     float x,y,z;
282
     int numEffects = 0;
283

    
284
     for(MatrixEffect eff: effects)
285
       {
286
       if( eff!=null )
287
         {
288
         Matrix.setIdentityM(matrix[numEffects],0);
289
         eff.compute(array,0,0,0);
290
         eff.apply(matrix[numEffects], array, 0);
291
         numEffects++;
292
         }
293
       }
294

    
295
     for(int index=0; index<mNumVertices; index+=VERT_ATTRIBS )
296
       {
297
       for(int mat=0; mat<numEffects; mat++)
298
         {
299
         tmp = matrix[mat];
300

    
301
         x = mVertAttribs[index+POS_ATTRIB  ];
302
         y = mVertAttribs[index+POS_ATTRIB+1];
303
         z = mVertAttribs[index+POS_ATTRIB+2];
304

    
305
         mVertAttribs[index+POS_ATTRIB  ] = tmp[0]*x + tmp[4]*y + tmp[ 8]*z + tmp[12];
306
         mVertAttribs[index+POS_ATTRIB+1] = tmp[1]*x + tmp[5]*y + tmp[ 9]*z + tmp[13];
307
         mVertAttribs[index+POS_ATTRIB+2] = tmp[2]*x + tmp[6]*y + tmp[10]*z + tmp[14];
308

    
309
         x = mVertAttribs[index+NOR_ATTRIB  ];
310
         y = mVertAttribs[index+NOR_ATTRIB+1];
311
         z = mVertAttribs[index+NOR_ATTRIB+2];
312

    
313
         mVertAttribs[index+NOR_ATTRIB  ] = tmp[0]*x + tmp[4]*y + tmp[ 8]*z;
314
         mVertAttribs[index+NOR_ATTRIB+1] = tmp[1]*x + tmp[5]*y + tmp[ 9]*z;
315
         mVertAttribs[index+NOR_ATTRIB+2] = tmp[2]*x + tmp[6]*y + tmp[10]*z;
316

    
317
         x = mVertAttribs[index+INF_ATTRIB  ];
318
         y = mVertAttribs[index+INF_ATTRIB+1];
319
         z = mVertAttribs[index+INF_ATTRIB+2];
320

    
321
         mVertAttribs[index+INF_ATTRIB  ] = tmp[0]*x + tmp[4]*y + tmp[ 8]*z;
322
         mVertAttribs[index+INF_ATTRIB+1] = tmp[1]*x + tmp[5]*y + tmp[ 9]*z;
323
         mVertAttribs[index+INF_ATTRIB+2] = tmp[2]*x + tmp[6]*y + tmp[10]*z;
324
         }
325
       }
326

    
327
     FloatBuffer attribs = ByteBuffer.allocateDirect(mNumVertices*VERT_SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
328
     attribs.put(mVertAttribs).position(0);
329

    
330
     mVBO.setData(mNumVertices*VERT_SIZE, attribs);
331
     mTFO.setData(mNumVertices*TRAN_SIZE, null   );
332
     }
333

    
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335
/**
336
 * Join a list of Meshes into this one.
337
 * <p>
338
 * Please note that calling this once with the complete list of Meshes will be much faster than
339
 * calling it repeatedly with one Mesh at a time, as we have to reallocate the array of vertices
340
 * each time.
341
 */
342
   public void join(MeshBase[] meshes)
343
     {
344

    
345
     }
346
   }
347

    
348

    
349

    
(1-1/5)