package net.hvidtfeldts.meshia.engine3d; import java.nio.IntBuffer; import javax.media.opengl.GL; import javax.media.opengl.GL2ES2; import net.hvidtfeldts.utils.Logger; import org.sunflow.SunflowAPI; import org.sunflow.core.ParameterList; import org.sunflow.core.ParameterList.InterpolationType; import org.sunflow.core.primitive.TriangleMesh; import wblut.geom.WB_Normal3d; import wblut.hemesh.HEC_Icosahedron; import wblut.hemesh.HE_Mesh; import com.jogamp.common.nio.Buffers; import com.jogamp.opengl.util.GLArrayDataServer; import com.jogamp.opengl.util.glsl.ShaderState; public class Hemesh3D extends AbstractObject3D implements SunflowRenderable { protected Hemesh3D(ShaderState shaderState, String name) { super(shaderState, name); } private GLArrayDataServer vertices; private GLArrayDataServer normals; private GLArrayDataServer colors; private final int[] indexBuffer = new int[] { -1 }; private int indexCount = -1; private static boolean WIRE = false; float[] vertexArray; float[] normalArray; float[] colorArray; int[] indexArray; @Override public void internalInit(final GL2ES2 gl) { HE_Mesh mesh; if (true) { mesh = (new HEC_Icosahedron()).create(); // mesh = (new HEC_Cube(0.1, 2, 2, 2)).create(); // double a = 1; // double factor = 1.5; // for (int i = 0; i < 0; i++) { // List<HE_Face> facesAsList = mesh.getFacesAsList(); // for (HE_Face hf : facesAsList) { // WB_Point3d faceCenter = hf.getFaceCenter(); // WB_Normal3d faceNormal = hf.getFaceNormal(); // HE_Selection triSplitFace = mesh.triSplitFace(hf, a); // } // a /= -factor; // } mesh.clean(); // mesh = (new HEC_Johnson(24, 0.5)).create(); // mesh.modify(new HEM_ChamferCorners().setDistance(0.172678)); // mesh.modify(new HEM_Extrude().setDistance(0.52372678)); // mesh.subdivide(new HES_CatmullClark2(), 2); // mesh.subdivide(new HES_CatmullClark(), 2); } gl.glGenBuffers(1, indexBuffer, 0); float[][] v = mesh.getVerticesAsFloat(); int[][] facesAsInt = mesh.getFacesAsInt(); Logger.log("Faces: " + facesAsInt.length); indexArray = null; if (WIRE) { int vCount = 0; for (int i = 0; i < facesAsInt.length; i++) { vCount += facesAsInt[i].length; } indexArray = new int[vCount * 2]; int c = 0; for (int i = 0; i < facesAsInt.length; i++) { for (int j = 0; j < facesAsInt[i].length - 1; j++) { indexArray[c++] = facesAsInt[i][j]; indexArray[c++] = facesAsInt[i][j + 1]; } } } else { int tris = 0; for (int i = 0; i < facesAsInt.length; i++) { tris += (facesAsInt[i].length - 2); } indexArray = new int[tris * 3]; int c = 0; for (int i = 0; i < facesAsInt.length; i++) { for (int j = 1; j < facesAsInt[i].length - 1; j++) { indexArray[c++] = facesAsInt[i][0]; indexArray[c++] = facesAsInt[i][j]; indexArray[c++] = facesAsInt[i][j + 1]; } } } // // IntBuffer intBuffer = ByteBuffer.allocateDirect(indices.length * 4).asIntBuffer(); IntBuffer intBuffer = Buffers.newDirectIntBuffer(indexArray.length * 4); intBuffer.put(indexArray); intBuffer.rewind(); indexCount = indexArray.length; gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer[0]); gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indexArray.length * 4, intBuffer, GL.GL_STATIC_DRAW); // gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0); WB_Normal3d[] vertexNormals = mesh.getVertexNormals(); vertexArray = new float[v.length * 3]; normalArray = new float[v.length * 3]; colorArray = new float[v.length * 4]; int count = 0; int colorCount = 0; int verCount = 0; for (int i = 0; i < v.length; i++) { for (int j = 0; j < 3; j++) { vertexArray[count++] = v[i][j]; } colorArray[colorCount++] = 1.0f; colorArray[colorCount++] = 1.0f; colorArray[colorCount++] = 1.0f; colorArray[colorCount++] = 1.0f; normalArray[verCount++] = (float) vertexNormals[i].x; normalArray[verCount++] = (float) vertexNormals[i].y; normalArray[verCount++] = (float) vertexNormals[i].z; } // Allocate Vertex Array vertices = GLArrayDataServer.createGLSL("vertex", 3, GL.GL_FLOAT, false, vertexArray.length / 3, GL.GL_STATIC_DRAW); for (int i = 0; i < vertexArray.length; i++) { vertices.putf(vertexArray[i]); } vertices.seal(gl, true); shaderState.ownAttribute(vertices, true); vertices.enableBuffer(gl, false); // Allocate Color Array colors = GLArrayDataServer.createGLSL("color", 4, GL.GL_FLOAT, false, colorArray.length / 4, GL.GL_STATIC_DRAW); for (int i = 0; i < colorArray.length; i++) { colors.putf(colorArray[i]); } colors.seal(gl, true); shaderState.ownAttribute(colors, true); colors.enableBuffer(gl, false); // Allocate Normal Array normals = GLArrayDataServer.createGLSL("normal", 3, GL.GL_FLOAT, false, normalArray.length / 3, GL.GL_STATIC_DRAW); for (int i = 0; i < normalArray.length; i += 1) { normals.putf(normalArray[i]); } normals.seal(gl, true); shaderState.ownAttribute(normals, true); normals.enableBuffer(gl, false); } @Override public void internalDraw(GL2ES2 gl) { vertices.enableBuffer(gl, true); colors.enableBuffer(gl, true); normals.enableBuffer(gl, true); // gl.glDrawArrays(GL.GL_TRIANGLES, 0, vertices.getElementCount()); gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer[0]); if (WIRE) { gl.glDrawElements( // GL.GL_TRIANGLES, // mode GL.GL_LINES, // mode indexCount, // count GL.GL_UNSIGNED_INT, // type 0 // element array buffer offset ); } else { gl.glDrawElements( GL.GL_TRIANGLES, // mode // GL.GL_LINES, // mode indexCount, // count GL.GL_UNSIGNED_INT, // type 0 // element array buffer offset ); } vertices.enableBuffer(gl, false); colors.enableBuffer(gl, false); normals.enableBuffer(gl, false); } /* * (non-Javadoc) * * @see net.hvidtfeldts.meshia.engine3d.SunflowRenderable#getTriangleMesh(org.sunflow.SunflowAPI) */ @Override public TriangleMesh getTriangleMesh(SunflowAPI api) { TriangleMesh tm = new TriangleMesh(); ParameterList pl = new ParameterList(); pl.addPoints("points", InterpolationType.VERTEX, vertexArray); pl.addIntegerArray("triangles", indexArray); pl.addVectors("normals", InterpolationType.VERTEX, normalArray); tm.update(pl, api); return tm; } }