PDA

Ver la versión completa : Velocidad PutPixel (fenix) Vs UnlockBuffer(SDL)



fjsantos
17/12/2007, 14:53
Buenas tardes

He realizado pruebas este fin de semana, con la función PutPixel de Fenix. He notado que esta es bastante lenta en cuanto se compara con la función de acceso a los píxeles de SDL.
En el SDL, con las funciones de LockBuffer y UnlockBuffer, escribe los píxeles en pantalla mucho más rápido que la de fénix.
Me pregunto si existe alguna forma de realizar el mismo proceso de bloqueo de buffer y escritura de píxeles en pantalla con el fenix.
Alguien lo sabe?

Un saludo, fjsantos.

chipan
17/12/2007, 20:00
No creo que se pueda, pero todo sería implementar un método similar en el propio compilador o en el interprete de fenix; pero eso ya se me escapa.

Drumpi
17/12/2007, 20:44
Bueno, los comandos PUT nunca fueron rápidos (salvo en las últimas versiones, donde se les ha dado un acelerón bueno), sobre todo si hacemos frame a cada pixel, aunque el set_fps esté a 0 (con frame he compilado con fénix un archivo en 28 segundos, sin frame la cosa subió a... no me dio tiempo ni a darle a empezar al cronómetro XD)
Hay una forma más rápida de acceder a los pixels de un mapa: con MAP_BUFFER (si no es esa, es una muy parecida), devuelve el puntero a la zona de memoria donde se guarda el mapa. No se si es lo mismo que con SDL, y tampoco lo he probado, pero está en la ayuda y quizás le saqueis algun uso.

fjsantos
18/12/2007, 10:04
Buenos días y gracias por contestar.

Como tú dices chipan, sería muy interesante implementar algo así en el compilador de fenix, ya que parece carecer de un método rápido para escribir píxeles (o tomar el valor de estos, directamente de pantalla).
He probado la opción que me has dado drumpi (usando MAP_BUFFER), aunque según parece, este método te devuelve la posición en memoria de un determinado Gráfico y no la del buffer de video, que es realmente la que necesito.
Me gustaría seguerir, la implementación en fenix de las rutinas de acceso a la memoria de video tanto como la de bloqueo y desbloqueo de buffer (LockScreen, UnlockScreen). Aunque sé que es mucho más sencillo pedir que hacer.

Un saludo, fjsantos.

juanvvc
18/12/2007, 12:16
La implementación de esas rutinas provocaría que Fenix deje de ser portable, pero es que además creo que estás equivocando la orientación del lenguaje: Fenix puede manejar fácilmente sprites, entendiendo "manejar" como mover, rotar, transparentar, colisionar... Eso y su orientación de procesos en paralelo son las dos características principales de Fenix.

Precisamente para poder realizar con facilidad esas tareas no te deja acceso directo a la memoria de vídeo, manejar directamente pixeles o incluso modificar dinámicamente los sprites.

Si no estás haciendo frame entre cada llamada a PutPixel (no lo estás haciendo, ¿verdad? :) ) para mejorar la velocidad aún tienes una alternativa: Fenix soporta librerías externas escritas en C, que es como se hacían en tiempos los lujos gráficos de la nieve y el agua. Supongo que así podrías usar Lock/Unlock screen sin problemas, pero en este caso plantéate si realmente es Fenix el lenguaje que tu juego necesita.

fjsantos
18/12/2007, 12:51
Hola juanvvc.

Realmente acabo de empezar a programar para esta consola, y estaba picoteando entre los diversos lenguajes. (Me decidí por probar SDL y Fenix).
Como bien has adivinado, lo que estoy haciendo son demos gráficas que necesitan el uso intensivo de la memoria de video pixel a pixel (En cuanto tenga los efectos terminados los compartiré con todos).
Empecé por fenix, y descubrí que con este tipo de operaciones, me iba muy lento el efecto (juraría que hago Frame, únicamente cada vez que tengo toda la pantalla dibujada, pero al estar en el trabajo y no tener el código delante, no me atrevo a afirmar lo uno u lo otro).
Lo que desconocía, debido aún a mi escaso conocimiento del lenguaje, es que podía usar librerías externas escritas en c (supongo que vale en SDL), miraré como funciona esto, y haré una prueba desde fenix usando Lock/Unlock. (creo recordar que al crear un proyecto con el SDL, me deja seleccionar entre librería o ejecutable).
Tu respuesta me habre una nueva posibilidad sobre este gran lenguaje (Fenix), que por su sencillez, es el idóneo para escribir juegos. (Aunque supongo que cada lenguaje se adapta para según que cosas).
Como curiosidad personal, me gustaría saber si alguien ha echo pruebas entre el SDL y fenix, para ver que diferencia de velocidades hay entre un lenguaje y otro (10%?, 20%?).
Un saludo, fjsantos.

