ogre3D学习基础1 -- 核心对象与脚本技术

一、核心对象介绍
1、命名空间
  Ogre3d使用了C++的特性--命名空间,可以防止命名混淆。使用方法也简单,using namespace Ogre;或者直接在使用时加上“Ogre::”的前缀,如Ogre::Vector3等。
2、Root对象 ---根对象
  根(Root)对象是OGRE系统的入口,该对象在程序一开始时创建,最后结束时销毁。可用来配置系统,还可以获得系统中其他对象的指针,比如场景管理器(SceneManager),绘制系统(RenderSystem),资源管理器(Resource Managers)等。
3、RenderSystem 对象----渲染系统对象
  渲染系统对象实际上是一个抽象类,它定义了3D API接口。不过一般情况下,我们并不对它进行操作,而是通过场景管理器简介进行操作,而这一过程是系统自动完成的。
4、SceneManager对象---场景管理器对象
  场景管理器(SceneManager)对象是ogre系统中最常用到的对象,它控制着由ogre引擎绘制的场景中的多有内容,还负责组织创建所有的摄像机(Cameras)、可移动的实体(Entities)、光线(Lights)和材质(Materials:对象的表面属性),并且管理场景中静态的部分,如整个场景地形。
5、 ResourceGroupManager对象
  资源组管理器(ResourceGroupManager)实际上是提供加载纹理(Textures)、网格(Meshes)等可重用资源的“集合体”。资源组管理器(ResourceGroupManager)中包括了大量的资源管理器(ResourceManagers),每个资源管理器(ResourceManagers)分管某类资源,比如纹理管理器(TextureManager)、网格管理器(MeshManager)。资源管理器(ResourceManager)能保证某类资源只被加载一次,它能较好地管理这些资源占用的内存,还可以在不同的位置搜寻需要的资源,搜寻的位置不仅包括文件路径(Paths),还包括压缩文件(ZIP文件)。
  你需要做的唯一的一件事就是告诉资源管理器(Resource Managers)到哪儿去找你想要加载的资源,你可以通过调用Root::getSingleton().addResourceLocation这个方法来实现这个功能,该方法能将位置信息传递给资源组管理器(ResourceGroupManager)。
6、Mesh 对象---网格对象
  网格(Mesh)对象表示的是具体的模型,它自身包括了一整套用来描述自身模型的数据,在广域范围(World Scale)内,网格(Mesh)对象相对比较小,网格(Mesh)对象通常用来表示可以移动的对象,而非那些静态的诸如背景之类的对象。
7、实体(Entity)
  实体(Entity)是场景中可移动对象的实例,它可以是一辆车、一个人、一条狗等等。实体(Entities)是以网格(Meshes)作为自身基础的。
当基于网格(Mesh)创建出一个实体(Entity)时,该实体(Entity)可能由多个子实体(SubEntity)构建而成,子实体(SubEntity)与网格(Mesh)中的子网格(SubMesh)一一对应。你可以通过调用Entity::getSubEntity方法获得子实体(SubEntity)。一旦你得到子实体(SubEntity)的指针,你可以通过调用setMaterialName方法改变其材质(Material)。通过这种方法,你可以改变你所创建的实体(Entity)的默认材质(Materials),从而使你创建出来的实体(Entity)与众不同。
8、材质(Materials)
  材质(Materials)是从来描述场景中的对象是如何被绘制出来的。它被用来指定对象的表面属性。
  材质(Materials)也可以通过编程来进行设置,通过调用SceneManager::createMaterial可以创建出新的材质(Materials)。你也可以在程序运行时,通过脚本(Script)来加载材质(Materials)。基本上来说,每一个在场景中可以看到的对象都会与材质(Material)类产生关联。
场景管理器(SceneManager)类管理着出现在场景中的所有材质(Materials)的链表(Master List)。
9、Overlays --- 层
  层(Overlays)允许你在一般的场景内容上绘制2D或3D元素。可以通过调用SceneManager::createOverlay方法创建层(Overlays),也可以通过创建一段“.overlay”脚本来定义层(Overlays)。常用为后一种,因为修改脚本后不需要重新编译代码。层创建后默认为隐藏,必须通过“show()”将层显示出来。
