2015-06-16 19 views
12

Sto provando a disegnare trame trasparenti (testo) nella mia app. Stranamente, funziona sul nuovissimo Nexus 7 e sulla mia seconda generazione di Moto X ma sul Nexus 7 originale le textures sono solo nere. Ho attivato il blending e la texture è 512x512 quindi non è un problema di power-of-two. Sto anche solo usando GL10 che dovrebbe essere supportato su tutto, giusto? Qualche ragione per cui le trame non funzionerebbero solo su questo dispositivo?Texture OpenGL Android Trasparente Disegna Nero

gl.glEnable(GL10.GL_BLEND); 
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); 
gl.glEnable(GL10.GL_TEXTURE_2D); 
// text drawn here 
gl.glDisable(GL10.GL_TEXTURE_2D); 
gl.glDisable(GL10.GL_BLEND); 

Ed ecco l'inizializzazione tessitura, dove ho caricare l'atlante di texture:

public void loadGlyphs(GL10 gl, Context context) { 
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.text_bitmap); 
    gl.glGenTextures(1, textures, 0); 
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 

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

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

    bitmap.recycle(); 
} 

Top mostra ciò che accade sul vecchio Nexus 7. Il quadro di fondo è una Moto X.

Bad

Good

Modifica: ecco un esempio completo. Nessuna trasparenza, non disegna nulla sul vecchio Nexus 7. Se mi libero della trama, disegna il quadrato in bianco come dovrebbe.

MainActivity.java

import android.app.Activity; 
import android.opengl.GLSurfaceView; 
import android.os.Bundle; 


public class MainActivity extends Activity { 

    private GLSurfaceView glView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     glView = new TestView(this); 
     setContentView(glView); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     glView.onPause(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     glView.onResume(); 
    } 
} 

TestView.java

import android.content.Context; 
import android.opengl.GLSurfaceView; 

public class TestView extends GLSurfaceView { 
    private TestRenderer renderer; 

    public TestView(Context context) { 
     super(context); 

     renderer = new TestRenderer(context); 
     setRenderer(renderer); 
    } 
} 

TestRenderer.java

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.opengl.GLSurfaceView; 
import android.opengl.GLU; 
import android.opengl.GLUtils; 

import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

public class TestRenderer implements GLSurfaceView.Renderer { 

    private FloatBuffer floatBuffer; 
    private FloatBuffer textureBuffer; 
    private Context context; 
    private int[] textures; 

    public TestRenderer(Context context) { 
     this.context = context; 
     textures = new int[1]; 
    } 

    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     floatBuffer = ByteBuffer.allocateDirect(4 * 2 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     floatBuffer.put(-0.5f); 
     floatBuffer.put(-0.5f); 
     floatBuffer.put(-0.5f); 
     floatBuffer.put(0.5f); 
     floatBuffer.put(0.5f); 
     floatBuffer.put(-0.5f); 
     floatBuffer.put(0.5f); 
     floatBuffer.put(0.5f); 
     floatBuffer.rewind(); 

     textureBuffer = ByteBuffer.allocateDirect(4*2*4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     textureBuffer.put(0); 
     textureBuffer.put(1); 
     textureBuffer.put(0); 
     textureBuffer.put(0); 
     textureBuffer.put(1); 
     textureBuffer.put(1); 
     textureBuffer.put(1); 
     textureBuffer.put(0); 
     textureBuffer.rewind(); 

     Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.test); 
     gl.glGenTextures(1, textures, 0); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); 
     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 
     bitmap.recycle(); 
    } 

    public void onSurfaceChanged(GL10 gl, int w, int h) { 
     gl.glMatrixMode(GL10.GL_PROJECTION); 
     gl.glLoadIdentity(); 
     GLU.gluPerspective(gl, 45.0f, (float) w/(float) h, 0.1f, 100.0f); 
     gl.glMatrixMode(GL10.GL_MODELVIEW); 
     gl.glLoadIdentity(); 
    } 

    public void onDrawFrame(GL10 gl) { 
     gl.glLoadIdentity(); 
     gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
     gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 
     gl.glTranslatef(0.0f, 0.0f, -5.0f); 

     gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 

     gl.glEnable(GL10.GL_TEXTURE_2D); 
     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
     gl.glFrontFace(GL10.GL_CW); 
     gl.glVertexPointer(2, GL10.GL_FLOAT, 0, floatBuffer); 
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
     gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
     gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glDisable(GL10.GL_TEXTURE_2D); 
    } 
} 

Edit: Ecco un esempio che ho trovato on-line. Se disattivo GL_TEXTURE_2D ottengo un quadrato bianco. Se abilito GL_TEXTURE_2D non ottengo nulla.

MainActivity public class MainActivity estende Activity {

private GLSurfaceView glSurfaceView; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     glSurfaceView = new GLSurfaceView(this); 

     glSurfaceView.setRenderer(new GlRenderer(this)); 
     setContentView(glSurfaceView); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     glSurfaceView.onResume(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     glSurfaceView.onPause(); 
    } 

} 

GlRenderer

public class GlRenderer implements Renderer { 

    private Square square; 
    private Context context; 

