当前位置: 首页 > news >正文

外国企业网站模板免费下载html网站设计

外国企业网站模板免费下载,html网站设计,外贸谷歌推广,一级域名二级域名从今天开始#xff0c;我们开始正式的学习osg框架#xff0c;今天我们学习的是osg的渲染模块#xff0c;我们来看一下代码结构。 所有DrawXXX的js模块都是渲染的模块#xff0c;我们逐一来简单介绍一下#xff0c;第一个Drawable.js#xff0c;这个模块是描述可绘制对象的…  从今天开始我们开始正式的学习osg框架今天我们学习的是osg的渲染模块我们来看一下代码结构。 所有DrawXXX的js模块都是渲染的模块我们逐一来简单介绍一下第一个Drawable.js这个模块是描述可绘制对象的类也是我们今天要讨论的类。在osg框架中渲染管道在准备时期首先要统计管理可绘制对象我们来看看Drawable模块到底做了什么操作进行了哪些管理。先贴出代码。 /* 可绘制对象*/ let StateBin require(./StateBin); let BoundingBox require(../util/BoundingBox); let BoundingSphere require(../util/BoundingSphere); let Vec3 require(../util/Vec3);let Drawable function (actor) {this._drawActor actor;//关联的DrawActorthis._geometry undefined;//渲染的几何Geometrythis._transform undefined;//世界变换 FloatArray(16)this._statebin undefined;//状态结点原始的状态没有额外功能时的状态this._curStatebin undefined;//如果状态会动态变化这里存储每一帧绘制时的状态结点this._depth 0.0;//场景深度值透明需要按深度排序绘制this._boundingBox undefined;//包围盒this._boundingSphere undefined;//包围球 }; Drawable.prototype {setGeometry: function (g, transform) {this._geometry g;this._transform transform;},getGeometry: function () {return this._geometry;},getTransform: function () {return this._transform;},setStateBin: function (sb) {this._statebin sb;},getStateBin: function () {return this._statebin;},getCurrentStateBin: function () {return this._curStatebin;},// setDepth: function (d) {// this._depth d;// },getDepth: function () {return this._depth;},reset: function () {this._geometry undefined;this._transform undefined;this._statebin undefined;this._curStatebin undefined;this._depth 0.0;this._boundingBox undefined;this._boundingSphere undefined;},valid: function () {if (this._drawActor.getBaseCamera().isBoundingBoxCulled(this.getBoundingBox())) {return false;}return true;},isTransparent: function () {return false;},//计算深度值computeDepth: function () {//根据包围盒和相机变换矩阵确认中心点的Z值let mvmatrix this._drawActor.getBaseCamera().getModelViewMatrix();let temp Vec3.MemoryPool.alloc();this._depth this.distanceZ(this.getBoundingBox().getCenter(temp), mvmatrix);Vec3.MemoryPool.free(temp);//drawable.setDepth(depth);},//相机的矩阵要取反distanceZ: function (coord, matrix) {return -(coord[0] * matrix[2] coord[1] * matrix[6] coord[2] * matrix[10] matrix[14]);},getBoundingBox: function () {if(this._boundingBox undefined){this._boundingBox new BoundingBox();this._boundingBox.copy(this._geometry.getBoundingBox(true));if(this._transform){this._boundingBox.transformMat4(this._transform);}}return this._boundingBox;},getBoundingSphere: function () {if(this._boundingSphere undefined) {this._boundingSphere new BoundingSphere();let bb this.getBoundingBox();this._boundingSphere.expandByBoundingBox(bb);}return this._boundingSphere;},getRadius: function () {return this.getBoundingSphere().getRadius();},// There are 3 cases when there is a prev / current render leaf// pSG: previousStateGraph// cSG: currentStateGraph// pRL: previousRenderLeaf// cRL: currentRenderLeaf//// A B C// ----- ----- ----- -----// | pSG | | cSG | -- SG -- | SG |// ---- ---- | ----- | ----// | | | | |// --v-- --v-- --v-- --v-- --v--// | pSG | | cSG | | pSG | | cSG | -- SG --// ---- ---- ---- ---- | ----- |// | | | | | |// --v-- --v-- --v-- --v-- --v-- --v--// | pRL | | cRL | | pRL | | cRL | | pRL | | cRL |// ----- ----- ----- ----- ----- -----////// Case A// no common parent StateGraphNode we need to// popStateSet until we find the common parent and then// pushStateSet from the common parent to the current RenderLeaf//// Case B// common parent StateGraphNode so we apply the current stateSet//// Case C// the StateGraphNode is common to the previous RenderLeaf so we dont need// to do anything except if we used an insertStateSetdraw: function (glstate, preDrawable) {//先接受状态再渲染几何let curStateGraph this._statebin;let curStateGraphStateSet curStateGraph.getStateSet();let curStateGraphParent curStateGraph.getParent();let preStateGraph;let preStateGraphParent;if(preDrawable ! undefined){preStateGraph preDrawable._statebin;preStateGraphParent preStateGraph.getParent();if(preStateGraphParent ! curStateGraphParent){//AStateBin.moveStateBin(glstate, preStateGraphParent, curStateGraphParent);glstate.applyStateSet(curStateGraphStateSet);}else if(preStateGraph ! curStateGraph){//Bglstate.applyStateSet(curStateGraphStateSet);}else{// in osg we call apply but actually we dont need// except if the stateSetStack changed.// for example if insert/remove StateSet has been used// if (glstate._stateSetStackChanged(idLastDraw, lastStateSetStackSize )) {// glstate.applyStateSet(curStateGraphStateSet);// }}}else{//如果preLeaf为空第一个绘制的几何状态遍历到根节点全部push到GLState中StateBin.moveStateBin(glstate, undefined, curStateGraphParent);glstate.applyStateSet(curStateGraphStateSet);}let camera this._drawActor.getBaseCamera();glstate.applyModelMatrix(this._transform, camera.getModelViewMatrix(), camera.getProjectionMatrix());this._geometry.draw(glstate);return true;}, }; module.exports Drawable;// set: function (stateGraph, geometry, , depth) { // this._statebin stateGraph; // this._geometry geometry; // // this._depth depth; // }, // drawGeometry: function (glstate) { // //let program glstate.getLastProgramApplied(); // //let programID program.getID(); // //let programCaches glstate.getProgramCaches(); // //let obj programCaches[programID]; // // if(!obj){//程序不存在创建一个新的 // // obj new CacheUniformApply(glstate, program); // // programCaches[programID] obj; // // } // // //从相机获取modelview和projection // //着色器暂时不需要透视矩阵 // //let modelview this._camera.get // // // // //glstate.applyModelViewMatrix(this._modelview); // //glstate.applyProjectionMatrix(this._projection); // glstate.applyTransformMatrix(this._transform); // //this._modelview this._camera.getModelViewMatrix(); // //Mat4.mul(this._modelview, this._modelview, this._transform); // //this._projection this._camera.getProjectionMatrix(); // glstate.applyModelMatrix(this._transform, this._camera.getModelViewMatrix(), this._camera.getProjectionMatrix()); // // // //let gluniforms program.getGLUniformsCache(); // //let modelviewloc gluniforms[glstate._modelViewMatrixUniform.getName()]; // //let viewloc gluniforms[glstate._viewMatrixUniform.getName()]; // // //obj.apply(glstate, this._modelview, this._modelworld, this._view, this._projection, this._normal); // this._geometry.draw(glstate); // }, 我们先来看看Drawable的构造函数截取构造函数代码 let Drawable function (actor) {this._drawActor actor;//关联的DrawActorthis._geometry undefined;//渲染的几何Geometrythis._transform undefined;//世界变换 FloatArray(16)this._statebin undefined;//状态结点原始的状态没有额外功能时的状态this._curStatebin undefined;//如果状态会动态变化这里存储每一帧绘制时的状态结点this._depth 0.0;//场景深度值透明需要按深度排序绘制this._boundingBox undefined;//包围盒this._boundingSphere undefined;//包围球 }; 首先我们看到第一个私有属性是DrawActor我们看看DrawActor是个什么模块先贴出DrawActor类代码。 /* 绘制对象角色每个DrawActor管理自己的渲染数据自己的状态树自己的相机树 如果该功能销毁直接销毁对应的DrawActor资源 但是他引用的状态相机并不是他管理 不想把各个DrawActor搅和在一起逻辑混乱绘制分几种情况全自动全手动半自动 全自动-所有的绘制流程从一开始数据构造好后就不会再变更只需在初始化时确认好 后续直接渲染即可 半自动-部分绘制流程是固定的部分绘制流程是动态的比如构件场景下需要点选高亮等功能变化 全手动-所有的绘制流程都是动态的每一帧都需要重新构造每个drawable部分功能数据*/ let Drawable require(./Drawable); let StateBin require(./StateBin); let NodeVisitor require(../util/NodeVisitor); let CullStack require(./CullStack); let Mat4 require(../util/Mat4); let Group require(../core/Group); let Geode require(../core/Geode); let MatrixTrasform require(../core/MatrixTransform); let SceneRoot require(../scene/SceneRoot); let Geometry require(../core/Geometry);let DrawActor function (renderer) {NodeVisitor.call(this, NodeVisitor.TRAVERSE_CHILDREN);CullStack.call(this);//为正确渲染准备的数据this._renderer renderer;//所属的渲染器固有资产不会变更this._baseCamera this._renderer.getMainCamera();//相机默认为主相机this._baseState new StateBin();//状态this._sceneRoot undefined;//所属的场景根节点//渲染的对象this._drawables [];//this._drawIndex 0;//当前绘制的索引数需要固定帧率渲染的地方使用//this._currentStateBin undefined;//当前处理的状态树结点临时数据////this._fixed false;//是否启用固定帧率this._valid true;//直接屏蔽渲染的标记 };DrawActor.prototype Object.create(NodeVisitor.prototype); Object.assign(DrawActor.prototype, CullStack.prototype); DrawActor.prototype.constructor DrawActor; Object.assign(DrawActor.prototype, {setBaseCamera: function (camera) {//设置当前相机可以自由设置自己独特的相机this._baseCamera camera;},getBaseCamera: function () {return this._baseCamera;},getBaseStateBin: function () {return this._baseState;},getBaseStateSet: function () {return this._baseState.getStateSet();},//复原场景根节点的状态revertBaseState: function () {if (this._sceneRoot) {this._baseState.setStateSet(this._sceneRoot.getStateSet());}},//与场景的唯一联系一定要先定义好场景的几何和状态再调用setSceneRootsetSceneRoot: function (root) {this._sceneRoot root;//一定要先定义好场景根节点的状态否则会出错//this._baseState.setStateSet(root.getStateSet());},createDrawable: function () {//base overridereturn new Drawable(this);//创建对应类型的Drawable},addDrawable: function (drawable) {this._drawables.push(drawable);},getDrawables: function () {return this._drawables;},valid: function (valid) {if (valid ! undefined) {this._valid valid;}return this._valid;},//遍历apply: function (node) {this[node.typeID](node);},//重载压入一个状态pushStateSet: function (stateset) {if (stateset) {//添加StateGraph子节点更新当前活动的StateGraph为新的状态this._currentStateBin this._currentStateBin.addStateSetChild(stateset);}},//重载弹出一个状态popStateSet: function (stateset) {if (stateset) {this._currentStateBin this._currentStateBin.getParent();}},//重载pushDrawable: function (geometry) {let drawable this.createDrawable();drawable.setStateBin(this._currentStateBin);drawable.setGeometry(geometry, this.getCurrentTransformMatrix());this.addDrawable(drawable);},//根重载绘制当前Actor下的drawables绘制不需要固定帧率永远在第一帧里绘制完毕draw: function (glstate, preCamera) {if (!this._valid) {//不再绘制return preCamera;}this.drawCamera(preCamera);//循环遍历一遍drawables绘制实体let preDrawable undefined;let l this._drawables.length;for (let i this._drawIndex; i l; i) {let drawable this._drawables[i];if (drawable.valid()) {drawable.draw(glstate, preDrawable);//成功绘制的preDrawable drawable;}this._drawIndex;}return this._baseCamera;},//每个新帧绘制之前的重置工作drawReset: function () {this._baseCamera.setClearFlag(false);this._drawIndex 0;},//当前Actor的对象是否全部绘制完毕drawFinished: function () {return this._drawables.length this._drawIndex;},//绘制相机状态(视口清空)drawCamera: function (preCamera) {if (preCamera this._baseCamera) {//重复的不再处理return;}//视口何时都需要设置let glstate this._renderer.getGLState();glstate.applyAttribute(this._baseCamera.getViewport());//以下是每个相机只需要处理一次的事情if (!this._baseCamera.getClearFlag()) {//更新视锥体确保剔除正确每帧相机的投影矩阵和视图矩阵可能都会变化this._baseCamera.updateCullFrustum();//清空颜色和深度但如果是主相机不再需要在最开始就已经清空let clearmask this._baseCamera.getClearMask();if (clearmask ! 0x0) {let gl glstate.getWebGLContext();if (clearmask gl.COLOR_BUFFER_BIT) {let color this._baseCamera.getClearColor();//清空颜色gl.clearColor(color[0], color[1], color[2], color[3]);}if (clearmask gl.DEPTH_BUFFER_BIT) {let depth this._baseCamera.getClearDepth();//清空深度gl.depthMask(true);gl.clearDepth(depth);}gl.clear(clearmask);}this._baseCamera.setClearFlag(true);}},//根重载线段求交返回相交的drawable对象linesegmentIntersect: function (start, end, threshold) {let LineSegmentIntersector require(../util/LineSegmentIntersector);let intersector new LineSegmentIntersector();intersector.initialize(start, end, threshold);let length this._drawables.length;for (let i 0; i length; i) {let drawable this._drawables[i];if (drawable.valid()) {//没有隐藏没有被剔除的drawable进行相交运算intersector.intersect(drawable);}}//线段求交结果需要根据ratio排序return intersector.getIntersections();}, });DrawActor.prototype[SceneRoot.typeID] function (root) {this._baseState.removeChildren();this._baseState.setStateSet(root.getStateSet());this._currentStateBin this._baseState;this.pushTransformMatrix(root.getRootTransform());//变换矩阵中先推入一个单位矩阵作为根节点非常重要this.traverse(root);this.popTransformMatrix();this._currentStateBin undefined; }; DrawActor.prototype[MatrixTrasform.typeID] function (node) {//模型矩阵变换let lastModelMatrix this.getCurrentTransformMatrix();let mmatrix undefined;if (lastModelMatrix) {mmatrix Mat4.clone(lastModelMatrix);} else {mmatrix Mat4.new();}node.computeLocalToWorldMatrix(mmatrix);this.pushTransformMatrix(mmatrix);//状态let stateset node.getStateSet();this.pushStateSet(stateset);this.traverse(node);this.popStateSet(stateset);this.popTransformMatrix(); }; DrawActor.prototype[Geode.typeID] function (geode) {this[Group.typeID](geode); }; DrawActor.prototype[Group.typeID] function (group) {let stateset group.getStateSet();this.pushStateSet(stateset);this.traverse(group);this.popStateSet(stateset); }; DrawActor.prototype[Geometry.typeID] function (geometry) {//Geometry已经是叶子不需要继续递归了let stateset geometry.getStateSet();this.pushStateSet(stateset);this.pushDrawable(geometry);this.popStateSet(stateset); }; module.exports DrawActor; // reset: function () { // this._drawables.length 0;//置空 // this._sceneRoot undefined; // }, // polytopeIntersect: function () { // // }, // sphereIntersect: function () { // // },   我们可以看到DrawActor是将要被绘制的对象分成全自动初始化模型数据就构造Drawable准备渲染、半自动事件触发后构造Drawable等待渲染、全手动用户自己构造Drawable用户自己将Drawable排入渲染队列。我们看到DrawActor的构造函数包含的私有属性有this._renderer渲染器、this._baseCamera待渲染模块所属相机、this._baseState状态对应shader里的uniform参数、this._sceneRoot所属场景根节点、this._drawables包含的渲染对象、this._drawIndex当前绘制的索引数代表本次绘制是第几次绘制如果一此不能全部绘制完就分多次绘制例如模型增长、this._currentStateBin当前处理的状态树节点、this._valid屏蔽渲染的标记true加入渲染队列false不加入渲染队列。   我们再来看看DrawActor的成员函数都做了什么我们依次来看。 1.setBaseCamera设置参考相机这就是设置当前绘制对象的观察相机。2.getBaseCamera获取参考相机。3.getbaseStateBin获取状态信息包括当前渲染对象绑定的shaderuniform参数以及frameBuffer材质。4.getBaseStateSet同样是获取当前渲染对象的状态信息shaderuniform材质信息depth深度缓冲等。5.revertBaseState恢复场景根节点状态包括shaderuniform参数材质信息depth深度缓存。6.setSceneRoot设置场景根节点。7.createDrawable创建渲染对象。8.addDrawable追加渲染对象进入绘制对象数组。9.getDrawable返回渲染对象数组。10.valid标记当前渲染对象是否被屏蔽。11.apply取出每个渲染节点。12.pushStateSet向stateBin中加入stateSet这里说明一点stateSet是stateBin的属性。13.popStateSet从stateBin中取出stateSet属性参数。14.pushDrawable创建渲染对象drawable然后加入drawActor的drawable渲染对象数组。15.draw这才是drawActor的核心功能函数同学们鲫鱼为大家隆重介绍绘制函数或者叫渲染函数这就是将所有的drawable渲染对象进行遍历渲染的功能函数。16.drawReset每一帧绘制之前的整理重置。17.drawFinished判断当前drawActor绘制对象是否全部将drawable数组中的渲染对象绘制完毕。18.drawCamera绘制相机状态视口深度缓冲如果没有渲染对象私有独立的相机就操作主相机。19.linesegmentIntersection射线碰撞重载父类方法。   依次看一下上面的函数我们大致了解了DrawActor类处理的是渲染流程管理的工作。我们接下来继续看Drawable类的其他属性。我们再贴出一次drawable的构造函数。 let Drawable function (actor) {this._drawActor actor;//关联的DrawActorthis._geometry undefined;//渲染的几何Geometrythis._transform undefined;//世界变换 FloatArray(16)this._statebin undefined;//状态结点原始的状态没有额外功能时的状态this._curStatebin undefined;//如果状态会动态变化这里存储每一帧绘制时的状态结点this._depth 0.0;//场景深度值透明需要按深度排序绘制this._boundingBox undefined;//包围盒this._boundingSphere undefined;//包围球 }; 我们已经看过了this._drawActor也知道了drawActor是管理渲染的类。接下来我们看this._geometry渲染的几何体成员对象。this._transform空间变换矩阵。this._statebin状态节点用来添加stateSet状态参数对象。this._currStatebin保存每一帧的临时状态stateSet。this._depth场景深度值作用于主相机或渲染对象私有相机如果有私有相机的话。this._boundingBox包围盒。this._boundingSphere包围球。这些就是Drawable类的成员。我们马上来看一下Drawable的成员函数。  Drawable成员函数。贴出代码。 setGeometry: function (g, transform) {this._geometry g;this._transform transform;},getGeometry: function () {return this._geometry;},getTransform: function () {return this._transform;},setStateBin: function (sb) {this._statebin sb;},getStateBin: function () {return this._statebin;},getCurrentStateBin: function () {return this._curStatebin;},// setDepth: function (d) {// this._depth d;// },getDepth: function () {return this._depth;},reset: function () {this._geometry undefined;this._transform undefined;this._statebin undefined;this._curStatebin undefined;this._depth 0.0;this._boundingBox undefined;this._boundingSphere undefined;},valid: function () {if (this._drawActor.getBaseCamera().isBoundingBoxCulled(this.getBoundingBox())) {return false;}return true;},isTransparent: function () {return false;},//计算深度值computeDepth: function () {//根据包围盒和相机变换矩阵确认中心点的Z值let mvmatrix this._drawActor.getBaseCamera().getModelViewMatrix();let temp Vec3.MemoryPool.alloc();this._depth this.distanceZ(this.getBoundingBox().getCenter(temp), mvmatrix);Vec3.MemoryPool.free(temp);//drawable.setDepth(depth);},//相机的矩阵要取反distanceZ: function (coord, matrix) {return -(coord[0] * matrix[2] coord[1] * matrix[6] coord[2] * matrix[10] matrix[14]);},getBoundingBox: function () {if(this._boundingBox undefined){this._boundingBox new BoundingBox();this._boundingBox.copy(this._geometry.getBoundingBox(true));if(this._transform){this._boundingBox.transformMat4(this._transform);}}return this._boundingBox;},getBoundingSphere: function () {if(this._boundingSphere undefined) {this._boundingSphere new BoundingSphere();let bb this.getBoundingBox();this._boundingSphere.expandByBoundingBox(bb);}return this._boundingSphere;},getRadius: function () {return this.getBoundingSphere().getRadius();}, 都是设置和获取属性的函数包括包围盒和包围球。接下来我们来看看最核心的部分隆重介绍draw绘制函数请看代码。 // There are 3 cases when there is a prev / current render leaf// pSG: previousStateGraph// cSG: currentStateGraph// pRL: previousRenderLeaf// cRL: currentRenderLeaf//// A B C// ----- ----- ----- -----// | pSG | | cSG | -- SG -- | SG |// ---- ---- | ----- | ----// | | | | |// --v-- --v-- --v-- --v-- --v--// | pSG | | cSG | | pSG | | cSG | -- SG --// ---- ---- ---- ---- | ----- |// | | | | | |// --v-- --v-- --v-- --v-- --v-- --v--// | pRL | | cRL | | pRL | | cRL | | pRL | | cRL |// ----- ----- ----- ----- ----- -----////// Case A// no common parent StateGraphNode we need to// popStateSet until we find the common parent and then// pushStateSet from the common parent to the current RenderLeaf//// Case B// common parent StateGraphNode so we apply the current stateSet//// Case C// the StateGraphNode is common to the previous RenderLeaf so we dont need// to do anything except if we used an insertStateSetdraw: function (glstate, preDrawable) {//先接受状态再渲染几何let curStateGraph this._statebin;let curStateGraphStateSet curStateGraph.getStateSet();let curStateGraphParent curStateGraph.getParent();let preStateGraph;let preStateGraphParent;if(preDrawable ! undefined){preStateGraph preDrawable._statebin;preStateGraphParent preStateGraph.getParent();if(preStateGraphParent ! curStateGraphParent){//AStateBin.moveStateBin(glstate, preStateGraphParent, curStateGraphParent);glstate.applyStateSet(curStateGraphStateSet);}else if(preStateGraph ! curStateGraph){//Bglstate.applyStateSet(curStateGraphStateSet);}else{// in osg we call apply but actually we dont need// except if the stateSetStack changed.// for example if insert/remove StateSet has been used// if (glstate._stateSetStackChanged(idLastDraw, lastStateSetStackSize )) {// glstate.applyStateSet(curStateGraphStateSet);// }}}else{//如果preLeaf为空第一个绘制的几何状态遍历到根节点全部push到GLState中StateBin.moveStateBin(glstate, undefined, curStateGraphParent);glstate.applyStateSet(curStateGraphStateSet);}let camera this._drawActor.getBaseCamera();glstate.applyModelMatrix(this._transform, camera.getModelViewMatrix(), camera.getProjectionMatrix());this._geometry.draw(glstate);return true;}, 我将注释也贴了出来我们可以看到渲染绘制是分三种情况的首先我们要了解一下StateGraph渲染属性这个来源于osg的概念。stateGraph是渲染的状态属性包括本次渲染绑定的shaderuniform参数frameBuffer材质属性depth深度属性。好了大致了解了StateGraph后我们再来了解一下RenderLeaf渲染叶这个同样来自osg的概念。RenderLeaf是渲染叶需要注意的是渲染叶保存的是sceneTree的节点状态而不是场景树的几何和transform信息。好了了解了这两个概念我们来看看这三种情况。A.前一帧stateGraph和后一帧stateGraph没有同一个父节点B.前后两帧stateGraph有同一个父节点C.前后两帧renderLeaf有共同父节点。针对这三种情况处理的方式不同需要注意。鲫鱼也才开始逐步研究osg框架理解不到位之处请各位方家海涵。  好了今天讲述的是osg的渲染模块中的一部分DrawActor和Drawable两个模块。下一篇会进一步讲述渲染模块。欢迎大家讨论祝大家元旦快乐。本文系原创如需引用请注明出处https://www.cnblogs.com/ccentry/p/10199157.html                         转载于:https://www.cnblogs.com/ccentry/p/10199157.html
http://www.zqtcl.cn/news/132516/

