【Ogre编程入门与进阶】第十五章 Ogre的“二维”与合成特效

本文详细介绍了Ogre 3D图形渲染引擎中处理二维内容的方法,重点讲解了“表层(Overlay)”的概念,包括其作用、属性和框架结构。通过实例展示了如何创建和使用表层,以及如何通过表层对象进行定位和属性设置。此外,文章还探讨了如何在表层中添加3D元素,以及使用合成器(Compositor framework)实现后处理特效,包括合成器链的应用,帮助读者理解Ogre中二维与合成特效的实现原理。
摘要由CSDN通过智能技术生成

15.1 Ogre中的“二维”

        早在第一章,我们就曾经向读者介绍过,Ogre是一个3D图形渲染引擎,通过Ogre可以制作出各种各样的三维动画和游戏。但是,不要以为Ogre中只能渲染跟3D相关的物体,Ogre同样可以渲染跟2D相关的物体,比如:图形、图片、文字等等。另外,在开发一些小型2D游戏(而非大型3D游戏)的时候,可能只是需要Ogre进行“二维”的编程,而无处理与“三维”有关的操作。

15.2 “表层(Overlay)”的概念

        在Ogre 中,“二维”的处理总是与“表层(Overlay)”的概念密切相关,这是因为Ogre中将所有的与“二维”相关的处理都被放置在称为“表层(Overlay)”中。顾名思义,表层是实质上是一个层,这个层覆盖在场景中所有其他的物体之上,而且,还有一点需要注意的是,表层在渲染队列的最后,也就是说,表层是场景中最后被渲染的。

        单纯从文字上讲,读者可能会对Ogre中“二维”、“表层”这些概念感到不好理解,其实,在我们之前章节的实例中,几乎每次都会看到Ogre中的“表层”。下面我们来看一个实例运行时的界面:

        上图是我们在第五章,运行一个实例的界面,可以看到,在界面中有一个三维的“食人魔”怪兽,另外在界面的左下角和右下角,分别有两个“层”(已用红框标出),它们是“二维”的,这就是Ogre中的“表层”。

 

笔者注:

        Ogre中的表层(Overlay):一般是用来制作Gui界面的,但是这个Gui界面不具备用户交互的功能。这些表层位于整个“屏幕”的最上层,就像上图所示的那样。当然,读者可以自己设置“表层”的属性,如形状、大小、颜色和透明度等。

        当然,Ogre中的表层不一定非得应用于Gui界面,如果在三维游戏中需要使用二维的画面,也可以利用表层来实现。比如,在一款三维游戏中有一面墙,上面挂着一幅风景画,那么就可以利用表层来实现这个这个二维的“墙壁加风景画”的效果。

 

 

        还有一点要特别注意,Ogre中的二维常常通过表层来处理,但是,不是说表层只能处理与二维有关的物体,事实上,表层也可以处理与三维有关的物体。

 

15.3 表层的框架结构

15.3.1 基本概念

        所谓的表层框架,就是一个表层整体的布局和结构,因为不同的表层上的元素都有不同的布局样式和结构层次。下面的这段脚本代码,就可以生成一个完整的表层框架:

 

MyOverlay

