【发布时间】:2012-12-14 12:39:55
【问题描述】:
底线在前面
我的 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);
}
有人知道我可以尝试解决这个问题吗?
【问题讨论】:
-
您是否手动检查了纹理数组以查看纹理坐标是否正确?可能是您需要使用顶点法线
标签: android opengl-es textures