在层(Overlays)中可以直接添加的元素只有层容器(OverlayContainers)。而在层容器中可以添加子元素,子元素的坐标位置是根据他们的父容器的左上角来进行定位的。

  层(Overlays)的转换 ----层可以旋转,滚动,按比例缩放等
10、关于2D坐标
  有绝对坐标(pixel)或者相对坐标(relative)的方式。
  绝对坐标方式(Pixel Mode) 指定精确的尺寸大小,不管屏幕上其他元素如何变化,通过这种方式指定的层元素的大小永远不会改变,但是如果准备将元素显示在屏幕中间或者底部时,最好采用相对坐标。
  相对坐标方式(Relative Mode) 创建的元素与屏幕保持固定的比例。 在相对坐标方式(Relative Mode)中,屏幕左上角的坐标为(0,0),右下角坐标为(1,1)。所以,如果你将一个元素放在(0.5,0.5),则它正好放在屏幕的正中央。

二、脚本---脚本都是简单的文本文件,修改简单
1、材质脚本
  材质脚本提供了一种在脚本中定义复杂材质的能力,且这些材质可以轻松地重复使用。
  格式 :
  若干个材质可以定义在一个材质脚本里。脚本的格式有些类似C++,以花括号('{','}')分隔各个部分,注释由双斜线'//'放在一行的开始表示(注意,注释不可以嵌套)。

 1 // This is a comment
 2 material walls/funkywall1//这是材质名,在整个系统中要保证它是唯一的
 3 {
 4   // first, preferred technique
 5   technique//技术1//可以有多个
 6   {
 7   // first pass
 8     pass//渲染通路1///可以有多个
 9     {
10       ambient 0.5 0.5 0.5
11       diffuse 1.0 1.0 1.0    
12       // Texture unit 0
13       texture_unit //纹理单元1
14       {
15         texture wibbly.jpg
16         scroll_anim 0.1 0.0
17         wave_xform scale sine 0.0 0.7 0.0 1.0
18       }
19       // Texture unit 1 (this is a multitexture pass)
20       texture_unit//纹理单元2
21       {
22         texture wobbly.png
23         rotate_anim 0.25
24         colour_op add
25       }
26     }
27   }
28   // Second technique, can be used as a fallback or LOD level
29   technique//技术2
30   {
31   // .. and so on
32   }
33 }

  注意:':'是表示脚本里材质复制的分隔符,所以不能用作材质名的一部分。
  一个材质可以通过在它的材质名后面使用冒号:后跟要复制的所涉及的材质名,从而复制以前定义过的材质。如果被复制的材质没有找到,那么它会被忽略.
  顶层材质属性
lod_distances ---这个属性控制着在不同距离上由哪个技术参与形成效果的距离。
receive_shadows ----这个属性控制着使用这种材质的物体上是否可以有阴影。
  格式: receive_shadows <on|off>
  默认: on
transparency_casts_shadows ----这个属性控制着透明物体是否可以生成特定种类的阴影。
  格式: transparency_casts_shadows <on|off>
  默认: off
set_texture_alias ----这个属性将一个纹理别名关联到一个纹理名上。
  格式: set_texture_alias <纹理别名> <纹理名>
  这个属性设置从其他材质复制过来的,在纹理单元状态里使用的纹理。


2、技术(Techniques)
  在材质脚本中,一个“技术”就是一个单独的渲染物体的方法。最简单的材质定义只包含一个技术,但是最好不要只写一个技术。在一个材质脚本中,技术的排列要有一定的先后顺序,例如,排在前面的技术比排在后面的技术有更高的优先级。一般来说,你要把最高级最需要的技术放在脚本的前面,然后将其他的备用的技术按照顺序依次放在后面。
  格式:Format: technique 技术名

scheme ----设置技术所属的“方案”,材质方案被用来控制从一套技术到另一套技术的顶层转换。

  格式: scheme <方案名>

  示例: scheme hdr

  默认: scheme Default

lod_index -----设置该技术所属的细节层次索引。每个技术都必须对应属于一个细节层次索引,默认它们都属于索引0,即最高等级的细节层次。 必须在lod_index   0层上至少有一个技术。
  格式: lod_index <数字>
  数字的合法数值范围是 0(最高细节层次)到 65535,尽管这是不可能的。在技术之间的细节层次索引中不能留空当。也就是说,细节层次索引要按顺序排列,  例如:0,1,2,3,……;而不能出现:0,10,20,30,……,这样的情况。
  示例: lod_index 1
  默认: lod_index 0
