2010-10-18 21 views
5

Estoy escribiendo una pequeña aplicación que en este momento genera un mapa aleatorio de texturas.Android OpenGL - ES Textura sangrando

Estoy dibujando este mapa como un grupo de "quads" de 10 x 15 que de hecho son todas las tiras de triángulos. Uso el "mapa" para tomar una int que tomo como la ubicación de la textura para este cuadrado en la texturaAtlas. entonces, por ejemplo, 0 es el "azulejo" inferior izquierdo. El atlas es de 128 x 128 y se divide en azulejos de 32 píxeles.

Sin embargo, parece que estoy obteniendo algunos artefactos extraños en los que la textura de una de las piezas se está deslizando hacia la siguiente ficha. Me pregunté si era la imagen en sí, pero hasta donde puedo decir, los píxeles están exactamente donde deberían estar. Luego miré los cordones de textura que estaba especificando pero todos parecen exactos (0.0, 0.25, 0.5, 0.75, 1.0 - dividiéndolo en las 4 filas y columnas que esperaría).

Lo curioso es que si lo ejecuto en el emulador no consigo ningún artefacto.

¿Existe una configuración que me falta que podría causar un sangrado de 1 píxel? Parecía solo que también era vertical, esto podría estar relacionado con que en el teléfono estoy "estirando" la imagen en esa dirección ya que la pantalla del teléfono es más grande de lo normal en esa dirección.

Cómo cargo la textura de este modo:

//Get a new ID 
    int id = newTextureID(gl); 

    //We will need to flip the texture vertically 
    Matrix flip = new Matrix(); 
    flip.postScale(1f, -1f); 

    //Load up and flip the texture 
    Bitmap temp = BitmapFactory.decodeResource(context.getResources(), resource); 

    //Store the widths for the texturemap 
    int width = temp.getWidth(); 
    int height = temp.getHeight(); 
    Bitmap bmp = Bitmap.createBitmap(temp, 0, 0, width, height, flip, true); 
    temp.recycle(); 

    //Bind 
    gl.glBindTexture(GL10.GL_TEXTURE_2D, id); 

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

    //Push onto the GPU 
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0); 

    TextureAtlas atlas = new TextureAtlas(id, width, height, tileSize); 
    return atlas; 

que luego hacerla de esta manera:

gl.glBindTexture(GL10.GL_TEXTURE_2D, currentAtlas.textureID); 
    //Enable the vertices buffer for writing and to be used during our rendering 
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
    //Specify the location and data format of an array of vertex coordinates to use 
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); 

    //Enable the texture buffer 
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); 
    gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); 

que sería tomar una foto, pero no estoy seguro cómo conseguir una tapa de la pantalla de la teléfono ...

Si alguien sabe cómo puedo capturar el fotograma actual y quizás ponerlo en un archivo, lo haré si ayuda a explicar lo que está pasando.

Esperamos su respuesta.

Editar: Aquí hay una captura de pantalla - nota Ejecuto la aplicación en el paisaje, pero la tapa está en el retrato. También disculpe las texturas horribles: D eran simplemente un titular de lugar/jugando.

ScreenCap

+0

Mientras que no puedo ayudar con el problema, puede utilizar el programa 'ddms' en el directorio de herramientas del SDK para tomar una captura de pantalla del dispositivo (ctrl-s). – richq

+0

¡Gracias! Sabía que debe haber una manera por la cual la gente lo hizo. Parece una herramienta generalmente útil también. – iexus

Respuesta

11

Bueno, después de hablar con un amigo que logró resolver este pequeño problema.

Resulta que si desea tener texturas perfectas de píxeles exactos, debe especificar que el borde de la textura está a la mitad del píxel.

Para hacer esto simplemente agregué medio píxel o restar medio píxel a la medición de los cordones de textura.

así:

//Top Left 
      textureCoords[textPlace] = xAdjust*currentAtlas.texSpaceWidth + currentAtlas.halfPixelAdjust;  textPlace++; 
      textureCoords[textPlace] = (yAdjust+1)*currentAtlas.texSpaceHeight - currentAtlas.halfPixelAdjust; textPlace++; 

Esto se calcula simplemente al cargar el atlas de textura:

(float)(0.5 * ((1.0f/numberOfTilesInAtlasRow)/pixelsPerTile)); 

Aunque si la altura es diferente a la anchura de cada baldosa (que podría suceder) que lo haría necesita calcularlos individualmente

Esto ha resuelto todos los artefactos para que pueda continuar. Espero que ayude a alguien más!

+0

hola. ¿Puedes explicarlo en más detalles? No entiendo cómo aplicar estas fórmulas a mis atlas.vAs I C para Atlas no baldosas xAdjust es x turno de sprite en el atlas. Pero por qué debería multiplicarlo a atlas witdh. ¿Están en píxeles? Gracias. –

+0

Esto funcionó muy bien para mí, aunque todavía tenía algunos problemas con las líneas cuando representación muy lejos y utilizando mipmapping. –

Cuestiones relacionadas