对openGLES的粗浅认识

BYCircleTextureFactory.h

// // BYCircleTextureFactory.h // SuperBalance1.1 // // Created by Bruce Yang on 8/1/11. // Copyright 2011 Home. All rights reserved. // #import "cocos2d.h" #import "GameConfig.h" #import "CirclePointsGenerator.h" #import "BYTextureDef.h" #import "BYSingle.h" @interface BYCircleTextureFactory : NSObject { } + (CCTexture2D*) genCircleTexture:(BYTextureDef*)textureDef; @end
BYCircleTextureFactory.mm

// // BYCircleTextureFactory.mm // SuperBalance1.1 // // Created by Bruce Yang on 8/1/11. // Copyright 2011 Home. All rights reserved. // #import "BYCircleTextureFactory.h" @implementation BYCircleTextureFactory /** * 绘制出圆角多边形的轮廓,在内部填充颜色 */ + (void) glesDraw:(CGPoint*)vertices colors:(ccColor4F*)colors arrayLen:(int)arrayLen { // 第一件事情就是禁用GL_TEXTURE_2D 和 GL_TEXTURE_COORD_ARRA两个opengl状态, // 因为,我们接下来只需要绘制颜色---这与纹理无关。 glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // 将顶点(x, y)数组和颜色(r, g, b, a)数组传给opengl glVertexPointer(2, GL_FLOAT, 0, vertices); glColorPointer(4, GL_FLOAT, 0, colors); glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)arrayLen); // 最后,我们重新激活GL_TEXTURE_COORD_ARRAY 和 GL_TEXTURE_2D两个状态, // 这样做的话是保持和之前调用的对称,并且不会破坏opengl状态机。 glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_2D); } /** * 绘制1个像素的多边形圆角边框 */ + (void) drawOnePixelBorder:(CGPoint*)outBorderVetices verticesCount:(int)outBorderVeticesCount { // openGL就是一个状态机,使用得时候该有的状态必须有,不需要的状态必须 disable 掉!!! glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glColor4f(0.0f, 0.0f, 0.0f, 1.0f); glVertexPointer(2, GL_FLOAT, 0, outBorderVetices); glDrawArrays(GL_LINE_LOOP, 0, outBorderVeticesCount); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_2D); } /** * 去除图片文件的后缀 */ + (NSString*) fileNameWithoutSuffix:(NSString*)fullName { NSMutableString *mutableString = [NSMutableString stringWithCapacity:50]; // 接收一下 [mutableString appendString:fullName]; NSString *suffix = [mutableString pathExtension]; // 获取文件后缀名 NSString *handledSuffix = [NSString stringWithFormat:@"%@%@", @".", suffix]; // 使后缀名带上前面那个点儿 NSRange suffixRange = [mutableString rangeOfString:handledSuffix]; [mutableString deleteCharactersInRange:suffixRange]; return mutableString; } /** * 将纹理、噪点图片与目标形状相混合,形状内的部分保留,形状外的部分剔除 */ + (void) textureOrNoiseBlend:(NSString*)imgName circleSize:(CGSize)circleSize { if(imgName != nil) { CCSprite *textureOrNoise; if([BYSingle getInstance].isIpad == NO) { textureOrNoise = [CCSprite spriteWithFile:imgName]; textureOrNoise.position = ccp(circleSize.width/2, circleSize.height/2); } else { textureOrNoise = [CCSprite spriteWithFile:[NSString stringWithFormat:@"%@-hd.png", [self fileNameWithoutSuffix:imgName]]]; textureOrNoise.position = ccp(circleSize.width, circleSize.height); } [textureOrNoise setBlendFunc:(ccBlendFunc){GL_DST_COLOR, GL_ZERO}]; [textureOrNoise visit]; } } /** * 将texture的尺寸扩大为原来的四倍(因为这里是静态类,因此需将+改为-)~ */ + (CGPoint*) convert2RetinaSize:(CGPoint*)vertices verticesCount:(int)verticesCount { CGPoint *target = new CGPoint[verticesCount]; for(int i = 0; i < verticesCount; i ++) { target[i] = ccpMult(vertices[i], 2.0f); } return target; } /** * 生成带边框的圆形纹理~ */ + (CCTexture2D*) genCircleTexture:(BYTextureDef*)textureDef { // 1: Create new CCRenderTexture CGPoint sizePoint = textureDef.polygonVertexs[0]; CGSize circleSize = CGSizeMake(sizePoint.x, sizePoint.y); CCRenderTexture *rt; if([BYSingle getInstance].isIpad == NO) { rt = [CCRenderTexture renderTextureWithWidth:circleSize.width height:circleSize.width]; } else { rt = [CCRenderTexture renderTextureWithWidth:circleSize.width*2 height:circleSize.width*2]; } // 颜色为黑色(白色等其他颜色亦可,因为不透明度为0) ccColor4F bgColor1 = (ccColor4F){0.95f, 1.0f, 0.33f, 0.0f}; // 就因为没有加上下面这句代码,害我足足找了两天,记住曝出的错误:OpenGL error 0x0504 in -[EAGLView swapBuffers] // 疯了,在网上查了下,说是什么 “堆栈下溢”,原来指的就是没有给 纹理打上底色??! [rt beginWithClear:bgColor1.r g:bgColor1.g b:bgColor1.b a:bgColor1.a]; CGPoint *finalResult = [CirclePointsGenerator genCirclePoints:circleSize]; // 多边形的顶点数~ int circleVertexCount = CIRCLE_SEGEMENTS_COUNT; // opengles绘制多边形边框总共的顶点数~ int borderTotalCount = circleVertexCount * 2 + 2; CGPoint borderVertexs[borderTotalCount]; ccColor4F borderColors[borderTotalCount]; // 又有新的需求,不需要渐变边框,只需要圆角+1px的外框 int outBorderVeticesCount = CIRCLE_SEGEMENTS_COUNT + 1; CGPoint outBorderVetices[outBorderVeticesCount]; // ************************* 对4代做修正~ ********************************* if([BYSingle getInstance].isRetinaSupported) { finalResult = [self convert2RetinaSize:finalResult verticesCount:borderTotalCount]; } if([BYSingle getInstance].isIpad == YES) { finalResult = [self convert2RetinaSize:finalResult verticesCount:borderTotalCount]; } // ************************* 对4代做修正~ ********************************* int k = 0; for(int i = 0; i < borderTotalCount; i ++) { borderVertexs[i] = finalResult[i]; borderColors[i] = (ccColor4F){1.0f, 1.0f, 1.0f, 1.0f}; if(i%2 == 0) { outBorderVetices[k] = finalResult[i]; k += 1; } } outBorderVetices[k] = outBorderVetices[0]; // --------------------------------- 蛋疼的分割线 --------------------------------- // opengles绘制多边形内容物总共的顶点数~ int contentTotalCount; if(circleVertexCount%2 == 1) { // 如果是顶点数为奇数的多边形 contentTotalCount = 3 + (circleVertexCount-3)/2*3; } else { // 如果是顶点数为偶数的多边形 contentTotalCount = 5 + (circleVertexCount-4)/2*3; } CGPoint originalContentVertexs[circleVertexCount]; CGPoint contentVertexs[contentTotalCount]; ccColor4F contentColors[contentTotalCount]; for(int i = 0; i < circleVertexCount; i ++) { originalContentVertexs[i] = finalResult[i * 2 + 1]; } // 内部3角形的颜色,需一致设置为不透明度为1.0f的白色,便于与纹理图片 blend 获得纹理~ ccColor4F contentColor = (ccColor4F){1.0f, 1.0f, 1.0f, 1.0f}; int j = 1; for(int i = 0; i < contentTotalCount; i ++) { if(i%3 == 0) { contentVertexs[i] = originalContentVertexs[0]; } else { contentVertexs[i] = originalContentVertexs[j]; j = j + 1; } contentColors[i] = contentColor; } // 释放内存,避免野指针的存在(使用完毕之后立即回收在堆上new出来的内存)~ delete finalResult; // 4: Draw into the texture // 一。首先以纯白填充多边形内容物,为绘制纹理和噪点做准备 [self glesDraw:contentVertexs colors:contentColors arrayLen:contentTotalCount]; // 二。绘制多边形边框 [self glesDraw:borderVertexs colors:borderColors arrayLen:borderTotalCount]; // 三。混合木质纹理~ [self textureOrNoiseBlend:textureDef.textureImgName circleSize:circleSize]; // 四。混合噪点图片~ [self textureOrNoiseBlend:textureDef.noiseImgName circleSize:circleSize]; // 五。绘制1个像素宽度的外部边框~ // [self drawOnePixelBorder:outBorderVetices verticesCount:outBorderVeticesCount]; // 至此 textureDef 所占据的堆内存可以释放掉了!! // 搞死哥了,哥在后面又用到过这个东西,结果总是曝出 EXC_BAD_ACCESS // 不过虽然 delete 掉了 textureDef,但奇怪的是,有时候依然还是能够访问到多边形顶点数组的数据~ delete textureDef; // 5: Call CCRenderTexture:end [rt end]; // 6: Create a new Sprite from the texture return rt.sprite.texture; } @end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值