2012-02-14 12 views
6

(Editar: Probé una muestra que simplemente pintaba un triángulo sin ninguna textura o sombreadores y solo OpenGL-ES 1.1 en mi dispositivo y podía ver los mismos artefactos. Probé la misma muestra en el emulador y no había artefactos allí en todo. ¿Podría ser un problema de Tegra 2 o necesito establecer un estado específico o algo que no es necesario en el emulador?)¿Por qué los colores de los píxeles no son correctos en OpenGL ES 2.0 en Android?

Estoy representando un cuadrado de píxeles correctos en la pantalla, pero cuando hago una captura de pantalla y mira el pixel y algunos de ellos están ligeramente deshabilitados o filtrados o algo así. Solo lo ves cuando lo acercas, pero ese no es el punto. Quiero hacer algunas operaciones matemáticas en el sombreador de píxeles y si los píxeles están ligeramente apagados y eso no es bueno para mí. Los necesito exactamente como en el mapa de bits en el que los puse.

Aquí hay una captura de pantalla agrandada del problema. Alrededor de la línea blanca de los valores oscuros son ligeramente más brillante de lo que deberían ser:

enter image description here

ya he intentado:

GLES20.glDisable(GLES20.GL_DITHER); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 

pero no tuvo ningún efecto. Los píxeles están un poco apagados. Es fácil ver entre un pixel oscuro y blanco porque el pixel oscuro al lado es un poco más brillante y ver los valores de r, g, b con un programa de pintura también me lo muestra.

¿Podría alguien ayudarme con esto?

algo más de información: CPU

Mi de dispositivo es un Tegra 2.0. Represento un cuadrado de 256x256 exactamente en 256x256 píxeles (lo comprobé tomando una captura de pantalla con eclipse DDMS). La transparencia está desactivada y el mapa de bits tiene un valor alfa de 255 para cada píxel. He creado la superficie como una superficie de 32 bits con alfa con:

glSurface.setEGLConfigChooser(8, 8, 8, 8, 0, 0); 

que simplifica el código, pero todavía se puede ver el problema cuando me hacen con siguientes shaders:

String vshaderquad = "attribute vec4 a_pos;    \n" + // in  position 
          "attribute vec2 a_tex;    \n" + // in  Texture coordinates 
          "varying vec2 vtex;     \n" + // out  Texture coordinates 
          "void main(void) {     \n" + 
          " gl_Position = vec4(a_pos);  \n" + 
          " vtex = a_tex;     \n" + 
          "}"; 

    String fshaderquad = "precision mediump float;      \n" + 
          "varying vec2  vtex;      \n" + 
          "uniform sampler2D samp0;      \n" + 
          "void main() {         \n" + 
          " gl_FragColor = texture2D(samp0, vtex);  \n" + 
          "}"; 

y comandos:

GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mapid[0]); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 
GLES20.glUniform1i(handlesampler0, 0); 
GLES20.glDisable(GLES20.GL_DITHER); 



GLES20.glViewport(0, 0, screenx, screeny); 

float screenx = (float)ddimx; 
float screeny = (float)ddimy; 
// 
vdata.put(0*4+0,  0.0f * (2.0f/screenx)); 
vdata.put(0*4+1, 256.0f * (2.0f/screeny)); 
vdata.put(0*4+2,  0.0f * (1.0f/256f)); 
vdata.put(0*4+3, 256.0f * (1.0f/256f)); 
// 
vdata.put(1*4+0,  0.0f * (2.0f/screenx)); 
vdata.put(1*4+1,  0.0f * (2.0f/screeny)); 
vdata.put(1*4+2,  0.0f * (1.0f/256f)); 
vdata.put(1*4+3,  0.0f * (1.0f/256f)); 
// 
vdata.put(2*4+0, 256.0f * (2.0f/screenx)); 
vdata.put(2*4+1, 256.0f * (2.0f/screeny)); 
vdata.put(2*4+2, 256.0f * (1.0f/256f)); 
vdata.put(2*4+3, 256.0f * (1.0f/256f)); 
// 
vdata.put(3*4+0, 256.0f * (2.0f/screenx)); 
vdata.put(3*4+1,  0.0f * (2.0f/screeny)); 
vdata.put(3*4+2, 256.0f * (1.0f/256f)); 
vdata.put(3*4+3,  0.0f * (1.0f/256f)); 

GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 

PD: El ligero cambio de color no es realmente visible sin un acercamiento extremo pero quiero hacer cálculos con los valores y eso significa que solo tienen que ser precisos.

Editar: He añadido una imagen de resolución completa. Los colores en las líneas deberían ir de (0,0,0) a (255,255,255) y son inversos al degradado de fondo. Hice esta imagen solo para probar la precisión de la textura y allí encontré el problema que no es realmente preciso. Sin embargo, tiene que acercarse para distinguir las diferencias, por eso también publiqué la imagen ampliada. Nota: Las coordenadas son diferentes a las del código publicado anteriormente, pero el problema es el mismo (traté diferentes coordenadas en pantalla y el problema persiste).

enter image description here

+0

Un Screengrab sería muy bueno para mostrar el problema, pero a partir de lo que se escribe sospecho que es [difuminado] (http://www.curious-creature.org/2010/12/08/bitmap-quality-banding-and-dithering/). Es un postprocesamiento, por lo que no debería afectar a los sombreadores de píxeles. –

+0

Hola, gracias por su respuesta y agregué una imagen para mostrar mejor el problema. Tampoco creo que sea simplemente un error de posprocesamiento porque hago algunos cálculos en los sombreadores y los valores esperados estaban apagados y señalo que ese es el problema. – HardCoder

+0

Pregunto como un idiota de Android: ¿hay alguna manera de que esté usando una pantalla PenTile y leyendo los colores que se calculan a partir de los elementos de visualización reales? – Tommy

Respuesta

3

Ok, creo que he encontrado la solución.

Como ya escribí, hice una captura de pantalla con el eclipse DDMS y eso parece estar causando el problema. Esa captura de pantalla no es el framebuffer exacto, pero existe algún tipo de suavizado/anti-aliasing allí.

Esto parece no ser el resultado del propio DDMS, pero parece que solo ocurre cuando se usa en mi dispositivo real. Cuando lo probé con el emulador, ese problema no apareció, por lo que podría ser que mi dispositivo tuviera una pantalla portátil (solo se lanzó en Japón hasta el momento y no encontré ningún material de información que lo confirmara o lo negara, pero su Sony y Sony lo hicieron). usa pantallas pentile en dispositivos) o tal vez tiene que ver con el chip tegra 2 o tal vez es algún tipo de compresión que ocurre cuando la imagen se transfiere o tal vez por alguna otra razón.

De cualquier manera, cuando uso la siguiente función puedo guardar capturas de pantalla que son absolutamente perfectas ya que toma el Framebuffer OpenGL-ES 2.0 y lo guarda en un archivo png que luego puedo transferir fácilmente con un archivo por lotes ("adb tire /mnt/sdcard/info/Testfile.txt ") y ver en mi equipo:

public boolean SaveFrameBuffer(int x, int y) 
{ try 
    { IntBuffer pinbuffer = IntBuffer.allocate(x*y*4); 
     IntBuffer poutbuffer = IntBuffer.allocate(x*y*4); 
     int   i,j,z; 
     int []  pin   = pinbuffer.array(); 
     int []  pout  = poutbuffer.array(); 
     // 
     GLES20.glReadPixels(0, 0, x, y, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, pinbuffer);    
     for(i=0;i<y;i++) 
     { for(j=0;j<x;j++) 
      { z = pin[(y-1-i)*x+j]; 
       pout[i*x+j] = (z & 0xff000000) | ((z >> 16) & 0x000000ff) | ((z << 16) & 0x00ff0000) | (z & 0x0000ff00); 
      } 
     } 
     Bitmap map = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888); 
     map.setPixels(pout, 0, x, 0,0, x, y); 
     OutputStream stream = new FileOutputStream("/sdcard/info/test.png"); 
     map.compress(CompressFormat.PNG, 100, stream); 
     stream.close(); 
     return true; 
    } catch (Exception e) 
    { e.printStackTrace(); 
     return false; 
    } 
} 
Cuestiones relacionadas