您的位置:首页 > 移动开发 > Cocos引擎

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

2015-12-31 15:58 597 查看
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~1
dNode->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”。

以上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: