2012-02-02 13 views
5

Udało mi się narysować wielobajtowy wielokąt, ale niestety tylko pierwszy piksel nałożonej tekstury jest używany w całym obszarze tekstur.OpenGL, GL_MODULATE i Multitexturing

Oto tekstur (GL_TEXTURE0 i GL_TEXTURE1):

iconoverlay

Rezultat jest taki:

result

Tylko czerwony piksel na górze jest używany. Próbowałem z jednym niebieskim pikselem 1x1 u góry i otrzymałem ten sam efekt z niebieską nakładką.

Mój kod:

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); 

Jest to problem, OpenGL, ale projekt iOS dostępna jest tutaj dla zainteresowanych: http://dl.dropbox.com/u/33811812/cocos2d/OpenGLTest.zip

EDIT: Z Czerwonej Księdze:

Jeśli używasz multiteksturacji i używasz glTexCoord *(), ustawiasz teksturę . rdinaty dla pierwszej jednostki tekstur. Innymi słowy, użyciu glTexCoord *() jest równoważne użyciu glMultiTexCoord * (GL_TEXTURE0, ...)

żadnych wskazówek, w jaki sposób przekazać tablicę współrzędnych? OpenGL ES 1.1 nie obsługuje glBegin() itp.

+2

Wydaje szukasz [glClientActiveTexture] (http://www.opengl.org/sdk/docs/man/xhtml/glClientActiveTexture.xml). –

+0

Genialny! Działa, oprócz tego, że ustawienie 'glClientActiveTexture (GL_TEXTURE0);' po rysowaniu powoduje, że znowu się nie uda. Mam inne metody rysowania, które muszę odwrócić dla stanów. Jak można to osiągnąć? –

+0

Spojrzałem również na 'glVertexAttribPointer', ale nie mam pojęcia, jak użyć tego do określenia współrzędnych GL_TEXTURE1 ... –

Odpowiedz

6

Wreszcie! Rozwiązaniem było to, że musiałem zrobić trzy rzeczy:

  • Zastosowanie glClientActiveTexture (GL_TEXTURE *) na 0 i 1 przed glTexCoordPointer
  • Korzystanie glEnableClientState (GL_TEXTURE_COORD_ARRAY) dla każdej fakturze, jak również
  • powrócić do glClientActiveTexture (GL_TEXTURE0), aby uniknąć konfliktu z dalszego losowania

Oto kod, który działa:

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); 

A wynik:

works