Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

package com.gebauz.HotPlate;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.MotionEvent;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.io.IOException;
import java.io.InputStream;


public class HotPlate extends Activity
{
    @Override
   
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        mGLView = new HotPlateView(this);
        setContentView(mGLView);
    }

    @Override
    protected void onPause()
    {
        super.onPause();
        mGLView.onPause();
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        mGLView.onResume();
    }

    private GLSurfaceView mGLView;
}

class HotPlateView extends GLSurfaceView
{
        HotPlateRenderer renderer;
        long lastUpdate = System.currentTimeMillis();
       
        public static int MAX_POINTERS = 5;
        private long updateDelta = 1000/30;
        private RefreshHandler redrawHandler = new RefreshHandler();

    class RefreshHandler extends Handler
    {
        @Override
        public void handleMessage(Message msg)
        {
                HotPlateView.this.update();
                HotPlateView.this.invalidate();
        }

        public void sleep(long delayMillis)
        {
                this.removeMessages(0);
            sendMessageDelayed(obtainMessage(0), delayMillis);
        }
    };
       
        public HotPlateView(Context context)
        {
        super(context);
        renderer = new HotPlateRenderer(context);
        setRenderer(renderer);
        setFocusableInTouchMode(true); // make sure we get touch events        
        lastUpdate = System.currentTimeMillis();
        update();
        }
       
        public float GetDeltaTime()
        {
                long now = System.currentTimeMillis();
                long delta = now - lastUpdate;
                lastUpdate = now;
                return ((float)delta / 1000.0f);
        }
       
        public void update()
        {
        float deltaTime = GetDeltaTime();
       
        // update game logic
        renderer.updatePlate(deltaTime);
       
        redrawHandler.sleep(updateDelta);
        }
       
    public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
/*        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            queueEvent(new Runnable() {
                // This method will be called on the rendering
                // thread:
                public void run() {
                    mMyRenderer.handleDpadCenter();
                }});
            return true;
        }*/

        return super.onKeyDown(keyCode, event);
    }
   
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        //dumpEvent(event);
       
        int pointerCount = event.getPointerCount();
        if (pointerCount > MAX_POINTERS)
                pointerCount = MAX_POINTERS;
        if (event.getAction() == MotionEvent.ACTION_UP)
        {
                renderer.DisableAllTouchPoints();
                return true;
        }
        for (int i = 0; i < MAX_POINTERS; i++)
        {
                //int id = event.getPointerId(i);
                //android.util.Log.v("TEST", "Pointer " + i + " [" + id + "]" + ": " + event.getX(i) + ", " + event.getY(i));
               
                if (i < pointerCount)
                {
                        if (!renderer.touchPoints[i].isActive)
                                renderer.touchPoints[i].Play();
                       
                        renderer.touchPoints[i].isActive = true;
                        renderer.touchPoints[i].X = event.getX(i);
                        renderer.touchPoints[i].Y = event.getY(i);
                }
                else
                {
                        renderer.touchPoints[i].isActive = false;                                      
                }
        }
       
                return true;
        //return super.onTouchEvent(event);
    }
   
    private void dumpEvent(MotionEvent event) {
           String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" ,
              "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" };
           StringBuilder sb = new StringBuilder();
           int action = event.getAction();
           int actionCode = action & MotionEvent.ACTION_MASK;
           sb.append("event ACTION_" ).append(names[actionCode]);
           if (actionCode == MotionEvent.ACTION_POINTER_DOWN
                 || actionCode == MotionEvent.ACTION_POINTER_UP) {
              sb.append("(pid " ).append(
              action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
              sb.append(")" );
           }
           sb.append("[" );
           for (int i = 0; i < event.getPointerCount(); i++) {
              sb.append("#" ).append(i);
              sb.append("(pid " ).append(event.getPointerId(i));
              sb.append(")=" ).append((int) event.getX(i));
              sb.append("," ).append((int) event.getY(i));
              if (i + 1 < event.getPointerCount())
                 sb.append(";" );
           }
           sb.append("]" );
           android.util.Log.d("TEST", sb.toString());
        }

};

class HotPlateRenderer implements GLSurfaceView.Renderer
{
        private Context context;
       
        float timePassed = 0;
        float heatRate = 0.08f;
       
        private FloatBuffer vertexBuffer;
        private FloatBuffer vertexBuffer2;
        private FloatBuffer colorBuffer;
        private FloatBuffer texCoordBuffer;
        private int[] textures = new int[2];
       
        private float vertices[] =
        {
                -1.0f, 1.0f, 0.0f,      //Top left
                1.0f, 1.0f, 0.0f,       // Top right
                -1.0f, -1.0f, 0.0f, //Bottom Left              
                1.0f, -1.0f, 0.0f       //Bottom Right         
        };
       
        private float vertices2[] =
        {
                -10.0f, 10.0f, 0.0f,
                10.0f, 10.0f, 0.0f,
                -10.0f, -10.0f, 0.0f,
                10.0f, -10.0f, 0.0f
        };
       
        private float colors[] =
        {
                0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 0.0f
    };
       
        private float texCoords[] =
        {
                0.0f, 1.0f,
                1.0f, 1.0f,
                0.0f, 0.0f,
                1.0f, 0.0f,
        };
       
        private int surfaceWidth;
        private int surfaceHeight;
       
