/**
* Copyright (C) 2013 Gundog Studios LLC.
*
* This program 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.
*
* This program 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 <http://www.gnu.org/licenses/>.
*/
package com.gundogstudios;
import java.util.ArrayList;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.content.Context;
import android.opengl.GLES11;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.godsandtowers.graphics.ModelFetcher;
import com.godsandtowers.sprites.BaseCreature;
import com.godsandtowers.sprites.BaseSpecial;
import com.godsandtowers.util.TDWAndroidPreferences;
import com.gundogstudios.gl.Actions;
import com.gundogstudios.gl.CombinedModel;
import com.gundogstudios.modules.AndroidAssets;
import com.gundogstudios.modules.AndroidGLES11;
import com.gundogstudios.modules.AndroidGLUtils;
import com.gundogstudios.modules.AndroidLogger;
import com.gundogstudios.modules.Modules;
import com.gundogstudios.modules.basic.BasicProfilerModule;
public class GundogStudiosModelViewerActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.modelviewer);
Modules.LOG = new AndroidLogger();
Modules.ASSETS = new AndroidAssets(this.getAssets());
Modules.GL = new AndroidGLES11();
Modules.PREFERENCES = new TDWAndroidPreferences(this);
Modules.PROFILER = new BasicProfilerModule();
RelativeLayout main = (RelativeLayout) this.findViewById(R.id.backgroundLayout);
final ModelView glView = new ModelView(this);
main.addView(glView, 0);
Button button;
final Activity activity = this;
button = (Button) this.findViewById(R.id.previous);
button.bringToFront();
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String model = glView.previousModel();
Toast.makeText(activity, model, Toast.LENGTH_SHORT).show();
}
});
button = (Button) this.findViewById(R.id.next);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String model = glView.nextModel();
Toast.makeText(activity, model, Toast.LENGTH_SHORT).show();
}
});
button = (Button) this.findViewById(R.id.up);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
glView.rotateUp();
}
});
button = (Button) this.findViewById(R.id.down);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
glView.rotateDown();
}
});
button = (Button) this.findViewById(R.id.left);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
glView.rotateLeft();
}
});
button = (Button) this.findViewById(R.id.right);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
glView.rotateRight();
}
});
button = (Button) this.findViewById(R.id.in);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
glView.zoomIn();
}
});
button = (Button) this.findViewById(R.id.out);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
glView.zoomOut();
}
});
final Button actionButton = (Button) this.findViewById(R.id.action);
actionButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int action = glView.nextAction();
actionButton.setText(Actions.toString(action));
}
});
button = (Button) this.findViewById(R.id.render);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
glView.requestRender();
}
});
}
private class ModelView extends GLSurfaceView implements Renderer {
private static final float TOUCH_SCALE = 0.005f;
private float xRot = -90f;
private float zRot = -90f;
private float xTrans = 0f;
private float yTrans = -.5f;
private float zTrans = -3f;
private float touchedX = 0;
private float touchedY = 0;
private ArrayList<CombinedModel> models;
private ArrayList<String> modelNames;
private int currentAction = Actions.IDLE;
private int current = 0;
private long lastRender = 0;
private boolean finishedLoading = false;
private ModelFetcher modelFetcher;
public ModelView(Context context) {
super(context);
// Turn on error-checking and logging
super.setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
super.setDebugFlags(DEBUG_LOG_GL_CALLS);
super.setRenderer(this);
super.requestFocus();
super.setFocusableInTouchMode(true);
super.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
@Override
public void onSurfaceCreated(GL10 UNUSED, EGLConfig config) {
Modules.GLUTIL = new AndroidGLUtils(UNUSED);
GLES11.glClearColor(0f, 0f, 0f, 0.0f);
GLES11.glShadeModel(GLES11.GL_SMOOTH);
GLES11.glClearDepthf(1.0f);
GLES11.glEnable(GLES11.GL_DEPTH_TEST);
GLES11.glDepthFunc(GLES11.GL_LESS);
GLES11.glHint(GLES11.GL_PERSPECTIVE_CORRECTION_HINT, GLES11.GL_NEAREST);
GLES11.glEnable(GLES11.GL_BLEND);
GLES11.glBlendFunc(GLES11.GL_SRC_ALPHA, GLES11.GL_ONE_MINUS_SRC_ALPHA);
GLES11.glEnable(GLES11.GL_ALPHA_TEST);
GLES11.glAlphaFunc(GLES11.GL_GREATER, .01f);
modelFetcher = new ModelFetcher();
modelFetcher.loadCustomModels(15, 7, ModelFetcher.FOREST_BACKGROUND, ModelFetcher.FOREST_WALL);
new Thread(new Runnable() {
@Override
public void run() {
loadModels();
finishedLoading = true;
Modules.LOG.info("ModelView", "Displaying Model: " + modelNames.get(current) + " IDLE");
}
}).start();
}
private void loadModels() {
// modelNames = modelFetcher.getAllModelNames();
// models = modelFetcher.getAllModels();
modelNames = new ArrayList<String>();
models = new ArrayList<CombinedModel>();
addModel(BaseCreature.FROZEN_SOLDIER_HORSEMAN);
addModel(BaseSpecial.DAMAGE_CREATURES);
addModel(BaseSpecial.HEAL_CREATURES);
addModel(BaseSpecial.KILL_CREATURES);
addModel(BaseSpecial.SLOW_CREATURES);
addModel(BaseSpecial.SPEEDUP_CREATURES);
addModel(BaseSpecial.STUN_CREATURES);
}
private void addModel(String modelName, Object... objects) {
models.add(modelFetcher.getModel(modelName, objects));
modelNames.add(modelName);
}
@Override
public void onDrawFrame(GL10 UNUSED) {
long currentTime = System.currentTimeMillis();
int timePassed = (int) (currentTime - lastRender);
if (timePassed < 0 || timePassed > 10000) {
timePassed = 20;
}
lastRender = currentTime;
modelFetcher.loadVBOandTextures();
if (!finishedLoading) {
Thread.yield();
return;
}
GLES11.glClear(GLES11.GL_COLOR_BUFFER_BIT | GLES11.GL_DEPTH_BUFFER_BIT);
GLES11.glMatrixMode(GLES11.GL_MODELVIEW);
GLES11.glLoadIdentity();
GLES11.glPushMatrix();
GLES11.glTranslatef(xTrans, yTrans, zTrans);
GLES11.glRotatef(xRot, 1, 0, 0);
GLES11.glRotatef(zRot, 0, 0, 1);
GLES11.glPushMatrix();
models.get(current).draw(timePassed);
GLES11.glPopMatrix();
Modules.PROFILER.updateRenderFPS();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES11.glViewport(0, 0, width, height);
GLES11.glMatrixMode(GLES11.GL_PROJECTION);
GLES11.glLoadIdentity();
float ratio = (float) width / (float) height;
GLU.gluPerspective(gl, 45.0f, ratio, 0.01f, 100.0f);
GLES11.glMatrixMode(GLES11.GL_MODELVIEW);
GLES11.glLoadIdentity();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
if (event.getAction() == MotionEvent.ACTION_MOVE) {
xTrans += (x - touchedX) * TOUCH_SCALE;
yTrans -= (y - touchedY) * TOUCH_SCALE;
}
touchedX = x;
touchedY = y;
return true;
}
public void zoomIn() {
zTrans += .5f;
}
public void zoomOut() {
zTrans -= .5f;
}
public void rotateLeft() {
zRot -= 5f;
}
public void rotateRight() {
zRot += 5f;
}
public void rotateUp() {
xRot -= 5f;
}
public void rotateDown() {
xRot += 5f;
}
public String nextModel() {
if (++current >= models.size())
current = 0;
currentAction = Actions.IDLE;
return modelNames.get(current);
}
public String previousModel() {
if (--current < 0)
current = models.size() - 1;
currentAction = Actions.IDLE;
return modelNames.get(current);
}
public int nextAction() {
switch (currentAction) {
case Actions.IDLE:
models.get(current).setAction(Actions.MOVE);
currentAction = Actions.MOVE;
break;
case Actions.MOVE:
models.get(current).setAction(Actions.ATTACK);
currentAction = Actions.ATTACK;
break;
case Actions.ATTACK:
models.get(current).setAction(Actions.DEATH);
currentAction = Actions.DEATH;
break;
case Actions.DEATH:
models.get(current).setAction(Actions.IDLE);
currentAction = Actions.IDLE;
break;
default:
Modules.LOG.error("ModelView", "Unknown Action");
}
return currentAction;
}
}
}