开发工具:
文件大小: 1mb
下载次数: 0
上传时间: 2019-03-03
详细说明:经典的OSG教程,感谢王锐大神的贡献!此教程非常适合进行OSG的学习。小伙伴们欢迎下载,祝学习顺利~~init Event- >set EventType(osgGA: GUIEventAdapter: FRAME)
if( cameraManipulator. validO)
cameraManipulator->inii(initEvenl, this);
从变量的名称可以猜测出 eventQueue的功能,它用于储存该视景器的事件队列。OS
中代衣事件的类是 SEga: GUIEventAdapter,它可以用于衣达各种类型的鼠标、键盘、触压
笔和窗口事件在用户程序中,我们往往通过继承 OSgga: GUIEventhandler类,并重写 handle
凶数的方法,获取实时的鼠标/键盘输入,)进而实现相应的用户代码(参见
osgkey boardhouse)。
eventQueue除了保存一个 GUIEventAdapter的链表之外,还提供了一系列对链表及其
元素的操作函数,这其中, createEvent函数的作用是分配和返回一个新的 GUIEventAdapter
事件的指针。
随后,这个新事件的类型被指定为 FRAME事件,即每帧都会触发的一个事件
那么, cameraManipulator呢?没错,它就是视景器中所用的场景漫游器的实例。通常
我们都会使用 setCameramanipulator来设置这个变量的内容,例如轨迹球漫游器
( TrackballManipulator)可以使用鼠标拖动米观察场景,而驾驶漫游器( DriveManipulator)
则使用类似」汽午鸳驶的效果来实现场景的漫游。
上面的代码将新创建的 FRAME事件和cwer对象本身传递给 camcraManipulator的
init函数,不同的漫游器(如 TrackballManipulator、 DriveManipulator)会重写各自的int函
数,实现自己所需的初始化工作。如果读者希望自己编写一个场景的漫游器,那么覆写并使
用 OSggA: Matrix Manipulator;init就可以灵活地初始化自定义漫游器的功能了,它的调用时
札就在这里。
那么,回到 viewerlnit函数……很好,这次似乎没有更多的内容了。没想到一个短短的
凶数竞然包含了那么多的信息,看来草率地阅读还貞是使不得。
解读成果:
OSg GA: EventQueue crealeEvenl, OSgGA: Matrix Manipulator: init, osg Viewer: Vi
osg viewer: Viewer: viewerInit
悬疑列表:
无
第二日
当前位置: osg Viewer/ Viewer cpp第385行, osg viewer:Ⅴ Viewer: realized
Ⅴ lewer; realize函数是我们十分熟悉的另一个函数,从OSG问世以米,我们就习惯于在
进入仿真循环之前调用它(现在的OSG会自动调用这个函数,如果我们忘记的话),以完成
窗口和场景的“设置”工作。那么,什么叫做“设置”,这句简单的场景设置又包含了多少
內谷呢?艰辛的旅程就此开始吧
首先是一行: setcamera with Focu(,其内容无非是设置类变量 camera WithFocus指向
的内容为NULL。至于这个“带有焦点的摄像机”是什么意思,我们似乎明白,似乎又不明
白,就先放入一个“悬疑刎表”( Todo list)中好了
下面遇到的函数就比较重要了,因为我们将会在很多地方遇到它:
Contexts contexts
getContexts(contexts)
变量 contexts是一个保存了osg: Graphics Context指针的向量组,而 Viewer: getContexts
函数的作用是获取所有的图形上下文,并保存到这个向量组中来。
对于需要将OSG嵌合到各式各样的GUI系统(如MFC,Q, wxWidgets等)的朋友来
说,osg: Graphics Context类是经常要打交道的对象之一。一种常用的嵌入方式也许是这样实
现的
osg: ref ptr traits=new osg:: Graphics Context: Traits
osg: ref ptr< osg: Referenced> windata
ncw osg Vicwcr: Graphics Window Win32: Window Data(h Wnd)
trails->X
0;
traits->y-O
traits->inherited Window Data= windata
osg: Graphics Contcxt*gc=osg: Graphics Contcxt: crcatc Graphics Contcxt( traits. gctO)
Camera camera- viewer. getCamerao
camera->setGraphics Context(gc)
viewer. setCamera( camera
这个过程虽然比较繁杂,但是顺序还是十分清楚的:首先设置嵌入窗口的特性( Traits)
例如Ⅹ、Y位置,宽度和扃度,以及父窗∏的句柄( inherited Window Data);然后根据特性
的设创建一个新的图形设备上下文( Graphics Context),将其赋予场景所用的摄像机。而
我们在 getContexts函数中所要获取的,也许就包括这样一个用户建立的 Graphics Context设
备
当前位置: osg Viewer/ Viewer;cpp第1061行,osgⅤ lewer∷Ⅴ lewer: get Contexts
在这个函数之中,首先判断场景的主摄像机 camera是否包含了一个有效的
Graphics Context设备,然后再遍历所有的从摄像机 slaves(一个视景器可以包含一个主摄像
级和多个从摄像机),将所有找到的 graphics Context图形上下文设备记录下来。
随后,将这些 Graphics Context的指针追加到传入参数( contexts向量组)中,并使用
std:sort执行了一步排序的工作,所谓的排序是按照这样的原则米进行的
1、屏幕数量较少的 Graphics Context设备排列靠前;
2、窗口ⅹ坐标较小的设备排列靠前;
3、窗∏Y坐标较小的设各排列靠前。
如果希望观察自己的稈序中所有的图形设备上下文,不妨使用这个数来收集一下。简
单的情形下,我们的程序中只有一个主摄像机,也就只有一个 Graphics Context设备,它表
达了一个全屏幕的图形窗口;而 osgcamera这个例」程序可以创建六个从摄像机,因此可以
得到六个图形上下文设备,且各个图形窗口的X坐标各不相同,这也正是这个例子想要表
达的。
可是,主摄像机的 GraphicsContext呢?为什么 osgcamera中不是七个 Graphics Context
设备呢?答案很简单,主摄像机没有创建图形上下文,因此也就得不到设备的指针。为了理
解这个现象的原因,我们个妨先回到 realize函数中
当前位置: osg Viewer/ liewer:cpp第394行,osgⅤ Viewer∷Ⅴ lewer: realize
有一个显而易见的事实是:。程序还没有进入仿真循环,且对于 osg Viewer∷ Viewer还
没有任何的操作之时,系统是不会存在任何图形上下文的;创建一个新的osg: Camera对象
也不会为其自动分配图形上下文。但是,图形上下文 Graphics Context却是场景显小的唯
平台,系统有必要在开始渲染之前完成其创建工作
假设用户已经在进入仿真循环之前,自行创建了新的 Camera摄像机对象,为其分配了
自定义的 Graphics Context设备,并将 Camera对象传递给视景器,就像σ sgviewerMFC和
osgcamera例子,以及我们在编写与GUI系统嵌合的仿真稈序时常做的那样。此时,系统已
经不必为图形上下文的创建作任何多余的工作,因为用户不需要更多的窗口来显示自己的场
景了。所以就算主摄像机 camera还没有分配 Graphics Context,只要系统中已经存在图形上
下文,即可以开始执行仿真程序了
但是,如果 geL Contexts没有得到任何图形上下文的话,就说明仿真系统还没有合适的
显示平台,此时就需要尝试创建一个缺省的 Graphics Context设备,并再次执行 getContexts
如果还是没能得到任何图形上下文的话,那么就不得不退出程序了。
创建缺省 Graphics Context设备的方法有以下儿种:
1、读取 OSG CONFIG FILE环境变量的內容:如果用户在这个环境变量中定义了一个
文件路径的话,那么系统会尝试用 osgI: readobjectFile函数读入这个文件,使用cg插件
进行解析;如果成功的话,则调用 osg viewer; Viewer:ake函数,使用配置信息设置当前的
视景器。这些工作在 osg viewer:Ⅴ lewer: reconfiguration函数中实现。
2、读取 OSG WINDOW坏境变量的内容:如果用户以“xywh”的格式在其中定义了
窗口的左上角坐标(x,y)和尺寸(w,h)的话(注意要以空格为分隔符),系统会尝试使
用 osg viewer:View: setUp ViewIn Window函数来创建设各。
3、读取 OSG SCREEN环境变量的内容:如果用户在其中定义了所用屏幕的数量的话,
系统会尝试用 osg viewer:iew: setUpⅤ iewOnSingleScreen函数,为每一个显示屏创建一个全
屏幕的图形窗口;如果同时运设置了 OSG WINDOW,那么这两个坏境变量都可以起到作
用,此时将调用 setUpⅤ lewIn window函数。
、如果上述环境变量都没有设置的话(事实上这也是最常见的情况),那么系统将调用
vIewer∷view: setUp view Across AllScreens函数,尝试创建一个仝屏显示的图形设备
那么,下文就从这几种图形设备建立的方法开始。至于后面的路,果然遥遥无期呢
解读成果:
osg viewer: Viewer: getContexts, osg Viewer: Viewer: read Configuration
悬疑列表:
类变量 camera withFocus的意义是什么?
第三日
当前位置: osy Viewer/View.cpp第575行, osg Viewer:Ⅴiew: setUpⅤ lewIn Window
这个函数有五个传入参数:窗口左上角坐标x,y,宽度 width,高度 height,以及屏幕
数 screenful。它的作用顾名思义是根据给定的窗冂参数来创建个图形设各。
首先函数将尝试获取osg: Display Settings的指针,这个类在OSG的窗口显示中扮演了
重要的地位:它保存了OSG目前用到的,与图形显示,尤其是立体显示有关的所有信息,
主要包括:
display Typc:显示器类型,默认为 MONITOR(监视器),此外还支持 POWERWALL
(威力墙), REALITY CENTER(虚拟实境中心)和 HEAD MOUNTED DISPLAY(头盔
显示器)。
stereoModel:立体显示模式,默认为 ANAGLY PHIC(互补色),此外还支持
QUAD BUFFER(四方体缓冲), HORIZONTAL SPLIT(水平分割), VERTICAL SPLIT(垂
直分割), LEFT EYE(左眼用), RIGHT EYE(右眼用), HORIZONTAL INTERLACE(水
平交错),Ⅴ ERTICAL INTERLACE(垂直交错), CHECKERBOARD(棋盘式交错,用于
DLP显示器)
eyeSeparation:双眼的物理距离,默认为0.05。
screen width, screenHeight:屏幕的实际宽度和高度,分别默认没置为0.325和0.26,
目前它们影响的仅仅是视图采用透视投影时的宽高比。
screen distance:人眼到屏幕的距离,默认为0.5
splitStereoHorizontalEyeMapping:默认为 LEFT EYE LEFT VIEWPORT(左眼渲染左
视凵),也可设为 LEFT EYE RIGHTⅤ EWPORT(左眼渲染右视口)。
splitstereohorizontalSeparation:左视口和右视口之间的距离(像素数),默认为0。
splitstcrco vcrtical EycMapping:默认为 LEFT EYE TOPⅤ EWPORT(左眼渲染顶视
∏),也可设为 LEFT EYE BOTTOM VIEWPORT(左眼渲染底视冂)。
splitstereo VerticalSeparation:顶视口和底视口之间的距离(像索数),默认为0
象 SplitStereoAutoAdjustAspectRatio:默认为true,用于屏幕分割之后对其宽高比进行补
max Numof( graphics Contexts:用户程序中最多可用的( graphics Contcxt(图形设备上下
文)数目,默认为32个。
numMultiSamples:多重采样的子像素样本数,默认为0。如果显示卡支持的话,打开
多重釆样可以大幅改善反走样(ant- -aliasing)的效果。
此外还有很多可以设置的类变量,如 minimum Number Siencilbils(模板缓存的最小位
数)等,其默认设置均在osg: Display Settings: setDefaults函数中完成,其中有些变量可能还
没有作用。要注意的是, Display settings的作用仪仅是保存所有可能在系统显示中用到的数
据,这个类本身并不会据此改变任何系统设置和渲染方式。
值得称道的是, Display Settings可以很方便地从系统环境变量或者命令行参数中获取用
户对显示设备的设置,详细的调用方法可以参阅 Display Settings: readEnvironmenlalⅤ ariables
和 DisplaySettings: readCommandLine两个函数的内容,十分通俗易懂。
如果希望在用户程序中更改 Display settings中的显示设置,请务必在执行视景器的
realize函数之前,当然也就是仿真循环开始之前。这一点也是要切记的
不知不觉中,似乎完全跑题了,那么我们还是先设法回到主题上来
当前位置: osg Viewer/ Vicw.cpp第579行, osg viewer:icw: setUp VicwInwindowo
代码解读的工作完全没有进展,看米需要加快进度了。获取系统显示设备的设置参数之
后,下血我们要开始创建新的 Graphics Context设备了,回忆“第二日”的内容中所介绍的
OSG与GU窗口嵌合的流程,第一步是新建一个显示设备特性实例:
osg: ref ptrtraits -new osg: Graphics Context: Traits
设置图形窗口的特性值。注意这里用到了一个函数 Screenldentifier: creadDISPLAY,它
的工作仅仅是尝试检査系统环境变量 DISPLAY,并调用 Screenldentifier: setscreenldentifier
函数,将其中的内容按照“ hostname:0.0”的格式解析为系统的主机名称( hostname),显
示数(在Win32下必须为0)和屏幕数(0或者其它数字)
根据立体显示模式的不同,窗∏特性中的模板位数等参量也会有所区分
下一步,创建新的 Graphics Context:并将其设置给视景器的主摄像机
osg: ref ptr gc
osg: Graphics Context: create Graphics Context(traits. geto)
camera->set Graphics Context(gc. geto
千万不要简单地使用new来创建新的 Graphics Context指针,因为相比起来,
create Graphics Context还完成了这样一些工作
1、获取窗口系统API接口,即 Graphics Context: Windowing SystemInterface的实例
2、执行 setUndefinedscreenDetails ToDefaultscreen函数,如果用户没有设置屏幕薮,则
自动设置为缺省值0
3、返川 WindowingSystcmIntcrfacc: create( Graphics Contcxt的值
看似一切顺利,但是稍一深究就会发现,这里面存在了一个重要但是不好理解的问题:
Windowing SystemInterface: create Graphics Context可是一个纯虚函数,它怎么可能返回新建
立的图形设备上下文呢?事实上,这个看似简单的 Windowing SystemInterface结构体也是另
有玄机的,注意这个函数:
void Graphics Context: Sct Windowing SystcmIntcrfacc
(Windowing SystemInterface callback)
它的作用是指定操作平台所使用的视窗API接口,也就是在特定的系统平台上创建图
形窗凵的时候,将会使用到哪些本地AP函数。当然, Windows系统要使用Win32AP,而
Linux系统要使用X1AP,Appe系统则使用 Carbon
切有关视窗AP接口的T作都是由( graphics window win32, Graphics window x11和
Graphics Window Carbon这二个类及其协作类来完成;而指定使用哪个窗冂系统API按∏
的关键,就在于源文件 osg Viewer( graphics Window win32.cpp中定义的结构体
Register Windowing SystemInterfaceProxy了,仃细研读一下这个结构体和刚才所述的
setwindowing SystemInterface数的关系,还有注意那个紧跟着结构体的全局变量
( Graphics window win32.cp,2367行),相信您一定会人呼巧妙的。
什么,( raphics window xll.cp中也有这个结构体?那么请仔绀检查下 CMake自动
生成的 osg viewer. vcproj工程,看看有没有包含这个多余的文件(对于 Windows系统来说)
这也诈就是使用 CMake来实现跨平台编译的好处之一了
至」 Windowing SystemInterface: create Graphics Context数是如何使用Win32AP来实
现图形设备的创建的,鉴于本文并不想追赶《资本论》的宏伟规模,就不再深究了,读者不
妨自行刨根问底
回来吧,回来吧。还是让我们回到 setUp ViewIn Window函数中来。
这个函数剩下的内容并不是很多,也不难理解,主要的工作有
1、调用 OSgga: GUIEventAdapter: setWindow Rectangle记录新建立的窗冂设备的大小,
因而这个设备上产生的键盘和鼠标事件可以以此为依据
2、设置主摄像机 camera的透视投影参数,并设置新的Ⅴ iewport视口。
3、执行osg< amera: setDraw Buffer和执行osg: Camera: setReadBuffer函数,这实质上
相当于在渲染的过程中执行 glDraw Buffer和 glReadBuffer’从而自动设置此摄像机想要绘制
和读取的缓存
就这样。不过这回真是一次又一次地离题万里……希望我们还是从中得到了一些收获和
启迪的,对吗?
解读成果
osg: Display Settings set Defaults, osg: Graphics Context: :create Graphics Context
g
viewer∷View: setUpⅤ lewIn Window
悬疑列表
类变量 camera With Focus的意义是什么?
第四日
当前位置: osg Viewer/ Viewer: cpp第426行, osg viewer:Ⅴ Newer: realized
setUp view On Single Screen和 setUp view AcrossAllScreens函数的头现流程与上一日介绍
的 setUp ViewIn Window区别不是很大。值得注意的是, setUp view Across AlIScreens函数中调
用 GraphicsContext: get Windowing SystemInterface函数取得了与平台相关的视窗AP接口类
(其中的原理请参看上一日的文字),并进而使用 Windowing SystemInterface: getNunScreens
函数取得了当前系统的显示屏幕数。
事实上,如果我们需要在自己的程序中获取屏幕分辨率,或者设置屏幕刷新率的话,也
可以使用同样的方法,调用 getScreenResolution, netScreen resolution和 netScreen RefreshRate
等相关函数即可。具体的实现方法可以参见 Graphics window Win32cpp的源代码
setUp View AcrossAlIScreens函数可以自行判断屏幕的数量,并且使用多个从摄像机来对
应多个屏幕的显示(或者使用主摄像机 camera来对应单一屏幕)。此外它还针对水平分割
显示( HORIZONTAL SPLIT)的情况,对摄像机的左/右眼设置自动做了处理,有兴趣的读
者不妨仔细研究
最后,本函数还执行了一个重要的工作,即Ⅴicw: assign ScencData To Cameras,这其中
包括以下几项上作:
对于场景漫游器 cameraManipulator,执行其 setNode函数和home函数,也就是设
置漫游器对应于场景图形根节点,并回到其原点位置。不过在我们使用 setCameraManipulator
凶数时也会自动执行同样的操作。
2、将场景图形赋予主摄像机 camera,同时设置它对应的渲染器( Renderer)的相关函
数。这里的渲染器起到了什么作用?还是先放到悬疑列表中吧,不过依照我们的解读速度
这个问题可能会悬疑很久
3、同样将场景图形赋予所有的从摄像机 slaves,并设置每个从摄像机的渲染器。
终于可以回到 realize函数的正轨了,还记得下一步要做什么吧?对,在尝试设置了缺
省的 Graphics context设备之后,我们需要再次使用 getContexts来获取设备,如果还是不成
功的话,则OSG不得不退出运行了(连图形窗∏都建立不起来,还玩什么)
当前位置: osg Viewer/viewer:cp第446行, osg viewer:Ⅴ lewer: realized
现在我们遍历所得的所有〔 raphics Contex设备(通常情况下,其实只有一个而凵)。对
于每个 GraphicsContext指针ge,依次执行
if realize Operation. valido & gc->valido
gc-makeCurrent(
realizeoperation(gc)
gc->release()
一头雾水,但是決不能轻言放弃。仔细研究一下吧,首先是( iraphicsContext: rcali7c函
数,实际上也就是 Graphics Context: realizelmplementation函数
realizelmplementation是纯虚函数吗?没错,回想一下第三日的内容,当我们尝试使用
create Graphics Context米创建一个图形设备上下文时,系统返回的实际上是这个函数的值
ref ptr< Graphics Context: WindowingSystemInterface>&wsref
windowing SystemInterfaceRefo
return wsref->create Graphics Context(trails
而正如我们历经千辛万苦所分析的那样, wsrf所指向的是平台相关的API接口类,也
就是Win32API的接冂,也就是( graphics window win32.cpp中对应类的实例。换句话说,此
时 WindowingsystemInterface: create Graphics Context函数返回的值,也应当是派生自
Graphics Context的具体类的实例!
正确,对于 Windows用户来说,这个凶数返回的恰恰是 Graphics Window Win32的实例,
而前文的 realizelmplementation函数,正是 Graphics window Win32: realizelmplementation
晕头转向了………那么,用一张图也许能解决一点问题吧
OSg: Camera
Camera
set Graphics Context
Windowing SystemInterface
c create Graphics Context
oSg: Graphics Context
osg Viewer:: Graphics window Win32
osg: Graphics Context::
osg viewer:: Graphics window l
WindowingSystemInterface
osg Viewer: Graphics Window Carbon
Win32WindowingSystem
X1l SystemInterface
OSXCarbon WindowingSystemInt
erface
1、视景器Ⅴ lewer的主/从摄像机均需要使用 setGraphics Context设置刈应的图形设备卜
下文,实际上也就是对应的显示窗凵
2、 Graphics Context的创建由半台相关的抽象按口类 Windowing SystemInterface负责,
对于Win32平台而言,这个类是由 Graphics Window win32 cpp ikJ win32 Windowing System类
具体实现的,它创建的显示窗∏设备即 osg viewer:( raphics Window win32的实例
3、进一步深究的话,如果窗口特性( Traits)中开启了 pbuffer选项,则OSG将尝试创
建 osg viewer: PixelBuffer win32设备,以实现离屏渲染( Offscreen Render),纹理烘焙
( Render -To- Texture)等工作;则只建立通常的 OpengL窗口
真是令人兴奋!没错, Graphics Contcxt: makc Current和 GraphicsContcx: rclcasccontcxt
凶数也是用相同的方法来实现多态性的,而它们的上作也就是 Opengl开发者使用函数
wglMake Current完成的工作,将渲染上下文RC对应到下确的窗口绘制句柄上。
如果您还想要深究具体的实现方法的话,就好好地阕读 Graphics window win32.cpp中的
相关内容吧,个过我们的旅程要继续了。
等等,刚才那段程序里面, realizeOperation是仆么,它又执行了什么?嗯,简单说来
这个变量是通过 Viewerbase: setRealizeOperation来设置的,其主要作用是在执行 realize函
数时,顺使完成用户指定的一些工作。您自凵的工作内容可以通过继承 osg:: Operalion类
并重载 operator操作符来添加 osgcatch这个妙趣橫生的例子(一个傻娃娃接玩具的小游戏)
中就使用了 setRealizeOperation,主要的作用是为场景中的 Drawable几何对象立即编译显示
列表( Display list)。有兴趣的话不妨细细把玩一下。
解读成果:
osg Viewer: View: setUp ViewOnSingleScreen
osg viewer: View: assignSceneData Cameras, osg viewer: View: setUp view acrossAllScreens
悬疑列表
类变量 camera with Focus的意义是什么?渲染器( Rcndcrcr)类起到什么作用?
第五日
当前位置: osy Viewer/ Viewer. cpp第463行,ogⅤ lewer: Viewer: realize
下面我们再次遍历所有 GraphicsContcxt设备,对于每个 Graphics Context指针gc,判断
它是否为 Graphics window对象,并执行( Graphics window: grabFocusltPointerIn Window函数。
阅读 Graphics Window Win32类(目 Graphics Context的具体实现者)的同名函数可以发现,
这个函数不过是负责把鼠标焦点转到当前窗口上而已
卜一步工作的代码如卜:
osg: :Timcr: instance(->sctStartTickO
setstartTick(osg: :Timer: instance0->getStartTick()
etUp Threading
首先调用osg: Timer: setStartTick函数,启动OSG内部定时器并开始计时。
随后,Ⅴ lewer: setStartTick函数的工作是找到当前视景器和所有 Graphics Context设备的
事件队列 eventQueue,并设定它们的启动时刻为当前时间。
下·行是调用Ⅴ ewer Base: set Up Threading函数……设置线程,对于·向以多线程渲染
而闻名的OSG而言,这一定是个值得深究的话题。
当前位置: oso Viewer; ViewerBase. cpp第122行, osg viewer; Viewer Base∷;
sctUpThreadingO
OSG的视景器包括四种线程模型,可以使用 set ThreadingModel进行设置,不同的线程
模型在仿真循环运行时将表现岀伓冋的渲染效率和线程控制特性。通常而言,这凹种线程的
特性如下:
Single threaded:单线程模型。OSG不会创建任何新线程来完成场景的筛选和渲染,因
而也不公对渲染效率的提高有仟何助益。它适合仟何配置下使用。
CullDraw ThreadPertontext:OSG将为每一个图形设备上下文( Graphics context)创建
个图形线程,以实现并行的渲染工作。如果有多个CPU的话,那么系统将尝试把线程分
别放在不同的CPU上运行,不过每一帧结束前都会强制同步所有的线程。
Draw ThreadPerContext:这线程模型同样会为每个 Graphics Context创建线程,并分配
到不同的CPU上。十分值得注意的是,这种模式会在当前帧的所有线程完成工作之前,开
始下一帧
(系统自动生成,下载前可以参看下载内容)
下载文件列表
相关说明
- 本站资源为会员上传分享交流与学习,如有侵犯您的权益,请联系我们删除.
- 本站是交换下载平台,提供交流渠道,下载内容来自于网络,除下载问题外,其它问题请自行百度。
- 本站已设置防盗链,请勿用迅雷、QQ旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
- 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
- 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
- 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.