CCVertexIndexData 主要用于保存实际持有vbo的VertexBuffer 类和 VertexStreanAtrribute 结构体的文件。 #1 VertexData 实际使用的对象

class CC_DLL VertexData : public Ref
{
public:/**Create function, used to create a instance of VertexData.*/static VertexData* create();/**Get the number of streams in the VertexData.*/size_t getVertexStreamCount() const;/**Set a stream to VertexData,given that stream is identified by semantic, so if the semantic is notspecified before, it will add a stream, or it will override the old one.@param buffer The binding buffer of the stream.@param stream The binding vertex attribute, its member semantic will be used as the identifier.*/bool setStream(VertexBuffer* buffer, const VertexStreamAttribute& stream);/**Remove the given streams.@param semantic The semantic of the stream.*/void removeStream(int semantic);/**Get the attribute of stream, const version.@param semantic The semantic of the stream.*/const VertexStreamAttribute* getStreamAttribute(int semantic) const;/**Get the attribute of stream.@param semantic The semantic of the stream.*/VertexStreamAttribute* getStreamAttribute(int semantic);/**Get the binded buffer of the stream.@param semantic The semantic of the stream.*/VertexBuffer* getStreamBuffer(int semantic) const;/**Called for rendering, it will bind the state of vertex data to current rendering pipeline.*/void use();
//.......
protected:/**Simple struct to bundle buffer and attribute.*/struct BufferAttribute{VertexBuffer* _buffer;VertexStreamAttribute _stream;};/**Streams in the VertexData.*/std::map<int, BufferAttribute> _vertexStreams;
};
复制代码

其中除了一系列设置属性获取属性的方法外最重要的就是 _vertexStreams 和 use()方法 _vertexStreams 保存了持有gl层使用 的顶点缓存对像即vbo的vertexBuffer 和用于glVertexAttributePointer*()方法的 VertexStreamAttribute 结构体, 实际的使用方法都在use方法内

