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 preferir al_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.

Si el post ha sido de tu agrado te invito a que me sigas para saber cuando haya escrito un nuevo post, haya actualizado algún sistema o publicado un nuevo software. Facebook | X | Instagram | Telegram | También estoy a tus órdenes para cualquier contratación en mi página de contacto