2010-02-27 10 views
5

के साथ समस्या हे, मुझे Freetype 2 लाइब्रेरी से लोड ओपनजीएल में ड्राइंग टेक्स्ट के साथ एक अजीब समस्या है। मैं जो देख रहा हूं उसका एक स्क्रीनशॉट यहां दिया गया है।Freetype और OpenGL

example http://img203.imageshack.us/img203/3316/freetypeweird.png

यहाँ लोड हो रहा है और मेरे पाठ प्रतिपादन के लिए मेरी कोड बिट्स हैं।

class Font 
{ 
    Font(const String& filename) 
    { 
     if (FT_New_Face(Font::ftLibrary, "arial.ttf", 0, &mFace)) { 
      cout << "UH OH!" << endl; 
     } 

     FT_Set_Char_Size(mFace, 16 * 64, 16 * 64, 72, 72); 
    } 

    Glyph* GetGlyph(const unsigned char ch) 
    { 
     if(FT_Load_Char(mFace, ch, FT_LOAD_RENDER)) 
      cout << "OUCH" << endl; 

     FT_Glyph glyph; 

     if(FT_Get_Glyph(mFace->glyph, &glyph)) 
      cout << "OUCH" << endl; 

     FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph; 

     Glyph* thisGlyph = new Glyph; 
     thisGlyph->buffer = bitmap_glyph->bitmap.buffer; 
     thisGlyph->width = bitmap_glyph->bitmap.width; 
     thisGlyph->height = bitmap_glyph->bitmap.rows; 

     return thisGlyph; 
    } 
}; 

प्रासंगिक ग्लिफ़ जानकारी (चौड़ाई, ऊंचाई, बफर) निम्नलिखित struct में संग्रहित है

struct Glyph { 
    GLubyte* buffer; 
    Uint width; 
    Uint height; 
}; 

और अंत में, यह रेंडर करने के लिए, मैं इस वर्ग RenderFont कहा जाता है।

class RenderFont 
{ 
    RenderFont(Font* font) 
    { 
     mTextureIds = new GLuint[128]; 

     mFirstDisplayListId=glGenLists(128); 
     glGenTextures(128, mTextureIds); 

     for(unsigned char i=0;i<128;i++) 
     { 
     MakeDisplayList(font, i); 
     } 
    } 

    void MakeDisplayList(Font* font, unsigned char ch) 
    { 
     Glyph* glyph = font->GetGlyph(ch); 

     glBindTexture(GL_TEXTURE_2D, mTextureIds[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, 
        glyph->width, 
        glyph->height, 
        0, 
        GL_ALPHA, 
        GL_UNSIGNED_BYTE, 
        glyph->buffer); 

     glNewList(mFirstDisplayListId+ch,GL_COMPILE); 
     glBindTexture(GL_TEXTURE_2D, mTextureIds[ch]); 

     glBegin(GL_QUADS); 
     glTexCoord2d(0,1); glVertex2f(0,glyph->height); 
     glTexCoord2d(0,0); glVertex2f(0,0); 
     glTexCoord2d(1,0); glVertex2f(glyph->width,0); 
     glTexCoord2d(1,1); glVertex2f(glyph->width,glyph->height); 
     glEnd(); 

     glTranslatef(16, 0, 0); 

     glEndList(); 
    } 

    void Draw(const String& text, Uint size, const TransformComponent* transform, const Color32* color) 
    { 
     glEnable(GL_TEXTURE_2D); 
     glEnable(GL_BLEND); 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

     glTranslatef(100, 250, 0.0f); 

     glListBase(mFirstDisplayListId); 

     glCallLists(text.length(), GL_UNSIGNED_BYTE, text.c_str()); 

     glDisable(GL_TEXTURE_2D); 
     glDisable(GL_BLEND); 

     glLoadIdentity(); 
    } 

private: 
    GLuint mFirstDisplayListId; 
    GLuint* mTextureIds; 
}; 

क्या कोई यहां पर अजीब कुछ भी देख रहा है जो खराब पाठ का कारण बनता है? यह अजीब बात है क्योंकि अगर मैं फ़ॉन्ट आकार या डीपीआई बदलता हूं, तो सही ढंग से प्रदर्शित होने वाले कुछ अक्षरों को खराब कर दिया जाता है, और अन्य अक्षरों को पहले सही ढंग से प्रदर्शित किया जाता है।

उत्तर

7

मैं freetype से परिचित नहीं हूँ, लेकिन तस्वीर से, यह वर्णों की चौड़ाई की तरह लग रहा सीधे बफ़र्स के आकार से संबंधित नहीं है (यानी। Glyph-> बफर एक को इंगित नहीं करता ग्लाइफ की सरणी-> चौड़ाई * ग्लिथ-> ऊंचाई बाइट्स)।

अनुमान के मुताबिक, मैं कहूंगा कि सभी वर्णों में स्मृति में एक चौड़ाई है (जैसा कि वे स्क्रीन पर उपयोग किए जाने वाले आकार के विपरीत हैं), शायद ग्लिफ की सभी चौड़ाईओं में सबसे बड़ी है, लेकिन आप उन्हें लोड करते हैं सही की बजाय प्रति-चौड़ाई चौड़ाई। इसलिए, केवल पूर्ण चौड़ाई का उपयोग करने वाले ग्लिफ सही हैं।

+0

यह समस्या थी। मैंने सब कुछ एक नए बफर में कॉपी किया जो कि एक निश्चित आकार था जो इसे खाली पिक्सल के साथ पैडिंग करता था और सब ठीक से काम करता था। धन्यवाद! – Morgan

1

क्या आप वाकई FT_Glyph वास्तव में एक बिटमैप ग्लिफ़ है? सुनिश्चित करें कि आप पहले FT_Glyph_To_Bitmap का उपयोग करें।

वैकल्पिक रूप से

, जब से तुम बाद में चारों ओर FT_Glyph रों संग्रहीत करने की आवश्यकता ही नहीं है, तो आप सिर्फ कर सकते हैं:

int error = FT_Load_Char(face, ch, FT_LOAD_RENDER); 
if(error) 
    return error; 

FT_GlyphSlot slot = face->glyph; 
FT_Bitmap bitmap = slot->bitmap; 

// do stuff with this FT_Bitmap 

FT_Bitmap पर दस्तावेजों के लिए here देखें। बस ध्यान दें कि अगली बार जब आप FT_Load_Char पर कॉल करेंगे, तो bitmap में डेटा अब मान्य नहीं होगा।

आपके पास स्मृति प्रबंधन के साथ कई समस्याएं भी हैं।

