2012-01-28 73 views
1

在iOS上使用幀緩衝對象進行渲染,根據Apple提供的適用於iOS的OpenGL ES編程指南,這似乎是蘋果在iOS上渲染的首選方式,應該使用glRenderbufferStorage()來指定寬度和高度等屬性。來自Munshi,Ginsburg和Shreiner的OpenGL ES 2.0編程指南。 Apple將renderbufferStorage替換爲:fromDrawable:將消息發送到上述指南中的EAGLContext。爲OpenGL ES設置CAEAGLLayer屬性?

然後,Apple會繼續寫入以從Renderbuffer中獲取寬度和高度,因爲該緩衝區會在創建時設置它們而不做進一步的細節。

雖然寬度和高度都是0。

CAEAGLLayer類引用寫入「設置圖層邊界以匹配顯示的尺寸」。 CAEAGLLayer類是Apple希望用作類視圖的支持類的類。這是通過從views layerClass方法返回它來完成的。這CAEAGLLayer只有1個屬性「drawableProperties」,這是一個NSDictionary。不幸的是,文檔是稀疏的。尺寸不能設置。

因此:如何繼續設置OpenGL ES的CAEAGLLayer屬性?

這裏是我的代碼迄今(注意蘋果的老例子使用的initWithCoder,我要麼猜測或從什麼地方得到了我不記得使用initWithFrame):

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
     // Initialization code 
     theCAEAGLLayer = (CAEAGLLayer*)self.layer; 
     theCAEAGLLayer.opaque = YES; 
     theEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 
     [EAGLContext setCurrentContext:theEAGLContext]; 
     glGenFramebuffers(1, &theFramebuffer); 
     glBindFramebuffer(GL_FRAMEBUFFER, theFramebuffer); 
     glGenRenderbuffers(1, &theColorRenderbuffer); 
     glBindRenderbuffer(GL_RENDERBUFFER, theColorRenderbuffer); 
     [theEAGLContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:theCAEAGLLayer]; 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, theColorRenderbuffer); 
     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &widthOfTheColorRenderbuffer); 
     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &heightOfTheColorRenderbuffer); 
     glGenRenderbuffers(1, &theDepthRenderbuffer); 
     glBindRenderbuffer(GL_RENDERBUFFER, theDepthRenderbuffer); 
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, widthOfTheColorRenderbuffer, heightOfTheColorRenderbuffer); 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, theDepthRenderbuffer); 
     if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
     { 

     } 
    } 
    return self; 
} 

回答

1

正確答案:

UIKit將某些操作分批在一起,並將它們推遲到runloop之後。這是因爲您可能擁有更改視圖大小並更改其中的不同位置文本的代碼。你可能想讓這些東西自動發生。

這可能對您意味着什麼,該圖層尚未確定尺寸。你有沒有嘗試過將你所擁有的東西移動到- (void)layoutSubviews

如果您打算僅針對iOS 5,則可以使用GLKView,並避免爲自己編寫任何這些東西。

其他評論:

glRenderbufferStorage將創建在一個不透明的位置的記錄使OpenGL可以借鑑,但操作系統應該怎麼猜,你的幀緩衝的是要顯示給用戶的一個,而不是僅僅是一箇中間結果? OpenGL規範明確沒有定義你如何與特定操作系統進行通信。在iOS中,它是通過renderbufferStorage:fromDrawable:實現的 - 這表示要添加與iOS知道如何合成的CALayer相當的存儲空間。 Apple的方法不是glRenderbufferStorage的替代方法,它可以做到glRenderbufferStorage不能也不應該做的事情,甚至在僅針對iOS進行編程時,您也可以多次使用它。

- (id)initWithFrame:是您在手動創建視圖時使用的初始化程序。系統使用- (id)initWithCoder:加載來自NIB的視圖。

您的UIView是否明確指定了layerClass作爲CAEAGLLayer?如果沒有,那麼對EAGL上下文的調用將被允許失敗。

+0

謝謝您的意見!我只是嘗試移動到layoutSubviews,這並沒有解決它。 layerClass確實正在返回[CAEAGLLayer類]。該視圖的大小設置爲「在Xcode中適合縮放」。如何調整圖層的大小?我會看看我能用GLKView和GLKViewController做什麼。 – Lars 2012-01-30 12:37:08

+0

圖層應該自動調整到視圖的大小,所以你看到的是很好奇。當我有機會時,我會挖掘一些有效的GL代碼,看看我能否找到更有用的東西;對不起,我還沒有能夠提供'在這裏,這絕對是問題'的答案類型。 – Tommy 2012-01-30 12:42:45