底线在前面
在立方体的每一侧使用我的 3D 对象(例如立方体)1 三角形正在正确渲染,而另一侧则没有。
概述
我正在尝试将在 Blender 中创建的 3D 对象导入我的 Android OpenGL 世界。
我编写了自己的自定义解析器来读取顶点、索引以及现在的纹理坐标。我可以很好地读取所有数据,并且没有纹理,形状很完美。问题是当我尝试读取纹理坐标时,在每个面上,一个三角形都非常糟糕,而其中一个三角形被正确渲染。
我相信这与在搅拌机中如何生成纹理坐标有关。我注意到在f 1/1 2/2 3/3 4/4
列出“纹理索引”的文件部分中,它们没有按照纹理列出的顺序排列。这可能是问题吗?如果我按照列出纹理索引的顺序构建纹理缓冲区会有帮助吗?
我的 .obj 文件
# Blender v2.63 (sub 0) OBJ File: ''
# www.blender.org
mtllib untitled.mtl
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.000000 0.334353
vt 0.332314 0.333333
vt 0.333333 0.665647
vt 0.001020 0.666667
vt 1.000000 0.001019
vt 0.998981 0.333333
vt 0.666667 0.332314
vt 0.667686 0.000000
vt 1.000000 0.665647
vt 0.667686 0.666667
vt 0.666667 0.334353
vt 0.334353 0.666667
vt 0.333333 0.334353
vt 0.665647 0.333333
vt 0.666667 0.665647
vt 0.333333 0.332314
vt 0.001020 0.333333
vt 0.000000 0.001020
vt 0.332314 0.000000
vt 0.333333 0.001019
vt 0.665647 0.000000
vt 0.334353 0.333333
usemtl Material_golden_fur_by_Dwaoviel.jpg
s off
f 1/1 2/2 3/3 4/4
f 5/5 8/6 7/7 6/8
f 1/6 5/9 6/10 2/11
f 2/12 6/13 7/14 3/15
f 3/16 7/17 8/18 4/19
f 5/20 1/21 4/7 8/22
我的解析器方法
public static Mesh createMesh(int resourceID)
{
Mesh m = new Mesh();
Scanner s;
BufferedReader inputStream = null;
ArrayList<Float> floats = new ArrayList<Float>();
ArrayList<Short> indicies = new ArrayList<Short>();
ArrayList<Float> textures = new ArrayList<Float>();
ArrayList<Short> texturesindex = new ArrayList<Short>();
try
{
inputStream = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(resourceID)));
s = new Scanner(inputStream);
String line = inputStream.readLine();
line = inputStream.readLine();
line = inputStream.readLine();
line = inputStream.readLine();
line = inputStream.readLine();
while(line.charAt(0) == 'v'&&line.charAt(1)!='t')
{
s = new Scanner(line);
s.next();
floats.add(s.nextFloat());
floats.add(s.nextFloat());
floats.add(s.nextFloat());
line = inputStream.readLine();
}
while(line.charAt(0)=='v' && line.charAt(1)=='t')
{
s = new Scanner(line);
s.next(); //read in "vt"
textures.add(s.nextFloat());
textures.add(s.nextFloat());
line = inputStream.readLine();
}
line = inputStream.readLine();
line = inputStream.readLine();
while(line != null && line.charAt(0) == 'f')
{
s = new Scanner(line);
s.useDelimiter("[ /\n]");
String xx = s.next();
int a,b,c,d;
int e,f,g,h;
a = s.nextShort();
e = s.nextShort();
b = s.nextShort();
f = s.nextShort();
c = s.nextShort();
g = s.nextShort();
d = s.nextShort();
h = s.nextShort();
indicies.add((short)a);
indicies.add((short)b);
indicies.add((short)c);
indicies.add((short)a);
indicies.add((short)c);
indicies.add((short)d);
line = inputStream.readLine();
}
float[] vertex = new float[floats.size()];
for(int i=0;i<vertex.length;i++)
{
vertex[i] = floats.get(i).floatValue();
}
short[] ind = new short[indicies.size()];
for(int i=0;i<ind.length;i++)
{
ind[i] = (short) (indicies.get(i).shortValue()-1); //minus one because its 1 based in that program
}
float[] texture = new float[floats.size()];
for(int i=0;i<texture.length;i++)
{
texture[i] = textures.get(i).floatValue();
}
m.constructVertexBuffer(vertex);
m.constructIndexBuffer(ind);
m.constructTextureBuffer(texture);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return m;
}
请注意,此方法基本上将尽可能多的纹理 uv 坐标读入数组列表,然后填充浮点数组,然后调用构造纹理缓冲区方法,该方法执行 OpenGL 所需的所有 ByteBuffer/FloatBuffer 内容。
我的构造方法
public void constructTextureBuffer(float[] texture)
{
ByteBuffer vbb = ByteBuffer.allocateDirect(texture.length*4);
vbb.order(ByteOrder.nativeOrder());
textureBuffer = vbb.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
有人对我可以尝试解决的问题有任何想法吗?