Project

General

Profile

Download (14.1 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ aa171dee

1 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4 fdec60a3 Leszek Koltunski
// This file is part of Magic Cube.                                                              //
5 0c52af30 Leszek Koltunski
//                                                                                               //
6 fdec60a3 Leszek Koltunski
// Magic Cube is free software: you can redistribute it and/or modify                            //
7 0c52af30 Leszek Koltunski
// 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 fdec60a3 Leszek Koltunski
// Magic Cube is distributed in the hope that it will be useful,                                 //
12 0c52af30 Leszek Koltunski
// 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 fdec60a3 Leszek Koltunski
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.magic;
21
22 0333d81e Leszek Koltunski
import android.content.SharedPreferences;
23 0c52af30 Leszek Koltunski
import android.opengl.GLSurfaceView;
24 e41e7dc3 Leszek Koltunski
import android.os.Bundle;
25 0c52af30 Leszek Koltunski
26 bc511ea5 Leszek Koltunski
import org.distorted.dialog.RubikDialogNewRecord;
27 e41e7dc3 Leszek Koltunski
import org.distorted.dialog.RubikDialogSolved;
28 64975793 Leszek Koltunski
import org.distorted.effect.BaseEffect;
29 0c52af30 Leszek Koltunski
import org.distorted.library.effect.VertexEffectSink;
30 e1111500 Leszek Koltunski
import org.distorted.library.main.DistortedLibrary;
31 0c52af30 Leszek Koltunski
import org.distorted.library.main.DistortedScreen;
32
import org.distorted.library.message.EffectListener;
33 4f9f99a2 Leszek Koltunski
import org.distorted.object.RubikObject;
34 27a70eae Leszek Koltunski
import org.distorted.object.RubikObjectList;
35 c3ffcf58 Leszek Koltunski
import org.distorted.scores.RubikScores;
36 211b48f2 Leszek Koltunski
import org.distorted.uistate.RubikState;
37 0333d81e Leszek Koltunski
import org.distorted.uistate.RubikStateSolving;
38 0c52af30 Leszek Koltunski
39
import javax.microedition.khronos.egl.EGLConfig;
40
import javax.microedition.khronos.opengles.GL10;
41
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43
44 9208e27b Leszek Koltunski
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
45 0c52af30 Leszek Koltunski
{
46 ba740a0c Leszek Koltunski
    public static final int NODE_FBO_SIZE = 600;
47 0c52af30 Leszek Koltunski
48
    private RubikSurfaceView mView;
49
    private DistortedScreen mScreen;
50 27a70eae Leszek Koltunski
    private RubikObjectList mNextObject;
51 4888e97c Leszek Koltunski
    private int mNextSize;
52 27a70eae Leszek Koltunski
    private int mScrambleObjectNum;
53 64975793 Leszek Koltunski
    private long mRotationFinishedID;
54
    private long[] mEffectID;
55 05fa94d9 Leszek Koltunski
    private boolean mFinishRotation, mRemoveRotation, mSetQuatCurrent, mSetQuatAccumulated;
56 27a70eae Leszek Koltunski
    private boolean mChangeObject, mSolveObject, mScrambleObject;
57 45686da2 Leszek Koltunski
    private boolean mCanRotate, mCanDrag, mCanUI;
58 47ba5ddc Leszek Koltunski
    private boolean mIsSolved;
59 e41e7dc3 Leszek Koltunski
    private boolean mIsNewRecord;
60
    private long mNewRecord;
61 27a70eae Leszek Koltunski
    private RubikObject mOldObject, mNewObject;
62 d1484aba Leszek Koltunski
    private int mScreenWidth, mScreenHeight;
63 5bfc1b49 Leszek Koltunski
    private SharedPreferences mPreferences;
64 aa171dee Leszek Koltunski
    private String mNextMoves;
65 9208e27b Leszek Koltunski
66 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
67
68
    RubikRenderer(RubikSurfaceView v)
69
      {
70
      mView = v;
71
      mScreen = new DistortedScreen();
72
73 27a70eae Leszek Koltunski
      mOldObject = null;
74
      mNewObject = null;
75 434f2f5a Leszek Koltunski
76 d1484aba Leszek Koltunski
      mScreenWidth = mScreenHeight = 0;
77 27a70eae Leszek Koltunski
      mScrambleObjectNum = 0;
78 d1484aba Leszek Koltunski
79 05fa94d9 Leszek Koltunski
      mFinishRotation     = false;
80
      mRemoveRotation     = false;
81
      mSetQuatCurrent     = false;
82
      mSetQuatAccumulated = false;
83 27a70eae Leszek Koltunski
      mChangeObject       = false;
84
      mSolveObject        = false;
85
      mScrambleObject     = false;
86 0c52af30 Leszek Koltunski
87 2ecf0c21 Leszek Koltunski
      mCanRotate   = true;
88
      mCanDrag     = true;
89 45686da2 Leszek Koltunski
      mCanUI       = true;
90 9208e27b Leszek Koltunski
91 64975793 Leszek Koltunski
      mEffectID = new long[BaseEffect.Type.LENGTH];
92 0c52af30 Leszek Koltunski
      }
93
94 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
95
96 aa171dee Leszek Koltunski
   private void createObjectNow(RubikObjectList object, int size, String moves)
97 47ba5ddc Leszek Koltunski
     {
98 27a70eae Leszek Koltunski
     boolean firstTime = (mNewObject==null);
99 5bfc1b49 Leszek Koltunski
100 27a70eae Leszek Koltunski
     if( mOldObject!=null ) mOldObject.releaseResources();
101
     mOldObject = mNewObject;
102 47ba5ddc Leszek Koltunski
103 aa171dee Leszek Koltunski
     mNewObject = object.create(size, mView.getQuatCurrent(), mView.getQuatAccumulated(), moves);
104 27a70eae Leszek Koltunski
     mNewObject.createTexture();
105
     mView.setMovement(object.getObjectMovementClass());
106
107
     if( firstTime ) mNewObject.restorePreferences(mPreferences);
108 47ba5ddc Leszek Koltunski
109
     if( mScreenWidth!=0 )
110
       {
111 27a70eae Leszek Koltunski
       mNewObject.recomputeScaleFactor(mScreenWidth, mScreenHeight);
112 47ba5ddc Leszek Koltunski
       }
113
114
     mIsSolved = true;
115
     }
116
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
119
120
   private void doEffectNow(BaseEffect.Type type)
121
     {
122
     int index = type.ordinal();
123
124 beb325a0 Leszek Koltunski
     try
125
       {
126
       mEffectID[index] = type.startEffect(this);
127
       }
128
     catch( Exception ex )
129 47ba5ddc Leszek Koltunski
       {
130 beb325a0 Leszek Koltunski
       android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage());
131
132 47ba5ddc Leszek Koltunski
       mCanUI     = true;
133
       mCanRotate = true;
134
       mCanDrag   = true;
135
       }
136
     }
137
138 0333d81e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
139
140
   void savePreferences(SharedPreferences.Editor editor)
141
     {
142 3c4a326c Leszek Koltunski
     if( mNewObject!=null )
143
       {
144
       mNewObject.savePreferences(editor);
145
       }
146 0333d81e Leszek Koltunski
     }
147
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
150
   void restorePreferences(SharedPreferences preferences)
151
     {
152 5bfc1b49 Leszek Koltunski
     mPreferences = preferences;
153 0333d81e Leszek Koltunski
     }
154
155 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
156
// no this will not race with onDrawFrame
157
158
   void finishRotation()
159
     {
160
     mFinishRotation = true;
161
     }
162
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164
165 aa171dee Leszek Koltunski
   void changeObject(RubikObjectList object, int size, String moves)
166 47ba5ddc Leszek Koltunski
     {
167 aa171dee Leszek Koltunski
     if( size>0 )
168 47ba5ddc Leszek Koltunski
       {
169 27a70eae Leszek Koltunski
       mChangeObject = true;
170
       mNextObject = object;
171 4888e97c Leszek Koltunski
       mNextSize   = size;
172 aa171dee Leszek Koltunski
       mNextMoves  = moves;
173 47ba5ddc Leszek Koltunski
       }
174
     }
175
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177
178 27a70eae Leszek Koltunski
   void scrambleObject(int num)
179 47ba5ddc Leszek Koltunski
     {
180
     if( mCanUI )
181
       {
182 27a70eae Leszek Koltunski
       mScrambleObject = true;
183
       mScrambleObjectNum = num;
184 47ba5ddc Leszek Koltunski
       }
185
     }
186
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188
189 27a70eae Leszek Koltunski
   void solveObject()
190 47ba5ddc Leszek Koltunski
     {
191
     if( mCanUI )
192
       {
193 27a70eae Leszek Koltunski
       mSolveObject = true;
194 47ba5ddc Leszek Koltunski
       }
195
     }
196
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198
199
   boolean canRotate()
200
     {
201
     return mCanRotate;
202
     }
203
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205
206
   boolean canDrag()
207
     {
208
     return mCanDrag;
209
     }
210
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212
213
   void setQuatCurrentOnNextRender()
214
     {
215
     mSetQuatCurrent = true;
216
     }
217
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219
220
   void setQuatAccumulatedOnNextRender()
221
     {
222
     mSetQuatAccumulated = true;
223
     }
224
225 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
226
// various things are done here delayed, 'after the next render' as not to be done mid-render and
227
// cause artifacts.
228
229 a7a7cc9c Leszek Koltunski
   @Override
230
   public void onDrawFrame(GL10 glUnused)
231
     {
232
     mScreen.render( System.currentTimeMillis() );
233
234
     if( mSetQuatCurrent )
235
       {
236
       mSetQuatCurrent = false;
237
       mView.setQuatCurrent();
238
       }
239
240
     if( mSetQuatAccumulated )
241
       {
242
       mSetQuatAccumulated = false;
243
       mView.setQuatAccumulated();
244
       }
245
246
     if( mFinishRotation )
247
       {
248
       mFinishRotation = false;
249
       mCanRotate      = false;
250
       mCanUI          = false;
251 27a70eae Leszek Koltunski
       mRotationFinishedID = mNewObject.finishRotationNow(this);
252 9cd7695f Leszek Koltunski
253
       if( mRotationFinishedID==0 ) // failed to add effect - should never happen
254
         {
255
         mCanRotate = true;
256
         mCanUI     = true;
257
         }
258 a7a7cc9c Leszek Koltunski
       }
259
260
     if( mRemoveRotation )
261
       {
262
       mRemoveRotation=false;
263 27a70eae Leszek Koltunski
       mNewObject.removeRotationNow();
264 a7a7cc9c Leszek Koltunski
265 27a70eae Leszek Koltunski
       boolean solved = mNewObject.isSolved();
266 a7a7cc9c Leszek Koltunski
267
       if( solved && !mIsSolved )
268
         {
269 0333d81e Leszek Koltunski
         if( RubikState.getCurrentState()==RubikState.SOLV )
270
           {
271
           RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
272 e41e7dc3 Leszek Koltunski
           mNewRecord = solving.stopCounting((RubikActivity)mView.getContext());
273
274
           if( mNewRecord< 0 )
275
             {
276
             mNewRecord = -mNewRecord;
277
             mIsNewRecord = false;
278
             }
279
           else
280
             {
281
             mIsNewRecord = true;
282
             }
283 0333d81e Leszek Koltunski
           }
284
285
         mCanDrag   = true;
286
         mCanRotate = false;
287
         mCanUI     = false;
288 a7a7cc9c Leszek Koltunski
         doEffectNow( BaseEffect.Type.WIN );
289
         }
290
       else
291
         {
292
         mCanRotate = true;
293
         mCanUI     = true;
294
         }
295
296
       mIsSolved = solved;
297
       }
298
299 27a70eae Leszek Koltunski
     if( mChangeObject )
300 a7a7cc9c Leszek Koltunski
       {
301 27a70eae Leszek Koltunski
       mChangeObject = false;
302
       mCanDrag      = false;
303
       mCanRotate    = false;
304
       mCanUI        = false;
305 aa171dee Leszek Koltunski
306
       if( mNewObject==null )
307
         {
308
         createObjectNow(mNextObject, mNextSize, mNextMoves);
309
         doEffectNow( BaseEffect.Type.SIZECHANGE );
310
         }
311
       else
312
         {
313
         RubikObjectList list = mNewObject.getObjectList();
314
         int size = mNewObject.getSize();
315
316
         if (list!=mNextObject || mNextSize!=size)
317
           {
318
           createObjectNow(mNextObject, mNextSize, mNextMoves);
319
           doEffectNow( BaseEffect.Type.SIZECHANGE );
320
           }
321
         else
322
           {
323
           mNewObject.initializeObject(mNextMoves);
324
           }
325
         }
326 a7a7cc9c Leszek Koltunski
       }
327
328 27a70eae Leszek Koltunski
     if( mSolveObject )
329 a7a7cc9c Leszek Koltunski
       {
330 27a70eae Leszek Koltunski
       mSolveObject    = false;
331 a7a7cc9c Leszek Koltunski
       mCanDrag        = false;
332
       mCanRotate      = false;
333
       mCanUI          = false;
334
       doEffectNow( BaseEffect.Type.SOLVE );
335
       }
336
337 27a70eae Leszek Koltunski
     if( mScrambleObject )
338 a7a7cc9c Leszek Koltunski
       {
339 27a70eae Leszek Koltunski
       mScrambleObject = false;
340
       mCanDrag        = false;
341
       mCanRotate      = false;
342
       mCanUI          = false;
343 fec72009 Leszek Koltunski
       mIsSolved       = false;
344 c3ffcf58 Leszek Koltunski
       RubikScores.getInstance().incrementNumPlays();
345 a7a7cc9c Leszek Koltunski
       doEffectNow( BaseEffect.Type.SCRAMBLE );
346
       }
347
     }
348 0c52af30 Leszek Koltunski
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350 aa8b36aa Leszek Koltunski
351
   @Override
352
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
353
      {
354 27a70eae Leszek Koltunski
      if( mNewObject!=null ) mNewObject.createTexture();
355 aa8b36aa Leszek Koltunski
356
      mScreen.resize(width, height);
357 123d6172 Leszek Koltunski
      mView.setScreenSize(width,height);
358 aa8b36aa Leszek Koltunski
359 27a70eae Leszek Koltunski
      if( mNewObject!=null )
360 beb325a0 Leszek Koltunski
        {
361 27a70eae Leszek Koltunski
        mNewObject.recomputeScaleFactor(width,height);
362 beb325a0 Leszek Koltunski
        }
363 aa8b36aa Leszek Koltunski
364
      mScreenHeight = height;
365
      mScreenWidth  = width;
366
      }
367
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369
370
   @Override
371
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
372
      {
373
      VertexEffectSink.enable();
374 64975793 Leszek Koltunski
      BaseEffect.Type.enableEffects();
375 aa8b36aa Leszek Koltunski
376
      try
377
        {
378
        DistortedLibrary.onCreate(mView.getContext());
379
        }
380
      catch(Exception ex)
381
        {
382
        android.util.Log.e("Rubik", ex.getMessage() );
383
        }
384
      }
385
386 ad9e8bb3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
387
// PUBLIC API
388 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
389 0c52af30 Leszek Koltunski
390 f647630d Leszek Koltunski
   public void effectFinished(final long effectID)
391 0c52af30 Leszek Koltunski
     {
392 45686da2 Leszek Koltunski
     if( effectID == mRotationFinishedID )
393 434f2f5a Leszek Koltunski
       {
394
       mRemoveRotation = true;
395
       }
396 45686da2 Leszek Koltunski
     else
397 3b12e641 Leszek Koltunski
       {
398 45686da2 Leszek Koltunski
       for(int i=0; i<BaseEffect.Type.LENGTH; i++)
399
         {
400
         if( effectID == mEffectID[i] )
401
           {
402
           mCanRotate   = true;
403
           mCanDrag     = true;
404
           mCanUI       = true;
405 ad9e8bb3 Leszek Koltunski
406
           if( i==BaseEffect.Type.SCRAMBLE.ordinal() )
407
             {
408
             final RubikActivity act = (RubikActivity)mView.getContext();
409
410
             act.runOnUiThread(new Runnable()
411
               {
412
               @Override
413
               public void run()
414
                 {
415
                 RubikState.switchState( act, RubikState.SOLV);
416
                 }
417
               });
418
             }
419 e41e7dc3 Leszek Koltunski
420
           if( i==BaseEffect.Type.WIN.ordinal() )
421
             {
422
             if( RubikState.getCurrentState()==RubikState.SOLV )
423
               {
424
               final RubikActivity act = (RubikActivity)mView.getContext();
425 bc511ea5 Leszek Koltunski
               Bundle bundle = new Bundle();
426
               bundle.putLong("time", mNewRecord );
427 e41e7dc3 Leszek Koltunski
428
               if( mIsNewRecord )
429
                 {
430 bc511ea5 Leszek Koltunski
                 RubikDialogNewRecord dialog = new RubikDialogNewRecord();
431 e41e7dc3 Leszek Koltunski
                 dialog.setArguments(bundle);
432
                 dialog.show( act.getSupportFragmentManager(), null);
433
                 }
434
               else
435
                 {
436
                 RubikDialogSolved dialog = new RubikDialogSolved();
437
                 dialog.setArguments(bundle);
438
                 dialog.show( act.getSupportFragmentManager(), null);
439
                 }
440
               }
441
             }
442
443 45686da2 Leszek Koltunski
           break;
444
           }
445
         }
446 3b12e641 Leszek Koltunski
       }
447 34747dd1 Leszek Koltunski
     }
448 f291130e Leszek Koltunski
449 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
450
451 27a70eae Leszek Koltunski
   public RubikObject getObject()
452 8197c92d Leszek Koltunski
     {
453 27a70eae Leszek Koltunski
     return mNewObject;
454 8197c92d Leszek Koltunski
     }
455
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457
458 27a70eae Leszek Koltunski
   public RubikObject getOldObject()
459 8197c92d Leszek Koltunski
     {
460 27a70eae Leszek Koltunski
     return mOldObject;
461 8197c92d Leszek Koltunski
     }
462
463 434f2f5a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
464
465 64975793 Leszek Koltunski
   public DistortedScreen getScreen()
466 434f2f5a Leszek Koltunski
     {
467 64975793 Leszek Koltunski
     return mScreen;
468 434f2f5a Leszek Koltunski
     }
469
470 8197c92d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
471
472 64975793 Leszek Koltunski
   public int getNumScrambles()
473 8197c92d Leszek Koltunski
     {
474 27a70eae Leszek Koltunski
     return mScrambleObjectNum;
475 8197c92d Leszek Koltunski
     }
476 0c52af30 Leszek Koltunski
}