smart - Bloqueo y desbloqueo de BitmapData no funciona en Android
reconocimiento facial android apk (1)
Para su pregunta original, a veces el modo GPU no capta los cambios en el bitmapdata subyacente. Pruebe cualquiera de estas operaciones después de su unlock()
para ''insinuar'' que debe volver a cargar los datos del mapa de bits:
bm.filters = [];
bm.bitmapData = m;
bm.alpha = 0.98+Math.random()*0.02;
Pero como descubriste, subir bitmapdata puede ser lento. Para aclarar GPU / modos directos de renderizado:
En el modo GPU, cambiar cualquier píxel en un mapa de bits requiere una nueva carga del mapa de bits completo, por lo que es el tamaño del mapa de bits el factor limitante. En modo directo, solo modifica las partes de la pantalla que se han actualizado. Así que supongo que algunas partes del juego cambian mucho la pantalla a la vez (lento en modo directo), mientras que este efecto cambia un mapa de bits grande, pero solo un poco a la vez (lento en modo GPU).
Tienes que ser creativo para maximizar tus GPU de rendimiento wrt:
- En el modo GPU, divida el efecto en muchos mapas de bits, y solo cambie la menor cantidad posible para cualquier cuadro dado. (esfuerzo medio)
- Utilice Starling GPU-accelerated framework y Starling filters (sombreadores GPU) para lograr su efecto (el esfuerzo depende de cuánto haya invertido en su juego ya), vea un par de ejemplos
El siguiente código borrará un mapa de bits (brush akk droplet) de otro mapa de bits (akka
El código funciona muy bien en PC y funciona bastante bien.
Cuando lo pruebo en más dispositivos Android, no funciona. No importa si es un dispositivo de gama alta o uno más lento. Hice algunas pruebas y descubrí que el problema son las funciones lock () y unlock () de BitmapData. Simplemente no actualiza la imagen en el dispositivo, solo una vez.
Intenté eliminarlos, pero luego se retrasa mucho. También la caída de rendimiento es notable en PC también. ¿Alguien sabe una solución, donde estoy haciendo mal?
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Rectangle;
var m:BitmapData = new water_pattern;
var b:BitmapData = new droplet;
var bm:Bitmap = new Bitmap(m);
var bla = new blabla();
addChild(bla);
bla.addChild(bm);
function p($x,$y){
var refPoint = new Point($x-b.width/2,$y-b.height/2);
for(var i=0;i<b.width;i++)
for(var j=0;j<b.height;j++)
{
var a:uint = (b.getPixel32(i,j)>> 24) & 0xFF;
a=0xFF-a;
var tp:uint = m.getPixel32(refPoint.x+i,refPoint.y+j);
var tp_trans:uint = (tp >> 24)&0xFF;
if(tp_trans>a){
tp=(tp&0x00FFFFFF)|(a<<24);
m.setPixel32(refPoint.x+i,refPoint.y+j,tp);
}
}
//for(var k=0;k<10000000;k++){};
}
var k=1;
var md = function(e)
{
m.lock();
p(bm.mouseX,bm.mouseY);
m.unlock();
};
bla.addEventListener(MouseEvent.MOUSE_DOWN,function(e)
{
bla.addEventListener(Event.EXIT_FRAME,md);
});
bla.addEventListener(MouseEvent.MOUSE_UP,function(e)
{
bla.removeEventListener(Event.EXIT_FRAME,md);
});
He reelaborado el código:
public function draw($x, $y)
{
var refPoint = new Point($x - brush.width / 2, $y - brush.height / 2);
var r:Rectangle = new Rectangle(refPoint.x, refPoint.y, brush.width, brush.height);
var pv:Vector.<uint> = pattern.getVector(r);
var bv:Vector.<uint> = brush.getVector(brush.rect);
for (var i = 0; i < bv.length; i++)
{
var a:uint = (bv[i]>>24) &0xFF;
a = 0xFF - a;
var tp:uint = pv[i];
var tp_trans:uint = (tp >> 24) & 0xFF;
// trace(a.toString(16) + " vs " + tp_trans.toString(16));
if (tp_trans > a)
{
tp = (tp & 0x00FFFFFF) | (a << 24);
// trace("??>" + tp);
pv[i] = tp;
}
}
pattern.setVector(r, pv);
}
Ahora funciona, pero aún así es bastante lento en el dispositivo. Eso antes de ver el comentario de Jeff Ward, así que lo cambié al modo render en la CPU. Funciona rápido El gran problema es que en el modo CPU el juego es muy lento en comparación con la GPU. Sin embargo, este script es rápido en la CPU pero inutilizable lento en la GPU.
Así que volví a probar el primer código y me sorprendí. Funciona. Jeff Ward, gracias, eres un genio. Ahora la pregunta sigue siendo ¿por qué? ¿Alguien puede explicar?