Revision 8becce57
Added by Leszek Koltunski about 4 years ago
src/main/java/org/distorted/magic/RubikRenderer.java | ||
---|---|---|
19 | 19 |
|
20 | 20 |
package org.distorted.magic; |
21 | 21 |
|
22 |
import android.content.SharedPreferences; |
|
23 | 22 |
import android.opengl.GLSurfaceView; |
24 |
import android.os.Bundle; |
|
25 |
|
|
26 |
import org.distorted.dialog.RubikDialogNewRecord; |
|
27 |
import org.distorted.dialog.RubikDialogSolved; |
|
28 | 23 |
import org.distorted.effect.BaseEffect; |
29 | 24 |
import org.distorted.library.effect.VertexEffectSink; |
30 | 25 |
import org.distorted.library.main.DistortedLibrary; |
31 | 26 |
import org.distorted.library.main.DistortedScreen; |
32 |
import org.distorted.library.message.EffectListener; |
|
33 |
import org.distorted.object.RubikObject; |
|
34 |
import org.distorted.object.RubikObjectList; |
|
35 |
import org.distorted.scores.RubikScores; |
|
36 |
import org.distorted.uistate.RubikState; |
|
37 |
import org.distorted.uistate.RubikStateSolving; |
|
38 | 27 |
|
39 | 28 |
import javax.microedition.khronos.egl.EGLConfig; |
40 | 29 |
import javax.microedition.khronos.opengles.GL10; |
41 | 30 |
|
42 | 31 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
43 | 32 |
|
44 |
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
|
|
33 |
public class RubikRenderer implements GLSurfaceView.Renderer |
|
45 | 34 |
{ |
46 |
public static final int NODE_FBO_SIZE = 600; |
|
47 |
|
|
48 |
private RubikSurfaceView mView; |
|
49 |
private DistortedScreen mScreen; |
|
50 |
private RubikObjectList mNextObject; |
|
51 |
private int mNextSize; |
|
52 |
private int mScrambleObjectNum; |
|
53 |
private long mRotationFinishedID; |
|
54 |
private long[] mEffectID; |
|
55 |
private boolean mFinishRotation, mRemoveRotation, mSetQuatCurrent, mSetQuatAccumulated; |
|
56 |
private boolean mChangeObject, mSolveObject, mScrambleObject; |
|
57 |
private boolean mCanRotate, mCanDrag, mCanUI; |
|
58 |
private boolean mIsSolved; |
|
59 |
private boolean mIsNewRecord; |
|
60 |
private long mNewRecord; |
|
61 |
private RubikObject mOldObject, mNewObject; |
|
62 |
private int mScreenWidth, mScreenHeight; |
|
63 |
private SharedPreferences mPreferences; |
|
64 |
private String mNextMoves; |
|
65 |
|
|
66 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
67 |
|
|
68 |
RubikRenderer(RubikSurfaceView v) |
|
69 |
{ |
|
70 |
mView = v; |
|
71 |
mScreen = new DistortedScreen(); |
|
72 |
|
|
73 |
mOldObject = null; |
|
74 |
mNewObject = null; |
|
75 |
|
|
76 |
mScreenWidth = mScreenHeight = 0; |
|
77 |
mScrambleObjectNum = 0; |
|
78 |
|
|
79 |
mFinishRotation = false; |
|
80 |
mRemoveRotation = false; |
|
81 |
mSetQuatCurrent = false; |
|
82 |
mSetQuatAccumulated = false; |
|
83 |
mChangeObject = false; |
|
84 |
mSolveObject = false; |
|
85 |
mScrambleObject = false; |
|
86 |
|
|
87 |
mCanRotate = true; |
|
88 |
mCanDrag = true; |
|
89 |
mCanUI = true; |
|
90 |
|
|
91 |
mEffectID = new long[BaseEffect.Type.LENGTH]; |
|
92 |
} |
|
93 |
|
|
94 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
95 |
|
|
96 |
private void createObjectNow(RubikObjectList object, int size, String moves) |
|
97 |
{ |
|
98 |
boolean firstTime = (mNewObject==null); |
|
99 |
|
|
100 |
if( mOldObject!=null ) mOldObject.releaseResources(); |
|
101 |
mOldObject = mNewObject; |
|
102 |
|
|
103 |
mNewObject = object.create(size, mView.getQuatCurrent(), mView.getQuatAccumulated(), moves); |
|
104 |
mNewObject.createTexture(); |
|
105 |
mView.setMovement(object.getObjectMovementClass()); |
|
106 |
|
|
107 |
if( firstTime ) mNewObject.restorePreferences(mPreferences); |
|
108 |
|
|
109 |
if( mScreenWidth!=0 ) |
|
110 |
{ |
|
111 |
mNewObject.recomputeScaleFactor(mScreenWidth, mScreenHeight); |
|
112 |
} |
|
113 |
|
|
114 |
mIsSolved = true; |
|
115 |
} |
|
116 |
|
|
117 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
118 |
// do all 'adjustable' effects (SizeChange, Solve, Scramble) |
|
119 |
|
|
120 |
private void doEffectNow(BaseEffect.Type type) |
|
121 |
{ |
|
122 |
int index = type.ordinal(); |
|
123 |
|
|
124 |
try |
|
125 |
{ |
|
126 |
mEffectID[index] = type.startEffect(this); |
|
127 |
} |
|
128 |
catch( Exception ex ) |
|
129 |
{ |
|
130 |
android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage()); |
|
131 |
|
|
132 |
mCanUI = true; |
|
133 |
mCanRotate = true; |
|
134 |
mCanDrag = true; |
|
135 |
} |
|
136 |
} |
|
137 |
|
|
138 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
139 |
|
|
140 |
void savePreferences(SharedPreferences.Editor editor) |
|
141 |
{ |
|
142 |
if( mNewObject!=null ) |
|
143 |
{ |
|
144 |
mNewObject.savePreferences(editor); |
|
145 |
} |
|
146 |
} |
|
147 |
|
|
148 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
149 |
|
|
150 |
void restorePreferences(SharedPreferences preferences) |
|
151 |
{ |
|
152 |
mPreferences = preferences; |
|
153 |
} |
|
154 |
|
|
155 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
156 |
// no this will not race with onDrawFrame |
|
157 |
|
|
158 |
void finishRotation() |
|
159 |
{ |
|
160 |
mFinishRotation = true; |
|
161 |
} |
|
162 |
|
|
163 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
164 |
|
|
165 |
void changeObject(RubikObjectList object, int size, String moves) |
|
166 |
{ |
|
167 |
if( size>0 ) |
|
168 |
{ |
|
169 |
mChangeObject = true; |
|
170 |
mNextObject = object; |
|
171 |
mNextSize = size; |
|
172 |
mNextMoves = moves; |
|
173 |
} |
|
174 |
} |
|
35 |
public static final int NODE_FBO_SIZE = 600; |
|
175 | 36 |
|
176 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
177 |
|
|
178 |
void scrambleObject(int num) |
|
179 |
{ |
|
180 |
if( mCanUI ) |
|
181 |
{ |
|
182 |
mScrambleObject = true; |
|
183 |
mScrambleObjectNum = num; |
|
184 |
} |
|
185 |
} |
|
37 |
private RubikSurfaceView mView; |
|
38 |
private DistortedScreen mScreen; |
|
186 | 39 |
|
187 | 40 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
188 | 41 |
|
189 |
void solveObject()
|
|
42 |
RubikRenderer(RubikSurfaceView v)
|
|
190 | 43 |
{ |
191 |
if( mCanUI ) |
|
192 |
{ |
|
193 |
mSolveObject = true; |
|
194 |
} |
|
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; |
|
44 |
mView = v; |
|
45 |
mScreen = new DistortedScreen(); |
|
223 | 46 |
} |
224 | 47 |
|
225 | 48 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
230 | 53 |
public void onDrawFrame(GL10 glUnused) |
231 | 54 |
{ |
232 | 55 |
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 |
mRotationFinishedID = mNewObject.finishRotationNow(this); |
|
252 |
|
|
253 |
if( mRotationFinishedID==0 ) // failed to add effect - should never happen |
|
254 |
{ |
|
255 |
mCanRotate = true; |
|
256 |
mCanUI = true; |
|
257 |
} |
|
258 |
} |
|
259 |
|
|
260 |
if( mRemoveRotation ) |
|
261 |
{ |
|
262 |
mRemoveRotation=false; |
|
263 |
mNewObject.removeRotationNow(); |
|
264 |
|
|
265 |
boolean solved = mNewObject.isSolved(); |
|
266 |
|
|
267 |
if( solved && !mIsSolved ) |
|
268 |
{ |
|
269 |
if( RubikState.getCurrentState()==RubikState.SOLV ) |
|
270 |
{ |
|
271 |
RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass(); |
|
272 |
mNewRecord = solving.stopCounting((RubikActivity)mView.getContext()); |
|
273 |
|
|
274 |
if( mNewRecord< 0 ) |
|
275 |
{ |
|
276 |
mNewRecord = -mNewRecord; |
|
277 |
mIsNewRecord = false; |
|
278 |
} |
|
279 |
else |
|
280 |
{ |
|
281 |
mIsNewRecord = true; |
|
282 |
} |
|
283 |
} |
|
284 |
|
|
285 |
mCanDrag = true; |
|
286 |
mCanRotate = false; |
|
287 |
mCanUI = false; |
|
288 |
doEffectNow( BaseEffect.Type.WIN ); |
|
289 |
} |
|
290 |
else |
|
291 |
{ |
|
292 |
mCanRotate = true; |
|
293 |
mCanUI = true; |
|
294 |
} |
|
295 |
|
|
296 |
mIsSolved = solved; |
|
297 |
} |
|
298 |
|
|
299 |
if( mChangeObject ) |
|
300 |
{ |
|
301 |
mChangeObject = false; |
|
302 |
mCanDrag = false; |
|
303 |
mCanRotate = false; |
|
304 |
mCanUI = false; |
|
305 |
|
|
306 |
if( mNewObject==null ) |
|
307 |
{ |
|
308 |
createObjectNow(mNextObject, mNextSize, mNextMoves); |
|
309 |
doEffectNow( BaseEffect.Type.SIZECHANGE ); |
|
310 |
} |
|
311 |
else |
|
312 |
{ |
|
313 |
RubikObjectList list = mNewObject.getObjectList(); |
|
314 |
int size = mNewObject.getSize(); |
|
315 |
|
|
316 |
if (list!=mNextObject || mNextSize!=size) |
|
317 |
{ |
|
318 |
createObjectNow(mNextObject, mNextSize, mNextMoves); |
|
319 |
doEffectNow( BaseEffect.Type.SIZECHANGE ); |
|
320 |
} |
|
321 |
else |
|
322 |
{ |
|
323 |
mNewObject.initializeObject(mNextMoves); |
|
324 |
} |
|
325 |
} |
|
326 |
} |
|
327 |
|
|
328 |
if( mSolveObject ) |
|
329 |
{ |
|
330 |
mSolveObject = false; |
|
331 |
mCanDrag = false; |
|
332 |
mCanRotate = false; |
|
333 |
mCanUI = false; |
|
334 |
doEffectNow( BaseEffect.Type.SOLVE ); |
|
335 |
} |
|
336 |
|
|
337 |
if( mScrambleObject ) |
|
338 |
{ |
|
339 |
mScrambleObject = false; |
|
340 |
mCanDrag = false; |
|
341 |
mCanRotate = false; |
|
342 |
mCanUI = false; |
|
343 |
mIsSolved = false; |
|
344 |
RubikScores.getInstance().incrementNumPlays(); |
|
345 |
doEffectNow( BaseEffect.Type.SCRAMBLE ); |
|
346 |
} |
|
56 |
mView.getPostRender().postRender(); |
|
347 | 57 |
} |
348 | 58 |
|
349 | 59 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
351 | 61 |
@Override |
352 | 62 |
public void onSurfaceChanged(GL10 glUnused, int width, int height) |
353 | 63 |
{ |
354 |
if( mNewObject!=null ) mNewObject.createTexture(); |
|
355 |
|
|
356 |
mScreen.resize(width, height); |
|
64 |
mScreen.resize(width,height); |
|
357 | 65 |
mView.setScreenSize(width,height); |
358 |
|
|
359 |
if( mNewObject!=null ) |
|
360 |
{ |
|
361 |
mNewObject.recomputeScaleFactor(width,height); |
|
362 |
} |
|
363 |
|
|
364 |
mScreenHeight = height; |
|
365 |
mScreenWidth = width; |
|
66 |
mView.getPostRender().setScreenSize(width,height); |
|
366 | 67 |
} |
367 | 68 |
|
368 | 69 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
383 | 84 |
} |
384 | 85 |
} |
385 | 86 |
|
386 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
387 |
// PUBLIC API |
|
388 | 87 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
389 | 88 |
|
390 |
public void effectFinished(final long effectID) |
|
391 |
{ |
|
392 |
if( effectID == mRotationFinishedID ) |
|
393 |
{ |
|
394 |
mRemoveRotation = true; |
|
395 |
} |
|
396 |
else |
|
397 |
{ |
|
398 |
for(int i=0; i<BaseEffect.Type.LENGTH; i++) |
|
399 |
{ |
|
400 |
if( effectID == mEffectID[i] ) |
|
401 |
{ |
|
402 |
mCanRotate = true; |
|
403 |
mCanDrag = true; |
|
404 |
mCanUI = true; |
|
405 |
|
|
406 |
if( i==BaseEffect.Type.SCRAMBLE.ordinal() ) |
|
407 |
{ |
|
408 |
final RubikActivity act = (RubikActivity)mView.getContext(); |
|
409 |
|
|
410 |
act.runOnUiThread(new Runnable() |
|
411 |
{ |
|
412 |
@Override |
|
413 |
public void run() |
|
414 |
{ |
|
415 |
RubikState.switchState( act, RubikState.SOLV); |
|
416 |
} |
|
417 |
}); |
|
418 |
} |
|
419 |
|
|
420 |
if( i==BaseEffect.Type.WIN.ordinal() ) |
|
421 |
{ |
|
422 |
if( RubikState.getCurrentState()==RubikState.SOLV ) |
|
423 |
{ |
|
424 |
final RubikActivity act = (RubikActivity)mView.getContext(); |
|
425 |
Bundle bundle = new Bundle(); |
|
426 |
bundle.putLong("time", mNewRecord ); |
|
427 |
|
|
428 |
if( mIsNewRecord ) |
|
429 |
{ |
|
430 |
RubikDialogNewRecord dialog = new RubikDialogNewRecord(); |
|
431 |
dialog.setArguments(bundle); |
|
432 |
dialog.show( act.getSupportFragmentManager(), null); |
|
433 |
} |
|
434 |
else |
|
435 |
{ |
|
436 |
RubikDialogSolved dialog = new RubikDialogSolved(); |
|
437 |
dialog.setArguments(bundle); |
|
438 |
dialog.show( act.getSupportFragmentManager(), null); |
|
439 |
} |
|
440 |
} |
|
441 |
} |
|
442 |
|
|
443 |
break; |
|
444 |
} |
|
445 |
} |
|
446 |
} |
|
447 |
} |
|
448 |
|
|
449 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
450 |
|
|
451 |
public RubikObject getObject() |
|
452 |
{ |
|
453 |
return mNewObject; |
|
454 |
} |
|
455 |
|
|
456 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
457 |
|
|
458 |
public RubikObject getOldObject() |
|
459 |
{ |
|
460 |
return mOldObject; |
|
461 |
} |
|
462 |
|
|
463 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
464 |
|
|
465 |
public DistortedScreen getScreen() |
|
89 |
DistortedScreen getScreen() |
|
466 | 90 |
{ |
467 | 91 |
return mScreen; |
468 | 92 |
} |
469 |
|
|
470 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
471 |
|
|
472 |
public int getNumScrambles() |
|
473 |
{ |
|
474 |
return mScrambleObjectNum; |
|
475 |
} |
|
476 | 93 |
} |
Also available in: Unified diff
Major progress with Prretty Patterns - hopefully only initializing the Object remains!