2009-02-04 13 views
24

मैं ओपनजीएल में कुछ पाठ खींचने के लिए एक सरल समझने की कोशिश कर रहा हूं। मेरे शोध ने इसे काफी जटिल कार्य दिखाया है। इसमें एक फ़ॉन्ट एटलस बनावट बनाने (या रनटाइम पर उत्पन्न) शामिल है, और फिर प्रत्येक पत्र के लिए केवल सही प्लेसमेंट और बनावट निर्देशांक के साथ एक ट्रैक्टर बनाना शामिल है।क्या आईफोन एसडीके के लिए एक सभ्य ओपनजीएल टेक्स्ट ड्राइंग लाइब्रेरी है?

मैंने freetype के बारे में कुछ अच्छी बातें सुनी हैं, लेकिन आईफोन पर इसे चलाने के तरीके के बारे में बहुत कम पता चला है, और यह बहुत जटिल प्रतीत होता है।

तो क्या कोई उद्देश्य-सी लिपटे ओपनजीएल टेक्स्ट लाइब्रेरी है जो आईफोन एसडीके के साथ काम करती है जो लोग उपयोग कर रहे हैं? या मैं बस यह सोचने पर हूं और एक आसान तरीका है जिसे मैं याद कर रहा हूं?

+0

[यह बहुत अच्छा लग रहा है] (http: // कोड .google.com/p/freetype-gl /) – bobobobo

उत्तर

8

सभी ग्लिफ जानकारी के साथ एक बनावट एटलस बनाने के लिए freetype का उपयोग करने का आपका विवरण बिल्कुल ठीक है जो मैं कर रहा हूं वर्तमान आईफोन परियोजना।

मैं प्री-प्रोसेस चरण में फ़ॉन्ट का सभी पार्सिंग करता हूं (विंडोज़ पर सभी सी # में ऐसा होता है)। एटलस स्वयं उत्पन्न हो जाता है और इसमें केवल वर्णों की आवश्यकता होती है - अंतरिक्ष पर कटौती करने के लिए, मैं कभी-कभी बनावट को आकार 2 और एक समझदार रिज़ॉल्यूशन रखने के लिए एक एकल एटलस से अधिक उत्पन्न करता हूं।

आप आसानी से freetype से ग्लाइफ जानकारी खींच सकते हैं। रनटाइम पर बनावट के साथ अपने ऐप के साथ पास करें और फिर आवश्यकतानुसार बनावट के यूवी कॉर्ड को बदलने के लिए यह काफी छोटा है।

क्या इसके लायक है के लिए, यह है कि कैसे मैं अपनी छोटी इंजन के अंदर एक ग्लिफ़ चरित्र को परिभाषित:

struct FontGlyph 
{ 

u32 char_code; 

u32 m_x;    // base x position on tpage 

u32 m_y;   // base y position on tpage 

u32 m_width;   // glyph width 

u32 m_height;   // glyph height 

i32 m_horiBearingX;  // Distance to X shift 

i32 m_horiBearingY;  // Distance to Y shift 

u32 m_horiAdvance;  // Total Horizontal advance this character requires 

u32 m__tpage_index;  // Which tpage does this glyph use? 

}; 

मैं तो एक 'SpriteString' वस्तु है, जो मैं से किसी भी अन्य स्ट्रिंग की तरह काफी व्यवहार करती है, अलग है sprites का उपयोग कर इसे आकर्षित कर सकते हैं ....

मैं मानता हूं कि यह सब काफी मामूली समस्या के लिए एक बड़ी नौकरी की तरह लग सकता है, लेकिन मुझे पता चला है कि यह मुझे बहुत लचीलापन देता है और वास्तव में इसे लागू करने में लंबा समय नहीं लगा जब मैं इसे नीचे चला गया।

यदि आपको किसी अन्य विवरण की आवश्यकता है तो उत्तर देने या टिप्पणी करने के लिए स्वतंत्र महसूस करें। (और अच्छी किस्मत :)


आपकी टिप्पणी का जवाब के रूप में मैं टिप्पणी अनुभाग में कमरे से बाहर भाग ...

चेक बाहर freetype प्रलेखन, यह मूल रूप से आप ग्लिफ़ डेटा के बारे में खिलवाड़ के बिना देता है , यह सिर्फ फ़ॉन्ट से बाहर खींचता है। खुद बनावट के लिए, आप प्रत्येक ग्लिफ को प्रस्तुत करने के लिए freetype मिलता है, और उसके बाद बनावट बनाने के लिए प्रबंधन। यह मैं अपने मुख्य ऐप से पूरी तरह से अलग प्रक्रिया के रूप में करता हूं। http://pastebin.com/md1c6354

कृपया ध्यान दें, हालांकि, यह केवल कभी मेरी आँखों के लिए और जनता के उपभोग के लिए नहीं करना था, इसलिए इस तथ्य यह :) नरक के रूप में

गन्दा है बहाना:

यहाँ मेरी उपकरण कोड का एक अंश है कि इस है

+0

यह संरचना निश्चित रूप से शामिल सभी चरणों को समझने में मेरी सहायता करती है। धन्यवाद। हालांकि मैं बनावट और ग्लिफ डेटा उत्पन्न करने के बारे में कैसे जाऊं? –

+0

धन्यवाद, यह सबसे अच्छा मार्ग होने का अंत हो सकता है। अगर मैं एक सभ्य समाधान के साथ आता हूं तो मैं इसे अच्छी तरह से लपेटने की कोशिश करता हूं और इसे साझा करने के लिए गिटूब पर टॉस करता हूं। –

+0

शानदार - मुझे संपर्क में रखें :) –

