1

我在 iOS objective-c 中做了一个类似 CC3DemoMultiScene 的示例,我遵循与示例中相同的代码

我的 AppDelegate 如下:

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{return YES;
}

-(void) applicationWillResignActive: (UIApplication*) application {
    [CCDirector.sharedDirector pause];
}

-(void) applicationDidBecomeActive: (UIApplication*) application {
    [CCDirector.sharedDirector resume];
}

-(void) applicationDidReceiveMemoryWarning: (UIApplication*) application {
}

-(void) applicationDidEnterBackground: (UIApplication*) application {
    [CCDirector.sharedDirector stopAnimation];
}

-(void) applicationWillEnterForeground: (UIApplication*) application {
    [CCDirector.sharedDirector startAnimation];
}

-(void)applicationWillTerminate: (UIApplication*) application {
    [CC3OpenGL terminateOpenGL];
}

-(void) applicationSignificantTimeChange: (UIApplication*) application {
    [CCDirector.sharedDirector setNextDeltaTimeZero: YES];
}

@end

编译时没有任何错误,但是在 iOS 模拟器中运行时,应用程序崩溃会打印出这个问题:

2015-08-14 16:43:26.446 ExampleCocos3d[9063:116836] *** Assertion failure in GLint CompileShader(GLenum, const char *)(), /Users/Dennis/Desktop/ExampleCocos3d/Libraries/DennisCocos3D/cocos2d/cocos2d/cocos2d/CCShader.m:173
2015-08-14 16:43:26.462 ExampleCocos3d[9063:116836] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error compiling shader'


  *** First throw call stack:
    (
        0   CoreFoundation                      0x000000010edc6c65 __exceptionPreprocess + 165
        1   libobjc.A.dylib                     0x000000010e642bb7 objc_exception_throw + 45
        2   CoreFoundation                      0x000000010edc6aca +[NSException raise:format:arguments:] + 106
        3   Foundation                          0x000000010e149a57 -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 169
        4   ExampleCocos3d                      0x000000010aab3d0c CompileShader + 364
        5   ExampleCocos3d                      0x000000010aab3964 -[CCShader initWithVertexShaderSource:fragmentShaderSource:] + 212
        6   ExampleCocos3d                      0x000000010aab3ebd -[CCShader initWithFragmentShaderSource:] + 77
        7   ExampleCocos3d                      0x000000010aab40d4 +[CCShader initialize] + 180
        8   libobjc.A.dylib                     0x000000010e6434d6 _class_initialize + 648
        9   libobjc.A.dylib                     0x000000010e64c6e1 lookUpImpOrForward + 351
        10  libobjc.A.dylib                     0x000000010e6590d3 objc_msgSend + 211
        11  ExampleCocos3d                      0x000000010aabd331 -[CCRenderer init] + 353
        12  ExampleCocos3d                      0x000000010ade7c1b -[CCDirector init] + 875
        13  ExampleCocos3d                      0x000000010ad6e266 -[CCDirectorIOS init] + 54
        14  ExampleCocos3d                      0x000000010ade7760 +[CCDirector sharedDirector] + 144
        15  ExampleCocos3d                      0x000000010ace34bd -[AppDelegate applicationDidBecomeActive:] + 61
        16  UIKit                               0x000000010c2b92ce -[UIApplication _stopDeactivatingForReason:] + 313
        17  UIKit                               0x000000010c2ce417 -[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:] + 2589
        18  FrontBoardServices                  0x0000000112a845e5 __31-[FBSSerialQueue performAsync:]_block_invoke_2 + 21
        19  CoreFoundation                      0x000000010ecfa41c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
        20  CoreFoundation                      0x000000010ecf0165 __CFRunLoopDoBlocks + 341
        21  CoreFoundation                      0x000000010eceff25 __CFRunLoopRun + 2389
        22  CoreFoundation                      0x000000010ecef366 CFRunLoopRunSpecific + 470
        23  GraphicsServices                    0x000000011071ca3e GSEventRunModal + 161
        24  UIKit                               0x000000010c2be900 UIApplicationMain + 1282
        25  Tripsland                           0x000000010ad63b4f main + 111
        26  libdyld.dylib                       0x000000010f465145 start + 1
        27  ???                                 0x0000000000000001 0x0 + 1
    )
    libc++abi.dylib: terminating with uncaught exception of type NSException
    (lldb)
                //------------------------------------------//
                //               THANKS GUYS                //
                //          GRETTINGS FROM BOLIVIA          //
                //             ROCK ON!!!! n_n'             //
                //------------------------------------------//

