Project

General

Profile

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

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

1 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4 ffd744be Leszek Koltunski
// This file is part of Distorted.                                                               //
5 0c52af30 Leszek Koltunski
//                                                                                               //
6 ffd744be Leszek Koltunski
// Distorted 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 ffd744be Leszek Koltunski
// Distorted 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 ffd744be Leszek Koltunski
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.magic;
21
22
import android.opengl.GLSurfaceView;
23
24 64975793 Leszek Koltunski
import org.distorted.effect.BaseEffect;
25 0c52af30 Leszek Koltunski
import org.distorted.library.effect.VertexEffectSink;
26 9208e27b Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
27 e1111500 Leszek Koltunski
import org.distorted.library.main.DistortedLibrary;
28 0c52af30 Leszek Koltunski
import org.distorted.library.main.DistortedScreen;
29 9208e27b Leszek Koltunski
import org.distorted.library.main.DistortedTexture;
30 39fb9047 Leszek Koltunski
import org.distorted.library.mesh.MeshFlat;
31 0c52af30 Leszek Koltunski
import org.distorted.library.message.EffectListener;
32
33
import javax.microedition.khronos.egl.EGLConfig;
34
import javax.microedition.khronos.opengles.GL10;
35
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37
38 9208e27b Leszek Koltunski
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
39 0c52af30 Leszek Koltunski
{
40
    private static final float CUBE_SCREEN_RATIO = 0.5f;
41
    private static final float CAMERA_DISTANCE   = 0.6f;  // 0.6 of the length of max(scrHeight,scrWidth)
42 9208e27b Leszek Koltunski
    public  static final int TEXTURE_SIZE = 600;
43 0c52af30 Leszek Koltunski
44
    private RubikSurfaceView mView;
45
    private DistortedScreen mScreen;
46
    private float mCubeSizeInScreenSpace;
47 3b12e641 Leszek Koltunski
    private int mNextCubeSize, mScrambleCubeNum;
48 64975793 Leszek Koltunski
    private long mRotationFinishedID;
49
    private long[] mEffectID;
50 05fa94d9 Leszek Koltunski
    private boolean mFinishRotation, mRemoveRotation, mSetQuatCurrent, mSetQuatAccumulated;
51 408d4676 Leszek Koltunski
    private boolean mSizeChangeCube, mSolveCube, mScrambleCube;
52 45686da2 Leszek Koltunski
    private boolean mCanRotate, mCanDrag, mCanUI;
53 434f2f5a Leszek Koltunski
    private RubikCube mOldCube, mNewCube;
54 d1484aba Leszek Koltunski
    private int mScreenWidth, mScreenHeight;
55 39fb9047 Leszek Koltunski
    private MeshFlat mMesh;
56 9208e27b Leszek Koltunski
57 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
58
59
    RubikRenderer(RubikSurfaceView v)
60
      {
61
      mView = v;
62
63
      mScreen = new DistortedScreen();
64
65 434f2f5a Leszek Koltunski
      mOldCube = null;
66
      mNewCube = null;
67
68 d1484aba Leszek Koltunski
      mScreenWidth = mScreenHeight = 0;
69 3b12e641 Leszek Koltunski
      mScrambleCubeNum = 0;
70 d1484aba Leszek Koltunski
71 05fa94d9 Leszek Koltunski
      mFinishRotation     = false;
72
      mRemoveRotation     = false;
73
      mSetQuatCurrent     = false;
74
      mSetQuatAccumulated = false;
75
      mSizeChangeCube     = true;
76
      mSolveCube          = false;
77
      mScrambleCube       = false;
78 0c52af30 Leszek Koltunski
79 2ecf0c21 Leszek Koltunski
      mCanRotate   = true;
80
      mCanDrag     = true;
81 45686da2 Leszek Koltunski
      mCanUI       = true;
82 9208e27b Leszek Koltunski
83 64975793 Leszek Koltunski
      mEffectID = new long[BaseEffect.Type.LENGTH];
84
85 39fb9047 Leszek Koltunski
      mMesh= new MeshFlat(20,20);
86 05fa94d9 Leszek Koltunski
      mNextCubeSize = RubikActivity.getSize();
87 0c52af30 Leszek Koltunski
      }
88
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90
// various things are done here delayed, 'after the next render' as not to be done mid-render and
91
// cause artifacts.
92
93 aa8b36aa Leszek Koltunski
    @Override
94 0c52af30 Leszek Koltunski
    public void onDrawFrame(GL10 glUnused) 
95
      {
96
      mScreen.render( System.currentTimeMillis() );
97
98 05fa94d9 Leszek Koltunski
      if( mSetQuatCurrent )
99 0c52af30 Leszek Koltunski
        {
100 05fa94d9 Leszek Koltunski
        mSetQuatCurrent = false;
101 45686da2 Leszek Koltunski
        mView.setQuatCurrent();
102 0c52af30 Leszek Koltunski
        }
103
104 05fa94d9 Leszek Koltunski
      if( mSetQuatAccumulated )
105 0c52af30 Leszek Koltunski
        {
106 05fa94d9 Leszek Koltunski
        mSetQuatAccumulated = false;
107 45686da2 Leszek Koltunski
        mView.setQuatAccumulated();
108 0c52af30 Leszek Koltunski
        }
109
110
      if( mFinishRotation )
111
        {
112 ebb64a1d Leszek Koltunski
        mFinishRotation = false;
113
        mCanRotate      = false;
114
        mCanUI          = false;
115 434f2f5a Leszek Koltunski
        mRotationFinishedID = mNewCube.finishRotationNow(this);
116 0c52af30 Leszek Koltunski
        }
117
118
      if( mRemoveRotation )
119
        {
120
        mRemoveRotation=false;
121 f647630d Leszek Koltunski
        mNewCube.removeRotationNow();
122 05fa94d9 Leszek Koltunski
123
        if( mNewCube.isSolved() )
124
          {
125 ebb64a1d Leszek Koltunski
          mCanDrag        = false;
126
          mCanRotate      = false;
127
          mCanUI          = false;
128
          doEffectNow( BaseEffect.Type.WIN );
129
          }
130
        else
131
          {
132
          mCanRotate = true;
133
          mCanUI     = true;
134 05fa94d9 Leszek Koltunski
          }
135 0c52af30 Leszek Koltunski
        }
136 34998c9d Leszek Koltunski
137 408d4676 Leszek Koltunski
      if( mSizeChangeCube )
138 34998c9d Leszek Koltunski
        {
139 408d4676 Leszek Koltunski
        mSizeChangeCube = false;
140
        mCanDrag        = false;
141
        mCanRotate      = false;
142 ebb64a1d Leszek Koltunski
        mCanUI          = false;
143 34998c9d Leszek Koltunski
        createCubeNow(mNextCubeSize);
144 05fa94d9 Leszek Koltunski
        doEffectNow( BaseEffect.Type.SIZECHANGE );
145 34998c9d Leszek Koltunski
        }
146 584f7954 Leszek Koltunski
147
      if( mSolveCube )
148
        {
149 ebb64a1d Leszek Koltunski
        mSolveCube      = false;
150
        mCanDrag        = false;
151
        mCanRotate      = false;
152
        mCanUI          = false;
153 05fa94d9 Leszek Koltunski
        doEffectNow( BaseEffect.Type.SOLVE );
154 584f7954 Leszek Koltunski
        }
155 3b12e641 Leszek Koltunski
156
      if( mScrambleCube )
157
        {
158
        mScrambleCube = false;
159
        mCanDrag      = false;
160
        mCanRotate    = false;
161 45686da2 Leszek Koltunski
        mCanUI        = false;
162 05fa94d9 Leszek Koltunski
        doEffectNow( BaseEffect.Type.SCRAMBLE );
163 3b12e641 Leszek Koltunski
        }
164 0c52af30 Leszek Koltunski
      }
165
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167 aa8b36aa Leszek Koltunski
168
   @Override
169
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
170
      {
171
      if( mNewCube!=null ) mNewCube.createTexture();
172
173
      float cameraDistance = CAMERA_DISTANCE*(width>height ? width:height);
174
      float fovInDegrees   = computeFOV(cameraDistance,height);
175
176
      mScreen.setProjection( fovInDegrees, 0.1f);
177
      mView.setScreenSize(width,height);
178
      mView.setCameraDist(cameraDistance);
179
      mScreen.resize(width, height);
180
181
      recomputeScaleFactor(width,height);
182
183
      mScreenHeight = height;
184
      mScreenWidth  = width;
185
      }
186
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188
189
   @Override
190
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
191
      {
192
      VertexEffectSink.enable();
193 64975793 Leszek Koltunski
      BaseEffect.Type.enableEffects();
194 aa8b36aa Leszek Koltunski
195
      try
196
        {
197
        DistortedLibrary.onCreate(mView.getContext());
198
        }
199
      catch(Exception ex)
200
        {
201
        android.util.Log.e("Rubik", ex.getMessage() );
202
        }
203
      }
204
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206 0c52af30 Leszek Koltunski
207 f647630d Leszek Koltunski
   public void effectFinished(final long effectID)
208 0c52af30 Leszek Koltunski
     {
209 45686da2 Leszek Koltunski
     if( effectID == mRotationFinishedID )
210 434f2f5a Leszek Koltunski
       {
211
       mRemoveRotation = true;
212
       }
213 45686da2 Leszek Koltunski
     else
214 3b12e641 Leszek Koltunski
       {
215 45686da2 Leszek Koltunski
       for(int i=0; i<BaseEffect.Type.LENGTH; i++)
216
         {
217
         if( effectID == mEffectID[i] )
218
           {
219
           mCanRotate   = true;
220
           mCanDrag     = true;
221
           mCanUI       = true;
222
           break;
223
           }
224
         }
225 3b12e641 Leszek Koltunski
       }
226 34747dd1 Leszek Koltunski
     }
227 f291130e Leszek Koltunski
228 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
229 34747dd1 Leszek Koltunski
230 aa8b36aa Leszek Koltunski
   private float computeFOV(float cameraDistance, int screenHeight)
231
     {
232
     double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) );