相关文章:

  • 成都 网站制作购物网站建设包括哪些
  • 浅谈电子商务网站建设产品推广方案怎么做
  • 做ppt的图片素材网站北京网站制作南昌
  • 全网视频合集网站建设宏基陆通工程建设有限公司网站
  • 极捷号网站建设wordpress搬家500错误
  • 网站加友情链接app开发培训课程
  • 济南网站排名优化报价平台推广话术
  • 自己做的创意的网站短链接生成站长工具
  • 爱站网是怎么回事网站语音转写怎么做
  • 一级a做爰片免播放器网站扬中门户网
  • 舆情网站大全模板网站有哪些在哪里下载
  • 新网站关键词怎么优化深圳公司网站推广
  • 新加坡购物网站排名英文版wordpress安装
  • 哪个网站做ppt能赚钱企查查企业信息
  • 学校建设网站的意义wordpress 鸟
  • 一个ip做网站网站建设基础课件
  • 包装设计十大网站连云港网站建设开发
  • 川沙网站建设网站推广服务外包有哪些渠道
  • 哪些网站可以做招商广告手机怎么创网站免费
  • 换物网站为什么做不起来网站开发工具的功能包括
  • 引导式网站君和网站建设
  • 西柏坡门户网站建设规划书自己做照片书的网站
  • 做网站横幅的图片多大公司做自己的网站平台台
  • 百度网站建设工资给城市建设提议献策的网站
  • 如何进入网站管理页面维护网站需要多少钱
  • 深圳住房和城乡建设局网站阿里云学生免费服务器
  • 如何做的网站手机可以用吗绵阳优化网站排名
  • 营销网站建设大全wordpress wp_register
  • 公司做年审在哪个网站网络seo专员招聘
  • 宿州网站建设费用网站快速建设入门教程