Carlos Robles frikiblog

Los Sprites parpadean, se pierden frames, algunas texturas no se cargan?

| 0 comments

En Andengine, y por ende en cualquier sistema basado en openGL, nos podemos encontrar un problema (curiosamente comun) que nos puede hacer volvernos locos.

Por lo general, creamos una textura, le añadimos sources, y luego definimos una region, y a partir de ahi hacemos un sprite animado. No tiene secreto.

Pues muchas veces nos encontramos que algo sale mal, y algunos de los frames no apareceren.  Es decir, la imagen animada a veces desaparece por un momento, como si uno de los frames fuese transparente.
Despues de mucho recorrer el código, y comprobar que las texturas estan cargadas por los procedimientos habituales la cosa se complica, porque ademas suele pasar que entre varios frames que realmente estan en la misma textura, unos se ven y otros no, por lo que la textura si que tiene que estar cargada en el hardware, si no no se veria ninguno. Por otro lado, ya se sabe que cuando una textura se intenta usar antes de que esté cargado, no aparece un rectangulo transparente, sino que aprece un rectangulo blanco. El enfoque era malo desde el principio.

Esto nos hace pensar un poco más, y nos acordamos de openGL ysus secretos. Hay una cosa que se llama Vertex Buffer Object , que es uno de los mayores trucos de kung fu de openGL,  muy resumido es una extension que permite que las imagenes estén en la tarjeta gráfica en vez de en la memoria del sistema, lo que permite un rendimiento mucho mayo, que no es nada que se deba despreciar. Pero a la vez es otro punto por donde pasan los datos, y que por tanto hay que tener controlado.

Me di cuenta que en el emulador el programa corria perfectamente, pero en el móvil no, y también me di cuenta que cada vez fallaba una imagen distinta, y en distintos moviles fallaba mas, menos, o nada. Por lo tanto no es algo de programación, sino de Hardware.

Con estos datos, y buscando por el completisimo Andengine, encuentro que ya han previsto la forma de desactivar el VBO, que siempre es mejor que meter un comando openGL a mano, porque soy un vago.

la forma es antes de crear el Engine, hacemos esto con el objeto EngineOptions que le vamos a pasar:

 engineOptions.getRenderOptions().disableExtensionVertexBufferObjects(); 

y … funciona!

Supongo que a no ser que tengas un dispositivo muy potente, la memoria gráfica es mas bien poca, y puede que sea que al intentar cargar un juego con demasiadas imágenes, no sea demasiado bueno depender de ella, porque puede fallar.

Y como lo tengo que hacer mucho, porque varias de las Activities que uso llevan un monton de imágenes, y ademas hay otras cuantas chorradas en comun, pues me he creado una subclase de EngineOptions que ya hace lo propio:

public class GameEngineOptions extends EngineOptions {

 public GameEngineOptions(boolean pFullscreen,
 ScreenOrientation pScreenOrientation,
IResolutionPolicy pResolutionPolicy, Camera pCamera) {
 super(pFullscreen, pScreenOrientation, pResolutionPolicy, pCamera);
getRenderOptions().disableExtensionVertexBufferObjects();
}

Leave a Reply

Required fields are marked *.

*