Android Open Source - smoke-or-fire G L E S Renderer






From Project

Back to project page smoke-or-fire.

License

The source code is released under:

GNU General Public License

If you think the Android project smoke-or-fire listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 *  Copyright 2012 Brian Flores/* ww  w.  java 2  s. c om*/
 *
 *  This file is part of SmokeOrFire.
 *
 *  SmokeOrFire 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.
 *
 *  SmokeOrFire 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 SmokeOrFire.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.votebrian.games.sof;

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

import java.lang.Thread;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.HashMap;

import android.content.Context;
import android.content.res.Resources;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Looper;
import android.os.Message;

import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;

import android.os.Handler;

import android.util.Log;

class GLESRenderer
        implements GLSurfaceView.Renderer {
    private Global gbl;
    private Context mCtx;
    private Deck mDeck;
    private Buttons mOverlayBtns;
    private PassButton mPass;

    private Labels mLbl;

    private Handler handler;

    private Resources mRes;

    public SharedPreferences         mSettings;
    public SharedPreferences.Editor mEditor;

    private SoundPool mSoundPool;
    private AudioManager mAudioManager;
    private HashMap<Integer, Integer> mSoundPoolMap;

    private final int EVENT_DOWN = 0;
    private final int EVENT_MOVE = 1;
    private final int EVENT_UP   = 2;

    private ByteBuffer mLbb;
    private FloatBuffer mLinesBuffer;
    private int mNumLines = 0;
    private int POINTS_PER_LINE = 3;
    private int BYTES_PER_POINT = 4;
    private float[] mLineVert = new float[24];

    private int mViewW = 0;
    private int mViewH = 0;
    private float mViewAngle = 10f;

    private float mNearH = 0f;
    private float mNearW = 0f;
    private float mNearZ = 5f;
    private float mFarZ  = 15f;

    private FloatBuffer mPositionBuffer;
    private FloatBuffer mDiffuseBuffer;

    private float mXAngle = 0;
    private float mYAngle = 0;

    private int mCurrRegion = -1;

    public final int SS_SUNLIGHT = GL10.GL_LIGHT0;

    private boolean relBtnsEnabled = false;
    private boolean mRunning = true;

    private long mStartTime = 0;
    private long mIdleTime;
    private long maxIdleTime = 5000;

    private int mSelectionFail = 0;
    // 0:  Ready for selection
    // 1:  Selection Failed. Deal disabled until cards cleared.
    // 2:  Cards cleared.  Reset counter

    public GLESRenderer(Context context) {
        mCtx = context;
        handler = new Handler();

        mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
        mAudioManager = (AudioManager) mCtx.getSystemService(Context.AUDIO_SERVICE);
        mSoundPoolMap = new HashMap();
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

        gbl = (Global) mCtx.getApplicationContext();


        // Shared Preferences Setup
        mRes = mCtx.getResources();

        mSettings = mCtx.getSharedPreferences( mRes.getString(R.string.prefs), Context.MODE_PRIVATE);
        mEditor = mSettings.edit();

        // Load chime
        mSoundPoolMap.put(1, mSoundPool.load(mCtx, R.raw.audio_chime, 1));

        // Default Preferences
        zeroCounter();
        resetFailed();
        mSelectionFail = 0;

        // Create Models
        mDeck = new Deck(mCtx, gl);
        mOverlayBtns = new Buttons(mCtx, gl);
        mPass = new PassButton(mCtx, gl);

        mLbl = new Labels(mCtx, gl);
        mLbl.enable();

        Global.setReady();

        blink();

        handler.removeCallbacks(mCheckIdle);
        handler.postDelayed(mCheckIdle, maxIdleTime);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);


        gl.glPushMatrix();

        // rotate card table
        gl.glRotatef(-20f, 1f, 0f, 0f);
        gl.glRotatef(  5f, 0f, 1f, 0f);
        gl.glRotatef(-10f, 0f, 0f, 1f);
        gl.glTranslatef( 1f, 3f, 0f);

        mDeck.draw(gl);

        gl.glPopMatrix();


        gl.glPushMatrix();

        mOverlayBtns.draw(gl);
        mPass.draw(gl);

        mLbl.draw(gl);

        gl.glPopMatrix();
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        mViewW = width;
        mViewH = height;

        initLighting(gl);

        setDisplayProperties(gl);
        setProjection(gl);

        mOverlayBtns.setVertices(mViewW, mViewH, mViewAngle);
        mPass.setVertices(mViewW, mViewH, mViewAngle);

        mLbl.setVertices(mViewW, mViewH, mViewAngle);

        gl.glLoadIdentity();
    }

    private void setProjection(GL10 gl) {
        float ratio = (float) mViewW / (float) mViewH;

        // determine the "half-width" and "half-height" of our view at the near cutoff Z value stuff
        // stuff stuff
        mNearH = (float) (mNearZ * (Math.tan(Math.toRadians(mViewAngle))));
        mNearW = mNearH * ratio;

        gl.glViewport(0, 0, mViewW, mViewH);

        // Define orthographic projection
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glFrustumf(-mNearW, mNearW, -mNearH, mNearH, mNearZ, mFarZ);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
    }

    private void setDisplayProperties(GL10 gl) {
        // Set background color
        gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        // Set to remove CW triangles
        gl.glEnable(GL10.GL_CULL_FACE);
        gl.glFrontFace(GL10.GL_CCW);
        gl.glCullFace(GL10.GL_BACK);

        gl.glClearDepthf(1.0f);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);

        // set blend parameter
        gl.glEnable(GL10.GL_BLEND);
        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

        gl.glDisable(GL10.GL_COLOR_MATERIAL);
    }

    private void initLighting(GL10 gl) {
        float[] diffuse = { 1.0f, 1.0f, 1.0f, 1.0f };
        ByteBuffer mDbb = ByteBuffer.allocateDirect( diffuse.length * 4 );
        mDbb.order(ByteOrder.nativeOrder());
        mDiffuseBuffer = mDbb.asFloatBuffer();
        mDiffuseBuffer.put(diffuse);
        mDiffuseBuffer.position(0);

        float[] pos = { 0.0f, 0.0f, 0.0f, 1.0f };
        ByteBuffer mPbb = ByteBuffer.allocateDirect( pos.length * 4 );
        mPbb.order(ByteOrder.nativeOrder());
        mPositionBuffer = mPbb.asFloatBuffer();
        mPositionBuffer.put(pos);
        mPositionBuffer.position(0);

        gl.glLightfv(SS_SUNLIGHT, GL10.GL_POSITION, mPositionBuffer);
        gl.glLightfv(SS_SUNLIGHT, GL10.GL_DIFFUSE, mDiffuseBuffer);
        // gl.glShadeModel(GL10.GL_SMOOTH);
        // gl.glEnable(GL10.GL_LIGHTING);
        gl.glDisable(GL10.GL_LIGHTING);
        // gl.glEnable(SS_SUNLIGHT);
    }

    public void buttonEvent(float x, float y, int event) {
        // determine region of button event
        // 0: SMOKE
        // 1: FIRE
        // 2: HIGHER
        // 3: LOWER
        int region = regionCalc(x, y);

        mIdleTime = System.currentTimeMillis();
        mLbl.disable();

        switch(event) {
            case EVENT_DOWN:
                mStartTime = System.currentTimeMillis();

                if(mSelectionFail == 1) {
                    // do nothing
                } else if(region == Global.PASS) {
                    // do nothing
                } else if( (region < 2) || relBtnsEnabled ) {
                    // highlight button
                    mOverlayBtns.highlightBtn(region);
                    mCurrRegion = region;
                }
                break;

            case EVENT_MOVE:
                if(System.currentTimeMillis() - mStartTime > 10000) {
                    removeAds();
                }

                if(mSelectionFail == 1) {
                    // do nothing
                } else {
                    // move highlight to correct button
                    // mOverlayBtns.settle();
                    if( (region < 2) || relBtnsEnabled ) {
                        if(region == mCurrRegion) {
                            // do nothing
                        } else {
                            mOverlayBtns.highlightBtn(region);
                            mCurrRegion = region;
                        }
                    }
                }
                break;

            case EVENT_UP:
                if(System.currentTimeMillis() - mStartTime > 10000) {
                    removeAds();
                }

                if(mSelectionFail == 1) {
                    clearTable();
                } else if(region == Global.PASS) {
                    // User has pressed the pass button on the bottom right
                    int temp_count = mSettings.getInt( mRes.getString(R.string.counter_pref), -1);
                    if(temp_count > 4) {
                        mPass.reset();
                    }
                } else if( (region < 2) || relBtnsEnabled ) {
                    // remove highlight after a slight delay
                    handler.postDelayed( new Runnable() {
                        public void run() {
                            mOverlayBtns.settle();
                        }
                    }, 100);
                    mCurrRegion = -1;

                    // deal card and determine outcome
                    // cards[0] is the previous card
                    // cards[1] is the current card
                    int[] cards = mDeck.deal();
                    int result = Global.BAD;

                    if(region < 2) {
                        // absolute selection
                        if( (region == Global.SMOKE) && (Deck.getSuit(cards[1]) > 1) ) {
                            result = Global.GOOD;
                        } else if( (region == Global.FIRE) && (Deck.getSuit(cards[1]) < 2) ) {
                            result = Global.GOOD;
                        }
                    } else {
                        // relative selection
                        int diff = Deck.getValue(cards[1]) - Deck.getValue(cards[0]);
                        if(diff == 0) {
                            result = Global.SOCIAL;
                        } else if(diff > 0 && region == Global.HIGHER) {
                            result = Global.GOOD;
                        } else if (diff < 0 && region == Global.LOWER) {
                            result = Global.GOOD;
                        }
                    }


                    switch(result) {
                        case Global.BAD:
                            // expand drink counter

                            // increment drink counter
                            incrementCounter();

                            // indicate fail preference
                            flagFailed();

                            // show cards on table

                            // disable all selections until cleared
                            mSelectionFail = 1;

                            // disable higher/lower selections
                            relBtnsEnabled = false;
                            mOverlayBtns.disableAll();
                            mPass.reset();
                            mLbl.disableRelative();
                            break;
                        case Global.GOOD:
                            // Check to see if user has earned ad-free preference
                            int temp_count = mSettings.getInt(mRes.getString(R.string.counter_pref), 0);
                            if(temp_count + 1 == Global.AD_FREE_THRESHOLD) {
                                removeAds();
                            }

                            // increment drink counter
                            incrementCounter();

                            // enable higher/lower selections
                            relBtnsEnabled = true;
                            mOverlayBtns.enableRelative();
                            mLbl.enableRelative();
                            break;
                        case Global.SOCIAL:
                            // highlight drink counter increment
                            incrementCounter();

                            // show social splash image
                            // show matching cards
                            break;
                    }
                }
                break;
        }
    }

    private void clearTable() {
        // clear cards from table
        mDeck.burnTable();

        // disable Relative selections
        mOverlayBtns.enableAll();
        mOverlayBtns.disableRelative();

        // Set counter to zero
        zeroCounter();

        // reset fail indicator
        resetFailed();

        mSelectionFail = 0;
    }

    private void incrementCounter() {
        int temp_count = mSettings.getInt( mRes.getString(R.string.counter_pref), -1);
        temp_count = temp_count + 1;
        mEditor.putInt( mRes.getString(R.string.counter_pref), temp_count);
        mEditor.commit();

        mPass.increment();
    }

    private void zeroCounter() {
        mEditor.putInt( mRes.getString(R.string.counter_pref), 0);
        mEditor.commit();
    }

    private void flagFailed() {
        mEditor.putBoolean( mRes.getString(R.string.fail_pref), true);
        mEditor.commit();
    }

    private void resetFailed() {
        mEditor.putBoolean( mRes.getString(R.string.fail_pref), false);
        mEditor.commit();
    }

    private int regionCalc(float x, float y) {
        float slope = (float) mViewH / (float) mViewW;
        float upslope = -1 * slope * (float) x + mViewH;
        float downslope = slope * x;

        // Specify touch region for PASS "button"
        // Set to the intersection of the bottom 20% and right-most 30% of screen.
        if( (y > (mViewH * 0.8)) && (x > (mViewW * 0.70)) ) {
            return Global.PASS;
        }

        if( y > upslope ) {
            if( y > downslope ) {
                return Global.LOWER;
            } else {
                return Global.FIRE;
            }
        } else {
            if( y > downslope ) {
                return Global.SMOKE;
            } else {
                return Global.HIGHER;
            }
        }
    }

    private void blink() {
        handler.postDelayed(new Runnable() {
            public void run() {
                mOverlayBtns.highlightAbsolute();
            }
        }, 1000);

        handler.postDelayed(new Runnable() {
            public void run() {
                mOverlayBtns.settle();
            }
        }, 1100);

        handler.postDelayed(new Runnable() {
            public void run() {
                mOverlayBtns.highlightAbsolute();
            }
        }, 1200);

        handler.postDelayed(new Runnable() {
            public void run() {
                mOverlayBtns.settle();
            }
        }, 1300);

        handler.postDelayed(new Runnable() {
            public void run() {
                mOverlayBtns.highlightAbsolute();
            }
        }, 1400);

        handler.postDelayed(new Runnable() {
            public void run() {
                mLbl.disable();
                mOverlayBtns.settle();
            }
        }, 1500);
    }


    // Check idle
    public Runnable mCheckIdle = new Runnable() {
        public void run() {
            long curr = System.currentTimeMillis();
            if(curr > mIdleTime + maxIdleTime) {
                // turn on labels
                mLbl.enable();
            }

            if(mRunning) {
                handler.postDelayed(this, 1000);
            }
        }
    };

    public void onPause() {
        mRunning = false;
        handler.removeCallbacks(mCheckIdle);
    }

    private void removeAds() {
        // play sound
        if(mSettings.getInt(mRes.getString(R.string.ad_pref), 0) == 0) {
            mSoundPool.play(mSoundPoolMap.get(1), 0.5f, 0.5f, 0, 0, 1f);
        }

        // set preference
        mEditor.putInt(mRes.getString(R.string.ad_pref), 1);
        mEditor.commit();
    }
}




Java Source Code List

net.votebrian.games.sof.AboutActivity.java
net.votebrian.games.sof.Base64DecoderException.java
net.votebrian.games.sof.Base64.java
net.votebrian.games.sof.Btn.java
net.votebrian.games.sof.Buttons.java
net.votebrian.games.sof.Card.java
net.votebrian.games.sof.Deck.java
net.votebrian.games.sof.GLESRenderer.java
net.votebrian.games.sof.Global.java
net.votebrian.games.sof.IabException.java
net.votebrian.games.sof.IabHelper.java
net.votebrian.games.sof.IabResult.java
net.votebrian.games.sof.Inventory.java
net.votebrian.games.sof.Labels.java
net.votebrian.games.sof.Model.java
net.votebrian.games.sof.PassButton.java
net.votebrian.games.sof.PurchaseActivity.java
net.votebrian.games.sof.Purchase.java
net.votebrian.games.sof.Security.java
net.votebrian.games.sof.SkuDetails.java
net.votebrian.games.sof.SoFActivity.java
net.votebrian.games.sof.SurfaceView.java
net.votebrian.games.sof.TutorialActivity.java