|
Images from buffer |
CodeStepper
Member #14,495
August 2012
|
How to load images from buffer in allegro5? Or something like this, because i don't know even how to display this :/ I've got this code: 1#include <ft2build.h>
2#include FT_FREETYPE_H
3
4#include <allegro5/allegro.h>
5
6#include <iostream>
7#include <fstream>
8
9int main( void )
10{
11 FT_Library library;
12 FT_Face face;
13
14 FT_Init_FreeType( &library );
15 FT_New_Face( library, "DejaVuSans.ttf", 0, &face );
16
17 FT_Set_Char_Size( face, 0, 16 * 64, 300, 300 );
18 FT_Set_Pixel_Sizes( face, 0, 16 );
19
20 FT_GlyphSlot slot = face->glyph;
21
22 FT_UInt gindex = FT_Get_Char_Index( face, 'W' );
23 FT_Load_Glyph( face, gindex, FT_LOAD_NO_BITMAP );
24 FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
25
26 al_init( );
27 ALLEGRO_DISPLAY *display = al_create_display( 800, 600 );
28
29 // slot->bitmap.buffer; ?? How to draw it in display?
30
31 al_flip_display( );
32
33 getchar( );
34
35 al_destroy_display( display );
36 return 0;
37}
You could tell me, that is allegro_font extension... ( EXAMPLE ) [WITH SPACES] A B C D E F G [NO SPACES] ABCDEFG Please, help |
AMCerasoli
Member #11,955
May 2010
|
What are you trying to say is that you want to use FreeType directly because the Allegro Font addon is slow when you draw text with spaces?
|
CodeStepper
Member #14,495
August 2012
|
Yes With spacing, example, between letters is 10px space, |
AMCerasoli
Member #11,955
May 2010
|
Well, then it's true, it's better if you find a way to use FreeType directly. I don't know how to do it, though. I have never heard this particular problem with spaces, but indeed Allegro has some problems when drawing fonts. There is a way to cache the text you want to draw before drawing it, that should make everything faster but it's a hacky (not elegant) way of doing it. It's a real hack: you just have to draw the text before using it... Yep take the drawing function and draw all the characters and numbers of your alphabet, after that, it should be faster... Instead of drawing, you can also use the al_get_text_width() function. Do something like this: al_get_text_width(font, "abcdefghijklmnñopqrstuvw123456789ABCDEFGHIJKLMNÑOPQRSTUW,.:;"); That should improve a bit. But If you're having problems with spaces... I really don't know... Now, I know this may sound a little bit crazy, but at the same time if you're experiencing too much lag when drawing fonts using Allegro, it's because you're using text a lot, so for that reason it might be better to use SFML since it handles better the font drawing operations. Because I don't know, using FreeType directly doesn't sound like a good idea to me. Edit: Have you created the font before or after creating the display?
|
CodeStepper
Member #14,495
August 2012
|
Thank you for your answer AMCerasoli said: you just have to draw the text before using it
Yes, i now it... 1if( this->hspacing == 0 )
2{
3 if( text_width > this->length ) text_width = this->length - text_width;
4 else if( this->halign == ALIGN_TO_LEFT ) text_width = 0;
5 else if( this->halign == ALIGN_TO_RIGHT ) text_width = this->length - text_width;
6 else text_width = this->length / 2 - text_width / 2;
7
8 al_draw_ustr( font, al_map_rgb( 90, 90, 90 ), text_width, text_height, 0, this->text );
9}
10else
11{
12 std::string stext = al_cstr( this->text );
13 std::string sbytes = al_cstr( this->bytes );
14 this->bcolumn = 0;
15
16 if( text_width + ( this->column * this->hspacing ) > this->length )
17 {
18 text_width = this->length - text_width - ( this->column * this->hspacing );
19 }
20 else if( this->halign == ALIGN_TO_LEFT ) text_width = 0;
21 else if( this->halign == ALIGN_TO_RIGHT ) text_width = this->length - text_width;
22 else text_width = this->length / 2 - text_width / 2;
23
24 unsigned short B = sbytes.size( );
25 for( unsigned short A = 0; A < B; ++A )
26 {
27 al_draw_text( font, al_map_rgb( 90, 90, 90 ),
28 text_width + al_get_text_width( font, stext.substr( 0, this->bcolumn ).c_str( ) ) + ( A * this->hspacing ),
29 text_height, 0,
30 stext.substr( this->bcolumn, sbytes[A] ).c_str( ) );
31 this->bcolumn += sbytes[A];
32 }
33}
IF no spacing From my provisional input hmm... I could use sfml, as you say, but I like allegro If you want to test this, have it: CPP BInput.cpp 1// Copyright by CodeStepper
2#pragma once
3#include "BInput.hpp"
4
5BInput::BInput( unsigned short x, unsigned short y, unsigned short width, unsigned short height )
6{
7 this->start_x = x;
8 this->start_y = y;
9 this->stop_x = width + x;
10 this->stop_y = height + y;
11
12 this->c_width = width;
13 this->c_height = height;
14
15 this->column = 0;
16 this->bcolumn = 0;
17 this->blink_pos = 0;
18
19 this->length = width - 20;
20 this->halign = ALIGN_TO_LEFT;
21 this->valign = ALIGN_TO_CENTER;
22 this->left_shift = 10;
23 this->top_shift = 0;
24
25 this->insert = true;
26 this->working = false;
27 this->afterwork = false;
28
29 this->vspacing = 0;
30 this->hspacing = 0;
31
32 this->text = al_ustr_new( "" );
33 this->bytes = al_ustr_new( "" );
34 this->view = al_create_bitmap( width - 20, height );
35}
36
37
38BInput::~BInput( void )
39{
40 al_ustr_free( this->text );
41 al_ustr_free( this->bytes );
42 al_destroy_bitmap( this->view );
43}
44
45
46void BInput::captureChar( ALLEGRO_KEYBOARD_EVENT key, ALLEGRO_FONT *font, ALLEGRO_DISPLAY *display )
47{
48 bool change = true;
49 if( key.unichar > 31 && key.unichar != 127 )
50 {
51 ALLEGRO_USTR *unicode = al_ustr_new( "" );
52 al_ustr_append_chr( unicode, key.unichar );
53
54 if( this->insert )
55 {
56 al_ustr_insert( this->text, this->bcolumn, unicode );
57 al_ustr_insert_chr( this->bytes, this->column, al_ustr_size( unicode ) );
58 }
59 else
60 {
61 al_ustr_replace_range( this->text, this->bcolumn, this->bcolumn + al_ustr_get( this->bytes, column ), unicode );
62 al_ustr_set_chr( this->bytes, this->column, al_ustr_size( unicode ) );
63 }
64
65 this->bcolumn += al_ustr_get( this->bytes, column );
66 this->column++;
67
68 al_ustr_free( unicode );
69 }
70 else
71 {
72 switch( key.keycode )
73 {
74 case ALLEGRO_KEY_BACKSPACE:
75 if( this->column > 0 )
76 {
77 this->column--;
78 this->bcolumn -= al_ustr_get( this->bytes, column );
79
80 al_ustr_remove_range( this->text, this->bcolumn, this->bcolumn + al_ustr_get( this->bytes, column ) );
81 al_ustr_remove_chr( this->bytes, this->column );
82 }
83 break;
84 default: change = false;
85 }
86 }
87
88 //////////////////////////////////////////////////////////////////////////
89 if( change )
90 {
91 short text_width = al_get_ustr_width( font, this->text ),
92 text_height = 0;
93
94 if( this->valign == ALIGN_TO_TOP ) text_height = 0;
95 else if( this->valign == ALIGN_TO_BOTTOM ) text_height = this->c_height - al_get_font_line_height( font );
96 else text_height = this->c_height / 2 - al_get_font_line_height( font ) / 2;
97
98 al_set_target_bitmap( this->view );
99 al_clear_to_color( al_map_rgba( 0, 0, 0, 0 ) );
100
101 if( this->hspacing == 0 )
102 {
103 if( text_width > this->length ) text_width = this->length - text_width;
104 else if( this->halign == ALIGN_TO_LEFT ) text_width = 0;
105 else if( this->halign == ALIGN_TO_RIGHT ) text_width = this->length - text_width;
106 else text_width = this->length / 2 - text_width / 2;
107
108 al_draw_ustr( font, al_map_rgb( 90, 90, 90 ), text_width, text_height, 0, this->text );
109 }
110 else
111 {
112 std::string stext = al_cstr( this->text );
113 std::string sbytes = al_cstr( this->bytes );
114 this->bcolumn = 0;
115
116 if( text_width + ( this->column * this->hspacing ) > this->length )
117 {
118 text_width = this->length - text_width - ( this->column * this->hspacing );
119 }
120 else if( this->halign == ALIGN_TO_LEFT ) text_width = 0;
121 else if( this->halign == ALIGN_TO_RIGHT ) text_width = this->length - text_width;
122 else text_width = this->length / 2 - text_width / 2;
123
124 unsigned short B = sbytes.size( );
125 for( unsigned short A = 0; A < B; ++A )
126 {
127 al_draw_text( font, al_map_rgb( 90, 90, 90 ),
128 text_width + al_get_text_width( font, stext.substr( 0, this->bcolumn ).c_str( ) ) + ( A * this->hspacing ),
129 text_height, 0,
130 stext.substr( this->bcolumn, sbytes[A] ).c_str( ) );
131 this->bcolumn += sbytes[A];
132 }
133 }
134
135 al_set_target_bitmap( al_get_backbuffer( display ) );
136
137 this->working = true;
138 this->afterwork = true;
139 }
140}
141
142/////////////////////
143void BInput::display( ALLEGRO_FONT *font )
144{
145 al_draw_filled_rectangle( this->start_x, this->start_y, this->stop_x, this->stop_y, al_map_rgb( 170, 170, 170 ) );
146 al_draw_filled_rectangle( this->start_x + 1, this->start_y + 1, this->stop_x - 1, this->stop_y - 1, al_map_rgb( 230, 230, 230 ) );
147 al_draw_bitmap( this->view, this->start_x + this->left_shift, this->start_y + this->top_shift, 0 );
148
149 if( this->working )
150 {
151 unsigned short reaper = ( this->column ) ? this->hspacing / 2 : 1;
152 this->blink_pos = this->start_x + this->left_shift + al_get_ustr_width( font, this->text ) + ( this->column * this->hspacing ) -
153 reaper;
154
155 if( this->blink_pos > this->start_x + this->length + this->left_shift )
156 this->blink_pos = this->start_x + this->length + this->left_shift;
157
158 this->working = false;
159 }
160 if( this->blink_pos )
161 {
162 al_draw_filled_rectangle
163 (
164 this->blink_pos,
165 this->start_y + this->c_height / 2 - al_get_font_line_height( font ) / 2 - this->vspacing,
166 this->blink_pos + 1,
167 this->start_y + this->c_height / 2 + al_get_font_line_height( font ) / 2 + this->vspacing,
168 al_map_rgb( 90, 90, 90 )
169 );
170 }
171}
172
173void BInput::blinker( ALLEGRO_FONT *font )
174{
175 if( !this->working )
176 {
177 unsigned short reaper = ( this->column ) ? this->hspacing / 2 : 1;
178 this->blink_pos = ( this->blink_pos && !this->afterwork )
179 ? 0
180 : this->start_x + this->left_shift + al_get_ustr_width( font, this->text ) + ( this->column * this->hspacing ) -
181 reaper;
182
183 if( this->blink_pos > this->start_x + this->length + this->left_shift )
184 this->blink_pos = this->start_x + this->length + this->left_shift;
185
186 this->afterwork = false;
187 }
188}
189/////////////////////
190
191void BInput::textShift( unsigned short width, char vertical_align, char horizontal_align, char top, char left )
192{
193 this->length = width;
194 this->halign = horizontal_align;
195 this->valign = vertical_align;
196 this->left_shift = left;
197 this->top_shift = top;
198}
199
200void BInput::spaceChange( char vertical_spacing, char horizontal_spacing )
201{
202 this->hspacing = horizontal_spacing;
203 this->vspacing = vertical_spacing;
204}
HEADER BInput.hpp 1// Copyright by CodeStepper
2#pragma once
3#include "BlackGUI.hpp"
4
5
6enum CONTROL_ALIGN
7{
8 ALIGN_TO_LEFT,
9 ALIGN_TO_RIGHT,
10 ALIGN_TO_CENTER,
11 ALIGN_TO_TOP,
12 ALIGN_TO_BOTTOM
13};
14
15
16class BInput : private BlackGUI
17{
18private:
19 unsigned short column;
20 unsigned short bcolumn;
21
22 unsigned short blink_pos;
23
24 unsigned short length;
25 char top_shift;
26 char left_shift;
27 char halign;
28 char valign;
29
30 char vspacing;
31 char hspacing;
32
33 bool insert;
34 bool working;
35 bool afterwork;
36
37 ALLEGRO_USTR *text;
38 ALLEGRO_USTR *bytes;
39 ALLEGRO_BITMAP *view;
40public:
41 BInput( unsigned short x, unsigned short y, unsigned short width, unsigned short height );
42 ~BInput( void );
43
44 void captureChar( ALLEGRO_KEYBOARD_EVENT key, ALLEGRO_FONT *font, ALLEGRO_DISPLAY *display );
45 void textShift( unsigned short width, char vertical_align, char horizontal_align, char top, char left );
46 void spaceChange( char vertical_spacing, char horizontal_spacing );
47
48 void display( ALLEGRO_FONT *font );
49 void blinker( ALLEGRO_FONT *font );
50};
CPP BlackGUI: 1// Copyright by CodeStepper
2#pragma once
3
4#include <allegro5/allegro.h>
5#include <allegro5/allegro_font.h>
6#include <allegro5/allegro_primitives.h>
7#include <iostream>
8
9
10class BlackGUI
11{
12protected:
13 unsigned short start_x;
14 unsigned short start_y;
15 unsigned short stop_x;
16 unsigned short stop_y;
17
18 unsigned short c_width;
19 unsigned short c_height;
20public:
21 void LoadTheme( const char *theme_name );
22 void UnloadTheme( void );
23};
HEADER BlackGUI 1#pragma once
2#include "BlackGUI.hpp"
3
4
5void BlackGUI::LoadTheme( const char *theme_name )
6{
7
8}
9
10
11void BlackGUI::UnloadTheme( void )
12{
13
14}
and of course main.cpp 1// Copyright by CodeStepper
2#include <allegro5/allegro.h>
3#include <allegro5/allegro_primitives.h>
4#include <allegro5/allegro_font.h>
5#include <allegro5/allegro_ttf.h>
6
7
8#include "BlackGUI.hpp"
9#include "BInput.hpp"
10
11
12int main( void )
13{
14 al_init( );
15 al_init_primitives_addon( );
16 al_init_font_addon( );
17 al_init_ttf_addon( );
18 al_install_keyboard( );
19
20 ALLEGRO_DISPLAY *display = al_create_display( 800, 600 );
21 ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue( );
22 ALLEGRO_TIMER *timer = al_create_timer( 1.0 / 60 );
23 ALLEGRO_FONT *font = al_load_font( "DejaVuSans.ttf", 14, 0 );
24
25 bool run = true;
26 bool redraw = true;
27 char counter = 0;
28
29 // Input allocation
30 BInput input( 50, 50, 500, 40 );
31
32 // Spacing
33 input.spaceChange( 5, 5 );
34
35 // Text shift ( blinker does not work correct now :P )
36 //input.textShift( 300, ALIGN_TO_CENTER, ALIGN_TO_CENTER, 10, 40 );
37
38 al_register_event_source( queue, al_get_keyboard_event_source( ) );
39 al_register_event_source( queue, al_get_timer_event_source( timer ) );
40 al_register_event_source( queue, al_get_display_event_source( display ) );
41
42 al_start_timer( timer );
43 while( run )
44 {
45 ALLEGRO_EVENT event;
46 al_wait_for_event( queue, &event );
47
48 if( event.type == ALLEGRO_EVENT_TIMER )
49 {
50 redraw = true;
51 }
52 else if( event.type == ALLEGRO_EVENT_KEY_UP )
53 {
54 if( event.keyboard.keycode == ALLEGRO_KEY_ESCAPE )
55 run = false;
56 }
57 else if( event.type == ALLEGRO_EVENT_KEY_CHAR )
58 {
59 input.captureChar( event.keyboard, font, display );
60 }
61
62 if( redraw && al_is_event_queue_empty( queue ) )
63 {
64 if( counter == 30 )
65 {
66 input.blinker( font );
67 counter = -1;
68 }
69 counter++;
70 redraw = false;
71
72 al_clear_to_color( al_map_rgb( 240, 240, 240 ) );
73
74 input.display( font );
75
76 al_flip_display( );
77 }
78 }
79
80 return 0;
81}
In this case i couldn't draw text before using it I minimize the CPU usage to minimum (at least I think so) If you want to help me with GUI creating, write on PM |
AMCerasoli
Member #11,955
May 2010
|
Wow. Too much code, I can't read it right now (working). Maybe this in your code but as I said I can't read it right now. How are you measuring the speed of your program?
|
CodeStepper
Member #14,495
August 2012
|
cheating only if i write something ( only if i write a lot of letters - small lag from 200, i think ), because then the function starts drawing, a picture to a bitmap, and finally a bitmap is displaying ( bitmap is changing when a letter is captured ) hmm... this code is only on copy - paste - debug My CPU is AMD Athlon 64 ( 2,4 Ghz ), so this new he is not ( I don't know, if I translate this correct ) I check usage of processor with process manager ( windows ) /// EDIT: |
AMCerasoli
Member #11,955
May 2010
|
I don't know man... I think you're not measuring the speed of your program correctly... Do you have a FPS (Frames Per Second) algorithm there? I can't see it in your code. You have your timer variable set to 60FPS, how many FPS are you getting?
|
CodeStepper
Member #14,495
August 2012
|
I have 28 when i put 400 letters This is my algorithm: 1#include <allegro5/allegro.h>
2#include <allegro5/allegro_primitives.h>
3#include <allegro5/allegro_font.h>
4#include <allegro5/allegro_ttf.h>
5
6
7#include "BlackGUI.hpp"
8#include "BInput.hpp"
9
10
11int main( void )
12{
13 al_init( );
14 al_init_primitives_addon( );
15 al_init_font_addon( );
16 al_init_ttf_addon( );
17 al_install_keyboard( );
18
19 ALLEGRO_DISPLAY *display = al_create_display( 800, 600 );
20 ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue( );
21 ALLEGRO_TIMER *timer = al_create_timer( 1.0 / 60 );
22 ALLEGRO_FONT *font = al_load_font( "DejaVuSans.ttf", 14, 0 );
23
24 bool run = true;
25 bool redraw = true;
26 char counter = 0;
27
28// Here ------
29 float cout = 0;
30 float bp = 0;
31// -------
32 // Input allocation
33 BInput input( 50, 50, 500, 40 );
34
35 // Spacing
36 input.spaceChange( 5, 5 );
37
38 al_register_event_source( queue, al_get_keyboard_event_source( ) );
39 al_register_event_source( queue, al_get_timer_event_source( timer ) );
40 al_register_event_source( queue, al_get_display_event_source( display ) );
41
42 al_start_timer( timer );
43 while( run )
44 {
45 ALLEGRO_EVENT event;
46 al_wait_for_event( queue, &event );
47
48 if( event.type == ALLEGRO_EVENT_TIMER )
49 {
50 redraw = true;
51 }
52 else if( event.type == ALLEGRO_EVENT_KEY_UP )
53 {
54 if( event.keyboard.keycode == ALLEGRO_KEY_ESCAPE )
55 run = false;
56 }
57 else if( event.type == ALLEGRO_EVENT_KEY_CHAR )
58 {
59 input.captureChar( event.keyboard, font, display );
60 }
61
62 if( redraw && al_is_event_queue_empty( queue ) )
63 {
64// And here ----------------------------
65 if( al_get_time( ) - bp < 1 )
66 {
67 cout++;
68 }
69 else
70 {
71 std::cout << cout;
72 cout = 0;
73 bp = al_get_time( );
74 }
75// ------------------------------------
76 if( counter == 30 )
77 {
78 input.blinker( font );
79 counter = -1;
80 }
81 counter++;
82 redraw = false;
83
84 al_clear_to_color( al_map_rgb( 240, 240, 240 ) );
85
86 input.display( font );
87
88 al_flip_display( );
89 }
90 }
91
92 return 0;
93}
|
AMCerasoli
Member #11,955
May 2010
|
Now I see... Your problem is in here: 1 std::string stext = al_cstr( this->text );
2 std::string sbytes = al_cstr( this->bytes );
3 this->bcolumn = 0;
4
5 if( text_width + ( this->column * this->hspacing ) > this->length )
6 {
7 text_width = this->length - text_width - ( this->column * this->hspacing );
8 }
9 else if( this->halign == ALIGN_TO_LEFT ) text_width = 0;
10 else if( this->halign == ALIGN_TO_RIGHT ) text_width = this->length - text_width;
11 else text_width = this->length / 2 - text_width / 2;
12
13 unsigned short B = sbytes.size( );
14 al_draw_ustr( font, al_map_rgb( 90, 90, 90 ), text_width, text_height, 0, this->text );
15 for( unsigned short A = 0; A < B; ++A )
16 {
17 al_draw_text( font, al_map_rgb( 90, 90, 90 ),
18 text_width + al_get_text_width( font, stext.substr( 0, this->bcolumn ).c_str( ) ) + ( A * this->hspacing ),
19 text_height, 0,
20 stext.substr( this->bcolumn, sbytes[A] ).c_str( ) );
21 this->bcolumn += sbytes[A];
22 }
23 }
But more precisely here: for( unsigned short A = 0; A < B; ++A ) { al_draw_text( font, al_map_rgb( 90, 90, 90 ), text_width + al_get_text_width( font, stext.substr( 0, this->bcolumn ).c_str( ) ) + ( A * this->hspacing ), text_height, 0, stext.substr( this->bcolumn, sbytes[A] ).c_str( ) ); this->bcolumn += sbytes[A]; } That is what is causing the lag when appending new characters and not when drawing them. If FreeType allows you to set the character spacing then it could help you. I don't know, have you tried creating the ALLEGRO_BITMAP from a file using al_load_bitmap_f()? You could try to load the FreeType bitmap into an ALLEGRO_FILE struct, and then use the function I just mentioned to create an ALLEGRO_BITMAP. But I'm not sure if that bitmap will be a video bitmap or a memory bitmap.
|
CodeStepper
Member #14,495
August 2012
|
Thank you for your answer. I try to write what you said, but it's not working :/ 1#include <ft2build.h>
2#include FT_FREETYPE_H
3
4#include <allegro5/allegro.h>
5#include <allegro5/allegro_memfile.h>
6
7#include <iostream>
8#include <fstream>
9
10int main( void )
11{
12 FT_Library library;
13 FT_Face face;
14
15 FT_Init_FreeType( &library );
16 FT_New_Face( library, "DejaVuSans.ttf", 0, &face );
17
18 FT_Set_Char_Size( face, 0, 16 * 64, 300, 300 );
19 FT_Set_Pixel_Sizes( face, 0, 16 );
20
21 FT_GlyphSlot slot = face->glyph;
22
23 FT_UInt gindex = FT_Get_Char_Index( face, 'W' );
24 FT_Load_Glyph( face, gindex, FT_LOAD_NO_BITMAP );
25 FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
26
27 al_init( );
28
29// Opening memfile ( am I doing this right? )
30 ALLEGRO_FILE *file = al_open_memfile( slot->bitmap.buffer, sizeof( slot->bitmap.buffer ), "r" );
31// Loading bitmap font
32 ALLEGRO_BITMAP *fontft = al_load_bitmap_f( file, ".png" );
33
34 ALLEGRO_DISPLAY *display = al_create_display( 800, 600 );
35
36 al_clear_to_color( al_map_rgb( 50, 50, 120 ) );
37// This doesn't working
38 al_draw_bitmap( fontft, 50, 50, 0 );
39 al_flip_display( );
40
41 getchar( );
42
43 al_destroy_display( display );
44 return 0;
45}
Error in CMD: Assertion failed: bitmap, file allegro-5.0.x\src\bitmap.c, line 315
|
Thomas Fjellstrom
Member #476
June 2000
|
Quote: sizeof( slot->bitmap.buffer ) You can't get the size of dynamically allocated arrays like that. You'll need to find where FreeType stores the actual size of that array. -- |
CodeStepper
Member #14,495
August 2012
|
I am looking, looking and I don't see anything... Maybe I try something else, because because i don't see any sense at this time to loading this liblary to script... |
|