Project

General

Profile

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

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ 27a70eae

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
25 64975793 Leszek Koltunski
import org.distorted.effect.BaseEffect;
26 0c52af30 Leszek Koltunski
import org.distorted.library.effect.VertexEffectSink;
27 9208e27b Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
28 e1111500 Leszek Koltunski
import org.distorted.library.main.DistortedLibrary;
29 0c52af30 Leszek Koltunski
import org.distorted.library.main.DistortedScreen;
30 9208e27b Leszek Koltunski
import org.distorted.library.main.DistortedTexture;
31 39fb9047 Leszek Koltunski
import org.distorted.library.mesh.MeshFlat;
32 0c52af30 Leszek Koltunski
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 211b48f2 Leszek Koltunski
import org.distorted.uistate.RubikState;
36 0333d81e Leszek Koltunski
import org.distorted.uistate.RubikStateSolving;
37 0c52af30 Leszek Koltunski
38
import javax.microedition.khronos.egl.EGLConfig;
39
import javax.microedition.khronos.opengles.GL10;
40
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42
43 9208e27b Leszek Koltunski
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
44 0c52af30 Leszek Koltunski
{
45 0fd3ac1f Leszek Koltunski
    static final float CAMERA_DISTANCE = 0.6f;  // 0.6 of the length of min(scrHeight,scrWidth)
46 123d6172 Leszek Koltunski
    public static final int TEXTURE_SIZE = 600;
47 0c52af30 Leszek Koltunski
48
    private RubikSurfaceView mView;
49
    private DistortedScreen mScreen;
50 27a70eae Leszek Koltunski
    private RubikObjectList mNextObject;
51
    private int mScrambleObjectNum;
52 64975793 Leszek Koltunski
    private long mRotationFinishedID;
53
    private long[] mEffectID;
54 05fa94d9 Leszek Koltunski
    private boolean mFinishRotation, mRemoveRotation, mSetQuatCurrent, mSetQuatAccumulated;
55 27a70eae Leszek Koltunski
    private boolean mChangeObject, mSolveObject, mScrambleObject;
56 45686da2 Leszek Koltunski
    private boolean mCanRotate, mCanDrag, mCanUI;
57 47ba5ddc Leszek Koltunski
    private boolean mIsSolved;
58 27a70eae Leszek Koltunski
    private RubikObject mOldObject, mNewObject;
59 d1484aba Leszek Koltunski
    private int mScreenWidth, mScreenHeight;
60 39fb9047 Leszek Koltunski
    private MeshFlat mMesh;
61 5bfc1b49 Leszek Koltunski
    private SharedPreferences mPreferences;
62 9208e27b Leszek Koltunski
63 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
64
65
    RubikRenderer(RubikSurfaceView v)
66
      {
67
      mView = v;
68
      mScreen = new DistortedScreen();
69
70 27a70eae Leszek Koltunski
      mOldObject = null;
71
      mNewObject = null;
72 434f2f5a Leszek Koltunski
73 d1484aba Leszek Koltunski
      mScreenWidth = mScreenHeight = 0;
74 27a70eae Leszek Koltunski
      mScrambleObjectNum = 0;
75 d1484aba Leszek Koltunski
76 05fa94d9 Leszek Koltunski
      mFinishRotation     = false;
77
      mRemoveRotation     = false;
78
      mSetQuatCurrent     = false;
79
      mSetQuatAccumulated = false;
80 27a70eae Leszek Koltunski
      mChangeObject       = false;
81
      mSolveObject        = false;
82
      mScrambleObject     = false;
83 0c52af30 Leszek Koltunski
84 2ecf0c21 Leszek Koltunski
      mCanRotate   = true;
85
      mCanDrag     = true;
86 45686da2 Leszek Koltunski
      mCanUI       = true;
87 9208e27b Leszek Koltunski
88 64975793 Leszek Koltunski
      mEffectID = new long[BaseEffect.Type.LENGTH];
89
90 39fb9047 Leszek Koltunski
      mMesh= new MeshFlat(20,20);
91 0c52af30 Leszek Koltunski
      }
92
93 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
94
95 27a70eae Leszek Koltunski
   private void createObjectNow(RubikObjectList object)
96 47ba5ddc Leszek Koltunski
     {
97 27a70eae Leszek Koltunski
     boolean firstTime = (mNewObject==null);
98 5bfc1b49 Leszek Koltunski
99 27a70eae Leszek Koltunski
     if( mOldObject!=null ) mOldObject.releaseResources();
100
     mOldObject = mNewObject;
101 47ba5ddc Leszek Koltunski
102
     DistortedTexture texture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
103
     DistortedEffects effects = new DistortedEffects();
104
105 27a70eae Leszek Koltunski
     mNewObject = object.create(mView.getQuatCurrent(), mView.getQuatAccumulated(), texture, mMesh, effects);
106
     mNewObject.createTexture();
107
     mView.setMovement(object.getObjectMovementClass());
108
109
     if( firstTime ) mNewObject.restorePreferences(mPreferences);
110 47ba5ddc Leszek Koltunski
111
     if( mScreenWidth!=0 )
112
       {
113 27a70eae Leszek Koltunski
       mNewObject.recomputeScaleFactor(mScreenWidth, mScreenHeight);
114 47ba5ddc Leszek Koltunski
       }
115
116
     mIsSolved = true;
117
     }
118
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
121
122
   private void doEffectNow(BaseEffect.Type type)
123
     {
124
     int index = type.ordinal();
125
126 beb325a0 Leszek Koltunski
     try
127
       {
128
       mEffectID[index] = type.startEffect(this);
129
       }
130
     catch( Exception ex )
131 47ba5ddc Leszek Koltunski
       {
132 beb325a0 Leszek Koltunski
       android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage());
133
134 47ba5ddc Leszek Koltunski
       mCanUI     = true;
135
       mCanRotate = true;
136
       mCanDrag   = true;
137
       }
138
     }
