Coco2d 2.1 and Xcode 7 iOS 9 crash ccShader

前端 未结 4 1097
离开以前
离开以前 2020-12-25 15:23

I tested Xcode 7 with but my cocos2d 2.1 games crash on simulator or on devices:

ccShader_PositionColorLenghtTexture_frag.h

2015-06-15 22:36:13.319 N         


        
相关标签:
4条回答
  • 2020-12-25 15:25

    The accepted answer did not work for me, but this did.

    Go to the file named CCGLProgram.m

    Replace the entire method named - (BOOL)compileShader:(CLuint *)shader type(GLenum)typebyteArray:(const GLchar *)source

    with this method

    #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 );
    }
    
    0 讨论(0)
  • 2020-12-25 15:38

    NOTE: Wanted to write this as a comment but don't have enough reputation to write a comment, hence writing this as an answer:

    The fix described by Reid does fix the issue. However it crashes on iOS 7 devices, because it uses containsString method which is only available in iOS 8 and above

    A simple change to the following line fixes the issue:

    if([sourceStr containsString:g_extensionStr]) {
    

    needs to be changed to:

    NSRange range = [sourceStr rangeOfString:g_extensionStr];
    if(range.length > 0) {
    
    0 讨论(0)
  • 2020-12-25 15:47

    I'm "rae" on forum.cocos2d-objc.org and I might as well put my answer here as well, since all roads lead to StackOverflow. :-)

    If you are using an older release of Cocos 2D, this may help. I edited CCGLProgram.m to change the beginning of the -(BOOL)compileShader: method thusly:

    #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
    

    It's a hack, but it works for up to Xcode 7 beta 2. Hope this is helpful to someone googling for this.

    Reid

    0 讨论(0)
  • 2020-12-25 15:49

    Using the accepted answer above, but for newer versions of cocos2d:

    In CCShader.m replace the lines

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

    with

    #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);
    
    0 讨论(0)
提交回复
热议问题