lod_distances ---这一属性必须在材质部分之外指定(例如,所有技术的父层次),而在这里进行介绍是因为它与这部分关系最密切。
  格式: lod_distances <distance_1> [<distance_2> ... <distance_n>]
  示例: lod_distances 300.0 600.5 1200
  必须保证每个细节层次上至少有一个技术(所以,如果你指定了三个距离,你就必须有技术1、技术2和技术3)。


3、渲染通路(Pass)
  一个渲染通路就是几何问题里的一次渲染;一个带有一整套渲染属性的渲染API的一次调用。一个技术可以包含有1到16个渲染通路。一个技术中的渲染通路的名字必须是唯一的,否则,最后一个渲染通路的结果就会是所有相同名字的渲染通路的效果的融合。
在.material脚本中“渲染通路”部分能够使用的一些属性:

ambient --设置此渲染通路中周围环境的反射系数。
  格式: ambient (<red> <green> <blue> [<alpha>]| vertexcolour)
  数值的取值范围在0.0到1.0之间。
  示例: ambient 0.0 0.8 0.0
  默认: ambient 1.0 1.0 1.0 1.0

diffuse ---设置此渲染通路中漫反射系数。
  格式: diffuse (<red> <green> <blue> [<alpha>]| vertexcolour)
  数值的取值范围在0.0到1.0之间。
  示例: diffuse 1.0 0.5 0.5
  默认: diffuse 1.0 1.0 1.0 1.0
specular ----设置此渲染通路中镜面反射颜色的反射系数。
  格式: specular (<red> <green> <blue> [<alpha>]| vertexcolour) <shininess>
  数值的取值范围在0.0到1.0之间。闪耀值(shininess)可以是任意比0大的值。
  示例: specular 1.0 1.0 1.0 12.5
  默认: specular 0.0 0.0 0.0 0.0 0.0
emissive ----设置一个物体自发光的量。
  格式: emissive (<red> <green> <blue> [<alpha>]| vertexcolour)
  数值的取值范围在0.0到1.0之间。
  示例: emissive 1.0 0.0 0.0
  默认: emissive 0.0 0.0 0.0 0.0
scene_blend -----设置此渲染通路与场景中现有的内容混合的方式。
  格式1: scene_blend <add|modulate|alpha_blend|colour_blend>
  示例: scene_blend add

  格式2: scene_blend <src_factor> <dest_factor>
  示例: scene_blend one one_minus_dest_alpha
  默认: scene_blend one zero (这句意为不透明的)

depth_check ----设置此渲染通路的深度缓冲检测的状态是打开状态还是关闭状态。
  格式: depth_check <on|off>
  默认: depth_check on
depth_write ---设置此渲染通路的深度缓冲写入的状态是打开状态还是关闭状态。
  格式: depth_write <on|off>
  默认: depth_write on

depth_func ----当深度检测打开时,设置用于比较深度值的函数。
  格式: depth_func <func>
  默认: depth_func less_equal
  如果深度检测处于打开状态(参看depth_check),那么将要写入的像素的深度值与缓冲区中现有内容的深度值会发生比较。一般来说,这种比较是小于等于,例如:将要写入的像素比现有内容距离我们更近(或相等)。可能的函数如下:
    always_fail 永远不向渲染目标写入像素
    always_pass 总是将像素写入渲染目标
    less 如果将要写入的像素的深度小于现在缓冲区内容的深度,则写入
    less_equal 如果将要写入的像素的深度小于等于现在缓冲区内容的深度,则写入
    equal 如果将要写入的像素的深度等于现在缓冲区内容的深度,则写入
    not_equal 如果将要写入的像素的深度不等于现在缓冲区内容的深度,则写入
    greater_equal 如果将要写入的像素的深度大于等于现在缓冲区内容的深度,则写入
    greater 如果将要写入的像素的深度大于现在缓冲区内容的深度,则写入
depth_bias -----设置此渲染通路的深度值的偏向。
  格式: depth_bias <constant_bias> [<slopescale_bias>]
