나는 이전에 VBO를 사용하기 위해 디스플레이 목록을 사용하여 작성한 OBJ 파서를 변환하려고 노력해 왔으며 외부의 도움없이 직접 문제를 파악할 수 있는지 알아보기 위해 시도했지만 지금은 코드를 너무 오래보고 오류를 찾을 수 없습니다.VBO에서 데이터를로드하는 내 OBJ 파서를 작성하여 단일 인덱스 목록과 일치하도록 데이터를 다시 정렬하는 방법은 무엇입니까?
이것은 OpenGLES 2.0을 통한 Android 앱이며 일부 삼각형이 화면에 표시되지만 올바른 장소에는 표시되지 않습니다. 나는 하나의 인덱스 목록을 기반으로 각 얼굴의 모든 요소를 얻으려는 나의 시도가 정확하지 않고 결국 모든 것을 던지지 만 내 오류를 발견 할 수 없다는 느낌이 들었습니다.
본질적으로 OBJ 형식은 정점, 텍스처 좌표 및 법선 벡터에 대해 별도의 색인을 제공하기 때문에 서로 순서가 완전히 다른 3 개의 데이터 목록이 작성되지만 VBO는 각 부분을 참조합니다 단일 색인 목록을 기반으로합니다. 여기
누군가가 나를 도울 수 있도록하기 위해, 내 코드입니다 :OBJToolkit :
public class OBJToolkit {
public static Mesh loadOBJ(String modelLocation) throws FileNotFoundException, IOException
{
Log.d("OBJToolkit", "Location searched for model: " + modelLocation);
ArrayList<Float> allVertices = new ArrayList<Float>();
ArrayList<Float> allTextureCoors = new ArrayList<Float>();
ArrayList<Float> allNormals = new ArrayList<Float>();
ArrayList<Face> faces = new ArrayList<Face>();
BufferedReader reader = new BufferedReader(new FileReader(new File(modelLocation)));
Mesh mesh = new Mesh();
Log.d("OBJToolkit", "About to read the contents of the model");
while (reader.ready())
{
String line = reader.readLine();
if (line == null)
break;
if (line.startsWith("v "))
{
allVertices.add(Float.valueOf(line.split(" ")[1]));
allVertices.add(Float.valueOf(line.split(" ")[2]));
allVertices.add(Float.valueOf(line.split(" ")[3]));
}
if (line.startsWith("vt "))
{
allTextureCoors.add(Float.valueOf(line.split(" ")[1]));
allTextureCoors.add(Float.valueOf(line.split(" ")[2]));
}
if (line.startsWith("vn "))
{
allNormals.add(Float.valueOf(line.split(" ")[1]));
allNormals.add(Float.valueOf(line.split(" ")[2]));
allNormals.add(Float.valueOf(line.split(" ")[3]));
}
if (line.startsWith("f "))
{
Face f = new Face();
String[] lineArray = line.split(" ");
for (int index = 1; index < lineArray.length; index++)
{
String[] valueArray = lineArray[index].split("/");
f.addVertexIndex(Integer.valueOf(valueArray[0]));
if (valueArray.length > 1)
f.addTextureIndex(Integer.valueOf(valueArray[1]));
if (valueArray.length > 2)
f.addNormalIndex(Integer.valueOf(valueArray[2]));
}
faces.add(f);
}
}
reader.close();
ArrayList<Float> verticesInOrder = new ArrayList<Float>();
ArrayList<Integer> indicesInOrder = new ArrayList<Integer>();
ArrayList<Float> textureCoorsInOrder = new ArrayList<Float>();
ArrayList<Float> normalsInOrder = new ArrayList<Float>();
int counter = 0;
Log.d("OBJToolkit", "About to reorganize each point of data");
for (Face f : faces)
{
for (int value : f.vertexIndices)
{
verticesInOrder.add(allVertices.get(value));
}
for (int value : f.textureIndices)
{
textureCoorsInOrder.add(allTextureCoors.get(value));
}
for (int value : f.normalIndices)
{
normalsInOrder.add(allNormals.get(value));
}
indicesInOrder.add(counter);
counter++;
}
Log.d("OBJToolkit", "Vertices");
printFloatArrayList(verticesInOrder);
Log.d("OBJToolkit", "Indices");
printIntegerArrayList(indicesInOrder);
Log.d("OBJToolkit", "Texture Coordinates");
printFloatArrayList(textureCoorsInOrder);
Log.d("OBJToolkit", "Normals");
printFloatArrayList(normalsInOrder);
Log.d("OBJToolkit", "About to create the VBOs");
mesh.createBuffers(floatListToFloatArray(verticesInOrder), integerListToShortArray(indicesInOrder), null, floatListToFloatArray(textureCoorsInOrder));
return mesh;
}
public static void printFloatArrayList(ArrayList<Float> list)
{
String strToPrint = "";
for (float value : list)
{
strToPrint += value + ", ";
}
Log.d("OBJToolkit", strToPrint);
}
public static void printIntegerArrayList(ArrayList<Integer> list)
{
String strToPrint = "";
for (float value : list)
{
strToPrint += value + ", ";
}
Log.d("OBJToolkit", strToPrint);
}
public static float[] floatListToFloatArray(ArrayList<Float> list)
{
Log.d("OBJToolkit", "Converting ArrayList Float");
float[] returnArray = new float[list.size()];
int counter = 0;
for (float i : list)
{
returnArray[counter] = i;
counter++;
}
return returnArray;
}
public static short[] integerListToShortArray(ArrayList<Integer> list)
{
Log.d("OBJToolkit", "Converting ArrayList Integer");
short[] returnArray = new short[list.size()];
int counter = 0;
for (int i : list)
{
returnArray[counter] = (short)i;
counter++;
}
return returnArray;
}
}
메쉬 클래스 :
public class Mesh {
Bitmap bitmap = null;
private FloatBuffer verticesBuffer;
private ShortBuffer indicesBuffer;
private int numOfIndices = -1;
private float[] rgba = new float[] {1.0f, 1.0f, 1.0f, 1.0f};
private FloatBuffer colorBuffer;
private FloatBuffer mTextureBuffer;
private int mTextureId = -1;
private Bitmap mBitmap;
private boolean mShouldLoadTexture = false;
public float x = 0, y = 0, z = 0, rx = 0, ry = 0, rz = 0;
public Mesh() {
}
public void draw(GL10 gl)
{
//Log.d("Mesh", "About to render mesh");
gl.glFrontFace(GL10.GL_CCW);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glCullFace(GL10.GL_BACK);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verticesBuffer);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
if (colorBuffer != null)
{
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
}
if (mShouldLoadTexture)
{
loadGLTexture(gl);
mShouldLoadTexture = false;
}
if (mTextureId != -1 && mTextureBuffer != null)
{
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);
}
gl.glTranslatef(x, y, z);
gl.glRotatef(rx, 1, 0, 0);
gl.glRotatef(ry, 0, 1, 0);
gl.glRotatef(rz, 0, 0, 1);
gl.glDrawElements(GL10.GL_TRIANGLES, numOfIndices, GL10.GL_UNSIGNED_SHORT, indicesBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
if (mTextureId != -1 && mTextureBuffer != null)
{
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
gl.glDisable(GL10.GL_CULL_FACE);
}
public void setTexture(Bitmap bitmap) {
this.bitmap = bitmap;
}
public void createBuffers(float[] vertices, short[] indices, float[] colors, float[] textureCoords)
{
Log.d("MeshCreateBuffers", "Vertices: " + floatArrayToString(vertices));
setVertices(vertices);
Log.d("MeshCreateBuffers", "Indices: " + shortArrayToString(indices));
setIndices(indices);
if (colors != null)
setColors(colors);
setTextureCoordinates(textureCoords);
Log.d("MeshCreateBuffers", "Texture Coors: " + floatArrayToString(textureCoords));
}
public String floatArrayToString(float[] array)
{
String returnString = "";
for (int i = 0; i < array.length; i++)
{
returnString += array[i];
}
return returnString;
}
public String shortArrayToString(short[] array)
{
String returnString = "";
for (int i = 0; i < array.length; i++)
{
returnString += array[i];
}
return returnString;
}
protected void setVertices(float[] vertices)
{
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
verticesBuffer = vbb.asFloatBuffer();
verticesBuffer.put(vertices);
verticesBuffer.position(0);
}
protected void setIndices(short[] indices)
{
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indicesBuffer = ibb.asShortBuffer();
indicesBuffer.put(indices);
indicesBuffer.position(0);
numOfIndices = indices.length;
}
protected void setColor(float red, float green, float blue, float alpha)
{
rgba[0] = red;
rgba[1] = green;
rgba[2] = blue;
rgba[3] = alpha;
}
protected void setColors(float[] colors)
{
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
cbb.order(ByteOrder.nativeOrder());
colorBuffer = cbb.asFloatBuffer();
colorBuffer.put(colors);
colorBuffer.position(0);
}
protected void setTextureCoordinates(float[] textureCoords)
{
ByteBuffer byteBuf = ByteBuffer.allocateDirect(textureCoords.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
mTextureBuffer = byteBuf.asFloatBuffer();
mTextureBuffer.put(textureCoords);
mTextureBuffer.position(0);
}
public void loadBitmap(Bitmap bitmap)
{
this.mBitmap = bitmap;
mShouldLoadTexture = true;
}
private void loadGLTexture(GL10 gl)
{
int[] textures = new int[1];
gl.glGenTextures(1, textures, 0);
mTextureId = textures[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);
}
}
것은 내가 노골적으로 잘못된 이상 - 복잡한 일을하고 있습니까 내가 방금 발견 할 수 없었던 것?
입력 내용을 기꺼이 제공 한 사람에게 감사드립니다.
이것은 많은 코드이며, OBJ 파일 형식은 1로 시작하는 인덱스를 사용합니다 (대부분의 프로그래밍 언어 배열에서와 같이 0이 아님). 잘못된 장소에있는 삼각형에 대한 귀하의 의견은 저를 이것을 생각하게했습니다. – OEP
오 이런, 내가 어떻게 그 하나를 놓칠 수 있었는지 모르겠지만, 확실히 내가 쓴 때에 대해 아는 것이 아닙니다! 고맙습니다. 그래도 문제가 완전히 해결되었는지 또는 일부인지 만 확실하지 않습니다. – jctjct3
도움이되어 주어서 기쁩니다 - 색인 생성 문제로 인해 (반복적으로) 시간을 낭비했습니다. – OEP