以前に作成した、表示リストを使用して代わりにVBOを使用するOBJパーサーを変換しようとして、外部の支援なしで自分で問題を理解できるかどうかを確認しようとしましたが、今はコードが長すぎて、エラーを見つけることができません。
これはOpenGLES2.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);
}
}
明らかに間違っていることや、見つけられなかったほど複雑なことをしているのでしょうか。
私は彼らの意見を提供してくれる人に感謝します。