blob: 72cefa3b7839b98d23c32badb3cb23e1f3d81773 [file] [log] [blame]
/*
* Copyright 2021 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package org.skia.androidkitdemo1;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import org.skia.androidkit.Canvas;
import org.skia.androidkit.Color;
import org.skia.androidkit.Matrix;
import org.skia.androidkit.Paint;
import org.skia.androidkit.Surface;
import static java.lang.Math.tan;
class Face {
private float rotX;
private float rotY;
Face(float rotX, float rotY) {
this.rotX = rotX;
this.rotY = rotY;
}
Matrix asMatrix(float scale) {
return new Matrix().rotateY(rotY).rotateX(rotX).translate(0, 0, scale);
}
}
class CubeRenderThread extends Thread {
private android.view.Surface mASurface;
private boolean mRunning;
// TODO: make these relative to surface size
private float mCubeSideLength = 500;
private int DX = 200;
private int DY = 300;
private float fAngle = (float)Math.PI / 12;
private float eyeZ = (float)(1.0f/tan(fAngle/2) - 1);
private Matrix cam = Matrix.makeLookAt(0, 0, eyeZ, 0, 0, 0, 0, 1, 0);
private Matrix perspective = Matrix.makePerspective(0.05f, 4, fAngle);
private Matrix viewport;
private Paint mPaint;
private final float rot = (float) Math.PI;
private Face[] faces = {new Face(0, 0),
new Face(0, rot),
new Face(rot/2, 0),
new Face(-rot/2, 0),
new Face(0, rot/2),
new Face(0, -rot/2),};
private static final String TAG = "*** AK CubeRenderThread";
public CubeRenderThread(android.view.Surface surface) {
mASurface = surface;
mPaint = new Paint();
mPaint.setColor(new Color(0, 1, 1, 1));
mPaint.setStroke(true);
mPaint.setStrokeWidth(10);
}
public void finish(){
mRunning = false;
}
@Override
public void run() {
mRunning = true;
long time_base = java.lang.System.currentTimeMillis();
Surface surface = Surface.CreateGL(mASurface);
viewport = new Matrix().translate(mCubeSideLength/2, mCubeSideLength/2, 0)
.scale(mCubeSideLength/2, mCubeSideLength/2, surface.getWidth());
while (mRunning) {
float t = (float)(java.lang.System.currentTimeMillis() - time_base) / 1000;
float speed = 0.5f;
float rads = t * speed % (float)(2 * Math.PI);
renderFrame(surface, rads);
surface.flushAndSubmit();
}
surface.release();
}
private void renderFrame(Surface surface, float rads) {
Canvas canvas = surface.getCanvas();
// clear canvas
canvas.drawColor(0xffffffff);
canvas.save();
canvas.concat(new Matrix().translate(DX, DY, 0));
canvas.concat(viewport.preConcat(perspective).preConcat(cam).preConcat(Matrix.makeInverse(viewport)));
for (Face f : faces) {
//TODO: auto restore
canvas.save();
Matrix trans = new Matrix().translate(mCubeSideLength/2, mCubeSideLength/2, 0);
Matrix m = new Matrix().rotateY(rads).rotateZ(rads).preConcat(f.asMatrix(mCubeSideLength/2));
canvas.concat(trans);
Matrix localToWorld = m.preConcat(Matrix.makeInverse(trans));
canvas.concat(localToWorld);
canvas.drawRect(0, 0, mCubeSideLength, mCubeSideLength, mPaint);
canvas.restore();
}
canvas.restore();
}
}
public class CubeActivity extends Activity implements SurfaceHolder.Callback {
private CubeRenderThread mRenderThread;
static {
System.loadLibrary("androidkit");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cube);
SurfaceView sv = findViewById(R.id.surfaceView);
sv.getHolder().addCallback(this);
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
if (mRenderThread != null) {
mRenderThread.finish();
try {
mRenderThread.join();
} catch (InterruptedException e) {}
}
mRenderThread = new CubeRenderThread(holder.getSurface());;
mRenderThread.start();
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
if (mRenderThread != null) {
mRenderThread.finish();
try {
mRenderThread.join();
} catch (InterruptedException e) {}
}
}
}