Project

General

Profile

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

examples / src / main / java / org / distorted / examples / meshfile / MeshFileRenderer.java @ 99093c35

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.examples.meshfile;
21

    
22
import android.content.Context;
23
import android.content.res.Resources;
24
import android.graphics.Bitmap;
25
import android.graphics.Canvas;
26
import android.graphics.Paint;
27
import android.opengl.GLSurfaceView;
28

    
29
import org.distorted.examples.R;
30
import org.distorted.library.effect.Effect;
31
import org.distorted.library.effect.EffectType;
32
import org.distorted.library.effect.MatrixEffectQuaternion;
33
import org.distorted.library.effect.MatrixEffectScale;
34
import org.distorted.library.effect.VertexEffectDisappear;
35
import org.distorted.library.main.DistortedEffects;
36
import org.distorted.library.main.DistortedLibrary;
37
import org.distorted.library.main.DistortedScreen;
38
import org.distorted.library.main.DistortedTexture;
39
import org.distorted.library.mesh.MeshBandedTriangle;
40
import org.distorted.library.mesh.MeshBase;
41
import org.distorted.library.mesh.MeshFile;
42
import org.distorted.library.mesh.MeshMultigon;
43
import org.distorted.library.mesh.MeshPolygon;
44
import org.distorted.library.type.DynamicQuat;
45
import org.distorted.library.type.Static3D;
46
import org.distorted.library.type.Static4D;
47

    
48
import org.distorted.objectlib.helpers.FactoryCubit;
49
import org.distorted.objectlib.helpers.ObjectFaceShape;
50
import org.distorted.objectlib.helpers.ObjectShape;
51

    
52
import java.io.DataInputStream;
53
import java.io.IOException;
54
import java.io.InputStream;
55

    
56
import javax.microedition.khronos.egl.EGLConfig;
57
import javax.microedition.khronos.opengles.GL10;
58

    
59
import static org.distorted.examples.meshfile.MeshFileActivity.MULTIGON;
60
import static org.distorted.examples.meshfile.MeshFileActivity.POLYGON;
61
import static org.distorted.examples.meshfile.MeshFileActivity.PROCEDURAL;
62
import static org.distorted.examples.meshfile.MeshFileActivity.TRIANGLE;
63

    
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65

    
66
class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.LibraryUser
67
{
68
    private static final float SQ3 = (float)Math.sqrt(3);
69
    private final float DEFAULT_SCALE = 0.3f;
70

    
71
    private final GLSurfaceView mView;
72
    private final Resources mResources;
73
    private final DistortedScreen mScreen;
74
    private final DistortedEffects mEffects;
75
    private final Static3D mScale;
76

    
77
    private DistortedTexture mTexture;
78
    private MeshBase mMesh;
79
    private long mTime;
80
    private float mCurrentScale;
81
    private boolean mNormals;
82

    
83
    Static4D mQuat1, mQuat2;
84
    int mScreenMin;
85

    
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

    
88
    MeshFileRenderer(GLSurfaceView v)
89
      {
90
      mView = v;
91
      mResources = v.getResources();
92

    
93
      mScreen = new DistortedScreen();
94
      mScale= new Static3D(1,1,1);
95
      Static3D center=new Static3D(0,0,0);
96

    
97
      mCurrentScale = DEFAULT_SCALE;
98
      mNormals = false;
99

    
100
      mQuat1 = new Static4D(0,0,0,1);
101
      mQuat2 = new Static4D(0,0,0,1);
102

    
103
      DynamicQuat quatInt1 = new DynamicQuat(0,0.5f);
104
      DynamicQuat quatInt2 = new DynamicQuat(0,0.5f);
105

    
106
      quatInt1.add(mQuat1);
107
      quatInt2.add(mQuat2);
108

    
109
      VertexEffectDisappear disappear = new VertexEffectDisappear();
110
      disappear.setMeshAssociation(1,-1);
111

    
112
      mEffects = new DistortedEffects();
113
      mEffects.apply( new MatrixEffectQuaternion(quatInt2, center) );
114
      mEffects.apply( new MatrixEffectQuaternion(quatInt1, center) );
115
      mEffects.apply( new MatrixEffectScale(mScale));
116

    
117
      mEffects.apply( disappear );
118

    
119
      mScreen.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
120
      mScreen.showFPS();
121
      }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124
   
125
    public void onDrawFrame(GL10 glUnused) 
126
      {
127
      mScreen.render( System.currentTimeMillis() );
128
      }
129

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131
    
132
    public void onSurfaceChanged(GL10 glUnused, int width, int height) 
133
      {
134
      mScreenMin = Math.min(width, height);
135
      float factor = mCurrentScale*mScreenMin;
136
      mScale.set(factor,factor,factor);
137
      mScreen.resize(width, height);
138
      }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141
    
142
    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
143
      {
144
      if( mTexture==null ) mTexture = new DistortedTexture();
145

    
146
      Effect.enableEffects(EffectType.VERTEX);
147
      DistortedLibrary.setMax(EffectType.VERTEX, 20);
148
      DistortedLibrary.needTransformFeedback();
149
      DistortedLibrary.onSurfaceCreated(this);
150
      }
151

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153
//   0 ---> 0
154
//  50 ---> DEFAULT_SCALE
155
// 100 ---> 4*DEFAULT_SCALE
156

    
157
    void setScale(int scale)
158
      {
159
      if( scale<= 50 )
160
        {
161
        mCurrentScale = DEFAULT_SCALE * scale / 50.0f;
162
        }
163
      else
164
        {
165
        mCurrentScale = DEFAULT_SCALE * ( 3*(scale/50.0f) - 2.0f);
166
        }
167

    
168
      float factor = mCurrentScale*mScreenMin;
169
      mScale.set(factor,factor,factor);
170
      }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
    void flipNormals()
175
      {
176
      mNormals = !mNormals;
177
      if( mMesh!=null ) mMesh.setShowNormals(mNormals);
178
      }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
    void open(int resourceID)
183
      {
184
      if( mTexture==null ) mTexture = new DistortedTexture();
185
      mTexture.setTexture( createTexture(resourceID) );
186

    
187
      long t1 = System.currentTimeMillis();
188

    
189
      if( resourceID==PROCEDURAL )
190
        {
191
        createMesh();
192
        }
193
      else if( resourceID==POLYGON )
194
        {
195
        createPolygon();
196
        }
197
      else if( resourceID==MULTIGON )
198
        {
199
        createMultigon();
200
        }
201
      else if( resourceID==TRIANGLE )
202
        {
203
        createTriangle();
204
        }
205
      else
206
        {
207
        openMesh(resourceID);
208
        }
209

    
210
      long t2 = System.currentTimeMillis();
211

    
212
      mTime = t2-t1;
213

    
214
      mScreen.detachAll();
215
      mScreen.attach(mTexture,mEffects,mMesh);
216
      }
217

    
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

    
220
    private Bitmap createTexture(int resourceID)
221
      {
222
      TextureFactory factory = TextureFactory.getInstance();
223

    
224
      float[] vertices;
225
      int[] colors;
226
      float F = 0.5f;
227
      float E = SQ3/2;
228

    
229
      if( resourceID == R.raw.deferredjob || resourceID == R.raw.meshjoin    ||
230
          resourceID == PROCEDURAL        || resourceID == POLYGON           ||
231
          resourceID == MULTIGON          || resourceID == TRIANGLE          ||
232
          resourceID == R.raw.predeform    ) return createWhiteTexture();
233

    
234
      if( resourceID == R.raw.cube2       ||
235
          resourceID == R.raw.cube3       ||
236
          resourceID == R.raw.cube4       ||
237
          resourceID == R.raw.cube5        )
238
        {
239
        colors = new int[] { 0xffffff00, 0xffffffff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffb5651d };
240
        vertices = new float[] { -F,-F, +F,-F, +F,+F, -F,+F};
241
        return factory.createTexture(vertices,colors,0.10f, 0.10f, true);
242
        }
243
      if( resourceID == R.raw.pyra3       ||
244
          resourceID == R.raw.pyra4       ||
245
          resourceID == R.raw.pyra5        )
246
        {
247
        colors = new int[] { 0xffffff00, 0xff00ff00, 0xff0000ff, 0xffff0000 };
248
        vertices = new float[] { -F,-E/3, +F,-E/3, 0.0f,2*E/3};
249
        return factory.createTexture(vertices,colors,0.05f, 0.05f, true);
250
        }
251
      if( resourceID == R.raw.dino )
252
        {
253
        colors = new int[] { 0xffffff00, 0xffffffff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffb5651d };
254
        vertices = new float[] { -F,F/3, 0,-2*F/3, +F,F/3 };
255
        return factory.createTexture(vertices,colors,0.05f, 0.03f, true);
256
        }
257
      if( resourceID == R.raw.skewb )
258
        {
259
        colors = new int[] { 0xffffff00, 0xffffffff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffb5651d };
260
        vertices = new float[] { -F+F/4,F/4, F/4,-F+F/4, F/4,F/4};
261
        return factory.createTexture(vertices,colors,0.05f, 0.08f, true);
262
        }
263

    
264
      return null;
265
      }
266

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

    
269
    private Bitmap createWhiteTexture()
270
      {
271
      int SIZE = 1;
272
      Bitmap bitmap = Bitmap.createBitmap(SIZE,SIZE, Bitmap.Config.ARGB_8888);
273
      Canvas canvas = new Canvas(bitmap);
274

    
275
      Paint paint = new Paint();
276
      paint.setColor(0xffffff55);
277
      paint.setStyle(Paint.Style.FILL);
278
      canvas.drawRect(0, 0, SIZE, SIZE, paint);
279

    
280
      return bitmap;
281
      }
282

    
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

    
285
    private void createTriangle()
286
      {
287
      float[] vL = {-1.0f, -0.5f};
288
      float[] vR = { 1.0f, -0.5f};
289
      float[] vT = { 0.0f,  1.0f};
290
      float C = 2f;
291
      float[] bands = { 1.0f, 0.00f*C, /*0.9f, 0.05f*C,*/ 0.8f, 0.06f*C, 0.5f, 0.09f*C, 0.0f, 0.10f*C};
292
      float[] normL = { vL[0]-vT[0], vL[1]-vT[1] };
293
      float[] normR = { vR[0]-vT[0], vR[1]-vT[1] };
294
      int mode = MeshBandedTriangle.MODE_NORMAL;
295
      int extraBands    = 2;
296
      int extraVertices = 1;
297

    
298
      mMesh = new MeshBandedTriangle(vL,vR,vT,bands,normL,normR,mode,extraBands,extraVertices);
299
      mMesh.setEffectAssociation(0,0,0);
300
      }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
    private void createPolygon()
305
      {
306
      float A = 0.5f;
307
      float B = 0.04f;
308

    
309
      int extraIndex    = 0;
310
      int extraVertices = 0;
311
      float[][] vertices = { {-A,-A}, {A,-A}, {A,A}, {-A,A} };
312

    
313
      float C = 2f;
314
      float[] bands = { 1.0f, 0.00f*C, 0.9f, 0.04f*C,  0.8f, 0.07f*C, 0.5f, 0.09f*C, 0.0f, 0.10f*C};
315
/*
316
      int numBands      = 5;
317
      float[] bands = new float[2*numBands];
318

    
319
      for(int i=0; i<numBands; i++)
320
        {
321
        bands[2*i  ] = 1 + i/(1.0f-numBands);
322
        bands[2*i+1] = B/(numBands-1)*i;
323
        }
324
*/
325
      mMesh = new MeshPolygon(vertices,bands,extraIndex,extraVertices,0.0f,0.0f);
326
      mMesh.setEffectAssociation(0,0,0);
327
      }
328

    
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
    private float[][] gen(float x, float y)
332
      {
333
      return new float[][] { {x+0.1f,y-0.1f} , {x-0.1f,y-0.1f} , {x-0.1f,y+0.1f} , {x+0.1f,y+0.1f} };
334
      }
335

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

    
338
    private void createMultigon()
339
      {
340
      float A = 0.5f;
341
      int extraIndex    = 0;
342
      int extraVertices = 0;
343

    
344
      float[][][] vertices = new float[19][][];
345

    
346
      vertices[ 0] = gen( 0.4f,-0.4f);
347
      vertices[ 1] = gen( 0.2f,-0.4f);
348
      vertices[ 2] = gen( 0.0f,-0.4f);
349
      vertices[ 3] = gen(-0.2f,-0.4f);
350
      vertices[ 4] = gen(-0.4f,-0.4f);
351
      vertices[ 5] = gen(-0.4f,-0.2f);
352
      vertices[ 6] = gen(-0.4f, 0.0f);
353
      vertices[ 7] = gen(-0.4f, 0.2f);
354
      vertices[ 8] = gen(-0.4f, 0.4f);
355
      vertices[ 9] = gen(-0.2f, 0.4f);
356
      vertices[10] = gen( 0.0f, 0.4f);
357
      vertices[11] = gen( 0.2f, 0.4f);
358
      vertices[12] = gen( 0.4f, 0.4f);
359
      vertices[13] = gen( 0.4f, 0.2f);
360
      vertices[14] = gen( 0.4f, 0.0f);
361
      vertices[15] = gen( 0.4f,-0.2f);
362
      vertices[16] = gen( 0.0f,-0.2f);
363
      vertices[17] = gen( 0.0f, 0.0f);
364
      vertices[18] = gen( 0.0f, 0.2f);
365

    
366
      float C = 0.5f;
367
      float[] bands = new float[] { 1.0f, 0.00f*C, 0.9f, 0.04f*C,  0.8f, 0.07f*C, 0.5f, 0.09f*C, 0.0f, 0.10f*C};
368
/*
369
      float B = 0.1f;
370
      int numBands = 7;
371
      float[] bands = new float[2*numBands];
372

    
373
      for(int i=0; i<numBands; i++)
374
        {
375
        bands[2*i  ] = 1 + i/(1.0f-numBands);
376
        bands[2*i+1] = B/(numBands-1)*i;
377
        }
378
*/
379
      mMesh = new MeshMultigon(vertices,bands,extraIndex,extraVertices);
380

    
381
      int numEff = mMesh.getNumEffComponents();
382

    
383
      for(int i=0; i<numEff; i++)
384
        {
385
        mMesh.setEffectAssociation(i, 0, i);
386
        }
387
      }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
    private float[][] createV()
392
      {
393
      return new float[][]
394
              {
395
              {-1.6281155f, -0.2072947f, -3.1770508f },
396
              { 1.2135257f, -1.9635254f, -3.1770515f },
397
              {-0.5427052f, -1.9635254f, -0.33541024f},
398
              {-1.9635254f, -0.7499998f, -1.2135254f },
399
              {-0.75000024f, 1.2135258f, -1.9635254f },
400
              { 1.2135253f,  0.87811553f,-1.4208202f },
401
              {-1.2135255f,  0.4635256f, -0.7499998f },
402
              { 1.2135255f, -1.9635254f, -3.1770515f },
403
              { 2.9697561f, -1.9635254f, -0.33541024f},
404
              { 1.2135255f, -1.9635254f, 0.75f },
405
              { 8.940697E-8f, 1.7881393E-7f, 0.0f },
406
              { 1.2135255f, -0.4635254f, 0.75f },
407
              { 0.0f, 0.0f, 0.0f },
408
              { 1.2135255f, 0.87811553f, -1.4208202f },
409
              { 2.427051f, 0.0f, 0.0f }
410

    
411
              };
412
      }
413

    
414
///////////////////////////////////////////////////////////////////////////////////////////////////
415

    
416
    private int[][][] createVI()
417
      {
418
      return new int[][][]
419
              {
420
                {{ 0, 1, 2, 3 }},
421
                {{ 4, 5, 1, 0 }},
422
                {{ 0, 3, 6, 4 }},
423
                {{ 2, 7, 8, 9 }},
424
                {{ 3, 2, 10,6 }, { 2, 9, 11, 12 }},
425
                {{13, 14, 8, 7}},
426
                {{ 6, 10, 5, 4}, { 11, 14, 13, 12}},
427
                {{ 9, 8, 14, 11}}
428
              };
429
      }
430

    
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432

    
433
    private void createMesh()
434
      {
435
      float[][] vertices = createV();
436
      int[][][] vertIndices = createVI();
437

    
438
      int numFaces = vertIndices.length;
439

    
440
      float h = 0.001f;
441
      int angle = 30;
442
      float R = 0.1f;
443
      float S = 0.5f;
444
      int N   = 6;
445
      int exI = 0;
446
      int exV = 0;
447
      float[][] bands  = { {h,angle,R,S,N,exI,exV} };
448

    
449
      int[] bandIndices= new int[numFaces];
450

    
451
      ObjectShape shape = new ObjectShape(vertices, vertIndices);
452
      ObjectFaceShape face = new ObjectFaceShape(bands, bandIndices, null);
453

    
454
      int[] outer = new int[numFaces];
455

    
456
      FactoryCubit factory = FactoryCubit.getInstance();
457
      factory.clear();
458
      factory.createNewFaceTransform(shape,outer);
459
      mMesh = factory.createRoundedSolid(shape,face,null,numFaces);
460

    
461
      int numEff = mMesh.getNumEffComponents();
462
      for(int i=0; i<numEff; i++) mMesh.setEffectAssociation(i, 0, i);
463
      }
464

    
465
///////////////////////////////////////////////////////////////////////////////////////////////////
466

    
467
    private void openMesh(int resourceID)
468
      {
469
      Context con = mView.getContext();
470
      Resources res = con.getResources();
471
      InputStream is = res.openRawResource(resourceID);
472
      DataInputStream dos = new DataInputStream(is);
473
      mMesh = new MeshFile(dos);
474

    
475
      int numEff = mMesh.getNumEffComponents();
476

    
477
      for(int i=0; i<numEff; i++)
478
        {
479
        mMesh.setEffectAssociation(i, 0, i);
480
        }
481

    
482
      try
483
        {
484
        is.close();
485
        }
486
      catch(IOException e)
487
        {
488
        android.util.Log.e("MeshFile", "Error closing InputStream: "+e.toString());
489
        }
490
      }
491

    
492
///////////////////////////////////////////////////////////////////////////////////////////////////
493

    
494
    MeshBase getMesh()
495
      {
496
      return mMesh;
497
      }
498

    
499
///////////////////////////////////////////////////////////////////////////////////////////////////
500

    
501
    long getTime()
502
      {
503
      return mTime;
504
      }
505

    
506
///////////////////////////////////////////////////////////////////////////////////////////////////
507

    
508
    int getBytes()
509
      {
510
      if( mMesh instanceof MeshFile )
511
        {
512
        return ((MeshFile)mMesh).getNumBytes();
513
        }
514

    
515
      return 0;
516
      }
517

    
518
///////////////////////////////////////////////////////////////////////////////////////////////////
519

    
520
    int getVertices()
521
      {
522
      return mMesh.getNumVertices();
523
      }
524

    
525
///////////////////////////////////////////////////////////////////////////////////////////////////
526

    
527
    int getEndEffIndex(int component)
528
      {
529
      return mMesh.getLastVertexEff(component);
530
      }
531

    
532
///////////////////////////////////////////////////////////////////////////////////////////////////
533

    
534
    int getEndTexIndex(int component)
535
      {
536
      return mMesh.getLastVertexTex(component);
537
      }
538

    
539
///////////////////////////////////////////////////////////////////////////////////////////////////
540

    
541
    int getEffComponentNum()
542
      {
543
      return mMesh.getNumEffComponents();
544
      }
545

    
546
///////////////////////////////////////////////////////////////////////////////////////////////////
547

    
548
    int getTexComponentNum()
549
      {
550
      return mMesh.getNumTexComponents();
551
      }
552

    
553
///////////////////////////////////////////////////////////////////////////////////////////////////
554

    
555
    public void distortedException(Exception ex)
556
      {
557
      android.util.Log.e("MeshFile", ex.getMessage() );
558
      }
559

    
560
///////////////////////////////////////////////////////////////////////////////////////////////////
561

    
562
    public InputStream localFile(int fileID)
563
      {
564
      return mResources.openRawResource(fileID);
565
      }
566

    
567
///////////////////////////////////////////////////////////////////////////////////////////////////
568

    
569
    public void logMessage(String message)
570
      {
571
      android.util.Log.e("MeshFile", message );
572
      }
573
}
(2-2/4)