PDA

Ver la Versión Completa : Moviendo Shapes (CLX): flickering y Off-screen bitmaps


kinobi
07-08-2003, 23:25:31
Hola,

estoy desarrollando un componente gráfico CLX (una especie de Shape) con capacidad de movimiento en tiempo de ejecución. He implementado la solución propuesta en este mismo foro (http://www.clubdelphi.com/foros/showthread.php?s=&threadid=435) para resolver la cuestión del movimiento. El problema surge por el molesto parpadeo (flickering) que tiene el control cuando se desplaza.

Siguiendo las instrucciones de la documentación, intento implementar el uso de un bitmap off-screen en el método Paint del control para, posteriormente, volcar el contenido del Bitmap sobre el Canvas del control y reducir así el parpadeo, ya que las operaciones de dibujo sobre el Canvas del Bitmap se producen en memoria y no sobre la pantalla.

Hasta aquí todo correcto, pero en la práctica no solo no consigo que se reduzca el parpadeo, sino que además se produce un efecto lateral: el control se dibuja con una brocha (Brush) completamente diferente a la que tiene realmente; parece como si el patrón de la brocha (color y style) fuesen aletorios.

No tengo mucha práctica con el uso de gráficos en Delphi, y especialmente con Qt (recuerdo que es un control CLX, no VCL), así que en esta dirección dejo los códigos fuentes del control (es una versión reducida, centrada sólo en el problema del parpadeo) y de un pequeño programa que ilustra el problema:

http://www.clubdelphi.com/users/kinobi/descargas/QCLXShape.zip

Saludos y muchas gracias.

guillotmarc
08-08-2003, 00:06:10
Hola Juan José.

Estoy intentado probar tu proyecto de muestra, pero al cargarlo, me indica que no puede encontrar la clase TCLXShape.

Nunca he creado una aplicación CLX, ¿ hay que hacer algo especial para abrir este proyecto ?.

Saludos.

kinobi
08-08-2003, 00:16:52
Hola Marc,

Posteado originalmente por guillotmarc
Nunca he creado una aplicación CLX, ¿ hay que hacer algo especial para abrir este proyecto ?.

que yo sepa no. Al estar la unidad (QCLXShape.pas) en el mismo directorio que el proyecto no debería tener problemas en localizarla.

Aunque ahora que me doy cuenta, el proyecto utiliza el control como un componente de la paleta. Puedes probar a instalarlo. En la unidad (QCLXShape) tienes el procedure Register (por defecto meterá el control en la pestaña "Pruebas" de la paleta de componentes, aunque, evidentemente, puedes cambiarlo).

Saludos y gracias por las molestias.

guillotmarc
08-08-2003, 00:20:11
Olvidalo, pensaba que era un componente de las CLX, ya he visto que es tu componente Shape. Ya lo he podido ejecutar.

Aunque los Shapes, dejan la estela por donde van pasando, el único parpadeo que veo aparece cuando un cuadro se sobrepone a otro. Lo que si puedo ver es como varia el dibujo en función del modo (por el tema comentado del grosor de la brocha).

¿ Es normal que vea una estela por donde va pasando el Shape ?.

Saludos.

guillotmarc
08-08-2003, 00:21:41
Vaya, veo que te me has adelantado. :)

kinobi
08-08-2003, 00:35:09
Hola,

Posteado originalmente por guillotmarc
Aunque los Shapes, dejan la estela por donde van pasando,
Vaya, eso no me ocurre a mí.

Posteado originalmente por guillotmarc
el único parpadeo que veo aparece cuando un cuadro se sobrepone a otro.
El parpadeo es más evidente cuanto más grande es la figura.

Posteado originalmente por guillotmarc
Lo que si puedo ver es como varia el dibujo en función del modo (por el tema comentado del grosor de la brocha).
Sí, evidentemente estoy manejando mal el Canvas del Bitmap off-screen, pero no tengo claro como hacerlo bien.

Saludos y de nuevo gracias.

guillotmarc
08-08-2003, 00:42:15
Hola.

Me acabo de dar cuenta de que al activar el OffScreenBmp, no hay un problema de tamaño de brocha, etc.... Sinó de transparencia, donde debería verse el fondo del formulario, se ve negro. (El efecto parece como si se hubiese cambiado el patrón de relleno).

Saludos.

guillotmarc
08-08-2003, 00:49:30
Quizá habria que iniciar el bitmap, copiando la el recuadro del formulario sobre el que se va a posicionar el Shape.

Hablando del bitmap, los Shapes no pueden cambiar de tamaño, así que solo haria falta asignar el tamaño del bitmap una vez, en la creación del componente. Ahora se está haciendo en cada repintado, cosa que forzosamente tiene que llevar su tiempo y debe ayudar al parpadeo. Incluso ¿ Es necesario volver a pintar el bitmap, no podemos incializarlo una vez y usar siempre el mismo ?

Saludos.

__cadetill
08-08-2003, 00:59:48
yo creo que es problema del redibujado del formulario, porque si pegas los componentes en un TPanel, funciona a las mil maravillas :confused:

guillotmarc
08-08-2003, 01:01:25
Bueno parece ser que utilizar siempre un mismo bitmap ya preparado, no es una opción, teniendo en cuenta de que siempre deberíamos inicializarlo con un rectangulo del formulario (cuando no inicializamos el bitmap, es cuando nos coge un fondo negro y por eso varia el patrón que se muestra).

A menos claro que no quieras tener efecto de transparencia, en cuyo caso si que siempre se podría utilizar directamente un bitmap ya preparado. En este caso imagino que se debería notar una disminución del parpadeo, puesto que el tiempo de ejecución del repintado tendría que ser considerablemente menor.

Saludos.

guillotmarc
08-08-2003, 01:14:24
Hola.

En efecto sobre un TPanel el componente no va dejando una estela.

Lo que se produce, en modo OffScreen es un parpadeo al sobreponerse dos Shape (primero se pinta uno y luego el otro sucesivamente varias veces, por lo que parpadea). Además del tema de cambio de patrón debido al fondo negro.

En modo no OffScreen, el problema está en el dibujo que se realiza, puesto que en el interior del componente, se va dejando una estela del paso del mismo (no se borra la estela, como pasa en el exterior del componente), así como una estela de otros componentes que pasen por el interior del primero.

Aunque como dije en mi primer mensaje, en mi Ordenador el movimiento es muy fluido, sin notarse parpadeos molestos al repintarse.

Saludos.

kinobi
08-08-2003, 01:36:37
Hola,

en primer lugar agradeceros las pruebas que habéis hecho.

Sí, parece que el Canvas del Parent del control influye decisivamente para el que haya o no parpadeo. Con un TPanel como Parent no se produce parpadeo (con o sin Off-screen bitmap), siempre que el control no pase por encima de otros controles.

Lo que me sorprende es que con un TPanel como Parent, se redibujan el interior de los controles por los que se pasa, y el propio control, dejando la estela de los bordes del control que movemos. Eso si no utilizamos el Off-screen bitmap, porque si lo utilizamos los dibuja todos bien, aunque con el Brush que no le corresponde.

Bueno, mañana volveré a la carga con el asunto. Buen trabajo el que habéis hecho, me ha puesto sobre varias pistas ... gracias.

Saludos.

Julià T.
08-08-2003, 04:20:11
Hola kinobi

para que siempre te dibuje bien sin estela en on mousemove pudes poner el código:

parent.InvalidateRect(Rect,Left,Top,Left+width,Top+height),True);

para que no redimensione el bmp (aunque creo que por defecto el bmp ya debe hacer la comparación antes de redimensionar), por lo que creo que no te a servir de mucho

if Bmp.Width<>ClientWidth then Bmp.Width := ClientWidth;
if Bmp.Height<>ClientHeight then Bmp.Height := ClientHeight;

finalmente para curiosidad, lo que se dibuja en el bmp, es lo que se ve en realidad, ya que si guardas el bmp en un fichero, sale con los colores cambiados.

guillotmarc
08-08-2003, 12:08:05
Hola.

Posteado originalmente por kinobi
Eso si no utilizamos el Off-screen bitmap, porque si lo utilizamos los dibuja todos bien, aunque con el Brush que no le corresponde.


Como comenté en un mensaje anterior, no es problema del brush, sinó del color de fondo. En modo normal, hace una transparencia mostrandose el fondo del formulario. En cambio en el modo Off-Screen, al dibujar el bitmap no indicamos que tiene que tener como fondo, por lo que coge todo el fondo de negro. El efecto parece ser un cambio de brocha, pero fijate que simplemente es que donde debería ser transparente es negro.

Saludos.

kinobi
08-08-2003, 19:02:24
Hola,

Posteado originalmente por Julià T.
para que siempre te dibuje bien sin estela en on mousemove pudes poner el código:
parent.InvalidateRect(Rect,Left,Top,Left+width,Top+height),True);

Correcto, pero entonces reaparece el parpadeo, incluso con un TPanel como Parent.

Posteado originalmente por guillotmarc
Como comenté en un mensaje anterior, no es problema del brush, sinó del color de fondo ...

De acuerdo. He probado activando la propiedad Transparent del Bitmap y funciona ... a medias. Ya que ahora dibuja correctamente la brocha del control, pero le pone color blanco al fondo. Problema: ¿cómo cambiar el color de fondo del bitmap para que sea igual al del control?

De todas formas, realmente no me preocupa tanto el problema de la brocha, ya que utilizaré siempre un estilo bsSolid, y con ese estilo funciona correctamente. Por otro lado, con un TPanel el problema del parpadeo desaparece (mientras no se pase por encima de otro control), independientemente a tener el off-screen bitmap activado o no. De momento me puede servir así, aunque seguiré trabajando en el asunto del off-screen bitmap y el asunto de las brochas, mejor dicho, el color de fondo del control.

Saludos y muchas gracias a todos por las molestias que os habéis tomado.

fdocortesl
08-08-2007, 01:25:22
Estimado,, mi nombre es Fdo. Cortés y necesito un componente del tipo tshape que tenga la propiedad "caption"... Conoces algo de lo ando buscando...