alpha_rejection --设置此项,可以使用alpha作为一个阀值,令渲染通路拒绝来自管线的像素。
  格式: alpha_rejection <function> <value>
  示例: alpha_rejection greater_equal 128
  默认: alpha_rejection always_pass
  如上例所示,拒绝所有来自管线的alpha值大于等于128的像素。 function参数可以选择在depth_function属性的参数列表中所列的参数。value参数理论上可以  是0到255之间的任意数,但是考虑到硬件兼容性,最好限制在0到128之间
cull_hardware ----设置此渲染通路的硬件裁剪模式。
  格式: cull_hardware <clockwise|anticlockwise|none>
  默认: cull_hardware clockwise
cull_software ----设置此渲染通路的软件裁剪模式。
  格式: cull_software <back|front|none>
  默认: cull_software back
lighting ---设置动态光照是处于打开状态还是关闭状态。如果光照被关闭,那么所有使用此渲染通路的物体将被完全照亮。如果使用了顶点程序,则此属性无效。
  格式: lighting <on|off>
  关闭动态光照会使得任何环境光、漫反射光、镜面反射光、放射光和阴影属性都成为了多余的。当打开光照时,物体按照顶点的法向被照亮。
  默认: lighting on
shading ----设置此渲染通路中为表现动态光照而使用的各种阴影形式。
  格式: shading <flat|gouraud|phong>
  当动态光照打开时,效果就在每个顶点处生成颜色值。这些值是否全平面插入(如何插入)就依赖于这个属性设置。
  flat 无插值参与。每个平面的阴影由平面上第一个顶点的颜色决定。
  gouraud   平面上每个顶点的颜色采用线性插入。
  phong   在全平面上插入顶点法线向量,被用于决定每个像素的颜色。能够得到更加自然的光照效果,但是代价也相应更高,在高级应用中表现更好。并不是  所有硬件都支持此属性。
  默认: shading gouraud
polygon_mode ---设置多边形应该如何被栅格化。
  格式: polygon_mode <solid|wireframe|points>
  solid 一般情况——填充多边形
  wireframe 多边形只画外边框
  points 只画每个多边形的点
  默认: polygon_mode solid
fog_override ---这个属性告诉渲染通路是否撤销场景的雾设置,而强制执行此渲染通路它自己的设置。
  格式: fog_override <override?> [<type> <colour> <density> <start> <end>]
  默认: fog_override false
  如果你指定第一个参数为真,并给出了其余参数,就表明你要告诉渲染通路如果在使用这些雾设置和使用场景设置之间选择的话,优先选择使用这些雾设置。如果你指定第一个参数为真,但没给出其余参数,就表明你要告诉渲染通路不使用任何雾设置,无论场景如何设置。以下是参数的解释:

  none = 没有雾,相当于使用'fog_override true'。
  linear = 线性雾,从 <start> 开始到 <end> 结束的这一段距离有雾。
  exp = 雾以几何方式增加(fog = 1/e^(distance * density)), 使用浓度 <density> 参数控制。
  exp2 = 雾以几何的二次方增加,更加快速(fog = 1/e^(distance * density)^2),使用浓度 <density> 参数控制。
  colour   3个0到1之间的符点数组成的序列,表示红色、绿色、蓝色的亮度。 
  density  用于'exp'或者'exp2'雾类型的浓度参数。虽不用于线性模式,但是也必须写上,作为占位符。 
  start   线性雾距离镜头的开始距离。在其它模式下,尽管不用这个参数,也必须写上,作为占位符。 
  end     线性雾距离镜头的结束距离。在其它模式下,尽管不用这个参数,也必须写上,作为占位符。 
  示例: fog_override true exp 1 1 1 0.002 100 10000

colour_write --设置此渲染通路的颜色写入是打开还是关闭的。
  格式: colour_write <on|off>
  默认: colour_write on
max_lights ---设置此渲染通路使用的光源的最大数量。 光源的最大数量由渲染系统设定,通常为8,常用于渲染固定功能材质。
  格式: max_lights <number>
  默认: max_lights 8
start_light ---设置此渲染通路使用的首个光源。
  格式: start_light <number>
  默认: start_light 0
