COCOS学习笔记--自定义绘制

来源:互联网 发布:电脑重装系统恢复数据 编辑:程序博客网 时间:2024/05/16 15:47

Cocos2dx3.0版本后渲染引入了OpenGlES3.0相关特性,使用了DrawNode类来进行绘制,那么我们就来看看DrawNode类具体是如何绘制点线面的

我们在DrawNode.cpp中可以看到DrawNode类提供了画点drawPoint()、画线drawLine()、画矩形drawRect()、画多边形drawPoly()、画矩形面drawSolidRect()、画多边形面drawSolidPoly()等等方法。

接下来我们以drawLine()这个方法为例,看下cocos到底是如何绘制图形的:

void DrawNode::drawLine(const Vec2 &origin, const Vec2 &destination, const Color4F &color){    ensureCapacityGLLine(2);        V2F_C4B_T2F *point = (V2F_C4B_T2F*)(_bufferGLLine + _bufferCountGLLine);        V2F_C4B_T2F a = {origin, Color4B(color), Tex2F(0.0, 0.0)};    V2F_C4B_T2F b = {destination, Color4B(color), Tex2F(0.0, 0.0)};        *point = a;    *(point+1) = b;        _bufferCountGLLine += 2;    _dirtyGLLine = true;}

该方法参数为终点、起点坐标、颜色值。

首先把参数传来的值赋给了V2F_C4B_T2F类型的变量,这个V2F_C4B_T2F是什么类型呢?我们看看:我们在ccTypes.h文件中可以找到对V2F_C4B_T2F的定义:

struct V2F_C4B_T2F{    /// vertices (2F)    Vec2       vertices;    /// colors (4B)    Color4B        colors;    /// tex coords (2F)    Tex2F          texCoords;};

原来V2F_C4B_T2F是一个结构体,里面点坐标、颜色值还有个Tex2F类型的成员。


回过头来,刚刚只是把绘制信息存储起来,那么drawLine具体绘制的方法在哪里呢?

我们可以在DrawNode.cpp中找到onDrawGLLine()方法,绘制线就是在这个方法里面进行的:

void DrawNode::onDrawGLLine(const Mat4 &transform, uint32_t flags){                                                                                                                                                                //得到用于存储管理GL编程对象的shader着色器单例    auto glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR);    //使用shader    glProgram->use();    //设置shader的一些内置uniform    glProgram->setUniformsForBuiltins(transform);    GL::blendFunc(_blendFunc.src, _blendFunc.dst);     if (_dirtyGLLine)    {                                                                                                                                                          //绑定一个新缓冲区        //同时把之前的一些缓冲区数据清掉        glBindBuffer(GL_ARRAY_BUFFER, _vboGLLine);        //去申请存放传来数据的相关内存        glBufferData(GL_ARRAY_BUFFER, sizeof(V2F_C4B_T2F)*_bufferCapacityGLLine, _bufferGLLine, GL_STREAM_DRAW);        _dirtyGLLine = false;}    //根据VAO还是VBO的顶点绘制方式进行不同处理    //在OpenGL2.0时只有VBO顶点绘制方式,VAO是OpenGL3.0后的特性    //VAO比VBO即省内存又提高渲染效率    if (Configuration::getInstance()->supportsShareableVAO())    {        GL::bindVAO(_vaoGLLine);    }    else    {        glBindBuffer(GL_ARRAY_BUFFER, _vboGLLine);        //激活attribute        GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);        // 给vertex指定数据源        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, vertices));        // 给color指定数据源        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, colors));        // 给texcood指定数据源        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, texCoords));}    //设置线的宽度    glLineWidth(_lineWidth);     glDrawArrays(GL_LINES, 0, _bufferCountGLLine);        if (Configuration::getInstance()->supportsShareableVAO())    {        GL::bindVAO(0);    }        glBindBuffer(GL_ARRAY_BUFFER, 0);        CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_bufferCountGLLine);    CHECK_GL_ERROR_DEBUG();}

好了,其他的图形绘制方法基本大同小异都是这个流程,如果你想深入理解,最好学习一下OpenGL的相关知识。


接下来我们就使用DrawNode类来进行一些图形绘制

//创建DrawNode对象auto dNode = DrawNode::create();//将DrawNode对象添加到HelloWorld的layer上this->addChild(dNode);

1.绘制点

//绘制点//参数:坐标、大小、颜色//Color4F的4个参数:R、B、G、alpha,范围0~1dNode->drawPoint(Vec2(200,200),20,Color4F(1,0,0,1));

 

2.绘制线

//绘制线//参数:起点坐标、终点坐标、颜色dNode->drawLine(Vec2(200,200),Vec2(400,400),Color4F(0,0,1,1));


3.绘制Bezier曲线

//绘制Bezier曲线//参数:起点坐标、控制点坐标、终点坐标、段数、颜色//CCRANDOM_0_1()为获得0~1之间随机数的宏                                                                                                                                                          //二级贝塞尔曲线dNode->drawQuadBezier(Vec2(200, 200), Vec2(100, 300), Vec2(500, 200), 15, Color4F(0, 1, 0, 1));                                                                                                                                                          //高阶贝塞尔曲线dNode->drawCubicBezier(Vec2(200, 200), Vec2(300, 300), Vec2(450, 200), Vec2(150, 100), 10, Color4F(CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), 1));
 


4.绘制三角形

//绘制三角形//参数:顶点坐标、颜色dNode->drawTriangle(Vec2(200, 300), Vec2(400, 300), Vec2(300, 400), Color4F(1, 0, 0, 1));


5.绘制矩形

//绘制矩形//参数:左下角顶点坐标、右上角顶点坐标、颜色dNode->drawRect(Vec2(300, 300), Vec2(400, 400), Color4F(1, 0, 0, 1));


6.绘制圆形

//绘制圆形//参数:圆心坐标、半径、角度(弧度)、段数、是否有线连到圆心、横、纵坐标缩放、颜色dNode->drawCircle(Vec2(480, 320), 100, CC_DEGREES_TO_RADIANS(90), 20, true, 1, 1, Color4F(1, 0, 0, 1));


7.绘制多边形

//绘制多边形//参数:顶点坐标数组、顶点数、是否封闭、颜色Vec2 vertices[] = { Vec2(100, 100), Vec2(150, 150), Vec2(200, 150), Vec2(200,200), Vec2(150, 200)};dNode->drawPoly(vertices, 5, true, Color4F(1, 0, 0, 1));

 

8.绘制矩形面

//绘制矩形面//参数:左下角顶点坐标、右上角顶点坐标、颜色dNode->drawSolidRect(Vec2(300, 300), Vec2(400, 400), Color4F(1, 0, 0, 1));

 其他绘制面的方法基本也和绘制线的相同,参数基本一样,只是方法名多了“Solid”。






以上。




 

3 0
原创粉丝点击