我正在调整问题,或者我想要理解OBJ文件中的顶点/索引/面。我想最终以编程方式解析OBJ文件,但首先我需要了解如何手动完成。我正在使用GLWallpaperService中的示例(由网络上的开发人员提供)来改编它。
我遇到的问题是它似乎与他提供的代码一起工作,以生成具有不同颜色面的通用立方体,他必须单独实现和绘制。我在下面调整了一些代码,试图从我从搅拌机输出的坐标中绘制一个基本的立方体并插入值。
public class GLCube {
private final int _nrOfVertices = 8;
private FloatBuffer _vertexBuffer;
private FloatBuffer _normalBuffer;
private ShortBuffer _indiceBuffer;
public GLCube() {
this.init();
}
private void init() {
// 3 is the number of coordinates to each vertex.
_vertexBuffer = BufferFactory.createFloatBuffer(_nrOfVertices * 3);
_normalBuffer = BufferFactory.createFloatBuffer(18);
_indiceBuffer = BufferFactory.createShortBuffer(72);
// Coordinates for the vertexes of the cube.
float[] vertexCoords = {
/*
1f, 1f, 0f,
0f, 1f, 0f,
0f, 0f, 0f,
1f, 0f, 0f,
1f, 0f, -1f,
1f, 1f, -1f,
0f, 1f, -1f,
0f, 0f, -1f,
*/
2.195671f, -0.176713f, -1.292541f,
2.195671f, -0.176713f, 0.707459f,
0.195671f, -0.176713f, 0.707459f,
0.195672f, -0.176713f, -1.292542f,
2.195672f, 1.823287f, -1.292541f,
2.195671f, 1.823287f, 0.707460f,
0.195671f, 1.823287f, 0.707459f,
0.195671f, 1.823287f, -1.292541f
};
short[] indicesArray = {/*
0, 1, 2, 0, 2, 3,
3, 4, 0, 4, 5, 0,
7, 2, 6, 6, 2, 1,
4, 7, 5, 7, 6, 5,
1, 0, 6, 6, 0, 5,
2, 7, 3, 7, 4, 3
*/
1,1,2, 1,3,1,
1,1,3, 1,4,1,
5,2,8, 2,7,2,
5,2,7, 2,6,2,
1,3,5, 3,6,3,
1,3,6, 3,2,3,
2,4,6, 4,7,4,
2,4,7, 4,3,4,
3,5,7, 5,8,5,
3,5,8, 5,4,5,
5,6,1, 6,4,6,
5,6,4, 6,8,6
};
//Coordinates for Normal Vector. Used for Lighting calculations
float[] normalCoords = {/*
0f, 0f, 1f, 0f, 0f, 1f,
0f, 0f, 1f, 0f, 0f, 1f,
0f, 0f, 1f, 0f, 0f, 1f,
1f, 0f, 0f, 1f, 0f, 0f,
1f, 0f, 0f, 1f, 0f, 0f,
1f, 0f, 0f, 1f, 0f, 0f,
-1f, 0f, 0f, -1f, 0f, 0f,
-1f, 0f, 0f, -1f, 0f, 0f,
-1f, 0f, 0f, -1f, 0f, 0f,
0f, 0f,-1f, 0f, 0f,-1f,
0f, 0f,-1f, 0f, 0f,-1f,
0f, 0f,-1f, 0f, 0f,-1f,
0f, 1f, 0f, 0f, 1f, 0f,
0f, 1f, 0f, 0f, 1f, 0f,
0f, 1f, 0f, 0f, 1f, 0f,
0f,-1f, 0f, 0f,-1f, 0f,
0f,-1f, 0f, 0f,-1f, 0f,
0f,-1f, 0f, 0f,-1f, 0f
*/
0f, -1f, 0f,
0f, 1f, 0f,
1f, -0f, 0f,
-0f, -0f, 1f,
-1f, -0f, -0f,
0f, 0f, -1f
};
_vertexBuffer.put(vertexCoords);
_normalBuffer.put(normalCoords);
_indiceBuffer.put(indicesArray);
_indiceBuffer.position(0);
_vertexBuffer.position(0);
_normalBuffer.position(0);
}
public void draw(GL10 gl) {
// 3 coordinates in each vertex
// 0 is the space between each vertex. They are densely packed in the array, so the value is 0
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);
// 0 is the space between each vertex. They are densely packed in the array, so the value is 0
gl.glNormalPointer(GL10.GL_FLOAT, 0, _normalBuffer);
gl.glColor4f(1.0f, 0f, 0f, 1f); //Red
gl.glDrawElements(GL10.GL_TRIANGLES, 72, GL10.GL_UNSIGNED_SHORT, _indiceBuffer);
}
}
这是Obj文件,也许我只是没有将值放在正确的数组中,但我一直试图弄清楚这一段时间,老实说,只是没有任何后台使用OpenGL所以这是我的第一个试图使用它的项目。
# Blender v2.58 (sub 1) OBJ File: ''
# www.blender.org
v 2.195671 -0.176713 -1.292541
v 2.195671 -0.176713 0.707459
v 0.195671 -0.176713 0.707459
v 0.195672 -0.176713 -1.292542
v 2.195672 1.823287 -1.292541
v 2.195671 1.823287 0.707460
v 0.195671 1.823287 0.707459
v 0.195671 1.823287 -1.292541
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 1.000000 -0.000000 0.000000
vn -0.000000 -0.000000 1.000000
vn -1.000000 -0.000000 -0.000000
vn 0.000000 0.000000 -1.000000
usemtl (null)
s off
f 1//1 2//1 3//1
f 1//1 3//1 4//1
f 5//2 8//2 7//2
f 5//2 7//2 6//2
f 1//3 5//3 6//3
f 1//3 6//3 2//3
f 2//4 6//4 7//4
f 2//4 7//4 3//4
f 3//5 7//5 8//5
f 3//5 8//5 4//5
f 5//6 1//6 4//6
f 5//6 4//6 8//6
对此的任何帮助都将非常感激。我留下他的价值评论,所以你可以看到什么有效。我在屏幕上看到的图像是一组完全扭曲的三角形,看起来它试图制作我的立方体,但它并没有完全到达那里。
包含改变内容的答案非常棒。 - =)
答案 0 :(得分:5)
我认为你是以错误的方式解释.obj格式。看看at this document。
基本上,您的面到顶点坐标的索引应该是第一个整数。 每个面都由索引定义,格式如下:
f v1/t1/n1 v2/t2/n2 v3/t3/n3
当v是顶点索引时,t是纹理坐标索引,n是正常索引。
所以这条线(定义了一个面/三角形)
f 1//1 2//1 3//1
顶点索引为1,2,3
,正常索引为1,1,1
。
你没有纹理坐标,所以没有索引,因此是双斜线。
请记住,构成面的顶点的索引和相关法线的索引是不同的。所以你必须创建两组索引。 (请参阅下面关于glDrawElements的编辑)
另一个小细节是要记住, .obj文件以1 的索引开始计数,尽管这可能是(可能是)数组中的第0个值。因此,您必须考虑到这一点(即从所有索引值中减去1)。
修改强>
查看代码,我发现您正在使用glDrawElements
。据我所知(但如果我错了,请纠正我)这不允许你为顶点,texcoords和法线提供多个(不同的)索引集。因此,您必须更改常规数据以匹配与顶点相同的索引。