OpenGL ES学习之四---你好三角形(顶点缓冲区对象)
加载顶点属性的方式二:顶点缓冲区对象(VBO) 使用缓冲区对象,减少客户内存和图像内存之间数据的复制,提高性能(CPU到GPU数据复制) 预定义宏
#define VERTEX\_POS\_SIZE 3 // x, y and z
#define VERTEX\_COLOR\_SIZE 4 // r, g, b, and a
#define VERTEX\_POS\_INDX 0
#define VERTEX\_COLOR\_INDX 1
用户数据结构
typedef struct
{
// Handle to a program object
GLuint programObject;
// VertexBufferObject Ids
GLuint vboIds\[2\];
// x-offset uniform location
GLuint offsetLoc;
} UserData;
初始化
bool VertexBufferObjects::init()
{
bool ret = false;
do
{
CC\_BREAK\_IF(false == TestCase::init());
const char vShaderStr\[\] =
"#version 300 es \\n"
"layout(location = 0) in vec4 a_position; \\n"
"layout(location = 1) in vec4 a_color; \\n"
"uniform float u_offset; \\n"
"out vec4 v_color; \\n"
"void main() \\n"
"{ \\n"
" v\_color = a\_color; \\n"
" gl\_Position = a\_position; \\n"
" gl\_Position.x += u\_offset; \\n"
"}";
const char fShaderStr\[\] =
"#version 300 es \\n"
"precision mediump float; \\n"
"in vec4 v_color; \\n"
"out vec4 o_fragColor; \\n"
"void main() \\n"
"{ \\n"
" o\_fragColor = v\_color; \\n"
"}";
// Create the program object
userData.programObject = GLShader::LoadProgram(vShaderStr, fShaderStr);
userData.offsetLoc = glGetUniformLocation(userData.programObject, "u_offset");
if (userData.programObject == 0)
{
return GL_FALSE;
}
// Store the program object
userData.vboIds\[0\] = 0;
userData.vboIds\[1\] = 0;
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
ret = true;
} while (0);
return ret;
}
绘制函数
void VertexBufferObjects::onDraw(const Mat4& transform, uint32_t flags)
{
auto winSize = Director::getInstance()->getWinSize();
// 3 vertices, with (x,y,z) ,(r, g, b, a) per-vertex
GLfloat vertices\[3 * (VERTEX\_POS\_SIZE + VERTEX\_COLOR\_SIZE)\] =
{
-0.5f, 0.5f, 0.0f, // v0
1.0f, 0.0f, 0.0f, 1.0f, // c0
-1.0f, -0.5f, 0.0f, // v1
0.0f, 1.0f, 0.0f, 1.0f, // c1
0.0f, -0.5f, 0.0f, // v2
0.0f, 0.0f, 1.0f, 1.0f, // c2
};
// Index buffer data
GLushort indices\[3\] = { 0, 1, 2 };
glViewport(0, 0, winSize.width, winSize.height);
glClear(GL\_COLOR\_BUFFER_BIT);
glUseProgram(userData.programObject);
glUniform1f(userData.offsetLoc, 0.0f);
//不使用顶点缓冲区对象绘制图元
DrawPrimitiveWithoutVBOs(vertices,
sizeof(GLfloat) * (VERTEX\_POS\_SIZE + VERTEX\_COLOR\_SIZE),
3, indices);
// Offset the vertex positions so both can be seen
glUniform1f(userData.offsetLoc, 1.0f);
//使用顶点缓冲区对象绘制图元
DrawPrimitiveWithVBOs(&userData, 3, vertices,
sizeof(GLfloat) * (VERTEX\_POS\_SIZE + VERTEX\_COLOR\_SIZE),
3, indices);
}
不使用缓冲区绘制
//
// vertices - pointer to a buffer that contains vertex
// attribute data
// vtxStride - stride of attribute data / vertex in bytes 步进(跨距)
// numIndices - number of indices that make up primitive
// drawn as triangles (顶点数目)
// indices - pointer to element index buffer.
//
void VertexBufferObjects::DrawPrimitiveWithoutVBOs(GLfloat *vertices,
GLint vtxStride,
GLint numIndices,
GLushort *indices)
{
GLfloat *vtxBuf = vertices;
glBindBuffer(GL\_ARRAY\_BUFFER, 0);
glBindBuffer(GL\_ELEMENT\_ARRAY_BUFFER, 0);
//启用属性
glEnableVertexAttribArray(VERTEX\_POS\_INDX);
glEnableVertexAttribArray(VERTEX\_COLOR\_INDX);
//加载顶点数据
glVertexAttribPointer(VERTEX\_POS\_INDX, VERTEX\_POS\_SIZE,
GL\_FLOAT, GL\_FALSE, vtxStride,
vtxBuf);
vtxBuf += VERTEX\_POS\_SIZE;
glVertexAttribPointer(VERTEX\_COLOR\_INDX,
VERTEX\_COLOR\_SIZE, GL_FLOAT,
GL_FALSE, vtxStride, vtxBuf);
glDrawElements(GL\_TRIANGLES, numIndices, GL\_UNSIGNED_SHORT,
indices);
//禁用顶点属性
glDisableVertexAttribArray(VERTEX\_POS\_INDX);
glDisableVertexAttribArray(VERTEX\_COLOR\_INDX);
}
使用缓冲区绘制
void VertexBufferObjects::DrawPrimitiveWithVBOs(UserData *userData,
GLint numVertices, GLfloat *vtxBuf,
GLint vtxStride, GLint numIndices,
GLushort *indices)
{
GLuint offset = 0;
// vboIds\[0\] - used to store vertex attribute data
// vboIds\[l\] - used to store element indices
if (userData->vboIds\[0\] == 0 && userData->vboIds\[1\] == 0)
{
// Only allocate on the first draw
//创建缓冲区对象
//void glGenBuffers(GLsizei n, GLuint *buffers)
//n:number of buffer object names to return
//buffers:pointer to an array of n entries, where allocated buffer objects are returned
glGenBuffers(2, userData->vboIds);
//激活缓冲区对象(is used to make a buffer object current.)
//void glBindBuffer(GLenum target, GLuint buffer);
//指定当前活动缓冲区的对象
//target can be set to any of the following targets :
//GL\_ARRAY\_BUFFER
// GL\_ELEMENT\_ARRAY_BUFFER
// GL\_COPY\_READ_BUFFER
// GL\_COPY\_WRITE_BUFFER
// GL\_PIXEL\_PACK_BUFFER
// GL\_PIXEL\_UNPACK_BUFFER
// GL\_TRANSFORM\_FEEDBACK_BUFFER
// GL\_UNIFORM\_BUFFER
// buffer buffer object to be assigned as the current object to target
glBindBuffer(GL\_ARRAY\_BUFFER, userData->vboIds\[0\]);
//用数据分配和初始化缓冲区对象
//void glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
//target:可以是GL\_ARRAY\_BUFFER()(顶点数组数据)或GL\_ELEMENT\_ARRAY_BUFFER(元素数组数据)
//size:存储相关数据所需的内存容量
//data:用于初始化缓冲区对象,可以是一个指向客户区内存的指针,也可以是NULL
//usage:数据在分配之后如何进行读写,如GL\_STREAM\_READ,GL\_STREAM\_DRAW,GL\_STREAM\_COPY
glBufferData(GL\_ARRAY\_BUFFER, vtxStride * numVertices,
vtxBuf, GL\_STATIC\_DRAW);
glBindBuffer(GL\_ELEMENT\_ARRAY_BUFFER, userData->vboIds\[1\]);
glBufferData(GL\_ELEMENT\_ARRAY_BUFFER,
sizeof(GLushort) * numIndices,
indices, GL\_STATIC\_DRAW);
}
glBindBuffer(GL\_ARRAY\_BUFFER, userData->vboIds\[0\]);
glBindBuffer(GL\_ELEMENT\_ARRAY_BUFFER, userData->vboIds\[1\]);
//启用顶点属性
glEnableVertexAttribArray(VERTEX\_POS\_INDX);
glEnableVertexAttribArray(VERTEX\_COLOR\_INDX);
//加载顶点数据
glVertexAttribPointer(VERTEX\_POS\_INDX, VERTEX\_POS\_SIZE,
GL\_FLOAT, GL\_FALSE, vtxStride,
(const void *)offset);
offset += VERTEX\_POS\_SIZE * sizeof(GLfloat);
//加载顶点数据
glVertexAttribPointer(VERTEX\_COLOR\_INDX,
VERTEX\_COLOR\_SIZE,
GL\_FLOAT, GL\_FALSE, vtxStride,
(const void *)offset);
glDrawElements(GL\_TRIANGLES, numIndices, GL\_UNSIGNED_SHORT,
0);
//禁用顶点属性
glDisableVertexAttribArray(VERTEX\_POS\_INDX);
glDisableVertexAttribArray(VERTEX\_COLOR\_INDX);
glBindBuffer(GL\_ARRAY\_BUFFER, 0);
glBindBuffer(GL\_ELEMENT\_ARRAY_BUFFER, 0);
}
效果图: 20 工程源码:CocosShader
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 xue_huashan@163.com
文章标题:OpenGL ES学习之四---你好三角形(顶点缓冲区对象)
文章字数:1.1k
本文作者:max-xue
发布时间:2017-06-19, 20:28:08
最后更新:2019-11-09, 10:44:34
原始链接:http://blog.le-more.com/2017/06/19/cocos/a1-b6-e7-82-b9-e7-bc-93/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。