您当前的位置: 首页 >  ar

LearnGL - 04 - VAO 探究

发布时间:2020-06-11 00:21:40 ,浏览量:6

文章目录
  • VAO 结构
  • GL LIKE 测试项目
    • gl_like.h
    • gl_like_gv.h
    • gl_like.cpp
    • Main.cpp
    • 运行效果
LearnGL - 学习笔记目录

本人才疏学浅,如有什么错误,望不吝指出。

上一篇:LearnGL - 03 - DrawQuad - VBO/EBO,学会了如何使用 EBO/IBO 画一个四边形。

这一篇:我将使用C++写个类似 OpenGL 在使用 VAO 期间的功能:

VAO 结构

VAO的结果差不多就如下图: 在这里插入图片描述

GL LIKE 测试项目

我模仿 OpenGL 一部分的 API 编写了测试项目:

gl_like.h
// gl_like.h // jave.lin - 测试模仿 opengl 的规范,没有参考 opengl specification 规范,只是自己的理解 // 不做过多的封装,只为简单的理解结束结构,大致的功能 //(什么 private fields, public getter/setter都不封装),实际项目时是不能这么封装的 #ifndef _GL_LIKE__H_ #define _GL_LIKE__H_ #include #include #include // 获取地址类型对象指针 #define GET_POINSTER_BY_VALUE(type, addressValue) ((type)((void*)addressValue)) // 获取指针对象地址值 #define GET_ADDRESS_VALUE(address) ((uint)address); // // symbol constants - 符号常量,参考 glad 的定义 // #define GL_ARRAY_BUFFER                         0x8892 #define GL_ELEMENT_ARRAY_BUFFER                 0x8893 #define GL_STATIC_DRAW                          0x88E4 #define GL_BYTE                                 0x1400 #define GL_UNSIGNED_BYTE                        0x1401 #define GL_SHORT                                0x1402 #define GL_UNSIGNED_SHORT                       0x1403 #define GL_INT                                  0x1404 #define GL_UNSIGNED_INT                         0x1405 #define GL_FLOAT                                0x1406 #define GL_POINTS                               0x0000 #define GL_LINES                                0x0001 #define GL_LINE_LOOP                            0x0002 #define GL_LINE_STRIP                           0x0003 #define GL_TRIANGLES                            0x0004 #define GL_TRIANGLE_STRIP                       0x0005 #define GL_TRIANGLE_FAN                         0x0006 // // custom symbol constants - 符号常量,自定义的,暂时还没有看到的参考资料 // #define GL_MAX_NUM_OF_VAO                       4096 #define GL_MAX_NUM_OF_VBO                       4096 #define GL_TRUE                                 1 #define GL_FALSE                                0 #define GL_INVALIDATED_CONTEXT                  1 #define GL_OUT_BO_MAX_COUNT                     2 #define GL_CREATE_FAILURE                       3 #define GL_CONTEXT_NOT_NULL                     4 #define GL_BINDING_UN_HANDLE_BUFF_TYPE          5 #define GL_SET_BUFF_VALUES_BUFF_NULL            6 // // declaretion - empty - 空定义 // // // typdef - 参考 glad 的 typedef 别名(C++中的话,使用using会更好,因为支持template,但typedef一直到c会更好) // typedef unsigned int GLenum; typedef unsigned char GLboolean; typedef unsigned int GLbitfield; typedef void GLvoid; typedef signed char GLbyte; typedef unsigned char GLubyte; typedef signed short GLshort; typedef unsigned short GLushort; typedef int GLint; typedef unsigned int GLuint; typedef int GLclampx; typedef int GLsizei; typedef float GLfloat; typedef float GLclampf; typedef double GLdouble; typedef double GLclampd; typedef void* GLeglClientBufferEXT; typedef void* GLeglImageOES; typedef char GLchar; typedef char GLcharARB; typedef signed long int GLsizeiptr; typedef GLbyte* _buffer_t; typedef GLubyte* _ubuffer_T; // // declaretion - sold // class _BuffObject { public: _ubuffer_T data = NULL; GLsizei size = 0; GLsizei capacity = 0; ~_BuffObject(); }; class BufferObject { // 缓存对象 public: _BuffObject* buf = NULL; ~BufferObject(); }; class VertexAttributeFormat { public: GLuint index = -1; // location 索引 GLint numOfComponent = 0; // 分量的数量 GLenum typeOfComponent = 0; // 分量的类型 GLboolean normalized = 0; // 分量值是否归一化 GLsizei stride = 0; // 顶点属性所在数据数组的每个分段大小 void* pointer = 0; // 在对应分段的字节偏移 GLuint setupToVBO = 0; // 安装到vbo ~VertexAttributeFormat(); }; class VertexArrayObject { // VAO public: BufferObject* vbo = NULL; // VBO 指针 BufferObject* ebo = NULL; // EBO 指针 std::vector<VertexAttributeFormat*>* vafs = NULL; // VBO 格式(规范) std::vector<GLuint>* vafs_enabled = NULL; // 启用的 VBO 格式 VertexArrayObject(); ~VertexArrayObject(); }; class Context { public: GLuint major = 0; GLuint minor = 0; VertexArrayObject* bindingVAO = NULL; // 绑定之后的VAO VertexArrayObject* defalultVAO = NULL; // 未绑定的VAO std::vector<VertexArrayObject*>* VAOs = NULL; // 已申请的所有 VAO 对象 std::vector<BufferObject*>* BOs = NULL; // 已申请的所有 BO 对象 Context(); ~Context(); inline VertexArrayObject* GetUsingVAO() const; // 获取当前用的VAO }; // // function - others // void Terminate(); void MakeCurrentContext(GLuint context); void CheckBuffType(GLenum buffType); void Error(const GLuint ec, const GLchar* msg); GLboolean CreateContext(GLuint major, GLuint minor, GLuint* context); void glGenVertexArrays(GLsizei n, GLuint* arrays); void glDeleteVertexArrays(GLsizei n, GLuint* arrays); void glBindVertexArray(GLuint array); void glGenBuffers(GLsizei n, GLuint* buffers); void glDeleteBuffers(GLsizei n, GLuint* buffers); void glBindBuffer(GLenum target, GLuint buffer); void glBufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage); void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); void glEnableVertexAttribArray(GLuint index); void glDisableVertexAttribArray(GLuint index); void glDrawArrays(GLenum mode, GLint first, GLsizei count); void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices); #endif // #ifndef _GL_LIKE__H_ 
gl_like_gv.h
// gl_like_gv.h // jave.lin - global variables #include"gl_like.h" #ifndef _GL_LIKE_GV__H_ #define _GL_LIKE_GV__H_ Context* currentContext = NULL; GLint errorCode = 0; GLchar* errorMsg = NULL; #endif 
gl_like.cpp
// gl_like.cpp // jave.lin - 定义以及实现 // 实现不一定是按 OpenGL 来的,都只是自己看了一些官方文档了解功能后,而编写的功能 // 所以会出现,只实现了部分的功能,会之不对的功能 #include #include #include #include"gl_like_gv.h" #include"gl_like.h" extern Context* currentContext; extern GLint errorCode; extern GLchar* errorMsg; // // function - definition // /* 	暂时没用上,这时对 glVertexAttribPointer 是的 normalized 来确定要不要归一化数据额类型的,
	需要再传入(复制)到 GPU 前就得处理的归一化
