class problem/ drawing pixels A5
verthex

The code below doesn't draw anything and I can't use ESC or close the window to exit. The drawing function is inside a class but that shouldn't be a problem. If I comment out line 91 in the 1st block of code everything works fine?

#SelectExpand
1#include <stdio.h> 2#include <allegro5/allegro.h> 3#include <allegro5/allegro_primitives.h> 4#include <allegro5/allegro_font.h> 5#include <allegro5/allegro_ttf.h> 6#include "some_class.h" 7 8const float FPS = 30; 9 10int main(int argc, char **argv) 11{ 12 int screen_width = 640; 13 int screen_height = 480; 14 15 some_class *the_class = new some_class(screen_width, screen_height); 16 17 ALLEGRO_DISPLAY *display = NULL; 18 ALLEGRO_BITMAP *bitmap = NULL; 19 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 20 ALLEGRO_TIMER *timer = NULL; 21 ALLEGRO_FONT *ttf_font; 22 23 bool exit = false; 24 25 if(!al_init()) 26 { 27 fprintf(stderr, "failed to initialize allegro!\n"); 28 return -1; 29 } 30 31 timer = al_create_timer(1.0 / FPS); 32 if(!timer) 33 { 34 fprintf(stderr, "failed to create timer!\n"); 35 return -1; 36 } 37 38 39 40 display = al_create_display(screen_width, screen_height); 41 42 if(!display) 43 { 44 fprintf(stderr, "failed to create display!\n"); 45 al_destroy_timer(timer); 46 return -1; 47 } 48 49 if (!al_init_primitives_addon()) 50 { 51 fprintf(stderr, "failed to initiialize primitives addon!\n"); 52 return -1; 53 } 54 55 if(!al_install_keyboard()) 56 { 57 fprintf(stderr, "failed to initialize the keyboard!\n"); 58 return -1; 59 } 60 61 event_queue = al_create_event_queue(); 62 63 if(!event_queue) 64 { 65 fprintf(stderr, "failed to create event_queue!\n"); 66 al_destroy_display(display); 67 al_destroy_timer(timer); 68 return -1; 69 } 70 71 al_register_event_source(event_queue, al_get_keyboard_event_source()); 72 al_register_event_source(event_queue, al_get_display_event_source(display)); 73 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 74 75 al_clear_to_color(al_map_rgb(0,0,0)); 76 77 al_flip_display(); 78 al_start_timer(timer); 79 80 bool redraw = true; 81 82 while(!exit) 83 { 84 85 ALLEGRO_EVENT ev; 86 al_wait_for_event(event_queue, &ev); 87 88 if (redraw) 89 { 90 91 the_class->draw(); 92 93 al_flip_display(); 94 redraw = false; 95 } 96 if(ev.type == ALLEGRO_EVENT_TIMER) 97 { 98 redraw = true; 99 } 100 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 101 { 102 exit = true; 103 break; 104 } 105 if(al_is_event_queue_empty(event_queue)) 106 { 107 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 108 { 109 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 110 { 111 exit = true; 112 break; 113 } 114 } 115 } 116 } 117 118 al_destroy_timer(timer); 119 al_destroy_display(display); 120 al_destroy_event_queue(event_queue); 121 122 delete the_class; 123 124 return 0; 125}

#SelectExpand
1#ifndef SOME_CLASS_H 2#define SOME_CLASS_H 3 4#include <allegro5/allegro.h> 5#include <allegro5/allegro_primitives.h> 6 7class some_class 8{ 9 private: 10 11 int SCREEN_HEIGHT_Y; 12 int SCREEN_WIDTH_X; 13 ALLEGRO_COLOR COLOR_WHITE; 14 15 public: 16 17 some_class(){} 18 ~some_class(){} 19 some_class(int sw, int sh) 20 { 21 SCREEN_HEIGHT_Y = sh; 22 SCREEN_WIDTH_X = sw; 23 COLOR_WHITE = al_map_rgb(0,0,255); 24 } 25 void draw() 26 { 27 for(int y = 0; y < SCREEN_HEIGHT_Y; y++) 28 { 29 for(int x = 0; x < SCREEN_WIDTH_X; x++) 30 { 31 al_draw_pixel(x, y, COLOR_WHITE); 32 } 33 } 34 } 35}; 36#endif

kazzmir

Its probably working but draw_pixel on a hardware surface is ultra slow. You should lock it, which downloads the surface to memory, then operate it and finally unlock it.