请帮忙!!或者 Cocos2D 库的 CCShader.m 文件中存在任何错误,错误产生在:

static GLint
CompileShader(GLenum type, const char *source)
{
    GLint shader = glCreateShader(type);

    const GLchar *sources[] = {
        CCShaderHeader,
        CCShaderTypeHeader(type),
        source,
    };

    glShaderSource(shader, 3, sources, NULL);

    glCompileShader(shader);

    NSCAssert(CCCheckShaderError(shader, GL_COMPILE_STATUS, glGetShaderiv, glGetShaderInfoLog), @"Error compiling shader");

    return shader;
}

第一次编辑:感谢推荐user2242300

以及来自CCShader的.h.m文件在

cocos2d-library-iOS.xcodeproj/cocos2d/cocos2d/CCShader.h
cocos2d-library-iOS.xcodeproj/cocos2d/cocos2d/CCShader.m

CCShader.h文件有:

#import <Foundation/Foundation.h>
#import "ccTypes.h"
#import "ccMacros.h"
#import "Platforms/CCGL.h"

/// Macro to embed GLSL source
#define CC_GLSL(x) @#x


extern const NSString *CCShaderUniformProjection;
extern const NSString *CCShaderUniformProjectionInv;
extern const NSString *CCShaderUniformViewSize;
extern const NSString *CCShaderUniformViewSizeInPixels;
extern const NSString *CCShaderUniformTime;
extern const NSString *CCShaderUniformSinTime;
extern const NSString *CCShaderUniformCosTime;
extern const NSString *CCShaderUniformRandom01;
extern const NSString *CCShaderUniformMainTexture;
extern const NSString *CCShaderUniformNormalMapTexture;
extern const NSString *CCShaderUniformAlphaTestValue;


@interface CCShader : NSObject<NSCopying>

@property(nonatomic, copy) NSString *debugName;

+(instancetype)shaderNamed:(NSString *)shaderName;

-(instancetype)initWithVertexShaderSource:(NSString *)vertexSource fragmentShaderSource:(NSString *)fragmentSource;
-(instancetype)initWithFragmentShaderSource:(NSString *)source;

+(instancetype)positionColorShader;
+(instancetype)positionTextureColorShader;
+(instancetype)positionTextureColorAlphaTestShader;
+(instancetype)positionTextureA8ColorShader;

@end

CCShader.m有:

#import "CCShader_private.h"
#import "ccMacros.h"
#import "Support/CCFileUtils.h"
#import "Support/uthash.h"
#import "CCRenderer_private.h"
#import "CCTexture_private.h"
#import "CCDirector.h"
#import "CCCache.h"
#import "CCGL.h"


enum {
    CCAttributePosition,
    CCAttributeTexCoord1,
    CCAttributeTexCoord2,
    CCAttributeColor,
};


const NSString *CCShaderUniformProjection = @"cc_Projection";
const NSString *CCShaderUniformProjectionInv = @"cc_ProjectionInv";
const NSString *CCShaderUniformViewSize = @"cc_ViewSize";
const NSString *CCShaderUniformViewSizeInPixels = @"cc_ViewSizeInPixels";
const NSString *CCShaderUniformTime = @"cc_Time";
const NSString *CCShaderUniformSinTime = @"cc_SinTime";
const NSString *CCShaderUniformCosTime = @"cc_CosTime";
const NSString *CCShaderUniformRandom01 = @"cc_Random01";
const NSString *CCShaderUniformMainTexture = @"cc_MainTexture";
const NSString *CCShaderUniformNormalMapTexture = @"cc_NormalMapTexture";
const NSString *CCShaderUniformAlphaTestValue = @"cc_AlphaTestValue";


// Stringify macros
#define STR(s) #s
#define XSTR(s) STR(s)

