Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ 10d53839

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.EffectNames;
32
import org.distorted.library.type.Dynamic1D;
33
import org.distorted.library.type.Dynamic3D;
34
import org.distorted.library.DistortedNode;
35
import org.distorted.library.type.Static1D;
36
import org.distorted.library.type.Static3D;
37
import org.distorted.library.type.Static4D;
38
import org.distorted.library.message.EffectListener;
39
import org.distorted.library.message.EffectMessage;
40
import org.distorted.library.Distorted;
41
import org.distorted.library.DistortedBitmap;
42

    
43
import android.graphics.Bitmap;
44
import android.graphics.BitmapFactory;
45
import android.graphics.Canvas;
46
import android.graphics.Paint;
47
import android.graphics.Typeface;
48
import android.opengl.GLES20;
49
import android.opengl.GLSurfaceView;
50

    
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52

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

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

    
112
  StarWarsRenderer(GLSurfaceView v)
113
    {
114
    mView = v;
115
     
116
    Distorted.setProjection(60.0f, 0.0f, 0.0f);
117
    }
118

    
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120
   
121
  public void onDrawFrame(GL10 glUnused) 
122
    {
123
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
124
    mRoot.draw(System.currentTimeMillis());
125
    }
126

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128
    
129
  public void onSurfaceChanged(GL10 glUnused, int width, int height) 
