2012-02-02 156 views
5

我已經成功繪製了一個多紋理多邊形,但不幸的是只有整個紋理區域使用了疊加紋理的第一個像素。OpenGL,GL_MODULATE和多紋理

下面是紋理(GL_TEXTURE0和GL_TEXTURE1):

overlayicon

結果是這樣的:正在使用

result

只有在頂部的紅色像素。我已經嘗試過只有1x1的藍色像素,而且我用藍色覆蓋獲得了相同的結果。

我的代碼:

glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
glDisableClientState(GL_COLOR_ARRAY); 

const CGPoint vertices[] = { 
    ccp(0,0), 
    ccp(100,0), 
    ccp(0,100), 
    ccp(100,100), 
}; 

// This will flip the image for us as well 
const CGPoint coordinates[] = { 
    ccp(0,1), 
    ccp(1,1), 
    ccp(0,0), 
    ccp(1,0), 
}; 

// Config multitextures 
glClientActiveTexture(GL_TEXTURE0); 
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, icon.name); 
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
glTexCoordPointer(2, GL_FLOAT, 0, coordinates); 
glEnable(GL_TEXTURE_2D); 

glClientActiveTexture(GL_TEXTURE1); 
glActiveTexture(GL_TEXTURE1); 
glBindTexture(GL_TEXTURE_2D, overlay.name); 
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
glTexCoordPointer(2, GL_FLOAT, 0, coordinates); 
glEnable(GL_TEXTURE_2D); 

GLubyte points = 4; 

// Draw the square 
glVertexPointer(2, GL_FLOAT, 0, vertices); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, points); 

// Revert back 
glActiveTexture(GL_TEXTURE1); 
glDisable(GL_TEXTURE_2D); 

// glClientActiveTexture(GL_TEXTURE0); // breaks multitexturing 
glActiveTexture(GL_TEXTURE0); 
glEnable(GL_TEXTURE_2D); 

glEnableClientState(GL_COLOR_ARRAY); 

這是一個OpenGL的問題,但iOS的項目可在這裏爲那些有興趣:http://dl.dropbox.com/u/33811812/cocos2d/OpenGLTest.zip

編輯: 從紅皮書:

如果您是多紋理,並且您使用glTexCoord *(),那麼您將設置 紋理coo rdinates爲第一個紋理單元。換句話說,使用 glTexCoord *()是相當於使用glMultiTexCoord * (GL_TEXTURE0,...)

任何提示如何通過座標的數組? OpenGL ES 1.1不支持glBegin()等。

+2

看來你正在尋找[glClientActiveTexture(http://www.opengl.org/sdk/docs/man/xhtml/glClientActiveTexture.xml)。 – 2012-02-02 17:23:34

+0

太棒了!除了在繪圖之後設置'glClientActiveTexture(GL_TEXTURE0);'外,它會再次失敗。我還需要其他繪製方法來恢復狀態。這怎麼能實現? – 2012-02-02 17:38:02

+0

我也看過'glVertexAttribPointer',但我不知道如何使用它來指定GL_TEXTURE1的座標... – 2012-02-02 17:49:25

回答

6

最後!該解決方案是我必須做的三兩件事:0和1的glTexCoordPointer

  • 使用glEnableClientState(GL_TEXTURE_COORD_ARRAY)之前每個紋理

    • 使用glClientActiveTexture(GL_TEXTURE *)以及
    • 恢復到glClientActiveTexture (GL_TEXTURE0),以避免衝突的進一步繪製

    下面是工作代碼:

    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glDisableClientState(GL_COLOR_ARRAY); 
    
    const CGPoint vertices[] = { 
        ccp(0,0), 
        ccp(100,0), 
        ccp(0,100), 
        ccp(100,100), 
    }; 
    
    // This will flip the image for us as well 
    const CGPoint coordinates[] = { 
        ccp(0,1), 
        ccp(1,1), 
        ccp(0,0), 
        ccp(1,0), 
    }; 
    
    // Config multitextures 
    glClientActiveTexture(GL_TEXTURE0); 
    glActiveTexture(GL_TEXTURE0); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glBindTexture(GL_TEXTURE_2D, icon.name); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
    glTexCoordPointer(2, GL_FLOAT, 0, coordinates); 
    glEnable(GL_TEXTURE_2D); 
    
    glClientActiveTexture(GL_TEXTURE1); 
    glActiveTexture(GL_TEXTURE1); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glBindTexture(GL_TEXTURE_2D, overlay.name); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
    glTexCoordPointer(2, GL_FLOAT, 0, coordinates); 
    glEnable(GL_TEXTURE_2D); 
    
    GLubyte points = 4; 
    
    // Draw the square 
    glVertexPointer(2, GL_FLOAT, 0, vertices); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, points); 
    
    // Revert back 
    glActiveTexture(GL_TEXTURE1); 
    glDisable(GL_TEXTURE_2D); 
    
    glClientActiveTexture(GL_TEXTURE0); 
    glActiveTexture(GL_TEXTURE0); 
    glEnable(GL_TEXTURE_2D); 
    
    glEnableClientState(GL_COLOR_ARRAY); 
    

    而結果:

    works