pd->Un gran juego el Snow Bros, uno de mis fravoritos, sin duda.

Eskema
18/12/2007, 15:27
sin hacer ningun tipo de pruebas, SDL debe ser mas rapido que fenix que es un lenguaje interpretado. Si tienes intencion de hacer cosas relativamente serias yo me olvidaria de fenix y usaria SDL o la minilib de ryleh

fjsantos
18/12/2007, 17:16
Buenas Eskema.

Sí, al ser interpretado es perfectamente lógico que sea más lento. Pero la comodidad y facilidad del fenix me atrae mucho. Siempre que no sea mucho más lento que el SDL (un 30% más lento ya me parecería mucho), no me importaría usarlo.

Esta tarde si tengo tiempo voy a intentar terminar una demo (movimiento de píxeles) en SDL y Fenix para comparar.

Un saludo, fjsantos.

Eskema
18/12/2007, 18:59
Es como todo, cuando te haces tu libreria en SDL y tienes tus funciones basicas (moversprites, dibujarlos, dibujar animaciones,etc) hacer un juego es relativamente facil.
A mi el codigo del fenix por los juegos que he visto me ha parecido un poco caotico, por eso me pase a SDL, según tengo entendido la velocidad puede ser hasta un 20% mas lento fenix, pero tambien depende de que version de fenix se use, las ultimas dicen estar muy optimizadas

fjsantos
18/12/2007, 19:19
Claro, todo es cuestión de crearte tus propias librerías.
Es cierto que el Fenix puede parecer un poco caótico al principio, pero cuando se le pilla la filosofía (yo la pillé en tiempos del Div Studio), es un lenguaje muy gratificante (los procesos me encantan y me parecen muy cómodos de utilizar).
Por lo que me cuentas, una velocidad inferior al 20% me parecería bastante aceptable.
El SDL por contra, sigue las normas de porgramación comunmente establecidas en la programación, incluyendo el usode librerías clásicas del c (math.h, timer.h, etc), lo cual gana la ventaja de la experiencia.

En fin, se nota que le tengo cariño al Div alias Fenix.

Un saludo, fjsantos.

Drumpi
18/12/2007, 19:31
Pues mira, si quieres ver la potencia de Fenix usando dlls, podrias mirar algunas, como la ETD o VSE del GRAN TRISTAN, que dan "algo" de soporte 3d a Fenix (no esperes más que la SNES, aunque quien sabe, si te lo curras...) o la m8ee que estan diseñando los de Colombian Developers, que es un motor de Modo8 que tenia DIV pero mejorado (es decir, sin bugs). Todos se integran perfectamente en Fenix, de hecho, la VSE pinta sobre un gráfico creado en tiempo de ejecución, es algo lenta, pero luego el resultado lo puedes rotar, escalar, mover, asignarle blendops, etc como si fuera un proceso.
El mundo de las dll esta bastante bien en Fenix (creo que en sourceforge, en donde estan los binarios oficiales alojados, estan muchas de ellas porque las recompilaron para una de las ultimas versiones), tienes la image.dll para cargar nuevos formatos, la ttf.dll, incluso se emepzó una gui.dll para desarrollar la IDE oficial (y para que cualquiera pudiera añadir listas, ventanas, etc en sus juegos sin comerse mucho la cabeza).
Otra cosa es que sean portables, pero creo que todas se pueden recompilar para Liux, gp2x, etc... Los fuentes suelen estar incluidos.

PD: yo he repintado un mapa de 800x600 a 1.333GHZ a más de 80fps con map_xputnp en las últimas versiones, no se si esto será suficiente para lo que tu quieres hacer, aunque a mi aun me queda optimizar ese código, que es de un motor de mapas tileados que estoy haciendo (en lenguaje Fenix, sin c ni sdl).

