Project

General

Profile

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

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

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
  public StarWarsRenderer(GLSurfaceView v) 
113
    {
114
    mView = v;
115
     
116
    Distorted.setFov(60.0f);
117
    }
118

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

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

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

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

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

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

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

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

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

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

    
321
      if( begin>0 ) ret++;
322
      else break;
323
      }
324

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

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

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