【问题标题】:Coco2d 2.1 and Xcode 7 iOS 9 crash ccShaderCocos2d 2.1 和 Xcode 7 iOS 9 崩溃 ccShader
【发布时间】:2015-09-01 01:31:28
【问题描述】:

我使用 Xcode 7 测试过,但我的 cocos2d 2.1 游戏在模拟器或设备上崩溃:

ccShader_PositionColorLenghtTexture_frag.h

2015-06-15 22:36:13.319 NanoWar[18789:456971] cocos2d: ERROR: 0:12: '' : syntax error: #extension must always be before any non-preprocessor tokens

cocos2d: ERROR: 0:26: Invalid call of undeclared identifier 'fwidth'

这个类使游戏崩溃

#extension GL_OES_standard_derivatives : enable                                                                             

#ifdef GL_ES                                                                                                                
varying mediump vec4 v_color;                                                                                               
varying mediump vec2 v_texcoord;                                                                                            
#else                                                                                                                       
varying vec4 v_color;                                                                                                       
varying vec2 v_texcoord;                                                                                                    
#endif                                                                                                                      

void main()                                                                                                                 
{                                                                                                                           
#ifdef GL_OES_standard_derivatives                                                                                          
#if defined GL_OES_standard_derivatives                                                                                     
    gl_FragColor = v_color*smoothstep(0.0, length(fwidth(v_texcoord)), 1.0 - length(v_texcoord));                           
#else                                                                                                                       
    gl_FragColor = v_color*step(0.0, 1.0 - length(v_texcoord));                                                             
#endif                                                                                                                      
#endif                                                                                                                      
}

【问题讨论】:

标签: xcode cocos2d-iphone


【解决方案1】:

我是forum.cocos2d-objc.org 上的“rae”,我也不妨把我的答案放在这里,因为条条大路通向 StackOverflow。 :-)

如果您使用的是旧版本的 Cocos 2D,这可能会有所帮助。我编辑 CCGLProgram.m 以更改 -(BOOL)compileShader: 方法的开头:

#define EXTENSION_STRING "#extension GL_OES_standard_derivatives : enable"
static NSString * g_extensionStr = @EXTENSION_STRING;

- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type byteArray:(const GLchar *)source
{
    GLint status;

    if (!source)
        return NO;

    // BEGIN workaround for Xcode 7 bug
    BOOL hasExtension = NO;
    NSString *sourceStr = [NSString stringWithUTF8String:source];
    if([sourceStr rangeOfString:g_extensionStr].location != NSNotFound) {
        hasExtension = YES;
        NSArray *strs = [sourceStr componentsSeparatedByString:g_extensionStr];
        assert(strs.count == 2);
        sourceStr = [strs componentsJoinedByString:@"\n"];
        source = (GLchar *)[sourceStr UTF8String];
    }

    const GLchar *sources[] = {
        (hasExtension ? EXTENSION_STRING "\n" : ""),
    #ifdef __CC_PLATFORM_IOS
        (type == GL_VERTEX_SHADER ? "precision highp float;\n" : "precision mediump float;\n"),
    #endif
        "uniform mat4 CC_PMatrix;\n"
        "uniform mat4 CC_MVMatrix;\n"
        "uniform mat4 CC_MVPMatrix;\n"
        "uniform vec4 CC_Time;\n"
        "uniform vec4 CC_SinTime;\n"
        "uniform vec4 CC_CosTime;\n"
        "uniform vec4 CC_Random01;\n"
        "//CC INCLUDES END\n\n",
        source,
    };
    // END workaround for Xcode 7 bug

这是一个 hack,但它适用于 Xcode 7 beta 2。希望这对搜索此内容的人有所帮助。

里德

【讨论】:

  • 如果您还支持 iOS 8.0 之前的 iOS 版本,请确保将 [sourceStr containsString:g_extensionStr] 替换为 [sourceStr rangeOfString:g_extensionStr].location != NSNotFound since - (BOOL)containsString :(NSString *)str NS_AVAILABLE(10_10, 8_0);
  • 谢谢桑杰!我合并了你的更改。
  • 此解决方案不适用于 cocos2d v2.2,但来自@bodagetta 的回答效果很好。
  • 与一个基于 Xcode3 构建的项目一起工作,我刚刚在 9 上毫无希望地打开了该项目。干杯肯定 +1
  • 似乎适用于 Xcode 11 和 iOS 13.2。我刚刚让我的旧 cocos2d 游戏重新编译。
【解决方案2】:

接受的答案对我不起作用,但确实如此。

转到名为CCGLProgram.m的文件

替换整个名为- (BOOL)compileShader:(CLuint *)shader type(GLenum)typebyteArray:(const GLchar *)source的方法

用这个方法

#define _IPHONE9_0 [[[UIDevice currentDevice] systemVersion] floatValue] == 9.000

#define EXTENSION_STRING "#extension GL_OES_standard_derivatives : enable"
static NSString * g_extensionStr = @EXTENSION_STRING;


- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type byteArray:(const GLchar *)source
{
GLint status;
if (!source)
    return NO;


#ifdef _IPHONE9_0

NSLog(@"USING IOS9 shaders");
// BEGIN workaround for Xcode 7 ios9----
BOOL hasExtension = NO;
NSString *sourceStr = [NSString stringWithUTF8String:source];
if([sourceStr containsString:g_extensionStr]) {
    hasExtension = YES;
    NSArray *strs = [sourceStr componentsSeparatedByString:g_extensionStr];
    assert(strs.count == 2);
    sourceStr = [strs componentsJoinedByString:@"\n"];
    source = (GLchar *)[sourceStr UTF8String];
}

const GLchar *sources[] = {
    (hasExtension ? EXTENSION_STRING "\n" : ""),
#ifdef __CC_PLATFORM_IOS
    (type == GL_VERTEX_SHADER ? "precision highp float;\n" : "precision mediump float;\n"),
 #endif
    "uniform mat4 CC_PMatrix;\n"
    "uniform mat4 CC_MVMatrix;\n"
    "uniform mat4 CC_MVPMatrix;\n"
    "uniform vec4 CC_Time;\n"
    "uniform vec4 CC_SinTime;\n"
    "uniform vec4 CC_CosTime;\n"
    "uniform vec4 CC_Random01;\n"
    "//CC INCLUDES END\n\n",
    source,
};
#else

NSLog(@"USING IOS8 shaders");

const GLchar *sources[] = {
#ifdef __CC_PLATFORM_IOS
    (type == GL_VERTEX_SHADER ? "precision highp float;\n" : "precision mediump float;\n"),
#endif
    "uniform mat4 CC_PMatrix;\n"
    "uniform mat4 CC_MVMatrix;\n"
    "uniform mat4 CC_MVPMatrix;\n"
    "uniform vec4 CC_Time;\n"
    "uniform vec4 CC_SinTime;\n"
    "uniform vec4 CC_CosTime;\n"
    "uniform vec4 CC_Random01;\n"
    "//CC INCLUDES END\n\n",
    source,
};

#endif


*shader = glCreateShader(type);
glShaderSource(*shader, sizeof(sources)/sizeof(*sources), sources, NULL);
glCompileShader(*shader);

glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);

if( ! status ) {
    GLsizei length;
    glGetShaderiv(*shader, GL_SHADER_SOURCE_LENGTH, &length);
    GLchar src[length];

    glGetShaderSource(*shader, length, NULL, src);
    CCLOG(@"cocos2d: ERROR: Failed to compile shader:\n%s", src);

    if( type == GL_VERTEX_SHADER )
        CCLOG(@"cocos2d: %@", [self vertexShaderLog] );
    else
        CCLOG(@"cocos2d: %@", [self fragmentShaderLog] );

    abort();
}
return ( status == GL_TRUE );
}

