OpenGL + Camera View (iPhone) - PullRequest
       2

OpenGL + Camera View (iPhone)

3 голосов
/ 08 апреля 2011

Я 2 дня пытался показать вид OpenGLES на камеру. Просмотр на iPhone.

Предварительный просмотр камеры один, работает. Один EAGLView (OpenGLES) работает.

Проблема в том, когда я пытаюсь поместить EAGLView поверх предварительного просмотра камеры.

Я могу разместить оба UIViews одновременно, но предварительный просмотр камеры всегда выполняется над EAGLView (неправильно!). Когда я установил альфа на 0.5 для предварительного просмотра камеры, я могу видеть оба UIViews так, как я хочу, но оба размыты (это нормально).

Я попытался [self.view yieldSubviewToFront: (EAGLView)], но ничего не изменилось.

EAGLView находится на IB как класс. CameraView добавляется как подпредставление по коду.

Здесь я поместил некоторый код, я могу загрузить больше, если вам это нужно.

Спасибо !!!

EAGLView

+ (Class)layerClass {
    return [CAEAGLLayer class];
}


//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder {


    puntosPintar=(GLfloat*)malloc(sizeof(GLfloat)*8);
    puntosPintar[0] = -0.25f;
    puntosPintar[1] = -1.22f;
    puntosPintar[2] = -0.41f;
    puntosPintar[3] = 0.0f;
    puntosPintar[4] = 0.35f;
    puntosPintar[5] = -1.69f;
    puntosPintar[6] = 0.15f;
    puntosPintar[7] = 0.0f;

    if ((self = [super initWithCoder:coder])) {
        // Get the layer
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

        eaglLayer.opaque = NO;
        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

        context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];

        if (!context || ![EAGLContext setCurrentContext:context]) {
            [self release];
            return nil;
        }


    }
    return self;
}




- (void)drawView {
    const GLubyte squareColors[] = {
        255, 255,   0, 255,
        0,   255, 255, 255,
        0,     0,   0,   0,
        255,   0, 255, 255,
    };

    [EAGLContext setCurrentContext:context];

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);


    glMatrixMode(GL_MODELVIEW);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glClear(GL_COLOR_BUFFER_BIT);

    glVertexPointer(2, GL_FLOAT, 0, puntosPintar);
    glEnableClientState(GL_VERTEX_ARRAY);

    glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);

    glEnableClientState(GL_COLOR_ARRAY);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];

}


- (void)layoutSubviews {
    [EAGLContext setCurrentContext:context];

    [self destroyFramebuffer];
    [self createFramebuffer];

    [self drawView];


}


- (BOOL)createFramebuffer {



    glGenFramebuffersOES(1, &viewFramebuffer);
    glGenRenderbuffersOES(1, &viewRenderbuffer);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);

    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
    if (USE_DEPTH_BUFFER) {
        glGenRenderbuffersOES(1, &depthRenderbuffer);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
        glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
    }



    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
        NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
        return NO;
    }


    return YES;
}

UIViewController, где я хочу показать оба Загрузка вида на камеру

    [CameraImageHelper startRunning];
    UIView *fafa;
    fafa= [[UIView alloc]initWithFrame:self.view.bounds]; //returns a UIView with the cameraview as a layer of that view. It works well (checked)
    fafa = [CameraImageHelper previewWithBounds:self.view.bounds];
    fafa.alpha=0.5;  //Only way to show both
    [self.view addSubview:fafa];
    [self.view bringSubviewToFront:fafa];

Загрузка EAGLView На .h я создал

IBOutlet EAGLView *openGLVista

На вид сделал загрузку:

openGLVista=[[EAGLView alloc]init];

enter image description here

CameraImageHelper.h

@interface CameraImageHelper : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>
{
    AVCaptureSession *session;
}
@property (retain) AVCaptureSession *session;

+ (void) startRunning;
+ (void) stopRunning;

+ (UIView *) previewWithBounds: (CGRect) bounds;
@end

CameraImageHelper.m

- (void) initialize
{
    NSError *error;
    AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] error:&error];
    if (!captureInput)
    {
        NSLog(@"Error: %@", error);
        return;
    }


    self.session = [[[AVCaptureSession alloc] init] autorelease];
    [self.session addInput:captureInput];
}

- (id) init
{
    if (self = [super init]) [self initialize];
    return self;
}

- (UIView *) previewWithBounds: (CGRect) bounds
{
    UIView *view = [[[UIView alloc] initWithFrame:bounds] autorelease];

    AVCaptureVideoPreviewLayer *preview = [AVCaptureVideoPreviewLayer layerWithSession: self.session];
    preview.frame = bounds;
    preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
    [view.layer addSublayer: preview];

    return view;
}

- (void) dealloc
{
    self.session = nil;
    [super dealloc];
}

#pragma mark Class Interface

+ (id) sharedInstance // private
{
    if(!sharedInstance) sharedInstance = [[self alloc] init];
    return sharedInstance;
}

+ (void) startRunning
{
    [[[self sharedInstance] session] startRunning]; 
}

+ (void) stopRunning
{
    [[[self sharedInstance] session] stopRunning];
}


+ (UIView *) previewWithBounds: (CGRect) bounds
{
    return [[self sharedInstance] previewWithBounds: (CGRect) bounds];
}

@end

1 Ответ

4 голосов
/ 08 апреля 2011

Я вижу, что в IB вы используете EAGLView в качестве view контроллера представления, а во фрагменте кода вы добавляете представление предварительного просмотра в качестве подпредставления этого представления. Другими словами, ваша иерархия представлений выглядит примерно так:

*- EAGLView
    +- Preview view

Таким образом, предварительный просмотр всегда находится над EAGLView, поскольку он является подвидом EAGLView. Если вы хотите иметь возможность отображать один из них поверх другого, вместо этого вам придется раскладывать вещи так:

*- some generic UIView
    +- EAGLView
    +- Preview view

Другими словами, в IB у вас должен быть общий UIView, связанный со свойством view, а затем перетащите EAGLView так, чтобы он находился внутри этого общего UIView. Тогда ваш код для добавления предварительного просмотра должен работать правильно.


Кстати, это не делает то, что вы, кажется, думаете:

fafa= [[UIView alloc]initWithFrame:self.view.bounds]; //returns a UIView with the cameraview as a layer of that view. It works well (checked)
fafa = [CameraImageHelper previewWithBounds:self.view.bounds];

Первая строка создает общий UIView. Затем второй выбрасывает его (утечка памяти!), Заменяя его на предварительный просмотр. Вы должны просто удалить первую строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...