在OpenGL ES 1.1和ES 2.0中使用顶点缓冲对象进行绘图的区别

4
我刚接触OpenGL,我使用苹果文档作为我的主要参考:http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html#//apple_ref/doc/uid/TP40008793-CH107-SW6 我的问题是,我正在使用OpenGL ES1.1而不是2,因此在第9-3节中使用的函数,例如glVertexAttribPointerglEnableVertexAttribArray无法识别... :)
我试图实现文档中描述的优化,将索引和顶点保存为一个包含所有数据(位置、颜色)的结构体(参见第9-1节)。
typedef struct _vertexStruct
{
  GLfloat position[3];
  GLubyte color[4];
} VertexStruct;

const VertexStruct vertices[] = {...};
const GLushort indices[] = {...};

需要使用VBO,比如在9-2,9-3代码示例中所示。

正如我所提到的,一些在那里使用的函数在OpenGL ES 1.1中并不存在。我想知道是否有一种方式可以用ES 1.1做同样的事情,也许是用其他代码?

谢谢, Alex


根据Christian的答案进行了编辑,尝试使用glVertexPointer、glColorPointer。这是代码,它打印出了立方体但没有颜色…… :( 。请问是否有可能在ES 1.1中以这种方式使用VBO?

typedef struct {
    GLubyte red;
    GLubyte green;
    GLubyte blue;
    GLubyte alpha;
} Color3D;

typedef struct {
    GLfloat x;
    GLfloat y;
    GLfloat z;
} Vertex3D;

typedef struct{
   Vector3D position;
   Color3D color;
} MeshVertex;

数据立方体:

static const MeshVertex meshVertices [] =
{

    { { 0.0, 1.0, 0.0 } , { 1.0, 0.0, 0.0 ,1.0 } },
    { { 0.0, 1.0, 1.0 } , { 0.0, 1.0, 0.0 ,1.0 } },
    { { 0.0, 0.0, 0.0 } , { 0.0, 0.0, 1.0 ,1.0 } },
    { { 0.0, 0.0, 1.0 } , { 1.0, 0.0, 0.0, 1.0 } },
    { { 1.0, 0.0, 0.0 } , { 0.0, 1.0, 0.0, 1.0 } },
    { { 1.0, 0.0, 1.0 } , { 0.0, 0.0, 1.0, 1.0 } },
    { { 1.0, 1.0, 0.0 } , { 1.0, 0.0, 0.0, 1.0 } },
    { { 1.0, 1.0, 1.0 } , { 0.0, 1.0, 0.0, 1.0 } }

};

static const GLushort meshIndices [] =
{   0, 1, 2 , 
    2, 1, 3 , 
    2, 3, 4 ,
    3, 5, 4 ,
    0, 2, 6 ,
    6, 2, 4 ,
    1, 7, 3 ,
    7, 5, 3 ,
    0, 6, 1 ,
    1, 6, 7 , 
    6, 4, 7 , 
    4, 5, 7 
};

功能

GLuint vertexBuffer;
GLuint indexBuffer;

- (void) CreateVertexBuffers 
{ 
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(meshVertices), meshVertices, GL_STATIC_DRAW);

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

}

- (void) DrawModelUsingVertexBuffers
{
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexPointer(3, GL_FLOAT, sizeof(MeshVertex), (void*)offsetof(MeshVertex,position));
    glEnableClientState(GL_VERTEX_ARRAY);


    glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(MeshVertex), (void*)offsetof(MeshVertex,color));
    glEnableClientState(GL_COLOR_ARRAY);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);  
    glDrawElements(GL_TRIANGLE_STRIP, sizeof(meshIndices)/sizeof(GLushort), GL_UNSIGNED_SHORT,    (void*)0);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
}
1个回答

4

glVertexAttribPointerglEnableVertexAttribArray等函数用于通用自定义顶点属性(这是OpenGL ES 2.0中提交顶点数据的唯一支持方法)。

当使用固定功能管线(如在OpenGL ES 1.1中必须使用)时,您只需使用内置属性(考虑在切换到顶点数组之前可能已经使用过的glVertexglColor调用)。每个属性都有一个类似于其立即模式对应项的函数,例如glVertexPointerglColorPointer(而不是glVertexAttribPointer)。通过使用如GL_VERTEX_ARRAYGL_COLOR_ARRAY这样的常量来启用/禁用这些数组,其中调用gl(En/Dis)ableClientState(而不是gl(En/Dis)ableVertexAttribArray)。

但是作为一般规则,您不应该使用2.0资源学习OpenGL ES 1.1编程,因为许多信息对您没有用处(至少如果您是OpenGL的新手)。例如,您链接站点上描述的某些方法可能不受1.1支持,例如VBO甚至VAO。但我也不得不承认,我完全没有ES经验,所以对此并不十分确定。

编辑:关于您的更新代码:我假设没有颜色意味着立方体是单一颜色,可能是白色。在您的第一个代码示例中,您使用了GLubyte color [4],现在则为一些Color3D类型,也许这不适用于glColorPointer(4, GL_UNSIGNED_BYTE, ...)调用(其中第一个参数是组件数,第二个参数是类型)?

如果您的Color3D类型只包含3种颜色或浮点颜色,我无论如何都建议您使用4-ubyte颜色,因为与位置的3个浮点数一起,您应该可以得到完美16字节对齐的顶点,这也是您提供的链接中建议的优化。

顺便说一下,在您的CreateVertexBuffers函数中重复创建索引缓冲区是错误吗?

编辑:您的颜色包含ubytes(从0(黑色)到255(全色)),而您使用浮点数进行初始化。因此,您的浮点值1.0(肯定表示全色)转换为ubyte,您会得到1,与整个[0,255]范围相比仍然很小,因此一切都是黑色的。当您使用ubytes时,应该使用ubytes进行初始化,因此只需将颜色数据中的每个0.0替换为0,将每个1.0替换为255即可。

顺便提一下,如果你在ES 1.1中使用VBO并至少绘制了一些内容,那么似乎ES 1.1支持VBO。我不知道是否也支持VAO。
另外,在这两个函数结束后,应该调用glBindBuffer(GL_ARRAY_BUFFER, 0)及同样的element array buffer函数。否则,其他函数可能会出现问题,因为它们假设没有缓冲区但缓冲区仍然被绑定。请记住,OpenGL是一个状态机,每个设置的状态都保持不变,直到再次更改或上下文被销毁。

嘿,谢谢回复,我尝试使用你提到的函数。使用它们,OpenGL可以绘制立方体,但没有颜色...我已经编辑了问题,并添加了一些我的代码,也许你可以给我一些关于代码的建议。 - alexpov
这个立方体是黑色的,是的,重复是一个打字错误 :),已经修复了。Color3D没问题,它是一个由4个ubyte组成的结构体,我已经添加了它的声明,还有Vertex3D和立方体数据。 - alexpov
是的 :) 那就是问题所在,我感到很蠢,非常感谢你... :) - alexpov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接