139
140 0333d81e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
141
142
   void savePreferences(SharedPreferences.Editor editor)
143
     {
144 27a70eae Leszek Koltunski
     mNewObject.savePreferences(editor);
145 0333d81e Leszek Koltunski
     }
146
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148
149
   void restorePreferences(SharedPreferences preferences)
150
     {
151 5bfc1b49 Leszek Koltunski
     mPreferences = preferences;
152 0333d81e Leszek Koltunski
     }
153
154 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
155
// no this will not race with onDrawFrame
156
157
   void finishRotation()
158
     {
159
     mFinishRotation = true;
160
     }
161
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163
164 27a70eae Leszek Koltunski
   boolean createObject(RubikObjectList object)
165 47ba5ddc Leszek Koltunski
     {
166 27a70eae Leszek Koltunski
     if( mCanDrag && mCanRotate && object!=mNextObject )
167 47ba5ddc Leszek Koltunski
       {
168 27a70eae Leszek Koltunski
       mChangeObject = true;
169
       mNextObject = object;
170 47ba5ddc Leszek Koltunski
       return true;
171
       }
172
173
     return false;
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 a7a7cc9c Leszek Koltunski
       }
253
254
     if( mRemoveRotation )
255
       {
256
       mRemoveRotation=false;
257 27a70eae Leszek Koltunski
       mNewObject.removeRotationNow();
258 a7a7cc9c Leszek Koltunski
259 27a70eae Leszek Koltunski
       boolean solved = mNewObject.isSolved();
260 a7a7cc9c Leszek Koltunski
261
       if( solved && !mIsSolved )
262
         {
263 0333d81e Leszek Koltunski
         if( RubikState.getCurrentState()==RubikState.SOLV )
264
           {
265
           RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
266
           long time = solving.stopCounting();
267
           android.util.Log.e("renderer", "solving time: "+time+" milliseconds");
268
           }
269
270
         mCanDrag   = true;
271
         mCanRotate = false;
272
         mCanUI     = false;
273 a7a7cc9c Leszek Koltunski
         doEffectNow( BaseEffect.Type.WIN );
274
         }
275
       else
276
         {
277
         mCanRotate = true;
278
         mCanUI     = true;
279
         }
280
281
       mIsSolved = solved;
282
       }
283
284 27a70eae Leszek Koltunski
     if( mChangeObject )
285 a7a7cc9c Leszek Koltunski
       {
286 27a70eae Leszek Koltunski
       mChangeObject = false;
287
       mCanDrag      = false;
288
       mCanRotate    = false;
289
       mCanUI        = false;
290
       createObjectNow(mNextObject);
291 a7a7cc9c Leszek Koltunski
       doEffectNow( BaseEffect.Type.SIZECHANGE );
292
       }
293
294 27a70eae Leszek Koltunski
     if( mSolveObject )
295 a7a7cc9c Leszek Koltunski
       {
296 27a70eae Leszek Koltunski
       mSolveObject    = false;
297 a7a7cc9c Leszek Koltunski
       mCanDrag        = false;
298
       mCanRotate      = false;
299
       mCanUI          = false;
300
       doEffectNow( BaseEffect.Type.SOLVE );
301
       }
302
303 27a70eae Leszek Koltunski
     if( mScrambleObject )
