package com.viveret.xprtworkloadw2016;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.util.Log;
import java.io.InputStream;
import java.io.IOException;
import org.smurn.jply.*;
import org.smurn.jply.util.*;
public class Mesh {
public static final int BYTES_PER_FLOAT = 4;
public static final int BYTES_PER_INT = 4;
public static final int BYTES_PER_SHORT = 2;
private static int gNumMeshes = 0;
public float positions[];
public float norms[];
public float colors[];
public int indices[];
private int mySize, myIndexIndex, myColorIndex;
private final FloatBuffer myPosBuf;
private final FloatBuffer myColorBuf;
private final IntBuffer myIndexBuffer;
private final int myMeshId;
private boolean myDataHasChanged;
// 0 = vert, 1 = col, 2 = indx
private final int bufs[] = new int[3];
// private static boolean gHasInitialized = false;
private long perfStartTime, perfDuration;
public Mesh(int vertCapacity, int numIndices) {
mySize = 0;
myIndexIndex = 0;
myColorIndex = 0;
perfStartTime = System.nanoTime();
perfDuration = 0;
GLES20.glGenBuffers(bufs.length, bufs, 0);
positions = new float[vertCapacity * 3];
norms = new float[vertCapacity * 3];
colors = new float[vertCapacity * 4];
indices = new int[numIndices];
myPosBuf = ByteBuffer.allocateDirect(positions.length *
BYTES_PER_FLOAT)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
myColorBuf = ByteBuffer.allocateDirect(colors.length *
BYTES_PER_FLOAT)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
myIndexBuffer = ByteBuffer.allocateDirect(indices.length *
BYTES_PER_INT)
.order(ByteOrder.nativeOrder())
.asIntBuffer();
myMeshId = gNumMeshes++ - 1;
dataHasChanged();
// Position
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufs[0]);
checkGLError("bind 0");
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, myPosBuf.capacity() * BYTES_PER_FLOAT,
myPosBuf, GLES20.GL_DYNAMIC_DRAW);
checkGLError("buffer data array buf");
// Color
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufs[1]);
checkGLError("bind 1");
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, myColorBuf
.capacity() * BYTES_PER_FLOAT,
myColorBuf, GLES20.GL_DYNAMIC_DRAW);
checkGLError("buffer color data array buf");
// Indices
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, bufs[2]);
checkGLError("bind 2");
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER,
myIndexBuffer.capacity()
* BYTES_PER_INT, myIndexBuffer,
GLES20.GL_DYNAMIC_DRAW);
checkGLError("buffer data element array");
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
checkGLError("bind array buf 0");
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
checkGLError("bind element array buf 0");
perfDuration += System.nanoTime() - perfStartTime;
perfStartTime = 0;
}
public int addVert(float[] axes) {
for (int i = 0; i < axes.length; i++) {
positions[mySize * 3 + i] = axes[i];
}
return mySize++ - 1;
}
public int addVert(float x, float y, float z) {
return addVert(new float[]{x, y, z});
}
public void addIndex(int i) {
indices[myIndexIndex] = i;
myIndexIndex++;
}
public void addIndex(int[] ar) {
for (int i : ar)
addIndex(i);
}
public int addColor(float[] axes) {
for (int i = 0; i < axes.length; i++) {
colors[myColorIndex * 4 + i] = axes[i];
}
return myColorIndex++ - 1;
}
public int addColor(float r, float g, float b, float a) {
return addColor(new float[]{r, g, b, a});
}
public int getSize() {
return mySize;
}
public void dataHasChanged() {
myPosBuf.put(positions).position(0);
myIndexBuffer.put(indices).position(0);
myColorBuf.put(colors).position(0);
myDataHasChanged = true;
}
public void renderSelf(GL10 unused) {
checkGLError("before");
// Position
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufs[0]);
if (myDataHasChanged) {
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0,
myPosBuf.capacity()
* BYTES_PER_FLOAT, myPosBuf);
}
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false,
0, 0);
GLES20.glEnableVertexAttribArray(0);
// Color
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufs[1]);
if (myDataHasChanged) {
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0,
myColorBuf.capacity()
* BYTES_PER_FLOAT, myColorBuf);
}
GLES20.glVertexAttribPointer(1, 4, GLES20.GL_FLOAT, false,
0, 0);
GLES20.glEnableVertexAttribArray(1);
// Indices
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, bufs[2]);
if (myDataHasChanged) {
GLES20.glBufferSubData(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0,
myIndexBuffer.capacity()
* BYTES_PER_INT, myIndexBuffer);
}
// Render
//GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mySize);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, myIndexBuffer
.capacity(), GLES20.GL_UNSIGNED_INT,
0);
GLES20.glDisableVertexAttribArray(0);
GLES20.glDisableVertexAttribArray(1);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
myDataHasChanged = false;
}
public void translate(float x, float y, float z) {
for (int i = 0; i < mySize; i += 3) {
positions[i] += x;
positions[i+1] += y;
positions[i+2] += z;
}
dataHasChanged();
}
public static void checkGLError(String op) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e(MyApplication.LOGTAG, op + ": glError " + error);
}
}
public void freeGL() {
final IntBuffer ib = ByteBuffer.allocateDirect(bufs.length *
BYTES_PER_INT)
.order(ByteOrder.nativeOrder())
.asIntBuffer();
GLES20.glDeleteBuffers(ib.capacity(), ib);
}
}