aboutsummaryrefslogtreecommitdiffstats
path: root/src/ru/olamedia/geom
diff options
context:
space:
mode:
Diffstat (limited to 'src/ru/olamedia/geom')
-rw-r--r--src/ru/olamedia/geom/ChunkMesh.java83
-rw-r--r--src/ru/olamedia/geom/ChunkMeshNode.java97
-rw-r--r--src/ru/olamedia/geom/ChunkMeshOctree.java95
-rw-r--r--src/ru/olamedia/geom/DisplayList.java1
-rw-r--r--src/ru/olamedia/geom/Frustum.java34
-rw-r--r--src/ru/olamedia/geom/Frustum2.java282
-rw-r--r--src/ru/olamedia/geom/ImmModeMesh.java465
-rw-r--r--src/ru/olamedia/geom/IndexedMeshBulder.java207
-rw-r--r--src/ru/olamedia/geom/Mesh.java76
-rw-r--r--src/ru/olamedia/geom/MultiMesh.java34
-rw-r--r--src/ru/olamedia/geom/SimpleQuadMesh.java145
-rw-r--r--src/ru/olamedia/geom/VoxelRaypicker.java37
12 files changed, 1502 insertions, 54 deletions
diff --git a/src/ru/olamedia/geom/ChunkMesh.java b/src/ru/olamedia/geom/ChunkMesh.java
new file mode 100644
index 0000000..3ff36df
--- /dev/null
+++ b/src/ru/olamedia/geom/ChunkMesh.java
@@ -0,0 +1,83 @@
+package ru.olamedia.geom;
+
+import ru.olamedia.olacraft.render.jogl.ChunkRangeRenderer;
+
+public class ChunkMesh {
+ private ImmModeMesh opaqueMesh;
+ private ImmModeMesh mesh;
+ private boolean isCompiled = false;
+ private boolean isValid = false;
+ private int vertexCount = 0;
+
+ private void updateVertexCount() {
+ vertexCount = 0;
+ if (null != mesh) {
+ vertexCount += mesh.getVertexCount();
+ }
+ if (null != opaqueMesh) {
+ vertexCount += opaqueMesh.getVertexCount();
+ }
+ }
+
+ public int getVertexCount() {
+ return vertexCount;
+ }
+
+ public void setMesh(ImmModeMesh m) {
+ mesh = m;
+ updateVertexCount();
+ }
+
+ public void setOpaqueMesh(ImmModeMesh m) {
+ opaqueMesh = m;
+ updateVertexCount();
+ }
+
+ public void render(int pass) {
+ if (pass == ChunkRangeRenderer.OPAQUE_PASS) {
+ if (null != opaqueMesh) {
+ opaqueMesh.draw();
+ }
+ } else {
+ if (null != mesh) {
+ mesh.draw();
+ }
+ }
+ }
+
+ public boolean isCompiled() {
+ return isCompiled;
+ }
+
+ public void setCompiled(boolean isCompiled) {
+ this.isCompiled = isCompiled;
+ }
+
+ public boolean isValid() {
+ return isValid;
+ }
+
+ public void setValid(boolean isValid) {
+ this.isValid = isValid;
+ }
+
+ public boolean isEmpty() {
+ return isValid() && (null == mesh) && (null == opaqueMesh);
+ }
+
+ public ImmModeMesh getTransparentMesh() {
+ return mesh;
+ }
+
+ public ImmModeMesh getOpaqueMesh() {
+ return opaqueMesh;
+ }
+
+ public int getOpaqueVertexCount() {
+ return null == opaqueMesh ? 0 : opaqueMesh.getVertexCount();
+ }
+
+ public int getTransparentVertexCount() {
+ return null == mesh ? 0 : mesh.getVertexCount();
+ }
+}
diff --git a/src/ru/olamedia/geom/ChunkMeshNode.java b/src/ru/olamedia/geom/ChunkMeshNode.java
new file mode 100644
index 0000000..f0593f3
--- /dev/null
+++ b/src/ru/olamedia/geom/ChunkMeshNode.java
@@ -0,0 +1,97 @@
+package ru.olamedia.geom;
+
+public class ChunkMeshNode {
+ private ChunkMesh mesh = new ChunkMesh();
+ private ChunkMesh[] leafs = new ChunkMesh[8];
+ private int vertexCount = 0;
+ private int opaqueVertexCount = 0;
+ private int transparentVertexCount = 0;
+ private int level = 1;
+ private int axisChunks = 2;
+ private int axisShift = 1;
+ private int volumeChunks = 8;
+
+ public ChunkMeshNode(int level) {
+ this.level = level;
+ this.axisChunks = (int) Math.pow(2, level);
+ this.axisShift = level;
+ this.volumeChunks = (int) Math.pow(8, level);
+ }
+
+ public void putChunkMesh(int chunkX, int chunkY, int chunkZ, ChunkMesh mesh) {
+ // id = 0..7
+ // final int id = (chunkX & )*4 + ()*2+(chunkZ & );
+ }
+
+ private void updateVertexCount() {
+ if (!mesh.isValid()) {
+ vertexCount = 0;
+ opaqueVertexCount = 0;
+ transparentVertexCount = 0;
+ for (ChunkMesh m : leafs) {
+ if (null != m) {
+ vertexCount += m.getVertexCount();
+ opaqueVertexCount += m.getOpaqueVertexCount();
+ transparentVertexCount += m.getTransparentVertexCount();
+ }
+ }
+ }
+ }
+
+ public int getVertexCount() {
+ return vertexCount;
+ }
+
+ public void render(int pass) {
+ if (mesh.isValid()) {
+ mesh.render(pass);
+ } else {
+ for (ChunkMesh m : leafs) {
+ if (null != m) {
+ m.render(pass);
+ }
+ }
+ }
+ }
+
+ public void combine() {
+ updateVertexCount();
+ if (!mesh.isValid()) {
+ if (transparentVertexCount > 0) {
+ final ImmModeMesh tMesh = ImmModeMesh.allocate(transparentVertexCount);
+ tMesh.setGLSL(true);
+ tMesh.enableColor4();
+ tMesh.enableTexCoord2();
+ tMesh.enableVertex3();
+ tMesh.beginQuads();
+ for (ChunkMesh m : leafs) {
+ if (null != m) {
+ tMesh.put(m.getTransparentMesh());
+ }
+ }
+ tMesh.end();
+ mesh.setMesh(tMesh);
+ } else {
+ mesh.setMesh(null);
+ }
+ if (opaqueVertexCount > 0) {
+ final ImmModeMesh oMesh = ImmModeMesh.allocate(opaqueVertexCount);
+ oMesh.setGLSL(true);
+ oMesh.enableColor4();
+ oMesh.enableTexCoord2();
+ oMesh.enableVertex3();
+ oMesh.beginQuads();
+ for (ChunkMesh m : leafs) {
+ if (null != m) {
+ oMesh.put(m.getOpaqueMesh());
+ }
+ }
+ oMesh.end();
+ mesh.setOpaqueMesh(oMesh);
+ } else {
+ mesh.setOpaqueMesh(null);
+ }
+ mesh.setValid(true);
+ }
+ }
+}
diff --git a/src/ru/olamedia/geom/ChunkMeshOctree.java b/src/ru/olamedia/geom/ChunkMeshOctree.java
new file mode 100644
index 0000000..1c5202c
--- /dev/null
+++ b/src/ru/olamedia/geom/ChunkMeshOctree.java
@@ -0,0 +1,95 @@
+package ru.olamedia.geom;
+
+import java.util.HashMap;
+
+import ru.olamedia.olacraft.game.Game;
+
+public class ChunkMeshOctree {
+ private HashMap<Integer, HashMap<Integer, HashMap<Integer, ChunkMeshNode>>> nodes = new HashMap<Integer, HashMap<Integer, HashMap<Integer, ChunkMeshNode>>>();
+ private static int level = 2;
+ private static int nodeAxisChunks = 4;
+ private static int nodeChunks = 64;
+ private static int levelp = 4;
+
+ private int getRenderDistance() {
+ return Game.instance.player.settings.renderDistance;
+ }
+
+ private int getCameraX() {
+ return (int) Game.instance.player.camera.getCameraX();
+ }
+
+ private int getCameraY() {
+ return (int) Game.instance.player.camera.getCameraY();
+ }
+
+ private int getCameraZ() {
+ return (int) Game.instance.player.camera.getCameraZ();
+ }
+
+ public void render(int pass) {
+ final int startX = getCameraX() - getRenderDistance() / 2;
+ final int startY = getCameraY() - getRenderDistance() / 2;
+ final int startZ = getCameraZ() - getRenderDistance() / 2;
+ final int deltaChunks = getRenderDistance() / 16;
+ // renderDistance = 256, deltaChunks = 16
+ // renderDistance = 128, deltaChunks = 8
+ // renderDistance = 64, deltaChunks = 4
+ // renderDistance = 32, deltaChunks = 2
+ // level = 1: 1 parent quadtree node (32x32x32), each root node = 8
+ // chunks
+ // level = 2: 2 parent quadtree nodes (64x64x64), each root node = 64
+ // chunks
+ final int chunkStartX = (startX / 16) / nodeAxisChunks;
+ final int chunkStartY = (startY / 16) / nodeAxisChunks;
+ final int chunkStartZ = (startZ / 16) / nodeAxisChunks;
+ for (int ix = chunkStartX; ix < nodeAxisChunks; ix++) {
+ for (int iy = chunkStartY; iy < nodeAxisChunks; iy++) {
+ for (int iz = chunkStartZ; iz < nodeAxisChunks; iz++) {
+ renderNode(ix, iy, iz, pass);
+ }
+ }
+ }
+ }
+
+ private void renderNode(int ix, int iy, int iz, int pass) {
+ if (!nodes.containsKey(ix)) {
+ return;
+ }
+ if (!nodes.get(ix).containsKey(iy)) {
+ return;
+ }
+ if (!nodes.get(ix).get(iy).containsKey(iz)) {
+ return;
+ }
+ nodes.get(ix).get(iy).get(iz).render(pass);
+ }
+
+ public void render(int x, int y, int z, int pass) {
+ final int ix = x >> 2;
+ final int iy = y >> 2;
+ final int iz = z >> 2;
+ if (!nodes.containsKey(ix)) {
+ nodes.put(ix, new HashMap<Integer, HashMap<Integer, ChunkMeshNode>>());
+ nodes.get(ix).put(iy, new HashMap<Integer, ChunkMeshNode>());
+ // nodes.get(ix).get(iy).put(iz, new ChunkMeshNode());
+ }
+ }
+
+ public void put(int chunkX, int chunkY, int chunkZ, ChunkMesh mesh) {
+ final int ix = chunkX / nodeAxisChunks;
+ final int iy = chunkY / nodeAxisChunks;
+ final int iz = chunkZ / nodeAxisChunks;
+ final int id = (chunkX & 64) * +(chunkY & 64) * +(chunkZ & 64);
+ if (!nodes.containsKey(ix)) {
+ nodes.put(ix, new HashMap<Integer, HashMap<Integer, ChunkMeshNode>>());
+ }
+ if (!nodes.get(ix).containsKey(iy)) {
+ nodes.get(ix).put(iy, new HashMap<Integer, ChunkMeshNode>());
+ }
+ if (!nodes.get(ix).get(iy).containsKey(iz)) {
+ nodes.get(ix).get(iy).put(iz, new ChunkMeshNode(level));
+ }
+ nodes.get(ix).get(iy).get(iz).combine();
+ }
+}
diff --git a/src/ru/olamedia/geom/DisplayList.java b/src/ru/olamedia/geom/DisplayList.java
index aeaffc7..eb6cf04 100644
--- a/src/ru/olamedia/geom/DisplayList.java
+++ b/src/ru/olamedia/geom/DisplayList.java
@@ -2,7 +2,6 @@ package ru.olamedia.geom;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
-import javax.media.opengl.GLAutoDrawable;
public class DisplayList {
private GL2 gl;
diff --git a/src/ru/olamedia/geom/Frustum.java b/src/ru/olamedia/geom/Frustum.java
index 2065157..1a9d58d 100644
--- a/src/ru/olamedia/geom/Frustum.java
+++ b/src/ru/olamedia/geom/Frustum.java
@@ -1,9 +1,43 @@
package ru.olamedia.geom;
+import java.nio.FloatBuffer;
+
+import org.openmali.vecmath2.Matrix4f;
+
+import com.jogamp.opengl.util.PMVMatrix;
+
//import org.openmali.spatial.bodies.Frustum;
public class Frustum extends org.openmali.spatial.bodies.Frustum {
+ protected PMVMatrix pmvMatrix;
+ protected int mvOffset;
+
public Frustum() {
super();
}
+
+ public Frustum(PMVMatrix matrix) {
+ super();
+ this.pmvMatrix = matrix;
+ }
+
+ public float[] getMatrixFloat(FloatBuffer b) {
+ if (pmvMatrix.usesBackingArray()) {
+ return b.array();
+ } else {
+ int p = b.position();
+ float[] pm = new float[16];
+ b.get(pm, p, 16);
+ b.position(p);
+ return pm;
+ }
+ }
+
+ public void compute() {
+ Matrix4f proj = new Matrix4f(getMatrixFloat(pmvMatrix.glGetPMatrixf()));
+ // proj.transpose();
+ Matrix4f modl = new Matrix4f(getMatrixFloat(pmvMatrix.glGetMviMatrixf()));
+ // modl.transpose();
+ compute(proj, modl);
+ }
}
diff --git a/src/ru/olamedia/geom/Frustum2.java b/src/ru/olamedia/geom/Frustum2.java
new file mode 100644
index 0000000..9c382b0
--- /dev/null
+++ b/src/ru/olamedia/geom/Frustum2.java
@@ -0,0 +1,282 @@
+package ru.olamedia.geom;
+
+import java.nio.FloatBuffer;
+
+import org.ode4j.ode.internal.gimpact.GimGeometry.aabb3f;
+import org.openmali.spatial.bodies.Box;
+import org.openmali.spatial.bodies.Classifier;
+import org.openmali.vecmath2.Matrix4f;
+
+import com.jogamp.opengl.math.FloatUtil;
+import com.jogamp.opengl.math.geom.AABBox;
+import com.jogamp.opengl.util.PMVMatrix;
+
+public class Frustum2 {
+ protected Plane[] planes = new Plane[6];
+ protected PMVMatrix pmvMatrix;
+ protected FloatBuffer pmv = FloatBuffer.allocate(16);
+ protected float[] mvp = new float[16];
+ protected int pmvOffset;
+
+ public Frustum2() {
+ for (int i = 0; i < 6; ++i) {
+ planes[i] = new Plane();
+ }
+ }
+
+ public Frustum2(PMVMatrix matrix) {
+ setMatrix(matrix);
+ for (int i = 0; i < 6; ++i) {
+ planes[i] = new Plane();
+ }
+ }
+
+ public void setMatrix(PMVMatrix matrix) {
+ this.pmvMatrix = matrix;
+ // pmv = pmvMatrix.glGetPMvMatrixf();
+ // pmvOffset = pmv.position();
+ makePmvMatrix();
+ }
+
+ protected Matrix4f proj;
+ protected Matrix4f modl;
+
+ private static FloatBuffer b;
+ private static int bOffset;
+
+ private static float f(int offset) {
+ return b.get(bOffset + offset);
+ }
+
+ public static Matrix4f getMatrix4f(FloatBuffer buf) {
+ b = buf;
+ bOffset = b.position();
+ return new Matrix4f(f(0), f(1), f(2), f(3), f(4), f(5), f(6)/* 12 */, f(7), f(8), f(9), f(10), f(11), f(12),
+ f(13), f(14), f(15));
+ }
+
+ public void makePmvMatrix() {
+ FloatUtil.multMatrixf(pmvMatrix.glGetPMatrixf(), pmvMatrix.glGetMvMatrixf(), mvp, 0);
+ getMatrix4f(pmvMatrix.glGetPMatrixf()).mul(getMatrix4f(pmvMatrix.glGetMvMatrixf())).writeToBuffer(pmv, true,
+ false);
+ }
+
+ protected class Vector3f {
+ public float x;
+ public float y;
+ public float z;
+
+ @Override
+ public String toString() {
+ return "{" + x + "," + y + "," + z + "}";
+ }
+ }
+
+ protected class Plane {
+ public Vector3f n = new Vector3f();
+ public float d;
+
+ public final float distanceTo(float x, float y, float z) {
+ return (n.x * x) + (n.y * y) + (n.z * z) + d;
+ }
+
+ @Override
+ public String toString() {
+ return "Plane[" + n + ", " + d + "]";
+ }
+ }
+
+ protected float[] getMatrixFloat(FloatBuffer b) {
+ if (pmvMatrix.usesBackingArray()) {
+ return b.array();
+ } else {
+ int p = b.position();
+ float[] pm = new float[16];
+ b.get(pm, p, 16);
+ b.position(p);
+ return pm;
+ }
+ }
+
+ protected float m(int a) {
+ return mvp[a];
+ // return pmv.get(a);
+ }
+
+ private static final boolean isInside(Plane p, AABBox box) {
+ final float[] low = box.getLow();
+ final float[] high = box.getHigh();
+ if (p.distanceTo(low[0], low[1], low[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(high[0], low[1], low[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(low[0], high[1], low[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(high[0], high[1], low[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(low[0], low[1], high[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(high[0], low[1], high[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(low[0], high[1], high[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(high[0], high[1], high[2]) > 0.0f)
+ return (true);
+
+ return (false);
+ }
+
+ /**
+ * Quick check to see if an orthogonal bounding box is inside the frustum
+ */
+ public final boolean isOutside(AABBox box) {
+
+ // if all points are behind 1 specific plane, we are out
+ // if we are in with all points, then we are fully in
+ for (int p = 0; p < 6; ++p) {
+ if (!isInside(planes[p], box)) {
+ return true;
+ }
+ }
+
+ // so if iTotalIn is 6, then all are inside the view
+ // if(iTotalIn == 6)
+ // return(IN);
+
+ // we must be partly in then otherwise
+ return false;
+ // for (int i = 0; i < 3; ++i) {
+ // if (!quickClassify(planes[i], box))
+ // return true;
+ // }
+ //
+ // // We make no attempt to determine whether it's fully inside or not.
+ // return false;
+ }
+
+ protected float[] mat = new float[16];
+
+ public void extractFrustumPlanes(boolean normalize) {
+ // Left: [30+00, 31+01, 32+02, 33+03]
+ // comboMatrix.m[12] + comboMatrix.m[0];
+
+ planes[0].n.x = m(12) + m(0);
+ planes[0].n.y = m(13) + m(1);
+ planes[0].n.z = m(14) + m(2);
+ planes[0].d = m(15) + m(3);
+
+ // Right: [30-00, 31-01, 32-02, 33-03]
+
+ planes[1].n.x = m(12) - m(0);
+ planes[1].n.y = m(13) - m(1);
+ planes[1].n.z = m(14) - m(2);
+ planes[1].d = m(15) - m(3);
+
+ // Bottom: [30+10, 31+11, 32+12, 33+13]
+
+ planes[2].n.x = m(12) + m(4);
+ planes[2].n.y = m(13) + m(5);
+ planes[2].n.z = m(14) + m(6);
+ planes[2].d = m(15) + m(7);
+
+ // Top: [30-10, 31-11, 32-12, 33-13]
+
+ planes[3].n.x = m(12) - m(4);
+ planes[3].n.y = m(13) - m(5);
+ planes[3].n.z = m(14) - m(6);
+ planes[3].d = m(15) - m(7);
+
+ // Far: [30-20, 31-21, 32-22, 33-23]
+
+ planes[5].n.x = m(12) - m(8);
+ planes[5].n.y = m(13) - m(9);
+ planes[5].n.z = m(14) - m(10);
+ planes[5].d = m(15) - m(11);
+
+ // Near: [30+20, 31+21, 32+22, 33+23]
+
+ planes[4].n.x = m(12) + m(8);
+ planes[4].n.y = m(13) + m(9);
+ planes[4].n.z = m(14) + m(10);
+ planes[4].d = m(15) + m(11);
+
+ // Normalize
+ if (normalize) {
+ for (int i = 0; i < 6; ++i) {
+ double mag = Math.sqrt(planes[i].n.x * planes[i].n.x + planes[i].n.y * planes[i].n.y + planes[i].n.z
+ * planes[i].n.z);
+
+ planes[i].n.x /= mag;
+ planes[i].n.y /= mag;
+ planes[i].n.z /= mag;
+ planes[i].d /= mag;
+ }
+ }
+ }
+
+ public void extractFrustumPlanes2(boolean normalize) {
+ // Left: [30+00, 31+01, 32+02, 33+03]
+ // comboMatrix.m[12] + comboMatrix.m[0];
+
+ planes[0].n.x = m(3) + m(0);
+ planes[0].n.y = m(7) + m(4);
+ planes[0].n.z = m(11) + m(8);
+ planes[0].d = m(15) + m(12);
+
+ // Right: [30-00, 31-01, 32-02, 33-03]
+
+ planes[1].n.x = m(3) - m(0);
+ planes[1].n.y = m(7) - m(4);
+ planes[1].n.z = m(11) - m(8);
+ planes[1].d = m(15) - m(12);
+
+ // Bottom: [30+10, 31+11, 32+12, 33+13]
+
+ planes[2].n.x = m(3) + m(1);
+ planes[2].n.y = m(7) + m(5);
+ planes[2].n.z = m(11) + m(9);
+ planes[2].d = m(15) + m(13);
+
+ // Top: [30-10, 31-11, 32-12, 33-13]
+
+ planes[3].n.x = m(3) - m(1);
+ planes[3].n.y = m(7) - m(5);
+ planes[3].n.z = m(11) - m(9);
+ planes[3].d = m(15) - m(13);
+
+ // Far: [30-20, 31-21, 32-22, 33-23]
+
+ planes[5].n.x = m(3) - m(2);
+ planes[5].n.y = m(7) - m(6);
+ planes[5].n.z = m(11) - m(10);
+ planes[5].d = m(15) - m(14);
+
+ // Near: [30+20, 31+21, 32+22, 33+23]
+
+ planes[4].n.x = m(3) + m(2);
+ planes[4].n.y = m(7) + m(6);
+ planes[4].n.z = m(11) + m(10);
+ planes[4].d = m(15) + m(14);
+
+ // Normalize
+ if (normalize) {
+ for (int i = 0; i < 6; ++i) {
+ double mag = Math.sqrt(planes[i].n.x * planes[i].n.x + planes[i].n.y * planes[i].n.y + planes[i].n.z
+ * planes[i].n.z);
+
+ planes[i].n.x /= mag;
+ planes[i].n.y /= mag;
+ planes[i].n.z /= mag;
+ planes[i].d /= mag;
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "f2\n" + m(0) + " " + m(1) + " " + m(2) + " " + m(3) + "\n" + m(4) + " " + m(5) + " " + m(6) + " "
+ + m(7) + "\n" + m(8) + " " + m(9) + " " + m(10) + " " + m(11) + "\n" + m(12) + " " + m(13) + " "
+ + m(14) + " " + m(15) + " " + "Frustum2[" + planes[0] + ", " + planes[1] + ", " + planes[2] + ", "
+ + planes[3] + ", " + planes[4] + ", " + planes[5] + "]";
+ }
+}
diff --git a/src/ru/olamedia/geom/ImmModeMesh.java b/src/ru/olamedia/geom/ImmModeMesh.java
new file mode 100644
index 0000000..4ce419b
--- /dev/null
+++ b/src/ru/olamedia/geom/ImmModeMesh.java
@@ -0,0 +1,465 @@
+package ru.olamedia.geom;
+
+import java.nio.Buffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.util.GLArrayDataServer;
+
+public class ImmModeMesh {
+ private IndexedMeshBulder indexed = IndexedMeshBulder.instance;
+ private boolean useIndexed = false;
+ protected GLArrayDataServer interleaved;
+ protected FloatBuffer buf;
+ private int vertexCount = 0;
+ protected int mode = GL2.GL_QUADS;
+ protected boolean isGLSL = false;
+ protected byte vertexComponent = 0;
+ protected byte normalComponent = 0;
+ protected byte colorComponent = 0;
+ protected byte texCoordComponent = 0;
+ protected float red = 1;
+ protected float green = 1;
+ protected float blue = 1;
+ protected float alpha = 1;
+ protected float offsetX = 0;
+ protected float offsetY = 0;
+ protected float offsetZ = 0;
+ protected float x = 0;
+ protected float y = 0;
+ protected float z = 0;
+ protected float nx = 0;
+ protected float ny = 0;
+ protected float nz = 0;
+ protected float u = 0;
+ protected float v = 0;
+ protected boolean isFinished = false;
+ protected boolean isServer = false;
+
+ public void setGLSL(boolean glsl) {
+ this.isGLSL = glsl;
+ }
+
+ public void makeServer() {
+ if (null == interleaved) {
+ if (isGLSL) {
+ allocateGLSLBuffer();
+ } else {
+ allocateFixedBuffer();
+ }
+ if (null != buf) {
+ buf.flip();
+ interleaved.put(buf);
+ buf.clear();
+ buf = null;
+ }
+ interleaved.seal(true);
+ isServer = true;
+ }
+ }
+
+ public Buffer getBuffer() {
+ if (!isServer) {
+ return buf;
+ }
+ return interleaved.getBuffer();
+ }
+
+ public void put(ImmModeMesh mesh) {
+ if (isServer) {
+ final FloatBuffer b = (FloatBuffer) mesh.getBuffer();
+ b.rewind();
+ interleaved.put(b);
+ } else {
+ final FloatBuffer b = (FloatBuffer) mesh.getBuffer();
+ b.rewind();
+ if (null == buf) {
+ allocateBuffer();
+ }
+ growBufferIfNecessary(b.remaining());
+ buf.put(b);
+ }
+ vertexCount += mesh.getVertexCount();
+ }
+
+ public void destroy() {
+ if (isServer) {
+ interleaved.destroy(GLContext.getCurrentGL().getGL2ES2());
+ interleaved = null;
+ } else {
+ if (null != buf) {
+ buf.clear();
+ buf = null;
+ }
+ }
+ }
+
+ public int getComponents() {
+ return vertexComponent + normalComponent + colorComponent + texCoordComponent;
+ }
+
+ protected void allocateBuffer() {
+ if (!isServer) {
+ buf = Buffers.newDirectFloatBuffer(getComponents() * getVertexCount());
+ } else {
+ if (isGLSL) {
+ allocateGLSLBuffer();
+ } else {
+ allocateFixedBuffer();
+ }
+ }
+ }
+
+ protected final void growBuffer(int additionalElements) {
+ final int osize = (buf != null) ? buf.capacity() : 0;
+ final int nsize = osize + (additionalElements * getComponents());
+ FloatBuffer newFBuffer = Buffers.newDirectFloatBuffer(nsize);
+ if (buf != null) {
+ buf.flip();
+ newFBuffer.put((FloatBuffer) buf);
+ }
+ buf = newFBuffer;
+ }
+
+ protected void allocateFixedBuffer() {
+ final GLArrayDataServer buf = GLArrayDataServer.createFixedInterleaved(getComponents(), GL.GL_FLOAT, false,
+ getVertexCount(), GL.GL_STATIC_DRAW);
+ if (vertexComponent != 0) {
+ buf.addFixedSubArray(GLPointerFunc.GL_VERTEX_ARRAY, vertexComponent, GL.GL_ARRAY_BUFFER);
+ }
+ if (colorComponent != 0) {
+ buf.addFixedSubArray(GLPointerFunc.GL_COLOR_ARRAY, colorComponent, GL.GL_ARRAY_BUFFER);
+ }
+ if (normalComponent != 0) {
+ buf.addFixedSubArray(GLPointerFunc.GL_NORMAL_ARRAY, normalComponent, GL.GL_ARRAY_BUFFER);
+ }
+ if (texCoordComponent != 0) {
+ buf.addFixedSubArray(GLPointerFunc.GL_TEXTURE_COORD_ARRAY, texCoordComponent, GL.GL_ARRAY_BUFFER);
+ }
+ interleaved = buf;
+ }
+
+ protected void allocateGLSLBuffer() {
+ final GLArrayDataServer buf = GLArrayDataServer.createGLSLInterleaved(getComponents(), GL.GL_FLOAT, false,
+ getVertexCount(), GL.GL_STATIC_DRAW);
+ if (vertexComponent != 0) {
+ buf.addGLSLSubArray("mesh_vertices", vertexComponent, GL.GL_ARRAY_BUFFER);
+ }
+ if (colorComponent != 0) {
+ buf.addGLSLSubArray("mesh_colors", colorComponent, GL.GL_ARRAY_BUFFER);
+ }
+ if (normalComponent != 0) {
+ buf.addGLSLSubArray("mesh_normal", normalComponent, GL.GL_ARRAY_BUFFER);
+ }
+ if (texCoordComponent != 0) {
+ buf.addGLSLSubArray("mesh_texCoord", texCoordComponent, GL.GL_ARRAY_BUFFER);
+ }
+ buf.rewind();
+ interleaved = buf;
+ }
+
+ protected final boolean growBufferIfNecessary(int spare) {
+ if (buf == null || buf.remaining() < spare) {
+ growBuffer(spare);
+ return true;
+ }
+ return false;
+ }
+
+ private void putf(float f) {
+ if (isServer) {
+ if (null == interleaved) {
+ allocateBuffer();
+ }
+ interleaved.putf(f);
+ } else {
+ // buf.put(f);
+ growBufferIfNecessary(256);
+ Buffers.putf(buf, f);
+ }
+ }
+
+ protected void putVertex() {
+ if (vertexComponent > 0) {
+ putf(x);
+ putf(y);
+ if (vertexComponent > 2) {
+ putf(z);
+ }
+ }
+ if (colorComponent > 0) {
+ putf(red);
+ putf(green);
+ putf(blue);
+ if (colorComponent > 3) {
+ putf(alpha);
+ }
+ }
+ if (normalComponent != 0) {
+ putf(nx);
+ putf(ny);
+ if (normalComponent > 2) {
+ putf(nz);
+ }
+ }
+ if (texCoordComponent > 0) {
+ putf(u);
+ putf(v);
+ }
+ }
+
+ public void getIndexed() {
+
+ }
+
+ public void enableColor3() {
+ colorComponent = 3;
+ if (useIndexed) {
+ indexed.setColorComponent(colorComponent);
+ }
+ }
+
+ public void enableColor4() {
+ colorComponent = 4;
+ if (useIndexed) {
+ indexed.setColorComponent(colorComponent);
+ }
+ }
+
+ public void enableVertex2() {
+ vertexComponent = 2;
+ if (useIndexed) {
+ indexed.setVertexComponent(vertexComponent);
+ }
+ }
+
+ public void enableVertex3() {
+ vertexComponent = 3;
+ if (useIndexed) {
+ indexed.setVertexComponent(vertexComponent);
+ }
+ }
+
+ public void enableNormal3() {
+ normalComponent = 3;
+ if (useIndexed) {
+ indexed.setNormalComponent(normalComponent);
+ }
+ }
+
+ public void enableTexCoord2() {
+ texCoordComponent = 2;
+ if (useIndexed) {
+ indexed.setUVComponent(texCoordComponent);
+ }
+ }
+
+ public void enableTexCoord4() {
+ texCoordComponent = 4;
+ if (useIndexed) {
+ indexed.setUVComponent(texCoordComponent);
+ }
+ }
+
+ public void glBegin(int mode) {
+ this.mode = mode;
+ allocateBuffer();
+ if (useIndexed) {
+ indexed.reset();
+ }
+ }
+
+ public void beginQuads() {
+ glBegin(GL2.GL_QUADS);
+ }
+
+ public void beginTriangles() {
+ glBegin(GL2.GL_TRIANGLES);
+ }
+
+ public void glEnd() {
+ if (useIndexed) {
+ indexed.end();
+ final IntBuffer ind = indexed.getIndices();
+ System.out.println("glEnd: " + vertexCount + " / " + ind.limit());
+ }
+ if (isServer) {
+ if (null == interleaved) {
+ allocateBuffer();
+ }
+ interleaved.seal(true);
+ }
+ isFinished = true;
+ }
+
+ public void end() {
+ glEnd();
+ }
+
+ public void setServer(boolean isServer) {
+ this.isServer = isServer;
+ }
+
+ public int getVBOName() {
+ return interleaved.getVBOName();
+ }
+
+ public int getMode() {
+ return mode;
+ }
+
+ public boolean draw() {
+ if (!isFinished) {
+ return false;
+ }
+ makeServer();
+ final GL2ES2 gl = GLContext.getCurrentGL().getGL2ES2();
+ interleaved.enableBuffer(gl, true);
+ // Вывод геометрии VBO выполняется такими же функциями, как и при
+ // использовании буфера в оперативной памяти.
+ gl.glDrawArrays(mode, 0, interleaved.getElementCount());
+ interleaved.enableBuffer(gl, false);
+ //gl.glFlush();
+ return true;
+ }
+
+ public void setColor(float red, float green, float blue) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ if (useIndexed) {
+ indexed.glColor3f(red, green, blue);
+ }
+ }
+
+ public void setColor(float red, float green, float blue, float alpha) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ this.alpha = alpha;
+ if (useIndexed) {
+ indexed.glColor4f(red, green, blue, alpha);
+ }
+ }
+
+ public void glColor3f(float red, float green, float blue) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ if (useIndexed) {
+ indexed.glColor3f(red, green, blue);
+ }
+ }
+
+ public void glColor4f(float red, float green, float blue, float alpha) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ this.alpha = alpha;
+ if (useIndexed) {
+ indexed.glColor4f(red, green, blue, alpha);
+ }
+ }
+
+ public void glVertex3f(float x, float y, float z) {
+ this.x = offsetX + x;
+ this.y = offsetY + y;
+ this.z = offsetZ + z;
+ putVertex();
+ if (useIndexed) {
+ indexed.glVertex3f(x, y, z);
+ }
+ }
+
+ public void glVertex2f(float x, float y) {
+ this.x = offsetX + x;
+ this.y = offsetY + y;
+ putVertex();
+ if (useIndexed) {
+ indexed.glVertex2f(x, y);
+ }
+ }
+
+ public void setUV(float u, float v) {
+ this.u = u;
+ this.v = v;
+ if (useIndexed) {
+ indexed.setUV(u, v);
+ }
+ }
+
+ public void glTexCoord2f(float u, float v) {
+ this.u = u;
+ this.v = v;
+ if (useIndexed) {
+ indexed.setUV(u, v);
+ }
+ }
+
+ public void glRectf(float x1, float y1, float x2, float y2) {
+ glVertex2f(x1, y1);
+ glVertex2f(x1, y2);
+ glVertex2f(x2, y2);
+ glVertex2f(x2, y1);
+ }
+
+ protected ImmModeMesh(int vertexCount) {
+ this.setVertexCount(vertexCount);
+ }
+
+ public static ImmModeMesh allocate(int elementCount) {
+ return new ImmModeMesh(elementCount);
+ }
+
+ public int getVertexCount() {
+ return vertexCount;
+ }
+
+ public void setVertexCount(int vertexCount) {
+ this.vertexCount = vertexCount;
+ }
+
+ public void glTranslate(float x, float y, float z) {
+ offsetX = x;
+ offsetY = y;
+ offsetZ = z;
+ if (useIndexed) {
+ indexed.glTranslate(x, y, z);
+ }
+ }
+
+ public void dispose() {
+ if (null != interleaved) {
+ interleaved.destroy(GLContext.getCurrentGL().getGL2ES2());
+ }
+ if (null != buf) {
+ buf.clear();
+ buf = null;
+ }
+ }
+
+ public void compact() {
+ if (null != interleaved) {
+ if (null != interleaved.getBuffer()) {
+ interleaved.getBuffer().flip();
+ ((FloatBuffer) interleaved.getBuffer()).compact();
+ }
+ }
+ }
+
+ public void glNormal3f(float nx, float ny, float nz) {
+ this.nx = nx;
+ this.ny = ny;
+ this.nz = nz;
+ if (useIndexed) {
+ indexed.glNormal3f(nx, ny, nz);
+ }
+ }
+}
diff --git a/src/ru/olamedia/geom/IndexedMeshBulder.java b/src/ru/olamedia/geom/IndexedMeshBulder.java
new file mode 100644
index 0000000..ec66305
--- /dev/null
+++ b/src/ru/olamedia/geom/IndexedMeshBulder.java
@@ -0,0 +1,207 @@
+package ru.olamedia.geom;
+
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+public class IndexedMeshBulder {
+ protected static IndexedMeshBulder instance = new IndexedMeshBulder();
+ protected IntBuffer indices = IntBuffer.allocate(4096);
+ protected FloatBuffer vertex = FloatBuffer.allocate(4096 * 3);
+ protected FloatBuffer color = FloatBuffer.allocate(4096 * 4);
+ protected FloatBuffer normal = FloatBuffer.allocate(4096 * 3);
+ protected FloatBuffer uv = FloatBuffer.allocate(4096 * 2);
+ protected int indexCount = 0;
+ protected int vertexCount = 0;
+ protected int colorCount = 0;
+ protected int normalCount = 0;
+ protected int uvCount = 0;
+
+ protected byte vertexComponent = 0;
+ protected byte normalComponent = 0;
+ protected byte colorComponent = 0;
+ protected byte uvComponent = 0;
+
+ protected float red = 1;
+ protected float green = 1;
+ protected float blue = 1;
+ protected float alpha = 1;
+ protected float offsetX = 0;
+ protected float offsetY = 0;
+ protected float offsetZ = 0;
+ protected float x = 0;
+ protected float y = 0;
+ protected float z = 0;
+ protected float nx = 0;
+ protected float ny = 0;
+ protected float nz = 0;
+ protected float u = 0;
+ protected float v = 0;
+
+ public void reset() {
+ vertex.clear();
+ color.clear();
+ normal.clear();
+ uv.clear();
+ indices.clear();
+ vertexCount = indexCount = vertexComponent = colorComponent = normalComponent = uvComponent = 0;
+ }
+
+ public void end(){
+ indices.flip();
+ vertex.flip();
+ color.flip();
+ normal.flip();
+ uv.flip();
+ }
+
+ public IntBuffer getIndices() {
+ IntBuffer ind = IntBuffer.allocate(indices.limit());
+ ind.put(indices);
+ return ind;
+ }
+
+ private boolean _sameVertex(int i) {
+ if (vertexComponent != 0) {
+ if (vertex.get(i * vertexComponent) == z) {
+ if (vertex.get(i * vertexComponent + 1) == y) {
+ if ((vertexComponent == 2) || (vertex.get(i * vertexComponent) == z)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean _sameColor(int i) {
+ if (colorComponent != 0) {
+ if (color.get(i * colorComponent) == red) {
+ if (color.get(i * colorComponent + 1) == green) {
+ if (color.get(i * colorComponent + 2) == blue) {
+ if ((colorComponent == 2) || (color.get(i * colorComponent) == alpha)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean _sameUV(int i) {
+ if (uvComponent != 0) {
+ if (uv.get(i * uvComponent) == u) {
+ if (uv.get(i * uvComponent + 1) == v) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private void _addVertex() {
+ if (vertexComponent != 0) {
+ vertex.put(x);
+ vertex.put(y);
+ if (vertexComponent > 2) {
+ vertex.put(z);
+ }
+ }
+ if (colorComponent != 0) {
+ color.put(red);
+ color.put(green);
+ color.put(blue);
+ if (colorComponent > 3) {
+ color.put(alpha);
+ }
+ }
+ if (normalComponent != 0) {
+ normal.put(nx);
+ normal.put(ny);
+ if (normalComponent > 2) {
+ normal.put(nz);
+ }
+ }
+ if (uvComponent != 0) {
+ uv.put(u);
+ uv.put(v);
+ }
+ indices.put(indexCount);
+ indexCount++;
+ }
+
+ private void putVertex() {
+ vertexCount++;
+ for (int i = 0; i < vertexCount; i++) {
+ if (_sameVertex(i) && _sameColor(i) && _sameUV(i)) {
+ indices.put(i);
+ return;
+ }
+ }
+ _addVertex();
+ }
+
+ public void setVertexComponent(byte vertexComponent) {
+ this.vertexComponent = vertexComponent;
+ }
+
+ public void setNormalComponent(byte normalComponent) {
+ this.normalComponent = normalComponent;
+ }
+
+ public void setColorComponent(byte colorComponent) {
+ this.colorComponent = colorComponent;
+ }
+
+ public void setUVComponent(byte uvComponent) {
+ this.uvComponent = uvComponent;
+ }
+
+ private int comps() {
+ return vertexComponent + normalComponent + colorComponent + uvComponent;
+ }
+
+ public void glTranslate(float x, float y, float z) {
+ offsetX = x;
+ offsetY = y;
+ offsetZ = z;
+ }
+
+ public void glColor3f(float red, float green, float blue) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ }
+
+ public void glColor4f(float red, float green, float blue, float alpha) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ this.alpha = alpha;
+ }
+
+ public void glVertex3f(float x, float y, float z) {
+ this.x = offsetX + x;
+ this.y = offsetY + y;
+ this.z = offsetZ + z;
+ putVertex();
+ }
+
+ public void glVertex2f(float x, float y) {
+ this.x = offsetX + x;
+ this.y = offsetY + y;
+ putVertex();
+ }
+
+ public void glNormal3f(float nx, float ny, float nz) {
+ this.nx = nx;
+ this.ny = ny;
+ this.nz = nz;
+ }
+
+ public void setUV(float u, float v) {
+ this.u = u;
+ this.v = v;
+ }
+
+}
diff --git a/src/ru/olamedia/geom/Mesh.java b/src/ru/olamedia/geom/Mesh.java
index bda53b9..7e25666 100644
--- a/src/ru/olamedia/geom/Mesh.java
+++ b/src/ru/olamedia/geom/Mesh.java
@@ -10,12 +10,52 @@ import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLContext;
-import javax.media.opengl.fixedfunc.GLPointerFunc;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLUniformData;
+import javax.vecmath.Point3f;
+
+import ru.olamedia.asset.Shader;
+import ru.olamedia.olacraft.game.Game;
import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderState;
import com.jogamp.opengl.util.texture.Texture;
public class Mesh {
+ private static Shader shader = null;
+ private static GLUniformData pmvMatrixUniform;
+ private static GLUniformData sunColor;
+
+ private static Shader getShader() {
+ if (null == shader) {
+ shader = new Shader();
+ shader.compile();
+ GL2ES2 gl = GLContext.getCurrentGL().getGL2ES2();
+ ShaderState state = shader.getState();
+ PMVMatrix pmvMatrix = Game.client.getScene().getPmvMatrix();
+ state.attachObject("pmvMatrix", pmvMatrix);
+ pmvMatrixUniform = new GLUniformData("pmvMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+ state.ownUniform(pmvMatrixUniform);
+ state.uniform(gl, pmvMatrixUniform);
+
+ state.attachObject("sunColor", sunColor);
+ sunColor = new GLUniformData("sunColor", 4, Game.client.getScene().dayTime.sunColor);
+ state.ownUniform(sunColor);
+ state.uniform(gl, sunColor);
+
+ // if (!state.uniform(gl, new GLUniformData("sunColor", 4,
+ // Game.client.getScene().time.sunColor))) {
+ // throw new GLException("Error setting sunColor in shader: " +
+ // state);
+ // }
+ if (!state.uniform(gl, new GLUniformData("mesh_ActiveTexture", 0))) {
+ throw new GLException("Error setting mesh_ActiveTexture in shader: " + state);
+ }
+ }
+ return shader;
+ }
+
public void invalidate() {
buffer = null;
data = null;
@@ -103,11 +143,11 @@ public class Mesh {
}
for (Integer m : materials.keySet()) {
int matVertCount = materials.get(m);
- final GLArrayDataServer interleaved = GLArrayDataServer.createFixedInterleaved(9, GL2.GL_FLOAT, false,
+ final GLArrayDataServer interleaved = GLArrayDataServer.createGLSLInterleaved(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);
+ interleaved.addGLSLSubArray("mesh_vertices", 3, GL.GL_ARRAY_BUFFER);
+ interleaved.addGLSLSubArray("mesh_colors", 4, GL.GL_ARRAY_BUFFER);
+ interleaved.addGLSLSubArray("mesh_texCoord", 2, GL.GL_ARRAY_BUFFER);
arrays.put(m, interleaved);
}
for (int n = 0; n < vertexCount; n++) {
@@ -143,6 +183,10 @@ public class Mesh {
zOffset = z;
}
+ public void setPoint3f(Point3f point) {
+ setPoint3f(point.x, point.y, point.z);
+ }
+
public void setPoint3f(float x, float y, float z) {
ptr = vertexPtr * vertexSize;
data[ptr + 0] = x + xOffset;
@@ -225,19 +269,24 @@ public class Mesh {
return;
}
GL glx = GLContext.getCurrentGL();
- if (true){
- GL2 gl = glx.getGL2();
- gl.glShadeModel(GL2.GL_FLAT);
- }
if (useVbo) {
GL2ES2 gl = glx.getGL2ES2();
// GL2 gl = glx.getGL2();
+ getShader().enable();
+ Game.client.getScene().dayTime.getClearColor();
+ getShader().getState().uniform(gl, pmvMatrixUniform);
+ getShader().getState().uniform(gl, sunColor);
for (Integer m : materials.keySet()) {
-
- gl.glEnable(GL.GL_TEXTURE_2D);
+ gl.glActiveTexture(GL.GL_TEXTURE0);
gl.glBindTexture(GL.GL_TEXTURE_2D, (int) m);
- 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_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_MAG_FILTER, GL.GL_LINEAR);
+ // gl.glTexParameteri(GL.GL_TEXTURE_2D,
+ // GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR);
arrays.get(m).enableBuffer(gl, true);
gl.glEnable(GL.GL_CULL_FACE);
gl.glEnable(GL.GL_DEPTH_TEST);
@@ -246,6 +295,7 @@ public class Mesh {
arrays.get(m).enableBuffer(gl, false);
// System.exit(0);
}
+ getShader().disable();
} else {
GL2 gl = glx.getGL2();
if (useDisplayList) {
diff --git a/src/ru/olamedia/geom/MultiMesh.java b/src/ru/olamedia/geom/MultiMesh.java
new file mode 100644
index 0000000..98becd1
--- /dev/null
+++ b/src/ru/olamedia/geom/MultiMesh.java
@@ -0,0 +1,34 @@
+package ru.olamedia.geom;
+
+import java.nio.IntBuffer;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL3;
+import javax.media.opengl.GLContext;
+
+public class MultiMesh {
+ private IntBuffer vboIndices;
+ private IntBuffer counts;
+ private int mode = GL2.GL_TRIANGLES;
+
+ public void clear() {
+ vboIndices.clear();
+ }
+
+ public void add(ImmModeMesh mesh) {
+ vboIndices.put(mesh.getVBOName());
+ }
+
+ public void draw() {
+ final GL3 gl = GLContext.getCurrentGL().getGL3();
+ }
+
+ public MultiMesh(int meshCount) {
+ vboIndices = IntBuffer.allocate(meshCount);
+ }
+
+ public static MultiMesh allocate(int meshCount) {
+ return new MultiMesh(meshCount);
+ }
+}
diff --git a/src/ru/olamedia/geom/SimpleQuadMesh.java b/src/ru/olamedia/geom/SimpleQuadMesh.java
index ad3c27c..c28c799 100644
--- a/src/ru/olamedia/geom/SimpleQuadMesh.java
+++ b/src/ru/olamedia/geom/SimpleQuadMesh.java
@@ -1,9 +1,28 @@
package ru.olamedia.geom;
+import javax.vecmath.Point3f;
+
+import ru.olamedia.asset.SpriteRectangle;
+
public class SimpleQuadMesh extends Mesh {
public boolean restart = true;
+ public Point3f bottomLeftBack = new Point3f();
+ public Point3f bottomLeftFront = new Point3f();
+ public Point3f bottomRightBack = new Point3f();
+ public Point3f bottomRightFront = new Point3f();
+
+ public Point3f topLeftBack = new Point3f();
+ public Point3f topLeftFront = new Point3f();
+ public Point3f topRightBack = new Point3f();
+ public Point3f topRightFront = new Point3f();
+
+ public float textureTop = 1;
+ public float textureBottom = 0;
+ public float textureLeft = 0;
+ public float textureRight = 1;
+
public void restart() {
restart = true;
}
@@ -16,108 +35,154 @@ public class SimpleQuadMesh extends Mesh {
super(size * 4);
}
- private void addBottomLeftBackVertex() {
- setPoint3f(-0.5f, -0.5f, -0.5f);
+ public void addBottomLeftBackVertex() {
+ setPoint3f(bottomLeftBack);
}
- private void addBottomLeftFrontVertex() {
- setPoint3f(-0.5f, -0.5f, 0.5f);
+ public void addBottomLeftFrontVertex() {
+ setPoint3f(bottomLeftFront);
}
- private void addBottomRightBackVertex() {
- setPoint3f(0.5f, -0.5f, -0.5f);
+ public void addBottomRightBackVertex() {
+ setPoint3f(bottomRightBack);
}
- private void addBottomRightFrontVertex() {
- setPoint3f(0.5f, -0.5f, 0.5f);
+ public void addBottomRightFrontVertex() {
+ setPoint3f(bottomRightFront);
}
- private void addTopLeftBackVertex() {
- setPoint3f(-0.5f, 0.5f, -0.5f);
+ public void addTopLeftBackVertex() {
+ setPoint3f(topLeftBack);
}
- private void addTopLeftFrontVertex() {
- setPoint3f(-0.5f, 0.5f, 0.5f);
+ public void addTopLeftFrontVertex() {
+ setPoint3f(topLeftFront);
}
- private void addTopRightBackVertex() {
- setPoint3f(0.5f, 0.5f, -0.5f);
+ public void addTopRightBackVertex() {
+ setPoint3f(topRightBack);
}
- private void addTopRightFrontVertex() {
- setPoint3f(0.5f, 0.5f, 0.5f);
+ public void addTopRightFrontVertex() {
+ setPoint3f(topRightFront);
}
public void addFrontQuad() {
// triangle strip: И
- setUV(0, 1);
+ setUV(textureLeft, textureTop);
addTopLeftFrontVertex(); // top left
- setUV(0, 0);
+ setUV(textureLeft, textureBottom);
addBottomLeftFrontVertex(); // bottom left
- setUV(1, 0);
+ setUV(textureRight, textureBottom);
addBottomRightFrontVertex(); // bottom right
- setUV(1, 1);
+ setUV(textureRight, textureTop);
addTopRightFrontVertex(); // top right
}
public void addBackQuad() {
// triangle strip: И
- setUV(0, 1);
+ setUV(textureLeft, textureTop);
addTopRightBackVertex();
- setUV(0, 0);
+ setUV(textureLeft, textureBottom);
addBottomRightBackVertex();
- setUV(1, 0);
+ setUV(textureRight, textureBottom);
addBottomLeftBackVertex();
- setUV(1, 1);
+ setUV(textureRight, textureTop);
addTopLeftBackVertex();
}
public void addLeftQuad() {
// triangle strip: И
- setUV(0, 1);
+ setUV(textureLeft, textureTop);
addTopLeftBackVertex();
- setUV(0, 0);
+ setUV(textureLeft, textureBottom);
addBottomLeftBackVertex();
- setUV(1, 0);
+ setUV(textureRight, textureBottom);
addBottomLeftFrontVertex();
- setUV(1, 1);
+ setUV(textureRight, textureTop);
addTopLeftFrontVertex();
}
public void addRightQuad() {
// triangle strip: И
- setUV(0, 1);
+ setUV(textureLeft, textureTop);
addTopRightFrontVertex();
- setUV(0, 0);
+ setUV(textureLeft, textureBottom);
addBottomRightFrontVertex();
- setUV(1, 0);
+ setUV(textureRight, textureBottom);
addBottomRightBackVertex();
- setUV(1, 1);
+ setUV(textureRight, textureTop);
addTopRightBackVertex();
}
public void addTopQuad() {
// triangle strip: И
- setUV(0, 0);
+ setUV(textureLeft, textureBottom);
addTopLeftBackVertex();
- setUV(0, 1);
+ setUV(textureLeft, textureTop);
addTopLeftFrontVertex();
- setUV(1, 1);
+ setUV(textureRight, textureTop);
addTopRightFrontVertex();
- setUV(1, 0);
+ setUV(textureRight, textureBottom);
addTopRightBackVertex();
}
public void addBottomQuad() {
// triangle strip: И
- setUV(0, 0);
+ setUV(textureLeft, textureBottom);
addBottomLeftFrontVertex();
- setUV(0, 1);
+ setUV(textureLeft, textureTop);
addBottomLeftBackVertex();
- setUV(1, 1);
+ setUV(textureRight, textureTop);
addBottomRightBackVertex();
- setUV(1, 0);
+ setUV(textureRight, textureBottom);
addBottomRightFrontVertex();
}
+ public void setPointOffset(float offset) {
+ bottomLeftBack.x = -offset;
+ bottomLeftBack.y = -offset;
+ bottomLeftBack.z = -offset;
+ //
+ bottomLeftFront.x = -offset;
+ bottomLeftFront.y = -offset;
+ bottomLeftFront.z = offset;
+ //
+ bottomRightBack.x = offset;
+ bottomRightBack.y = -offset;
+ bottomRightBack.z = -offset;
+ //
+ bottomRightFront.x = offset;
+ bottomRightFront.y = -offset;
+ bottomRightFront.z = offset;
+ //
+ topLeftBack.x = -offset;
+ topLeftBack.y = offset;
+ topLeftBack.z = -offset;
+ //
+ topLeftFront.x = -offset;
+ topLeftFront.y = offset;
+ topLeftFront.z = offset;
+ //
+ topRightBack.x = offset;
+ topRightBack.y = offset;
+ topRightBack.z = -offset;
+ //
+ topRightFront.x = offset;
+ topRightFront.y = offset;
+ topRightFront.z = offset;
+
+ }
+
+ public void setTextureOffset(SpriteRectangle offset) {
+ if (null != offset) {
+ // System.out.print("Offset " + "[" + offset.topLeft.x + "," +
+ // offset.topLeft.y + "]");
+ textureTop = offset.topLeft.y;
+ textureLeft = offset.topLeft.x;
+ textureRight = offset.bottomRight.x;
+ textureBottom = offset.bottomRight.y;
+ }
+ }
+
}
diff --git a/src/ru/olamedia/geom/VoxelRaypicker.java b/src/ru/olamedia/geom/VoxelRaypicker.java
new file mode 100644
index 0000000..9e8c533
--- /dev/null
+++ b/src/ru/olamedia/geom/VoxelRaypicker.java
@@ -0,0 +1,37 @@
+package ru.olamedia.geom;
+
+public class VoxelRaypicker {
+ public float[] center = new float[3];
+ public float[] dir = new float[3];
+ public float radius;
+ public float[] picker = new float[3];
+ public float[] minDelta = new float[3];
+ public float[] delta = new float[3];
+ public float[] absDelta = new float[3];
+
+ private void calcDelta(byte i) {
+ if (dir[i] > 0) {
+ delta[i] = ((float) ((int) (center[i] + 1)) - center[i]) / dir[i];
+ absDelta[i] = delta[i];
+ } else if (dir[0] < 0) {
+ delta[i] = -((float) ((int) (center[i] - 1)) - center[i]) / dir[i];
+ absDelta[i] = delta[i];
+ } else {
+ delta[i] = 0;
+ absDelta[i] = 0;
+ }
+ minDelta[i] = delta[i];
+ }
+
+ public void reset() {
+ picker[0] = center[0];
+ picker[1] = center[1];
+ picker[2] = center[2];
+ calcDelta((byte) 0);
+ calcDelta((byte) 1);
+ calcDelta((byte) 2);
+ }
+
+ public void next() {
+ }
+}