2014-07-15 2 views
2

Je suis en train de convertir le code de travail openGL en openGL ES. Après quelques recherches, j'ai conclu que la fonction suivante ne fonctionne pas dans ES car la conversion entre format et internalFormat n'est pas supportée (c'est-à-dire que les formats source et de destination doivent être les mêmes). Le correctif le plus simple semble être de convertir les données alpha en rgba où r=g=b=0, ce que faisait OpenGL avant sous la surface. Mon correctif ci-joint ne semble pas fonctionner, car Je ne pense pas comprendre comment le tampon est formaté pour effectuer cette conversion manuellement. Aussi peut-être il y a une fonction openGL ES que je peux appeler qui fera cette copie pour moi. Je ne sais pas si c'est important, mais le fichier est un fichier TGA.glTexImage2D convertir alpha à rgba OpenGL ES

void foo(unsigned char *inBytes, 
      unsigned int inWidth, 
      unsigned int inHeight) { 
    int error; 

    GLenum internalTexFormat = GL_RGBA; 
    GLenum texDataFormat = GL_ALPHA; 

    if(myAttemptedFix) { 
      texDataFormat = GL_RGBA; 

      unsigned char rgbaBytes[inWidth * inHeight * 4]; 
      for(int i=0; i < inWidth * inHeight; i++) { 
       rgbaBytes[4*i] = 0; 
       rgbaBytes[4*i + 1] = 0; 
       rgbaBytes[4*i + 2] = 0; 
       rgbaBytes[4*i + 3] = inBytes[i]; 
      } 
      inBytes = &rgbaBytes[0]; 

    } 


    glBindTexture(GL_TEXTURE_2D, mTextureID); 

    error = glGetError(); 
    if(error != GL_NO_ERROR) {  // error 
     printf("Error binding to texture id %d, error = %d\n", 
       (int)mTextureID, 
       error); 
     }  

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
    if(mRepeat) { 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
     } 
    else { 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 
     } 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 

    glTexImage2D(GL_TEXTURE_2D, 0, 
        internalTexFormat, inWidth, 
        inHeight, 0, 
        texDataFormat, GL_UNSIGNED_BYTE, inBytes); 

    error = glGetError(); 
    if(error != GL_NO_ERROR) {  // error 
     printf("Error setting texture data for id %d, error = %d, \"%s\"\n", 
       (int)mTextureID, error, glGetString(error)); 
     } 
} 

Edit: Quand je lance mon Réparez décrit le sprite correctement mais met aussi beaucoup d'ordure au fond qui ressemble un peu comme le braille:

+0

Pourquoi utilisez-vous GL_ALPHA comme format interne? Ces valeurs doivent correspondre les unes aux autres. Si vous avez une texture avec une seule valeur par pixel, vous devez utiliser GL_RED pour le format et le format interne. – dari

+1

@dari: 'GL_RED' n'est un format interne valide dans aucune version d'OpenGL ES. –

+0

Quand vous dites "ne semble pas fonctionner", pouvez-vous décrire exactement quel est le problème? De même, quelles sont vos valeurs pour 'inWidth',' inHeight' et 'mRepeat'? –

Répondre

2

Cela ressemble plus à une Problème C++ Je crois que vos données corrompues est causée par cette (raccourci) structure du code:

if (myAttemptedFix) { 
    unsigned char rgbaBytes[inWidth * inHeight * 4]; 
    inBytes = &rgbaBytes[0]; 
} 

La portée de rgbaBytes est le corps du if -Déclaration. Ainsi, la mémoire réservée pour le tableau devient invalide après l'accolade fermante, et son contenu devient indéfini au-delà de ce point. Mais vous faites votre inBytes point variable à cette mémoire, et l'utiliser après rgbaBytes est sorti de la portée.

Puisque inBytes pointe ensuite vers la mémoire non réservée, il est très probable que la mémoire soit occupée par d'autres variables dans le code entre ce point et l'appel glTexImage2D(). Ainsi, le contenu est saccagé avant que inBytes ne soit consommé par l'appel glTexImage2D().

La meilleure façon de résoudre ce problème est de déplacer la déclaration rgbaBytes en dehors du if -Déclaration:

unsigned char rgbaBytes[inWidth * inHeight * 4]; 
if (myAttemptedFix) { 
    inBytes = &rgbaBytes[0]; 
} 

Vous aurez probablement envie de rendre la structure de code un peu plus agréable une fois que vous avez tout cela compris, mais cela devrait au moins le rendre fonctionnel. Pourquoi utilisez-vous GL_ALPHA comme format et GL_RGBA comme format interne?

+0

Vous avez raison! Merci beaucoup. Je suis trop habitué à ne pas gérer ce genre de choses en Python. –

Questions connexes