{

         zorder 500

       

         container Panel(MyContainer1)

         {

                   metrics_mode pixels

                   left 0

                   top 0

                   width 50

                   height 50

 

                   container Panel(MyContainer2)

                   {

                            metrics_mode pixels

                            left 20

                            top 20

                            width 30

                            height 30

 

                            element TextArea(MyTextAreaOverlayElement)

                            {

                                     metrics_mode pixels

                                     left 15

                                     top 3

                                     width 15

                                     height 15

 

                                     font_name StarWars

                                     char_height 0.06

                                     colour 0.9 0.9 0.9

                                     caption MyTextAreaOverlayElement

                            }

                   }

           }

}

 

        通过使用这段脚本,生成的表层框架如下图所示:

 

 

        从上图可以看出,表层框架中有两种不同的“物品”:Container(容器)和Element(元素),我们可以把他们统称为表层对象。顾名思义,表层对象就是存在于表层上的实实在在的对象。表层Container(容器)用来“盛放”表层Element(元素)。对于表层对象,有如下几点需要注意

        1.表层的外层必须是一个Container(容器)类型的表层对象,正如上图中的Container1。

        2.表层中的Container(容器)可以相互嵌套,也就是说,Container(容器)中可以再包含一个Container(容器)。正如上图中的Container1中又包含了Container2、3、4。

        那么,如何对表层中的对象进行定位呢? 我们可以在脚本的代码中看到其中的端倪。一般来说,对于每一个Element和Container,都是相对于其父容器进行定位,也就是说,看这个Element或Container盛放在哪一个容器中,比如,上图中的TextAreaOverlayElement2盛放于Container3中,那么Container3就是TextAreaOverlayElement2的父容器。

        在表层对象TextAreaOverlayElement2的定义脚本中有如下一行代码:

        metrics_mode relative

        可以看出,TextAreaOverlayElement2表层对象使用了relative即相对定位的方法,而其他表层对象的脚本代码中使用的代码是:metrics_modepixels,即采用的是像素定位的方法。

 

笔者注:

        在我们选择表层对象的布局方式时,只能选择相对定位法或是元素定位法中的一种,不能同时选择两种。而且,容器本身与容器中的元素可以采用不同的定位方法。

在实际应用中,多数是采用 “相对定位” 的方式对表层元素进行定位,这样做的好处是,在我们改变窗口的大小(或是表层的大小)时,表层对象的位置不会因此而发生相对的改变,另外,使用相对定位法时,我们也无需关心用户使用电脑屏幕的分辨率,因为相对定位不会因为屏幕分辨率的不同而使表层的布局结构发生改变。

 

 

        例如,上图中的底层容器Container1被放置到了屏幕绝对位置(0,0)处,Container2被放置到了相对于Container1(也就是Container2的父容器)的(2,5)处,而元素TextAreaOverlayElement1被放置在了相对于其父容器Container2的(15,3)位置处,但如果相对于Container1来说(即电脑屏幕(0,0)处),TextAreaOverlayElement1是被放置在了(17,8)位置处。(17,8)由它本身的相对位置(15,3)和它的父容器(2,5)相加得到。

 

笔者注:

        1.在Ogre中,表层Element类下有非常多的派生类,也就是说,表层中的元素有非常多的种类,这些派生类都包括:PanelOverlayElement,BorderPanelOverlayElement以及TextAreaOverlayElement等。但是有一点需要注意,由于表层框架中不包括文本资源的类,因此如果我们需要在表层中渲染并显示文字,需要使用到表层之外的Font与FontManager类等来处理文本的渲染与显示。

        2.Ogre中的表层对象可以简单的分为两类:第一类是由Ogre进行管理的,上面的表层脚本就是其中的一个例子,这类的脚本由Ogre自身对其进行管理,多数用来进行一些简单的纹理输出与显示;第二类不由Ogre对其进行管理,比如我们在接下来会讲到的Gui界面等。这两类表层对象都可以被Ogre支持。

 

 