    public GlRenderer(Context context) { 
     this.context = context; 
     this.square = new Square(); 
    } 

    @Override 
    public void onDrawFrame(GL10 gl) { 
     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
     gl.glLoadIdentity(); 
     gl.glTranslatef(0.0f, 0.0f, -5.0f); 
     square.draw(gl); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     if(height == 0) { 
      height = 1; 
     } 
     gl.glViewport(0, 0, width, height); 
     gl.glMatrixMode(GL10.GL_PROJECTION); 
     gl.glLoadIdentity(); 

     GLU.gluPerspective(gl, 45.0f, (float)width/(float)height, 0.1f, 100.0f); 

     gl.glMatrixMode(GL10.GL_MODELVIEW); 
     gl.glLoadIdentity(); 
    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     square.loadGLTexture(gl, this.context); 

     gl.glEnable(GL10.GL_TEXTURE_2D); 
     gl.glShadeModel(GL10.GL_SMOOTH); 
     gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); 
     gl.glClearDepthf(1.0f); 
     gl.glEnable(GL10.GL_DEPTH_TEST); 
     gl.glDepthFunc(GL10.GL_LEQUAL); 
     gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 
    } 
} 

Piazza

formato
public class Square { 

    private FloatBuffer vertexBuffer; 
    private float vertices[] = { 
      -1.0f, -1.0f, 0.0f, 
      -1.0f, 1.0f, 0.0f, 
      1.0f, -1.0f, 0.0f, 
      1.0f, 1.0f, 0.0f 
    }; 

    private FloatBuffer textureBuffer; 
    private float texture[] = { 
      0.0f, 1.0f, 
      0.0f, 0.0f, 
      1.0f, 1.0f, 
      1.0f, 0.0f 
    }; 

    private int[] textures = new int[1]; 

    public Square() { 
     ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4); 
     byteBuffer.order(ByteOrder.nativeOrder()); 
     vertexBuffer = byteBuffer.asFloatBuffer(); 
     vertexBuffer.put(vertices); 
     vertexBuffer.position(0); 
     byteBuffer = ByteBuffer.allocateDirect(texture.length * 4); 
     byteBuffer.order(ByteOrder.nativeOrder()); 
     textureBuffer = byteBuffer.asFloatBuffer(); 
     textureBuffer.put(texture); 
     textureBuffer.position(0); 
    } 

    public void loadGLTexture(GL10 gl, Context context) { 
     Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), 
       R.drawable.test); 

     gl.glGenTextures(1, textures, 0); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 

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

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

     bitmap.recycle(); 
    } 

    public void draw(GL10 gl) { 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 
     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
     gl.glFrontFace(GL10.GL_CW); 
     gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); 
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length/3); 
     gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
    } 
} 
+0

Forse è il tipo di texture che stai usando. Mostra il codice di creazione/inizializzazione della trama. – MuertoExcobito

+0

@MuertoExcobito ha aggiunto il codice –

+0

Stavo guidando per scoprire quali formati di trama stai usando, ma GLUtils.texImage2d lo fa internamente, quindi non è così informativo. Ma forse il tuo codice di disegno dipende dal fatto di trovarsi in un canale specifico (es.alfa), e invece lo sta mettendo in rosso? Questo era un problema in OpenGL quando si passava a 3.2 core, perché 'GL_ALPHA' era deprecato. – MuertoExcobito

risposta

1

Dopo molto la risoluzione dei problemi, sono stato in grado di risolvere il problema su entrambi i dispositivi (e presumibilmente tutti i dispositivi) con l'aggiunta di spostamento struttura come così:

gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); 
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); 

Non sono sicuro del motivo per cui questo era necessario per due dispositivi, ma non per gli altri due.

2

Di che colore è la vostra struttura sta usando? Corrisponde al formato di colore che lo shader si aspetta?

Se il tuo formato colore è RGBA8888 e lo shader si aspetta RGB256 puoi avere problemi come questo. (Cercherà informazioni canale alfa nel posto sbagliato)

+0

Ho appena loggato 'GLUtils.getInternalFormat (bitmap)' e ho ripristinato 6408, che corrisponde a GL_RGBA –

+0

Hmmm, puoi provare ad aprire la tua texture in GIMP per esempio ed esportarlo in modalità RGB? Quindi provare ad esportare in scala di grigi e vedere la differenza? Alcune altre cose che proverei: prova a cambiare la precisione dello shader in HIGHP float. Prova a cambiare canale alfa dal primo bitplane all'ultimo bitplane (o viceversa). Stai usando la compressione della trama? Alcuni algoritmi di compressione non supportano il canale alfa ... – DKIT

+0

Il passaggio tra RGB e Scala di grigi non ha influito affatto. Ho cambiato il livello di compressione PNG in GIMP da 9 a 0 senza alcuna differenza. Ho anche aggiunto un altro esempio. È interessante notare che non c'è trasparenza in quell'esempio e l'immagine non è ancora visualizzata. Non potrebbe semplicemente piacere a GLUtils generarlo? Le trame funzionano in altre app, quindi non sono sicuro di quale sia l'accordo –