233
     return (float)(2*halfFOVInRadians*(180/Math.PI));
234
     }
235 34747dd1 Leszek Koltunski
236 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
237
// no this will not race with onDrawFrame
238 0c52af30 Leszek Koltunski
239 aa8b36aa Leszek Koltunski
   void finishRotation()
240
     {
241
     mFinishRotation = true;
242
     }
243 0c52af30 Leszek Koltunski
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245
246 f291130e Leszek Koltunski
   boolean createCube(int newSize)
247 34998c9d Leszek Koltunski
     {
248 34747dd1 Leszek Koltunski
     if( mCanDrag && mCanRotate && (mNewCube==null || newSize != mNewCube.getSize()) )
249 f291130e Leszek Koltunski
       {
250 408d4676 Leszek Koltunski
       mSizeChangeCube = true;
251 f291130e Leszek Koltunski
       mNextCubeSize = newSize;
252
       return true;
253
       }
254
255
     return false;
256 34998c9d Leszek Koltunski
     }
257
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259
260 ce0c7ca8 Leszek Koltunski
   private void recomputeScaleFactor(int screenWidth, int screenHeight)
261 8197c92d Leszek Koltunski
     {
262 ce0c7ca8 Leszek Koltunski
     mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(screenWidth>screenHeight ? screenHeight:screenWidth);
263 434f2f5a Leszek Koltunski
264 ce0c7ca8 Leszek Koltunski
     if( mNewCube!=null )
265
       {
266
       mNewCube.recomputeScaleFactor(screenWidth, screenHeight, mCubeSizeInScreenSpace);
267
       }
268
     }
