2011-01-27 36 views
1

這是我第一次瞭解opengl。我爲iphone繪製了一個簡單的opengles示例。起初我忘記使用glBindTexture,但它的工作。後來我嘗試添加另一個四邊形,並且看到當我使用glBindTexture時,沒有任何四邊形被紋理化,它們是白色的。然後我刪除了新添加的四元組,當glBindTexture在那裏時它仍然不起作用。如果我評論說一切都很好。當然,我將需要超過一個四...與紋理。如何在iphone的opengles中使用glBindTexture?

編輯:這種方法是在我的視圖控制器,有一個從Apple OpenglES示例中被盜的EAGLView。它初始化opengl。我爲每個quad有一個Place類的實例。起初爲了測試我只使用了一個四核;我只有一個Place的對象,正如我所說我忘了使用glBindTexture。但在此之後,當我開始使用它時,紋理不再有效,即使只有一個四邊形。

EDIT2:這裏是我想要的東西的例子:http://www.youtube.com/watch?v=U2uH-jrsSxs


-(void) setupOpenGL 
{ 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    // Enable use of the texture 
    glEnable(GL_TEXTURE_2D); 
    // Enable blending 
    glEnable(GL_BLEND); 
    // Set a blending function to use 
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

    //!!!!!!!!!!!! 
    //EDIT: THIS IS WHERE I WAS WRONG: I NEED TO SET THESE FOR EVERY TEXTURE I USE 
    //THEY ARE NOT GLOBAL 
    //!!!!!!!!!!!! 
    // Set the texture parameters to use a minifying filter and a linear filer (weighted average) 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    //same for magnification 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    //----------------- 

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 

    for (Place *p in locations) 
    { 
    [p loadTexture]; 
    [p reloadTitle]; 
    /* 
    p.relativeHeading = 123.45; 
    p.absoluteHeading = 23.45; 
    p.distance = 1234.5; 
    [p reloadHeading]; 
    [p reloadDistance]; 
    */ 
    } 

    glError = glGetError(); //check if we f*cked up already or not; 
    NSLog(@"setupOpenGL result: %i", glError); 
} 

這裏是代碼我Place類:


- (void) loadTexture 
{ 
    Byte * textureData = [Place getTexture]; 
    glGenTextures(1, &textureID); 

    glBindTexture(GL_TEXTURE_2D, self.textureID); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 
    TEXTURE_W, TEXTURE_H, 0, 
    GL_RGBA, GL_UNSIGNED_BYTE, textureData); 
    //copy the texture to video memory we can safely release our own copy of the texture after this 
    GLenum glError = 0; 
    glError = glGetError(); 
} 

- (void) reloadTitle 
{ 
    CGSize actualSize = CGSizeZero; //not used now 

    CGRect cropRect = CGRectMake(TITLE_X, TITLE_Y, TITLE_W, TITLE_H); 
    Byte *imageData = [self writeTextOverTexture: 
    [Place getTextureCrop : cropRect] : cropRect.size : 
    CGRectMake(0, 0, TITLE_W, TITLE_H) : 
    self.title : [UIFont fontWithName: @"Arial" size: 14] : 
    [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1] : 
    &actualSize]; 

    glBindTexture(GL_TEXTURE_2D, self.textureID); 
    glTexSubImage2D(GL_TEXTURE_2D, 0, 
    TITLE_X, TITLE_Y, TITLE_W , TITLE_H, GL_RGBA, GL_UNSIGNED_BYTE, imageData); 
} 

- (void) reloadDistance 
{ 
//...very similar to reloadTitle 
} 

- (void) reloadHeading 
{ 
    // very similar to the other too 
} 

這裏是繪製四邊形的方法。基本上在每個「地點」我都有經度/緯度,當我繪製時,我使用iPhone羅盤標題,位置和加速計將其他地方繪製在正確的位置。


- (void) drawFrame 
{ 
    if (location == nil) return; 
    if (myHeading == -1) return; 

    [(EAGLView *)self.glView setFramebuffer]; 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    perspective(LANDSCAPE_FOV, WIDTH/HEIGHT , 1.0f, 20.0f); 
    glRotatef((GLfloat)rollAngle, 0, 0, 1); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    double tmpPitchAngle = pitchAngle; 
    tmpPitchAngle -= 20; 
    tmpPitchAngle = clampValue(tmpPitchAngle, -85, +85); 

    //glRotatef((GLfloat) tmpPitchAngle, 1, 0, 0); 
    glRotatef((GLfloat) myHeading, 0, 1, 0); 

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 

    for (Place *p in locations) 
    { 
    glPushMatrix(); 
     glRotatef(-p.absoluteHeading, 0, 1, 0); 
     glTranslatef(0, 0, -5); 
     glScalef(0.4, 0.4, 1.0); 
     glBindTexture(GL_TEXTURE_2D, p.textureID); 
     glVertexPointer (3, GL_BYTE, 0, KVertices); 
     glTexCoordPointer(2, GL_BYTE, 0, texCoords); 
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
    glPopMatrix(); 
    } 

    glError = glGetError(); 
    NSLog(@"glError drawFrame = %i", glError); 

    [(EAGLView *)self.glView presentFramebuffer]; 
} 

我該如何做這項工作?當我忘記綁定紋理時,我使用了什麼紋理。據我所知glBindTexture是用來選擇,或激活一個紋理,所以我可以繪製或改變它。

回答

2

你錯過了一些東西,把這個glTexImage2D後:

glTexParameteri(GL_TEXTURE_2D, GL_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_MAG_FILTER, GL_NEAREST); 

那麼你的紋理會出現,不看白。這是因爲默認情況下,OpenGL使用mipmapped濾鏡。由於您沒有mipmap,紋理不完整,看起來完全是白色。

+0

這不是我所有的代碼!我有一個用於初始化opengl的方法,其中包括啓用紋理。然後我爲每個紋理創建一個Objective-C對象。我最好發佈更多的代碼。 – 2011-01-27 11:55:38

+2

@kudor這不起作用,glTexParameter會影響當前綁定的紋理。這不是一個全球性的國家。 – 2011-01-27 12:28:50

2

OpenGL是一個狀態機。其中一個狀態是目標GL_TEXTURE_2D的當前紋理。您可以在任何時候上傳紋理來替換當前紋理。

在OpenGL 1.0中,沒有glGenTextures/glBindTexture,它假定在第一次執行時,您將在使用前立即提交每個紋理,並且作爲第二次,您將通過顯示列表執行所有操作,讓司機有機會緩存​​紋理,因爲它看起來合適。顯示列表在OpenGL ES中已經過時並且不被使用,並且可能是一個糟糕的主意。從OpenGL 1.1開始,在OpenGL ES的所有迭代中,可以使用紋理名稱和各種相關功能。

紋理名稱只是保持GL_TEXTURE_2D狀態的存儲版本的一種方式。因此,如果您創建一個紋理名稱並將其綁定,那麼您將創建一個可以更改紋理(和紋理參數)的環境,而不會影響任何其他指定的紋理。驅動程序很容易將圖像緩存在GPU可尋址內存中。

但是,如果您不想使用紋理名稱,實際上並不需要。只有上傳和使用紋理纔有效。這可能就是爲什麼你的應用程序沒有任何對glBindTexture的調用。

鑑於您使用的是紋理名稱,在提供新的子圖像之前,您的reloadTitle不應該綁定相關的紋理嗎?你似乎並沒有在drawFrame中綁定任何特定的紋理?

相關問題