Project

General

Profile

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

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ 45686da2

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