1

क्रैश लैंडिंग डेमो की जांच करें। प्रदान की गई Texture2D कक्षा टेक्स्ट और फ़ॉन्ट के साथ बनावट बनाने के लिए अनुमति देता है। (उम्मीद है कि एक बेहतर जवाब होगा, मैं एक ओपनल्स व्यू पर ड्राइंग का एक आसान तरीका पसंद करूंगा)

+0

मुझे लगता है कि मैं काफी कुछ नहीं ढूंढ रहा हूं। मेरा मानना ​​है कि फ्लाई पर एक पूरी स्ट्रिंग के लिए बनावट बनाता है, जो एक सीपीयू गहन ऑपरेशन है। व्यक्तिगत quads से शब्दों को बनाने के लिए एक और तरीका तलाश रहे हैं ताकि मैं रनटाइम पर मनमाना पाठ प्रस्तुत कर सकूं। यह बहुत तेज होना चाहिए। –

+0

आपको क्यों लगता है कि आपका प्रस्तावित तरीका तेज होगा? – Jacob

+0

आप बनावट के बिना किसी दृश्य को आकर्षित नहीं कर सकते हैं - यह पर्याप्त तेज़ी से नहीं चलाएगा – bobobobo

22

ऐसा करने का एक तरीका एक UILabel स्थापित करके और फिर अपनी परत को बनावट में प्रस्तुत करना है। इसके लिए एक अप्रत्यक्ष मार्ग सबसे पहले UILabel को टेक्स्ट, फ़ॉन्ट इत्यादि के साथ स्थापित करना होगा।और उसके बाद निम्न कोड

