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<Float> vertixList = new ArrayList<Float>(),
texCoordsList = new ArrayList<Float>(),
normalsList = new ArrayList<Float>();
ArrayList<Integer> vertixIndexList = new ArrayList<Integer>(),
texCoordsIndexList = new ArrayList<Integer>(),
normalIndexList = new ArrayList<Integer>();
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<Float>
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);
}
}
Comments