2013-05-04 1 views
1

Я хотел бы сделать видео в текстуре OpenGL ES, чтобы я мог применить эту текстуру к 3D-поверхности в моей программе iOS. Для этого я использую GPUImage, но он не работает, текстура, кажется, не загружается в выход.GPUImage render to OpenGL ES текстура не работает

Вот код .h:

#import <UIKit/UIKit.h> 
#import <GLKit/GLKit.h> 

#import "GPUImage.h" 

@interface ViewController : GLKViewController <GPUImageTextureOutputDelegate> 
{ 
    GLuint texture; 
    GPUImageMovie* movie; 
    GPUImageTextureOutput *output; 


    GPUImagePixellateFilter* pixellateFilter; 
} 

@end 

А вот части the.m файла:

Init

- (void)setupGL 
{ 
    [EAGLContext setCurrentContext:self.context]; 

    [self loadShaders]; 

    _vertexArrayBuff = generateSphere(0, 0, 0, 10, 20, 10, &_arraySize); 

    glEnable(GL_DEPTH_TEST); 

    glGenVertexArraysOES(1, &_vertexArray); 
    glBindVertexArrayOES(_vertexArray); 

    glGenBuffers(1, &_vertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, _arraySize * sizeof(GLfloat), _vertexArrayBuff, GL_STATIC_DRAW); 

    glEnableVertexAttribArray(GLKVertexAttribPosition); 
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(0)); 
    glEnableVertexAttribArray(GLKVertexAttribNormal); 
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(12)); 
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0); 
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(24)); 

    glBindVertexArrayOES(0); 

    NSString* fileStr = [[NSBundle mainBundle] pathForResource:@"video" ofType:@"mp4"]; 
    NSURL* fileUrl = [NSURL fileURLWithPath:fileStr]; 
    movie = [[GPUImageMovie alloc] initWithURL:fileUrl]; 

    output = [[GPUImageTextureOutput alloc] init]; 
    output.delegate = self; 

    pixellateFilter = [[GPUImagePixellateFilter alloc] init]; 

    [movie addTarget:pixellateFilter]; 
    [pixellateFilter addTarget:output]; 

    [movie startProcessing]; 
} 

Рендер

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect 
{ 
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glBindVertexArrayOES(_vertexArray); 

    // Render the object again with ES2 
    glUseProgram(_program); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); 
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); 
    glUniform1i(uniforms[UNIFORM_TEXTUTRE], 0); 

    glDrawArrays(GL_TRIANGLES, 0, _arraySize/8); 
} 

Делегат

- (void)newFrameReadyFromTextureOutput:(GPUImageTextureOutput *)callbackTextureOutput; 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     texture = callbackTextureOutput.texture; 
    }); 
} 

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

Но когда я пытаюсь установить текстуру с GPUImage, она больше не работает, моя текстура не отображается, вместо этого у меня есть черная поверхность.

Кто-нибудь знает, что я сделал не так? Я следил за CubeExample от GPUImage, но он не работает.

Мне действительно нужна помощь сейчас

Спасибо!

PS: Я нацеливание IOS 6.1, и я использую XCode 4.6.2

EDIT

Вот код функции, вызываемой в начале:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:[[[GPUImageContext sharedImageProcessingContext] context] sharegroup]]; 

    if (!self.context) { 
     NSLog(@"Failed to create ES context"); 
    } 

    GLKView *view = (GLKView *)self.view; 
    view.context = self.context; 
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24; 

    [self setupGL]; 
} 

ответ

0

Я думаю, что вам не хватает одной важной части кода примера CubeExample. Для получения текстур, созданных в контексте OpenGL ES GPUImage, необходимо использовать группу разделов для отображения в контексте OpenGL ES вашего представления.

В CubeExample, я не использую GLKit, поэтому я создаю контекст для моего CAEAGLLayer-хостинг вид, используя следующий код:

context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:[[[GPUImageContext sharedImageProcessingContext] context] sharegroup]]; 

Это захватывает группу акций, используемый при обработке изображений GPUImage в OpenGL ES контекст и использует это как группу разделов для контекста рендеринга для моего представления.

Я не очень много работал с GLKit (я предпочел более низкий уровень OpenGL ES, в основном по привычке), но я считаю, что в какой-то момент вы настроили контекст OpenGL ES для своего GLKView. Вы можете вставить общую группу общего доступа GPUImage в этот момент или до установки или работы GPUImage, вы можете использовать метод -useSharegroup: для sharedImageProcessingContext GPUImageContext, чтобы пойти другим путем и настроить GPUImage на использование общей группы контекста вашего представления.

+0

Благодарим вас за ответ. На самом деле я использовал группу share (я редактировал свой пост), я просто забыл показать вам код, делающий это.Таким образом, он все еще не работает :( –

+0

@FabienHenon - Это с источником видео в реальном времени или видео? Если файл фильма, это на устройстве или в симуляторе? Известная ошибка с воспроизведением фильмов в симуляторе прямо сейчас. –

+0

Это фильм с симулятора. Он работает, когда я использую AVFundation напрямую, но не тогда, когда я использую GPUImage –