4

我是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 中使用的函数,例如glVertexAttribPointerglEnableVertexAttribArray ... :)

我试图进行本文档中描述的优化:将索引和顶点作为一个结构保存,其中包含所有数据:位置、颜色(清单 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 在这种方式中使用 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);
}
4

1 回答 1

4

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

当使用固定功能管道时(就像在 OpenGL ES 1.1 中必须使用的那样),您只需使用内置属性(想想glVertexandglColor调用,您可能在切换到顶点数组之前使用过)。每个属性都有一些函数,它们的调用类似于它们的直接模式对应物,比如glVertexPointeror glColorPointer(而不是glVertexAttribPointer)。这些数组通过使用类似或(而不是)的gl(En/Dis)ableClientState常量调用来启用/禁用。GL_VERTEX_ARRAYGL_COLOR_ARRAYgl(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 字节颜色,​​因为与位置的 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。

And by the way, you should call glBindBuffer(GL_ARRAY_BUFFER, 0) and likewise for the element array buffer after you're finished with using them at the end of these two functions. Othwerwise you may get problems in other functions which assume no buffers but the buffers are still bound. Always remember that OpenGL is a state machine and every state you set stays until it's changed again or the context is destroyed.

于 2011-09-01T17:56:55.520 回答