Project

General

Profile

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

examples / src / main / java / org / distorted / examples / meshfile / MeshFileRenderer.java @ 30f337e5

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.EffectName;
32
import org.distorted.library.effect.EffectType;
33
import org.distorted.library.effect.MatrixEffectQuaternion;
34
import org.distorted.library.effect.MatrixEffectScale;
35
import org.distorted.library.effect.VertexEffectDisappear;
36
import org.distorted.library.main.DistortedEffects;
37
import org.distorted.library.main.DistortedLibrary;
38
import org.distorted.library.main.DistortedScreen;
39
import org.distorted.library.main.DistortedTexture;
40
import org.distorted.library.mesh.MeshBandedTriangle;
41
import org.distorted.library.mesh.MeshBase;
42
import org.distorted.library.mesh.MeshFile;
43
import org.distorted.library.mesh.MeshMultigon;
44
import org.distorted.library.mesh.MeshPolygon;
45
import org.distorted.library.type.DynamicQuat;
46
import org.distorted.library.type.Static3D;
47
import org.distorted.library.type.Static4D;
48

    
49
import org.distorted.objectlib.helpers.FactoryCubit;
50
import org.distorted.objectlib.helpers.ObjectFaceShape;
51
import org.distorted.objectlib.helpers.ObjectShape;
52
import org.distorted.objectlib.helpers.ObjectVertexEffects;
53

    
54
import java.io.DataInputStream;
55
import java.io.IOException;
56
import java.io.InputStream;
57

    
58
import javax.microedition.khronos.egl.EGLConfig;
59
import javax.microedition.khronos.opengles.GL10;
60

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

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

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

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

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

    
85
    Static4D mQuat1, mQuat2;
86
    int mScreenMin;
87

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

    
90
    MeshFileRenderer(GLSurfaceView v)
91
      {
92
      mView = v;
93
      mResources = v.getResources();
94

    
95
      mScreen = new DistortedScreen();
96
      mScale= new Static3D(1,1,1);
97
      Static3D center=new Static3D(0,0,0);
98

    
99
      mCurrentScale = DEFAULT_SCALE;
100
      mNormals = false;
101

    
102
      mQuat1 = new Static4D(0,0,0,1);
103
      mQuat2 = new Static4D(0,0,0,1);
104

    
105
      DynamicQuat quatInt1 = new DynamicQuat(0,0.5f);
106
      DynamicQuat quatInt2 = new DynamicQuat(0,0.5f);
107

    
108
      quatInt1.add(mQuat1);
109
      quatInt2.add(mQuat2);
110

    
111
      VertexEffectDisappear disappear = new VertexEffectDisappear();
112
      disappear.setMeshAssociation(1,-1);
113

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

    
119
      mEffects.apply( disappear );
120

    
121
      mScreen.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
122
      mScreen.showFPS();
123
      }
124

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

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

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

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

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
//   0 ---> 0
156
//  50 ---> DEFAULT_SCALE
157
// 100 ---> 4*DEFAULT_SCALE
158

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

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

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

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

    
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

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

    
189
      long t1 = System.currentTimeMillis();
190

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

    
212
      long t2 = System.currentTimeMillis();
213

    
214
      mTime = t2-t1;
215

    
216
      mScreen.detachAll();
217
      mScreen.attach(mTexture,mEffects,mMesh);
218
      }
219

    
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221

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

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

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

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

    
266
      return null;
267
      }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

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

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

    
282
      return bitmap;
283
      }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
    private void createTriangle()
288
      {
289
      float[] vL = {-1.0f, -0.5f};
290
      float[] vR = { 1.0f, -0.5f};
291
      float[] vT = { 0.0f,  1.0f};
292
      float C = 2f;
293
      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};
294
      float[] normL = { vL[0]-vT[0], vL[1]-vT[1] };
295
      float[] normR = { vR[0]-vT[0], vR[1]-vT[1] };
296
      int mode = MeshBandedTriangle.MODE_NORMAL;
297
      int extraBands    = 2;
298
      int extraVertices = 1;
299

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

    
304
///////////////////////////////////////////////////////////////////////////////////////////////////
305

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

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

    
315
      float C = 2f;
316
      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};
317

    
318
      mMesh = new MeshPolygon(vertices,bands,extraIndex,extraVertices,0.0f,0.0f);
319
      mMesh.setEffectAssociation(0,0,0);
320
      }
321

    
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323

    
324
    private float[][] gen(float x, float y)
325
      {
326
      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} };
327
      }
328

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

    
331
    private void createMultigon()