/*
    main texture size points/pixels?
*/
static const GLchar *CCShaderHeader =
    "#ifndef GL_ES\n"
    "#define lowp\n"
    "#define mediump\n"
    "#define highp\n"
    "#endif\n\n"
    "uniform highp mat4 cc_Projection;\n"
    "uniform highp mat4 cc_ProjectionInv;\n"
    "uniform highp vec2 cc_ViewSize;\n"
    "uniform highp vec2 cc_ViewSizeInPixels;\n"
    "uniform highp vec4 cc_Time;\n"
    "uniform highp vec4 cc_SinTime;\n"
    "uniform highp vec4 cc_CosTime;\n"
    "uniform highp vec4 cc_Random01;\n\n"
    "uniform " XSTR(CC_SHADER_COLOR_PRECISION) " sampler2D cc_MainTexture;\n\n"
    "uniform " XSTR(CC_SHADER_COLOR_PRECISION) " sampler2D cc_NormalMapTexture;\n\n"
    "varying " XSTR(CC_SHADER_COLOR_PRECISION) " vec4 cc_FragColor;\n"
    "varying highp vec2 cc_FragTexCoord1;\n"
    "varying highp vec2 cc_FragTexCoord2;\n\n"
    "// End Cocos2D shader header.\n\n";

static const GLchar *CCVertexShaderHeader =
    "#ifdef GL_ES\n"
    "precision highp float;\n\n"
    "#endif\n\n"
    "#define CC_NODE_RENDER_SUBPIXEL " XSTR(CC_NODE_RENDER_SUBPIXEL) "\n"
    "attribute highp vec4 cc_Position;\n"
    "attribute highp vec2 cc_TexCoord1;\n"
    "attribute highp vec2 cc_TexCoord2;\n"
    "attribute highp vec4 cc_Color;\n\n"
    "// End Cocos2D vertex shader header.\n\n";

static const GLchar *CCFragmentShaderHeader =
    "#ifdef GL_ES\n"
    "precision " XSTR(CC_SHADER_DEFAULT_FRAGMENT_PRECISION) " float;\n"
    "#endif\n\n"
    "// End Cocos2D fragment shader header.\n\n";

static NSString *CCDefaultVShader =
    @"void main(){\n"
    @"  gl_Position = cc_Position;\n"
    @"#if !CC_NODE_RENDER_SUBPIXEL\n"
    @"  vec2 pixelPos = (0.5*gl_Position.xy/gl_Position.w + 0.5)*cc_ViewSizeInPixels;\n"
    @"  gl_Position.xy = (2.0*floor(pixelPos)/cc_ViewSizeInPixels - 1.0)*gl_Position.w;\n"
    @"#endif\n\n"
    @"  cc_FragColor = clamp(cc_Color, 0.0, 1.0);\n"
    @"  cc_FragTexCoord1 = cc_TexCoord1;\n"
    @"  cc_FragTexCoord2 = cc_TexCoord2;\n"
    @"}\n";

typedef void (* GetShaderivFunc) (GLuint shader, GLenum pname, GLint* param);
typedef void (* GetShaderInfoLogFunc) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);

static BOOL
CCCheckShaderError(GLint obj, GLenum status, GetShaderivFunc getiv, GetShaderInfoLogFunc getInfoLog)
{
    GLint success;
    getiv(obj, status, &success);

    if(!success){
        GLint length;
        getiv(obj, GL_INFO_LOG_LENGTH, &length);

        char *log = (char *)alloca(length);
        getInfoLog(obj, length, NULL, log);

        fprintf(stderr, "Shader compile error for 0x%04X: %s\n", status, log);
        return NO;
    } else {
        return YES;
    }
}

static const GLchar *
CCShaderTypeHeader(GLenum type)
{
    switch(type){
        case GL_VERTEX_SHADER: return CCVertexShaderHeader;
        case GL_FRAGMENT_SHADER: return CCFragmentShaderHeader;
        default: NSCAssert(NO, @"Bad shader type enumeration."); return NULL;
    }
}

static GLint
CompileShader(GLenum type, const char *source)
{
    GLint shader = glCreateShader(type);

    const GLchar *sources[] = {
        CCShaderHeader,
        CCShaderTypeHeader(type),
        source,
    };

    glShaderSource(shader, 3, sources, NULL);

    glCompileShader(shader);

    NSCAssert(CCCheckShaderError(shader, GL_COMPILE_STATUS, glGetShaderiv, glGetShaderInfoLog), @"Error compiling shader");

    return shader;
}


@interface CCShaderCache : CCCache @end
@implementation CCShaderCache

