package destr.jogl.pointer; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.StringTokenizer; import javax.media.opengl.GL; import javax.media.opengl.GL2; public class MeshRAM { private static ByteBuffer makeBuff( float[] data ){ ByteBuffer byteBuffer = ByteBuffer.allocateDirect(data.length * Float.SIZE); byteBuffer.order(ByteOrder.nativeOrder()); byteBuffer.asFloatBuffer().put(data).position(0); return byteBuffer; } private static int[] extractObjFace(String line) {//TODO сделать более жевучий эекстрактер StringTokenizer fTokens = new StringTokenizer(line.replaceFirst("//", "/0/"), "/"); return new int[]{ Integer.parseInt(fTokens.nextToken())-1, Integer.parseInt(fTokens.nextToken())-1, Integer.parseInt(fTokens.nextToken())-1, }; } private static float[] arrByIndexArray( Float[] array, int size, Integer[] index) { float[] result = new float[index.length*size]; int ii = 0; for(int i = 0; i < index.length; i++){ int start = index[i] * size; for(int j = 0; j < size; j++ ) { float value = 0; try { value = array[start+j].floatValue(); } catch (ArrayIndexOutOfBoundsException e) { System.err.println("Bad index:"+e.getMessage()); //TODO вывод ошибки с укаzанием наzвания файла и индекса } finally { result[ii++] = value; } } } return result; } public MeshRAM( GL gl, InputStream is ){ try { InputStreamReader isr = new InputStreamReader(is, "UTF-8"); BufferedReader br = new BufferedReader(isr); objReader(gl, br); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void objReader(GL gl, BufferedReader reader) throws NumberFormatException, IOException{ ArrayList vertixList = new ArrayList(), texCoordsList = new ArrayList(), normalsList = new ArrayList(); ArrayList vertixIndexList = new ArrayList(), texCoordsIndexList = new ArrayList(), normalIndexList = new ArrayList(); String line; while (((line = reader.readLine()) != null) ) { if(line.length() <= 0) continue; StringTokenizer tokens = new StringTokenizer(line, " "); if (line.startsWith("v ")){ tokens.nextToken(); // skip the OBJ word vertixList.add(Float.parseFloat(tokens.nextToken())); vertixList.add(Float.parseFloat(tokens.nextToken())); vertixList.add(Float.parseFloat(tokens.nextToken())); } else if (line.startsWith("vt")) { // tex-coord tokens.nextToken(); texCoordsList.add(Float.parseFloat(tokens.nextToken())); texCoordsList.add(Float.parseFloat(tokens.nextToken())); //texCoordsList.add(Float.parseFloat(tokens.nextToken())); } else if (line.startsWith("vn")) {// normal tokens.nextToken(); normalsList.add(Float.parseFloat(tokens.nextToken())); normalsList.add(Float.parseFloat(tokens.nextToken())); normalsList.add(Float.parseFloat(tokens.nextToken())); } else if (line.startsWith("f ")) { tokens.nextToken(); int []face; face = extractObjFace(tokens.nextToken()); vertixIndexList.add(face[0]); texCoordsIndexList.add(face[1]); normalIndexList.add(face[2]); face = extractObjFace(tokens.nextToken()); vertixIndexList.add(face[0]); texCoordsIndexList.add(face[1]); normalIndexList.add(face[2]); face = extractObjFace(tokens.nextToken()); vertixIndexList.add(face[0]); texCoordsIndexList.add(face[1]); normalIndexList.add(face[2]); } else if (line.startsWith("s ")) { } else if (line.startsWith("#")) { } } Float[] nullFloatArr = new Float[0]; // Требуется для формирование Float[] иz ArrayList Integer[] nullIntArr = new Integer[0]; // Тожесамое для Integer onBufferLoad( gl, makeBuff(arrByIndexArray(vertixList.toArray(nullFloatArr), 3, vertixIndexList.toArray(nullIntArr))), makeBuff(arrByIndexArray(normalsList.toArray(nullFloatArr), 3, normalIndexList.toArray(nullIntArr))), makeBuff(arrByIndexArray(texCoordsList.toArray(nullFloatArr), 2, texCoordsIndexList.toArray(nullIntArr))) ); } private int vertixLength; private ByteBuffer vertixBB, normalesBB, texCoordsBB; private void onBufferLoad( GL gl, ByteBuffer vertixBB, ByteBuffer normalesBB, ByteBuffer texCoordsBB){ vertixLength = vertixBB.capacity()/Float.SIZE/3; this.vertixBB = vertixBB; this.normalesBB = normalesBB; this.texCoordsBB = texCoordsBB; } public void enable(GL2 gl){ gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY); } public void bind(GL2 gl){ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); gl.glVertexPointer(3, GL2.GL_FLOAT, 0, vertixBB); gl.glNormalPointer(GL2.GL_FLOAT, 0, normalesBB); gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, texCoordsBB); } public void draw(GL2 gl){ gl.glDrawArrays(GL.GL_TRIANGLES, 0, vertixLength); } public void unBind(GL2 gl){ } public void disable(GL2 gl){ gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); gl.glDisableClientState(GL2.GL_NORMAL_ARRAY); gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY); } }