【讨论】:

  • 我用的是cocos2d-iphone 2.1 我觉得如果你用的是最新版本的cocos2d,对你来说会不一样。
  • 在 Cocos2d 2.1 版中使用它,它就像一个魅力:D!谢谢!
【解决方案3】:

使用上面接受的答案,但对于较新版本的 cocos2d:

在 CCShader.m 中替换行

static GLint
CompileShaderSources(GLenum type, NSArray *sources)
{

#define EXTENSION_STRING "#extension GL_OES_standard_derivatives : enable"
static NSString * g_extensionStr = @EXTENSION_STRING;

static NSArray * PrependExtensionIfNeeded(NSArray *sources)
{
    NSMutableArray *mutableSources = [NSMutableArray array];

    BOOL hasExtension = NO;

    for (NSString *source in sources)
    {
        NSString *newSource = [source copy];
        if([source rangeOfString:g_extensionStr].location != NSNotFound)
        {
            hasExtension = YES;
            NSArray *strs = [source componentsSeparatedByString:g_extensionStr];
            newSource = [strs componentsJoinedByString:@"\n"];
        }

        [mutableSources addObject:newSource];
    }

    if (hasExtension)
    {
        NSMutableString *firstSource = [NSMutableString stringWithString:[mutableSources firstObject]];
        [firstSource insertString:[NSString stringWithFormat:@"%@\n", g_extensionStr] atIndex:0];
        [mutableSources replaceObjectAtIndex:0 withObject:firstSource];
    }

    return mutableSources;
}

static GLint
CompileShaderSources(GLenum type, NSArray *sources)
{
    sources = PrependExtensionIfNeeded(sources);

【讨论】:

    【解决方案4】:

    注意:想写这个作为评论,但没有足够的声誉来写评论,因此写这个作为答案:

    Reid 描述的修复确实解决了这个问题。但是它在 iOS 7 设备上崩溃,因为它使用了仅在 iOS 8 及更高版本中可用的containsString 方法

    对以下行进行简单更改即可解决此问题:

    if([sourceStr containsString:g_extensionStr]) {
    

    需要改成:

    NSRange range = [sourceStr rangeOfString:g_extensionStr];
    if(range.length > 0) {
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      相关资源
      最近更新 更多