al_lock_bitmap(al_get_target_bitmap(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE);
al_putpixel(...);
al_unlock_bitmap(al_get_target_bitmap());

Something like that. Also you should lock/unlock outside the for loop.

verthex

I changed it to the following and its still the same (in terms of problems). Its supposed to draw white pixels... no?

#SelectExpand
1#ifndef SOME_CLASS_H 2#define SOME_CLASS_H 3 4#include <allegro5/allegro.h> 5#include <allegro5/allegro_primitives.h> 6 7class some_class 8{ 9 private: 10 11 int SCREEN_HEIGHT_Y; 12 int SCREEN_WIDTH_X; 13 ALLEGRO_COLOR COLOR_WHITE; 14 15 public: 16 17 some_class(){} 18 ~some_class(){} 19 some_class(int sw, int sh) 20 { 21 SCREEN_HEIGHT_Y = sh; 22 SCREEN_WIDTH_X = sw; 23 COLOR_WHITE = al_map_rgb(255,255,255); 24 } 25 void draw() 26 { 27 al_lock_bitmap(al_get_target_bitmap(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE); 28 for(int y = 0; y < SCREEN_HEIGHT_Y; y++) 29 { 30 for(int x = 0; x < SCREEN_WIDTH_X; x++) 31 { 32 al_draw_pixel(x, y, COLOR_WHITE); 33 } 34 } 35 al_unlock_bitmap(al_get_target_bitmap()); 36 } 37}; 38#endif

EDIT: Things get even weirder when I place the drawing function contents into main(), it actually works. There must be something wrong with the class part?

#SelectExpand
1#include <stdio.h> 2#include <allegro5/allegro.h> 3#include <allegro5/allegro_primitives.h> 4#include <allegro5/allegro_font.h> 5#include <allegro5/allegro_ttf.h> 6#include "some_class.h" 7 8const float FPS = 30; 9 10int main(int argc, char **argv) 11{ 12 int screen_width = 320; 13 int screen_height = 200; 14 15 some_class *the_class = new some_class(screen_width, screen_height); 16 17 ALLEGRO_DISPLAY *display = NULL; 18 ALLEGRO_BITMAP *bitmap = NULL; 19 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 20 ALLEGRO_TIMER *timer = NULL; 21 ALLEGRO_FONT *ttf_font; 22 23 bool exit = false; 24 25 if(!al_init()) 26 { 27 fprintf(stderr, "failed to initialize allegro!\n"); 28 return -1; 29 } 30 31 timer = al_create_timer(1.0 / FPS); 32 if(!timer) 33 { 34 fprintf(stderr, "failed to create timer!\n"); 35 return -1; 36 } 37 38 39 40 display = al_create_display(screen_width, screen_height); 41 42 if(!display) 43 { 44 fprintf(stderr, "failed to create display!\n"); 45 al_destroy_timer(timer); 46 return -1; 47 } 48 49 if (!al_init_primitives_addon()) 50 { 51 fprintf(stderr, "failed to initiialize primitives addon!\n"); 52 return -1; 53 } 54 55 if(!al_install_keyboard()) 56 { 57 fprintf(stderr, "failed to initialize the keyboard!\n"); 58 return -1; 59 } 60 61 event_queue = al_create_event_queue(); 62 63 if(!event_queue) 64 { 65 fprintf(stderr, "failed to create event_queue!\n"); 66 al_destroy_display(display); 67 al_destroy_timer(timer); 68 return -1; 69 } 70 71 al_register_event_source(event_queue, al_get_keyboard_event_source()); 72 al_register_event_source(event_queue, al_get_display_event_source(display)); 73 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 74 75 al_clear_to_color(al_map_rgb(0,0,0)); 76 77 al_flip_display(); 78 al_start_timer(timer); 79 80 bool redraw = true; 81 82 int SCREEN_HEIGHT_Y; 83 int SCREEN_WIDTH_X; 84 ALLEGRO_COLOR COLOR_WHITE; 85 SCREEN_HEIGHT_Y = 200; 86 SCREEN_WIDTH_X = 320; 87 COLOR_WHITE = al_map_rgb(255,255,255); 88 89 while(!exit) 90 { 91 92 ALLEGRO_EVENT ev; 93 al_wait_for_event(event_queue, &ev); 94 95 if (redraw) 96 { 97 98 //the_class->draw(); 99 100 al_lock_bitmap(al_get_target_bitmap(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE); 101 for(int y = 0; y < SCREEN_HEIGHT_Y; y++) 102 { 103 for(int x = 0; x < SCREEN_WIDTH_X; x++) 104 { 105 al_draw_pixel(x, y, COLOR_WHITE); 106 } 107 } 108 al_unlock_bitmap(al_get_target_bitmap()); 109 110 111 al_flip_display(); 112 redraw = false; 113 } 114 if(ev.type == ALLEGRO_EVENT_TIMER) 115 { 116 redraw = true; 117 } 118 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 119 { 120 exit = true; 121 break; 122 } 123 if(al_is_event_queue_empty(event_queue)) 124 { 125 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 126 { 127 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 128 { 129 exit = true; 130 break; 131 } 132 } 133 } 134 } 135 136 al_destroy_timer(timer); 137 al_destroy_display(display); 138 al_destroy_event_queue(event_queue); 139 140 delete the_class; 141 142 return 0; 143}

Polybios

It works for me if the class constructor is called after al_init. Maybe al_map_rgb doesn't work before that is called.

As for the input, my impression was that the event queue is flooded with timer events because drawing is still too slow.

SiegeLord
Polybios said:

It works for me if the class constructor is called after al_init. Maybe al_map_rgb doesn't work before that is called.

This is correct. al_map_rgb and the like use a lookup table that is initialized in al_init.

verthex

I moved the class constructor right up before the game loop like so and it works now.

#SelectExpand
1 2some_class *the_class = new some_class(screen_width, screen_height); 3 4 while(!exit) 5 { 6 7 ALLEGRO_EVENT ev; 8 al_wait_for_event(event_queue, &ev); 9 10 if (redraw) 11 { 12 the_class->draw(); 13 al_flip_display(); 14 redraw = false; 15 } 16 if(ev.type == ALLEGRO_EVENT_TIMER) 17 { 18 redraw = true; 19 } 20 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 21 { 22 exit = true; 23 break; 24 } 25 if(al_is_event_queue_empty(event_queue)) 26 { 27 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 28 { 29 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 30 { 31 exit = true; 32 break; 33 } 34 } 35 } 36 }

Thread #608093. Printed from Allegro.cc