/**
* 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.gl;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import com.gundogstudios.modules.GLES11Module;
import com.gundogstudios.modules.Modules;
public class ModelUtils {
private static final int CHAR_SIZE = Character.SIZE / Byte.SIZE;
private static final int FLOAT_SIZE = Float.SIZE / Byte.SIZE;
public static final String TEXTURE_QUALITY = "TextureQuality";
public static final String MESH_QUALITY = "MeshQuality";
public static final int LOW_QUALITY = 0;
public static final int MEDIUM_QUALITY = 1;
public static final int HIGH_QUALITY = 2;
public static int generateIndexBuffer(short[] indices) {
if (indices == null)
return 0;
int[] vboIds = new int[1];
GLES11Module gl = Modules.GL;
gl.glGenBuffers(1, vboIds, 0);
ByteBuffer indexByteBuffer = ByteBuffer.allocateDirect(CHAR_SIZE * indices.length);
CharBuffer indexBuffer = indexByteBuffer.order(ByteOrder.nativeOrder()).asCharBuffer();
for (int x = 0; x < indices.length; x++) {
indexBuffer.put((char) indices[x]);
}
indexBuffer.position(0);
gl.glBindBuffer(GLES11Module.GL_ELEMENT_ARRAY_BUFFER, vboIds[0]);
gl.glBufferData(GLES11Module.GL_ELEMENT_ARRAY_BUFFER, indexByteBuffer.capacity(), indexByteBuffer,
GLES11Module.GL_STATIC_DRAW);
gl.glBindBuffer(GLES11Module.GL_ELEMENT_ARRAY_BUFFER, 0);
return vboIds[0];
}
public static int generateTextureBuffer(float[] uvs) {
if (uvs == null)
return 0;
int[] vboIds = new int[1];
GLES11Module gl = Modules.GL;
gl.glGenBuffers(vboIds.length, vboIds, 0);
ByteBuffer uvByteBuffer = ByteBuffer.allocateDirect(uvs.length * FLOAT_SIZE).order(ByteOrder.nativeOrder());
FloatBuffer uvBuffer = uvByteBuffer.asFloatBuffer();
uvBuffer.put(uvs);
uvByteBuffer.position(0);
gl.glBindBuffer(GLES11Module.GL_ARRAY_BUFFER, vboIds[0]);
gl.glBufferData(GLES11Module.GL_ARRAY_BUFFER, uvByteBuffer.capacity(), uvByteBuffer,
GLES11Module.GL_STATIC_DRAW);
gl.glBindBuffer(GLES11Module.GL_ARRAY_BUFFER, 0);
return vboIds[0];
}
public static int[] generateVertexBuffer(float[][] vertices) {
if (vertices == null)
return null;
GLES11Module gl = Modules.GL;
int[] vboIds = new int[vertices.length];
gl.glGenBuffers(vboIds.length, vboIds, 0);
for (int i = 0; i < vertices.length; i++) {
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices[i].length * FLOAT_SIZE).order(
ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = vertexByteBuffer.asFloatBuffer();
vertexBuffer.put(vertices[i]);
vertexByteBuffer.position(0);
gl.glBindBuffer(GLES11Module.GL_ARRAY_BUFFER, vboIds[i]);
gl.glBufferData(GLES11Module.GL_ARRAY_BUFFER, vertexByteBuffer.capacity(), vertexByteBuffer,
GLES11Module.GL_STATIC_DRAW);
}
gl.glBindBuffer(GLES11Module.GL_ARRAY_BUFFER, 0);
return vboIds;
}
public static ArrayList<GSModel> createModel(int textureId, GSModelVBOs modelData) {
ArrayList<GSModel> models = new ArrayList<GSModel>();
int indexBufferID = modelData.getIndexBufferId();
int textureBufferID = modelData.getTextureBufferId();
int indexCount = modelData.getIndexCount();
int[] actionIDs = modelData.getIdleBufferIds();
int animationLength = modelData.getIdleAnimationLength();
int action = Actions.IDLE;
if (actionIDs != null) {
GSModel model = new GSModel(action, animationLength, actionIDs, indexBufferID, textureBufferID, textureId,
indexCount);
models.add(model);
}
actionIDs = modelData.getMoveBufferIds();
animationLength = modelData.getMoveAnimationLength();
action = Actions.MOVE;
if (actionIDs != null) {
GSModel model = new GSModel(action, animationLength, actionIDs, indexBufferID, textureBufferID, textureId,
indexCount);
models.add(model);
}
actionIDs = modelData.getAttackBufferIds();
animationLength = modelData.getMoveAnimationLength();
action = Actions.ATTACK;
if (actionIDs != null) {
GSModel model = new GSModel(action, animationLength, actionIDs, indexBufferID, textureBufferID, textureId,
indexCount);
models.add(model);
}
actionIDs = modelData.getDeathBufferIds();
animationLength = modelData.getMoveAnimationLength();
action = Actions.DEATH;
if (actionIDs != null) {
GSModel model = new GSModel(action, animationLength, actionIDs, indexBufferID, textureBufferID, textureId,
indexCount);
models.add(model);
}
return models;
}
public static boolean useMIPMAPs() {
return false;// ModuleManager.PREFERENCES.get(TEXTURE_QUALITY, HIGH_QUALITY) != LOW_QUALITY;
}
public static int getTextureFilter() {
return getTextureQuality() == HIGH_QUALITY ? GLES11Module.GL_LINEAR : GLES11Module.GL_NEAREST;
}
public static int getMeshQuality() {
return Modules.PREFERENCES.get(MESH_QUALITY, HIGH_QUALITY);
}
public static int getTextureQuality() {
long memory = Runtime.getRuntime().maxMemory();
int quality;
if (memory < 20000000) {
quality = LOW_QUALITY;
} else if (memory < 40000000) {
quality = MEDIUM_QUALITY;
} else {
quality = HIGH_QUALITY;
}
return Modules.PREFERENCES.get(TEXTURE_QUALITY, quality);
}
public static int getMeshFrameRate() {
switch (getMeshQuality()) {
case (HIGH_QUALITY):
return 20;
case (MEDIUM_QUALITY):
return 10;
case (LOW_QUALITY):
return 5;
default:
return 1;
}
}
public static int getBitmapScaleSize() {
switch (getTextureQuality()) {
case (HIGH_QUALITY):
return 1;
case (MEDIUM_QUALITY):
return 2;
case (LOW_QUALITY):
default:
return 4;
}
}
public static float getParticleScaleSize() {
switch (getTextureQuality()) {
case (HIGH_QUALITY):
return 1f;
case (MEDIUM_QUALITY):
return 1.5f;
case (LOW_QUALITY):
default:
return 2f;
}
}
public static void decreaseTextureQuality() {
int newQuality;
switch (getTextureQuality()) {
case (HIGH_QUALITY):
newQuality = MEDIUM_QUALITY;
case (MEDIUM_QUALITY):
newQuality = LOW_QUALITY;
case (LOW_QUALITY):
default:
newQuality = LOW_QUALITY;
}
Modules.PREFERENCES.put(TEXTURE_QUALITY, newQuality);
}
}