qba10 Temat założony przez niniejszego użytkownika |
[C++. FreeType2] Polskie znaki » 2011-07-30 00:01:36 Korzystam kodu z lekcji nehe (bodajże lekcja 43) o wykorzystaniu freetype do wyświetlania tekstu w programie z opengl'em Jednak mam problem z wyświetlaniem polskich liter i generalnie z korzystaniem z unicode W internecie znalazłem taki link: http://forum.warsztat.gd/index.php?topic=12446.0Jednak nie za bardzo kumam jak wykorzystać te informacje. Poniżej daję dwie funkcję które służą do generowania tablicy znaków z danej czionki; void make_dlist( FT_Face face, char ch, GLuint list_base, GLuint * tex_base ) { if( FT_Load_Glyph( face, FT_Get_Char_Index( face, ch ), FT_LOAD_DEFAULT ) ) throw std::runtime_error( "FT_Load_Glyph failed" ); FT_Glyph glyph; if( FT_Get_Glyph( face->glyph, & glyph ) ) throw std::runtime_error( "FT_Get_Glyph failed" ); FT_Glyph_To_Bitmap( & glyph, ft_render_mode_normal, 0, 1 ); FT_BitmapGlyph bitmap_glyph =( FT_BitmapGlyph ) glyph; FT_Bitmap & bitmap = bitmap_glyph->bitmap; int width = next_p2( bitmap.width ); int height = next_p2( bitmap.rows ); GLubyte * expanded_data = new GLubyte[ 2 * width * height ]; for( int j = 0; j < height; j++ ) { for( int i = 0; i < width; i++ ) { expanded_data[ 2 *( i + j * width ) ] = expanded_data[ 2 *( i + j * width ) + 1 ] =( i >= bitmap.width || j >= bitmap.rows ) ? 0 : bitmap.buffer[ i + bitmap.width * j ]; } } glBindTexture( GL_TEXTURE_2D, tex_base[ ch ] ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data ); delete[] expanded_data; glNewList( list_base + ch, GL_COMPILE ); glBindTexture( GL_TEXTURE_2D, tex_base[ ch ] ); glTranslatef( bitmap_glyph->left, 0, 0 ); glPushMatrix(); glTranslatef( 0, bitmap_glyph->top - bitmap.rows, 0 ); float x =( float ) bitmap.width /( float ) width, y =( float ) bitmap.rows /( float ) height; glBegin( GL_QUADS ); glTexCoord2d( 0, 0 ); glVertex2f( 0, bitmap.rows ); glTexCoord2d( 0, y ); glVertex2f( 0, 0 ); glTexCoord2d( x, y ); glVertex2f( bitmap.width, 0 ); glTexCoord2d( x, 0 ); glVertex2f( bitmap.width, bitmap.rows ); glEnd(); glPopMatrix(); glTranslatef( face->glyph->advance.x >> 6, 0, 0 ); glEndList(); }
void font_data::init( const char * fname, unsigned int h ) { textures = new GLuint[ 128 ]; this->h = h; FT_Library library; if( FT_Init_FreeType( & library ) ) throw std::runtime_error( "FT_Init_FreeType failed" ); FT_Face face; if( FT_New_Face( library, fname, 0, & face ) ) throw std::runtime_error( "FT_New_Face failed (there is probably a problem with your font file)" ); FT_Set_Char_Size( face, h << 6, h << 6, 96, 96 ); list_base = glGenLists( 128 ); glGenTextures( 128, textures ); for( unsigned char i = 0; i < 128; i++ ) make_dlist( face, i, list_base, textures ); FT_Done_Face( face ); FT_Done_FreeType( library ); }
kombinowałem cos takiego: list_base = glGenLists( 256 ); glGenTextures( 256, textures ); wchar_t * str = L"!\"#$%&'()*+,-./0123456789:;=>?@ABCDEFGHIJKLMNO\ PQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~•€£°¡¿ÅÀÂÁ\ ¡ÄåàâáąäÆæßÇćÈçćèÏïÉÈÊËęÌéèêëęìÎÏÍîïíŁłÑńÒñńòØÖÔÓøöôóÛÙÜÚÙ\ ûùüúùØøŚ©ś¹«»ŸÝÿýŹŻ®ź¾żАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯаб\ вгдеёжзийклмнопрстуфхцчшщъыьэюяΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγ\ δεζηθικλμνξοπρστυφχψω";
for( unsigned short i = 0; i < 256; i++ ) make_dlist( face, str[ i ], list_base, textures );
Ale zamiast polskich liter wyświetlały mi się któreś z tych liter: ÅÀÂÁ¡Äå |
|
DejaVu |
» 2011-07-30 14:12:23 Sprawdź sobie w źródłach biblioteki SFML :) Ona pracuje na OpenGLu i można w niej określić pulę znaków, które mają być załadowane. http://cpp0x.pl/kursy/Kurs-SFML-C++/Wyswietlanie-tekstu/341
bool Font::LoadFromFile( const std::string & Filename, unsigned int CharSize, const Unicode::Text & Charset ) { myGlyphs.clear(); Unicode::UTF32String UTFCharset = Charset; if( UTFCharset.find( L' ' ) != Unicode::UTF32String::npos ) UTFCharset += L' '; if( UTFCharset.find( L'\n' ) != Unicode::UTF32String::npos ) UTFCharset += L'\n'; if( UTFCharset.find( L'\v' ) != Unicode::UTF32String::npos ) UTFCharset += L'\v'; if( UTFCharset.find( L'\t' ) != Unicode::UTF32String::npos ) UTFCharset += L'\t'; return priv::FontLoader::GetInstance().LoadFontFromFile( Filename, CharSize, UTFCharset, * this ); }
bool FontLoader::LoadFontFromFile( const std::string & Filename, unsigned int CharSize, const Unicode::UTF32String & Charset, Font & LoadedFont ) { if( !myLibrary ) { std::cerr << "Failed to load font \"" << Filename << "\", FreeType has not been initialized" << std::endl; return false; } FT_Face FontFace; FT_Error Error = FT_New_Face( myLibrary, Filename.c_str(), 0, & FontFace ); if( Error ) { std::cerr << "Failed to load font \"" << Filename << "\" (" << GetErrorDesc( Error ) << ")" << std::endl; return false; } Error = CreateBitmapFont( FontFace, CharSize, Charset, LoadedFont ); if( Error ) std::cerr << "Failed to load font \"" << Filename << "\" (" << GetErrorDesc( Error ) << ")" << std::endl; FT_Done_Face( FontFace ); return Error == 0; }
FT_Error FontLoader::CreateBitmapFont( FT_Face FontFace, unsigned int CharSize, const Unicode::UTF32String & Charset, Font & LoadedFont ) { priv::GraphicsContext Ctx; GLint MaxSize; GLCheck( glGetIntegerv( GL_MAX_TEXTURE_SIZE, & MaxSize ) ); int NbChars = static_cast < int >( sqrt( static_cast < double >( Charset.length() ) ) * 0.75 ); if( NbChars * CharSize >= static_cast < unsigned int >( MaxSize ) ) CharSize = MaxSize / NbChars; unsigned int Left = 0; unsigned int Top = 0; unsigned int TexWidth = Image::GetValidTextureSize( CharSize * NbChars ); unsigned int TexHeight = CharSize * NbChars; std::vector < unsigned int > Tops( TexWidth, 0 ); std::vector < Uint8 > GlyphsBuffer( TexWidth * TexHeight * 4 ); FT_Error Error = FT_Set_Pixel_Sizes( FontFace, CharSize, CharSize ); if( Error ) return Error; Error = FT_Select_Charmap( FontFace, FT_ENCODING_UNICODE ); if( Error ) return Error; typedef std::multimap < FT_BitmapGlyph, Uint32, SizeCompare > GlyphTable; GlyphTable Glyphs; for( std::size_t i = 0; i < Charset.length(); ++i ) { Error = FT_Load_Char( FontFace, Charset[ i ], FT_LOAD_TARGET_NORMAL ); if( Error ) return Error; FT_Glyph Glyph; Error = FT_Get_Glyph( FontFace->glyph, & Glyph ); if( Error ) return Error; FT_Glyph_To_Bitmap( & Glyph, FT_RENDER_MODE_NORMAL, 0, 1 ); FT_BitmapGlyph BitmapGlyph =( FT_BitmapGlyph ) Glyph; Glyphs.insert( std::make_pair( BitmapGlyph, Charset[ i ] ) ); } unsigned int MaxHeight = 0; std::map < Uint32, IntRect > Coords; for( GlyphTable::const_iterator i = Glyphs.begin(); i != Glyphs.end(); ++i ) { Glyph & CurGlyph = LoadedFont.myGlyphs[ i->second ]; FT_BitmapGlyph BitmapGlyph = i->first; FT_Bitmap & Bitmap = BitmapGlyph->bitmap; if( Left + Bitmap.width + 1 >= TexWidth ) Left = 0; Top = Tops[ Left ]; for( int x = 0; x < Bitmap.width + 1; ++x ) Top = std::max( Top, Tops[ Left + x ] ); Top++; if( Top + Bitmap.rows + 1 >= TexHeight ) { TexHeight *= 2; GlyphsBuffer.resize( TexWidth * TexHeight * 4 ); } CurGlyph.Rectangle.Left = BitmapGlyph->left; CurGlyph.Rectangle.Top = - BitmapGlyph->top; CurGlyph.Rectangle.Right = CurGlyph.Rectangle.Left + Bitmap.width; CurGlyph.Rectangle.Bottom = Bitmap.rows - BitmapGlyph->top; CurGlyph.Advance = BitmapGlyph->root.advance.x >> 16; Coords[ i->second ] = IntRect( Left + 1, Top + 1, Left + Bitmap.width + 1, Top + Bitmap.rows + 1 ); const Uint8 * Pixels = Bitmap.buffer; for( int y = 0; y < Bitmap.rows; ++y ) { for( int x = 0; x < Bitmap.width; ++x ) { std::size_t Index = x + Left + 1 +( y + Top + 1 ) * TexWidth; GlyphsBuffer[ Index * 4 + 0 ] = 255; GlyphsBuffer[ Index * 4 + 1 ] = 255; GlyphsBuffer[ Index * 4 + 2 ] = 255; GlyphsBuffer[ Index * 4 + 3 ] = Pixels[ x ]; } Pixels += Bitmap.pitch; } for( int x = 0; x < Bitmap.width + 1; ++x ) Tops[ Left + x ] = Top + Bitmap.rows; Left += Bitmap.width + 1; if( Top + Bitmap.rows > MaxHeight ) MaxHeight = Top + Bitmap.rows; FT_Done_Glyph(( FT_Glyph ) BitmapGlyph ); } TexHeight = MaxHeight + 1; GlyphsBuffer.resize( TexWidth * TexHeight * 4 ); LoadedFont.myTexture.LoadFromPixels( TexWidth, TexHeight, & GlyphsBuffer[ 0 ] ); for( std::size_t i = 0; i < Charset.size(); ++i ) { Uint32 CurChar = Charset[ i ]; LoadedFont.myGlyphs[ CurChar ].TexCoords = LoadedFont.myTexture.GetTexCoords( Coords[ CurChar ] ); } LoadedFont.myCharSize = CharSize; return 0; }
|
|
« 1 » |