Hoy quiero contarte un error muy extraño que me ocurrió al programar con Allegro 5 y C.
Allegro 5 no dibuja bitmap
El problema era que yo invocaba a al_draw_scaled_bitmap
y no se dibujaba ninguna imagen pero tampoco se mostraba
ningún error, ni un segmentation fault. Tampoco servía al_draw_bitmap
. No había ningún error y todo lo demás funcionaba
perfectamente (dibujaba rectángulos con al_draw_filled_rectangle
, tenía timers, eventos y todo iba perfecto),
simplemente las imágenes no se estaban dibujando.
Esto no sería raro si no fuera porque en otra computadora que tengo sí funcionaba, pero al clonar el repositorio en la segunda PC me comenzó a aparecer este problema.
Obviamente ya había revisado y probado lo siguiente:
- Rutas de imágenes
- Formato de imágenes. Primero intenté con PNG, luego JPG y finalmente BMP
- Que
al_load_bitmap
no devolviera un puntero nulo - Que
al_init_image_addon
no devolviera false - No usar
al_draw_scaled_bitmap
y preferiral_draw_bitmap
- Cambiar el tamaño de las imágenes
Y te repito: ese mismo código funcionaba en otra PC. El compilador tampoco se quejó ni mostró errores.
Solución
Solucionar un error cuando el compilador o programa te lo indican es más fácil que solucionarlo cuando nadie te dice nada sobre el error y simplemente las cosas no funcionan.
El problema es que yo cargaba las imágenes antes de invocar a al_create_display
. Es decir,
tenía mi función main
y se veía así de manera simplificada:
al_init();
al_init_primitives_addon();
al_install_keyboard();
// Cargo las imágenes e inicializo la librería de imagen
if (!al_init_image_addon())
{
fprintf(stderr, "Error inicializando librería imagen");
}
ALLEGRO_BITMAP *imagen_pieza_caida = NULL;
ALLEGRO_BITMAP *imagen_pieza_movimiento = NULL;
imagen_pieza_caida = al_load_bitmap("bitmap.png");
if (!imagen_pieza_caida)
{
fprintf(stderr, "Error cargando imagen");
}
imagen_pieza_movimiento = al_load_bitmap("2.png");
if (!imagen_pieza_movimiento)
{
fprintf(stderr, "Error cargando imagen");
}
// Y ya después de todo, invoco a `al_create_display`
al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);
al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
// Aquí se configura el tamaño de la pantalla
ALLEGRO_DISPLAY *disp = al_create_display((MEDIDA_CUADRO * ANCHO_CUADRICULA * BITS_EN_UN_BYTE) + OFFSET_X, (ALTO_CUADRICULA * MEDIDA_CUADRO) + GROSOR_BORDE * 2);
ALLEGRO_FONT *font = al_create_builtin_font();
Fíjate en que estoy invocando a al_create_display
y al_set_new_*
después de al_load_bitmap
. Eso es lo que causaba el problema.
La solución fue mover esas líneas casi al inicio, un poco abajo de al_init
así:
int main()
{
srand(time(NULL));
al_init();
al_init_primitives_addon();
al_install_keyboard();
al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);
al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
// Aquí se configura el tamaño de la pantalla
ALLEGRO_DISPLAY *disp = al_create_display((MEDIDA_CUADRO * ANCHO_CUADRICULA * BITS_EN_UN_BYTE) + OFFSET_X, (ALTO_CUADRICULA * MEDIDA_CUADRO) + GROSOR_BORDE * 2);
ALLEGRO_FONT *font = al_create_builtin_font();
// Aquí el resto del código como al_load_bitmap y al_init_image_addon
}
Puede que el error suene obvio pero el compilador ni allegro se quejaron en ningún momento. Yo no me di cuenta
de que estaba cargando las imágenes antes de invocar a al_create_display
, y pude
notar el problema al comparar las direcciones de memoria (printf
con %p
) de los
búfers donde se estaban dibujando las imágenes.
Así que imagino que lo que pasó es que las imágenes se estaban dibujando en otro lugar o búfer, pero sigue sin quedarme claro por qué en la otra PC no me ocurrió este error.
Puedes ver el commit en el repositorio del juego en donde me ocurrió este problema.