UIGraphicsBeginImageContext(yourLabel.frame.size); 
[yourLabel.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *layerImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

UILabel को UIImage पर कैप्चर करने के लिए उपयोग करें। इसके बाद आप initWithImage का उपयोग कर सकते हैं: क्रैश लैंडिंग प्रोजेक्ट में Texture2D क्लास का कन्स्ट्रक्टर इसे एक बनावट में बदलने के लिए।

ऐसा लगता है कि initWithImage: उस उदाहरण में UIImage को बिटमैप संदर्भ में दोबारा प्रस्तुत करता है और बनावट बनाने के लिए इसका उपयोग करता है। एक छोटे से काम के साथ, आप उस विधि से प्रासंगिक कोड निकाल सकते हैं और उपरोक्त कोड को अपनी परत को सीधे बनावट में प्रस्तुत करने के लिए बदल सकते हैं।

इस तरह, आपको अपने बनावट के लिए पाठ बनाते समय यूआईएलएबल का अच्छा यूनिकोड और फ़ॉन्ट समर्थन मिलता है।

+0

मैं प्रत्येक प्रस्तुत स्ट्रिंग के लिए फ्लाई पर एक अलग बनावट उत्पन्न करने से बचने की कोशिश कर रहा हूं मेरे ऐप में कई अलग-अलग तार प्रदर्शित होंगे और ऐसा लगता है कि यह सीपीयू और मेमोरी पर एक बड़ी तनाव होगी। –

+2

यह प्रभावी रूप से आईफोन आपके द्वारा देखे जाने वाले पाठ के प्रत्येक टुकड़े के लिए करता है। सभी UILabels CALayer समर्थित हैं, और कैलियर सिर्फ ओपनजीएल बनावट लपेटे गए हैं। मुझे नहीं लगता कि यह संसाधन संसाधन है जितना आप मानते हैं। –

+0

क्रैश लैंडिंग डेमो एप्लिकेशन अब आईफोन डेवलपर साइट से डाउनलोड करने के लिए उपलब्ध नहीं है, क्या कोई उपयुक्त विकल्प है – rck

6

मुझे इसका एक आसान समाधान मिला। यहां एक त्वरित कार्य है जिसके लिए मैंने लिखा था। (आप Texture2D वर्ग की आवश्यकता होगी।)

- (void) drawText:(NSString*)theString AtX:(float)X Y:(float)Y { 
// Use black 
glColor4f(0, 0, 0, 1.0); 

// Set up texture 
Texture2D* statusTexture = [[Texture2D alloc] initWithString:theString dimensions:CGSizeMake(150, 150) alignment:UITextAlignmentLeft fontName:@"Helvetica" fontSize:11]; 

// Bind texture 
glBindTexture(GL_TEXTURE_2D, [statusTexture name]); 

// Enable modes needed for drawing 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
glEnableClientState(GL_VERTEX_ARRAY); 
glEnable(GL_TEXTURE_2D); 
glEnable(GL_BLEND); 

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

// Draw 
[statusTexture drawInRect:CGRectMake(X,Y-1,1,1)]; 

// Disable modes so they don't interfere with other parts of the program 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
glDisableClientState(GL_VERTEX_ARRAY); 
glDisable(GL_TEXTURE_2D); 
glDisable(GL_BLEND);  
} 

मेरा मानना ​​है कि इनपुट निर्देशांक अपनी दुनिया में होने का समन्वय करता है की जरूरत है, लेकिन मुझे यकीन है कि सामान्य रूप से सच है नहीं कर रहा हूँ या यह सिर्फ मेरे लिए उस तरह से काम करता है। इसे सही करने के लिए आपको ऑफ़सेट के साथ खेलना पड़ सकता है।

+5

स्टेटसटेक्चर के साथ एक मेम रिसाव? –

+0

टोनी टोनेव का समाधान मेरे लिए काम करता था। मुझे डस्टिन के लिंक से बनावट 2 डी मिला। बहुत साफ समाधान। यदि आवश्यक हो तो बाद में कैशिंग जोड़ने में आसान। – Voltron

3

उस विधि के लिए धन्यवाद। यह मुझे कुछ समय बचाया।

हालांकि कुछ चीजें मुझे बदलनी पड़ीं। glBlendFunc कॉल की जरूरत होने के लिए:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_ALPHA) 

और दूसरी बात, पाठ एक बिंदु में ड्राइंग जा करने के लिए दिखाई दिया। CGRectMake कॉल एक 1x1 आयत बना रहा है, जब तक कि मैं इसे गलत तरीके से पढ़ रहा हूं।

3

"चिंतन" फ़ॉन्ट पुस्तकालय का उपयोग करें:

http://www.themusingsofalostprogrammer.com/2010/01/how-to-do-font-rendering-in-opengl-on.html

Font font("Verdena"); 
font.print("Hello World!", x, y, z); 

आसान :)

