使用SCNRenderer时未渲染overlaySKScene

问题描述 投票:0回答:2

我使用

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

SCN渲染器设置:

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];
}
ios sprite-kit ios9 scenekit
2个回答
0
投票

弄乱 skScene。设置。当我切换到 ios9 时,没有任何触摸通过。我必须添加 skScene.userInteractionEnabled = NO; iOS8 中不需要。我猜默认值已更改或将其设置为覆盖不再更改默认值。

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


0
投票

苹果似乎添加了一个新属性:

    self.scnView?.rendersContinuously = true

这为我解决了问题。

https://developer.apple.com/documentation/scenekit/scnview/2867339-renderscontinuously

© www.soinside.com 2019 - 2024. All rights reserved.