GLKView doesn't fill up the containing view

244 Views Asked by At

I want to display a CIImage in a GLKView. The GLKView is in a containing view (the superview). I want the GLKView to render the image as aspect-fill. I want the GLKView to take up all the space of the containing UIView.

But not matter what I seem to do it comes out the wrong way. The result can be seen in the following image. The containing view has red background to make it easy to see. At the top we have the navigation bar and at the bottom is a toolbar with some grayed-out icons.

enter image description here

I simply have no idea why the GLKView won't fill up all of the containing view.

This is the code of the GLRenderer that does this

class GLImageRenderer {
    private var glContext: EAGLContext
    private var videoDisplayViewBounds: CGRect
    private var videoDisplayView: GLKView
    private var scale: CGFloat
    private var renderContext: CIContext

    init(superView: UIView) {
        superView.backgroundColor = UIColor.red
        glContext = EAGLContext(api: EAGLRenderingAPI.openGLES2)!
        videoDisplayView = GLKView(frame: superView.frame, context: glContext)
        videoDisplayView.contentScaleFactor = UIScreen.main.scale
        videoDisplayView.contentMode = .scaleAspectFill
        videoDisplayView.frame = superView.frame
        videoDisplayView.transform = CGAffineTransform.init(rotationAngle: CGFloat.pi/2)

        superView.addSubview(videoDisplayView)
        superView.sendSubviewToBack(videoDisplayView)

        renderContext = CIContext(eaglContext: videoDisplayView.context)

        videoDisplayView.bindDrawable()
        videoDisplayViewBounds = CGRect(x: 0,
                                        y: 0,
                                        width: videoDisplayView.drawableWidth,
                                        height: videoDisplayView.drawableHeight)

        scale = UIScreen.main.scale
    }

    func draw(ciimage: CIImage) {
        let drawFrame = ciimage.extent

        let imageAspectRatio = drawFrame.width / drawFrame.height
        let viewAspectRatio = videoDisplayViewBounds.width / videoDisplayViewBounds.height


        var newDrawFrame: CGRect
        if imageAspectRatio > viewAspectRatio {
            newDrawFrame = CGRect(x: drawFrame.minX + ((drawFrame.width - drawFrame.height * viewAspectRatio) / scale),
                                  y: drawFrame.minY,
                                  width: drawFrame.height * viewAspectRatio,
                                  height: drawFrame.height)
        } else {
            newDrawFrame = CGRect(x: drawFrame.minX,
                                  y: drawFrame.minY + ((drawFrame.height - drawFrame.width / viewAspectRatio) / scale),
                                  width: drawFrame.width,
                                  height: drawFrame.width / viewAspectRatio)
        }

        videoDisplayView.bindDrawable()
        if videoDisplayView.context != EAGLContext.current() {
            EAGLContext.setCurrent(videoDisplayView.context)
        }

        glClearColor(0.5, 0.5, 0.5, 1.0)
        glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
        glEnable(GLenum(GL_BLEND))
        glBlendFunc(GLenum(GL_ONE), GLenum(GL_ONE_MINUS_SRC_ALPHA))

        renderContext.draw(ciimage, in:videoDisplayViewBounds, from: newDrawFrame)
        videoDisplayView.display()
    }

    func close() {
        videoDisplayView.removeFromSuperview()
    }
}

As can be seen I set the content mode of the GLKView as aspect-fill, and the GLKView's frame is set to match the super view, but still it doesn't match up when rendering. I also tried different combinations of the CGRect arguments to the ciimage draw method, and although I obviously get some different results they all end up in the same place and never fills up the super view.

Any ideas?

0

There are 0 best solutions below