2009-11-12 78 views
1

我正在用於iPhone的openGL,雖然一切都很好,但我必須在遊戲的某些部分使用大量的精靈表等待一秒鐘。有沒有辦法爲這些部分創建一個加載屏幕?或者通過任何方式來知道某個紋理是否完成了openGL加載?在iphone上加載一個openGL遊戲的屏幕?

編輯:

我打開我的紋理具有這種功能:

-(void)loadTexture:(NSString*)nombre { 

CGImageRef textureImage = [UIImage imageNamed:nombre].CGImage; 
if (textureImage == nil) { 
    NSLog(@"Failed to load texture image"); 
    return; 
} 

textureWidth = NextPowerOfTwo(CGImageGetWidth(textureImage)); 
textureHeight = NextPowerOfTwo(CGImageGetHeight(textureImage)); 

imageSizeX= CGImageGetWidth(textureImage); 
imageSizeY= CGImageGetHeight(textureImage); 

GLubyte *textureData = (GLubyte *)calloc(1,textureWidth * textureHeight * 4); // Por 4 pues cada pixel necesita 4 bytes, RGBA 

CGContextRef textureContext = CGBitmapContextCreate(textureData, textureWidth,textureHeight,8, textureWidth * 4,CGImageGetColorSpace(textureImage),kCGImageAlphaPremultipliedLast); 
CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)textureWidth, (float)textureHeight), textureImage); 

CGContextRelease(textureContext); 

glGenTextures(1, &textures[0]); 

glBindTexture(GL_TEXTURE_2D, textures[0]); 

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData); 

free(textureData); 


glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

} 

我通常加載我需要deppending對遊戲的部分的紋理,例如,一個或兩個1024x1024的貼圖,其用於因爲精靈表對於大多數關卡都是足夠的,但是在某些關卡中,例如boss戰,我會加載大約5或6個紋理(老闆很大,有很多不同的攻擊),而且遊戲需要大約2或3秒一次加載所有這些紋理。

+0

由於_you_裝入紋理(通過OpenGL的), 當你的代碼完成後,你應該知道。 如何加載紋理?代碼示例將非常有用。 – Andreas 2009-11-12 18:29:28

+0

這個問題聽起來很多,就像你沒有自己實現GL-stuff一樣。 – Till 2009-11-12 18:49:23

+0

@Andreas:我爲這個問題添加了一些代碼,希望現在更清楚。謝謝。 @Till:?。 – 2009-11-12 20:30:48

回答

2

As Till解釋說,由於您正在同步加載紋理,所以一旦「loadTexture」完成,它就會被加載。

通過OpenGL在另一個線程中渲染到另一個線程,而通過OpenGL加載時會變得非常麻煩。

A - 經常使用 - 黑客是更新紋理加載的屏幕:

  1. 呈現0%的屏幕
  2. loadTexture
  3. 呈現10%的屏幕
  4. loadTexture
  5. 重複的需要

隨着一點額外的工作很容易生成一個具有關於加載時間信息的小表,因此「x%」非常接近實際;)

我們通常自動執行此步驟,並在發佈新版本之前執行「加載」操作,其中我們記錄何時加載了哪些資源以及需要多長時間。

1

由於您正在同步加載紋理,因此,只要loadTexture方法完成,就可以立即加載該紋理。

編輯/添加: 有幾件事情你應該避免/改變你的代碼。不是說這樣可以真正解決你的實際問題,只是一般性的建議......

1st:不要使用imageNamed加載紋理圖像 - 這通常是一個壞主意。使用imageWithContentsOfFile,因爲這樣不會使圖像緩存中的數據無法重複使用。

第二次:一旦加載了紋理,就會有一個術語叫做「加熱紋理」 - 它基本上是簡單地使用該紋理進行快速和骯髒的(甚至是離屏)渲染。這樣,您可以確定紋理將完全可用,並且在進行第一次「真實」渲染時不會受到額外的懲罰。我們正在談論幾毫秒的懲罰 - 所以沒有太大的影響,但顯而易見。

第3:嘗試將紋理加載轉移到應用程序空閒的點 - 例如。等待啓動屏幕中的用戶輸入 - 但不要在applicationDidFinishLaunching方法中執行此操作。

這裏給你一個問題 - 你爲什麼要在渲染/關卡內加載紋理。爲什麼不預先加載你可能需要的一切?您可以使用高達24mb的紋理內存而不會施加任何處罰(以及減去fbo內存)。

+0

謝謝。任何關於如何減少加載的想法,也許只是在屏幕上繪製一個小的加載動畫並在我的方法加載完紋理後立即移除它,或者其他建議? – 2009-11-12 21:22:29

+0

@Til:「你爲什麼要在渲染時加載紋理/爲什麼不預加載你可能需要的所有東西?你可以使用高達24mb的紋理內存而不用施加任何懲罰(好吧,減去fbo內存)。」我原本是在一開始就預加載所有的紋理......但是當我一次嘗試加載太多紋理時(總共有大約10 MB的png紋理!),應用程序將我踢出去了。我想立刻預先加載所有紋理,但我不知道如何... – 2009-11-24 05:31:32

0

或者,您可以在加載紋理時簡單地顯示UIImageView動畫。這有一個獨特的威脅畫的特殊好處...這是一個特殊情況,就像UIActivityIndi​​catorView(微調)。我不確定蘋果如何在技術上實現這一目標,但效果很好。

唯一的問題是您需要將加載動畫幀保存在單獨的文件中,而不是放在精靈表中。

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIImageView_Class/Reference/Reference.html