Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ d79a56d3

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

    
22
import java.io.IOException;
23
import java.io.InputStream;
24
import java.util.Random;
25

    
26
import javax.microedition.khronos.egl.EGLConfig;
27
import javax.microedition.khronos.opengles.GL10;
28

    
29
import org.distorted.examples.R;
30

    
31
import org.distorted.library.DistortedNode;
32
import org.distorted.library.DistortedScreen;
33
import org.distorted.library.MeshFlat;
34
import org.distorted.library.EffectNames;
35
import org.distorted.library.type.Dynamic1D;
36
import org.distorted.library.type.Dynamic3D;
37
import org.distorted.library.type.Static1D;
38
import org.distorted.library.type.Static3D;
39
import org.distorted.library.type.Static4D;
40
import org.distorted.library.message.EffectListener;
41
import org.distorted.library.message.EffectMessage;
42
import org.distorted.library.Distorted;
43
import org.distorted.library.DistortedTexture;
44
import org.distorted.library.DistortedEffects;
45

    
46
import android.graphics.Bitmap;
47
import android.graphics.BitmapFactory;
48
import android.graphics.Canvas;
49
import android.graphics.Paint;
50
import android.graphics.Typeface;
51
import android.opengl.GLES30;
52
import android.opengl.GLSurfaceView;
53

    
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

    
56
class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
57
  {
58
  private final String[] mGFFAString = 
59
         
60
            { "A long time ago, in a galaxy far,",
61
              "far away...." };                    // yes, there really was a four-dot ellipsis
62

    
63
  private final String[] mCRAWLString = 
64
      
65
            { "It is a period of civil war.",      // in the original 1977 version, there was no 
66
              "Rebel spaceships, striking",        // 'Episode IV New Hope' subtitle line before
67
              "from a hidden base, have",          // the crawl. Lets keep to the classic.
68
              "won their first victory",
69
              "against the evil Galactic",
70
              "Empire.",
71
              "",
72
              "During the battle, rebel",
73
              "spies managed to steal",
74
              "secret plans to the Empire's",
75
              "ultimate weapon, the",
76
              "DEATH STAR, an armored",
77
              "space station with enough",
78
              "power to destroy an entire",
79
              "planet.",
80
              "",
81
              "Pursued by the Empire's",
82
              "sinister agents, Princess",
83
              "Leia races home aboard her",
84
              "starship, custodian of the",
85
              "stolen plans that can save",
86
              "her people and restore",
87
              "freedom to the galaxy...." };      // four-dot.
88
   
89
  private final int NUM_STARS = 40;
90
   
91
  private final int CRAWL_COLOR = 0xffffe81f;
92
  private final int GFFA_COLOR  = 0xff0000ff;
93
  private final int FONT_HEIGHT      = 40;
94
  private final int VERTICAL_SPACING = 10;
95
  private final String CRAWL_TYPEFACE = "News Gothic";
96
   
97
  private final int CRAWL_WIDTH = 500;
98
  private final int CRAWL_HEIGHT= (FONT_HEIGHT+VERTICAL_SPACING)*(mCRAWLString.length+1);
99
   
100
  private final int GFFA_WIDTH = 600;
101
  private final int GFFA_HEIGHT= (FONT_HEIGHT+VERTICAL_SPACING)*(mGFFAString.length+1);
102
   
103
  private final float CRAWL_ANGLE = -30.0f;
104
  private final float FOV_ANGLE   =  60.0f;
105

    
106
  private GLSurfaceView mView;
107
  private DistortedTexture mGFFATexture, mLogoTexture, mCrawlTexture, mCrawlBackgroundTexture, mStarTexture;
108
  private DistortedEffects mGFFAEffects, mLogoEffects, mCrawlEffects, mCrawlBackgroundEffects;
109
  private DistortedEffects[] mStarEffects;
110
  private DistortedNode mBackground;
111
  private DistortedScreen mScreen;
112
  private MeshFlat mQuad;
113

    
114
  private long gffaID, logoID, crawlID;
115
  private Random mRnd = new Random(0);
116
  private int mWidth, mHeight;
117

    
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119

    
120
  StarWarsRenderer(GLSurfaceView v)
121
    {
122
    mView = v;
123

    
124
    mQuad = new MeshFlat(1,1);
125

    
126
    mGFFAEffects            = new DistortedEffects();
127
    mLogoEffects            = new DistortedEffects();
128
    mCrawlEffects           = new DistortedEffects();
129
    mCrawlBackgroundEffects = new DistortedEffects();
130

    
131
    if( NUM_STARS>0 )
132
      {
133
      mStarEffects = new DistortedEffects[NUM_STARS];
134
      mStarEffects[0] = new DistortedEffects();
135

    
136
      for (int i = 1; i < NUM_STARS; i++)
137
        mStarEffects[i] = new DistortedEffects(mStarEffects[0], Distorted.CLONE_VERTEX);
138
      }
139

    
140
    mScreen = new DistortedScreen();
141
    mScreen.setProjection(FOV_ANGLE, 0.02f);
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  public void onPause()
147
    {
148
    mWidth = 0;
149
    mHeight= 0;
150
    }
151

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153
   
154
  public void onDrawFrame(GL10 glUnused) 
155
    {
156
    mScreen.render(System.currentTimeMillis());
157
    }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160
    
161
  public void onSurfaceChanged(GL10 glUnused, int width, int height) 
162
    {
163
    if( mWidth!=width || mHeight!=height )  // after onPause() we get 2 calls here
164
      {
165
      mWidth = width;
166
      mHeight= height;
167

    
168
      mGFFAEffects.abortAllEffects();
169
      mLogoEffects.abortAllEffects();
170
      mCrawlEffects.abortAllEffects();
171
      mCrawlBackgroundEffects.abortAllEffects();
172

    
173
      for(int i=0; i<NUM_STARS; i++) mStarEffects[i].abortAllEffects();
174

    
175
      mScreen.detachAll();
176
      setupScreen(width,height);
177
      mScreen.resize(width, height);
178
      }
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182
    
183
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
184
    {
185
    setupBitmaps();
186

    
187
    DistortedEffects.enableEffect(EffectNames.SMOOTH_ALPHA);
188
    DistortedEffects.enableEffect(EffectNames.ALPHA);
189

    
190
    try
191
      {
192
      Distorted.onCreate(mView.getContext());
193
      }
194
    catch(Exception ex)
195
      {
196
      android.util.Log.e("Star Wars", ex.getMessage() );
197
      }
198
    }
199
    
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

    
202
  private void setupScreen(int w, int h)
203
    {
204
    double angleA = (90.0f - FOV_ANGLE/2)*Math.PI/180;
205
    double angleB = (90.0f - FOV_ANGLE/2 +CRAWL_ANGLE)*Math.PI/180;
206

    
207
    if( mCrawlBackgroundTexture!=null ) mCrawlBackgroundTexture.markForDeletion();
208
    mCrawlBackgroundTexture = new DistortedTexture(w,(int)(h*Math.sin(angleA)/Math.sin(angleB)));
209
       
210
    int randomTime;
211
    float randomX, randomY, randomS, randomAlpha1, randomAlpha2;
212

    
213
    float starScaleX = (float)mStarTexture.getWidth()/w;
214
    float starScaleY = (float)mStarTexture.getHeight()/h;
215

    
216
    Static1D alphaNoise = new Static1D(0.4f);
217

    
218
    for(int i=0; i<NUM_STARS; i++)
219
      {
220
      randomX = mRnd.nextFloat() -0.5f;
221
      randomY = mRnd.nextFloat() -0.5f;
222
      randomS = 0.2f+ 0.8f*mRnd.nextFloat();
223
      randomAlpha1 = 0.2f + 0.8f*mRnd.nextFloat();
224
      randomAlpha2 = 0.8f + 0.2f*mRnd.nextFloat();
225
      randomTime = 500+mRnd.nextInt(2000);
226
      
227
      mStarEffects[i].move( new Static3D(randomX,randomY,0) );
228
      mStarEffects[i].scale( new Static3D(randomS*starScaleX, randomS*starScaleY, 1) );
229

    
230
      Dynamic1D di = new Dynamic1D(randomTime,0.0f);
231
      di.setNoise(alphaNoise);
232
      di.add(new Static1D(randomAlpha1));
233
      di.add(new Static1D(randomAlpha2));
234
      
235
      mStarEffects[i].alpha(di);
236
      
237
      mScreen.attach(mStarTexture, mStarEffects[i], mQuad);
238
      }
239

    
240
    float qx = (float)mGFFATexture.getWidth()/w;
241
    float qy = (float)mGFFATexture.getHeight()/h;
242

    
243
    Dynamic1D di = new Dynamic1D(6000,0.5f);
244
    di.add(new Static1D(1.0f));
245
    di.add(new Static1D(1.0f));
246
    di.add(new Static1D(0.0f));
247
    
248
    mGFFAEffects.move( new Static3D(qx/2-0.3f,qy/2-0.16f,0) );
249
    mGFFAEffects.scale( new Static3D(qx,qy,1) );
250
    mGFFAEffects.alpha(di);
251
      
252
    mScreen.attach(mGFFATexture, mGFFAEffects, mQuad);
253
    mGFFAEffects.registerForMessages(this);
254
    }
255
    
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

    
258
  private void setupBitmaps()
259
    {
260
    InputStream is1 = mView.getContext().getResources().openRawResource(R.raw.starwars);
261
    InputStream is2 = mView.getContext().getResources().openRawResource(R.raw.star);
262
    
263
    Bitmap bitmapStar, bitmapGFFA, bitmapLogo, bitmapText;
264
      
265
    try 
266
      {
267
      bitmapLogo = BitmapFactory.decodeStream(is1);
268
      bitmapStar = BitmapFactory.decodeStream(is2);
269
      } 
270
    finally 
271
      {
272
      try 
273
        {
274
        is1.close();
275
        is2.close();
276
        } 
277
      catch(IOException e) { }
278
      } 
279
      
280
    Paint paint = new Paint();
281
    paint.setAntiAlias(true);
282
    paint.setTextAlign(Paint.Align.LEFT);
283
    paint.setTextSize(FONT_HEIGHT);
284
    paint.setColor(GFFA_COLOR);
285
      
286
    Typeface tf = Typeface.create(CRAWL_TYPEFACE, Typeface.BOLD);
287
    paint.setTypeface(tf);     
288
 
289
    ///// create GFFA ///////////////////
290
    if( mGFFATexture==null ) mGFFATexture  = new DistortedTexture(GFFA_WIDTH,GFFA_HEIGHT);
291
    bitmapGFFA = Bitmap.createBitmap(GFFA_WIDTH,GFFA_HEIGHT,Bitmap.Config.ARGB_8888);
292
    bitmapGFFA.eraseColor(0x00000000);
293
    Canvas gffaCanvas = new Canvas(bitmapGFFA);
294
      
295
    for(int i=0; i<mGFFAString.length; i++)
296
      {
297
      gffaCanvas.drawText(mGFFAString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), paint);  
298
      }
299
  
300
    mGFFATexture.setTexture(bitmapGFFA);
301
      
302
    ///// create Logo ///////////////////
303
    if( mLogoTexture==null ) mLogoTexture  = new DistortedTexture(bitmapLogo.getWidth(),bitmapLogo.getHeight());
304
    mLogoTexture.setTexture(bitmapLogo);
305

    
306
    ///// create CRAWL //////////////////
307
    if( mCrawlTexture==null ) mCrawlTexture = new DistortedTexture(CRAWL_WIDTH,CRAWL_HEIGHT);
308
    bitmapText = Bitmap.createBitmap(CRAWL_WIDTH,CRAWL_HEIGHT,Bitmap.Config.ARGB_8888);
309
    bitmapText.eraseColor(0x00000000);
310
    Canvas textCanvas = new Canvas(bitmapText);
311
    paint.setColor(CRAWL_COLOR);
312
  
313
    for(int i=0; i<mCRAWLString.length; i++)
314
      {
315
      displayJustified(mCRAWLString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), CRAWL_WIDTH, textCanvas, paint);  
316
      }
317
      
318
    mCrawlTexture.setTexture(bitmapText);
319
      
320
    ///// create Stars ///////////////////
321
    if( mStarTexture==null ) mStarTexture = new DistortedTexture(bitmapStar.getWidth(),bitmapStar.getHeight());
322
    mStarTexture.setTexture(bitmapStar);
323

    
324
    gffaID = mGFFAEffects.getID();
325
    logoID = mLogoEffects.getID();
326
    crawlID= mCrawlEffects.getID();
327
    }
328
 
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
  private void displayJustified(String str, int x, int y, int length, Canvas c, Paint paint)
332
    { 
333
    int len       = str.length();
334
    int numspaces = retNumSpaces(str);
335
    
336
    if( len>0 && str.charAt(len-1) == ' ' ) numspaces--;
337

    
338
    float left=x,w = (numspaces>0 ? (length-paint.measureText(str))/numspaces : 0);
339
    String tmp;
340
    int begin,end=0;
341

    
342
    while( end<len )
343
      {
344
      begin=end;
345
      end = str.indexOf(' ', begin)+1;
346
      if( end<=0 ) end = len;
347

    
348
      tmp = str.substring(begin,end);
349
      c.drawText( tmp, left, y, paint);
350
      left+= (paint.measureText(tmp)+w);
351
      }  
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355
   
356
  private int retNumSpaces(String str)
357
    {
358
    int begin=0, ret=0;
359

    
360
    while( true )
361
      {
362
      begin = str.indexOf(' ', begin) +1;
363

    
364
      if( begin>0 ) ret++;
365
      else break;
366
      }
367

    
368
    return ret;
369
    }
370
    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372
// the library sending messages to us. This is running on a library 'MessageSender' thread.
373

    
374
  public void effectMessage(final EffectMessage em, final long effectID, final EffectNames effectName, final long objectID)
375
    {
376
    if( em==EffectMessage.EFFECT_FINISHED )
377
      {
378
      if( objectID == gffaID )
379
        {
380
        mScreen.detach(mGFFAEffects);
381
        mGFFATexture.markForDeletion();
382

    
383
        float qx= (float)mScreen.getWidth() /mLogoTexture.getWidth() ;
384
        float qy= (float)mScreen.getHeight()/mLogoTexture.getHeight();
385

    
386
        float initSize= 3.0f;
387
        float finaSize= 0.1f;
388
      
389
        Dynamic3D di = new Dynamic3D(10000,0.5f);
390
        di.add(qx<qy ? (new Static3D(initSize,initSize*qx/qy,1)) : (new Static3D(initSize*qy/qx,initSize,1)));
391
        di.add(qx<qy ? (new Static3D(finaSize,finaSize*qx/qy,1)) : (new Static3D(finaSize*qy/qx,finaSize,1)));
392

    
393
        mLogoEffects.scale(di);
394

    
395
        mScreen.attach(mLogoTexture, mLogoEffects,mQuad);
396
        mLogoEffects.registerForMessages(this);
397
        }
398
      else if( objectID==logoID )
399
        {
400
        mScreen.detach(mLogoEffects);
401
        mLogoTexture.markForDeletion();
402
        
403
        int crawlW = mCrawlTexture.getWidth();
404
        int crawlH = mCrawlTexture.getHeight();
405
        int screenW= mScreen.getWidth();
406
        int screenH= mScreen.getHeight();
407
        int backH  = mCrawlBackgroundTexture.getHeight();
408
        float scale= (float)screenW/crawlW;
409

    
410
        //mCrawlBackgroundEffects.move( new Static3D(0,screenH-backH,0) );
411
        mCrawlBackgroundEffects.rotate( new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(0.5f,1.0f,0.0f) );
412
        mCrawlBackgroundEffects.scale( new Static3D(1.0f, (float)backH/screenH,1.0f) );
413

    
414
        final int transpDist = 5;
415
        Static4D region = new Static4D(screenW/2,(1-transpDist)*backH,transpDist*backH,transpDist*backH);
416
        //mCrawlBackgroundEffects.alpha(new Static1D(1-transpDist*0.6f), region, true);
417

    
418
        Dynamic3D di = new Dynamic3D(70000,0.5f);
419
        di.add(new Static3D(screenW/2,+backH       , 0));
420
        di.add(new Static3D(screenW/2,-scale*crawlH, 0));
421

    
422
        //mCrawlEffects.move(di);
423
        //mCrawlEffects.scale( new Static3D(scale,scale,scale) );
424
        //mCrawlEffects.move( new Static3D(-crawlW/2,0,0) );
425
        
426
        mBackground = mScreen.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects,mQuad);
427
        mBackground.attach(mCrawlTexture, mCrawlEffects,mQuad);
428
        mBackground.glDisable(GLES30.GL_DEPTH_TEST);
429
        mBackground.glDepthMask(false);
430
        mCrawlEffects.registerForMessages(this);
431
        }
432
      else if( objectID==crawlID )
433
        {
434
        mScreen.detach(mBackground);
435
        mBackground.detach(mCrawlEffects);
436
        mCrawlTexture.markForDeletion();
437
        mCrawlBackgroundEffects.abortAllEffects();
438
        mCrawlBackgroundTexture.markForDeletion();
439
        }
440
      }
441
    }
442
  }
(2-2/3)