304 a7a7cc9c Leszek Koltunski
       {
305 27a70eae Leszek Koltunski
       mScrambleObject = false;
306
       mCanDrag        = false;
307
       mCanRotate      = false;
308
       mCanUI          = false;
309 a7a7cc9c Leszek Koltunski
       doEffectNow( BaseEffect.Type.SCRAMBLE );
310
       }
311
     }
312 0c52af30 Leszek Koltunski
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314 aa8b36aa Leszek Koltunski
315
   @Override
316
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
317
      {
318 27a70eae Leszek Koltunski
      if( mNewObject!=null ) mNewObject.createTexture();
319 aa8b36aa Leszek Koltunski
320 123d6172 Leszek Koltunski
      double halfFOVInRadians = Math.atan( 1.0f/(2*CAMERA_DISTANCE) );
321
      float fovInDegrees = (float)(2*halfFOVInRadians*(180/Math.PI));
322 beb325a0 Leszek Koltunski
323
      mScreen.setProjection( fovInDegrees, 0.1f);
324 aa8b36aa Leszek Koltunski
      mScreen.resize(width, height);
325 123d6172 Leszek Koltunski
      mView.setScreenSize(width,height);
326 aa8b36aa Leszek Koltunski
327 27a70eae Leszek Koltunski
      if( mNewObject!=null )
328 beb325a0 Leszek Koltunski
        {
329 27a70eae Leszek Koltunski
        mNewObject.recomputeScaleFactor(width,height);
330 beb325a0 Leszek Koltunski
        }
331 aa8b36aa Leszek Koltunski
332
      mScreenHeight = height;
333
      mScreenWidth  = width;
334
      }
335
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337
338
   @Override
339
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
340
      {
341
      VertexEffectSink.enable();
342 64975793 Leszek Koltunski
      BaseEffect.Type.enableEffects();
343 aa8b36aa Leszek Koltunski
344
      try
345
        {
346
        DistortedLibrary.onCreate(mView.getContext());
347
        }
348
      catch(Exception ex)
349
        {
350
        android.util.Log.e("Rubik", ex.getMessage() );
351
        }
352
      }
353
354 ad9e8bb3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
355
// PUBLIC API
356 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
357 0c52af30 Leszek Koltunski
358 f647630d Leszek Koltunski
   public void effectFinished(final long effectID)
359 0c52af30 Leszek Koltunski
     {
360 45686da2 Leszek Koltunski
     if( effectID == mRotationFinishedID )
361 434f2f5a Leszek Koltunski
       {
362
       mRemoveRotation = true;
363
       }
364 45686da2 Leszek Koltunski
     else
365 3b12e641 Leszek Koltunski
       {
366 45686da2 Leszek Koltunski
       for(int i=0; i<BaseEffect.Type.LENGTH; i++)
367
         {
368
         if( effectID == mEffectID[i] )
369
           {
370
           mCanRotate   = true;
371
           mCanDrag     = true;
372
           mCanUI       = true;
373 ad9e8bb3 Leszek Koltunski
374
           if( i==BaseEffect.Type.SCRAMBLE.ordinal() )
375
             {
376
             final RubikActivity act = (RubikActivity)mView.getContext();
377
378
             act.runOnUiThread(new Runnable()
379
               {
380
               @Override
381
               public void run()
382
                 {
383
                 RubikState.switchState( act, RubikState.SOLV);
384
                 }
385
               });
386
             }
387 45686da2 Leszek Koltunski
           break;
388
           }
389
         }
390 3b12e641 Leszek Koltunski
       }
391 34747dd1 Leszek Koltunski
     }
392 f291130e Leszek Koltunski
393 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
394
395 27a70eae Leszek Koltunski
   public RubikObject getObject()
396 8197c92d Leszek Koltunski
     {
397 27a70eae Leszek Koltunski
     return mNewObject;
398 8197c92d Leszek Koltunski
     }
399
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401
402 27a70eae Leszek Koltunski
   public RubikObject getOldObject()
403 8197c92d Leszek Koltunski
     {
404 27a70eae Leszek Koltunski
     return mOldObject;
405 8197c92d Leszek Koltunski
     }
406
407 434f2f5a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
408
409 64975793 Leszek Koltunski
   public DistortedScreen getScreen()
410 434f2f5a Leszek Koltunski
     {
411 64975793 Leszek Koltunski
     return mScreen;
412 434f2f5a Leszek Koltunski
     }
413
414 8197c92d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
415
416 64975793 Leszek Koltunski
   public int getNumScrambles()
417 8197c92d Leszek Koltunski
     {
418 27a70eae Leszek Koltunski
     return mScrambleObjectNum;
419 8197c92d Leszek Koltunski
     }
420 0c52af30 Leszek Koltunski
}