2014-01-07 9 views
11

CoreImageフィルタをフルスクリーンレンダリング出力に適用しようとしていますが、出力として黒い画面が表示されているため何かが見当たりません。OpenGLのレンダリングからテクスチャへのCIFilterの適用

まず、シーン全体をテクスチャに描画します。その後、私はそのテクスチャからCoreImageを作成します。これは最終的に描画して表示します。しかし、私が得るのは黒い画面です。私は、テクスチャに描き、OpenGLESでCoreImageの統合にアップルのガイドラインを以下ました:

レンダラ:

@interface Renderer() { 
    EAGLContext* _context; 
    GLuint _defaultFramebuffer, _drawFramebuffer, _depthRenderbuffer, _colorRenderbuffer, _drawTexture; 
    GLint _backingWidth, _backingHeight; 
    CIImage *_coreImage; 
    CIFilter *_coreFilter; 
    CIContext *_coreContext; 
} 

初期化方法:

- (BOOL)initOpenGL 
{ 
    _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 
    if (!_context) return NO; 

    [EAGLContext setCurrentContext:_context]; 

    glGenFramebuffers(1, &_defaultFramebuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, _defaultFramebuffer); 

    glGenRenderbuffers(1, &_colorRenderbuffer); 
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderbuffer); 

    glGenFramebuffers(1, &_drawFramebuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, _drawFramebuffer); 

    glGenTextures(1, &_drawTexture); 
    glBindTexture(GL_TEXTURE_2D, _drawTexture); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _drawTexture, 0); 

    glGenRenderbuffers(1, &_depthRenderbuffer); 
    glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer); 

    _coreFilter = [CIFilter filterWithName:@"CIColorInvert"]; 
    [_coreFilter setDefaults]; 

    NSDictionary *opts = @{ kCIContextWorkingColorSpace : [NSNull null] }; 
    _coreContext = [CIContext contextWithEAGLContext:_context options:opts]; 

    return YES; 
} 
WWDC2012 511と https://developer.apple.com/library/ios/documentation/3ddrawing/conceptual/opengles_programmingguide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html

ここでは、関連するコードです

レイヤーサイズが変更されるたびにメモリを割り当てます(初期化時および方向変更時):

- (void)resizeFromLayer:(CAEAGLLayer *)layer 
{ 
    layer.contentsScale = 1; 

    glBindFramebuffer(GL_FRAMEBUFFER, _defaultFramebuffer); 

    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer); 
    [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; 

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_backingWidth); 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_backingHeight); 

    // glCheckFramebufferStatus ... SUCCESS 

    glBindFramebuffer(GL_FRAMEBUFFER, _drawFramebuffer); 

    glBindTexture(GL_TEXTURE_2D, _drawTexture); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backingWidth, _backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 

    glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _backingWidth, _backingHeight); 

    // glCheckFramebufferStatus ... SUCCESS 
} 

Drawメソッド:

- (void)render:(Scene *)scene 
{ 
    [EAGLContext setCurrentContext:_context]; 

    glBindFramebuffer(GL_FRAMEBUFFER, _drawFramebuffer); 

    // Draw using GLKit, custom shaders, drawArrays, drawElements 
    // Now rendered scene is in _drawTexture 

    glBindFramebuffer(GL_FRAMEBUFFER, _defaultFramebuffer); 
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer); 

    // Create CIImage with our render-to-texture texture 
    _coreImage = [CIImage imageWithTexture:_drawTexture size:CGSizeMake(_backingWidth, _backingHeight) flipped:NO colorSpace:nil]; 

    // Ignore filtering for now; Draw CIImage to current render buffer 
    [_coreContext drawImage:_coreImage inRect:CGRectMake(0, 0, _backingWidth, _backingHeight) fromRect:CGRectMake(0, 0, _backingWidth, _backingHeight)]; 

    // Present 
    [_context presentRenderbuffer:GL_RENDERBUFFER]; 
} 

注意、シーンを描画した後、_drawTextureは、レンダリングされたシーンが含まれています。 Xcodeデバッグツール(Capture OpenGL ESフレーム)を使ってチェックします。

EDIT:他のテクスチャから_drawTextureのCIImageを作成しようとすると、正しく表示されます。私の疑問は、CIContextがCIImageを通してレンダリングしようとすると、_drawTextureが準備ができていないか、何らかの形でロックされている可能性があるということです。

EDIT2:

glViewport(0, 0, _backingWidth, _backingHeight); 
    glClearColor(0, 0.8, 0, 1); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

結果はまだ黒です:私もちょうどビューポートクリアしてすべての描画コードを交換してみました。これは、描画テクスチャやフレームバッファで問題が発生する可能性があることを示唆しています。

+0

これはなぜ地球上でダウンしているのでしょうか? –

+1

それは面白いです。通常は、これはCore Imageコンテキストがレンダリングと同じOpenGL ESコンテキストで作成されていないためですが、ここで正しく設定されているように見えます。パススルーシェーダを使用し、レンダリングされたテクスチャを使用してクワッドをスクリーンに描画する場合、シーンがテクスチャに正しくレンダリングされていることを確認できますか?最後に、Core Imageと結婚していない場合は、https://github.com/BradLarson/GPUImageというプロジェクトもあります。このプロジェクトは、このスタイルのGPUサイドの後処理を行うこともできます。そこにあるCubeExampleサンプルアプリケーションを参照してください。 –

+0

私は_drawTextureを使ってクワッドをレンダリングしました。それは黒です。そのテクスチャやレンダリングで何かが間違っているように見えます。たぶん私は、レンダリングからテクスチャまで何かが欠けているかもしれません。 Diffは私がレンダリングバッファの代わりにGL_COLOR_ATTACHEMNT0としてテクスチャを付けているということだけです。 –

答えて

5

私はついに間違ったことを発見しました。 iOSの2つのテクスチャの非パワーは線形フィルタリングを持っており、エッジの折り返しにクランプする必要があります。

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); 

私のテクスチャは、画面と同じサイズを持っていたが、私はこれら4つのparamsを設定しませんでした。

次世代の場合:上記のコードは、OpenGL ESとCoreImageの相互接続の完全な有効な例です。ちょうどあなたのテクスチャを正しく初期化することを確認してください!