269 9208e27b Leszek Koltunski
270 ce0c7ca8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
271 d1484aba Leszek Koltunski
272 ce0c7ca8 Leszek Koltunski
   void scrambleCube(int num)
273
     {
274 45686da2 Leszek Koltunski
     if( mCanUI )
275 e56c3711 Leszek Koltunski
       {
276 ce0c7ca8 Leszek Koltunski
       mScrambleCube = true;
277
       mScrambleCubeNum = num;
278 8197c92d Leszek Koltunski
       }
279
     }
280 0c52af30 Leszek Koltunski
281 d1484aba Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
282
283 ce0c7ca8 Leszek Koltunski
   void solveCube()
284 d1484aba Leszek Koltunski
     {
285 45686da2 Leszek Koltunski
     if( mCanUI )
286 34747dd1 Leszek Koltunski
       {
287 ce0c7ca8 Leszek Koltunski
       mSolveCube = true;
288 34747dd1 Leszek Koltunski
       }
289 d1484aba Leszek Koltunski
     }
290
291 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
292
293 ce0c7ca8 Leszek Koltunski
   private void createCubeNow(int newSize)
294 8197c92d Leszek Koltunski
     {
295 ce0c7ca8 Leszek Koltunski
     if( mOldCube!=null ) mOldCube.releaseResources();
296
     mOldCube = mNewCube;
297
298
     DistortedTexture texture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
299
     DistortedEffects effects = new DistortedEffects();
300
301 45686da2 Leszek Koltunski
     mNewCube = new RubikCube(newSize, mView.getQuatCurrent(), mView.getQuatAccumulated(), texture, mMesh, effects);
302 ce0c7ca8 Leszek Koltunski
     mNewCube.createTexture();
303
304
     if( mScreenWidth!=0 )
305 2ecf0c21 Leszek Koltunski
       {
306 ce0c7ca8 Leszek Koltunski
       recomputeScaleFactor(mScreenWidth,mScreenHeight);
307 2ecf0c21 Leszek Koltunski
       }
308 3b12e641 Leszek Koltunski
     }