fjsantos
19/12/2007, 11:22
Buenos días Drumpi.
Animado por tu post, he estado mirando diversas dlls para fenix, aunque no imaginaba la abundancia que habría de estas. Miré, por encima, las dlls que me comentas, y he de decir que tienen muy buena pinta. Creo que se podrían hacer cosas muy interesantes con ellas, tipo Wolfstein o Doom (aunque me suelo decantar más por el 2d bien diseñado).
Por otro lado, ayer estuve 'jugueteando' con el SDL (que pena el tener tan pocas horas libres al día para usarla) y me está consiguiendo enganchar.
En fins, me debato entre dos aguas...
Un saludo, fjsantos.

rlyeh
19/12/2007, 13:43
Por qué no creáis una imagen en negro de 320x240 pixels, la cargais y la dejais cargada en memoria durante todo el juego.

Luego en el codigo, en cada frame, accedeis a la memoria del grafico y cambiais lo que queriais, y luego subís la imagen a la pantalla, asi una y otra vez en cada frame.

Seguro que el truco funciona y teneis velocidad maxima, ademas es portable, y a fin de cuentas es casi lo mismo que acceder a la memoria de video directamente.

fjsantos
19/12/2007, 14:01
Buenas rlyeh.

Es una solución muy interesante la que me comentas, y la verdad, no se me había ocurrido (y eso que drumpi ya me dió la pista cuando me comentó el método MAP_BUFFER). Esta tarde nada más llege a mi casa lo pruebo y mañana posteo los resultados que obtenga.
Sin duda una solución excelente...

Un saludo, fjsantos.

rlyeh
20/12/2007, 21:27
Funcionó?
Por cierto las tasas de la idea son 5 eur. xD

fjsantos
20/12/2007, 22:05
Buenas rlyeh.

Acabo de probar tu idea, sin embargo he echo una pequeña variante que me era más cómoda. Usé las instrucciones MAP_PUT_PIXEL y MAP_GET_PIXEL. Lo demás como comentabas. Sin embargo y por desgracia, la velocidad sigue siendo muy lenta (no creo que llegue a los 10 frames). Me queda probar MAP_BUFFER (no sé si obtendré el mismo resultado con esta otra función).
Otra cosa que tengo es la velocidad SET_FPS(60,0), aunque esto lo único que debería proporcionar es la máxima velocidad que permita el procesador no?.
Por otro lado con el SDL estoy obteniendo excelentes resultados, he echo una pequeña demo que espero postear hoy o mañana (ha quedado bastante bién y con una buena media de velocidad).
Así que si no funciona con MAP_BUFFER, habrá que seguir pensando.

Un saludo, fjsantos.