130
    { 
131
    Distorted.onSurfaceChanged(width, height); 
132
    setupScreen(width,height);
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136
    
137
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
138
    {
139
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
140

    
141
    setupBitmaps();
142
         
143
    try
144
      {
145
      Distorted.onSurfaceCreated(mView.getContext());
146
      }
147
    catch(Exception ex)
148
      {
149
      android.util.Log.e("Star Wars", ex.getMessage() );
150
      }
151
    }
152
    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

    
155
  private void setupScreen(int w, int h)
156
    {
157
    mScreen = new DistortedBitmap(w,h,1);
158
    mRoot = new DistortedNode(mScreen);
159
      
160
    mCrawlBackground = new DistortedBitmap(w,(int)(Math.sqrt(3.0)*h),1);
161
       
162
    int randomA, randomX, randomY, randomTime;
163
    float randomS, randomAlpha1, randomAlpha2;
164
       
165
    Static3D center = new Static3D(0,0,0);
166
    Static3D axis   = new Static3D(0,0,1);
167

    
168
    Static1D alphaNoise = new Static1D(0.4f);
169

    
170
    for(int i=0; i<NUM_STARS; i++)
171
      {
172
      randomX = mRnd.nextInt(w);
173
      randomY = mRnd.nextInt(h);
174
      randomS = 0.2f+ mRnd.nextFloat();
175
      randomA = (int)(180*mRnd.nextFloat());
176
      randomAlpha1 = 0.2f + 0.8f*mRnd.nextFloat();
177
      randomAlpha2 = 0.8f + 0.2f*mRnd.nextFloat();
178
      randomTime = 500+mRnd.nextInt(2000);
179
      
180
      mStars[i].move( new Static3D(randomX,randomY,0) );
181
      mStars[i].scale( new Static3D(randomS,randomS,randomS) );
182
      mStars[i].rotate( new Static1D(randomA), axis, center );
183
      
184
      Dynamic1D di = new Dynamic1D(randomTime,0.0f);
185
      di.setNoise(alphaNoise);
186
      di.add(new Static1D(randomAlpha1));
187
      di.add(new Static1D(randomAlpha2));
188
      
189
      mStars[i].alpha(di);
190
      
191
      mRoot.attach(mStars[i]);
192
      }
193
      
194
    float scale = (0.5f*w/mGFFA.getWidth());
195
    
196
    Dynamic1D di = new Dynamic1D(6000,0.5f);
197
    di.add(new Static1D(1.0f));
198
    di.add(new Static1D(1.0f));
199
    di.add(new Static1D(0.0f));
200
    
201
    mGFFA.move( new Static3D(w/5,h/3,0) );
202
    mGFFA.scale( new Static3D(scale,scale,scale) );
203
    mGFFA.alpha(di);
204
      
205
    mRoot.attach(mGFFA);
206
    mGFFA.addEventListener(this); 
207
    }
208
    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

    
211
  private void setupBitmaps()
212
    {
213
    InputStream is1 = mView.getContext().getResources().openRawResource(R.raw.starwars);
214
    InputStream is2 = mView.getContext().getResources().openRawResource(R.raw.star);
215
    
216
    Bitmap bitmapStar, bitmapGFFA, bitmapLogo, bitmapText;
217
      
218
    try 
219
      {
220
      bitmapLogo = BitmapFactory.decodeStream(is1);
221
      bitmapStar = BitmapFactory.decodeStream(is2);
222
      } 
223
    finally 
224
      {
225
      try 
226
        {
227
        is1.close();
228
        is2.close();
229
        } 
230
      catch(IOException e) { }
231
      } 
232
      
233
    Paint paint = new Paint();
234
    paint.setAntiAlias(true);
235
    paint.setTextAlign(Paint.Align.LEFT);
236
    paint.setTextSize(FONT_HEIGHT);
237
    paint.setColor(GFFA_COLOR);
238
      
239
    Typeface tf = Typeface.create(CRAWL_TYPEFACE, Typeface.BOLD);
240
    paint.setTypeface(tf);     
241
 
242
    ///// create GFFA ///////////////////
243
    mGFFA  = new DistortedBitmap(GFFA_WIDTH, GFFA_HEIGHT, 1);
244
    bitmapGFFA = Bitmap.createBitmap(GFFA_WIDTH,GFFA_HEIGHT,Bitmap.Config.ARGB_8888);
245
    bitmapGFFA.eraseColor(0x00000000);
246
    Canvas gffaCanvas = new Canvas(bitmapGFFA);
247
      
248
    for(int i=0; i<mGFFAString.length; i++)
249
      {
250
      gffaCanvas.drawText(mGFFAString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), paint);  
251
      }
252
  
253
    mGFFA.setBitmap(bitmapGFFA);
254
      
255
    ///// create Logo ///////////////////
256
    mLogo  = new DistortedBitmap(bitmapLogo, 1);
257
      
258
    ///// create CRAWL //////////////////
259
    mCrawl = new DistortedBitmap(CRAWL_WIDTH, CRAWL_HEIGHT, 1);
260
    bitmapText = Bitmap.createBitmap(CRAWL_WIDTH,CRAWL_HEIGHT,Bitmap.Config.ARGB_8888);
261
    bitmapText.eraseColor(0x00000000);
262
    Canvas textCanvas = new Canvas(bitmapText);
263
    paint.setColor(CRAWL_COLOR);
264
  
265
    for(int i=0; i<mCRAWLString.length; i++)
266
      {
267
      displayJustified(mCRAWLString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), CRAWL_WIDTH, textCanvas, paint);  
268
      }
269
      
270
    mCrawl.setBitmap(bitmapText);
271
      
272
    ///// create Stars ///////////////////
273
      
274
    mStars = new DistortedBitmap[NUM_STARS];
275
      
276
    mStars[0] = new DistortedBitmap(bitmapStar,1);
277
      
278
    for(int i=1; i<NUM_STARS; i++)
279
      {
280
      mStars[i] = new DistortedBitmap(mStars[0], Distorted.CLONE_BITMAP|Distorted.CLONE_VERTEX);  
281
      }
282
      
283
    gffaID = mGFFA.getID();
284
    logoID = mLogo.getID();
285
    crawlID= mCrawl.getID();
286
    }
287
 
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289

    
290
  private void displayJustified(String str, int x, int y, int length, Canvas c, Paint paint)
