Briahas
3/21/2018 - 1:52 PM

display CIImage via GLKView

display CIImage via GLKView

//
//  FWKCIImageView.m
//  LineEngraver
//
//  Created by Viktor Goltvyanytsya on 8/8/16.
//
//








#import "FWKCIImageView.h"
#import <GLKit/GLKView.h>
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>

@interface FWKCIImageView ()<GLKViewDelegate>
{
    CIImage         *_ciImage;
    EAGLContext     *_eaglContext;
    CIContext       *_ciContext;
    GLKView         *_glView;
}

@end

@implementation FWKCIImageView

-(void)dealloc;
{
    _ciImage = nil;
    _eaglContext = nil;
    _ciContext = nil;
    
    if( _glView )
    {
        [_glView removeFromSuperview];
    }
    _glView = nil;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        
        [self setBackgroundColor:[UIColor clearColor]];
        
        [self setAutoresizesSubviews:NO];
        [self setTranslatesAutoresizingMaskIntoConstraints:NO];
        
        _eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
        _eaglContext.multiThreaded = YES;
        
        _ciContext = [CIContext
                          contextWithEAGLContext:_eaglContext
                          options: @{kCIContextUseSoftwareRenderer: @NO} ];
        
        _glView = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height) context:_eaglContext];
        _glView.enableSetNeedsDisplay = NO;
        _glView.delegate = self;
        _glView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
        [self addSubview:_glView];

        
        [EAGLContext setCurrentContext:_eaglContext];
    }
    return self;
}

- (CIImage *)ciImage
{
    return _ciImage;
}

- (void)setCiImage:(CIImage *)image
{
    _ciImage = image;
    
    [self _drawCIImage:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}

- (void)setFrame:(CGRect)frame
{
    BOOL changed = !CGSizeEqualToSize(self.frame.size, frame.size);
    
    [super setFrame:frame];
    
    if (changed && _ciImage)
    {
        [self _drawCIImage:frame];
    }
}

#pragma mark -GLKViewDelegate methods

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    
}

#pragma mark -Private methods

- (void)_drawCIImage:(CGRect)frame
{
    [_glView bindDrawable];
    
    if (_eaglContext != [EAGLContext currentContext])
    {
        [EAGLContext setCurrentContext:_eaglContext];
    }
    
    // clear eagl view to grey
    glClearColor(0.5, 0.5, 0.5, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    
    // set the blend mode to "source over" so that CI will use that
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    
    if (_ciImage)
    {
        [_glView setFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
        
        CGSize imageSize = _ciImage.extent.size;
        CGFloat drawableWidth = _glView.drawableWidth;
        CGFloat drawableHeight = _glView.drawableHeight;
        
        CGRect drawFrame = CGRectMake(0, 0, drawableWidth, drawableHeight);
        
        CGFloat imageAR = imageSize.width / imageSize.height;
        CGFloat viewAR = drawFrame.size.width / drawFrame.size.height;
        if (imageAR > viewAR)
        {
            drawFrame.origin.y += (drawFrame.size.height - drawFrame.size.width / imageAR) / 2.0;
            drawFrame.size.height = drawFrame.size.width / imageAR;
        }
        else
        {
            drawFrame.origin.x += (drawFrame.size.width - drawFrame.size.height * imageAR) / 2.0;
            drawFrame.size.width = drawFrame.size.height * imageAR;
        }
        
        [_ciContext drawImage:_ciImage inRect:drawFrame fromRect:[_ciImage extent]];
    }
    
    [_glView display];
}

@end
//
//  FWKCIImageView.h
//  LineEngraver
//
//  Created by Viktor Goltvyanytsya on 8/8/16.
//
//









#import <UIKit/UIKit.h>

@interface FWKCIImageView : UIView

- (CIImage *)ciImage;
- (void)setCiImage:(CIImage *)image;

@end