-(id)createSharedDataForKey:(id<NSCopying>)key
{
    NSString *shaderName = (NSString *)key;

    NSString *fragmentName = [shaderName stringByAppendingPathExtension:@"fsh"];
    NSString *fragmentPath = [[CCFileUtils sharedFileUtils] fullPathForFilename:fragmentName];
    NSAssert(fragmentPath, @"Failed to find '%@'.", fragmentName);
    NSString *fragmentSource = [NSString stringWithContentsOfFile:fragmentPath encoding:NSUTF8StringEncoding error:nil];

    NSString *vertexName = [shaderName stringByAppendingPathExtension:@"vsh"];
    NSString *vertexPath = [[CCFileUtils sharedFileUtils] fullPathForFilename:vertexName];
    NSString *vertexSource = (vertexPath ? [NSString stringWithContentsOfFile:vertexPath encoding:NSUTF8StringEncoding error:nil] : CCDefaultVShader);

    CCShader *shader = [[CCShader alloc] initWithVertexShaderSource:vertexSource fragmentShaderSource:fragmentSource];
    shader.debugName = @"shaderName";

    return shader;
}

-(id)createPublicObjectForSharedData:(id)data
{
    return [data copy];
}

@end


@implementation CCShader {
    BOOL _ownsProgram;
}

+(GLuint)createVAOforCCVertexBuffer:(GLuint)vbo elementBuffer:(GLuint)ebo
{
    glPushGroupMarkerEXT(0, "CCShader: Creating vertex buffer");

    GLuint vao = 0;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glEnableVertexAttribArray(CCAttributePosition);
    glEnableVertexAttribArray(CCAttributeTexCoord1);
    glEnableVertexAttribArray(CCAttributeTexCoord2);
    glEnableVertexAttribArray(CCAttributeColor);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(CCAttributePosition, 4, GL_FLOAT, GL_FALSE, sizeof(CCVertex), (void *)offsetof(CCVertex, position));
    glVertexAttribPointer(CCAttributeTexCoord1, 2, GL_FLOAT, GL_FALSE, sizeof(CCVertex), (void *)offsetof(CCVertex, texCoord1));
    glVertexAttribPointer(CCAttributeTexCoord2, 2, GL_FLOAT, GL_FALSE, sizeof(CCVertex), (void *)offsetof(CCVertex, texCoord2));
    glVertexAttribPointer(CCAttributeColor, 4, GL_FLOAT, GL_FALSE, sizeof(CCVertex), (void *)offsetof(CCVertex, color));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glPopGroupMarkerEXT();

    return vao;
}

//MARK: Uniform Setters:

static CCUniformSetter
SetFloat(NSString *name, GLint location)
{
    return ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
        NSNumber *value = shaderUniforms[name] ?: globalShaderUniforms[name] ?: @(0.0);
        NSCAssert([value isKindOfClass:[NSNumber class]], @"Shader uniform '%@' value must be wrapped in a NSNumber.", name);

        glUniform1f(location, value.floatValue);
    };
}

static CCUniformSetter
SetVec2(NSString *name, GLint location)
{
    NSString *textureName = nil;
    bool pixelSize = [name hasSuffix:@"PixelSize"];
    if(pixelSize){
        textureName = [name substringToIndex:name.length - @"PixelSize".length];
    } else if([name hasSuffix:@"Size"]){
        textureName = [name substringToIndex:name.length - @"Size".length];
    }

    return ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
        NSValue *value = shaderUniforms[name] ?: globalShaderUniforms[name];

        // Fall back on looking up the actual texture size if the name matches a texture.
        if(value == nil && textureName){
            CCTexture *texture = shaderUniforms[textureName] ?: globalShaderUniforms[textureName];
            GLKVector2 sizeInPixels = GLKVector2Make(texture.pixelWidth, texture.pixelHeight);

            GLKVector2 size = GLKVector2MultiplyScalar(sizeInPixels, pixelSize ? 1.0 : 1.0/texture.contentScale);
            value = [NSValue valueWithGLKVector2:size];
        }

        // Finally fall back on 0.
        if(value == nil) value = [NSValue valueWithGLKVector2:GLKVector2Make(0.0f, 0.0f)];

        NSCAssert([value isKindOfClass:[NSValue class]], @"Shader uniform '%@' value must be wrapped in a NSValue.", name);

        if(strcmp(value.objCType, @encode(GLKVector2)) == 0){
            GLKVector2 v; [value getValue:&v];
            glUniform2f(location, v.x, v.y);
        } else if(strcmp(value.objCType, @encode(CGPoint)) == 0){
            CGPoint v = {}; [value getValue:&v];
            glUniform2f(location, v.x, v.y);
        } else if(strcmp(value.objCType, @encode(CGSize)) == 0){
            CGSize v = {}; [value getValue:&v];
            glUniform2f(location, v.width, v.height);
        } else {
            NSCAssert(NO, @"Shader uniformm 'vec2 %@' value must be passed using [NSValue valueWithGLKVector2:], [NSValue valueWithCGPoint:], or [NSValue valueWithCGSize:]", name);
        }
    };
}