iteration --设置此渲染通路是否被迭代,多次重复执行。
  格式 1: iteration <once | once_per_light> [lightType]
  格式 2: iteration <number> [<per_light> [lightType]]
  格式 3: iteration <number> [<per_n_lights> <num_lights> [lightType]]
  示例:
  iteration once 渲染通路只执行一次,默认设置。
  iteration once_per_light point 渲染通路每个光源点执行一次。
  iteration 5 此渲染通路的渲染状态将被建立,并且绘图调用将执行5次。
  iteration 5 per_light point 此渲染通路的渲染状态将被建立,并且绘图调用将每个光源点各执行5次。
  iteration 1 per_n_lights 2 point 此渲染通路的渲染状态将被建立,并且绘图调用将每2个光源点执行5次。
point_size --- 此设置允许你在渲染一个点列或者一个point sprites列时改变点的大小。
  格式: point_size <size>
  默认: point_size 1.0
point_sprites --- 这个设置指定此渲染通路的硬件point sprites渲染是否打开。如果打开了,意味着一个点列被作为一个四元组列渲染而不是作 为一列点渲染。
point_size_attenuation --- 定义点的大小是否根据视觉空间距离增加而衰减,以及以何种方式衰减。
  格式: point_size_attenuation <on|off> [constant linear quadratic]
  默认: point_size_attenuation off
point_size_min ----- 设置点衰减(详见上面point_size_attenuation)的最小值。
  格式: point_size_min <size>
  默认: point_size_min 0
point_size_max ----- 设置点衰减(详见上面point_size_attenuation)的最大值。细节详见上面point_size。 0值意味着将最大值设置为当前显卡所 支持的最  大值。
  格式: point_size_max <size>
  默认: point_size_max 0


4、纹理单元----可用的纹理层属性

texture_alias ---设置此纹理单元的别名。
  格式: texture_alias <纹理别名>
  示例: texture_alias NormalMap
texture ---- 设置这一层要使用的静态纹理图像的名字。
  格式: texture <texturename> [<type>] [unlimited | numMipMaps] [alpha] [<PixelFormat>]
  示例: texture funkywall.jpg
  参数type允许你指定创建的纹理类型——默认值是'2d',
  1d ,2d ,3d ;cubic {这类纹理由贴在立方体内侧的6个2D纹理组成。可由3D纹理坐标指向,并且对于立方体反射映射(cubic reflection maps)和标准映  射(normal maps)很有用}。
  'numMipMaps'选项允许你指定这个纹理的mipmap数量。默认值无限('unlimited')。
  'alpha'选项允许你指定一个单独的通道(透明的)纹理作为alpha装载,而不是默认的载入红色通道。
  <PixelFormat>选项允许你指定想要创建的像素格式,可能不同于装载的纹理文件的像素格式。
anim_texture(活动纹理) ---- 设置用于活动纹理层的图像。
  格式1 (短格式): anim_texture <base_name> <num_frames> <duration>
  示例: anim_texture flame.jpg 5 2.5
  格式2 (长格式): anim_texture <frame1> <frame2> ... <duration>
  示例: anim_texture flamestart.jpg flamemore.png flameagain.jpg moreflame.jpg lastflame.tga 2.5
cubic_texture (立方体纹理)--- 设置在立方体纹理内使用的图像。
  格式1 (短格式): cubic_texture <base_name> <combinedUVW|separateUV>
  格式1 (短格式): cubic_texture <base_name> <combinedUVW|separateUV>
tex_coord_set (纹理坐标集)---设置这个纹理层要使用的纹理坐标集。一个网格可以定义多个纹理坐标集,此属性设置这个材质使用哪一 个坐标集。
  格式: tex_coord_set <set_num>
  示例: tex_coord_set 2
  默认: tex_coord_set 0
tex_address_mode(纹理寻址模式) ---- 定义在这个纹理层的纹理坐标超过1.0时发生的事情。
  简单格式: tex_address_mode <uvw_mode>
  扩展格式: tex_address_mode <u_mode> <v_mode> [<w_mode>]
tex_border_colour(纹理边界色) --- 设置边界色。
  格式: tex_border_colour <red> <green> <blue> [<alpha>]
  颜色的数值取值范围在0.0到1.0。
  示例: tex_border_colour 0.0 1.0 0.3
  默认: tex_border_colour 0.0 0.0 0.0 1.0
filtering(过滤) ----设置当放大或缩小纹理时,使用的纹理过滤形式
  格式1: filtering <none|bilinear|trilinear|anisotropic>
  默认: filtering bilinear
  格式2: filtering <minification> <magnification> <mip>
  默认: filtering linear linear point
