c - 在 OpenGL ES 1.1 与 ES 2.0 中使用顶点缓冲区对象进行绘图

标签 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 因此在 list 9-3 中使用的函数如 glVertexAttribPointer , glEnableVertexAttribArray 无法识别 ... :)

我尝试进行本文档中描述的优化: 将索引和顶点保存为一个结构及其所有数据:位置、颜色( list 9-1)

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

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

并使用 list 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);
}

最佳答案

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

当使用固定功能管道(在 OpenGL ES 1.1 中必须这样做)时,您只需使用内置属性(想想 glVertexglColor 调用,您可能在切换到顶点数组之前使用过)。每个属性都有一些函数,它们的调用方式类似于它们的直接模式对应项,例如 glVertexPointerglColorPointer(而不是 glVertexAttribPointer)。这些数组是通过使用 GL_VERTEX_ARRAYGL_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 个 float ,您应该得到完美的 16 -字节对齐的顶点,这也是他们在您提供的链接中建议的优化。

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

编辑:您的颜色包含 ubytes(范围从 0(黑色)到 255(全彩色))并且您用 float 初始化它们。所以你的 float 值 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) 并且在这两个函数的末尾使用完元素数组缓冲区后同样如此。 Othwerwise 你可能会在其他函数中遇到问题,这些函数假定没有缓冲区,但缓冲区仍然是绑定(bind)的。永远记住,OpenGL 是一个状态机,您设置的每个状态都会一直保持,直到它再次更改或上下文被销毁。

关于c - 在 OpenGL ES 1.1 与 ES 2.0 中使用顶点缓冲区对象进行绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7274219/

相关文章:

C代码小波变换及解释

c - scanf ("%c", &c) 和 scanf ("%c", &c) 的区别

ios - 在 iOS 上处理大量像素

ios - 在 iOS 上更改 OpenGL ES 版本

c - 无法弄清楚 ~ 运算符在 c 中如何工作

c++ - 具有自动超频功能的多核处理器上的准确 C/C++ 时钟?

android - 构建 3D 模型查看器 android?

qt - 在 EGL 上渲染时的 OpenGL 撕裂效果

android - 在android中同时绘制剪裁平面和线框

android - OpenGL ES 2 纹理图集最前沿