首页 > 代码库 > cocos2d-x游戏引擎核心之四——绘图原理和绘图技巧

cocos2d-x游戏引擎核心之四——绘图原理和绘图技巧

一、OpenGL基础

  游戏引擎是对底层绘图接口的包装,Cocos2d-x 也一样,它是对不同平台下 OpenGL 的包装。OpenGL 全称为 Open Graphics Library,是一个开放的、跨平台的高性能图形接口。OpenGL ES 则是 OpenGL 在移动设备上的衍生版本,具备与 OpenGL 一致的结构,包含了常用的图形功能。Cocos2d-x 就是一个基于 OpenGL 的游戏引擎,因此它的绘图部分完全由 OpenGL 实现。OpenGL 是一个基于 C 语言的三维图形 API,基本功能包含绘制几何图形、变换、着色、光照、贴图等。除了基本功能,OpenGL还提供了诸如曲面图元、光栅操作、景深、shader 编程等高级功能。

(1)状态机:

  OpenGL 是一个基于状态的绘图模型,我们把这种模型称为状态机。为了正确地绘制图形,我们需要把 OpenGL 设置到合适的状态,然后调用绘图指令。(绘图流程和状态机优势)。

(2)坐标系:OpenGL 是一个三维图形接口,在程序中使用右手三维坐标系。

(3)渲染流水线:

  当我们把绘制的图形传递给 OpenGL 后,OpenGL 还要进行许多操作才能完成 3D 空间到屏幕的投影。通常,渲染流水线过程
有如下几步:显示列表、求值器、顶点装配、像素操作、纹理装配、光栅化和片断操作等。OpenGL 从 2.0 版本开始引入了可编程着色器(shader)。

(4)绘图函数:

(5)矩阵与变换:OpenGL 对顶点进行的处理实际上可以归纳为接受顶点数据、进行投影、得到变换后的顶点数据这 3 个步骤。

在计算机中,坐标变换是通过矩阵乘法实现的。

:详细参见《cocos2d-x高级开发教程》、《OpenGL编程指南》

二、Cocos2d-x绘图原理

 

void CCSprite::draw(void){    //1. 初始准备    CC_PROFILER_START_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw");    CCAssert(!m_pobBatchNode, "If CCSprite is being rendered by CCSpriteBatchNode, CCSprite#draw SHOULD NOT be called");    CC_NODE_DRAW_SETUP();    //2. 颜色混合函数    ccGLBlendFunc( m_sBlendFunc.src, m_sBlendFunc.dst );    //3. 绑定纹理    if (m_pobTexture != NULL)    {        ccGLBindTexture2D( m_pobTexture->getName() );    }    else    {        ccGLBindTexture2D(0);    }        //    // Attributes    //    //4. 绘图    ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex );#define kQuadSize sizeof(m_sQuad.bl)    long offset = (long)&m_sQuad;    // vertex    //顶点坐标    int diff = offsetof( ccV3F_C4B_T2F, vertices);    glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));    // texCoods    //纹理坐标    diff = offsetof( ccV3F_C4B_T2F, texCoords);    glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));    // color    //顶点颜色    diff = offsetof( ccV3F_C4B_T2F, colors);    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));    //绘制图形    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);    CHECK_GL_ERROR_DEBUG();//5. 调试相关的处理#if CC_SPRITE_DEBUG_DRAW == 1    //调试模式 1:绘制边框    // draw bounding box    CCPoint vertices[4]={        ccp(m_sQuad.tl.vertices.x,m_sQuad.tl.vertices.y),        ccp(m_sQuad.bl.vertices.x,m_sQuad.bl.vertices.y),        ccp(m_sQuad.br.vertices.x,m_sQuad.br.vertices.y),        ccp(m_sQuad.tr.vertices.x,m_sQuad.tr.vertices.y),    };    ccDrawPoly(vertices, 4, true);#elif CC_SPRITE_DEBUG_DRAW == 2    // draw texture box    //调试模式 2:绘制纹理边缘    CCSize s = this->getTextureRect().size;    CCPoint offsetPix = this->getOffsetPosition();    CCPoint vertices[4] = {        ccp(offsetPix.x,offsetPix.y), ccp(offsetPix.x+s.width,offsetPix.y),        ccp(offsetPix.x+s.width,offsetPix.y+s.height), ccp(offsetPix.x,offsetPix.y+s.height)    };    ccDrawPoly(vertices, 4, true);#endif // CC_SPRITE_DEBUG_DRAW    CC_INCREMENT_GL_DRAWS(1);    CC_PROFILER_STOP_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw");}

 

 

 

OpenGL绘图技巧(遮罩层和小窗预览,可编程着色器)

cocos2d-x游戏引擎核心之四——绘图原理和绘图技巧