先备份下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; }
发表评论