Project

General

Profile

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

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ 5560eea9

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 34747dd1 Leszek Koltunski
import org.distorted.effect.AppearEffect;
25
import org.distorted.effect.DisappearEffect;
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
import org.distorted.library.mesh.MeshQuad;
32 0c52af30 Leszek Koltunski
import org.distorted.library.message.EffectListener;
33
import org.distorted.library.message.EffectMessage;
34
import org.distorted.library.type.Static4D;
35
36
import javax.microedition.khronos.egl.EGLConfig;
37
import javax.microedition.khronos.opengles.GL10;
38
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40
41 9208e27b Leszek Koltunski
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
42 0c52af30 Leszek Koltunski
{
43
    private static final float CUBE_SCREEN_RATIO = 0.5f;
44
    private static final float CAMERA_DISTANCE   = 0.6f;  // 0.6 of the length of max(scrHeight,scrWidth)
45 9208e27b Leszek Koltunski
    public  static final int TEXTURE_SIZE = 600;
46 0c52af30 Leszek Koltunski
47
    private RubikSurfaceView mView;
48
    private DistortedScreen mScreen;
49
    private Static4D mQuatCurrent, mQuatAccumulated;
50
    private Static4D mTempCurrent, mTempAccumulated;
51
    private float mCubeSizeInScreenSpace;
52 34998c9d Leszek Koltunski
    private int mNextCubeSize;
53 34747dd1 Leszek Koltunski
    private long mRotationFinishedID, mDisappearEffectID, mAppearEffectID;
54 0c52af30 Leszek Koltunski
    private boolean mFinishRotation, mRemoveRotation, mFinishDragCurrent, mFinishDragAccumulated;
55 434f2f5a Leszek Koltunski
    private boolean mCanRotate, mCanDrag;
56
    private RubikCube mOldCube, mNewCube;
57 d1484aba Leszek Koltunski
    private int mScreenWidth, mScreenHeight;
58 9208e27b Leszek Koltunski
    private MeshQuad mMesh;
59 aa8b36aa Leszek Koltunski
    private AppearEffect.Type mAppearType;
60
    private DisappearEffect.Type mDisappearType;
61
    private int mAppearDuration, mDisappearDuration;
62 9208e27b Leszek Koltunski
63 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
64
65
    RubikRenderer(RubikSurfaceView v)
66
      {
67
      mView = v;
68
69
      mScreen = new DistortedScreen();
70
71 434f2f5a Leszek Koltunski
      mOldCube = null;
72
      mNewCube = null;
73
74 0c52af30 Leszek Koltunski
      mTempCurrent     = new Static4D(0,0,0,1);
75 ee5c2ae1 Leszek Koltunski
      mTempAccumulated = new Static4D(0,0,0,1);
76 0c52af30 Leszek Koltunski
      mQuatCurrent     = new Static4D(0,0,0,1);
77 ee5c2ae1 Leszek Koltunski
      mQuatAccumulated = new Static4D(0,0,0,1);
78 0c52af30 Leszek Koltunski
79 d1484aba Leszek Koltunski
      mScreenWidth = mScreenHeight = 0;
80
81 0c52af30 Leszek Koltunski
      mFinishRotation        = false;
82
      mRemoveRotation        = false;
83
      mFinishDragCurrent     = false;
84
      mFinishDragAccumulated = false;
85
86
      mCanRotate = true;
87 434f2f5a Leszek Koltunski
      mCanDrag   = true;
88 9208e27b Leszek Koltunski
89 fe381d8e Leszek Koltunski
      mAppearType        = AppearEffect.Type.SCALE;
90
      mDisappearType     = DisappearEffect.Type.SCALE;
91 aa8b36aa Leszek Koltunski
      mAppearDuration    = 1000;
92
      mDisappearDuration = 1000;
93
94 9208e27b Leszek Koltunski
      mMesh= new MeshQuad();
95 34747dd1 Leszek Koltunski
      mNextCubeSize =RubikActivity.getSize();
96 0c52af30 Leszek Koltunski
      }
97
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99
// various things are done here delayed, 'after the next render' as not to be done mid-render and
100
// cause artifacts.
101
102 aa8b36aa Leszek Koltunski
    @Override
103 0c52af30 Leszek Koltunski
    public void onDrawFrame(GL10 glUnused) 
104
      {
105
      mScreen.render( System.currentTimeMillis() );
106
107
      if( mFinishDragCurrent )
108
        {
109
        mFinishDragCurrent = false;
110
        mQuatCurrent.set(mTempCurrent);
111
        }
112
113
      if( mFinishDragAccumulated )
114
        {
115
        mFinishDragAccumulated = false;
116
        mQuatAccumulated.set(mTempAccumulated);
117
        }
118
119
      if( mFinishRotation )
120
        {
121
        mCanRotate = false;
122
        mFinishRotation=false;
123 434f2f5a Leszek Koltunski
        mRotationFinishedID = mNewCube.finishRotationNow(this);
124 0c52af30 Leszek Koltunski
        }
125
126
      if( mRemoveRotation )
127
        {
128
        mRemoveRotation=false;
129 434f2f5a Leszek Koltunski
        mNewCube.removeRotationNow(this);
130 0c52af30 Leszek Koltunski
        mCanRotate = true;
131
        }
132 34998c9d Leszek Koltunski
133
      if( mNextCubeSize!=0 )
134
        {
135
        createCubeNow(mNextCubeSize);
136 434f2f5a Leszek Koltunski
137 34747dd1 Leszek Koltunski
        mCanDrag   = false;
138
        mCanRotate = false;
139 34998c9d Leszek Koltunski
        mNextCubeSize = 0;
140 34747dd1 Leszek Koltunski
141
        if( mOldCube!=null ) disappearCube();
142
        else                    appearCube();
143 34998c9d Leszek Koltunski
        }
144 0c52af30 Leszek Koltunski
      }
145
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147 aa8b36aa Leszek Koltunski
148
   @Override
149
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
150
      {
151
      if( mNewCube!=null ) mNewCube.createTexture();
152
153
      float cameraDistance = CAMERA_DISTANCE*(width>height ? width:height);
154
      float fovInDegrees   = computeFOV(cameraDistance,height);
155
156
      mScreen.setProjection( fovInDegrees, 0.1f);
157
      mView.setScreenSize(width,height);
158
      mView.setCameraDist(cameraDistance);
159
      mScreen.resize(width, height);
160
161
      recomputeScaleFactor(width,height);
162
163
      mScreenHeight = height;
164
      mScreenWidth  = width;
165
      }
166
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
169
   @Override
170
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
171
      {
172
      VertexEffectSink.enable();
173
      AppearEffect.enableEffects();
174
      DisappearEffect.enableEffects();
175
176
      try
177
        {
178
        DistortedLibrary.onCreate(mView.getContext());
179
        }
180
      catch(Exception ex)
181
        {
182
        android.util.Log.e("Rubik", ex.getMessage() );
183
        }
184
      }
185
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187 0c52af30 Leszek Koltunski
188
   public void effectMessage(final EffectMessage em, final long effectID, final long objectID)
189
     {
190 434f2f5a Leszek Koltunski
     if(      effectID == mRotationFinishedID )
191
       {
192
       mRemoveRotation = true;
193
       }
194 34747dd1 Leszek Koltunski
     else if( effectID == mDisappearEffectID )
195
       {
196
       appearCube();
197
       }
198
     else if( effectID == mAppearEffectID    )
199 434f2f5a Leszek Koltunski
       {
200 34747dd1 Leszek Koltunski
       mCanRotate = true;
201
       mCanDrag   = true;
202
       }
203
     }
204 f291130e Leszek Koltunski
205 34747dd1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
206 f291130e Leszek Koltunski
207 34747dd1 Leszek Koltunski
   private void disappearCube()
208
     {
209
     try
210
       {
211 aa8b36aa Leszek Koltunski
       DisappearEffect effect = DisappearEffect.create(mDisappearType);
212
       mDisappearEffectID = effect.start(mDisappearDuration,mScreen,mOldCube,this);
213 34747dd1 Leszek Koltunski
       }
214
     catch(Exception ex)
215
       {
216
       android.util.Log.e("Renderer", "failed to create DisappearEffect, exception: "+ex.getMessage());
217
       }
218
     }
219 f291130e Leszek Koltunski
220 34747dd1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
221
222
   private void appearCube()
223
     {
224
     try
225
       {
226 aa8b36aa Leszek Koltunski
       AppearEffect effect = AppearEffect.create(mAppearType);
227
       mAppearEffectID = effect.start(mAppearDuration,mScreen,mNewCube,this);
228 34747dd1 Leszek Koltunski
       }
229
     catch(Exception ex)
230
       {
231
       android.util.Log.e("Renderer", "failed to create AppearEffect, exception: "+ex.getMessage());
232
233
       mScreen.attach(mNewCube); //
234
       mCanRotate = true;        // just appear the cube
235
       mCanDrag   = true;        //
236 434f2f5a Leszek Koltunski
       }
237 0c52af30 Leszek Koltunski
     }
238
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240 34747dd1 Leszek Koltunski
241 aa8b36aa Leszek Koltunski
   private float computeFOV(float cameraDistance, int screenHeight)
242
     {
243
     double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) );