void VertexData::use()
{uint32_t flags(0);for(auto& element : _vertexStreams){flags = flags | (1 << element.second._stream._semantic);}GL::enableVertexAttribs(flags);int lastVBO = -1;for(auto& element : _vertexStreams){//glEnableVertexAttribArray((GLint)element.second._stream._semantic);auto vertexStreamAttrib = element.second._stream;auto vertexBuffer = element.second._buffer;// don't call glBindBuffer() if not needed. Expensive operation.int vbo = vertexBuffer->getVBO();if (vbo != lastVBO) {glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->getVBO());lastVBO = vbo;}glVertexAttribPointer(GLint(vertexStreamAttrib._semantic),vertexStreamAttrib._size,vertexStreamAttrib._type,vertexStreamAttrib._normalize,vertexBuffer->getSizePerVertex(),(GLvoid*)((long)vertexStreamAttrib._offset));}
}
复制代码

glVertexAttribPointer方法各参数的意义在之前的日记中有提到过这里就不说明了,会与 对应的vertexStreamAttribute各参数的一同说明

#VertexStreamAttribute 保存了顶点着色器的顶点属性的绑定参数

struct CC_DLL VertexStreamAttribute
{/**Constructor.*/VertexStreamAttribute(): _normalize(false),_offset(0),_semantic(0),_type(0),_size(0){}/**Constructor@param offset The offset of the attribute.@param semantic The semantic (Position, Texcoord, Color etc) of attribute.@param type The type of attribute, could be GL_FLOAT, GL_UNSIGNED_BYTE etc.@param size Describe how many elements of type in the attribute.*/VertexStreamAttribute(int offset, int semantic, int type, int size): _normalize(false),_offset(offset),_semantic(semantic),_type(type),_size(size){}/**Constructor@param offset The offset of the attribute.@param semantic The semantic (Position, Texcoord, Color etc) of attribute.@param type The type of attribute, could be GL_FLOAT, GL_UNSIGNED_BYTE etc.@param size Describe how many elements of type in the attribute.@param normalize If true, the data will be normalized by dividing 255.*/VertexStreamAttribute(int offset, int semantic, int type, int size, bool normalize): _normalize(normalize),_offset(offset),_semantic(semantic),_type(type),_size(size){}/**Whether the attribute should be normalized or not.*/bool _normalize;/**The offset of the attribute in the buffer.*/int _offset;/**Describe that the attribute usage, could be Position, Color etc.这里应该对应的是之前GLProgram里声明的顶点属性名称 枚举里的值*/int _semantic;/**Describe the type of attribute, could be GL_FLOAT, GL_UNSIGNED_BYTE etc.*/int _type;/**Describe how many elements of type in the attribute.*/int _size;
};
复制代码

感觉这个应该放在上面的VertexData的use方法上面说明,应该更合适些 这里估计一种顶点属性就会有一个对应的VertexStreamAttribute 所以如果你需要往顶点shader里传递Position TexCoord 等多个绑定顶点属性时就需要创建多个VertexStreamAttribute, 这些都是在引擎底层实现的使用者基本上不需要去管理

VertexBuffer

实际持有opengl 提供的vbo索引的cocos对象

lass CC_DLL VertexBuffer : public Ref
{
public:/**Create an instance of VertexBuffer.@param sizePerVertex Size in bytes of one vertex.@param vertexNumber The number of vertex.@param usage A hint to indicate whether the vertexBuffer are updated frequently or not to let GL optimise it.*/static VertexBuffer* create(int sizePerVertex, int vertexNumber, GLenum usage = GL_STATIC_DRAW);/**Get the size in bytes of one vertex.*/int getSizePerVertex() const;/**Get the number of vertices.*/int getVertexNumber() const;/**Update all or part of vertices data, if the range specified exceeds the vertex buffer, it will be clipped.@param verts The pointer of the vertex data.@param count The number of vertices to update.@param begin The first vertex to update.*/bool updateVertices(const void* verts, int count, int begin);/**Get the size of the vertex array in bytes, equals getSizePerVertex() * getVertexNumber().*/int getSize() const;/**Get the internal openGL handle.*/GLuint getVBO() const;protected:/**Constructor.*/VertexBuffer();/**Destructor.*/virtual ~VertexBuffer();/**Init the storage of vertex buffer.@param sizePerVertex Size in bytes of one vertex.@param vertexNumber The number of vertex.@param usage A hint to indicate whether the vertexBuffer are updated frequently or not to let GL optimise it.*/bool init(int sizePerVertex, int vertexNumber, GLenum usage = GL_STATIC_DRAW);
protected:/**Event handler for foreground.*/void recreateVBO() const;/**Event listener for foreground.*/EventListenerCustom* _recreateVBOEventListener;
protected:/**Internal handle for openGL.*/mutable GLuint _vbo;/**Size in bytes for one vertex.*/int _sizePerVertex;/**Number of vertices.*/int _vertexNumber;/**Buffer used for shadow copy.*/std::vector<unsigned char> _shadowCopy;/**Hint for optimisation in GL.*/GLenum _usage;
protected:/**Static member to indicate that use _shadowCopy or not. */static bool _enableShadowCopy;
public:/**Static getter for shadowCopy.*/static bool isShadowCopyEnabled() { return _enableShadowCopy; }/**Static setter for shadowCopy.*/static void enableShadowCopy(bool enabled) { _enableShadowCopy = enabled; }
};
复制代码

如果有opengl基础的同学估计看到这些方法的时候就知道这个类是干什么的了

bool VertexBuffer::init(int sizePerVertex, int vertexNumber, GLenum usage/* = GL_STATIC_DRAW*/)
{if(0 == sizePerVertex || 0 == vertexNumber)return false;_sizePerVertex = sizePerVertex;_vertexNumber = vertexNumber;_usage = usage;if(isShadowCopyEnabled()){_shadowCopy.resize(sizePerVertex * _vertexNumber);}glGenBuffers(1, &_vbo);glBindBuffer(GL_ARRAY_BUFFER, _vbo);glBufferData(GL_ARRAY_BUFFER, getSize(), nullptr, _usage);glBindBuffer(GL_ARRAY_BUFFER, 0);return true;
}
复制代码

看到上面init函数的实现后是不是一下子就看懂了,这就是个用来管理对应VBO的管理对象(Cocos中使用了大量这种对象, 基本上使用到的opengl里的handler都有对应的管理对象,就像CCGLProgram)

bool VertexBuffer::updateVertices(const void* verts, int count, int begin)
{if(count <= 0 || nullptr == verts) return false;if(begin < 0){CCLOGERROR("Update vertices with begin = %d, will set begin to 0", begin);begin = 0;}if(count + begin > _vertexNumber){CCLOGERROR("updated vertices exceed the max size of vertex buffer, will set count to _vertexNumber-begin");count = _vertexNumber - begin;}if(isShadowCopyEnabled()){memcpy(&_shadowCopy[begin * _sizePerVertex], verts, count * _sizePerVertex);}glBindBuffer(GL_ARRAY_BUFFER, _vbo);glBufferSubData(GL_ARRAY_BUFFER, begin * _sizePerVertex, count * _sizePerVertex, verts); glBindBuffer(GL_ARRAY_BUFFER, 0);return true;
}
复制代码

上面是VertexBuffer的刷新方法, 绑定对应VBO 使用glsubData类型方法修改VBO缓存中对应区域的数据

#IndexBuffer IndexBuffer 和VertexBuffer实际上功能差不多,但是是用于保存顶点索引缓存的主要用于Mesh等有指定渲染顺序的功能的,它绑定的VBO单独用于保存顶点索引 GL_ELEMENT_ARRAY_BUFFER (并没有在CCVertexIndexData文件中发现IndexData这个类, 可能跟它并不需要使用VertexStreamAttribute类似的结构体的关系吧,虽然这个索引的正确性决定了你最终的渲染结果,可能跟数据量和复杂度有关)

转载于:https://juejin.im/post/5a30dd42f265da431b6d3262

Cocos2dx源码记录(3) CCVertexIndexData相关推荐

  1. Cocos2dx源码记录(1) CCGLProgram

    前言: 这个系列是我自己在看cocos2dx源码时记录的一些比较重要的数据结构跟方法中间可能穿插些opengl的知识. 每个介绍的类之间没有固定引用顺序,仅作为个人的记录,可能会有点乱(其实主要是为了 ...

  2. Cocos2dx源码记录(11) CCPrimtiveCommand,CCPrimetive

    #1 CCPrimetive 因为CCPrimtiveCommand里有用到这个就先分析下这个吧 按照字面的意思应该是由一系列顶点属性和带有顺序的顶点索引的图元面片类 /**Primitive can ...

  3. Cocos2dx源码记录(6) CCTrianglesCommand

    CCQuadCommand类继承自CCTrianglesCommand类, 因为一个4个点的封闭图形由两个三角形组成.下面先介绍父类CCTrianglesCommand 然后再简单地介绍下CCQuad ...

  4. Gem5模拟器,popnet模拟器源码记录(十五)

    在使用王小航老师课题组开源的Gem5代码进行大规模的Chiplet并行仿真时,有个关键问题是:为什么原来的gem5不可以进行大规模仿真?为什么精度不够?也是论文提出的背景: (20条消息) 傻白探索C ...

  5. 学习vue-router源码记录-1

    因为本人开发中使用的是VUE技术栈,最近也是开始源码的学习,以此记录个人理解,若行文有误,请多多指教. 1.new Router和install 在vue中我们使用vue-router时需要先进行ne ...

  6. Ubuntu16.04编译android6.0.1源码记录

    目录 目录 一.安装环境 二.下载源码 1.下载repo 2.初始化repo 3.同步源代码 关于驱动 三.编译源码 四.导入源码到AS 五.刷入真机 六.修改源码 总结: 3.同步源代码 关于驱动 ...

  7. 【GAT】图注意力网络 - 简单的源码记录

    由于和GCN代码比较相似,所以部分内容从GCN那篇博客中截取. 1 - cora数据集 GNN常用数据集之Cora数据集 2 - 源码含义记录 首先我们来整体看一下代码的组成 截图中的这一大坨为命令行 ...

  8. 安卓贴图源码---记录旋转后位置..类似in/百度魔图

    效果如图: 类似in,百度魔图,的贴图功能  核心的地方:单/多点 旋转缩放后记录各个顶点小图标位置 引用这里 http://blog.csdn.net/xiaanming/article/detai ...

  9. 远古守卫/cocos2d-x 源码/塔防游戏/高仿王国保卫战

    下载地址:下载地址 本源码高度模仿IOS游戏王国保卫战,由国外IOS商业开发教程网站raywenderlich内部工程师制作,有非常完整的关卡设计,战斗流程,长达12个关卡,各种敌兵,怪物,箭塔,炮塔 ...

  10. windows编译安卓源码记录

    环境 Windows10 + vmware17 + ubuntu22 ubuntu环境设置 装完ubuntu系统后拖拽复制文件进去验证vmtools功能情况,如果vmtools异常很麻烦,试了n多方法 ...

最新文章

  1. 区块链中的智能合约是什么?
  2. virtualbox ubuntu安装图解
  3. VOFM、Copy Control与合并开票
  4. java 文件流关闭 finally,关于java:为什么需要在“ finally”内关闭文件,而仍将其嵌入在“ try / catch”块内?...
  5. mysql报错ERROR 1045 (28000)
  6. uview中使用_使用uniapp自带的地图_实现地图点选位置功能---基于Vue的uniapp手机端_前端UI_uview工作笔记006
  7. 20 分钟教你搞懂 Git!
  8. 小干货:Linux 系统的备份恢复
  9. Springboot @Validated和@Valid
  10. Mysql之INFORMATION_SCHEMA解析1
  11. 一个壮观的雨瀑布视频
  12. 读懂 PetaLinux:让 Linux 在 Zynq 上轻松起“跑”(转)
  13. 获奖!CACTER邮件安全网关荣获电子邮件安全优秀产品奖项
  14. perl oracle ppm,perl – 为什么没有找到ppm:命令?
  15. 重大问题思考-2021年总结
  16. Oracle set timing on
  17. 基于android点餐系统需求分析,基于Android的点餐系统的设计及实现
  18. UserWarning: mkl-service package failed to import, therefore Intel(R) MKL in
  19. java计算机毕业设计中学招生管理系统源码+数据库+系统+lw文档+mybatis+运行部署
  20. 【ArcGIS微课1000例】0034:地图线状符号设计教程

热门文章

  1. 关于Xcode的一些方法-15-05-02
  2. 【一周一算法】算法3:最常用的排序——快速排序
  3. 黑盒测试和白盒测试之间的差别
  4. NoiseAsh Rule Tec All Collection for Mac(无源均衡器)
  5. Android自定义控件之实现listview滑动时渐隐渐现顶部栏
  6. 语言技巧——scanf读入多行字符串
  7. 制作Camtasia 2020击键标记动画——保存及应用
  8. python 装饰器 二
  9. hdu5414(2015多校10)--CRB and String(字符串匹配)
  10. [LeetCode]144.Binary Tree Preorder Traversal