From c150be9eb7e0d69def245d877bd66f6df87f58a1 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 21 Aug 2012 23:08:30 -0400 Subject: Get Dimension working on Android. --- .../dimension/android/RaytracedView.java | 178 +++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/com/tavianator/dimension/android/RaytracedView.java (limited to 'src/com/tavianator/dimension/android/RaytracedView.java') diff --git a/src/com/tavianator/dimension/android/RaytracedView.java b/src/com/tavianator/dimension/android/RaytracedView.java new file mode 100644 index 0000000..4a88793 --- /dev/null +++ b/src/com/tavianator/dimension/android/RaytracedView.java @@ -0,0 +1,178 @@ +/************************************************************************* + * Copyright (C) 2010-2011 Tavian Barnes * + * * + * This file is part of The Dimension Android Binding. * + * * + * The Dimension Android Binding is free software; you can redistribute * + * it and/or modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Android Binding is distributed in the hope that it will * + * be useful, but WITHOUT ANY WARRANTY; without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * + * the GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +package com.tavianator.dimension.android; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.PixelFormat; +import android.graphics.PorterDuff; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +/** + * @author Tavian Barnes + * @version 1.0 + * @since 1.0 + */ +@SuppressLint("HandlerLeak") +public class RaytracedView extends SurfaceView implements + SurfaceHolder.Callback { + private static final String TAG = RaytracedView.class.getSimpleName(); + + private static final int NFRAMES = 64; + + static { + System.loadLibrary("dimension"); + Log.d(TAG, "libdimension loaded sucessfully!"); + } + + private static final int MSG_RENDER = 0; + private static final int MSG_QUIT = 1; + + private static class RenderPayload { + public int width; + public int height; + + public RenderPayload(int width, int height) { + this.width = width; + this.height = height; + } + } + + private class RenderHandler extends Handler { + public RenderHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_RENDER: + handleRender((RenderPayload) msg.obj); + break; + case MSG_QUIT: + handleQuit(); + break; + } + } + + private void handleRender(RenderPayload payload) { + render(payload.width, payload.height); + } + + private void handleQuit() { + getLooper().quit(); + } + } + + private RenderHandler m_Handler; + private int mWidth, mHeight; + private int[] mBitmap; + + public RaytracedView(Context context) { + super(context); + init(); + } + + public RaytracedView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public RaytracedView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + private void init() { + SurfaceHolder holder = getHolder(); + holder.addCallback(this); + holder.setFormat(PixelFormat.TRANSLUCENT); + } + + public void surfaceCreated(SurfaceHolder holder) { + HandlerThread thread = new HandlerThread("RenderThread"); + thread.start(); + + m_Handler = new RenderHandler(thread.getLooper()); + } + + public void surfaceChanged(SurfaceHolder holder, int format, int width, + int height) { + m_Handler.obtainMessage(MSG_RENDER, new RenderPayload(width, height)) + .sendToTarget(); + } + + public void surfaceDestroyed(SurfaceHolder holder) { + m_Handler.sendEmptyMessage(MSG_QUIT); + } + + private void render(int width, int height) { + mBitmap = new int[width * height]; + mWidth = width; + mHeight = height; + + renderNative(width, height); + + for (int i = 0; i < NFRAMES; ++i) { + waitNative(((double) i) / NFRAMES); + draw(); + } + + joinNative(); + draw(); + } + + private void draw() { + SurfaceHolder holder = getHolder(); + Canvas canvas = holder.lockCanvas(); + if (canvas == null) { + return; + } + + canvas.drawColor(0, PorterDuff.Mode.CLEAR); + canvas.drawBitmap(mBitmap, 0, mWidth, 0.0F, 0.0F, mWidth, mHeight, + true, null); + + holder.unlockCanvasAndPost(canvas); + } + + /** Start the render. */ + private native void renderNative(int width, int height); + + /** Wait for the render to reach a certain amount of progress. */ + private native void waitNative(double progress); + + /** Wait for the render to complete. */ + private native void joinNative(); + + /** Called by JNI code to set the pixel colors. */ + private void setPixel(int x, int y, int color) { + y = mHeight - y - 1; + mBitmap[y * mWidth + x] = color; + } +} -- cgit v1.2.3