// jave.lin : 这是处理数据类型归一化到单精度的过程
// 有符号数据类型归一化处理
templateinline GLfloat Normalized_signed(DataType value) {
    // jave.lin : 对应 Katex 是: f = \frac{c}{2^b-1}
    return (GLfloat)((value) / (std::pow(2, sizeof(DataType) * 8 - 1)));
}
// 无符号数据类型归一化处理
templateinline GLfloat Normalized_unsigned(DataType value) {
    // jave.lin : 对应 Katex 是: f = \frac{2c + 1}{2^b-1}
    return (GLfloat)((value * 2 + 1) / (std::pow(2, sizeof(DataType) * 8 - 1)));
}
*/ void PrintVertex(GLuint vertexID, VertexAttributeFormat* format, _ubuffer_T buffer) { std::cout << "VertexID:" << vertexID << " Location:" << format->index << " NumOfComponent:" << format->numOfComponent << " TypeOfComponent:" << format->typeOfComponent << " Normalized:" << (format->normalized == GL_TRUE ? "true" : "false") << " Strid:" << format->stride << " Pointer(Offset):" << ((GLuint)format->pointer) << "\n"; if (format->typeOfComponent == GL_FLOAT) { GLuint offset = (GLuint)format->pointer; GLfloat* pointer = (GLfloat*)(buffer + offset); std::cout << (format->numOfComponent == 1 ? "float" : "vec") << format->numOfComponent << "( "; for (size_t i = 0; i < format->numOfComponent; i++) { std::cout << *(pointer + i) << (i == (format->numOfComponent - 1) ? " " : ", "); } std::cout << ")"; } else { GLchar str[512]; sprintf_s(str, "PrintVertex Error, type of component unhandle : %d", format->typeOfComponent); throw str; } std::cout << "\n"; } // PrintVertex // // api function - definition // inline VertexArrayObject* Context::GetUsingVAO() const { // 如果没有绑定 VAO,就使用默认的 VAO return this->bindingVAO ? this->bindingVAO : this->defalultVAO; } // Context::GetUsingVAO // // construct function - definition // VertexArrayObject::VertexArrayObject() { this->vafs = new std::vector<VertexAttributeFormat*>; this->vafs_enabled = new std::vector<GLuint>(); } // VertexArrayObject Context::Context() { this->defalultVAO = new VertexArrayObject; this->VAOs = new std::vector<VertexArrayObject*>; this->BOs = new std::vector<BufferObject*>; } // Context // // destruct function - definition // _BuffObject::~_BuffObject() { if (this->data != NULL) free(this->data); this->data = NULL; } // ~_BuffObject BufferObject::~BufferObject() { if (this->buf != NULL) delete this->buf; this->buf = NULL; } // ~BufferObject VertexArrayObject::~VertexArrayObject() { this->vbo = NULL; this->ebo = NULL; if (this->vafs != NULL) { std::vector<VertexAttributeFormat*>::iterator begin = this->vafs->begin(); std::vector<VertexAttributeFormat*>::iterator end = this->vafs->end(); for (; begin != end; begin++) { delete* begin; } this->vafs->clear(); this->vafs = NULL; } if (this->vafs_enabled != NULL) { this->vafs_enabled->clear(); this->vafs_enabled = NULL; } } // VertexArrayObject VertexAttributeFormat::~VertexAttributeFormat() { this->pointer = NULL; } // ~VertexAttributeFormat Context::~Context() { if (this->VAOs != NULL) { std::vector<VertexArrayObject*>::iterator begin_vao = this->VAOs->begin(); std::vector<VertexArrayObject*>::iterator end_va0 = this->VAOs->end(); for (; begin_vao != end_va0; begin_vao++) { delete* begin_vao; } this->VAOs->clear(); this->VAOs = NULL; } if (this->BOs != NULL) { std::vector<BufferObject*>::iterator begin_vbo = this->BOs->begin(); std::vector<BufferObject*>::iterator end_vb0 = this->BOs->end(); for (; begin_vbo != end_vb0; begin_vbo++) { delete* begin_vbo; } this->BOs->clear(); this->BOs = NULL; } if (this->defalultVAO != NULL) { delete this->defalultVAO; this->defalultVAO = NULL; } this->bindingVAO = NULL; } // ~Context void Terminate() { if (currentContext != NULL) { delete currentContext; currentContext = NULL; } } // Terminater void MakeCurrentContext(GLuint context) { currentContext = (Context*)((void*)context); } // MakeCurrentContext void CheckBuffType(GLenum buffType) { switch (buffType) { case GL_ARRAY_BUFFER: // VBO break; case GL_ELEMENT_ARRAY_BUFFER: // EBO break; default: GLchar str[512]; sprintf_s(str, "binding unhandle buffer type : %d", buffType); Error(GL_BINDING_UN_HANDLE_BUFF_TYPE, (const GLchar*)str); break; } // end switch } // end CheckBuffType void Error(const GLuint ec, const GLchar* msg) { errorCode = ec; if (errorMsg == NULL) { errorMsg = (GLchar*)malloc(512); } strcpy_s(errorMsg, 512, msg); throw msg; } // end Error GLboolean CreateContext(GLuint major, GLuint minor, GLuint* context) { if (currentContext != NULL) { Error(GL_CONTEXT_NOT_NULL, (const GLchar*)"context not null"); return GL_FALSE; } Context* p = new Context(); *context = (GLuint) (p); if (p == NULL) { Error(GL_CREATE_FAILURE, (const GLchar*)"create context failure"); return GL_FALSE; } p->major = major; p->minor = minor; return GL_TRUE; } // end CreateContext // // gllike api // void glGenVertexArrays(GLsizei n, GLuint* arrays) { *arrays = 0; if (currentContext == NULL) { Error(GL_INVALIDATED_CONTEXT, (const GLchar*)"context == null"); return; } if ((currentContext->VAOs->size() + n) >= GL_MAX_NUM_OF_VAO) { Error(GL_OUT_BO_MAX_COUNT, (const GLchar*)"out of vao buffer object max count"); return; } for (size_t i = 0; i < n; i++) { // glGenVertexArrays 只生成空数据的指针 VAO 对象 VertexArrayObject* vao = new VertexArrayObject; *(arrays + i) = (GLuint)((void*)(vao)); if (*(arrays + i) == 0) { Error(GL_CREATE_FAILURE, (const GLchar*)"gen vao buffer failure"); return; } else { currentContext->VAOs->push_back(vao); } } } // end glGenVertexArrays void glDeleteVertexArrays(GLsizei n, GLuint* arrays) { for (size_t i = 0; i < n; i++) { VertexArrayObject* p = (VertexArrayObject*)(*(arrays + i)); std::vector<VertexArrayObject*>::const_iterator begin = currentContext->VAOs->begin(); std::vector<VertexArrayObject*>::const_iterator end = currentContext->VAOs->end(); for (; begin != end; begin++) { if (*begin == p) { currentContext->VAOs->erase(begin); break; } } delete p; *(arrays + i) = 0; } } // end glDeleteVertexArrays void glBindVertexArray(GLuint array) { currentContext->bindingVAO = (VertexArrayObject*)array; currentContext->defalultVAO->vbo = NULL; currentContext->defalultVAO->ebo = NULL; if (currentContext->defalultVAO->vafs != NULL) { std::vector<VertexAttributeFormat*>::const_iterator begin_vaf, end_vaf; begin_vaf = currentContext->defalultVAO->vafs->begin(); end_vaf = currentContext->defalultVAO->vafs->end(); for (; begin_vaf != end_vaf; begin_vaf++) { delete *begin_vaf; } currentContext->defalultVAO->vafs->clear(); } if (currentContext->defalultVAO->vafs_enabled != NULL) { currentContext->defalultVAO->vafs_enabled->clear(); } } // end glBindVertexArray void glGenBuffers(GLsizei n, GLuint* buffers) { *buffers = 0; if (currentContext == NULL) { Error(GL_INVALIDATED_CONTEXT, (const GLchar*)"context == null"); return; } if ((currentContext->BOs->size() + n) >= GL_MAX_NUM_OF_VBO) { Error(GL_OUT_BO_MAX_COUNT, (const GLchar*)"out of bo buffer object max count"); return; } for (size_t i = 0; i < n; i++) { // glGenBuffers 只生成空数据的指针 VBO 对象 BufferObject* vbo = new BufferObject; *(buffers + i) = (GLuint)((void*)(vbo)); if (*(buffers + i) == 0) { Error(GL_CREATE_FAILURE, (const GLchar*)"gen bo buffer failure"); return; } else { currentContext->BOs->push_back(vbo); } } } // glGenBuffers void glDeleteBuffers(GLsizei n, GLuint* buffers) { for (size_t i = 0; i < n; i++) { BufferObject* p = (BufferObject*)(*(buffers + i)); std::vector<BufferObject*>::const_iterator begin = currentContext->BOs->begin(); std::vector<BufferObject*>::const_iterator end = currentContext->BOs->end(); for (; begin != end; begin++) { if (*begin == p) { currentContext->BOs->erase(begin); break; } } delete p; *(buffers + i) = 0; } } // glDeleteBuffers void glBindBuffer(GLenum target, GLuint buffer) { CheckBuffType(target); switch (target) { case GL_ARRAY_BUFFER: // VBO currentContext->GetUsingVAO()->vbo = (BufferObject*)(buffer); break; case GL_ELEMENT_ARRAY_BUFFER: // EBO currentContext->GetUsingVAO()->ebo = (BufferObject*)(buffer); break; default: throw "un handle glBindBuffer target type"; break; } } // glBindBuffer void glBufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) { CheckBuffType(target); // usage 参数不使用,因为这个与硬件加速相关 GLboolean validated = true; _BuffObject** buffObj = NULL; // 目前只对两种缓存类型做处理 switch (target) { case GL_ARRAY_BUFFER: // VBO buffObj = &(currentContext->GetUsingVAO()->vbo->buf); break; case GL_ELEMENT_ARRAY_BUFFER: // EBO buffObj = &(currentContext->GetUsingVAO()->ebo->buf); break; default: validated = false; GLchar str[512]; sprintf_s(str, "binding unhandle buffer type : %d", target); Error(GL_BINDING_UN_HANDLE_BUFF_TYPE, (const GLchar*)str); break; } // end switch if (validated) { if (*buffObj == NULL) { *buffObj = new _BuffObject(); } if ((*buffObj)->size < size) { if ((*buffObj)->data == NULL) { (*buffObj)->data = (_ubuffer_T)malloc(size); } else { (*buffObj)->data = (_ubuffer_T)realloc((void*)((*buffObj)->data), size); } (*buffObj)->capacity = size; } (*buffObj)->size = size; memcpy((*buffObj)->data, data, size); } } // end glBufferData void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer) { std::vector<VertexAttributeFormat*>* pVec = currentContext->GetUsingVAO()->vafs; std::vector<VertexAttributeFormat*>::const_iterator begin = pVec->begin(); std::vector<VertexAttributeFormat*>::const_iterator end = pVec->end(); bool found = false; VertexAttributeFormat* p = NULL; for (; begin != end; begin++) { p = *begin; if (p->index == index) { // 先看看目前有无重复设置的 found = true; // 有重复的 break; } } if (!found) { // 没有重复的,则新建一个 p = new VertexAttributeFormat; p->index = index; pVec->push_back(p); } if (pVec->size() > 128) { // 假装最多只能有 128 个 vertex attribute GLchar str[512]; sprintf_s(str, "glVertexAttribPointer number of vertex attribute more than 128"); throw str; } p->numOfComponent = size; p->typeOfComponent = type; p->normalized = normalized; p->stride = stride; p->pointer = (void*)pointer; p->setupToVBO = (GLuint)((void*)currentContext->GetUsingVAO()->vbo); // 记录安装时的 VBO 是哪个 } // end glVertexAttribPointer void glEnableVertexAttribArray(GLuint index) { std::vector<GLuint>* pVec = currentContext->GetUsingVAO()->vafs_enabled; // 启用 attribute 的数据记录 std::vector<GLuint>::const_iterator begin = pVec->begin(); std::vector<GLuint>::const_iterator end = pVec->end(); VertexAttributeFormat* p = NULL; bool found = false; for (; begin != end; begin++) { if ((*begin) == index) { // 如果本身是启用的,则不添加 found = true; break; } } if (found == false) { // 如果没有启用,则添加 pVec->push_back(index); } } // end glEnableVertexAttribArray void glDisableVertexAttribArray(GLuint index) { std::vector<GLuint>* pVec = currentContext->GetUsingVAO()->vafs_enabled; std::vector<GLuint>::const_iterator begin = pVec->begin(); std::vector<GLuint>::const_iterator end = pVec->end(); VertexAttributeFormat* p = NULL; for (; begin != end; begin++) { if ((*begin) == index) { pVec->erase(begin); // 找到启用的 attribute 索引,就删除 break; } } } // end glDisableVertexAttribArray void glDrawArrays(GLenum mode, GLint first, GLsizei count) { if (mode == GL_TRIANGLES) { // 目前只支持三角形 std::cout << "glDrawArray mode : GL_TRIANGLES\n"; if (count <= 0 || count % 3 != 0) { // 如果绘制的索引数量不是 3 的倍数,则报错 GLchar str[512]; sprintf_s(str, "glDrawArrays mode is triangle, but 'count' not the times of three : %d", count); throw str; } VertexArrayObject* vao; std::vector<GLuint>::const_iterator begin_enabled_index, end_enabled_index; std::vector<VertexAttributeFormat*>::const_iterator begin_vaf, end_vaf; vao = currentContext->GetUsingVAO(); // 使用的 VAO end_enabled_index = vao->vafs_enabled->end(); // 顶点规范的启用索引数组 end_vaf = vao->vafs->end(); // 遍历顶点数 for (size_t i = 0; i < count; i ++) { // 遍历属性索引 begin_enabled_index = vao->vafs_enabled->begin(); for (; begin_enabled_index != end_enabled_index; begin_enabled_index++) { GLboolean found = false; // 查找属性索引对应的格式(规范) begin_vaf = vao->vafs->begin(); for (; begin_vaf != end_vaf; begin_vaf++) { if ((*begin_vaf)->index == *begin_enabled_index) { found = true; break; } } // 如果找不到启用的 attribute,则报错(OpenGL 这里会使用 静态的顶点属性,这里就不实现了,直接报错) if (!found) { GLchar str[512]; sprintf_s(str, "glDrawArrays mode is triangle, but not found attribute loation : %d", *begin_enabled_index); throw str; } // 取格式(规范)中绑定的 VBO BufferObject* vbo = (BufferObject*)((*begin_vaf)->setupToVBO); // 取 VBO 中的数据 _ubuffer_T buffer = (vbo->buf->data); // 取顶点的偏移,按 stride 来偏移 // 这里为了测试 VAO 整体应用,只打印一下数据即可 // 其实也可以再写个 C++ 版本的软渲染器来替换这里的打印也是可以的 GLuint offset = ((GLuint)((*begin_vaf)->stride)) * i; PrintVertex(i, *begin_vaf, buffer + offset); } } } else { GLchar str[512]; sprintf_s(str, "unhandle glDrawArrays mode : %d", mode); throw str; } } // end glDrawArrays void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) { if (mode == GL_TRIANGLES) { // 目前只支持三角形 std::cout << "glDrawElements mode : GL_TRIANGLES\n"; if (count <= 0 || count % 3 != 0) { // 如果绘制的索引数量不是 3 的倍数,则报错 GLchar str[512]; sprintf_s(str, "glDrawElements mode is triangle, but 'count' not the times of three : %d", count); throw str; } VertexArrayObject* vao; BufferObject* ebo; GLuint vertexIndex; std::vector<GLuint>::const_iterator begin_enabled_index, end_enabled_index; std::vector<VertexAttributeFormat*>::const_iterator begin_vaf, end_vaf; vao = currentContext->GetUsingVAO(); ebo = vao->ebo; end_enabled_index = vao->vafs_enabled->end(); end_vaf = vao->vafs->end(); if (type != GL_UNSIGNED_INT) { GLchar str[512]; sprintf_s(str, "glDrawElements unhandle type : %d", type); throw str; } GLuint* indexBuffer = (GLuint*)(ebo->buf->data + (GLuint)indices); // 真正的索引缓存数据 // 根据索引遍历顶点数 for (size_t i = 0; i < count; i++) { // 获取 EBO 中的索引值 vertexIndex = *(indexBuffer + i); // 遍历属性索引 begin_enabled_index = vao->vafs_enabled->begin(); for (; begin_enabled_index != end_enabled_index; begin_enabled_index++) { GLboolean found = false; // 查找属性索引对应的格式(规范) begin_vaf = vao->vafs->begin(); for (; begin_vaf != end_vaf; begin_vaf++) { if ((*begin_vaf)->index == *begin_enabled_index) { found = true; break; } } if (!found) { GLchar str[512]; sprintf_s(str, "glDrawElements mode is triangle, but not found attribute loation : %d", *begin_enabled_index); throw str; } // 取格式(规范)中绑定的 VBO BufferObject* vbo = (BufferObject*)((*begin_vaf)->setupToVBO); // 取 VBO 中的数据 _ubuffer_T buffer = (vbo->buf->data); // 取顶点的偏移,按 stride 来偏移 // 这里为了测试 VAO 整体应用,只打印一下数据即可 // 其实也可以再写个 C++ 版本的软渲染器来替换这里的打印也是可以的 GLuint offset = ((GLuint)((*begin_vaf)->stride)) * vertexIndex; // 使用索引值来偏移 VBO 数据 PrintVertex(i, *begin_vaf, buffer + offset); } } } else { GLchar str[512]; sprintf_s(str, "unhandle glDrawElements mode : %d", mode); throw str; } } // end glDrawElements 
Main.cpp
// Main.cpp // jave.lin - 测试自己写的 gllike,目前为了测试 VAO/VBO/EBO 等接口的使用 #include #include #include"gl_like.h" extern Context* currentContext; extern GLint errorCode; extern GLchar* errorMsg; void PrintGlobalError() { GLchar errorCodeMeans[512] = { 0 }; switch (errorCode) { case GL_INVALIDATED_CONTEXT: strcpy_s(errorCodeMeans, 512, "Invalidated context"); break; case GL_OUT_BO_MAX_COUNT: strcpy_s(errorCodeMeans, 512, "Out of buffer object max count"); break; case GL_CREATE_FAILURE: strcpy_s(errorCodeMeans, 512, "Create / alloc failure"); break; case GL_CONTEXT_NOT_NULL: strcpy_s(errorCodeMeans, 512, "Context not null"); break; case GL_BINDING_UN_HANDLE_BUFF_TYPE: strcpy_s(errorCodeMeans, 512, "Binding unhandle buffer type"); break; case GL_SET_BUFF_VALUES_BUFF_NULL: strcpy_s(errorCodeMeans, 512, "Buffer is NULL, while Setting buffer"); break; default: break; } if (errorCode != 0) { std::cout << "Error Code : " << errorCode << ", Mean : " << errorCodeMeans << ", Message : " << (errorMsg == NULL ? "" : errorMsg) << "\n"; } } void testDrawTriangleByOnlyVBO_2FloatComponent() { GLuint vbo; // 生成 VBO glGenBuffers(1, &vbo); if (vbo == 0) { std::cout << "Generate VBO Buffer Failure : " << vbo << "\n"; exit(EXIT_FAILURE); } // 顶点 GLfloat vertices[9] = { -0.5f, -0.5f, +0.5f, -0.5f, +0.0f, +0.5f, }; // 绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, vbo); // 设置 VBO 数据 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 设置 0 索引顶点属性 VBO 格式 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, (GLsizei)sizeof(GLfloat) * 2, 0); // 启用 0 索引顶点属性 VBO 格式 glEnableVertexAttribArray(0); // 绘制 VBO 内容 glDrawArrays(GL_TRIANGLES, 0, 3); // 禁用 0 索引顶点属性 VBO 格式 glDisableVertexAttribArray(0); // 取消绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, 0); // 删除 VBO glDeleteBuffers(1, &vbo); } // testDrawTriangleByOnlyVBO void testDrawTriangleByOnlyVBO() { GLuint vbo; // 生成 VBO glGenBuffers(1, &vbo); if (vbo == 0) { std::cout << "Generate VBO Buffer Failure : " << vbo << "\n"; exit(EXIT_FAILURE); } // 顶点 GLfloat vertices[9] = { -0.5f, -0.5f, +0.0f, +0.5f, -0.5f, +0.0f, +0.0f, +0.5f, +0.0f, }; // 绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, vbo); // 设置 VBO 数据 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 设置 0 索引顶点属性 VBO 格式 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, (GLsizei)sizeof(GLfloat) * 3, 0); // 启用 0 索引顶点属性 VBO 格式 glEnableVertexAttribArray(0); // 绘制 VBO 内容 glDrawArrays(GL_TRIANGLES, 0, 3); // 禁用 0 索引顶点属性 VBO 格式 glDisableVertexAttribArray(0); // 取消绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, 0); // 删除 VBO glDeleteBuffers(1, &vbo); } // testDrawTriangleByOnlyVBO void testDrawQuadByOnlyVBO() { GLuint vbo; // 生成 VBO glGenBuffers(1, &vbo); if (vbo == 0) { std::cout << "Generate VBO Buffer Failure : " << vbo << "\n"; exit(EXIT_FAILURE); } // 顶点 GLfloat vertices[18] = { -0.5f, -0.5f, +0.0f, +0.5f, -0.5f, +0.0f, -0.5f, +0.5f, +0.0f, +0.5f, -0.5f, +0.0f, +0.5f, +0.5f, +0.0f, -0.5f, +0.5f, +0.0f, }; // 绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, vbo); // 设置 VBO 数据 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 设置 0 索引顶点属性 VBO 格式 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, (GLsizei)sizeof(GLfloat) * 3, 0); // 启用 0 索引顶点属性 VBO 格式 glEnableVertexAttribArray(0); // 绘制 VBO 内容 glDrawArrays(GL_TRIANGLES, 0, 6); // 禁用 0 索引顶点属性 VBO 格式 glDisableVertexAttribArray(0); // 取消绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, 0); // 删除 VBO glDeleteBuffers(1, &vbo); } // testDrawQuadByOnlyVBO void testDrawQuadByOnlyVBO_2Attribute_Pos_Col_inSingleVBO() { GLuint vbo; // 生成 VBO glGenBuffers(1, &vbo); if (vbo == 0) { std::cout << "Generate VBO Buffer Failure : " << vbo << "\n"; exit(EXIT_FAILURE); } // 顶点 GLfloat vertices[36] = { // x	y	  z			r	  g		b -0.5f, -0.5f, +0.0f, 1.0f, 0.0f, 0.0f, +0.5f, -0.5f, +0.0f, 0.0f, 1.0f, 0.0f, -0.5f, +0.5f, +0.0f, 0.0f, 0.0f, 1.0f, +0.5f, -0.5f, +0.0f, 0.0f, 1.0f, 0.0f, +0.5f, +0.5f, +0.0f, 1.0f, 1.0f, 0.0f, -0.5f, +0.5f, +0.0f, 0.0f, 0.0f, 1.0f, }; // 绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, vbo); // 设置 VBO 数据 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 设置 0 索引顶点属性 VBO 格式 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, (GLsizei)sizeof(GLfloat) * 6, 0); // 设置 1 索引顶点属性 VBO 格式 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, (GLsizei)sizeof(GLfloat) * 6, (const void*)(sizeof(GLfloat) * 3)); // 启用 0 索引顶点属性 VBO 格式 glEnableVertexAttribArray(0); // 启用 1 索引顶点属性 VBO 格式 glEnableVertexAttribArray(1); // 绘制 VBO 内容 glDrawArrays(GL_TRIANGLES, 0, 6); // 禁用 0 索引顶点属性 VBO 格式 glDisableVertexAttribArray(0); // 禁用 1 索引顶点属性 VBO 格式 glDisableVertexAttribArray(1); // 取消绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, 0); // 删除 VBO glDeleteBuffers(1, &vbo); } // testDrawQuadByOnlyVBO void testDrawQuadByOnlyVBO_2Attribute_Pos_Col_TwoVBO() { GLuint vbo[2]; // 生成 VBO glGenBuffers(2, vbo); if (vbo[0] == 0 || vbo[1] == 0) { std::cout << "Generate VBO Buffer Failure : [0]=" << vbo[0] << "[1]=" << vbo[1] << "\n"; exit(EXIT_FAILURE); } // 顶点 GLfloat vertices[18] = { // x	y	  z  -0.5f, -0.5f, +0.0f, +0.5f, -0.5f, +0.0f, -0.5f, +0.5f, +0.0f, +0.5f, -0.5f, +0.0f, +0.5f, +0.5f, +0.0f, -0.5f, +0.5f, +0.0f, }; // 颜色 GLfloat colors[18] = { //r	  g		b 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; // 绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); // 设置 VBO 数据 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 设置 0 索引顶点属性 VBO 格式 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, (GLsizei)sizeof(GLfloat) * 3, 0); // 启用 0 索引顶点属性 VBO 格式 glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); // 设置 VBO 数据 glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); // 设置 0 索引顶点属性 VBO 格式 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, (GLsizei)sizeof(GLfloat) * 3, 0); // 启用 0 索引顶点属性 VBO 格式 glEnableVertexAttribArray(1); // 绘制 VBO 内容 glDrawArrays(GL_TRIANGLES, 0, 6); // 禁用 0 索引顶点属性 VBO 格式 glDisableVertexAttribArray(0); // 禁用 1 索引顶点属性 VBO 格式 glDisableVertexAttribArray(1); // 取消绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, 0); // 删除 VBO glDeleteBuffers(2, vbo); } // testDrawQuadByOnlyVBO void testVAO_VBO_EBO_vertex_single_buff() { GLuint vao; // 生成 VAO glGenVertexArrays(1, &vao); if (vao == 0) { std::cout << "Generate VAO Buffer Failure : " << vao << "\n"; exit(EXIT_FAILURE); } GLuint vbo; // 生成 VBO glGenBuffers(1, &vbo); if (vbo == 0) { std::cout << "Generate VBO Buffer Failure : " << vbo << "\n"; exit(EXIT_FAILURE); } GLuint ebo; // 生成 EBO glGenBuffers(1, &ebo); if (ebo == 0) { std::cout << "Generate EBO Buffer Failure : " << ebo << "\n"; exit(EXIT_FAILURE); } // 顶点 GLfloat vertices[24] = { // x	y	  z			r	  g		b -0.5f, -0.5f, +0.0f, 1.0f, 0.0f, 0.0f, +0.5f, -0.5f, +0.0f, 0.0f, 1.0f, 0.0f, +0.5f, +0.5f, +0.0f, 0.0f, 0.0f, 1.0f, -0.5f, +0.5f, +0.0f, 1.0f, 1.0f, 0.0f, }; // 索引 GLuint indices[] = { 0, 1, 3, 1, 2, 3 }; // 绑定 VAO glBindVertexArray(vao); // 绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, vbo); // 设置 VBO 数据 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 绑定 EBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); // 设置 EBO 数据 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // 设置 0 索引顶点属性 VBO 格式 glVertexAttribPointer(0, 3, GL_FLOAT, GL_TRUE, (GLsizei)sizeof(GLfloat) * 6, 0); // 设置 1 索引顶点属性 VBO 格式 glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, (GLsizei)sizeof(GLfloat) * 6, (void*)(sizeof(GLfloat) * 3)); // 启用 0 索引顶点属性 VBO 格式 glEnableVertexAttribArray(0); // 启用 1 索引顶点属性 VBO 格式 glEnableVertexAttribArray(1); // 绘制 EBO 内容,当前我们绑定了 VAO 的,所以使用的是 VAO 内的 EBO glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // 禁用 0 索引顶点属性 VBO 格式 glDisableVertexAttribArray(0); // 禁用 1 索引顶点属性 VBO 格式 glDisableVertexAttribArray(1); // 取消绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, 0); // 取消绑定 EBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // 取消绑定 VAO glBindVertexArray(0); // 删除 EBO glDeleteBuffers(1, &ebo); // 删除 VBO glDeleteBuffers(1, &vbo); // 删除 VAO glDeleteVertexArrays(1, &vao); } void testMultiVAO() { GLuint vao[2]; // 生成 VAO glGenVertexArrays(2, vao); if (vao[0] == 0 || vao[1] == 0) { std::cout << "Generate VAO Buffer Failure : [0]=" << vao[0] << " [1]=" << vao[1] << "\n"; exit(EXIT_FAILURE); } GLuint vbo[2]; // 生成 VBO glGenBuffers(2, vbo); if (vbo[0] == 0 || vbo[1] == 0) { std::cout << "Generate VBO Buffer Failure : [0]=" << vbo[0] << " [1]=" << vbo[1] << "\n"; exit(EXIT_FAILURE); } GLuint ebo[2]; // 生成 EBO glGenBuffers(2, ebo); if (ebo[0] == 0 || ebo[1] == 0) { std::cout << "Generate EBO Buffer Failure : [0]=" << ebo[0] << " [1]=" << ebo[1] << "\n"; exit(EXIT_FAILURE); } // // 第一个 VAO 的设置 // // 顶点 GLfloat vertices_0[24] = { // x	y	  z			r	  g		b -0.5f, -0.5f, +0.0f, 1.0f, 0.0f, 0.0f, +0.5f, -0.5f, +0.0f, 0.0f, 1.0f, 0.0f, +0.5f, +0.5f, +0.0f, 0.0f, 0.0f, 1.0f, -0.5f, +0.5f, +0.0f, 1.0f, 1.0f, 0.0f, }; // 索引 GLuint indices_0[] = { 0, 1, 3, 1, 2, 3 }; // 绑定 VAO[0] glBindVertexArray(vao[0]); // 绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); // 设置 VBO 数据 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_0), vertices_0, GL_STATIC_DRAW); // 绑定 EBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); // 设置 EBO 数据 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices_0), indices_0, GL_STATIC_DRAW); // 设置 0 索引顶点属性 VBO 格式 glVertexAttribPointer(0, 3, GL_FLOAT, GL_TRUE, (GLsizei)sizeof(GLfloat) * 6, 0); // 设置 1 索引顶点属性 VBO 格式 glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, (GLsizei)sizeof(GLfloat) * 6, (void*)(sizeof(GLfloat) * 3)); // 启用 0 索引顶点属性 VBO 格式 glEnableVertexAttribArray(0); // 启用 1 索引顶点属性 VBO 格式 glEnableVertexAttribArray(1); // // 第二个 VAO 的设置 // // 顶点 GLfloat vertices_1[18] = { // x	y	  z			r	  g		b -0.5f, -0.5f, +0.0f, 1.0f, 0.0f, 0.0f, +0.5f, -0.5f, +0.0f, 0.0f, 1.0f, 0.0f, +0.5f, +0.5f, +0.0f, 0.0f, 0.0f, 1.0f, }; // 索引 GLuint indices_1[] = { 0, 1, 2 }; // 绑定 VAO[0] glBindVertexArray(vao[1]); // 绑定 VBO glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); // 设置 VBO 数据 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_1), vertices_1, GL_STATIC_DRAW); // 绑定 EBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[1]); // 设置 EBO 数据 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices_1), indices_1, GL_STATIC_DRAW); // 设置 0 索引顶点属性 VBO 格式 glVertexAttribPointer(0, 3, GL_FLOAT, GL_TRUE, (GLsizei)sizeof(GLfloat) * 6, 0); // 设置 1 索引顶点属性 VBO 格式 glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, (GLsizei)sizeof(GLfloat) * 6, (void*)(sizeof(GLfloat) * 3)); // 启用 0 索引顶点属性 VBO 格式 glEnableVertexAttribArray(0); // 启用 1 索引顶点属性 VBO 格式 glEnableVertexAttribArray(1); // // 开始绘制 // // 绘制第一个 VAO glBindVertexArray(vao[0]); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // 绘制第二个 VAO glBindVertexArray(vao[1]); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); // 取消绑定 VAO glBindVertexArray(0); // 删除 EBO glDeleteBuffers(2, ebo); // 删除 VBO glDeleteBuffers(2, vbo); // 删除 VAO glDeleteVertexArrays(2, vao); } int main() { GLuint context; if (!CreateContext(4, 6, &context)) { std::cout << "Create Context Failure\n"; exit(EXIT_FAILURE); } MakeCurrentContext(context); std::cout << " === Testing [testDrawTriangleByOnlyVBO_2FloatComponent] START ===\n"; testDrawTriangleByOnlyVBO_2FloatComponent(); std::cout << " === Testing [testDrawTriangleByOnlyVBO_2FloatComponent] END ===\n\n"; std::cout << " === Testing [testDrawTriangleByOnlyVBO] START ===\n"; testDrawTriangleByOnlyVBO(); std::cout << " === Testing [testDrawTriangleByOnlyVBO] END ===\n\n"; std::cout << " === Testing [testDrawQuadByOnlyVBO] START ===\n"; testDrawQuadByOnlyVBO(); std::cout << " === Testing [testDrawQuadByOnlyVBO] END ===\n\n"; std::cout << " === Testing [testDrawQuadByOnlyVBO_2Attribute_Pos_Col_inSingleVBO] START ===\n"; testDrawQuadByOnlyVBO_2Attribute_Pos_Col_inSingleVBO(); std::cout << " === Testing [testDrawQuadByOnlyVBO_2Attribute_Pos_Col_inSingleVBO] END ===\n\n"; std::cout << " === Testing [testDrawQuadByOnlyVBO_2Attribute_Pos_Col_TwoVBO] START ===\n"; testDrawQuadByOnlyVBO_2Attribute_Pos_Col_TwoVBO(); std::cout << " === Testing [testDrawQuadByOnlyVBO_2Attribute_Pos_Col_TwoVBO] END ===\n\n"; std::cout << " === Testing [testVAO_VBO_EBO_vertex_single_buff] START ===\n"; testVAO_VBO_EBO_vertex_single_buff(); std::cout << " === Testing [testVAO_VBO_EBO_vertex_single_buff] END ===\n\n"; std::cout << " === Testing [testMultiVAO] START ===\n"; testMultiVAO(); std::cout << " === Testing [testMultiVAO] END ===\n\n"; // 实现分开的 VBO Terminate(); PrintGlobalError(); return 0; } 
运行效果
=== Testing [testDrawTriangleByOnlyVBO_2FloatComponent] START === glDrawArray mode : GL_TRIANGLES
VertexID:0 Location:0 NumOfComponent:2 TypeOfComponent:5126 Normalized:false Strid:8 Pointer(Offset):0 vec2( -0.5, -0.5 ) VertexID:1 Location:0 NumOfComponent:2 TypeOfComponent:5126 Normalized:false Strid:8 Pointer(Offset):0 vec2( 0.5, -0.5 ) VertexID:2 Location:0 NumOfComponent:2 TypeOfComponent:5126 Normalized:false Strid:8 Pointer(Offset):0 vec2( 0, 0.5 ) === Testing [testDrawTriangleByOnlyVBO_2FloatComponent] END === === Testing [testDrawTriangleByOnlyVBO] START === glDrawArray mode : GL_TRIANGLES
VertexID:0 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( -0.5, -0.5, 0 ) VertexID:1 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:2 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0, 0.5, 0 ) === Testing [testDrawTriangleByOnlyVBO] END === === Testing [testDrawQuadByOnlyVBO] START === glDrawArray mode : GL_TRIANGLES
VertexID:0 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( -0.5, -0.5, 0 ) VertexID:1 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:2 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( -0.5, 0.5, 0 ) VertexID:3 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:4 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0.5, 0.5, 0 ) VertexID:5 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( -0.5, 0.5, 0 ) === Testing [testDrawQuadByOnlyVBO] END === === Testing [testDrawQuadByOnlyVBO_2Attribute_Pos_Col_inSingleVBO] START === glDrawArray mode : GL_TRIANGLES
VertexID:0 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):0 vec3( -0.5, -0.5, 0 ) VertexID:0 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):12 vec3( 1, 0, 0 ) VertexID:1 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:1 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):12 vec3( 0, 1, 0 ) VertexID:2 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):0 vec3( -0.5, 0.5, 0 ) VertexID:2 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):12 vec3( 0, 0, 1 ) VertexID:3 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:3 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):12 vec3( 0, 1, 0 ) VertexID:4 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):0 vec3( 0.5, 0.5, 0 ) VertexID:4 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):12 vec3( 1, 1, 0 ) VertexID:5 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):0 vec3( -0.5, 0.5, 0 ) VertexID:5 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:24 Pointer(Offset):12 vec3( 0, 0, 1 ) === Testing [testDrawQuadByOnlyVBO_2Attribute_Pos_Col_inSingleVBO] END === === Testing [testDrawQuadByOnlyVBO_2Attribute_Pos_Col_TwoVBO] START === glDrawArray mode : GL_TRIANGLES
VertexID:0 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( -0.5, -0.5, 0 ) VertexID:0 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 1, 0, 0 ) VertexID:1 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:1 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0, 1, 0 ) VertexID:2 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( -0.5, 0.5, 0 ) VertexID:2 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0, 0, 1 ) VertexID:3 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:3 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0, 1, 0 ) VertexID:4 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0.5, 0.5, 0 ) VertexID:4 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 1, 1, 0 ) VertexID:5 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( -0.5, 0.5, 0 ) VertexID:5 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:false Strid:12 Pointer(Offset):0 vec3( 0, 0, 1 ) === Testing [testDrawQuadByOnlyVBO_2Attribute_Pos_Col_TwoVBO] END === === Testing [testVAO_VBO_EBO_vertex_single_buff] START === glDrawElements mode : GL_TRIANGLES
VertexID:0 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( -0.5, -0.5, 0 ) VertexID:0 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 1, 0, 0 ) VertexID:1 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:1 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 0, 1, 0 ) VertexID:2 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( -0.5, 0.5, 0 ) VertexID:2 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 1, 1, 0 ) VertexID:3 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:3 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 0, 1, 0 ) VertexID:4 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( 0.5, 0.5, 0 ) VertexID:4 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 0, 0, 1 ) VertexID:5 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( -0.5, 0.5, 0 ) VertexID:5 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 1, 1, 0 ) === Testing [testVAO_VBO_EBO_vertex_single_buff] END === === Testing [testMultiVAO] START === glDrawElements mode : GL_TRIANGLES
VertexID:0 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( -0.5, -0.5, 0 ) VertexID:0 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 1, 0, 0 ) VertexID:1 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:1 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 0, 1, 0 ) VertexID:2 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( -0.5, 0.5, 0 ) VertexID:2 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 1, 1, 0 ) VertexID:3 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:3 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 0, 1, 0 ) VertexID:4 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( 0.5, 0.5, 0 ) VertexID:4 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 0, 0, 1 ) VertexID:5 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( -0.5, 0.5, 0 ) VertexID:5 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 1, 1, 0 ) glDrawElements mode : GL_TRIANGLES
VertexID:0 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( -0.5, -0.5, 0 ) VertexID:0 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 1, 0, 0 ) VertexID:1 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( 0.5, -0.5, 0 ) VertexID:1 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 0, 1, 0 ) VertexID:2 Location:0 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):0 vec3( 0.5, 0.5, 0 ) VertexID:2 Location:1 NumOfComponent:3 TypeOfComponent:5126 Normalized:true Strid:24 Pointer(Offset):12 vec3( 0, 0, 1 ) === Testing [testMultiVAO] END === 
关注
打赏
1688896170
查看更多评论

暂无认证

  • 6浏览

    0关注

    115984博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.2410s