




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、任何一个DEMO、仿真项目、游戏,都少不了文字这种媒体。这不可不说是对图形视觉媒体的补充我们还有一些无法超越文字来向观众表达的心事,或是补充说明,或是感悟,或是感激。ZwqX一般的文字不属于图形渲染部分,而属于用户界面部分,这在游戏引擎中看或许一目了然,但是在底层的图形渲染APIOPENGL或D3D中,文字的显示“并不是必须”,但它是多么深深地被需要着口牙。所以,把字体设置、文字显示作为一种图形学技术而非单纯的完全我属或他属,我是这么想的。(同样,拾取也算是这样吧?乱弹OpenGL选择-拾取机制)本文来源于ZwqXin( 转载请注明原文地址:怎么表达文字呢?在OpenGL中,我们没有什么现成的
2、东西可用,但确实有办法让我们“得到这种技术”。让我最记忆深刻的是NEHE的两三篇教程(貌似都是十几课吧),讲述的就是今天的这个主题。可以到NEHE网站或者在DANCINGWIND的中文翻译(见搜集的优良OpenGL教程 )看看。而我所知道的这三种方法,前两种应该就是来自那里吧(记得),当时要努力完成课程DEMO,于是胡胡混混地就把相应的那两三课学了,而且把它的文字显示方法应用到自己的程序中(还经历了一段艰辛的探索史.连我当时的MyFont类也记录了这份小辛酸,现在看来,是因为当时的知识水平不够理解吧)。然后后来又一个课程DEMO,老师后来觉得我应该“写中文”,于是我又去探索中文字体显示方法了,
3、并在一个开源DEMO中找到,分析代码段后就拿来主义了,至昨不曾好好考究这就是我所知的第三种方法。三种方法都是三步曲:在初始化的时候“创建字体”Build,在渲染阶段“应用字体”(显示文字)Print,在程序结束或不再需要文字显示的时候“销毁字体”kill。其中前两步比较重要,着重讨论讨论哈1. 常规的屏幕字体打印(NormalFont)应用得比较广,大名鼎鼎的AZURE以前的DEMO就是用这个的。NEHE教程中作为首次出现的字体显示方法,介绍应该比较全面,大家想仔细了解的话请务必从上面网址进入学习(当然还有因为我理解不透不敢乱讲的缘由)。1. /一般的英语字体打印2. voidMyFont:B
4、uildGLFont(intfontHeight)3. 4. HDChDC=:GetDC(HWND_DESKTOP);/就是这里搞晕了半晚5. 6. inttFontHeight=-1*fontHeight;7. 8. NormalFontBase=glGenLists(96);/StorageFor96Characters9. HFONTfont=CreateFont(-tFontHeight,/HeightOfFont10. 0,/WidthOfFont11. 0,/AngleOfEscapement12. 0,/OrientationAngle13. FW_BOLD,/FontWeigh
5、t14. TRUE,/Italic15. FALSE,/Underline16. FALSE,/Strikeout17. ANSI_CHARSET,/CharacterSetIdentifier18. OUT_TT_PRECIS,/OutputPrecision19. CLIP_DEFAULT_PRECIS,/ClippingPrecision20. ANTIALIASED_QUALITY,/OutputQuality21. FF_DONTCARE|DEFAULT_PITCH,/FamilyAndPitch22. Georgia);/FontName23. 24. HFONToldfont=(
6、HFONT)SelectObject(hDC,font);/SelectsTheFontWeWant25. 26. wglUseFontBitmaps(hDC,32,96,NormalFontBase);/Builds96CharactersStartingAtCharacter3227. 28. SelectObject(hDC,oldfont);/SelectsTheFontWeWanttoreturnto29. DeleteObject(font);/DeleteTheFont30. 31. SetBkMode(hDC,TRANSPARENT);32. 33. NormalFont=tr
7、ue;34. 其中bUild的时候首先用到的是GDI的CreateFont函数创建字体这应该是比较常用的方法,设置了关于字体的一切并选入字体后,有一步重要的操作:wglUseFontBitmaps。1. 2. wglUseFontBitmap3. 为当前选中的GDI字体创建一组OpenGL显示列表位图字体4. BOOLwglUseFontBitmap(HDChDC,DWORDdwFirst,DWORDdwCount,DWORDdwListBase);5. 6. 参数7. hDC8. 设备环境句柄9. 10. dwFirst11. 用于创建显示列表字体的第一个字符的ASCII值12. 13. d
8、wCount14. 字符数15. 16. dwListBase17. 第一个显示列表的名称18. 19. 返回值20. 成功返回TRUE,否则返回FALSE21. 输入为DC,32,96以及创建的96个新显示列表的base列表。函数绘制从ASCII码为32-128的字符进入显示列表,依赖OPENGL显示列表的高速显示能力(直接从硬件拿存储区),可以方便进行字符的切换。在Print过程中,调用glCallLists就能调动起这些列表了,但是怎么决定具体要“调动”哪些字母呢(96个之中)?1. voidMyFont:PrintGLText(GLintx,GLinty,constchar*strin
9、g,.)2. chartext256;3. va_listpArguments;4. 5. if(string=NULL)6. return;7. 8. va_start(pArguments,string);9. vsprintf(text,string,pArguments);10. va_end(pArguments);11. 12. 13. glPushAttrib(GL_LIST_BIT|GL_CURRENT_BIT|GL_ENABLE_BIT|GL_LIGHTING_BIT);14. glDisable(GL_DEPTH_TEST);15. glDisable(GL_LIGHTIN
10、G);16. glDisable(GL_TEXTURE_2D);17. glColor4f(mColor0,mColor1,mColor2,mColor3);18. 19. glWindowPos2i(x,y);20. 21. glListBase(NormalFontBase-32);22. glCallLists(strlen(text),GL_UNSIGNED_BYTE,text);23. glPopAttrib();24. 首先看函数形式printf形式,若想有个详细了解,可到这里看看。简单来说,就是C时代的可变参数列。va_start - vsprintf - (va_arg)- v
11、a_end这套机制就是为了把可变参数列的内容,通过va_list(char*指针)一个一个从栈中取出来赋予他者我们的glCallLists所要接受的所有“具体字符”,通过base为基础的索引快速寻觅而取得对应ASCII字符的字体信息(实际是位图字体),并依照期望使其形成为“具体字符串”印入屏幕。另外着重介绍的是我所添加的两个优化它们贯穿三种文字显示方法之中。其一是glPushAttrib,它与glPopAttrib配合,保证了其之间的OPENGL状态设置的独立性,使其不影响该代码逻辑的前后的具体渲染状态。当然参数取GL_ALL_ATTRIB_BITS是保险点,但只要你弄清楚自己的需要,像上面这
12、样给予特定的状态作为参数效率会更高。恩,颜色,光照,深度测试,混合选择与当前方法最匹配的状态而没有对状态机的后顾之忧,如同文字本身一样作为对象完全独立于图形渲染“模块”。另一是glWindowPos2i(x,y),按OpenGL编程指南第8章所说,它取代我们以前用的glRasterPos2i,不再让作为描绘对象的物体承受模型-视图-投影变换之苦乱弹OpenGL中的矩阵变换(上) ,而是直接独立到OPENGL世界的出口屏幕坐标系,如GDI般用窗口坐标(根据屏幕像素数)来描述文字的起点位置。这同样是赋予文字的独立性,而且意义重大可知道,当时我用glRasterPos2i多么狼狈,好难才让文字不在场
13、景“里面”乱窜。在具体应用中,在初始化调用BuildGLFont.,在渲染阶段调用PrintGLText。譬如:1. /CMAINFRAME2. MyFontmFont;3. 4. /初始化:5. mFont.BuildGLFont(25);/25是字体字高,控制字体大小6. 7. /渲染阶段(RenderGLScene)8. 9. mFont.PrintGLText(530,710,http:/www.Z-My3DGraphics);10. 11. /将在坐标X=530,Y=710位置开始绘制文字。对1024*768大小的渲染窗口中,即在右上角注意,OpenGL窗口坐标系的原点在窗口的左下角
14、,横坐标为X,竖坐标为Y,最大值在右上角。(同见乱弹OpenGL选择-拾取机制 )浏览一下效果,第一行就是了,因为我默认用的是Georgia字体(应该一般人电脑都有),所以很漂亮接下来会谈及其余两种方法,并比较之。真正的纹理文字是怎样弄的呢?怎样让中文字体乖乖显示?什么时候用哪种方法?我集成的MyFont类是怎样个怪样?听下回分解:在OpenGL上设置字体和显示文字(下)本文来源于ZwqXin( 转载请注明原文地址:Tags:OpenGL代码工具类C分类:OpenGL技术| 评论:1 | 引用:0 | 浏览:7399 水效果 - 水池在OpenGL上设置字体和显示文字(下) 分享到新浪微博QQ
15、空间腾讯微博人人网豆瓣0 点击这里获取该日志的TrackBack引用地址 相关文章: 乱弹OpenGL选择-拾取机制(下)(2009-6-14 23:3:8)乱弹OpenGL选择-拾取机制(上)(2009-6-13 16:54:2)子类调用父类的纯虚函数之问题(2009-6-8 23:18:32)视锥类CFrustum .zwqxin ver(2009-6-2 22:39:52)标准MFC在OpenGL(2009-5-31 17:46:47)QuickSort 快速排序的实现(2009-5-6 1:21:55)全屏反锯齿 - 多重采样(2009-5-3 19:50:7)全屏反锯齿 - 多重采样
16、(2009-5-2 16:21:56)图像处理里的空间域滤波(2009-4-27 23:53:18)一年前,首次献给OpenGL之夜.雷达追踪(2009-4-5 22:18:52)在OpenGL上设置字体和显示文字(下)2009-8-6 10:22:27 | 发布:zwqxin本篇紧随上篇,继续说一下鄙人所了解的在OpenGL进行文字显示的方法,也方便不知从哪个次元来到这里的学习者提供一点这方面的信息。上一篇见:在OpenGL上设置字体和显示文字(上) ZwqX本文来源于ZwqXin( 转载请注明原文地址:2. 纹理字体最近接触Irrlicht引擎,里面的GUI模块涉及的字体设置就是用了这种纹
17、理字体的方法。事实上,上篇的方法最后多少了涉及到了位图字体,但是这里所说的,是直接从一张“写着各个英文字符和其他常用字符”的纹理上,按对此纹理上的图案“结构”的先验知识而获取字符对应的“纹理部分”,显示到屏幕上。换句话来说,这就是真正的纹理贴图了,因此必须结合一张特定设计的“字体纹理”。要显示一个字符,需要你绘制一个一定大小的矩形(这个长度值相当于之前的字体高度它控制最后出来的文字的大小),然后找到你所需字符在该纹理上的纹理坐标,作为索引检索出纹理上的对应字符部分的小纹理,贴到该矩形上。1. 2. /从字体集纹理中取出的字符3. voidMyFont:BuildTextureFont(GLui
18、ntfonttex,intfontHeight,intscreenWidth,intscreenHeight)4. 5. TextureFontFont=fonttex;6. 7. floatcx;/HoldsOurXCharacterCoord8. floatcy;/HoldsOurYCharacterCoord9. 10. glEnable(GL_TEXTURE_2D);11. 12. TextureFontBase=glGenLists(256);/Creating256DisplayLists13. 14. glBindTexture(GL_TEXTURE_2D,TextureFont
19、Font);/SelectOurFontTexture15. 16. for(intloop=0;loop1)TextureSet=1;5. if(TextureSetbmiHeader.biSize=sizeof(binf-bmiHeader);33. binf-bmiHeader.biWidth=bm.bmWidth;34. binf-bmiHeader.biHeight=bm.bmHeight;35. binf-bmiHeader.biPlanes=1;36. binf-bmiHeader.biBitCount=1;37. binf-bmiHeader.biCompression=BI_
20、RGB;38. binf-bmiHeader.biSizeImage=bufsize;39. 40. UCHAR*Bits=newUCHARbufsize;41. :GetDIBits(MDC,bitmap,0,bm.bmHeight,Bits,binf,DIB_RGB_COLORS);42. 43. glPixelStorei(GL_UNPACK_ALIGNMENT,1);44. 45. /glRasterPos2i(x,y);46. glWindowPos2i(x,y);47. glBitmap(size.cx,size.cy,0,0,0,0,Bits);48. 49. deleteBit
21、s;50. SelectObject(MDC,oldBmp);51. :DeleteDC(MDC);52. 53. 54. voidMyFont:PrintGDIText(GLintx,GLinty,CStringstr)55. 56. glLoadIdentity();57. glPushAttrib(GL_CURRENT_BIT|GL_LIGHTING_BIT);58. 59. glDisable(GL_TEXTURE_2D);60. glDisable(GL_LIGHTING);61. 62. glColor4f(mColor0,mColor1,mColor2,mColor3);63.
22、64. PrintfChtext(x,y,str);65. 66. glPopAttrib();67. glPushAttrib和glWindowPos2i的意义不多说了。看主体函数PrintfChtext。几个GDI函数: GetTextExtentPoint32用当前所选字体来计算字符串尺寸,按逻辑单位计算的高和宽都没有考虑裁剪取的情况。 CreateBitmap创建单位色位图。函数所做的是依据字符串大小建立一张单色位图,把该位图信息存入UCHAR数组Bits内。类似的操作在认识HBITMAP与Bmp操作(整内存拷贝版) 也谈过,所以细节部分譬如为什么要取宽度位8倍数等等就略过。重点是要把
23、数组Bits交给谁。恩,glBitmap函数道出了一切。OpenGL里除了几何对象(点、线、多边形)和纹理图像对象外,还有一种不常用的对象,位图Bitmap。一般来说这样的位图是灰度的,也就是位图矩块内每个像素只有1BIT的信息0 OR 1。这对文字来说正好,因为文字就是黑色(/透明)背景中的白色部分,黑白分明。颜色可以在绘制位图后用glColor设置嘛。glBitmap函数就是用来根据数据显示位图的。而该位图内可以说是被打印了GDI文字上去(用TextOut),于是最后在屏幕上的还是位图文字,且可以用glWindowPos2i调节起始点位置。就这样,完成的GDI文字从基于DC的GDI环境,显示到基于RC的OPenGL环境上。可喜可贺。具体应用:1. 2. /CMAINFRAME3. MyFontmFont;4. 5. /初始化:6. mFont.BuildGDIFont(宋体,FW_NORMAL,25);7. /25是字体字高,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 公司房租租凭合同范本
- 劳动安全协议合同范本
- 包子店加盟签约合同范本
- 人工打草合同范本
- 冲孔加工销售合同范本
- 2024年河南省直第三人民医院招聘笔试真题
- 第14课《回忆我的母亲》教学设计 2024-2025学年统编版语文七年级上册
- 力工合同范例
- 中国铁建合同范本
- 包月工作合同范本
- 让孩子变成学习的天使——由《第56号教室的奇迹》读书分享
- 外阴及阴道炎症
- 球泡检验标准
- 公安笔录模板之询问嫌疑人(书面传唤治安案件)
- 振动分析基础讲义1
- 记账凭证汇总表excel模板
- 邓丽君经典歌曲30首简谱(共33页)
- 故障诊断技术的国内外发展现状(共3页)
- 园林绿化施工通用表格模板
- 初中《生物》(人教版)实验目录表
- 人民检察院信访案件终结办法
评论
0/150
提交评论