291
    { 
292
    int len       = str.length();
293
    int numspaces = retNumSpaces(str);
294
    
295
    if( len>0 && str.charAt(len-1) == ' ' ) numspaces--;
296

    
297
    float left=x,w = (numspaces>0 ? (length-paint.measureText(str))/numspaces : 0);
298
    String tmp;
299
    int begin,end=0;
300

    
301
    while( end<len )
302
      {
303
      begin=end;
304
      end = str.indexOf(' ', begin)+1;
305
      if( end<=0 ) end = len;
306

    
307
      tmp = str.substring(begin,end);
308
      c.drawText( tmp, left, y, paint);
309
      left+= (paint.measureText(tmp)+w);
310
      }  
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314
   
315
  private int retNumSpaces(String str)
316
    {
317
    int begin=0, ret=0;
318

    
319
    while( true )
320
      {
321
      begin = str.indexOf(' ', begin) +1;
322

    
323
      if( begin>0 ) ret++;
324
      else break;
325
      }
326

    
327
    return ret;
328
    }
329
    
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331
// the library sending messages to us. This is running on a library 'MessageSender' thread.
332

    
333
  public void effectMessage(final EffectMessage em, final long effectID, final EffectNames effectName, final long objectID, final String message)
334
    {
335
    if( em==EffectMessage.EFFECT_FINISHED )
336
      {
337
      if( objectID == gffaID )
338
        {
339
        mRoot.detach(mGFFA);   
340
        mGFFA.removeEventListener(this);
341
       
342
        int screenW=mScreen.getWidth();
343
        int screenH=mScreen.getHeight();
344
        
345
        int logoW = mLogo.getWidth();
346
        int logoH = mLogo.getHeight();
347
      
348
        int initSize= (int)(3.0f*screenW/logoW);
349
        int finaSize= (int)(0.1f*screenW/logoW);
350
      
351
        Dynamic3D di = new Dynamic3D(10000,0.5f);
352
        di.add(new Static3D(initSize,initSize,1));
353
        di.add(new Static3D(finaSize,finaSize,1));
354

    
355
        mLogo.move( new Static3D(screenW/2,screenH/2,0) );
356
        mLogo.scale(di);
357
        mLogo.move( new Static3D(-logoW/2,-logoH/2,0) );
358
      
359
        mRoot.attach(mLogo);
360
        mLogo.addEventListener(this);
361
        }
362
      else if( objectID==logoID )
363
        {
364
        mRoot.detach(mLogo);   
365
        mLogo.removeEventListener(this);
366
        
367
        int crawlW = mCrawl.getWidth();
368
        int crawlH = mCrawl.getHeight();
369
        int screenW= mScreen.getWidth();
370
        int screenH= mScreen.getHeight();
371
        int backH  = mCrawlBackground.getHeight();
372
        float scale= (float)screenW/crawlW;
373
      
374
        Dynamic3D di = new Dynamic3D(60000,0.5f);
375
        di.add(new Static3D(screenW/2,+backH       , 0));
376
        di.add(new Static3D(screenW/2,-scale*crawlH, 0));
377
        
378
        mCrawlBackground.move( new Static3D(0,screenH-backH,0) );
379
        mCrawlBackground.rotate( new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,backH,0) );
380
        
381
        final int transpDist = 5;
382
        Static4D region = new Static4D(screenW/2,(1-transpDist)*backH,transpDist*backH,transpDist*backH);
383
        mCrawlBackground.alpha(new Static1D(1-transpDist/2), region, true);
384
        
385
        mCrawl.move(di);
386
        mCrawl.scale( new Static3D(scale,scale,scale) );
387
        mCrawl.move( new Static3D(-crawlW/2,0,0) );
388
        
389
        mBackground = mRoot.attach(mCrawlBackground);
390
        mBackground.attach(mCrawl);
391
        mCrawl.addEventListener(this);
392
        }
393
      else if( objectID==crawlID )
394
        {
395
        mRoot.detach(mBackground);
396
        mBackground.detach(mCrawl);
397
        mCrawl.removeEventListener(this);
398
        }
399
      }
400
    }
401
  }
(2-2/3)