OpenGL 3.3 core与OpenGLES 3.0的VAO与VBO使用差距

文章比较了OpenGL3.3和OpenGLES3.0中glVertexAttribPointer函数的pointer参数处理方式,指出OpenGLES允许pointer作为指针或偏移量,而OpenGL3.3仅支持偏移量,且需配合VBO。文章提供了三种在OpenGLES中的顶点数据处理示例:不使用VAO/VBO、仅使用VBO和同时使用VAO/VBO。
摘要由CSDN通过智能技术生成

背景

学完《Learn OpenGL》之后,又开始看安卓端的OpenGLES,发现有如下代码:

// 这是用于GLES
  GLfloat vVertices[] = {
      0.0f,  0.5f, 0.0f,
      -0.5f, -0.5f, 0.0f,
      0.5f, -0.5f, 0.0f,
  };

  // Load the vertex data
  glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
  glEnableVertexAttribArray (0);

第一次看这段代码我困惑于为什么不用创建对应的VAO和VBO,而是直接使用glVertexAttribPointer,后来查阅发现《Learn OpenGL》使用OpenGL3.3 core和OpenGLES3.0虽然语法很像,但是具体略有区别。

glVertexAttribPointer的差别

单看glVertexAttribPointer的文档可以发现,首先两者的签名是相同的:

void glVertexAttribPointer(	GLuint	index,
							GLint	size,
							GLenum	type,
							GLboolean	normalized,
							GLsizei	stride,
							const GLvoid *	pointer);

但是在对于pointer参数的解释上,两者存在不同:

对于OpenGLES

pointer Specifies a pointer to the first generic vertex attribute in the array. If a non-zero buffer is currently bound to the GL_ARRAY_BUFFER target, pointer specifies an offset of into the array in the data store of that buffer. The initial value is 0.

If a non-zero named buffer object is bound to the GL_ARRAY_BUFFER target (see glBindBuffer), pointer is treated as a byte offset into the buffer object’s data store and the buffer object binding (GL_ARRAY_BUFFER_BINDING) is saved as generic vertex attribute array state (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) for index index.

Client vertex arrays (a binding of zero to the GL_ARRAY_BUFFER target) are only valid in conjunction with the zero named vertex array object. This is provided for backwards compatibility with OpenGL ES 2.0.

对于OpenGL 3.3

pointerSpecifies a offset of the first component of the first generic vertex attribute in the array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target. The initial value is 0.

If pointer is not NULL, a non-zero named buffer object must be bound to the GL_ARRAY_BUFFER target (see glBindBuffer), otherwise an error is generated.

总结

简单来说:对于OpenGLES,glVertexAttribPointer的pointer可以作为指向数组的指针,也可以作为偏移量,这取决于是否有buffer(VBO) 绑定在上面。而对于OpenGL3.3,pointer只能作为偏移量,如果pointer不为NULL并且没有绑定VBO,则会报错。

代码示例

OpenGLES3.0

由于GLES3.0对于GLES2.0的兼容性设计,以下三种使用顶点数据的方式均可:

假设这是顶点数据

    LOGCATE("TriangleSample::Draw");
    GLfloat vVertices[] = {
            0.0f,  0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
    };

不使用VAO及VBO

    // =============================================
    // Load the vertex data without VAO and VBO
    glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
    glEnableVertexAttribArray (0);

只用VBO不用VAO

    //  Using VBO only
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), vVertices, GL_STATIC_DRAW);
    glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL );
    glEnableVertexAttribArray (0);

同时使用VAO和VBO

     // Using VAO and VBO
     GLuint vao;
     GLuint vbo;
     glGenVertexArrays(1, &vao);
     glBindVertexArray(vao);
     glGenBuffers(1, &vbo);
     glBindBuffer(GL_ARRAY_BUFFER, vbo);
     glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), vVertices, GL_STATIC_DRAW);
     glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL );
     glEnableVertexAttribArray (0);

OpenGL 3.3 Core

只能使用VBO+VAO的模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值