我正在尝试遵循 Ray Wenderlich 的教程,使用 OpenGLES 为背景创建具有纹理和单独纹理的山丘(http://www.raywenderlich.com/3888/how-to-create-a-game-like-tiny-翅膀第 1 部分)。但是,我正在尝试将其转换为 Cocos2D 2,因为他的教程仅适用于 OpenGLES 1。我已经成功达到了一定程度,我的 spriteWithColor 和 stripedSpriteWithColor1 方法都可以自己正常工作,但是如果我创建两个单独的精灵和一个接一个地使用一种方法,创建的第二个不会在 iOS 模拟器或实际设备上呈现。我不是 OpenGLES 专家,所以我无法调试此错误,这是我的源代码:
-(CCSprite *)stripedSpriteWithColor1:(ccColor4F)c1 color2:(ccColor4F)c2 textureSize:(float)textureSize stripes:(int) nStripes {
// 1: Create new CCRenderTexture
CCRenderTexture *rt = [CCRenderTexture renderTextureWithWidth:textureSize height:textureSize];
// 2: Call CCRenderTexture:begin
[rt beginWithClear:c1.r g:c1.g b:c1.b a:c1.a];
// 3: Draw into texture
//OpenGL gradient
NSLog(@"Strip color is: %f : %f : %f", c2.r,c2.g,c2.b);
CGPoint vertices[nStripes*6];
ccColor4F colors[nStripes*6];
int nVertices = 0;
float x1 = -textureSize;
float x2;
float y1 = textureSize;
float y2 = 0;
float dx = textureSize / nStripes * 2;
float stripeWidth = dx/2;
ccColor4F stripColor = (ccColor4F){c2.r,c2.g,c2.b,c2.a};
for (int i=0; i<nStripes; i++) {
x2 = x1 + textureSize;
colors[nVertices] = stripColor;
vertices[nVertices++] = CGPointMake(x1, y1);
colors[nVertices] = stripColor;
vertices[nVertices++] = CGPointMake(x1+stripeWidth, y1);
colors[nVertices] = stripColor;
vertices[nVertices++] = CGPointMake(x2, y2);
colors[nVertices] = stripColor;
vertices[nVertices++] = vertices[nVertices-3];
colors[nVertices] = stripColor;
vertices[nVertices++] = vertices[nVertices-3];
colors[nVertices] = stripColor;
vertices[nVertices++] = CGPointMake(x2+stripeWidth, y2);
x1 += dx;
}
[self.shaderProgram use];
ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position | kCCVertexAttribFlag_Color);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, 0, colors);
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)nVertices);
//Gradient
float gradientAlpha = 0.2;
nVertices = 0;
vertices[nVertices] = CGPointMake(0, 0);
colors[nVertices++] = (ccColor4F){0,0,0,0};
vertices[nVertices] = CGPointMake(textureSize, 0);
colors[nVertices++] = (ccColor4F){0,0,0,0};
vertices[nVertices] = CGPointMake(0, textureSize);
colors[nVertices++] = (ccColor4F){0,0,0,gradientAlpha};
vertices[nVertices] = CGPointMake(textureSize, textureSize);
colors[nVertices++] = (ccColor4F){0,0,0,gradientAlpha};
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, 0, colors);
glDrawArrays(GL_TRIANGLE_STRIP,0, (GLsizei)nVertices);
// Highlighting
float borderWidth = textureSize/18;
float borderAlpha = 0.7f;
nVertices = 0;
vertices[nVertices] = CGPointMake(0, 0);
colors [nVertices++] = (ccColor4F){1,1,1,borderAlpha};
vertices[nVertices] = CGPointMake(textureSize,0);
colors [nVertices++] = (ccColor4F){1,1,1,borderAlpha};
vertices[nVertices] = CGPointMake(0, borderWidth);
colors [nVertices++] = (ccColor4F){0,0,0,0};
vertices[nVertices] = CGPointMake(textureSize,borderWidth);
colors [nVertices++] = (ccColor4F){0,0,0,0};
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, 0, colors);
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nVertices);
//Noise
CCSprite *noise = [CCSprite spriteWithFile:@"noise.png"];
[noise setBlendFunc:(ccBlendFunc){GL_DST_COLOR, GL_ZERO}];
noise.position = ccp(textureSize/2, textureSize/2);
[noise visit];
[rt end];
// Return texture sprite
return [CCSprite spriteWithTexture:rt.sprite.texture];
}
-(CCSprite *)spriteWithColor:(ccColor4F)bgColor textureSize:(float)textureSize {
// 1: Create new CCRenderTexture
CCRenderTexture *newt = [CCRenderTexture renderTextureWithWidth:textureSize height:textureSize];
// 2: Call CCRenderTexture:begin
[newt beginWithClear:bgColor.r g:bgColor.g b:bgColor.b a:bgColor.a];
// 3: Draw into the texture
//openGL gradient
//ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_Color );
float gradientAlpha = 0.2;
CGPoint vertices[4];
ccColor4F colors[4];
int nVertices = 0;
vertices[nVertices] = CGPointMake(0, 0);
colors[nVertices++] = (ccColor4F){0, 0, 0, 0};
vertices[nVertices] = CGPointMake(textureSize, 0);
colors[nVertices++] = (ccColor4F){0, 0, 0, 0};
vertices[nVertices] = CGPointMake(0, textureSize);
colors[nVertices++] = (ccColor4F){0, 0, 0, gradientAlpha};
vertices[nVertices] = CGPointMake(textureSize, textureSize);
colors[nVertices++] = (ccColor4F){0, 0, 0, gradientAlpha};
// gradient
[self.shaderProgram use];
ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position | kCCVertexAttribFlag_Color);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, 0, colors);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nVertices);
CCSprite *noise = [CCSprite spriteWithFile:@"noise.png"];
[noise setBlendFunc:(ccBlendFunc){GL_DST_COLOR, GL_ZERO}];
noise.position = ccp(textureSize/2, textureSize/2);
[noise visit];
// 4: Call CCRenderTexture:end
[newt end];
// 5: Create a new Sprite from the texture
return [CCSprite spriteWithTexture:newt.sprite.texture];
}
- (ccColor4F)randomBrightColor {
while (true) {
float requiredBrightness = 172;
ccColor4B randomColor =
ccc4(arc4random() % 255,
arc4random() % 255,
arc4random() % 255,
255);
if (randomColor.r > requiredBrightness ||
randomColor.g > requiredBrightness ||
randomColor.b > requiredBrightness) {
return ccc4FFromccc4B(randomColor);
}
}
}
- (void)genBackground {
CGSize winSize = [CCDirector sharedDirector].winSize;
[_background removeFromParentAndCleanup:YES];
ccColor4F color3 = [self randomBrightColor];
ccColor4F color4 = [self randomBrightColor];
CCSprite *stripes = [self stripedSpriteWithColor1:color3 color2:color4 textureSize:512 stripes:4];
stripes.position = ccp(winSize.width/2,winSize.height/2);
ccTexParams tp2 = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT};
[stripes.texture setTexParameters:&tp2];
_terrain.stripes = stripes;
ccColor4F bgColor = [self randomBrightColor];
_background = [self spriteWithColor:bgColor textureSize:512];
_background.position = ccp(winSize.width/2, winSize.height/2);
ccTexParams tp = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT};
[_background.texture setTexParameters:&tp];
[self addChild:_background];
}
-(id) init {
if((self=[super init])) {
self.shaderProgram = [[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionColor];
CC_NODE_DRAW_SETUP();
_terrain = [Terrain node];
[self addChild:_terrain z:1];
[self genBackground];
self.isTouchEnabled = YES;
// [self scheduleUpdate];
}
return self;
}