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

时间:2011-09-01 17:40:23

标签: c opengl-es opengl-es-2.0 vbo vertex-buffer

我是openGL的新手。我使用苹果文档作为我的主要参考 http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html#//apple_ref/doc/uid/TP40008793-CH107-SW6

我的问题是我使用的是openGL ES 1.1 而不是 2 因此清单9-3中使用的函数,例如 glVertexAttribPointer glEnableVertexAttribArray 无法识别......:)

我尝试进行本文档中描述的优化: 将索引和顶点作为结构包含其所有数据:position,color(清单9-1)

typedef struct _vertexStruct
{
  GLfloat position[3];
  GLubyte color[4];
} VertexStruct;

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

并使用清单9-2,9-3中的VBO

正如我所提到的,openGL ES 1.1中不存在一些在那里使用的功能。我想知道是否有一种方法可以在ES 1.1中使用其他代码进行相同的操作?

感谢, 亚历


根据基督徒的回答编辑,尝试使用glVertexPointer,glColorPointer。 这是代码,它打印立方体,但没有颜色...... :(。任何人,是否可以使用 使用ES 1.1的这种方式的维也纳国际中心

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 个答案:

答案 0 :(得分:4)

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

使用固定功能管道时(就像在OpenGL ES 1.1中一样),您只需使用内置属性(考虑glVertexglColor调用,您可能在切换到顶点数组)。每个属性都有一些函数,类似于它们的立即模式对应物,如glVertexPointerglColorPointer(而不是glVertexAttribPointer)。通过使用gl(En/Dis)ableClientStateGL_VERTEX_ARRAY(而不是GL_COLOR_ARRAY)等常量调用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)。但是,你可能会在其他函数中遇到问题,这些函数假定没有缓冲区,但缓冲区仍然是绑定的。永远记住,OpenGL是一个状态机,你设置的每个状态都会保持不变,直到它再次被改变或者上下文被破坏。