static CCUniformSetter
SetVec3(NSString *name, GLint location)
{
    return ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
        NSValue *value = shaderUniforms[name] ?: globalShaderUniforms[name] ?: [NSValue valueWithGLKVector3:GLKVector3Make(0.0f, 0.0f, 0.0f)];
        NSCAssert([value isKindOfClass:[NSValue class]], @"Shader uniform '%@' value must be wrapped in a NSValue.", name);
        NSCAssert(strcmp(value.objCType, @encode(GLKVector3)) == 0, @"Shader uniformm 'vec3 %@' value must be passed using [NSValue valueWithGLKVector3:]", name);

        GLKVector3 v; [value getValue:&v];
        glUniform3f(location, v.x, v.y, v.z);
    };
}

static CCUniformSetter
SetVec4(NSString *name, GLint location)
{
    return ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
        NSValue *value = shaderUniforms[name] ?: globalShaderUniforms[name] ?: [NSValue valueWithGLKVector4:GLKVector4Make(0.0f, 0.0f, 0.0f, 1.0f)];

        if([value isKindOfClass:[NSValue class]]){
            NSCAssert(strcmp([(NSValue *)value objCType], @encode(GLKVector4)) == 0, @"Shader uniformm 'vec4 %@' value must be passed using [NSValue valueWithGLKVector4:].", name);

            GLKVector4 v; [value getValue:&v];
            glUniform4f(location, v.x, v.y, v.z, v.w);
        } else if([value isKindOfClass:[CCColor class]]){
            GLKVector4 v = [(CCColor *)value glkVector4];
            glUniform4f(location, v.x, v.y, v.z, v.w);
        } else {
            NSCAssert(NO, @"Shader uniformm 'vec4 %@' value must be passed using [NSValue valueWithGLKVector4:] or a CCColor object.", name);
        }
    };
}

static CCUniformSetter
SetMat4(NSString *name, GLint location)
{
    return ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
        NSValue *value = shaderUniforms[name] ?: globalShaderUniforms[name] ?: [NSValue valueWithGLKMatrix4:GLKMatrix4Identity];
        NSCAssert([value isKindOfClass:[NSValue class]], @"Shader uniform '%@' value must be wrapped in a NSValue.", name);
        NSCAssert(strcmp(value.objCType, @encode(GLKMatrix4)) == 0, @"Shader uniformm 'mat4 %@' value must be passed using [NSValue valueWithGLKMatrix4:]", name);

        GLKMatrix4 m; [value getValue:&m];
        glUniformMatrix4fv(location, 1, GL_FALSE, m.m);
    };
}

-(NSDictionary *)uniformSettersForProgram:(GLuint)program
{
    NSMutableDictionary *uniformSetters = [NSMutableDictionary dictionary];

    glUseProgram(program);

    GLint count = 0;
    glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count);

    int textureUnit = 0;

    for(int i=0; i<count; i++){
        GLchar cname[256];
        GLsizei length = 0;
        GLsizei size = 0;
        GLenum type = 0;

        glGetActiveUniform(program, i, sizeof(cname), &length, &size, &type, cname);
        NSAssert(size == 1, @"Uniform arrays not supported. (yet?)");

        NSString *name = @(cname);
        GLint location = glGetUniformLocation(program, cname);

        // Setup a block that is responsible for binding that uniform variable's value.
        switch(type){
            default: NSAssert(NO, @"Uniform type not supported. (yet?)");
            case GL_FLOAT: uniformSetters[name] = SetFloat(name, location); break;
            case GL_FLOAT_VEC2: uniformSetters[name] = SetVec2(name, location); break;
            case GL_FLOAT_VEC3: uniformSetters[name] = SetVec3(name, location); break;
            case GL_FLOAT_VEC4: uniformSetters[name] = SetVec4(name, location); break;
            case GL_FLOAT_MAT4: uniformSetters[name] = SetMat4(name, location); break;
            case GL_SAMPLER_2D: {
                // Sampler setters are handled a differently since the real work is binding the texture and not setting the uniform value.
                uniformSetters[name] = ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
                    CCTexture *texture = shaderUniforms[name] ?: globalShaderUniforms[name] ?: [CCTexture none];
                    NSAssert([texture isKindOfClass:[CCTexture class]], @"Shader uniform '%@' value must be a CCTexture object.", name);

                    // Bind the texture to the texture unit for the uniform.
                    glActiveTexture(GL_TEXTURE0 + textureUnit);
                    glBindTexture(GL_TEXTURE_2D, texture.name);
                };

                // Bind the texture unit at init time.
                glUniform1i(location, textureUnit);
                textureUnit++;
            }
        }
    }

    return uniformSetters;
}

