2010-10-13 15 views
5

Ich erstelle erfolgreich meine Texturen mit GLUtils.texImage2D, , aber wenn ich die erzeugten Texturen verwende, bekomme ich Probleme mit meinem Alpha: Sie sind dunkler als gewünscht.Probleme mit GLUtils.texImage2D und Alpha in Texturen

nachdem ich einige Dinge überprüft habe, habe ich endlich die Schlussfolgerung, dass das Problem von GLUtils.texImage2D kommt (GL10.GL_TEXTURE_2D, level, bmp, 0);

Ich habe eine zweite Funktion erstellt, die gl.glTexImage2D verwendet (GL10.GL_TEXTURE_2D, Ebene, GL10.GL_RGBA, width, height, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixels2);

aber es ist teuer in der Verarbeitung, um pixels2 zu erstellen, das ist ein bytebuffer, in dem ich die Bytes recyopy, während die Werte von der Bitmap ARGB zur Beschaffenheit RGBA ändern müssen.

Hat jemand das bemerkt? und wenn ja, wie haben Sie dieses Problem lösen ...

jason


Danke für Ihre Antwort, Ich verwende bereits

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); 

und ich bin immer dieses Problem

Mein Problem ist, dass das von GLUtils erzeugte Alpha nicht das der Textur ist, es ist dunkler.

der Unterschied ist wie ein Blick auf eine Farbe in der Sonne und im Schatten (wenn das Sinn macht).

Ich habe bereits versucht gl.gltextimage2d aber die Schaffung des Puffers dauert zu lange, es sei denn, es ist ein Werkzeug, ein Bitmap zu einem Byte-Puffer zu konvertieren, die ich weiß nicht, von ...

Antwort

3

Der Alpha-Kanal ist das arme schlecht behandelte Stiefkind einer großen Anzahl von Programmierern ist alles was ich sagen kann ...aber der Upload funktioniert ziemlich effizient, wenn Sie das tun:

  • Schätzung Ihre größte Textur (wie 1024x1024) und erstellen Sie ein int-Array dieser Größe (1024 * 1024), die Sie in einigen statischen Variablen speichern oder irgendwo, wo man zugreifen kann, so dass Sie (allocation Zeit ist hier wertvoll)

  • dann tut dies nicht, dass die Array neu erstellen müssen:

    bitmap.getPixels(pixels, 0, width, 0, 0, width, height); 
    gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, width, height, 
        0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, IntBuffer.wrap(pixels)); 
    

ich bedaure, nicht mit eine andere Lösung gefunden ... Das ursprüngliche Problem ist, dass der Implementor der GLUtils.texImage2D Funktion den Alphakanal falsch behandelt hat, was zu schwarzen Rändern führt, wenn das Bild größer angezeigt wird (der bilineare Filter berechnet die Farbe zwischen vier Pixeln) und wenn die rgb-Werte der Pixel mit transparenten Alphas verfälscht wurden (wie zum Beispiel schwarz), ist das Ergebnis, dass eine Art von "Farbverlaufen" über dem transparenten Rand stattfindet, der sich dort bildet. Sehr hässlich. Vielleicht wurde es getan, um die Kompressionsrate zu verbessern, da die RGB-Werte in Alpha-transparenten Bereichen in PSDs eine Menge Junk enthalten, die, wenn sie eliminiert werden, viel Raum für Verbesserungen bei Komprimierungsalgorithmen liefern)

Edit: Leider war dieser Ansatz nur Arbeiten Sie für graue Bilder richtig, da der rote und blaue Kanal beim Holen der Pixel aus der Bitmap vertauscht wird. Zumindest auf meinem Gerät. Ich bin nicht sicher, wie richtig diese auch für andere Geräte, aber in meinem Fall, das hier hat den Trick:

for (int i=0;i<pixels.length;i+=1) { 
    int argb = pixels[i]; 
    pixels[i] = argb&0xff00ff00 | ((argb&0xff)<<16) | ((argb>>16)&0xff); 
} 
0

Es gibt eine Fragen in GLUtils mit vorgemischtem Alpha. Die einzige Lösung, die ich vorschlagen kann, ist, zu verwenden:

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA) 

Falls Sie andere Blendfunktionen benötigen Sie gl.glTexImage2D verwenden.

5

GLUtils.texImage2D generiert eine vormultiplizierte Alpha-Textur. In dieser generierten Textur werden alle Pixel mit dem Alpha-Wert multipliziert, sodass Sie den Alpha-Wert nicht noch einmal multiplizieren müssen. Versuchen wir

gl.glBlendFunc (GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);

1

Android Bitmap speichern Bilder von PNG geladen mit premultiplied Farben. GLUtils.texImage2D verwendet auch Farben, die von alpha vormultipliziert wurden, so dass Sie auf diese Weise keine Originalfarben erhalten.

Um PNG-Bilder ohne RGB Kanäle werden Premultiplied ich 3rd party PNGDecoder und Last Textur mit glTexImage2D zu laden. Sie können PNGDecoder Bibliothek erhalten PNG zu dekodieren von hier: http://twl.l33tlabs.org/#downloads

3

Lösung wird here gefunden. Es ist verwandt, wie es von anderen mit vormultiplexiertem Alpha angegeben wird.

Im Surface Constructor

setEGLConfigChooser(8, 8, 8, 8, 0, 0); 
    getHolder().setFormat(PixelFormat.RGBA_8888); 

Im View.Renderer onSurfaceCreated

gl.glEnable(GL10.GL_BLEND); 
    gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);