332
      {
333
      float A = 0.5f;
334
      int extraIndex    = 0;
335
      int extraVertices = 0;
336

    
337
      float[][][] vertices = new float[19][][];
338

    
339
      vertices[ 0] = gen( 0.4f,-0.4f);
340
      vertices[ 1] = gen( 0.2f,-0.4f);
341
      vertices[ 2] = gen( 0.0f,-0.4f);
342
      vertices[ 3] = gen(-0.2f,-0.4f);
343
      vertices[ 4] = gen(-0.4f,-0.4f);
344
      vertices[ 5] = gen(-0.4f,-0.2f);
345
      vertices[ 6] = gen(-0.4f, 0.0f);
346
      vertices[ 7] = gen(-0.4f, 0.2f);
347
      vertices[ 8] = gen(-0.4f, 0.4f);
348
      vertices[ 9] = gen(-0.2f, 0.4f);
349
      vertices[10] = gen( 0.0f, 0.4f);
350
      vertices[11] = gen( 0.2f, 0.4f);
351
      vertices[12] = gen( 0.4f, 0.4f);
352
      vertices[13] = gen( 0.4f, 0.2f);
353
      vertices[14] = gen( 0.4f, 0.0f);
354
      vertices[15] = gen( 0.4f,-0.2f);
355
      vertices[16] = gen( 0.0f,-0.2f);
356
      vertices[17] = gen( 0.0f, 0.0f);
357
      vertices[18] = gen( 0.0f, 0.2f);
358

    
359
      float C = 0.5f;
360
      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};
361
/*
362
      float B = 0.1f;
363
      int numBands = 7;
364
      float[] bands = new float[2*numBands];
365

    
366
      for(int i=0; i<numBands; i++)
367
        {
368
        bands[2*i  ] = 1 + i/(1.0f-numBands);
369
        bands[2*i+1] = B/(numBands-1)*i;
370
        }
371
*/
372
      mMesh = new MeshMultigon(vertices,bands,extraIndex,extraVertices);
373

    
374
      int numEff = mMesh.getNumEffComponents();
375

    
376
      for(int i=0; i<numEff; i++)
377
        {
378
        mMesh.setEffectAssociation(i, 0, i);
379
        }
380
      }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

    
384
    private float[][] createV()
385
      {
386
      final float X = 0.7f;
387
      final float Y = 0.7f;
388
      final float Z = 1.0f;
389

    
390
      return new float[][]
391
        {
392
                {-X,-Y,-Z},
393
                {+X,-Y,-Z},
394
                {+X,+Y,-Z},
395
                {-X,-Y,+Z},
396
                {+X,-Y,+Z},
397
                {+X,+Y,+Z},
398
        };
399
      }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
    private int[][][] createVI()
404
      {
405
      return new int[][][]
406
        {
407
                {{2,1,0}},
408
                {{3,4,5}},
409
                {{0,3,5,2}},
410
                {{0,1,4,3}},
411
                {{5,4,1,2}}
412
        };
413
      }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416
// String[] names, float[][] variables, float[][] centers, float[][] regions, boolean[] use
417

    
418
    private ObjectVertexEffects createEffects()
419
      {
420
      final float R = 0.7f;
421

    
422
      String[] names = { EffectName.PIPE.name() };
423
      float[][] vars = { {0.3f,0,0,1,2*R} };
424
      float[][] cens = { {-R,R,0} };
425
      float[][] regs = { {0,0,0,0} };
426
      boolean[] use  = { true };
427

    
428
      return new ObjectVertexEffects(names,vars,cens,regs,use);
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
      ObjectVertexEffects effects = createEffects();
454

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

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

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

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467

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

    
476
      int numEff = mMesh.getNumEffComponents();
477

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

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

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

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

    
500
///////////////////////////////////////////////////////////////////////////////////////////////////
501

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

    
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508

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

    
516
      return 0;
517
      }
518

    
519
///////////////////////////////////////////////////////////////////////////////////////////////////
520

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

    
526
///////////////////////////////////////////////////////////////////////////////////////////////////
527

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

    
533
///////////////////////////////////////////////////////////////////////////////////////////////////
534

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

    
540
///////////////////////////////////////////////////////////////////////////////////////////////////
541

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

    
547
///////////////////////////////////////////////////////////////////////////////////////////////////
548

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

    
554
///////////////////////////////////////////////////////////////////////////////////////////////////
555

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

    
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562

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

    
568
///////////////////////////////////////////////////////////////////////////////////////////////////
569

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