Drumpi
20/12/2007, 22:19
Emmm, la máxima velocidad de la CPU la obtienes con set_fps(0,0), que lo hace de forma automática, y si me apuras, creo que con un fs de 3 irá mejor (set_fps(0,3), no significa que haga el frameskip, no debería hacerlo, pero creo que las rutinas de dibujado están más "cómodas con un fs múltiplo de 3, pruebalo)

Por cierto ¿hay mucha diferencia entre Fenix y c+sdl? salvo lo obvio de la programacion secuencial/concurrente.
Idea loca: ¿se podría portar CDIV a GP2X?

chipan
20/12/2007, 22:48
Rlyeh, me has plagiado la idea de la imagen en negro para utilizarla como buffer de pantalla; ¡date por querellao!; a ver si subo una prueba de "falso efecto 3d" utilizando esta tecnica.

fjsantos
21/12/2007, 00:36
Buenas Drumpi.

Tienes toda la razón, debe de ponerse SET_FPS(0, 0), para conseguir la máxima velocidad, (estaba pensando en la máxima de los clásicos 60 fps por segundo).
Bueno, he probado lo que me recomiendas SET_FPS(0, 3) y sigue bastante mal de frames. (En realidad no he notado ningún cambio).
Con respecto si hay mucha diferencia entre Fenix y SDL, (supongo que te refieres a programación), pues por lo poco que llevo visto, a parte de la metodologí ade programación que usa (que ya es bastante diferente), se echan muchas de menos de las comodidades de Fenix en SDL. Hay bastantes métodos para implementar que en Fenix ya vienen de serie. A parte de esto, el SDL al ser c, da mucha más flexibilidad y madurez en el lenguaje, y aunque no lo conozcas, puedes tirar de los conocimientos de c de toda la vida (librerías clásicas como math.h, time.h, etc).
Eso sí, Fenix para mi gusto, es más sencillo y cómodo, pero como veo, para algunas cosas carece de velocidad.
Con respecto a si se podría portar, creo que no soy el más indicado para contestar a una pregunta así.

Chipan, estoy deseando ver ese efecto 3d utilizando el buffer de pantalla!

Bueno voy a ver si posteo al fin, uno de los efectos de píxeles que tengo programado.

Un saludo, fjsantos.

rlyeh
21/12/2007, 14:29
Según os había entendido yo tenías que usar MAP_BUFFER, y luego acceder al array del grafico como si fuera el de pantalla. Y luego subir el grafico a memoria quizás, o quizás no porque ya está subido y al actualizar su contenidos actualizas en memoria de video. Cosa a comprobar...

De todas formas estaría bien que pegases el código a ver por qué te va *tan* lento...

fjsantos
21/12/2007, 17:25
Buenas tardes rlyeh.
En realidad he usado MAP_PUT_PIXEL y MAP_GET_PIXEL sobre el gráfico. Y luego lo he mostrado en pantalla. Pero como tú indicas, la velocidad es la misma ya que el gráfico, una vez cargado ya se encuentra en memoria.

Sea como fuere, aquí te dejo el código para ver si consigues velocidad.

También te subo la imagen que estoy utilizando.

Un saludo, fjsantos.



PROGRAM gp32;

GLOBAL
int image;
PRIVATE proc;
BEGIN
proc = Inic();
LOOP
proc = CreateSnow();
proc = MoveSnow();
FRAME;
END
END

PROCESS Inic()
PRIVATE
int colors[12];
BEGIN
colors[0] = 0;
colors[1] = 0;
colors[2] = 0;
colors[3] = 127;
colors[4] = 127;
colors[5] = 127;
colors[6] = 255;
colors[7] = 255;
colors[8] = 255;
colors[9] = 255;
colors[10] = 255;
colors[11] = 255;
SET_MODE(320, 240, MODE_8BITS);
SET_FPS(0, 3);
SET_COLORS(0, 4, &colors);
image = LOAD_PNG("images\fjsantos.png");
END

PROCESS CreateSnow()
PRIVATE
int i;
BEGIN
FOR(i = 0; i < 10; i++)
MAP_PUT_PIXEL(0, image, RAND(0, 319), 0, 2);
END
END

PROCESS MoveSnow()
PRIVATE
int i, j, pixel, r;
BEGIN
FOR(j = 239; j >= 0; j--)
FOR(i = 0; i < 320; i++)
pixel = MAP_GET_PIXEL(0, image, i, j);
SWITCH(pixel)
CASE 0:
END
CASE 2:
IF(((i > 0 && MAP_GET_PIXEL(0, image, i - 1, j + 1) == 3) || i == 0) && MAP_GET_PIXEL(0, image, i, j + 1) == 3 && ((i < 319 && MAP_GET_PIXEL(0, image, i + 1, j + 1) == 3) || i == 319))
MAP_PUT_PIXEL(0, image, i, j, 3);
ELSE
r = RAND(-1, 1);
IF(MAP_GET_PIXEL(0, image, i + r, j + 1) < 2)
IF(MAP_GET_PIXEL(0, image, i, j) == 2)
MAP_PUT_PIXEL(0, image, i, j, 0);
END
IF(j + 1 == 239)
MAP_PUT_PIXEL(0, image, i, j, 3);
END
IF(i + r > 319 || i + r < 0)
MAP_PUT_PIXEL(0, image, i, j + 1, 2);
ELSE
MAP_PUT_PIXEL(0, image, i + r, j + 1, 2);
END
END
END
END
END
END
END
PUT_SCREEN(0, image);
END

Drumpi
21/12/2007, 18:28
Buenas Drumpi.

Tienes toda la raz&#243;n, debe de ponerse SET_FPS(0, 0), para conseguir la m&#225;xima velocidad, (estaba pensando en la m&#225;xima de los cl&#225;sicos 60 fps por segundo).
Bueno, he probado lo que me recomiendas SET_FPS(0, 3) y sigue bastante mal de frames. (En realidad no he notado ning&#250;n cambio).
Con respecto si hay mucha diferencia entre Fenix y SDL, (supongo que te refieres a programaci&#243;n), pues por lo poco que llevo visto, a parte de la metodolog&#237; ade programaci&#243;n que usa (que ya es bastante diferente), se echan muchas de menos de las comodidades de Fenix en SDL. Hay bastantes m&#233;todos para implementar que en Fenix ya vienen de serie. A parte de esto, el SDL al ser c, da mucha m&#225;s flexibilidad y madurez en el lenguaje, y aunque no lo conozcas, puedes tirar de los conocimientos de c de toda la vida (librer&#237;as cl&#225;sicas como math.h, time.h, etc).
Eso s&#237;, Fenix para mi gusto, es m&#225;s sencillo y c&#243;modo, pero como veo, para algunas cosas carece de velocidad.
Con respecto a si se podr&#237;a portar, creo que no soy el m&#225;s indicado para contestar a una pregunta as&#237;.

Chipan, estoy deseando ver ese efecto 3d utilizando el buffer de pantalla!

Bueno voy a ver si posteo al fin, uno de los efectos de p&#237;xeles que tengo programado.

Un saludo, fjsantos.


Bueno, tendr&#233; que re-aprender c++, que hace ya A&#209;OS que no lo cojo... y tampoco es que me ense&#241;asen mucho (soy teleco, no inform&#225;tico :P). Obviamente no espero tener un scroll o las funciones con strings, pero si las funciones b&#225;sicas de dibujado, &#191;carga de imagenes en memoria? y el tema de sonido y teclado.
Respecto a set_fps, es l&#243;gico, solo te ir&#237;a m&#225;s r&#225;pido si le sobrase tiempo para representar las 60 im&#225;genes por segundo, solo supon&#237;a que, a lo mejor, internamente, deja de comprobar si ya ha pasado el tiempo, y as&#237; ara&#241;as alg&#250;n herzio m&#225;s (&#191;herzio se escribe con c o con z?)
Una cosa m&#225;s que se me ha ocurrido: tu dibujas sobre toda la pantalla &#191;no? quiz&#225;s te convenga desactivar el dump y el restore para forzar el refresco de toda la pantalla, de otra forma creo que gasta algo de tiempo en calcular que tiene que repintar toda la pantalla secci&#243;n por secci&#243;n. Se hace as&#237;:

dump_type=1;
restore_type=1;

Procura hacerlo antes del set_fps, a ver si as&#237; ganas algun frame extra.
Otra cosilla m&#225;s: crear y destruir procesos es algo costoso en recursos, trata de evitarlo; manten los procesos create_snow y move_snow vivos en paralelo, mete su c&#243;digo interno en un bucle y haz frame antes de volver al principio, y que el main solo haga frame.
Y tampoco necesitas guardar el id de los procesos al llamarlos obligatoriamente, te puedes ahorrar el "proc="

fjsantos
22/12/2007, 12:54
Buenas Drumpi.

Te agradezco mucho tus aportaciones sobre le c&#243;digo.
He probado todo lo que me comentabas. He forzado el Dump y el Restore a pintar toda la pantalla, y adem&#225;s he mantenido los procesos CreateSnow y MoveSnow vivos y en paralelo, creando un bucle en ellos y ejecutando Frame (al mismo tiempo he ejecutado Frame en el principal).
El resultado por desgracia es el mismo, a simple vista, no percibo ning&#250;n cambio en lo que respecta a velocidad.
En fin, parece que este tipo de efectos estan reservados para las SDL y el c o c++.

Un saludo, fjsantos.

pd->Yo herzio lo escribo con z, pero es una de esas cosas de las que nunca se est&#225; seguro.

Drumpi
22/12/2007, 18:20
Nada, para eso estamos. Ya que no programo, por lo menos ofrezco ayuda, algo hay que aportar :P
Se me ocurre que se podr&#237;a probar el c&#243;digo sin usar put_pixel, a base de crear un proceso por copo de nieve, aunque un n&#250;mero excesivo de procesos puede ralentizar la m&#225;quina.

fjsantos
23/12/2007, 12:33
Buenos d&#237;as Drumpi.

Aunque, en esta ocasi&#243;n, no he probado lo que me comentas, creo que en este caso, se ralentizar&#237;a la m&#225;quina bastante ya que estamos hablando de (10 p&#237;xeles en movimiento por l&#237;nea horizontal, multiplicado por 240 l&#237;neas), o lo que es lo mismo 2400 procesos que muevan cada uno su propio p&#237;xel. (lo cual, como bien comentas, es inviable).

Lo &#250;nico que se me ocurre, es crear una dll en SDL que bloquee el buffer, pinte el p&#237;xel y lo desbloquee, pero claro, ya eso ser&#237;a utilizar SDL.

En fin, te agradezco todo el esfuerzo e ideas que ofreces d&#237;a a d&#237;a, a ver si desempolvas tus conocimientos de c o c++ y te animas a realizar algo :).

Un saludo, fjsantos.