यह यूनिकोड समर्थन के साथ आता है, भार ग्लिफ़ "मांग", और यहां तक ​​कि एक तरीका है आउटपुट चर

font.print(x, y, z) << "fps: " << fps; 
+1

यह बहुत सुंदर सेक्सी दिखता है। –

+2

यह लाइब्रेरी प्रत्येक वर्ण को एक अलग बनावट के रूप में लोड करती है, जो बहुत धीमी होगी यदि आप ड्राइंग के किसी भी सभ्य आकार की मात्रा कर रहे हैं। यह कुछ अन्य उत्तरों द्वारा सुझाए गए एक बनावट एटलस का उपयोग करने के लिए * अधिक * बेहतर है। –

+0

दुख है कि यह ओपनजीएल ईएस 1 (2 नहीं) में है, और डाउनलोड लिंक अब काम नहीं करता है .. – Xys

1

हाँ, वें ईर 2 हैं जो मुझे के बारे में पता है। चाल है, आपको क्वार्ट्ज (CGContext * फ़ंक्शंस) का उपयोग करके बनावट में प्रस्तुत करना होगा, फिर उपयोगकर्ता को देखने के लिए उस बनावट को प्रस्तुत करना होगा।

यदि आप प्रदर्शन के बारे में चिंतित हैं, तो आप अपने बनावट एटलस उत्पन्न करने के लिए क्वार्ट्ज का भी उपयोग कर सकते हैं।

एक बनावट उत्पादन उपकरण (xCode में) once you know the basics of rendering a font को चाबुक करना काफी आसान है।

आपको बस एक वैध CGContext है। आप इस texture loader में कुछ वाकई महान नमूना कोड पा सकते हैं।

मूल रूप से कोड है:

// Create the cgcontext as shown by links above 

// Now to render text into the cg context, 
// the drop the raw data behind the cgcontext 
// to opengl. 2 ways to do this: 
// 1) CG* way: (advantage: easy to use color) 
CGContextSelectFont(cgContext, "Arial", 24, kCGEncodingMacRoman); 

// set color to yellow text 
CGContextSetRGBFillColor(cgContext, 1, 1, 0, 1) ; // Be sure to use FILL not stroke! 

// draw it in there 
CGContextShowTextAtPoint(cgContext, 20, 20, "HI THERE", strlen("HI THERE")) ; 

/* 
// WAY #2: this way it's always black and white 
// DRAW SOME TEXT IN IT 
// that works ok but let's try cg to control color 
UIGraphicsPushContext(cgContext); 
UIFont *helv = [UIFont fontWithName:@"Helvetica" size:[UIFont systemFontSize]]; 
NSString* msg = @"Hi hello" ; 
[msg drawInRect:CGRectMake(0,0,pow2Width,pow2Height) withFont:helv] ; 
    UIGraphicsPopContext(); 
*/ 

// put imData into OpenGL's memory 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pow2Width, pow2Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imData); 
CHECK_GL ; 

यह पता बहुत अच्छी और antialiased देख आता है,

tex atlas

ios फोंट की एक सूची available here है, और साथ prerenders here

2

मैं "संगीत" फ़ॉन्ट लाइब्रेरी के समान एक फ़ॉन्ट क्लास बनाया है, मेमोरी लीक से कम और teus min प्रत्येक चरित्र, प्रत्येक फ्रेम के लिए मिश्रण निर्माण। यह अभी भी प्रत्येक चरित्र के लिए एक अलग glTexture का उपयोग करता है। नोट: बनावट 2 डी को अपनी बनावट हटाने पर टिप्पणी करने के लिए बदला गया है। निर्माता में

init: _font = new Font("Helvetica", 40);

redraw में उपयोग() विधि: _font->draw("Hello, World!", 50, 100, ALIGN_LEFT);

GitHub लिंक:

https://github.com/chandl34/public/tree/master/personal/c%2B%2B/Font

+0

क्या आप जानते हैं कि OpenGLES 2.0 के बराबर है या नहीं? अग्रिम में धन्यवाद – Xys

संबंधित मुद्दे