309
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311 408d4676 Leszek Koltunski
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
312 3b12e641 Leszek Koltunski
313 05fa94d9 Leszek Koltunski
   private void doEffectNow(BaseEffect.Type type)
314 3b12e641 Leszek Koltunski
     {
315 05fa94d9 Leszek Koltunski
     int index = type.ordinal();
316
317
     mEffectID[index] = type.startEffect(this);
318 3b12e641 Leszek Koltunski
319 64975793 Leszek Koltunski
     if( mEffectID[index] == -1 )
320
       {
321 408d4676 Leszek Koltunski
       mCanUI     = true;
322 3b12e641 Leszek Koltunski
       mCanRotate = true;
323
       mCanDrag   = true;
324
       }
325 f548942f Leszek Koltunski
     }
326
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328 8197c92d Leszek Koltunski
329 64975793 Leszek Koltunski
   float returnCubeSizeInScreenSpace()
330 584f7954 Leszek Koltunski
     {
331 64975793 Leszek Koltunski
     return mCubeSizeInScreenSpace;
332 584f7954 Leszek Koltunski
     }
333
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335
336 64975793 Leszek Koltunski
   boolean canRotate()
337 f548942f Leszek Koltunski
     {
338 64975793 Leszek Koltunski
     return mCanRotate;
339
     }
340 584f7954 Leszek Koltunski
341 64975793 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
342
343
   boolean canDrag()
344
     {
345
     return mCanDrag;
346 8197c92d Leszek Koltunski
     }
347 0c52af30 Leszek Koltunski
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349
350 64975793 Leszek Koltunski
   public RubikCube getCube()
351 8197c92d Leszek Koltunski
     {
352 64975793 Leszek Koltunski
     return mNewCube;
353 8197c92d Leszek Koltunski
     }
354
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356
357 64975793 Leszek Koltunski
   public RubikCube getOldCube()
358 8197c92d Leszek Koltunski
     {
359 64975793 Leszek Koltunski
     return mOldCube;
360 8197c92d Leszek Koltunski
     }
361
362 434f2f5a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
363
364 64975793 Leszek Koltunski
   public DistortedScreen getScreen()
365 434f2f5a Leszek Koltunski
     {
366 64975793 Leszek Koltunski
     return mScreen;
367 434f2f5a Leszek Koltunski
     }
368
369 8197c92d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
370
371 64975793 Leszek Koltunski
   public int getNumScrambles()
372 8197c92d Leszek Koltunski
     {
373 64975793 Leszek Koltunski
     return mScrambleCubeNum;
374 8197c92d Leszek Koltunski
     }
375 0c52af30 Leszek Koltunski
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377
378 45686da2 Leszek Koltunski
   void setQuatCurrentOnNextRender()
379 8197c92d Leszek Koltunski
     {
380 05fa94d9 Leszek Koltunski
     mSetQuatCurrent = true;
381 8197c92d Leszek Koltunski
     }
382 0c52af30 Leszek Koltunski
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384
385 45686da2 Leszek Koltunski
   void setQuatAccumulatedOnNextRender()
386 8197c92d Leszek Koltunski
     {
387 05fa94d9 Leszek Koltunski
     mSetQuatAccumulated = true;
388 8197c92d Leszek Koltunski
     }
389 0c52af30 Leszek Koltunski
}