Project

General

Profile

Download (13.3 KB) Statistics
| Branch: | Revision:

examples / src / main / java / org / distorted / examples / rubik / RubikRenderer.java @ 3d267840

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// 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
// Distorted is distributed in the hope that it will be useful,                                  //
12
// 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
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.examples.rubik;
21

    
22
import android.graphics.Bitmap;
23
import android.graphics.Canvas;
24
import android.graphics.Paint;
25
import android.opengl.GLSurfaceView;
26

    
27
import org.distorted.library.effect.EffectName;
28
import org.distorted.library.effect.MatrixEffectMove;
29
import org.distorted.library.effect.MatrixEffectQuaternion;
30
import org.distorted.library.effect.MatrixEffectScale;
31
import org.distorted.library.effect.PostprocessEffectGlow;
32
import org.distorted.library.effect.VertexEffectSink;
33
import org.distorted.library.main.Distorted;
34
import org.distorted.library.main.DistortedEffects;
35
import org.distorted.library.main.DistortedScreen;
36
import org.distorted.library.main.DistortedTexture;
37
import org.distorted.library.mesh.MeshCubes;
38
import org.distorted.library.type.Static1D;
39
import org.distorted.library.type.Static3D;
40
import org.distorted.library.type.Static4D;
41

    
42
import javax.microedition.khronos.egl.EGLConfig;
43
import javax.microedition.khronos.opengles.GL10;
44

    
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46

    
47
class RubikRenderer implements GLSurfaceView.Renderer
48
{
49
            static final int NUM_CUBES =   3;
50
    private static final int SIZE      = 200;
51

    
52
    private static final float CUBE_SCREEN_RATIO = 0.5f;
53

    
54
    private GLSurfaceView mView;
55
    private DistortedTexture mTexture;
56
    private DistortedScreen mScreen;
57
    private Static3D mMove, mScale, mCenter;
58
    private MeshCubes[][][] mCubes;
59
    private DistortedEffects[][][] mEffects;
60

    
61
    private int mScreenWidth, mScreenHeight;
62
    private int mLastRow, mLastCol, mLastSli;
63

    
64
    private Static1D mGlowRadius;
65
    private Static4D mGlowColor;
66

    
67
    private Static4D mQuatCurrent, mQuatAccumulated;
68
    private Static4D mTempCurrent, mTempAccumulated;
69
    int mScreenMin;
70

    
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72

    
73
    RubikRenderer(GLSurfaceView v)
74
      {
75
      mView = v;
76

    
77
      mScreen = new DistortedScreen();
78
      mScreen.setProjection(90.0f, 0.1f);
79

    
80
      mTempCurrent     = new Static4D(0,0,0,1);
81
      mTempAccumulated = initializeQuat();
82
      mQuatCurrent     = new Static4D(0,0,0,1);
83
      mQuatAccumulated = initializeQuat();
84

    
85
      mCubes = new MeshCubes[NUM_CUBES][NUM_CUBES][NUM_CUBES];
86
      mEffects = new DistortedEffects[NUM_CUBES][NUM_CUBES][NUM_CUBES];
87
      Static3D[][][] cubeVectors = new Static3D[NUM_CUBES][NUM_CUBES][NUM_CUBES];
88

    
89
      float sinkDegree = 3.0f - 1.7f/NUM_CUBES; // f(1)=1.3, f(inf)=3
90

    
91
      VertexEffectSink sink = new VertexEffectSink( new Static1D(sinkDegree),
92
                                                    new Static3D(SIZE*0.5f, SIZE*0.5f, SIZE*0.5f),
93
                                                    new Static4D(0,0,0, SIZE*0.72f) );
94
      mMove  = new Static3D(0,0,0);
95
      mScale = new Static3D(1,1,1);
96
      mCenter= new Static3D(0,0,0);
97

    
98
      mLastRow = mLastCol = mLastSli = 0;
99

    
100
      mGlowRadius = new Static1D(5);
101
      mGlowColor  = new Static4D(1.0f,1.0f,1.0f,0.6f);
102

    
103
      MatrixEffectMove       move  = new MatrixEffectMove(mMove);
104
      MatrixEffectScale      scale = new MatrixEffectScale(mScale);
105
      MatrixEffectQuaternion quat1 = new MatrixEffectQuaternion(mQuatCurrent    , mCenter);
106
      MatrixEffectQuaternion quat2 = new MatrixEffectQuaternion(mQuatAccumulated, mCenter);
107

    
108
      // 3x2 bitmap = 6 squares:
109
      //
110
      // RED     GREEN   BLUE
111
      // YELLOW  WHITE   BROWN
112

    
113
      final float ze = 0.0f;
114
      final float ot = 1.0f/3.0f;
115
      final float tt = 2.0f/3.0f;
116
      final float oh = 1.0f/2.0f;
117
      final float of = 1.0f/40.0f;
118

    
119
      final Static4D mapFront = new Static4D(ze,oh, ze+ot,oh+oh);
120
      final Static4D mapBack  = new Static4D(tt,ze, tt+ot,ze+oh);
121
      final Static4D mapLeft  = new Static4D(ot,ze, ot+ot,ze+oh);
122
      final Static4D mapRight = new Static4D(ze,ze, ze+ot,ze+oh);
123
      final Static4D mapTop   = new Static4D(tt,oh, tt+ot,oh+oh);
124
      final Static4D mapBottom= new Static4D(ot,oh, ot+ot,oh+oh);
125

    
126
      final Static4D mapBlack = new Static4D(ze,ze, ze+of,ze+of);
127

    
128
      Static4D tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom;
129
      float nc = 0.5f*(NUM_CUBES-1);
130
      int vertices = (int)(24.0f/NUM_CUBES + 2.0f);
131

    
132
      for(int x = 0; x< NUM_CUBES; x++)
133
        for(int y = 0; y< NUM_CUBES; y++)
134
          for(int z = 0; z< NUM_CUBES; z++)
135
            {
136
            if( x==0 || x==NUM_CUBES-1 || y==0 || y==NUM_CUBES-1 || z==0 || z==NUM_CUBES-1 ) // only the external walls
137
              {
138
              tmpLeft  = (x==            0 ? mapLeft  :mapBlack);
139
              tmpRight = (x== NUM_CUBES -1 ? mapRight :mapBlack);
140
              tmpFront = (z== NUM_CUBES -1 ? mapFront :mapBlack);
141
              tmpBack  = (z==            0 ? mapBack  :mapBlack);
142
              tmpTop   = (y== NUM_CUBES -1 ? mapTop   :mapBlack);
143
              tmpBottom= (y==            0 ? mapBottom:mapBlack);
144

    
145
              mCubes[x][y][z] = new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom);
146

    
147
              cubeVectors[x][y][z] = new Static3D( SIZE*(x-nc), SIZE*(y-nc), SIZE*(z-nc) );
148

    
149
              mEffects[x][y][z] = new DistortedEffects();
150
              mEffects[x][y][z].apply(sink);
151
              mEffects[x][y][z].apply(move);
152
              mEffects[x][y][z].apply(scale);
153
              mEffects[x][y][z].apply(quat1);
154
              mEffects[x][y][z].apply(quat2);
155
              mEffects[x][y][z].apply( new MatrixEffectMove(cubeVectors[x][y][z]) );
156
              }
157
            }
158
      }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161
   