244
     return (float)(2*halfFOVInRadians*(180/Math.PI));
245
     }
246 34747dd1 Leszek Koltunski
247 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
248
// no this will not race with onDrawFrame
249 0c52af30 Leszek Koltunski
250 aa8b36aa Leszek Koltunski
   void finishRotation()
251
     {
252
     mFinishRotation = true;
253
     }
254 0c52af30 Leszek Koltunski
255 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
256 0c52af30 Leszek Koltunski
257 aa8b36aa Leszek Koltunski
   void setAppearDuration(int duration)
258
     {
259
     mAppearDuration = duration;
260
     }
261 0c52af30 Leszek Koltunski
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263
264 aa8b36aa Leszek Koltunski
   void setDisappearDuration(int duration)
265
     {
266
     mDisappearDuration = duration;
267
     }
268 0c52af30 Leszek Koltunski
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270
271 aa8b36aa Leszek Koltunski
   void setAppearType(AppearEffect.Type type)
272 8197c92d Leszek Koltunski
     {
273 aa8b36aa Leszek Koltunski
     mAppearType = type;
274 8197c92d Leszek Koltunski
     }
275 0c52af30 Leszek Koltunski
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277
278 aa8b36aa Leszek Koltunski
   void setDisappearType(DisappearEffect.Type type)