15.3.2 表层对象的属性

        Ogre的表层元素类和表层容器类是可扩展的,也就是说,程序开发人员可以在基类已有功能的基础上,按照自己的需要对其功能进行扩展。

        不过,也有一部分表层的属性是Ogre中自带的,这些属性包括:Panel、BorderPanel、TextArea,我们可以在脚本中改变这些属性的值,以达到改变表层的目的。下面我们就对着几个属性一一介绍:

        (1)Panel(面板)

        我们可以把Panel(面板)看作是一个矩形区域,这个矩形区域可以包含其他的表层对象(表层元素和表层容器)。我们可以改变面板的透明度、面板的材质等不同的属性,下面我们就来一一介绍:

        · Transparent属性:该属性用来设置面板是否为透明。它有两个取值(true和false),当取值为true时表示,该面板为透明背景,且面板自己无须渲染。

        ·  tiling(layer,x_tile,y_tile)属性: 该属性用来设置材质的纹理在整个面板上X和Y方向贴图的次数。layer是指纹理层,取值为0一直到总纹理层数-1,比如,一共有5个纹理层,那么layer的取值就是0到4,我们可以利用layer设置多个纹理层相互叠加的背景效果。x_tile,y_tile分别是纹理在整个面板上X和Y方向贴图的次数。

        ·uv_coords (topleft_u,topleft_v,bottomright_u,bottomright_v)属性:该属性用来设置面板上的纹理的坐标位置。

 

 

        (2)BorderPanel(边缘面板)

        这种面板同第一种Panel面板相比显得更“高级”,它比Panel多了一个“边框”,这个边框是独立于面板的,也就是说,这个边框的属性可以独立于面板本身单独的设定。如果读者有过HTML编程的经验,相信对HTML中表格的操作不会陌生。BorderPanel的操作方法就跟HTML中的表格边框的操作方法类似,下面我们就详细的讲解一下它具有的属性:

        ·border_size(left,right,top,bottom),这个属性用来设置边框的尺寸,有left,right,top,bottom四个属性值,可以为表格的“左、右、上、下”等设置不同的尺寸。

         ·border_material(name),这个属性用来设置边框的材质,属性通过将材质的名称(name)作为一个参数传递进去,是边框具备一种材质。

 

笔者注:

        边框的材质信息和面板中心区域的材质信息不同,因为中心区域里的材质通常只是平铺的,而边框上的材质往往就不能这样处理,因此,边框上面的材质通常不同于中心区域的材质。

 

        ·border_topleft_uv(u1,v1,u2,v2),这个属性用来设置边框顶部左侧的纹理坐标,与之类似的还有border_topright_uv,border_bottomleft_uv,border_bottomright_uv三个属性值,这里就不一一介绍了。

        ·border_left_uv(u1,v1,u2,v2) ,这个属性用来设置边框整体的纹理坐标,与之类似的还有border_right_uv,border_top_uv,border_bottom_uv三个属性,这里也就不一一介绍了。

 

        (3)TextArea(元素)

        通过它,可以渲染并显示文本。我们可以使用Ogre中的FontManager和Font类来定义字体,或者直接使用事先编写好的.fontdef文件。TextArea(元素)有如下的几个属性:

        ·font_name (name),这个属性用来设置要使用字体的名字。这个字体的名字通常被定义在一个.fontdef文件中,而且,在使用它之前要脚本调用这个“名字”时,它出在可用的状态。

        ·char_height(height),这个属性用来设置要显示的文字占屏幕高度的百分比。

        ·colour (red,green,blue),这个属性用来设置要显示的文字的颜色,有红、绿、蓝三个值。这三个值的取值范围都是0到1,通过这个属性,可以让我们要显示的文字有不同的颜色,使整个画面更加生动起来。不过,如果我们使用的字体已经实现定义好了颜色,那么就不必再使用这个属性了。

        ·colour_bottom(red,green,blue) 和 colour_top(red,green,blue),从这个属性的名称就可以看出来,它是用来定义文字上部和底部的颜色的,通过这两个属性,可以使文字的上部和下部显示不同的颜色,从而达到一种渐变的效果。

        (4)元素布局

        在上文中曾经介绍过,表层对象在其父容器中的定位方式有两种:相对定位法和元素定位法。每一个表层对象在其父容器中都有两个布局属性:垂直属性和水平属性。我们可以vert_align标记来设置垂直属性,标记的取值可以是top,center或者bottom中的一个;同样的,我们可以用horiz_align标记来设置水平属性,标记的取值可以是left,middle或者right中的一个。在默认的情况下,系统会自动将表层对象定位在其父容器的top和left处,也就是父容器的左上方。

 

