2016-03-25 5 views
0

In meiner App verwende ich eine GLSurfaceView, um ein 2-dimensionales Hintergrundbild anzuzeigen, das sich je nach angezeigtem Inhalt ändert. Das Bild wird als Textur verwendet, die auf einem einfachen Rechteck mit demselben Seitenverhältnis wie der Bildschirm des Telefons wiedergegeben wird. Wenn sich der Hintergrund ändert, wird ein Alpha-Blend-Übergangseffekt wiedergegeben. Wenn das Gerät Open GL ES 2.0 nicht unterstützt, wird stattdessen ein statisches Bild verwendet. (Zusätzliche Informationen: das Bild/Textur ist kein Quadrat und hat nicht die Größe einer Stärke von 2)Android: OpenGL-Textur wird auf einigen Geräten weiß

Einige Kunden haben berichtet, dass der Hintergrund bei einigen Geräten (zB LG E455) weiß wird, wodurch die App unbrauchbar wird. weil der oben angezeigte Text ebenfalls weiß ist. Ich habe nach einer Lösung für das Problem gesucht, konnte aber nichts finden.

Da ich die App kostenlos ohne Werbung zur Verfügung stelle (ich denke, dass Anzeigen nicht zur App passen) und ich keine externe Finanzierung bekomme, ist es für mich keine Option, das betreffende Gerät zu kaufen (LG E455) - wie es ein altes Gerät ist - zu dem einzigen Zweck, dieses eine Problem zu debuggen.

ich den folgenden Code verwende die Texturen zu laden:

int getTexture(GL10 gl, int index) { 
    if (BackgroundRenderer.this.textures[index] == 0) { 
     gl.glGenTextures(1, BackgroundRenderer.this.textures, index); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, BackgroundRenderer.this.textures[index]); 

     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); 

     Bitmap bitmap = ResourceStore.getBackgroundBitmap(index); 

     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 
    } 

    return BackgroundRenderer.this.textures[index]; 
} 

Versionsprüfung und Initialisierung:

private static boolean supportsOpenGLES2(Context context) { 
    ActivityManager activityManager = (ActivityManager) 
      context.getSystemService(Context.ACTIVITY_SERVICE); 
    ConfigurationInfo configurationInfo = 
      activityManager.getDeviceConfigurationInfo(); 
    return configurationInfo.reqGlEsVersion >= 0x20000; 
} 

public BackgroundManager(Context context, ViewPager eventSource) { 
    this.context = context; 
    supportsRendering = BackgroundManager.supportsOpenGLES2(context); 
    eventSource.setTag(id.TAG_BACKGROUND_MANAGER, this); 

    if (this.supportsRendering) { 
     this.backgroundSurfaceView = new GLSurfaceView(context); 
     this.backgroundSurfaceView.setFocusable(false); 
     this.backgroundSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); 
     eventSource.addOnPageChangeListener(BackgroundManager.getRenderer()); 
     this.backgroundSurfaceView.setRenderer(BackgroundManager.getRenderer()); 
     this.backgroundSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); 
    } else { 
     this.backgroundStillView = new View(context); 
    } 
} 

Wenn Sie mehr Code benötigen, erklären Sie mir bitte.

Ich habe über einige mögliche Lösungen gedacht:

a) das Problem zu beheben (weiß nicht, wie ...)

b) die Phantasie Effekte deaktivieren, falls das Gerät nicht unterstützt wird, Aber hier ist die Frage, wie kann ich erkennen, ob das Rendering im Voraus funktioniert? Das Gerät übergibt meine Open GL 2.0 Versionsprüfung.

c) Wechseln Sie statt OpenGL zu einer anderen Rendering-Lösung, da ich das Gefühl habe, dass es für meinen Zweck übertrieben ist. Irgendwelche Vorschläge?

Hinweis: Die Lösung in Android 'white box' textures OpenGL ES 1.0 on some devices vorgeschlagen gilt nicht, weil ich eine andere API und das Gerät funktioniert die Erweiterung nach http://specdevice.com/showspec.php?id=02c2-cba8-ffff-ffffebe99653 unterstützen (obwohl ich nicht sicher bin, ob die Informationen richtig/glaubwürdig ist)

Thank Sie für Ihre Vorschläge!

Antwort

2

Das Problem hier ist, dass einige Geräte keine Zwei-Potenz-Texturen unterstützen. Aus diesem Grund weisen einige Geräte nur eine weiße Textur auf.

Um dies zu lösen, ist es am besten, immer eine Zweierpotenz Bitmap zu verwenden, wenn Sie die Textur erzeugen.

Power-of-Two-Bitmaps sind Bitmaps, deren Breite/Höhe eine Potenz von zwei ist (256, 512, 1024 usw.). Wie es momentan aussieht, laden Sie Ihre Bitmap über ResourceStore, und ich bezweifle, dass dieses Tool eine PO2-Bitmap erstellt.

Um dieses Problem zu überwinden, gehen Sie folgendermaßen vor:

  1. Bitmap erstellen normalerweise wie Sie tun
  2. die Maße Ihrer Bitmap finden (können zum Beispiel sagen, seine 500x800)
  3. erstellen eine neue Bitmap, die PO2 ist und größer als die ursprüngliche Bitmap (in diesem Beispiel 512x1024)
  4. Kopieren Sie Ihre ursprüngliche Bitmap auf dieser neuen Bitmap, behalten Sie die ursprüngliche Bitmap-Größe, so dass die neue Bitmap auf der rechten Seite und leere Bereiche haben Unterseite.
  5. Passen Sie Ihre Texturkoordinaten an - anstelle von 1 für die x-Koordinate verwenden Sie 500/512 anstelle von 1 für die y-Koordinate, verwenden Sie 800/1024. Dies verhindert, dass diese hässlichen weißen Ecken angezeigt werden.

Hier ist ein Codebeispiel:

public void getTexture(GL10 gl, int index) { 
    if (BackgroundRenderer.this.textures[index] == 0) { 
     //calls to gl.glGenTextures, gl.glBindTexture etc 

     Bitmap originalBitmap = ResourceStore.getBackgroundBitmap(index); 

     int po2W = 1; 
     int po2H = 1; 

     while (po2W < originalBitmap.getWidth()) 
      po2W *= 2; 

     while (po2H < originalBitmap.getHeight()) 
      po2H *= 2; 

     Bitmap po2Bitmap = Bitmap.createBitmap(po2W, po2H, Config.ARGB_8888); 

     Canvas canvas = new Canvas(po2Bitmap); 
     canvas.drawBitmap(originalBitmap, 0, 0, myPaint); 

     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, po2Bitmap, 0); 

     // these ratios need to be used for setting the texture coordinates! 
     mWidthRatio = (float)orignalBitmap.getWidth()/(float)po2Bitmap.getWidth(); 
     mHeightRatio = (float)orignalBitmap.getHeight()/(float)po2Bitmap.getHeight(); 
    } 

    return BackgroundRenderer.this.textures[index]; 
} 

Nun müssen Sie die Textur-Koordinaten neu zu definieren:

float textureData[] = { 
     0,   0,    // top left 
     0,   mHeightRatio, // bottom left 
     mWidthRatio, mHeightRatio, // bottom right 
     mWidthRatio, 0    // top right 
}; 

Jetzt sollten Sie gut zu gehen.

Lassen Sie mich wissen, wenn es ein Problem gibt.

+0

Vielen Dank, das hat mein Problem gelöst! Vielen Dank für die Bereitstellung einer solchen einfachen Lösung. War einfach zu implementieren! –

Verwandte Themen