        class TouchPoint
        {
                public boolean isActive = false;
                public float X = 0.0f;
                public float Y = 0.0f;
               
                public android.media.MediaPlayer soundPlayer;
               
                public TouchPoint(Context context)
                {
                        soundPlayer = android.media.MediaPlayer.create(context, R.raw.burn);                   
                }
               
                public void Play()
                {
                        soundPlayer.seekTo(0);
                        soundPlayer.start();
                }
        }
       
        public TouchPoint touchPoints[] = new TouchPoint[HotPlateView.MAX_POINTERS];
       
        public HotPlateRenderer(Context context)
        {      
                this.context = context;
               
                for (int i = 0; i < HotPlateView.MAX_POINTERS; i++)
                {
                        touchPoints[i] = new TouchPoint(context);
                }
               
                ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
                byteBuf.order(ByteOrder.nativeOrder());
                vertexBuffer = byteBuf.asFloatBuffer();
                vertexBuffer.put(vertices);
                vertexBuffer.position(0);
               
                byteBuf = ByteBuffer.allocateDirect(vertices2.length * 4);
                byteBuf.order(ByteOrder.nativeOrder());
                vertexBuffer2 = byteBuf.asFloatBuffer();
                vertexBuffer2.put(vertices2);
                vertexBuffer2.position(0);
               
                byteBuf = ByteBuffer.allocateDirect(colors.length * 4);
                byteBuf.order(ByteOrder.nativeOrder());
                colorBuffer = byteBuf.asFloatBuffer();
                colorBuffer.put(colors);
                colorBuffer.position(0);
               
                byteBuf = ByteBuffer.allocateDirect(texCoords.length * 4);
                byteBuf.order(ByteOrder.nativeOrder());
                texCoordBuffer = byteBuf.asFloatBuffer();
                texCoordBuffer.put(texCoords);
                texCoordBuffer.position(0);
        }
       
        public void LoadTexture(GL10 gl, Context context, int resource, int texture)
        {
                InputStream is = context.getResources().openRawResource(resource);
                Bitmap bitmap = null;
                try
                {
                        bitmap = BitmapFactory.decodeStream(is);
                }
                finally
                {
                        try
                        {
                                is.close();
                                is = null;
                        }
                        catch (IOException e)
                        {                              
                        }
                }
               
                gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[texture]);
               
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
               
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
               
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
               
                bitmap.recycle();              
        }
       
        public void DisableAllTouchPoints()
        {
                for (int i = 0; i < HotPlateView.MAX_POINTERS; i++)
                        touchPoints[i].isActive = false;
        }
       
    public void onSurfaceCreated(GL10 gl, EGLConfig config)
    {
                gl.glGenTextures(2, textures, 0);
        LoadTexture(gl, this.context, R.drawable.hotplate, 0);
        LoadTexture(gl, this.context, R.drawable.smoke, 1);
       
                gl.glEnable(GL10.GL_TEXTURE_2D);                        //Enable Texture Mapping ( NEW )
                gl.glShadeModel(GL10.GL_SMOOTH);                        //Enable Smooth Shading
                gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);        //Black Background
               
                //Really Nice Perspective Calculations
                gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);        
    }

    public void onSurfaceChanged(GL10 gl, int w, int h)
    {
        gl.glViewport(0, 0, w, h);
        surfaceWidth = w;
        surfaceHeight = h;
    }

    public void onDrawFrame(GL10 gl)
    {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
       
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        float halfW = 1.0f;
        float halfH = 1.0f;
        if (surfaceWidth > surfaceHeight)
        {
                halfW = (float)surfaceWidth / (float)surfaceHeight;
                halfH = 1.0f;
        }
        else
        {
                halfW = 1.0f;
                halfH = (float)surfaceHeight / (float)surfaceWidth;
        }        
        gl.glOrthof(-halfW, halfW, -halfH, halfH, 0, 1.0f);
       
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
       
                gl.glFrontFace(GL10.GL_CW);
               
                gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
               
                //Point to our vertex buffer
                gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
                gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
                gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoordBuffer);             
               
                //Enable vertex buffer
                gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
                gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
                gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
               
                gl.glEnable(GL10.GL_BLEND);
                gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE);
               
                gl.glEnable(GL10.GL_TEXTURE_2D);
               
                //Draw the vertices as triangle strip
                gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
               
                // draw touch points
                for (int i = 0; i < HotPlateView.MAX_POINTERS; i++)
                {
                        DrawTouchPoint(gl, i);
                }

                //Disable the client state before leaving
                gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
                gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
                gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }
   
   
    public void updatePlate(float deltaTime)
    {
        timePassed += deltaTime;
       
        float alpha = timePassed * heatRate;
        if (alpha > 1.0f)
                alpha = 1.0f;
       
        for (int i = 0; i < colors.length; i++)
        {
                colorBuffer.put(i, alpha);
        }
    }
   
    public void DrawTouchPoint(GL10 gl, int i)
    {
        if (!touchPoints[i].isActive)
                return;
       
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrthof(0.0f, surfaceWidth, surfaceHeight, 0.0f, 0.0f, 1.0f);
       
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
       
        gl.glTranslatef(touchPoints[i].X, touchPoints[i].Y, 0.0f);
                gl.glScalef(50.0f, 50.0f, 1.0f);
               
                gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[1]);
               
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);

    }
}