279 8197c92d Leszek Koltunski
     {
280 aa8b36aa Leszek Koltunski
     mDisappearType = type;
281 8197c92d Leszek Koltunski
     }
282 0c52af30 Leszek Koltunski
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284
285 f291130e Leszek Koltunski
   boolean createCube(int newSize)
286 34998c9d Leszek Koltunski
     {
287 34747dd1 Leszek Koltunski
     if( mCanDrag && mCanRotate && (mNewCube==null || newSize != mNewCube.getSize()) )
288 f291130e Leszek Koltunski
       {
289
       mNextCubeSize = newSize;
290
       return true;
291
       }
292
293
     return false;
294 34998c9d Leszek Koltunski
     }
295
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297
298 34747dd1 Leszek Koltunski
   private void createCubeNow(int newSize)
299 8197c92d Leszek Koltunski
     {
300 e56c3711 Leszek Koltunski
     if( mOldCube!=null ) mOldCube.releaseResources();
301
     mOldCube = mNewCube;
302 434f2f5a Leszek Koltunski
303 e56c3711 Leszek Koltunski
     DistortedTexture texture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
304
     DistortedEffects effects = new DistortedEffects();
305 9208e27b Leszek Koltunski
306 e56c3711 Leszek Koltunski
     mNewCube = new RubikCube(newSize, mQuatCurrent, mQuatAccumulated, texture, mMesh, effects);
307
     mNewCube.createTexture();
308 d1484aba Leszek Koltunski
309 e56c3711 Leszek Koltunski
     if( mScreenWidth!=0 )
310
       {
311
       recomputeScaleFactor(mScreenWidth,mScreenHeight);
312 8197c92d Leszek Koltunski
       }
313
     }
314 0c52af30 Leszek Koltunski
315 d1484aba Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
316
317 34998c9d Leszek Koltunski
   private void recomputeScaleFactor(int screenWidth, int screenHeight)
318 d1484aba Leszek Koltunski
     {
319
     mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(screenWidth>screenHeight ? screenHeight:screenWidth);
320 34747dd1 Leszek Koltunski
321
     if( mNewCube!=null )
322
       {
323
       mNewCube.recomputeScaleFactor(screenWidth, screenHeight, mCubeSizeInScreenSpace);
324
       }
325 d1484aba Leszek Koltunski
     }
326
327 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
328
329 8197c92d Leszek Koltunski
   void scrambleCube()
330
     {
331
332
     }
333 0c52af30 Leszek Koltunski
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335
336 8197c92d Leszek Koltunski
   float returnCubeSizeInScreenSpace()
337
     {
338
     return mCubeSizeInScreenSpace;
339
     }
340
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342
343
   boolean canRotate()
344
     {
345
     return mCanRotate;
346
     }
347
348 434f2f5a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
349
350
   boolean canDrag()
351
     {
352
     return mCanDrag;
353
     }
354
355 8197c92d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
356
357
   RubikCube getCube()
358
     {
359 434f2f5a Leszek Koltunski
     return mNewCube;
360 8197c92d Leszek Koltunski
     }
361 0c52af30 Leszek Koltunski
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363
364 8197c92d Leszek Koltunski
   void setQuatCurrent(Static4D current)
365
     {
366
     mTempCurrent.set(current);
367
     mFinishDragCurrent = true;
368
     }
369 0c52af30 Leszek Koltunski
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371
372 8197c92d Leszek Koltunski
   void setQuatAccumulated(Static4D accumulated)
373
     {
374
     mTempAccumulated.set(accumulated);
375
     mFinishDragAccumulated = true;
376
     }
377 0c52af30 Leszek Koltunski
}