2014-01-07 2 views
11

Corelmage 필터를 내 전체 화면 렌더링 출력에 적용하려고하지만 출력물로 검정색 화면이 표시되어 누락 된 것처럼 보입니다.CIFilter를 OpenGL 렌더링에서 텍스처로 적용

먼저 전체 장면을 텍스처로 그립니다. 그런 다음 텍스쳐로 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 
} 

그리기 방법 :

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

결과는 여전히 검은 색이다 : 나는 또한 단지 뷰포트 청소 모든 그리기 코드를 교체했습니다. 그것은 문제가 draw texture 나 framebuffer와 관련이있을 수 있음을 암시합니다.

+0

왜 지구상에서 이것이 downvoted 것입니까? –

+1

재미 있습니다. 보통, Core Image 컨텍스트가 렌더링과 동일한 OpenGL ES 컨텍스트로 생성되지 않았기 때문에 이것이라고 말하고 싶지만, 여기서는 제대로 설정되어있는 것 같습니다. 패스 스루 쉐이더를 사용하고 렌더링 된 텍스처를 사용하여 화면에 쿼드를 그리는 경우 장면이 텍스처에 제대로 렌더링되는지 확인할 수 있습니까? 마지막으로 Core Image와 결혼하지 않았다면이 스타일의 GPU 사이드 포스트 프로세싱을 할 수있는 https://github.com/BradLarson/GPUImage 프로젝트가 있습니다. CubeExample 샘플 응용 프로그램을 참조하십시오. –

+0

좋아, 나는 _drawTexture를 사용하여 쿼드를 렌더링했고 그것은 검은 색입니다. 그 텍스쳐 나 렌더링에 문제가있는 것처럼 보입니다. 어쩌면 나는 render-to-texture로 뭔가를 놓치고있다. 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의 상호 연결에 대한 완벽한 예입니다. 텍스처를 올바르게 초기화해야합니다.

관련 문제