1

我终于完成了 Wavefront OBJ 解析器的构建,但在渲染我的测试对象(立方体)时仍然存在一些问题。

所以这就是我将顶点和索引(面)解析为数据数组的方式。我暂时忽略了纹理和法线。

顶点:

v -0.307796 0.00433517 0
v 0.299126 0.00433517 0
v 0.299126 0.00433517 0.48337
v -0.307796 0.00433517 0.48337
v -0.307796 0.364153 0.48337
v 0.299126 0.364153 0.48337
v 0.299126 0.364153 0
v -0.307796 0.364153 0

作为:

const Vertex Vertices[] = {
    {-0.307796,0.00433517,0},
    {0.299126,0.00433517,0},
    {0.299126,0.00433517,0.48337},
    {-0.307796,0.00433517,0.48337},
    {-0.307796,0.364153,0.48337},
    {0.299126,0.364153,0.48337},
    {0.299126,0.364153,0},
    {-0.307796,0.364153,0}
};

面孔:

f 7/1/1 3/2/2 2/3/3
f 3/4/4 7/5/5 6/6/6
f 5/7/7 1/8/8 4/9/9
f 1/10/10 5/11/11 8/12/12
f 7/13/13 1/14/14 8/15/15
f 1/16/16 7/17/17 2/18/18
f 3/19/19 5/20/20 4/21/21
f 5/22/22 3/23/23 6/24/24
f 5/25/25 7/26/26 8/27/27
f 7/28/28 5/29/29 6/30/30
f 3/31/31 1/32/32 2/33/33
f 1/34/34 3/35/35 4/36/36

作为:

const GLubyte Indices[] = {
7,1,1, 3,2,2, 2,3,3,
3,4,4, 7,5,5, 6,6,6,
5,7,7, 1,8,8, 4,9,9,
1,10,10, 5,11,11, 8,12,12,
7,13,13, 1,14,14, 8,15,15,
1,16,16, 7,17,17, 2,18,18,
3,19,19, 5,20,20, 4,21,21,
5,22,22, 3,23,23, 6,24,24,
5,25,25, 7,26,26, 8,27,27,
7,28,28, 5,29,29, 6,30,30,
3,31,31, 1,32,32, 2,33,33,
1,34,34, 3,35,35, 4,36,36
};

仅作为顶点位置的索引:

const GLubyte Indices[] = {
    7, 3, 2, 
    3, 7, 6, 
    5, 1, 4, 
    1, 5, 8, 
    7, 1, 8, 
    1, 7, 2, 
    3, 5, 4, 
    5, 3, 6, 
    5, 7, 8, 
    7, 5, 6, 
    3, 1, 2, 
    1, 3, 4 
};

设置VBO:

GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

GLuint indexBuffer;
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);

渲染代码:

glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);

CC3GLMatrix *modelView = [CC3GLMatrix matrix];
[modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)];
_currentRotation += displayLink.duration * 90;
[modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, 0)];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);

// 1
glViewport(0, 0, self.frame.size.width, self.frame.size.height);

// 2
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));

// 3
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);

结果几乎什么都没有,所以一定有什么我做错了。

此外,由于我没有初始化法线或纹理坐标,索引会导致任何问题吗?

4

1 回答 1

1

Wavefront obj 格式表示,如果您在面部定义中有 3 的序列,那么它们的含义是:

vertex-index/vertex-texture-index/vector-normal-index

您正在将所有索引读入单个数组GLubyte Indices[]并使用它,就好像它只是顶点的索引一样。
如果你想取消纹理和法线,你只需要取每个三元组的第一个数字。

f 6/1/1 3/2/2 2/3/3 7/4/4

面是索引 [6,3,2,7] 的四边形顶点。像你一样使用索引数组需要你告诉 OpenGl 索引以三元组的形式多路复用。你看起来不像那样做。它还需要用于法线和纹理坐标的额外缓冲区。

于 2012-05-21T21:03:20.500 回答