max_anisotropy (最大各向异性)---- 当过滤纹理时,设置渲染器将要补偿的各项异性的程度。
  格式: max_anisotropy <value>
  默认: max_anisotropy 1
mipmap_bias ---设置用于mipmap计算的偏向值,因此允许你决定哪一级的纹理细节用于哪个距离。
  格式: mipmap_bias <value>
  默认: mipmap_bias 0
colour_op --决定这个纹理层的颜色如何与它下面的一层叠加复合起来(或者如果它是第一层的话,如何将它与光照效果复合起来)。
  格式: colour_op <replace|add|modulate|alpha_blend>
  默认: colour_op modulate
colour_op_ex --- 这是colour_op属性的扩展版,对于在这个纹理层与前面一个纹理层之间应用的混合允许极详细的控制。多纹理硬件可以应 用更加复杂的混合操  作,但受限于硬件所能用的纹理单元数。
  格式: colour_op_ex <operation> <source1> <source2> [<manual_factor>] [<manual_colour1>] [<manual_colour2>]
  示例: colour_op_ex add_signed src_manual src_current 0.5
  默认: none (colour_op modulate)
colour_op_multipass_fallback --在如果使用了colour_op_ex属性且没有足够的多纹理硬件支持时,设置这个纹理层的多路后撤操作.
  格式: colour_op_multipass_fallback <src_factor> <dest_factor>
  示例: colour_op_mulitpass_fallback one one_minus_dest_alpha

alpha_op_ex --行为方式与colour_op_ex如出一辙,只不过它是决定alpha值如何在纹理层之间复合,而不是colour值。唯一的区别是 colour_op_ex最后是两  个颜色值,而alpha_op_ex是一个浮点值。
env_map --打开/关闭纹理坐标效果,以决定这一层能否环境映射。
  格式: env_map <off|spherical|planar|cubic_reflection|cubic_normal>
  默认: env_map off
scroll ----- 给纹理设置一个固定的滚动偏移量。
  格式: scroll <x> <y>
scroll_anim---给纹理层设置一个动态的滚动。对于在纹理层上创建固定速度的滚动效果很有用(对于不同的滚动速度,详见wave_xform属性)
  格式: scroll_anim <xspeed> <yspeed>
rotate -- 将一个纹理旋转一个固定的角度。
  格式: rotate <angle>
  参数<angle>是逆时针旋转的角的度数
rotate_anim -- 这一层创建动态旋转效果。对于创建固定速度的旋转动作比较有用(对于变速的情况,详见wave_xform)。
  格式: rotate_anim <revs_per_second>
  参数<revs_per_second>是每秒逆时针旋转的次数。
scale -- 调整这个纹理层应用的比例系数。用于调整纹理的大小,不改变几何体。这是一个固定的比例系数,如果你想要动态的比例系数, 详见wave_xform。
  格式: scale <x_scale> <y_scale>
  比例的有效值要大于0,比例系数如果为2,就表示在那一维上的纹理有2倍那么大。
wave_xform -- 建立一个基于波功能的动态改变形式。用于更高级的纹理层改变效果。你可以在一个纹理层中随意添加多个此属性的实例。
  格式: wave_xform <xform_type> <wave_type> <base> <frequency> <phase> <amplitude>
  示例: wave_xform scale_x sine 1.0 0.2 0.0 5.0
transform --- 这个属性允许你为纹理单元指定一个4x4变换矩阵,因而取代上述的滚动、旋转、比例属性。
  格式: transform m00 m01 m02 m03 m10 m11 m12 m13 m20 m21 m22 m23 m30 m31 m32 m33
  上面4x4矩阵中的数值序号为m<row><col>,前面一个为行号,后面一个为列号。
binding_type(绑定类型 )----- 告诉这个纹理单元是绑定到片断处理单元还是绑定到顶点处理单元。
  格式: binding_type <vertex|fragment>
  默认: binding_type fragment

content_type (内容类型)--- 告诉这个纹理单元从哪里取得它的内容,默认是从用texture,cubic_texture,anim_texture属性定义的一个命名纹理中取得内  容。
  格式: content_type <named|shadow>
  默认: content_type named

 这些东西看得头晕眼花的,好吧,先理论后实践。

posted @ 2013-08-29 14:50  struggle_time  阅读(1646)  评论(1编辑  收藏  举报