//MARK: Init Methods:

-(instancetype)initWithProgram:(GLuint)program uniformSetters:(NSDictionary *)uniformSetters ownsProgram:(BOOL)ownsProgram
{
    if((self = [super init])){
        _program = program;
        _uniformSetters = uniformSetters;
        _ownsProgram = ownsProgram;
    }

    return self;
}

-(instancetype)initWithVertexShaderSource:(NSString *)vertexSource fragmentShaderSource:(NSString *)fragmentSource
{
    glPushGroupMarkerEXT(0, "CCShader: Init");

    GLuint program = glCreateProgram();
    glBindAttribLocation(program, CCAttributePosition, "cc_Position");
    glBindAttribLocation(program, CCAttributeTexCoord1, "cc_TexCoord1");
    glBindAttribLocation(program, CCAttributeTexCoord2, "cc_TexCoord2");
    glBindAttribLocation(program, CCAttributeColor, "cc_Color");

    GLint vshader = CompileShader(GL_VERTEX_SHADER, vertexSource.UTF8String);
    glAttachShader(program, vshader);

    GLint fshader = CompileShader(GL_FRAGMENT_SHADER, fragmentSource.UTF8String);
    glAttachShader(program, fshader);

    glLinkProgram(program);
    NSCAssert(CCCheckShaderError(program, GL_LINK_STATUS, glGetProgramiv, glGetProgramInfoLog), @"Error linking shader program");

    glDeleteShader(vshader);
    glDeleteShader(fshader);

    glPopGroupMarkerEXT();

    return [self initWithProgram:program uniformSetters:[self uniformSettersForProgram:program] ownsProgram:YES];
}

-(instancetype)initWithFragmentShaderSource:(NSString *)source
{
    return [self initWithVertexShaderSource:CCDefaultVShader fragmentShaderSource:source];
}

- (void)dealloc
{
    CCLOGINFO( @"cocos2d: deallocing %@", self);

    if(_ownsProgram && _program) glDeleteProgram(_program);
}

-(instancetype)copyWithZone:(NSZone *)zone
{
    return [[CCShader allocWithZone:zone] initWithProgram:_program uniformSetters:_uniformSetters ownsProgram:NO];
}

static CCShaderCache *CC_SHADER_CACHE = nil;
static CCShader *CC_SHADER_POS_COLOR = nil;
static CCShader *CC_SHADER_POS_TEX_COLOR = nil;
static CCShader *CC_SHADER_POS_TEXA8_COLOR = nil;
static CCShader *CC_SHADER_POS_TEX_COLOR_ALPHA_TEST = nil;

+(void)initialize
{
    // +initialize may be called due to loading a subclass.
    if(self != [CCShader class]) return;

    CC_SHADER_CACHE = [[CCShaderCache alloc] init];

    // Setup the builtin shaders.
    CC_SHADER_POS_COLOR = [[self alloc] initWithFragmentShaderSource:@"void main(){gl_FragColor = cc_FragColor;}"];
    CC_SHADER_POS_COLOR.debugName = @"CCPositionColorShader";

    CC_SHADER_POS_TEX_COLOR = [[self alloc] initWithFragmentShaderSource:@"void main(){gl_FragColor = cc_FragColor*texture2D(cc_MainTexture, cc_FragTexCoord1);}"];
    CC_SHADER_POS_TEX_COLOR.debugName = @"CCPositionTextureColorShader";

    CC_SHADER_POS_TEXA8_COLOR = [[self alloc] initWithFragmentShaderSource:@"void main(){gl_FragColor = cc_FragColor*texture2D(cc_MainTexture, cc_FragTexCoord1).a;}"];
    CC_SHADER_POS_TEXA8_COLOR.debugName = @"CCPositionTextureA8ColorShader";

    CC_SHADER_POS_TEX_COLOR_ALPHA_TEST = [[self alloc] initWithFragmentShaderSource:CC_GLSL(
        uniform float cc_AlphaTestValue;
        void main(){
            vec4 tex = texture2D(cc_MainTexture, cc_FragTexCoord1);
            if(tex.a <= cc_AlphaTestValue) discard;
            gl_FragColor = cc_FragColor*tex;
        }
    )];
    CC_SHADER_POS_TEX_COLOR_ALPHA_TEST.debugName = @"CCPositionTextureColorAlphaTestShader";
}

