簡體   English   中英

使用GLKit進行按需OpenGL ES渲染

[英]On-demand OpenGL ES rendering using GLKit

我正在研究轉換我的OpenGL渲染代碼以利用GLKit的一些功能(即異步紋理加載和GLKView/Controller提供的自動化)。 但是,似乎這些類的設計主要是為了適應使用動畫循環渲染的人,而我正在使用按需渲染。 另外,一些渲染是針對紋理而不是GLKView的幀緩沖,所以我是否應該只是將GLKView子類化並添加其他FBO?

這種類型的設置是否有推薦的方法? 我希望有類似的東西:

  • 將視圖控制器的preferredFramesPerSecond0 ,或者只是暫停幀更新?
  • 忽略glkViewControllerUpdateglkView:drawInRect:方法,只需在需要時繪制我需要的東西。
  • 使用視圖的setNeedsDisplay和普通的UIView一起顯示框架(我是否需要調用bindDrawable因為我也將渲染到紋理?)。

如果這不是新API的設計,那么也許不值得努力? 我希望文檔比它更徹底。 當API稍微“成熟”時,可能會提供更多樣本......

謝謝

我最終使用的方法是不打擾GLKViewController ,而只是直接在UIViewController子類下使用GLKView

顯然, GLKViewController旨在供那些需要為游戲等應用程序提供一致渲染循環的人使用。 沒有它,繪制到GLKView就像調用[glkView setNeedsDisplay]一樣簡單。 請務必將enableSetNeedsDisplay設置為YES以啟用此行為。

如果您仍想使用GLKViewController ,則可以在viewWillAppear禁用動畫渲染循環,如下所示:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];    // setPaused automatically set to NO in super's implementation

    [self setPaused:YES];
}

另外,將resumeOnDidBecomeActive設置為NO以防止視圖控制器自動重新開始。

然而,使用帶有GLKView的普通UIViewController是完全可以接受的,我已經看到Apple工程師推薦它作為執行按需繪圖的適當方式。

我剛剛使用EAGLContext管理器將我的代碼轉換為使用GLKit類。

你建議你可以“.. glkView:drawInRect: .. glkView:drawInRect:方法,只需要在我需要的時候畫出你需要的東西”。 這似乎是表現明智的明智選擇; 我假設(雖然沒有嘗試過)如果你只是沒有指定GLKViewDelegate或者提供帶有drawInRect:的子類GLKView drawInRect:定義那么就不會發生動畫循環渲染。 你試過這個嗎?

另一種方法是簡單地創建一些@property (assign, nonatomic) BOOL shouldUpdate; 在你的MyController : GLKViewController <GLKViewDelegate>類中,只有在有事情要做時才會更新:

[self setDelegate:self]; // in init or awakeFromNib or other..

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    if ([self shouldUpdate]) { ...

我相信你明白了,這並不復雜。

值得一提的是:官方API文檔聲明viewDidLoad應該在您的GLKViewController用於初始GL設置。 我有這個問題; 由於某種原因,我的glCreateShader調用總是返回零。 這可能是由於我設置EAGLContext后初始化; 我無法將其作為init參數傳遞,因為我在Storyboard中創建了控制器。 但是,代碼沒有任何邏輯上的錯誤,所以如果您遇到類似問題,我會提供此友好警告。 我的解決方案只是在我的drawInRect中有以下內容:

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    if ([self initialGLSetupDone] == NO) {
        [self beforeFirstRender];
        [self setInitialGLSetupDone:YES];
    }
    // .. rest of render code goes here.
}

顯然,不必要地在那里安裝IF並不理想,但這是一個簡單的解決方案。

如果您嘗試更新以使用GLKit,請告訴我它是怎么回事。

創建GLKView后,添加以下行:

glkView.enableSetNeedsDisplay = TRUE;

(因此,沒有人會自動重繪視圖)

如果要重繪,請插入以下行:

[glkView setNeedsDisplay];

...然后drawInRect例程將只調用一次。

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM