好记性不如铅笔头

C && C++, cocos2dx, 编程

cocos2dx学习笔记:CCDrawingPrimitives

先备份下opengles常用的几何图像,如下图。

图像来自【 http://blog.php1.cn/article/details/1151 】

CONTENTS

opengles常用的几何图像绘制

CCDrawingPrimitives.cpp代码笔记

代码笔记写的比较简单,很多用到的上下文代码也一并放到了注释里面。看起来可能会比较乱。

/*
初始化方法,从方法中可以看出使用的是Shader_Position_uColor这个shader,它的内容为
【 ccShader_Position_uColor_vert.h 】和【ccShader_Position_uColor_frag.h 】
里面有a_position(attribute)和u_color,u_pointSize两个uniform,
其中,a_position在
void CCShaderCache::loadDefaultShader(CCGLProgram *p, int type)
{       
	case kCCShaderType_Position_uColor:
		p->initWithVertexShaderByteArray(ccPosition_uColor_vert, ccPosition_uColor_frag);              
		p->addAttribute("aVertex", kCCVertexAttrib_Position);
		break;
}
这个代码段中被bind,但是作者感觉这里可能有点问题,
p->addAttribute("aVertex", kCCVertexAttrib_Position);应该改为
p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
但是后面的代码仍然可以继续工作。比较奇怪,暂时没有找到原因。
*/
static void lazy_init( void )
{
    if( ! s_bInitialized ) {

        //
        // Position and 1 color passed as a uniform (to simulate glColor4ub )
        //
        s_pShader = CCShaderCache::sharedShaderCache()->programForKey(kCCShader_Position_uColor);
        s_pShader->retain();
        
        //==>>获取常量的句柄
        s_nColorLocation = glGetUniformLocation( s_pShader->getProgram(), "u_color");
    CHECK_GL_ERROR_DEBUG();
        s_nPointSizeLocation = glGetUniformLocation( s_pShader->getProgram(), "u_pointSize");
    CHECK_GL_ERROR_DEBUG();

        s_bInitialized = true;
    }
}

// When switching from backround to foreground on android, we want the params to be initialized again
void ccDrawInit()
{
    lazy_init();
}

void ccDrawFree()
{
	CC_SAFE_RELEASE_NULL(s_pShader);
	s_bInitialized = false;
}

/*
void ccGLEnableVertexAttribs( unsigned int flags )
{
    ccGLBindVAO(0);
    
    bool enablePosition = flags & kCCVertexAttribFlag_Position;
 
    if( enablePosition != s_bVertexAttribPosition ) {
        if( enablePosition )
            glEnableVertexAttribArray( kCCVertexAttrib_Position );
        else
            glDisableVertexAttribArray( kCCVertexAttrib_Position );
 
        s_bVertexAttribPosition = enablePosition;
    }
 
    bool enableColor = (flags & kCCVertexAttribFlag_Color) != 0 ? true : false;
 
    if( enableColor != s_bVertexAttribColor ) {
        if( enableColor )
            glEnableVertexAttribArray( kCCVertexAttrib_Color );
        else
            glDisableVertexAttribArray( kCCVertexAttrib_Color );
 
        s_bVertexAttribColor = enableColor;
    }
 
    bool enableTexCoords = (flags & kCCVertexAttribFlag_TexCoords) != 0 ? true : false;
 
    if( enableTexCoords != s_bVertexAttribTexCoords ) {
        if( enableTexCoords )
            glEnableVertexAttribArray( kCCVertexAttrib_TexCoords );
        else
            glDisableVertexAttribArray( kCCVertexAttrib_TexCoords );
 
        s_bVertexAttribTexCoords = enableTexCoords;
    }
}
*/


//==>>画点
void ccDrawPoint( const CCPoint& point )
{
    lazy_init();

    ccVertex2F p;
    p.x = point.x;
    p.y = point.y;

//==>>首先enable输入点矩阵
    ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
//==>>选用当前的shader
    s_pShader->use();
//==>>刷新内置的矩阵
    s_pShader->setUniformsForBuiltins();
    
//==>>更新颜色和大小的常量值
    s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
    s_pShader->setUniformLocationWith1f(s_nPointSizeLocation, s_fPointSize);

#ifdef EMSCRIPTEN
    setGLBufferData(&p, 8);
    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0);
#else
//==>>将坐标点写入attribute
    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, &p);
#endif // EMSCRIPTEN

//==>>画一个点
    glDrawArrays(GL_POINTS, 0, 1);

    CC_INCREMENT_GL_DRAWS(1);
}



void ccDrawPoints( const CCPoint *points, unsigned int numberOfPoints )
{
    lazy_init();
。。。。。
。。。。。
//==>>绘制独立的点。
    glDrawArrays(GL_POINTS, 0, (GLsizei) numberOfPoints);

    CC_SAFE_DELETE_ARRAY(newPoints);

    CC_INCREMENT_GL_DRAWS(1);
}


void ccDrawLine( const CCPoint& origin, const CCPoint& destination )
{
    lazy_init();
。。。。。
。。。。。
//==>>顶点两两连接,为多条线段构成。
    glDrawArrays(GL_LINES, 0, 2);

    CC_INCREMENT_GL_DRAWS(1);
}

void ccDrawRect( CCPoint origin, CCPoint destination )
{
。。。。。
。。。。。
}

void ccDrawSolidRect( CCPoint origin, CCPoint destination, ccColor4F color )
{
。。。。。
。。。。。
}