162
    public void onDrawFrame(GL10 glUnused) 
163
      {
164
      mScreen.render( System.currentTimeMillis() );
165

    
166
      mQuatCurrent.set(mTempCurrent);
167
      mQuatAccumulated.set(mTempAccumulated);
168
      }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171
    
172
    public void onSurfaceChanged(GL10 glUnused, int width, int height) 
173
      {
174
      mScreenWidth = width;
175
      mScreenHeight= height;
176
      mScreenMin = width<height ? width:height;
177

    
178
      float w = mTexture.getWidth();
179
      float h = mTexture.getHeight();
180
      float d = mTexture.getDepth(mCubes[0][0][0]);
181

    
182
      float factor = CUBE_SCREEN_RATIO*(width>height ? height/h:width/w)/ NUM_CUBES;
183

    
184
      mCenter.set(w/2,h/2,d/2);
185
      mMove.set( (width-factor*w)/2 , (height-factor*h)/2 , -factor*d/2 );
186
      mScale.set(factor,factor,factor);
187

    
188
      mScreen.resize(width, height);
189
      }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
    
193
    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
194
      {
195
      Bitmap bitmap;
196

    
197
      final int S = 128;
198
      final int W = 3*S;
199
      final int H = 2*S;
200
      final int R = S/10;
201
      final int M = S/20;
202

    
203
      Paint paint = new Paint();
204
      bitmap = Bitmap.createBitmap(W,H, Bitmap.Config.ARGB_8888);
205
      Canvas canvas = new Canvas(bitmap);
206

    
207
      paint.setAntiAlias(true);
208
      paint.setTextAlign(Paint.Align.CENTER);
209
      paint.setStyle(Paint.Style.FILL);
210

    
211
      // 3x2 bitmap = 6 squares:
212
      //
213
      // RED     GREEN   BLUE
214
      // YELLOW  WHITE   BROWN
215

    
216
      paint.setColor(0xff000000);                                  // BLACK BACKGROUND
217
      canvas.drawRect(0, 0, W, H, paint);                          //
218

    
219
      paint.setColor(0xffff0000);                                  // RED
220
      canvas.drawRoundRect(    M,   M,   S-M,   S-M, R, R, paint); //
221
      paint.setColor(0xff00ff00);                                  // GREEN
222
      canvas.drawRoundRect(  S+M,   M, 2*S-M,   S-M, R, R, paint); //
223
      paint.setColor(0xff0000ff);                                  // BLUE
224
      canvas.drawRoundRect(2*S+M,   M, 3*S-M,   S-M, R, R, paint); //
225
      paint.setColor(0xffffff00);                                  // YELLOW
226
      canvas.drawRoundRect(    M, S+M,   S-M, 2*S-M, R, R, paint); //
227
      paint.setColor(0xffffffff);                                  // WHITE
228
      canvas.drawRoundRect(  S+M, S+M, 2*S-M, 2*S-M, R, R, paint); //
229
      paint.setColor(0xffb5651d);                                  // BROWN
230
      canvas.drawRoundRect(2*S+M, S+M, 3*S-M, 2*S-M, R, R, paint); //
231

    
232
      if( mTexture==null ) mTexture = new DistortedTexture(SIZE,SIZE);
233
      mTexture.setTexture(bitmap);
234

    
235
      mScreen.detachAll();
236

    
237
      for(int x = 0; x< NUM_CUBES; x++)
238
        for(int y = 0; y< NUM_CUBES; y++)
239
          for(int z = 0; z< NUM_CUBES; z++)
240
            if( x==0 || x==NUM_CUBES-1 || y==0 || y==NUM_CUBES-1 || z==0 || z==NUM_CUBES-1 ) // only the external walls
241
              {
242
              mScreen.attach(mTexture,mEffects[x][y][z],mCubes[x][y][z]);
243
              }
244

    
245
      PostprocessEffectGlow.enable();
246
      VertexEffectSink.enable();
247

    
248
      try
249
        {
250
        Distorted.onCreate(mView.getContext());
251
        }
252
      catch(Exception ex)
253
        {
254
        android.util.Log.e("Rubik", ex.getMessage() );
255
        }
256
      }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

    