笔者注:

        下面,我们要向读者介绍一个深度(Z-Order)的概念,有过HTML编程的读者都会对Div中的层深度非常熟悉,每一个Div都有一个Z-Order的属性值,Z-Order是一个层深度的概念,它用来区分不同的Div层的叠放顺序,Z-Order值小的层放置在下面,Z-Order值大的层放置在上面。同理,在Ogre中,表层也有一个Z-Order的属性。这里的Z-Order的作用就是:意义在于: z-order值较的层会被绘制在底层,而 z-order值较大的层被绘制在上层,覆盖下面的层,因此这个Z-Order值,实质上是用来决定表层的绘制顺序的。

 

15.4 有关表层的例子

15.4.1 表层的简单使用

        在通过示例介绍模板的使用之前,我们先来通过一些简单的示例回顾一下表层元素的一些常用属性。需要说明一点:表层元素(OverlayElement)属性可以用在表层脚本中的container或element代码块中,它们必须各自占用一行。

        第一步,在media目录下新建一个文件夹名叫MyOverlays,然后在MyOverlays文件夹下新建一个文件名叫MyOverlay1.overlay,然后在这个文件内填入以下代码:

MyOverlayTest1

{

       zorder 500

       container Panel(MyOverlayTest1/ImagePanel)

       {    

              metrics_mode pixels

              horz_align right

              vert_align bottom

              top -640

              left -650

              width 640

              height 640

              material MyOverlayMaterial1

       }

}

        这里MyOverlayTest1即为表层名,它的zorder值设置为了500,接着定义了一个container对象,类型名为Panel,它是一块能包含其它元素(或容器)的矩形区域,这里我们定义的实例名为“MyOverlayTest1/ImagePanel”。紧接着就是定义了一系列表层元素的属性:

        ·metrics_mode用来设置元素的大小和位置的单位,格式是metrics_mode<pixels|relative>。当采用像素模式的时候,元素的大小和位置以像素为单位进行衡量,在这种模式下,元素的位置和大小会随着电脑屏幕分辨率的变换而变换。例如:800*600分辨率下,某个元素的左上角坐标为20,20,大小为60,60。那么它将显示在屏幕左上方,但当分辨率为1024*768的时候,它的大小会发生变换,而且位置也会朝着左上方移动一下。当采用相对模式是,元素的位置和尺寸与显示分辨率无关,也就是说,元素的显示结果可以适应任何的屏幕分辨率。

        ·horz_align用来设置元素的水平对齐方式,其格式为:horz_align<left|center|right>。从属性的取值上可以猜想到,这个属性有可以设置3种元素的水平对齐方式:居左、居中和居右。

        ·left用来设置元素相对于它上一层的水平位置,其格式为:left <value>,在这里,元素的位置是相对于上一层的位置而言的。同理,top就是设置元素相对于它上一层的垂直位置。

        ·width/height用来设置元素的宽度和高度,它的大小是相对于屏幕大小而言的。

        ·material用来设置用于此元素的材质名。

        第二步,由于我们在第一步中使用到了MyOverlayMaterial1这个材质,所以我们还需要自己定义这个材质。打开media/materials/scripts这个文件夹,打开文件夹下的MyTest.material这个文件(如果没有这个文件,我们就手动新建一个),然后添加一个新材质,如下所示:

material MyOverlayMaterial1

{

    technique

    {

        pass

        {

            lighting off

            scene_blend alpha_blend

            depth_check off

            texture_unit

            {

                texture leaf.png

            }

        }

    }

}

        定义材质的内容我们这里就不多做介绍,如果读者哪里不明白可以参照材质介绍的相应章节温习一下。

        第三步,需要在程序中通过代码调用相应的Overlay,同样,我们使用我们在前面章节保存的模板代码,修改createScene函数中的内容如下:

void createScene()

{

Ogre::Overlay*pOverlay =Ogre::OverlayManager::getSingleton().getByName("MyOverlayTest1");

pOverlay->show();

Ogre::Entity*ogreHead =mSceneMgr->createEntity("Head","ogrehead.mesh");

Ogre::SceneNode*headNode =mSceneMgr->getRootSceneNode()->createChildSceneNode();

headNode->attachObject(ogreHead);

// Set ambient light

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

// Create a light

Ogre::Light*l =mSceneMgr->createLight("MainLight");

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值