aboutsummaryrefslogtreecommitdiffstats
path: root/src/ru/olamedia/geom/Mesh.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/ru/olamedia/geom/Mesh.java')
-rw-r--r--src/ru/olamedia/geom/Mesh.java346
1 files changed, 346 insertions, 0 deletions
diff --git a/src/ru/olamedia/geom/Mesh.java b/src/ru/olamedia/geom/Mesh.java
new file mode 100644
index 0000000..140cc4d
--- /dev/null
+++ b/src/ru/olamedia/geom/Mesh.java
@@ -0,0 +1,346 @@
+package ru.olamedia.geom;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
+
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.texture.Texture;
+
+public class Mesh {
+ private FloatBuffer buffer;
+ private float[] data;
+ private int ptr;
+ private int vertexCount;
+ private int vertexPtr;
+ private float xOffset;
+ private float yOffset;
+ private float zOffset;
+
+ private boolean useColor;
+ private float red = 1f;
+ private float green = 1f;
+ private float blue = 1f;
+ private float alpha = 1f;
+
+ private boolean useTexture;
+ private float GLTexture;
+ private float u = 0f;
+ private float v = 0f;
+ @SuppressWarnings("unused")
+ private float uFactor = 1f;
+ @SuppressWarnings("unused")
+ private float vFactor = 1f;
+
+ private boolean wireframe = false;
+
+ private static int vertexSize = 10;
+
+ private GLArrayDataServer interleaved;
+ private HashMap<Integer, Integer> materials = new HashMap<Integer, Integer>();
+ private HashMap<Integer, GLArrayDataServer> arrays = new HashMap<Integer, GLArrayDataServer>();
+
+ public void setTexture(Texture tex) {
+ if (null != tex) {
+ setTextureSize(tex.getWidth(), tex.getHeight());
+ setGLTexture(tex.getTextureObject(null));
+ }
+ }
+
+ public void setGLTexture(int tex) {
+ this.GLTexture = tex;
+ }
+
+ @SuppressWarnings("unused")
+ private static boolean useVbo = true;
+
+ private static boolean useQuad = true;
+ private static boolean useDisplayList = false;
+ private DisplayList DL;
+
+ public Mesh(int size) {
+ vertexCount = 0;
+ data = new float[size * vertexSize];
+ // data = new float[size * vertexSize];
+ vertexPtr = 0;
+ useTexture = false;
+ useColor = false;
+ }
+
+ private static FloatBuffer generateFloatBuffer(int size) {
+ return ByteBuffer.allocateDirect(size * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
+ }
+
+ /**
+ * Reallocates an array with a new size, and copies the contents of the old
+ * array to the new array.
+ *
+ * @param oldArray
+ * the old array, to be reallocated.
+ * @param newSize
+ * the new array size.
+ * @return A new array with the same contents.
+ */
+ private static float[] resizeArray(float[] oldArray, int newSize) {
+ int oldSize = oldArray.length;
+ float[] newArray = new float[newSize];
+ int preserveLength = Math.min(oldSize, newSize);
+ if (preserveLength > 0)
+ System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
+ return newArray;
+ }
+
+ public void compact() {
+ // data = resizeArray(data, vertexCount * vertexSize);
+ int size = vertexCount * vertexSize;
+ buffer = generateFloatBuffer(size);
+ buffer.position(0);
+ buffer.put(data, 0, size);
+ data = null;
+ // calc vertex count for each material
+ for (int n = 0; n < vertexCount; n++) {
+ int tex = (int) buffer.get(vertexSize * n + 9);
+ if (!materials.containsKey(tex)) {
+ materials.put(tex, 1);
+ } else {
+ materials.put(tex, materials.get(tex) + 1);
+ }
+ }
+ for (Integer m : materials.keySet()) {
+ int matVertCount = materials.get(m);
+ final GLArrayDataServer interleaved = GLArrayDataServer.createFixedInterleaved(9, GL2.GL_FLOAT, false,
+ matVertCount, GL.GL_STATIC_DRAW);
+ interleaved.addFixedSubArray(GLPointerFunc.GL_VERTEX_ARRAY, 3, GL.GL_ARRAY_BUFFER);
+ interleaved.addFixedSubArray(GLPointerFunc.GL_COLOR_ARRAY, 4, GL.GL_ARRAY_BUFFER);
+ interleaved.addFixedSubArray(GLPointerFunc.GL_TEXTURE_COORD_ARRAY, 2, GL.GL_ARRAY_BUFFER);
+ arrays.put(m, interleaved);
+ }
+ for (int n = 0; n < vertexCount; n++) {
+ int m = (int) buffer.get(vertexSize * n + 9);
+ final GLArrayDataServer interleaved = arrays.get(m);
+ interleaved.putf(buffer.get(vertexSize * n + 0));
+ interleaved.putf(buffer.get(vertexSize * n + 1));
+ interleaved.putf(buffer.get(vertexSize * n + 2));
+ interleaved.putf(buffer.get(vertexSize * n + 3));
+ interleaved.putf(buffer.get(vertexSize * n + 4));
+ interleaved.putf(buffer.get(vertexSize * n + 5));
+ interleaved.putf(buffer.get(vertexSize * n + 6));
+ interleaved.putf(buffer.get(vertexSize * n + 7));
+ interleaved.putf(buffer.get(vertexSize * n + 8));
+ }
+ for (Integer m : materials.keySet()) {
+ final GLArrayDataServer interleaved = arrays.get(m);
+ interleaved.seal(true);
+ }
+ // interleaved.put(buffer);
+ if (vertexCount > 0) {
+ // System.out.println(interleaved);
+ }
+ /*
+ * buffer.position(0);
+ * buffer.limit(size * vertexSize);
+ * buffer.position(0);
+ * buffer.limit(vertexCount * vertexSize);
+ * buffer.compact();
+ * buffer.position(0);
+ */
+ }
+
+ public void endMesh() {
+ compact();
+ }
+
+ public void setTranslation(float x, float y, float z) {
+ xOffset = x;
+ yOffset = y;
+ zOffset = z;
+ }
+
+ public void setPoint3f(float x, float y, float z) {
+ ptr = vertexPtr * vertexSize;
+ data[ptr + 0] = x + xOffset;
+ // buffer.put(x + xOffset);
+ data[ptr + 1] = y + yOffset;
+ // buffer.put(y + yOffset);
+ data[ptr + 2] = z + zOffset;
+ // buffer.put(z + zOffset);
+ if (useColor) {
+ data[ptr + 3] = red;
+ // buffer.put(red);
+ data[ptr + 4] = green;
+ // buffer.put(green);
+ data[ptr + 5] = blue;
+ // buffer.put(blue);
+ data[ptr + 6] = alpha;
+ // buffer.put(alpha);
+ } else {
+ // buffer.put(1f);
+ // buffer.put(1f);
+ // buffer.put(1f);
+ // buffer.put(1f);
+ }
+ if (useTexture) {
+ // buffer.put(GLTexture);
+ data[ptr + 7] = u;// * uFactor;
+ // buffer.put(u);
+ data[ptr + 8] = v;// * vFactor;
+ data[ptr + 9] = GLTexture;
+ // buffer.put(v);
+ } else {
+ // buffer.put(0f);
+ // buffer.put(0f);
+ // buffer.put(0f);
+ }
+ vertexPtr++;
+ vertexCount++;
+ }
+
+ public void setColor4f(float red, float green, float blue, float alpha) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ this.alpha = alpha;
+ }
+
+ public void useColor() {
+ useColor = true;
+ }
+
+ public void useTexture() {
+ useTexture = true;
+ }
+
+ public void setUV(float u, float v) {
+ this.u = u;
+ this.v = v;
+ }
+
+ public void setTextureSize(float uSize, float vSize) {
+ this.uFactor = uSize;
+ this.vFactor = vSize;
+ }
+
+ public boolean joglIsVBOAvailable(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ return gl.isFunctionAvailable("glGenBuffers") && gl.isFunctionAvailable("glBindBuffer")
+ && gl.isFunctionAvailable("glBufferData") && gl.isFunctionAvailable("glDeleteBuffers");
+ }
+
+ public void joglCreateVBO(GLAutoDrawable drawable) {
+ @SuppressWarnings("unused")
+ GL2 gl = drawable.getGL().getGL2();
+ // gl.glInterleavedArrays(GL2.GL_T2F_C4F_N3F_V3F, stride, pointer)
+
+ }
+
+ public void joglRender(GL glx) {
+ if (vertexCount < 1) {
+ return;
+ }
+ GL2 gl;
+ GL2ES2 es2;
+ gl = glx.getGL2();
+ if (useDisplayList) {
+ gl.glEnable(GL2.GL_CULL_FACE);
+ gl.glEnable(GL2.GL_DEPTH_TEST);
+ }
+ if (wireframe) {
+ // Set wireframe mode
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_LINE);
+ } else {
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL);
+ }
+
+ if (useVbo) {
+ // es2 = glx.getGL2ES2();
+ // gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, data);
+
+ // gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
+ // gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);
+ for (Integer m : materials.keySet()) {
+ //final GLArrayDataServer interleaved = arrays.get(m);
+ arrays.get(m).enableBuffer(gl, true);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ gl.glEnable(GL2.GL_CULL_FACE);
+ gl.glEnable(GL2.GL_DEPTH_TEST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, (int) m);
+ gl.glDrawArrays(GL2.GL_QUADS, 0, arrays.get(m).getElementCount());
+ arrays.get(m).enableBuffer(gl, false);
+ }
+ /*
+ * gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
+ * gl.glVertexPointer(3, GL2.GL_FLOAT, 10, buffer);
+ * gl.glDrawArrays(GL2.GL_QUADS, 0, vertexCount);
+ * gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
+ */
+
+ } else {
+ if (useDisplayList) {
+ if (DL == null) {
+ DL = new DisplayList(glx);
+ } else {
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST);
+ DL.render();
+ return;
+ }
+ DL.begin();
+ }
+ gl.glPushAttrib(GL2.GL_ENABLE_BIT | GL2.GL_POLYGON_BIT | GL2.GL_TEXTURE_BIT);
+ if (useTexture) {
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST);
+ }
+ for (int quadI = 0; quadI < vertexCount / 4; quadI++) {
+ ptr = (quadI * 4 + 0) * vertexSize;
+ if (useTexture) {
+ gl.glBindTexture(GL.GL_TEXTURE_2D, (int) buffer.get(ptr + 9));
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
+ // gl.glDisable(GL.GL_BLEND);
+ // gl.glTexParameterf(GL.GL_TEXTURE_2D,
+ // GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, 0);
+ }
+ if (useQuad) {
+ gl.glBegin(GL2.GL_QUADS);
+ } else {
+ gl.glBegin(GL2.GL_TRIANGLE_STRIP);
+ }
+ {
+ for (int i = 0; i < 4; i++) {
+ int k = (useQuad) ? i : ((i == 2) ? 3 : (i == 3 ? 2 : i));
+ ptr = (quadI * 4 + k) * vertexSize;
+ if (useColor) {
+ gl.glColor4f(buffer.get(ptr + 3), buffer.get(ptr + 4), buffer.get(ptr + 5),
+ buffer.get(ptr + 6));
+ }
+ if (useTexture) {
+ float u = buffer.get(ptr + 7);
+ float v = buffer.get(ptr + 8);
+ gl.glTexCoord2f(u, v);
+ }
+ gl.glVertex3f(buffer.get(ptr), buffer.get(ptr + 1), buffer.get(ptr + 2));
+ }
+ }
+ gl.glEnd();
+ }
+ gl.glPopAttrib();
+ if (useDisplayList) {
+ DL.end();
+ DL.render();
+ }
+ }
+ }
+}