OverlaySKScene not showing when using SCNRenderer

I use SCNRendererto render the scene into an existing OpenGL context (basically a modified version of the Vuforia ImageTarget sample) and overlaySKSceneto display annotations for objects in the scene.

Since the upgrade to iOS 9, is overlaySKSceneno longer displayed. Called none of the actions of each frame ( update:, didEvaluateActions, ...).

It worked with iOS 8, and the same SKScenestill works with SCNViewa different view controller in the same application.

Context Setting:

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

OpenGL Initiation (mostly copied from Vuforia sample):

- (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 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];
}

Configure 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 makes a callback:

- (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];
}
+4
1

skScene. . ios9, . skScene.userInteractionEnabled = NO; iOS8. , .

, , , skScene.

0

Source: https://habr.com/ru/post/1609606/


All Articles