  1. आप new Glyph का उपयोग अपने ग्लिफ़ आवंटित करने के लिए, लेकिन कभी delete. फोन के बाद से आप सिर्फ बनावट और प्रदर्शन सूची उत्पन्न करने के लिए, आप एक std::auto_ptr<Glyph> का उपयोग करना चाहिए अस्थायी रूप से एक ग्लिफ़ बनाने की जरूरत है।

  2. आप कभी भी FT_Glyph_Done पर कॉल नहीं करते हैं, इसलिए आपके द्वारा आवंटित सभी FT_Glyph एस जारी नहीं किए जाते हैं।

+0

स्मृति प्रबंधन के बारे में टिप के लिए धन्यवाद। मुझे यकीन है कि मेरे डेटा गलती से दुर्घटना से नष्ट कर दिया हो रही नहीं किया गया था जब यह नहीं होना चाहिए बनाने के लिए बाहर सिर्फ परीक्षण प्रयोजनों के लिए कि कोड के सभी छीन लिया। – Morgan

-1

"16" अंक में फ़ॉन्ट का आकार होना चाहिए। इसलिए, अनुवाद करते समय आपको "16" की बजाय ग्लाइफ-> चौड़ाई का उपयोग करना चाहिए। इसके अलावा, कुछ अक्षरों को सर्वश्रेष्ठ दिखने वाले ग्रंथों के लिए कर्नाई की आवश्यकता हो सकती है। उदाहरण के लिए "एवी" उपयोग के बिना "ए वी" जैसा दिख सकता है।

2

उपयोग:

glPixelStorei(GL_PACK_ALIGNMENT, 1);<br> 
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

यह मैं हूँ से बाहर बिल्ली भी नाराज है, लेकिन आप रिक्ति आप इसे देने के लिए, नहीं सामान्य 32-बिट सीमाओं यह उम्मीद उपयोग करने के लिए ओपन बताने के लिए की जरूरत है। छवियों परिवर्तन की पिच, लेकिन OpenGL अपने बनावट सृजन से पहले इन कॉल के बिना छोटे पैकिंग संरेखण उपयोग करने के लिए पता नहीं है।

मैं इस तरह यह कार्य करें:

// Convert the glyph to a bitmap. 
FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, NULL, true); 
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph; 

// This reference will make accessing the bitmap easier 
FT_Bitmap& bitmap = bitmap_glyph->bitmap; 

int _Left = abs(bitmap_glyph->left); 
int _Top = abs(bitmap_glyph->top); 
int _Height = abs(bitmap.rows); 
int _Width = _Left+abs(bitmap.width); 

// If it's not a glyph or spacing, go to the next one 
if ((_Width == 0 || _Height == 0) && !isspace(i)) 
    return; 

advances[i] = max(_Width, face->glyph->advance.x >> 6); 

vector<unsigned char> Data(_Height*_Width*2, 0); 
for (int32 h=0; h < abs(bitmap.rows); ++h) 
    for (int32 w=0; w < abs(bitmap.width); ++w) 
    { 
     int32 luminance = bitmap.buffer[h*bitmap.pitch + w]; 
     Data[(h*_Width + w + _Left)*2 + 0] = 255; 
     Data[(h*_Width + w + _Left)*2 + 1] = luminance; 
    } 

मैं शायद स्ट्रिंग प्रारंभ समारोह में 255 (श्वेत) के लिए कदम सकता है तो बस अपना अल्फा मूल्यों के लिए FreeType में मूल्यों का उपयोग, लेकिन इस तरह से अधिक वर्णनात्मक लगता है और गति मेरे उपयोग में कोई मुद्दा नहीं है।

पता & डाटा [0] अब प्रकार GL_UNSIGNED_CHAR और आकार _Width*_Height के साथ एक GL_LUMINANCE_ALPHA external प्रारूप होता है,। यह किसी को भी बनाना चाहिए जो इस सामान के जीवन को आसान बनाता है।