+(instancetype)positionColorShader
{
    return CC_SHADER_POS_COLOR;
}

+(instancetype)positionTextureColorShader
{
    return CC_SHADER_POS_TEX_COLOR;
}

+(instancetype)positionTextureColorAlphaTestShader
{
    return CC_SHADER_POS_TEX_COLOR_ALPHA_TEST;
}

+(instancetype)positionTextureA8ColorShader
{
    return CC_SHADER_POS_TEXA8_COLOR;
}

+(instancetype)shaderNamed:(NSString *)shaderName
{
    return [CC_SHADER_CACHE objectForKey:shaderName];
}

@end

您可以从以下位置获取示例代码:cocos3dFile Projects中的CC3DemoMultiScene

第二次编辑:

我在 StackOverflow 和这个论坛上阅读了几个回复:Cocos 2D 论坛,我不得不重新安装 xCode,我不知道发生了什么?但现在,不要给我看 CCShader 错误,给我看:

OpenGL error GL_INVALID_OPERATION detected at -[CCRenderer(NoARCPrivate) setRenderState:] 232

在 2 个不同的 ViewController 中显示 1 个 Cocos 3D 场景的最佳方式是什么?

再次感谢!!

4

1 回答 1

1

经过多次搜索和调查,导致问题的原因是因为这会导致在 MainViewController createGLView 方法(初始化 CCDirector.sharedDirector 单例)之前调用 AppDelegate applicationDidBecomeActive: 方法(引用 CCDirector.sharedDirector 单例)。

引用 AppDelegate applicationDidBecomeActive: 中未初始化的 CCDirector.sharedDirector 单例:在正确设置 OpenGL 上下文之前触发一大堆 Cocos2D OpenGL ES 初始化,导致一堆着色器加载活动失败。

解决此问题的最佳方法是确保在其他地方对 CCDirector.sharedDirector 单例的任何引用之前运行 MainViewController createGLView 方法中的代码。

我们也可以在短期内通过注释掉 AppDelegate applicationDidBecomeActive: 方法中的代码来回避这个问题,但这可能会影响您的应用在后台进出时的行为。

就像@Bill Hollings在以下问题中的答案: iOS 9 上 Xcode 7.1.1 中的 Error CompileShader?错误 cocos3d + 故事板?

我配置并尝试了一个示例DennisCocos3D Prueba (dropbox)

或尝试:

在 MainViewController .m 文件中:

 -(CCGLView*) createGLView {

    // Create the view first, since it creates the GL context, which CCDirector expects during init.
    CCGLView* glView = [CCGLView viewWithFrame: _cc3FrameView.bounds
                                   pixelFormat: kEAGLColorFormatRGBA8
                                   depthFormat: GL_DEPTH24_STENCIL8     // Shadow volumes require a stencil
                            preserveBackbuffer: NO
                               numberOfSamples: 1];



    CCDirector* director = CCDirector.sharedDirector;
    director.animationInterval = (1.0f / kAnimationFrameRate);
    director.displayStats = YES;
    director.view = glView;

    // Run the initial static 2D intro scene
    [director runWithScene: [[self makeIntroScene] asCCScene]];

    if(![[CCDirector sharedDirector]  runningScene])
    {

        [[CCDirector sharedDirector] runWithScene:[[self makeIntroScene] asCCScene]];
    }
    else
    {
        [[CCDirector sharedDirector] startAnimation];


        [[CCDirector sharedDirector] replaceScene:[[self makeIntroScene] asCCScene]];
    }

    return glView;
}
于 2016-04-26T03:33:13.363 回答