翻译:Panda3D Manual/V. Programming with Panda/J. Text and Image Rendering
来源:互联网 发布:jenkins 插件源码下载 编辑:程序博客网 时间:2024/05/20 14:42
文本和图片渲染(Text and Image Rendering)
Panda能够在屏幕或3维世界动态地绘制文字,它支持全部Unicode字符集,可以方便地渲染各国语言(包括亚洲语言,但要选择恰当的字体)。
Panda3D提供3种文本接口,你可以按需选择:TextNode是基础的文本渲染类,其他两个类都是构建于它之上;OnscreenTex是TextNode的高层封装,OnscreenImage和OnscreenTex类似,但它用于渲染图片;DirectLabel也是TextNode的高层封装,它集成到DirectGUI系统中。
国际字符集
Panda把输入的文本字符串默认当成iso8859格式,该格式在Linux上称为Latin-1,它的一个字符占用一个字节,支持绝大部分的字母文字,在大多数情况下适用。如果想用iso8859以外的字符,就必须使用更高级的编码系统如utf-8(一个字符可以占用1个、2个或3个字节)。为了使用utf-8,将下面这行写入你的Config.prc文件:
text-encoding utf8
然后,确保你输入的字符串是“utf-8”编码格式,例如你可以把你的Python源代码文件保存为“utf-8”格式(Windows下实现起来比较麻烦,我们推荐使用非微软的编辑器如Emacs或Eclipse)。
字体(Text Fonts)
Panda3D支持多种字体,如果你的Panda3D在支持FreeType库的条件下编译(Panda3D发行版默认已经支持),就可以直接载入任意的TTF文件,或者其他FreeType支持的字体文件:
font = loader.loadFont('arial.ttf')
字体文件的搜索路径跟模型文件的搜索一样,你也可以给出字体文件的完全路径(注意使用Panda的路径格式)。
也可以使用panda提供的egg-mkfont命令行工具来预生成一种字体:
egg-mkfont -o arial.egg arial.ttf
该命令将生成一个egg文件(上例中为arial.egg文件)和一个相关的纹理文件,可以当成字体来载入:
font = loader.loadFont('arial.egg')
egg-mkfont工具有很多种参数,使用“egg-mkfont -h”列出全部选项。
预生成字体的好处是,(a)所得到的egg文件可以被不支持FreeType的Panda版本使用,(b)可以使用Photoshop等图像工具对得到的纹理图片进行修改,制作出某种文字效果。但从另一方面来说,你必须预先确定你要对哪种字符集使用字体,默认字符为ASCII字符。
在Panda3D发行版的模型文件夹里有3种默认的字体文件,分别是“cmr12.egg”,一种罗马字体,“cmss12.egg”一种Sans-Serif 字体,“cmtt12.egg”一种Teletypewriter风格的固定宽度字体。这3种字体是由Metafont工具(Panda3D不包含)提供的免费字体。如果你没有加载其他字体,panda会使用一种默认的字体图片。
Text Node
Panda3D最基础的渲染文字方法就是TextNode接口,它用起来可能不如OnscreenText或DirectLabel对象那么方便,但它能对文字进行更多的控制。
使用TextNode,只需创建一个TextNode对象并调用setText()来设定要显示的文本,然后把TextNode连接到任何地方(可以把它放到aspect2d节点下,产生一个2维屏幕文本,或放到3维场景中)。注意,如果你把文本连接成render2d或aspect2d的子节点,你必须给它一个很小的缩小比例,因为在render2d中整个屏幕空间坐标大小仅为 (-1, 1)。
text = TextNode('node name')
text.setText("Every day in every way I'm getting better and better.")
textNodePath = aspect2d.attachNewNode(text)
textNodePath.setScale(0.07)
注意TextNode的构造函数接受一个字符串名字,但该名字与要显示的文本没有任何关系,而且默认的文本颜色为白色;在此文本显示为黑色是为了便于读者阅读。
TextNode为我们提供大量的属性用以调节文字的形态。
字体
cmr12 = loader.loadFont('cmr12.egg')
text.setFont(cmr12)
你可以使用任何字体,包括TTF文件。见前面的字体部分。
缩小的大写字母
text.setSmallCaps(1)
setSmallCaps()接受一个布尔值;真的话将进入缩小大写模式。在这个模式下不显示小写字母,而大写字母要比真实的大小要小。它用于字体没有小写形式时。
可以指定“小写”字母的大小:
text.setSmallCapsScale(0.4)
值为1.0时与大写字母同等大小,0.5为一半大。默认值为0.8。
倾斜
text.setSlant(0.3)
Slant用以模拟斜体字的效果。参数值为0.0时不倾斜,1.0为45度右倾。一般把值设为0.2到0.3的效果最好。可以用一个负数得到反方向的倾斜。
颜色
text.setTextColor(1, 0.5, 0.5, 1)
颜色值由r、g、b、a四个分量指定。注意a值如果不是1,文本将有些透明。
阴影
text.setShadow(0.05, 0.05)
text.setShadowColor(0, 0, 0, 1)
阴影只是一份文本的拷贝,在原文本后面显示,向右下方稍稍偏移一点位置,造成文字突出平面的感觉,尤其当文字颜色与背景颜色对比度不太高时很明显。(本例的文本颜色与背景相近都是粉色,可以看到其阴影效果很清晰)使用阴影的缺点就是渲染文字所需的多边形变成了2倍。
设置阴影需要调用两个函数:setShadow()接受一对数字参数,分别指定阴影向右、向下偏移的距离,用的是屏幕的长度单位;一般是一个很小的数如0.05。setShadowColor()接受指定阴影的rgba颜色,默认为白色。
行宽(Wordwrap)
默认状态下,文本将以一行显示,除非它包含换行字符。打开行宽将根据指定的行宽自动将文本分割为多行:
text.setWordwrap(15.0)
setWordwrap()的参数是每一行的最大宽度,用的是屏幕的长度单位。
对齐
文本默认为左对齐;从textNodePath.setPos()指定的位置开始向右显示文字。如果文本有多行,可以居中对齐或右对齐:
text.setAlign(TextNode.ACenter)
setAlign()的参数应该是TextNode.ALeft、TextNode.ACenter和TextNode.Aright其中之一。注意改变对齐方式将改变文本的起始位置。
边框
可以在文本外围绘制一个矩形边框:
text.setFrameColor(0, 0, 1, 1)
text.setFrameAsMargin(0.2, 0.2, 0.1, 0.1)
和阴影一样,设置边框需要两个函数:一个指定颜色,另一个指定边框的尺寸。setFrameAsMargin()指定4个参数,分别给出上下左右边框与文本之间的距离。全部4个都是0.0时边框紧紧包围文本(即使某些字体会超出边界)。
卡片(Card)
最后,你可以在文本矩形之后绘制卡片效果:
text.setCardColor(1, 1, 0.5, 1)
text.setCardAsMargin(0, 0, 0, 0)
这样做使文本在相近的背景色下更方便阅读。通常卡片是半透明的,可以通过setCardColor()指定alpha值为0.2或0.3。
setCardAsMargin()的参数与setFrameAsMargin()一样:分别是卡片上下左右的距离。(本例,我们同时设置了卡片和边框,你可以把卡片设成与文本吻合,而边框则要宽一些——setCardAsMargin()与上例中setFrameAsMargin()参数稍微不同。)
拾取(pick)一个TextNode
严格说来,TextNode没有几何数据,因此不能被拾取。
有2种可能的办法:
(1)在TexeNode后面创建一个卡片,使用CardMaker。可以用cardMaker.setFrame(textNode.getFrameActual())设定卡片的大小与文本框架相同。然后你需要将文本从卡片前面移出几英寸以消除Z-fighting现象,或者显示地把文本贴花(decal)到卡片上,如下:
card = NodePath(cardMaker.generate())
tnp = card.attachNewNode(textNode) card.setEffect(DecalEffect.make())
(2)不要把TextNode直接连接到scene graph,而是把textNode.generate()返回的节点连接到scene graph。它是一个静态节点,包含渲染文本的多边形。之后文本若发生了改变,它并不自动更新此节点的几何模型;你必须用新的textNode.generate()代替旧的节点。但该节点是百分之百可以被拾取的。如果已经指定textNode.setCardDecal(1),那么该节点的第一个子节点应该就是卡片的几何模型。
OnscreenText
为方便用户使用,OnscreenText对象对TextNode进行了封装,使用它,可以快速地在屏幕上显示文本而不必创建TextNode和进行一系列格式设置。但它不提供TextNode那样对渲染的直接控制,也不支持DirectLable的DirectGUI属性。显示普通文本时用OnscreenText是一种快捷的方法:
from direct.gui.OnscreenText import OnscreenText
textObject = OnscreenText(text = 'my text string', pos = (-0.5, 0.02), scale = 0.07)
OnscreenText对象继承自NodePath,因此可以对文本对象使用所有标准的NodePath操作。当你不再需要这些文本使,使用:
textObject.destroy()
下面是构造函数的几个关键参数:
text
要显示的文本。如果暂时没有可以留空,在以后通过setText()指定,但最好预先指定
style
一个在OnscreenText.py文件头部定义的预定义参数。你没有指定的参数会有一个默认的值;但是,指定的参数值将覆盖掉预定义的值
pos
文本在屏幕上的x、y位置
scale
文本的大小。单个浮点数(通常是一个很小的数如0.07)或者是一个浮点数2元组,指定x、y方向上的缩放值
fg
指定文本的(r、g、b、a)前景色,各分量的值可以是浮点数也可以是整数
bg
指定文本的(r、g、b、a)背景色,如果第四个分量a的值不为0,文本后面将出现一个对应颜色的卡片
shadow
指定阴影的(r、g、b、a)颜色,如果第四个分量a的值不为0,文字将产生阴影
frame
指定文本边框的(r、g、b、a)颜色,如果第四个分量a的值不为0,文字将有边框
align
TextNode.ALeft、TextNode.ACenter和TextNode.Aright三个值其中之一
wordwrap
文字的行宽,留空表示自动行宽
font
文本的字体
parent
文本的父节点NodePath,默认为aspect2d
mayChange
当文本属性需要在运行时动态改变时值设为真,值为假时属性保持不变(此时内存更加优化)。默认为假。
OnscreenImage的作用与OnscreenText新近,但它用于显示图片而不是文本。
OnscreenImage
和OnscreenText一样,OnscreenImage是一个在屏幕上快速显示图片的方法,如果想要显示一张常规的图片而没有其他要求时,就使用OnscreenImage:
from direct.gui.OnscreenImage import OnscreenImage
imageObject = OnscreenImage(image = 'myImage.jpg', pos = (-0.5, 0, 0.02))
可以使用setImage()来变换另一张图片:
imageObject.setImage('myImage2.jpg')
如果想去掉图片,如下:
imageObject.destroy()
下面列出该类构造器的关键参数:
image
要显示的图片或一个文件名。如果暂时没有可以留空,在以后通过setImage()指定
pos
在屏幕上的x、y、z位置,一个浮点3元组或一个向量,y值为0
scale
图片的大小,可以是单个浮点数,也可以是一个3元组或一个向量,y值应该为1
hpr
图片的h、p、r值,可以是一个浮点3元组或一个向量
color
图片的(r、g、b、a)颜色,通常是一个浮点或整数4元组
parent
图片的父节点NodePath,默认为aspect2d
注意:为了打开图像透明度,必须首先设置TransparencyAttrib,否则图片的透明部分将会显示为黑色:
from pandac.PandaModules import TransparencyAttrib
self.myImage=OnscreenImage(image = 'myImage.png', pos = (0, 0, 0))
self.myImage.setTransparency(TransparencyAttrib.MAlpha)
Panda不支持GIF,因此需要图片透明时应该使用PNG或TGA。
植入的文本属性(Embedded Text Properties)
我们可以在一个段落当中改变文本的属性。为此,必须首先定义你想改变的文本属性,为每种属性命名。然后你就可以对字符串中的某些字符使用这些预定义的文本属性。
定义你的文本属性
可以创建任意多个TextProperties对象。每个对象保存一种文本属性,你可以对一个TextNode直接应用其中一种属性。这些属性包括单个字符属性如字体、颜色、阴影和倾斜,以及文字行格式属性如对齐和行宽。
tpRed = TextProperties()
tpRed.setTextColor(1, 0, 0, 1)
tpSlant = TextProperties()
tpSlant.setSlant(0.3)
tpRoman = TextProperties()
tpRoman.setFont(cmr12)
在一个TextProperties对象里你可以尽量多或尽量少地设定不同属性。只有你指定的属性才会应用到文本字符串;你没有指定的属性将维持不变。上例中,对某个文本字符串应用tpRed将只会把文本颜色变为红色;其他属性,如倾斜、阴影和字体,将维持原状。类似的,tpSlant只改变文字的倾斜度,tpRoman只改变字体。
注册新的TextProperties对象
需要一个指向全局TextPropertiesManager对象的指针:
tpMgr = TextPropertiesManager.getGlobalPtr()
在创建了TextProperties对象之后,你必须在TextPropertiesManager中注册,并为每个TextProperties对象取一个不同的名字:
tpMgr.setProperties("red", tpRed)
tpMgr.setProperties("slant", tpSlant)
tpMgr.setProperties("roman", tpRoman)
在文本字符串中引用TextProperties
现在你可以在字符串中放入特殊字符以激活这些变化的属性。为此,你将使用特殊字符‘/1’,或者ASCII值0x01的字符。用两个‘/1’作为某种引号标出注册TextProperties时使用的名字,例如,‘/1red/1’激活tpRed,‘/1slant/1’激活tpSlant。
序列‘/1red/1’作用相当于一个push命令,它把tpRed添加到当前的文本属性,先前的属性也被记录下来。要回到原来的属性状态,使用‘/2’字符。每个‘/2’将撤回最近一次‘/1name/1’激活的属性。
下面这个函数:
text.setText("Every day in /1slant/1every way/2 I'm /1red/1getting /1roman/1better /1slant/1and/2 better./2/2")
得到文本字符:
可以对任何产生文本的Panda结构使用这些特殊字符,包括TextNode、OnscreenText和任何DirectGui对象。
- 翻译:Panda3D Manual/V. Programming with Panda/J. Text and Image Rendering
- 翻译:Panda3D Manual/V. Programming with Panda/Q. Panda Rendering Process
- 翻译:Panda3D Manual/V. Programming with Panda/V. Math Engine
- 翻译:Panda3D Manual/V. Programming with Panda/E. Camera Control
- 翻译:Panda3D Manual/V. Programming with Panda/F. Sound
- 翻译:Panda3D Manual/V. Programming with Panda/G. Intervals
- 翻译:Panda3D Manual/V. Programming with Panda/K. DirectGUI
- 翻译:Panda3D Manual/V. Programming with Panda/L. Render Effects
- 翻译:Panda3D Manual/V. Programming with Panda/M. Texturing
- 翻译:Panda3D Manual/V. Programming with Panda/S. Particle Effects
- 翻译:Panda3D Manual/V. Programming with Panda/T. Collision Detection
- 翻译:Panda3D Manual/V. Programming with Panda/U. Hardware support
- 翻译:Panda3D Manual/V. Programming with Panda/W. Physics Engine
- 翻译:Panda3D Manual/V. Programming with Panda/X. Motion Paths
- 翻译:Panda3D Manual/V. Programming with Panda/Y. Timing
- 翻译:Panda3D Manual/V. Programming with Panda/Z. Networking
- 翻译:Panda3D Manual/V. Programming with Panda/G. Intervals
- 翻译:Panda3D Manual/V. Programming with Panda/D. Actors and Characters
- div+css 布局
- 翻译:Panda3D Manual/V. Programming with Panda/H. Tasks and Event Handling
- 5 Most Common Web Standards Misconceptions
- 翻译:Panda3D Manual/V. Programming with Panda/I. Fog and Lighting
- 关于HTML,input radio的奇怪问题。
- 翻译:Panda3D Manual/V. Programming with Panda/J. Text and Image Rendering
- 翻译:Panda3D Manual/V. Programming with Panda/K. DirectGUI
- 翻译:Panda3D Manual/V. Programming with Panda/L. Render Effects
- Flash P2P 通信技巧 (AS-Java-AS)
- 翻译:Panda3D Manual/V. Programming with Panda/M. Texturing
- 翻译:Panda3D Manual/V. Programming with Panda/N. Pixel and Vertex Shaders
- 翻译:Panda3D Manual/V. Programming with Panda/O. Finite State Machines
- NASM源代码分析之预处理(2)
- 翻译:Panda3D Manual/V. Programming with Panda/P. Advanced operations with Panda's internal structures