Coco2d 2.1 和 Xcode 7 iOS 9 崩溃 ccShader

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30864055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 07:18:49  来源:igfitidea点击:

Coco2d 2.1 and Xcode 7 iOS 9 crash ccShader

xcodecocos2d-iphone

提问by Beno?t Freslon

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

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

ccShader_PositionColorLenghtTexture_frag.h

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

and

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

This class crash the game

这个类使游戏崩溃

#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                                                                                                                      
}

回答by Reid Ellis

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

我是forum.cocos2d-objc.org上的“rae” ,我也不妨把我的答案放在这里,因为所有的道路都通向 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:

如果您使用的是较旧版本的 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

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

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

Reid

里德

回答by bodagetta

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

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

Go to the file named CCGLProgram.m

转到名为的文件 CCGLProgram.m

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

替换整个方法命名 - (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 );
}

回答by Austin Borden

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

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

In CCShader.m replace the lines

在 CCShader.m 中替换行

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);

回答by Deep Shah

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 Reiddoes fix the issue. However it crashes on iOS 7 devices, because it uses containsStringmethod which is only available in iOS 8 and above

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

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) {