void ccDrawPoly( const CCPoint *poli, unsigned int numberOfPoints, bool closePolygon )
{
    lazy_init();
。。。。。
。。。。。
        if( closePolygon )
        	//==>>绘制一系列线段,但是首尾相连,构成一个封闭曲线。
            glDrawArrays(GL_LINE_LOOP, 0, (GLsizei) numberOfPoints);
        else
        	//==>>绘制一系列线段。
            glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) numberOfPoints);

        CC_SAFE_DELETE_ARRAY(newPoli);
    }

    CC_INCREMENT_GL_DRAWS(1);
}

void ccDrawSolidPoly( const CCPoint *poli, unsigned int numberOfPoints, ccColor4F color )
{
    lazy_init();
。。。。。
。。。。。
//==>>以一个点为三角形公共顶点,组成一系列相邻的三角形。
    glDrawArrays(GL_TRIANGLE_FAN, 0, (GLsizei) numberOfPoints);

    CC_SAFE_DELETE_ARRAY(newPoli);
    CC_INCREMENT_GL_DRAWS(1);
}
//==>>画圆
void ccDrawCircle( const CCPoint& center, float radius, float angle, unsigned int segments, bool drawLineToCenter, float scaleX, float scaleY)
{
    lazy_init();
//==>>先计算要画的点
    int additionalSegment = 1;
    if (drawLineToCenter)
        additionalSegment++;

    const float coef = 2.0f * (float)M_PI/segments;

    GLfloat *vertices = (GLfloat*)calloc( sizeof(GLfloat)*2*(segments+2), 1);
    if( ! vertices )
        return;

    for(unsigned int i = 0;i <= segments; i++) {
        float rads = i*coef;
        GLfloat j = radius * cosf(rads + angle) * scaleX + center.x;
        GLfloat k = radius * sinf(rads + angle) * scaleY + center.y;

        vertices[i*2] = j;
        vertices[i*2+1] = k;
    }
    vertices[(segments+1)*2] = center.x;
    vertices[(segments+1)*2+1] = center.y;

    s_pShader->use();
    s_pShader->setUniformsForBuiltins();
    s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
//==>>enable输入点的矩阵
    ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );

#ifdef EMSCRIPTEN
    setGLBufferData(vertices, sizeof(GLfloat)*2*(segments+2));
    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0);
#else
//==>>将坐标点传入
    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);
#endif // EMSCRIPTEN
//==>>画线段
    glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segments+additionalSegment);

    free( vertices );

    CC_INCREMENT_GL_DRAWS(1);
}

void CC_DLL ccDrawCircle( const CCPoint& center, float radius, float angle, unsigned int segments, bool drawLineToCenter)
{
	。。。。。
	。。。。。
}

void ccDrawQuadBezier(const CCPoint& origin, const CCPoint& control, const CCPoint& destination, unsigned int segments)
{
	。。。。。
	。。。。。
}

void ccDrawCatmullRom( CCPointArray *points, unsigned int segments )
{
	。。。。。
	。。。。。
}

void ccDrawCardinalSpline( CCPointArray *config, float tension,  unsigned int segments )
{
	。。。。。
	。。。。。
}

//==>>画贝塞尔曲线
void ccDrawCubicBezier(const CCPoint& origin, const CCPoint& control1, const CCPoint& control2, const CCPoint& destination, unsigned int segments)
{
    lazy_init();
//==>>先计算出需要画的点
    ccVertex2F* vertices = new ccVertex2F[segments + 1];

    float t = 0;
    for(unsigned int i = 0; i < segments; i++)
    {
        vertices[i].x = powf(1 - t, 3) * origin.x + 3.0f * powf(1 - t, 2) * t * control1.x + 3.0f * (1 - t) * t * t * control2.x + t * t * t * destination.x;
        vertices[i].y = powf(1 - t, 3) * origin.y + 3.0f * powf(1 - t, 2) * t * control1.y + 3.0f * (1 - t) * t * t * control2.y + t * t * t * destination.y;
        t += 1.0f / segments;
    }
    vertices[segments].x = destination.x;
    vertices[segments].y = destination.y;

    s_pShader->use();
    s_pShader->setUniformsForBuiltins();
    s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
//==>>enable输入点的矩阵
    ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );

#ifdef EMSCRIPTEN
    setGLBufferData(vertices, (segments + 1) * sizeof(ccVertex2F));
    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0);
#else
//==>>将坐标点传入
    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);
#endif // EMSCRIPTEN
//==>>画线段
    glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segments + 1);
    CC_SAFE_DELETE_ARRAY(vertices);

    CC_INCREMENT_GL_DRAWS(1);
}

//==>>更新保存的颜色
void ccDrawColor4F( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
{
    s_tColor.r = r;
    s_tColor.g = g;
    s_tColor.b = b;
    s_tColor.a = a;
}

//==>>更新保存的点的大小
void ccPointSize( GLfloat pointSize )
{
    s_fPointSize = pointSize * CC_CONTENT_SCALE_FACTOR();

    //TODO :glPointSize( pointSize );

}
//==>>更新保存的颜色
void ccDrawColor4B( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
{
    s_tColor.r = r/255.0f;
    s_tColor.g = g/255.0f;
    s_tColor.b = b/255.0f;
    s_tColor.a = a/255.0f;
}

 

发表评论

2 × 3 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据