Project

General

Profile

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

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ 05fa94d9

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
        mCanRotate = false;
113
        mFinishRotation=false;
114 434f2f5a Leszek Koltunski
        mRotationFinishedID = mNewCube.finishRotationNow(this);
115 0c52af30 Leszek Koltunski
        }
116
117
      if( mRemoveRotation )
118
        {
119
        mRemoveRotation=false;
120 f647630d Leszek Koltunski
        mNewCube.removeRotationNow();
121 05fa94d9 Leszek Koltunski
122
        if( mNewCube.isSolved() )
123
          {
124
          android.util.Log.e("renderer", "CUBE IS SOLVED NOW");
125
          }
126
127 0c52af30 Leszek Koltunski
        mCanRotate = true;
128
        }
129 34998c9d Leszek Koltunski
130 408d4676 Leszek Koltunski
      if( mSizeChangeCube )
131 34998c9d Leszek Koltunski
        {
132 408d4676 Leszek Koltunski
        mSizeChangeCube = false;
133
        mCanDrag        = false;
134
        mCanRotate      = false;
135 34998c9d Leszek Koltunski
        createCubeNow(mNextCubeSize);
136 05fa94d9 Leszek Koltunski
        doEffectNow( BaseEffect.Type.SIZECHANGE );
137 34998c9d Leszek Koltunski
        }
138 584f7954 Leszek Koltunski
139
      if( mSolveCube )
140
        {
141 2ecf0c21 Leszek Koltunski
        mSolveCube   = false;
142
        mCanDrag     = false;
143
        mCanRotate   = false;
144 45686da2 Leszek Koltunski
        mCanUI       = false;
145 05fa94d9 Leszek Koltunski
        doEffectNow( BaseEffect.Type.SOLVE );
146 584f7954 Leszek Koltunski
        }
147 3b12e641 Leszek Koltunski
148
      if( mScrambleCube )
149
        {
150
        mScrambleCube = false;
151
        mCanDrag      = false;
152
        mCanRotate    = false;
153 45686da2 Leszek Koltunski
        mCanUI        = false;
154 05fa94d9 Leszek Koltunski
        doEffectNow( BaseEffect.Type.SCRAMBLE );
155 3b12e641 Leszek Koltunski
        }
156 0c52af30 Leszek Koltunski
      }
157
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159 aa8b36aa Leszek Koltunski
160
   @Override
161
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
162
      {
163
      if( mNewCube!=null ) mNewCube.createTexture();
164
165
      float cameraDistance = CAMERA_DISTANCE*(width>height ? width:height);
166
      float fovInDegrees   = computeFOV(cameraDistance,height);
167
168
      mScreen.setProjection( fovInDegrees, 0.1f);
169
      mView.setScreenSize(width,height);
170
      mView.setCameraDist(cameraDistance);
171
      mScreen.resize(width, height);
172
173
      recomputeScaleFactor(width,height);
174
175
      mScreenHeight = height;
176
      mScreenWidth  = width;
177
      }
178
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180
181
   @Override
182
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
183
      {
184
      VertexEffectSink.enable();
185 64975793 Leszek Koltunski
      BaseEffect.Type.enableEffects();
186 aa8b36aa Leszek Koltunski
187
      try
188
        {
189
        DistortedLibrary.onCreate(mView.getContext());
190
        }
191
      catch(Exception ex)
192
        {
193
        android.util.Log.e("Rubik", ex.getMessage() );
194
        }
195
      }
196
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198 0c52af30 Leszek Koltunski
199 f647630d Leszek Koltunski
   public void effectFinished(final long effectID)
200 0c52af30 Leszek Koltunski
     {
201 45686da2 Leszek Koltunski
     if( effectID == mRotationFinishedID )
202 434f2f5a Leszek Koltunski
       {
203
       mRemoveRotation = true;
204
       }
205 45686da2 Leszek Koltunski
     else
206 3b12e641 Leszek Koltunski
       {
207 45686da2 Leszek Koltunski
       for(int i=0; i<BaseEffect.Type.LENGTH; i++)
208
         {
209
         if( effectID == mEffectID[i] )
210
           {
211
           mCanRotate   = true;
212
           mCanDrag     = true;
213
           mCanUI       = true;
214
           break;
215
           }
216
         }
217 3b12e641 Leszek Koltunski
       }
218 34747dd1 Leszek Koltunski
     }
219 f291130e Leszek Koltunski
220 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
221 34747dd1 Leszek Koltunski
222 aa8b36aa Leszek Koltunski
   private float computeFOV(float cameraDistance, int screenHeight)
223
     {
224
     double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) );
225
     return (float)(2*halfFOVInRadians*(180/Math.PI));
226
     }
227 34747dd1 Leszek Koltunski
228 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
229
// no this will not race with onDrawFrame
230 0c52af30 Leszek Koltunski
231 aa8b36aa Leszek Koltunski
   void finishRotation()
232
     {
233
     mFinishRotation = true;
234
     }
235 0c52af30 Leszek Koltunski
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237
238 f291130e Leszek Koltunski
   boolean createCube(int newSize)
239 34998c9d Leszek Koltunski
     {
240 34747dd1 Leszek Koltunski
     if( mCanDrag && mCanRotate && (mNewCube==null || newSize != mNewCube.getSize()) )
241 f291130e Leszek Koltunski
       {
242 408d4676 Leszek Koltunski
       mSizeChangeCube = true;
243 f291130e Leszek Koltunski
       mNextCubeSize = newSize;
244
       return true;
245
       }
246
247
     return false;
248 34998c9d Leszek Koltunski
     }
249
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251
252 ce0c7ca8 Leszek Koltunski
   private void recomputeScaleFactor(int screenWidth, int screenHeight)