260
    float returnCameraDistance()
261
      {
262
      float fov = mScreen.getFOV();
263
      double fovInRadians = (fov*Math.PI) / 180.0;
264
      double distance = (mScreenHeight*0.5f)/Math.tan(fovInRadians*0.5);
265

    
266
      return (float)distance;
267
      }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270
// NUM_CUBES individual little cubes, each SIZE in size, times 'scaleFactor' (see onSurfaceChanged)
271

    
272
    float returnCubeSize()
273
      {
274
      float w = mTexture.getWidth();
275
      float h = mTexture.getHeight();
276
      float max = (mScreenWidth>mScreenHeight ? mScreenHeight/h:mScreenWidth/w);
277
      float scaleFactor = CUBE_SCREEN_RATIO*max/NUM_CUBES;
278

    
279
      return scaleFactor*NUM_CUBES*SIZE;
280
      }
281

    
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283

    
284
    void rotateFace(Static3D vector, int angle, int row )
285
      {
286
      String vect = "("+vector.get1()+","+vector.get2()+","+vector.get3()+")";
287

    
288
      android.util.Log.e("rubik", "rotating by "+angle+" degrees, row="+row+" vector: "+vect);
289
      }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292

    
293
    float getScreenWidth()
294
      {
295
      return mScreenWidth;
296
      }
297

    
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

    
300
    float getScreenHeight()
301
      {
302
      return mScreenHeight;
303
      }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

    
307
    void abortLastEffect()
308
      {
309
      mEffects[mLastCol][mLastRow][mLastSli].abortByName(EffectName.GLOW);
310
      }
311

    
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313

    
314
    void applyNewEffect(int col, int row, int sli)
315
      {
316
      mLastCol = col;
317
      mLastRow = row;
318
      mLastSli = sli;
319

    
320
      mEffects[mLastCol][mLastRow][mLastSli].apply(new PostprocessEffectGlow(mGlowRadius,mGlowColor));
321
      }
322

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324
// Initial rotation of the cube. Something semi-random that looks good.
325

    
326
    Static4D initializeQuat()
327
      {
328
      return new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
329
      }
330

    
331
///////////////////////////////////////////////////////////////////////////////////////////////////
332

    
333
    void setQuatCurrent(Static4D current)
334
      {
335
      mTempCurrent.set(current);
336
      }
337

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

    
340
    void setQuatAccumulated(Static4D accumulated)
341
      {
342
      mTempAccumulated.set(accumulated);
343
      }
344
}
(2-2/3)