سؤال

أنا أحاول معرفة بسيطة لرسم بعض النص في برنامج OpenGL.بحثي وقد أظهرت مهمة معقدة إلى حد ما.فإنه ينطوي على خلق (أو توليد في وقت التشغيل) الخط أطلس الملمس, ثم خلق رباعية لكل حرف مع مجرد الحق في التنسيب والملمس الإحداثيات.

لقد سمعت أشياء جيدة عن freetype ، ولكن وجدت القليل جدا عن كيفية الحصول عليها تشغيل على اي فون ، ويبدو أن تكون معقدة جدا.

لذلك ليس هناك أي هدف-ج ملفوفة OpenGL مكتبة النص الذي يعمل مع اي فون SDK التي كان الناس يستخدمونها ؟ أو أنا فقط أكثر من هذا التفكير و هناك نهج أسهل أن أنا في عداد المفقودين ؟

هل كانت مفيدة؟

المحلول

وصفك استخدام راسم FreeType إلى إنشاء أطلس نسيج جنبا إلى جنب مع جميع المعلومات الحرف الرسومي هو بالضبط ما أفعله في المشروع الحالي فون بلدي.

وأفعل كل إعراب الخط في خطوة ما قبل عملية (كل في C # على ويندوز كما يحدث). الأطلس نفسه يحصل لدت ويحتوي فقط على الحروف المطلوبة - لخفض الفضاء، وأنا أيضا في بعض الأحيان في نهاية المطاف توليد أكثر من أطلس واحدة للحفاظ على القوام أحجام pow2 وقرار معقول.

ويمكنك سحب بسهولة على معلومات الصورة الرمزية من راسم 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"، الذي يتصرف الى حد كبير مثل أي سلسلة أخرى، بصرف النظر عن يمكنني رسم باستخدام العفاريت ....

وأنا أتفق هذا قد يبدو وكأنه كل مهمة كبيرة لمشكلة تافهة إلى حد ما، ولكني وجدت انها أعطاني الكثير من المرونة وحقا لم تأخذ هذا الوقت الطويل لتنفيذ عندما وصلت الى اسفل.

لا تتردد في الرد أو التعليق على ما اذا كنت بحاجة إلى أي تفاصيل أخرى. (وحظا سعيدا:)


والرد على تعليقك وأنا نفدت من الغرفة في قسم التعليق ...

وتحقق من وثائق راسم FreeType، وأنه يعطي أساسا لكم البيانات الشكل المنقوش دون العبث شيء، وأنه مجرد تسحب ذلك الحق من خارج الخط. أما بالنسبة للمواد أنفسهم، وتحصل على راسم FreeType لتقديم كل رسومي، ومن ثم إدارة أن بناء النسيج. هذا أفعل باعتباره عملية ما قبل منفصلة تماما عن بلدي التطبيق الرئيسي.

وفيما يلي مقتطفات من التعليمات البرمجية أداة بلدي أن يفعل ذلك: http://pastebin.com/md1c6354

تجدر الإشارة على الرغم من هذا كان فقط المقصود من أي وقت مضى لعيني وليس للاستهلاك العام، حتى يبرر حقيقة انها الفوضى كما الجحيم:)

نصائح أخرى

وإحدى الطرق للقيام بذلك هي من خلال إنشاء UILabel ثم جعل طبقة لها في الملمس. سيكون طريقا غير مباشر لهذا ستكون أولا بإعداد UILabel مع النص، والخط، وغيرها، وبعد ذلك استخدام التعليمات البرمجية التالية

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

ولالتقاط UILabel إلى UIImage. هل يمكن بعد ذلك استخدام initWithImage: منشئ فئة Texture2D في المشروع CrashLanding لتحويل هذا إلى نسيج

ويبدو initWithImage: في هذا المثال إعادة يجعل UIImage إلى سياق النقطية ويستخدم هذا لخلق نسيج. مع القليل من العمل، هل يمكن استخلاص شفرة ذات الصلة من تلك الطريقة وتغيير رمز أعلاه لجعل طبقة الخاصة بك مباشرة في الملمس.

وبهذه الطريقة، يمكنك الحصول على لطيفة يونيكود والخط دعم UILabel عند إنشاء نص الملمس الخاص بك.

ولقد وجدت حل بسيط لهذه. وهنا وظيفة سريعة كتبت عن ذلك. (سوف تحتاج إلى الدرجة 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);    
}

وأعتقد أن إدخال الإحداثيات يجب أن تكون في إحداثيات العالم الذي تعيشون فيه، ولكن لست متأكدا إذا كان ذلك صحيحا بشكل عام أو ما اذا كان يعمل فقط على هذا النحو بالنسبة لي. قد تحتاج للعب مع إزاحة للحصول على ذلك الحق.

وشكرا لهذا الأسلوب. أنها وفرت لي بعض الوقت.

وكانت هناك بضعة أشياء اضطررت الى تغيير بالرغم من ذلك. الدعوة glBlendFunc اللازمة ليكون:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_ALPHA)

وثانيا، يبدو أن النص المراد رسم في نقطة واحدة. الدعوة CGRectMake هو خلق المستطيل 1X1، إلا إذا أنا أقرأ أن بشكل غير صحيح.

استخدم في "تأملات" مكتبة الخط:

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;

ولقد خلقت فئة الخط مماثلة إلى المكتبة الخط "التأملات"، ناقص تسرب الذاكرة وناقص خلق نسيج لكل حرف، كل إطار. فإنه لا يزال يستخدم glTexture مختلفة لكل حرف بالرغم من ذلك. ملاحظة: تم تغيير Texture2D التعليق الخروج حذف نسيجه

والحرف الأول في المنشئ: _font = new Font("Helvetica", 40);

واستخدامها في إعادة رسم () الأسلوب: _font->draw("Hello, World!", 50, 100, ALIGN_LEFT);

وصلة جيثب:

https://github.com/chandl34 / العام / شجرة / سيد / الشخصية / ج٪ 2B٪ 2B / الخط

وتحقق التجريبي تحطم الهبوط. الطبقة Texture2D التي يتم توفيرها يسمح لخلق القوام مع النص والخط. (نأمل أن تكون هناك إجابة أفضل أحب طريقة أسهل للسحب إلى وجهة نظر opengles)

نعم ، هناك 2 علمي.هو خدعة ، عليك أن تجعل إلى نسيج باستخدام الكوارتز (CGContext* وظائف) ، ثم تقدم أن نسيج للمستخدم أن يرى.

إذا كنت قلقا بشأن الأداء, يمكنك أيضا استخدام الكوارتز لتوليد نسيج أطلس.

من السهل إلى حد ما جهز نسيج الجيل أداة (في كسكودي) بمجرد أن تعرف أساسيات التقديم الخط.

كل ما عليك القيام به هو صالح CGContext.يمكنك أن تجد بعض عظيم حقا نموذج التعليمة البرمجية في هذه نسيج محمل.

في الأساس رمز المثل:

// 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 ;

يخرج تبدو جيدة جدا و والحواف المحسنة,

tex atlas

قائمة دائرة الرقابة الداخلية الخطوط متوفرة هنا, و مع prerenders هنا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top