2013-08-08 5 views
4

gl 컨텍스트로 CAEAGLLayer 서브 클래스를 설정하려고합니다. 즉, CAEAGLLayer를 반환하고 UIView 하위 클래스 내에서이 컨텍스트를 바인딩하는 UIView 하위 클래스를 만드는 대신 레이어의 서브 클래 싱을 직접 수행하고 레이어의 init에서 컨텍스트를 설정하려고합니다.OpenGL 컨텍스트로 CAEAGLLayer 서브 클래스를 설정하는 방법 : 현재 그리기 프레임 버퍼가 유효하지 않습니다.

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     self.opaque = YES; 

     _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 
     NSAssert([EAGLContext setCurrentContext:_glContext], @""); 

     glGenRenderbuffers(1, &_colorRenderBuffer); 
     glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer); 
     [_glContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:self]; 

     glGenFramebuffers(1, &_framebuffer); 
     glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer); 

     /// . . . 

모든 항목이 정상적으로 보입니다. 그러나 "pass-thru"버텍스/조각 셰이더 쌍과 이있는 쉐이더 프로그램을 만들려고 시도하는 동안 오류를 반환하지 않으면 "현재 그리기 프레임 버퍼가 유효하지 않습니다."라는 오류 메시지가 나타납니다. 전체에 어떤 시점에서 몇 가지 추가 설정이있을 수 있습니다 만약 내가 궁금하네요

- (BOOL)linkAndValidateProgram 
{ 
    GLint status; 
    glLinkProgram(_shaderProgram); 

#ifdef DEBUG 
    GLint infoLogLength; 
    GLchar *infoLog = NULL; 
    glGetProgramiv(_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength); 
    if (infoLogLength > 0) { 
     infoLog = (GLchar *)malloc(infoLogLength); 
     glGetProgramInfoLog(_shaderProgram, infoLogLength, &infoLogLength, infoLog); 
     NSLog(@"Program link log:\n%s", infoLog); 
     free(infoLog); 
    } 
#endif 

    glGetProgramiv(_shaderProgram, GL_LINK_STATUS, &status); 
    if (!status) { 
     return NO; 
    } 

    glValidateProgram(_shaderProgram); 

#ifdef DEBUG 
    glGetProgramiv(_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength); 
    if (infoLogLength > 0) { 
     infoLog = (GLchar *)malloc(infoLogLength); 
     glGetProgramInfoLog(_shaderProgram, infoLogLength, &infoLogLength, infoLog); 
     NSLog(@"Program validation log:\n%s", infoLog); 
     free(infoLog); 
    } 
#endif 

    glGetProgramiv(_shaderProgram, GL_VALIDATE_STATUS, &status); 
    if (!status) { 
     return NO; 
    } 

    glUseProgram(_shaderProgram); 
    return YES; 
} 

을 :

(쉐이더를 부착 후) 쉐이더 프로그램의 유효성을 확인 링크와 코드는 경우에, 그래서처럼 보인다 내가 깨닫지 못할 수도 있고 init에서 GL을 설정하려고 시도하는 것으로 건너 뛸 수도있는 CAEAGLLayer의 라이프 사이클?

답변

1

문제는 레이어가 init의 해당 지점에 치수가 없다는 것입니다. 레이어에 렌더링 버퍼 저장소를 설정하려고 할 때 차례대로 버퍼가 0으로 설정됩니다.

업데이트 : 현재 가장 좋은 생각은 init에 크기를 지정하는 대신 테스트의 목적은 친절하지만 해키라고 생각합니다.) 레이어 크기가 변경 될 때마다 버퍼 저장소를 다시 설정해야합니다. 그래서 저는 을 다음과 같이 재정의했습니다.

- (void)setBounds:(CGRect)bounds 
{ 
    [super setBounds:bounds]; 
    [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:self]; 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &someVariableToHoldWidthIfYouNeedIt); 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &someVariableToHoldHeightIfYouNeedIt); 
} 
+0

감사합니다. 정확하게 똑같은 문제로 고심하고 있습니다. – daivuk

+0

사실, 만약 당신이 올바른 방법으로하고 싶다면 (또는 적어도 이것이 현재 최선의 생각입니다.) override -setBounds : 레이어가 크기가 바뀔 때마다 버퍼 저장소로 다시 할당하므로 프레임 버퍼가 레이어 크기와 계속 동기화하십시오. – SaldaVonSchwartz

0

는 지금까지 내가이

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

처럼보기에 layerClass 방법을 덮어 쓸 필요가 알고 또한 당신은 MYCEAGLLayer에 drawableProperties을 설정해야합니다.