253 8197c92d Leszek Koltunski
     {
254 ce0c7ca8 Leszek Koltunski
     mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(screenWidth>screenHeight ? screenHeight:screenWidth);
255 434f2f5a Leszek Koltunski
256 ce0c7ca8 Leszek Koltunski
     if( mNewCube!=null )
257
       {
258
       mNewCube.recomputeScaleFactor(screenWidth, screenHeight, mCubeSizeInScreenSpace);
259
       }
260
     }
261 9208e27b Leszek Koltunski
262 ce0c7ca8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
263 d1484aba Leszek Koltunski
264 ce0c7ca8 Leszek Koltunski
   void scrambleCube(int num)
265
     {
266 45686da2 Leszek Koltunski
     if( mCanUI )
267 e56c3711 Leszek Koltunski
       {
268 ce0c7ca8 Leszek Koltunski
       mScrambleCube = true;
269
       mScrambleCubeNum = num;
270 8197c92d Leszek Koltunski
       }
271
     }
272 0c52af30 Leszek Koltunski
273 d1484aba Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
274
275 ce0c7ca8 Leszek Koltunski
   void solveCube()
276 d1484aba Leszek Koltunski
     {
277 45686da2 Leszek Koltunski
     if( mCanUI )
278 34747dd1 Leszek Koltunski
       {
279 ce0c7ca8 Leszek Koltunski
       mSolveCube = true;
280 34747dd1 Leszek Koltunski
       }
281 d1484aba Leszek Koltunski
     }
282
283 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
284
285 ce0c7ca8 Leszek Koltunski
   private void createCubeNow(int newSize)
286 8197c92d Leszek Koltunski
     {
287 ce0c7ca8 Leszek Koltunski
     if( mOldCube!=null ) mOldCube.releaseResources();
288
     mOldCube = mNewCube;
289
290
     DistortedTexture texture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
291
     DistortedEffects effects = new DistortedEffects();
292
293 45686da2 Leszek Koltunski
     mNewCube = new RubikCube(newSize, mView.getQuatCurrent(), mView.getQuatAccumulated(), texture, mMesh, effects);
294 ce0c7ca8 Leszek Koltunski
     mNewCube.createTexture();
295
296
     if( mScreenWidth!=0 )
297 2ecf0c21 Leszek Koltunski
       {
298 ce0c7ca8 Leszek Koltunski
       recomputeScaleFactor(mScreenWidth,mScreenHeight);
299 2ecf0c21 Leszek Koltunski
       }
300 3b12e641 Leszek Koltunski
     }
301
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303 408d4676 Leszek Koltunski
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
304 3b12e641 Leszek Koltunski
305 05fa94d9 Leszek Koltunski
   private void doEffectNow(BaseEffect.Type type)
306 3b12e641 Leszek Koltunski
     {
307 05fa94d9 Leszek Koltunski
     int index = type.ordinal();
308
309
     mEffectID[index] = type.startEffect(this);
310 3b12e641 Leszek Koltunski
311 64975793 Leszek Koltunski
     if( mEffectID[index] == -1 )
312
       {
313 408d4676 Leszek Koltunski
       mCanUI     = true;
314 3b12e641 Leszek Koltunski
       mCanRotate = true;
315
       mCanDrag   = true;
316
       }
317 f548942f Leszek Koltunski
     }
318
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320 8197c92d Leszek Koltunski
321 64975793 Leszek Koltunski
   float returnCubeSizeInScreenSpace()
322 584f7954 Leszek Koltunski
     {
323 64975793 Leszek Koltunski
     return mCubeSizeInScreenSpace;
324 584f7954 Leszek Koltunski
     }
325
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327
328 64975793 Leszek Koltunski
   boolean canRotate()
329 f548942f Leszek Koltunski
     {
330 64975793 Leszek Koltunski
     return mCanRotate;
331
     }
332 584f7954 Leszek Koltunski
333 64975793 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
334
335
   boolean canDrag()
336
     {
337
     return mCanDrag;
338 8197c92d Leszek Koltunski
     }
339 0c52af30 Leszek Koltunski
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341
342 64975793 Leszek Koltunski
   public RubikCube getCube()
343 8197c92d Leszek Koltunski
     {
344 64975793 Leszek Koltunski
     return mNewCube;
345 8197c92d Leszek Koltunski
     }
346
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348
349 64975793 Leszek Koltunski
   public RubikCube getOldCube()
350 8197c92d Leszek Koltunski
     {
351 64975793 Leszek Koltunski
     return mOldCube;
352 8197c92d Leszek Koltunski
     }
353
354 434f2f5a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
355
356 64975793 Leszek Koltunski
   public DistortedScreen getScreen()
357 434f2f5a Leszek Koltunski
     {
358 64975793 Leszek Koltunski
     return mScreen;
359 434f2f5a Leszek Koltunski
     }
360
361 8197c92d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
362
363 64975793 Leszek Koltunski
   public int getNumScrambles()
364 8197c92d Leszek Koltunski
     {
365 64975793 Leszek Koltunski
     return mScrambleCubeNum;
366 8197c92d Leszek Koltunski
     }
367 0c52af30 Leszek Koltunski
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369
370 45686da2 Leszek Koltunski
   void setQuatCurrentOnNextRender()
371 8197c92d Leszek Koltunski
     {
372 05fa94d9 Leszek Koltunski
     mSetQuatCurrent = true;
373 8197c92d Leszek Koltunski
     }
374 0c52af30 Leszek Koltunski
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376
377 45686da2 Leszek Koltunski
   void setQuatAccumulatedOnNextRender()
378 8197c92d Leszek Koltunski
     {
379 05fa94d9 Leszek Koltunski
     mSetQuatAccumulated = true;
380 8197c92d Leszek Koltunski
     }
381 0c52af30 Leszek Koltunski
}