使用SCNRenderer时,overlaySKScene未呈现

时间:2015-09-30 10:04:39

标签: ios sprite-kit ios9 scenekit

我正在使用SCNRenderer将场景渲染到现有的OpenGL上下文(基本上是Vuforia ImageTarget示例的修改版本)和overlaySKScene以显示场景中对象的注释。

自iOS 9更新后,overlaySKScene不再呈现。没有任何每帧动作(update:didEvaluateActions,...)被调用。

它适用于iOS 8,同一个应用程序中的SKScene同样适用于SCNView在另一个视图控制器中。

上下文设置:

self.context = [[EAGLContext alloc] initWithAPI:context.API sharegroup:scnViewContext.sharegroup];

OpenGL初始化(主要从Vuforia样本中复制):

- (void)createFramebuffer
{
    if (self.context) {
        // Create default framebuffer object
        glGenFramebuffers(1, &_defaultFramebuffer);
        glBindFramebuffer(GL_FRAMEBUFFER, self.defaultFramebuffer);

        // Create colour renderbuffer and allocate backing store
        glGenRenderbuffers(1, &_colorRenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, self.colorRenderbuffer);

        // Allocate the renderbuffer's storage (shared with the drawable object)
        [self.context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];
        GLint framebufferWidth;
        GLint framebufferHeight;
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);

        // Create the depth render buffer and allocate storage
        glGenRenderbuffers(1, &_depthRenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, self.depthRenderbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, framebufferWidth, framebufferHeight);

        // Attach colour and depth render buffers to the frame buffer
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, self.colorRenderbuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, self.depthRenderbuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, self.stencilRenderbuffer);

        // Leave the colour render buffer bound so future rendering operations will act on it
        glBindRenderbuffer(GL_RENDERBUFFER, self.colorRenderbuffer);
    }
}

- (void)setFramebuffer{
    // The EAGLContext must be set for each thread that wishes to use it.  Set
    // it the first time this method is called (on the render thread)
    if (self.context != [EAGLContext currentContext]) {
        [EAGLContext setCurrentContext:self.context];
    }

    if (!self.defaultFramebuffer) {
        // Perform on the main thread to ensure safe memory allocation for the
        // shared buffer.  Block until the operation is complete to prevent
        // simultaneous access to the OpenGL context
        [self performSelectorOnMainThread:@selector(createFramebuffer) withObject:self waitUntilDone:YES];
    }

    glBindFramebuffer(GL_FRAMEBUFFER, self.defaultFramebuffer);
}

- (BOOL)presentFramebuffer
{
    // setFramebuffer must have been called before presentFramebuffer, therefore
    // we know the context is valid and has been set for this (render) thread

    // Bind the colour render buffer and present it
    glBindRenderbuffer(GL_RENDERBUFFER, self.colorRenderbuffer);

    return [self.context presentRenderbuffer:GL_RENDERBUFFER];
}

SCNRenderer设置:

self.skScene = [[MarkerOverlayScene alloc] initWithSize:CGSizeMake(2048, 2048)];

self.renderer = [SCNRenderer rendererWithContext:self.context options:nil];
self.renderer.autoenablesDefaultLighting = NO;
self.renderer.delegate = self;
self.renderer.overlaySKScene = self.skScene;
self.renderer.playing = YES;

if (self.sceneURL) {
    self.renderer.scene = [SCNScene sceneWithURL:self.sceneURL options:nil error:nil];

    [self.renderer prepareObjects:@[self.renderer.scene] withCompletionHandler:^(BOOL success) {
    }];
}

Vuforia渲染回调:

- (void)renderFrameQCAR
{
    [self setFramebuffer];

    // Clear colour and depth buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Render video background and retrieve tracking state
    QCAR::State state = QCAR::Renderer::getInstance().begin();
    QCAR::Renderer::getInstance().drawVideoBackground();

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    glCullFace(GL_BACK);
    if(QCAR::Renderer::getInstance().getVideoBackgroundConfig().mReflection == QCAR::VIDEO_BACKGROUND_REFLECTION_ON) {
        glFrontFace(GL_CW);  //Front camera
    } else {
        glFrontFace(GL_CCW);   //Back camera
    }

    for (int i = 0; i < state.getNumTrackableResults(); ++i) {
        // Get the trackable
        const QCAR::TrackableResult* result = state.getTrackableResult(i);

        QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(result->getPose());

        SCNMatrix4 matrix = [self convertARMatrix:modelViewMatrix];
        matrix = SCNMatrix4Mult(SCNMatrix4MakeRotation(M_PI_2, 1, 0, 0), matrix);
        matrix = SCNMatrix4Mult(SCNMatrix4MakeScale(10, 10, 10), matrix);

        self.arTransform = matrix;
    }

    if (state.getNumTrackableResults() == 0) {
        self.arTransform = SCNMatrix4Identity;
    }

    [self.renderer renderAtTime:CFAbsoluteTimeGetCurrent() - self.startTime];

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    QCAR::Renderer::getInstance().end();
    [self presentFramebuffer];
}

1 个答案:

答案 0 :(得分:0)

与skScene混淆。设置。当我切换到ios9时,没有任何接触通过。我不得不添加skScene.userInteractionEnabled = NO;这在iOS8中是不需要的。我猜默认值已更改或将其设置为叠加层不再更改默认值。

无论如何,问题可能在于skScene设置。