打零3D基础入门XNA 4.0(2)——模型与BasicEffect

第一不良卧谈会

【题外话】

女生宿舍

落得一样篇文章介绍了3D开发基础及XNA开发顺序的整布局,以及利用Model类的Draw方法将模型绘制到屏幕及。本文就上亦然篇文章继续,介绍XNA中范的组织、BasicEffect的采用和用户输入和界面显示的办法相当,本文尽量把遇到的概念都分析清楚,但以避开复杂的数学方面的知,希望对没碰了3D开发的同桌有助。

班会结束后,大家各自回到宿舍。

 

芷苓洗了颜面回到床上,拿出手机看小说。覃沁在通话,一个东北姑娘,一丁东北腔却带来在温柔,轻声细语的,听不彻底说啊。徐沫沫任语气是和它爸爸妈妈打电话,嗓门忽大忽小的。因为它们虽在芷苓的上铺,想不听其说啊还不便。

【系列索引】

徐沫沫通话的横意思就是是:“母亲家长,一切都吓,就是太烫了,宿舍里没空调,只来个别单电风扇,好好,我明天尽管失去市一个小电扇放在床头。爸爸,开学你受自己之五千片还剩有为,不用还为自己那么多,一千块就得了,爱尔喲,爸爸再见,妈妈再见”。

  1. 打零3D基础入门XNA
    4.0(1)——3D开发基础
  2. 自打零3D基础入门XNA
    4.0(2)——模型和BasicEffect

倘杨羽灵同刘怡萱于讨论各自所用的护肤品品牌与采取后的成效。

 

“芷苓,你安息前都未足够个面膜的呢?”羽灵正使开辟面膜的口袋时,看了芷苓一眼问道。

【文章索引】

“哦,我有些用护肤品的,不习惯”芷苓的视线从手机里易出,看正在羽灵笑着对。

  1. Model模型的构造
  2. BasicEffect效果的装置
  3. XNA的用户输入
  4. XNA界面的显示方式

“哎呦,女生要过得硬爱护自己啦,敷面膜就是轻自己之见哦,多为此几不好就是习以为常了”怡萱也一头敷在面膜一边商量。

 

“都说没有丑女人只发生嗜睡女人,虽说我们尚年轻,但为只要早护理皮肤,让她一直保持水嫩,来,给您平切开”羽灵从友好的面膜盒里将出同切片为芷苓。

【一、Model模型的结构】

“谢谢啊”,芷苓接了面膜,把她身处床边的柜子里。

达成一致首稿子使Model自带的Draw方法实现了第一手用载入的Model绘制到指定的职上,但是有时绘制出的作用并无合乎我们的意料,比如下图(下图的范是通过Maya创建的一个室):

芷苓真的有点敷面膜,护肤品也异常少用,一凡它的于自我管理方面的确是疲劳,二凡是她家的经济条件虽不发愁吃过,但为并没有剩余的钱给它们进最多的护肤品,一直很少用,自然吧就是没有这习惯了。

夜10接触,大家忙于完各自的业务后,陆续躺下了。

通过ILSpy查看Microsoft.Xna.Framework.Graphics.Model,可以望其Draw方法的代码如下:

“哎,我们班男生都挺帅的吧,各有特点,你们以为吧”陶昕然首先被了话题。别当女神都是高高在上,很神秘之。其实,她们有来时候是极度八卦的。

“对啊对啊,特别是马宏烨,他笑笑起来有酒窝哦,好好看”徐沫沫激动之游说。

 1 public void Draw(Matrix world, Matrix view, Matrix projection)
 2 {
 3     int count = this.meshes.Count;
 4     int count2 = this.bones.Count;
 5     Matrix[] array = Model.sharedDrawBoneMatrices;
 6     if (array == null || array.Length < count2)
 7     {
 8         array = new Matrix[count2];
 9         Model.sharedDrawBoneMatrices = array;
10     }
11     this.CopyAbsoluteBoneTransformsTo(array);
12     for (int i = 0; i < count; i++)
13     {
14         ModelMesh modelMesh = this.meshes[i];
15         int index = modelMesh.ParentBone.Index;
16         int count3 = modelMesh.Effects.Count;
17         for (int j = 0; j < count3; j++)
18         {
19             Effect effect = modelMesh.Effects[j];
20             if (effect == null)
21             {
22                 throw new InvalidOperationException(FrameworkResources.ModelHasNoEffect);
23             }
24             IEffectMatrices effectMatrices = effect as IEffectMatrices;
25             if (effectMatrices == null)
26             {
27                 throw new InvalidOperationException(FrameworkResources.ModelHasNoIEffectMatrices);
28             }
29             effectMatrices.World = array[index] * world;
30             effectMatrices.View = view;
31             effectMatrices.Projection = projection;
32         }
33         modelMesh.Draw();
34     }
35 }

“喔哦,原来你欣赏这种形式的”陶昕然略带玩谑回道。

View Code

“没有了,人家只是纯粹觉得难堪了,好看的人数以及东西我们还设明欣赏嘛”。徐沫沫说正在还带在同等沾羞涩之话音。

内部可见,Draw方法通过遍历模型的Mesh,然后重新遍历每个Mesh的Effect,并对准每个Effect进行安装,最后使Mesh的Draw方法将那绘制到屏幕上。

“我觉着李子毅又大又投中的范,还特别有魅力之,你们不认为吧?”。怡萱参与进来了。

为了解Model的渲染,我们率先需要了解Model的布局。实际上,在一个Model对象中,包含Bone集合(model.Bones)、Mesh集合(model.Meshes)以及根Bone(model.Root)三只属性,其布局以及干如下:

“是生那点魅力,但觉得他小高傲,不极端好相处”,羽灵也参加了。

陶:“覃沁,你对咱班男生怎么看?”

可观看于每个ModelMesh,包含一组ModelMeshPart与一个ParentBone。其中,

“不怎么看,都太嫩”,覃沁此话一发,徐沫沫忍不住笑出声了。

  • ModelMesh代表单个可以独自运动的大体对象。例如,一个car的Model可以蕴涵一个车体(body)的ModelMesh、四个车轱辘(wheel)的ModelMesh与一对门(door)的ModelMesh。
  • ModelMeshPart表示单个一律材料的构件,其代表一个独立的绘图调用(draw
    call)。例如,上述车身可以蕴涵着品质之外部、使用环境映射(environment
    mapping)效果的挡风玻璃以及使用法线贴图(normalmap
    texture)效果的座椅等等。
  • ModelBone表示了对应的ModelMesh如何变换,其涵盖一个Transform的转移矩阵。ModelBone是因树形存储的,每个ModelBone都有一个父节点以及几独子节点。上述的每个ModelMesh都发生一个ParentBone,ModelMesh可以因ModelBone的易来规定最终显示的职等。例如,上述车门的ModelBone与车轮的ModelBone是车身的子节点等等。

陶:“沫沫,你乐啊”。

据此遍历一个Model中拥有的ModelMesh,然后遍历其中有的ModelMeshPart,并且根据ModelMesh的ParentBone来用诸一个ModelMeshPart绘制到指定的职位及就是足以绘制出整体的Model。

缓缓:“没什么,都无比浅,让人口感念歪了”。

可是对此每个ModelMeshPart,其实际渲染的功用还设有Effect的性质被,对于默认来说,Effect都为BasicEffect。此外,对于ModelBone,其易矩阵都是对立其本身的Parent来之,不过Model类也供了一个方法,即CopyAbsoluteBoneTransformsTo(),即可将每个Bone相对于RootBone的变矩阵复制到一个矩阵数组中,然后将那个下及Effect中即可。这种方法及上述提到的Model.Draw类似,不过自己写的言辞就是可以起定义每个ModelMeshPart渲染之机能,当然也得以装每个ModelMeshPart的渲染位置。

芷苓:“覃沁,你刚好与谁打电话啊,声音好温柔哦”芷苓也起八卦起来。

那么连下去便随此思路去贯彻,同时以安各一个Effect时,使用Effect提供的用默认光照的方法EnableDefaultLighting(),启用后效果如下:

“我男朋友”覃沁毫不避讳的说。

芷苓:“他是咱学校的也?”

这么的职能就算上了咱们的意料,按上述的法子实现之代码如下:

源远流长:“不是,他当北京呢,他家在那边”。

芷苓:“在那看呢?”

 1 Matrix world = Matrix.CreateWorld(Vector3.Zero, Vector3.Forward, Vector3.Up);
 2 
 3 Matrix[] transforms = new Matrix[model.Bones.Count];
 4 this.model.CopyAbsoluteBoneTransformsTo(transforms);
 5 
 6 foreach (ModelMesh mesh in model.Meshes)
 7 {
 8     Int32 boneIndex = mesh.ParentBone.Index;
 9 
10     foreach (ModelMeshPart part in mesh.MeshParts)
11     {
12         BasicEffect effect = part.Effect as BasicEffect;
13         
14         effect.EnableDefaultLighting();
15         effect.World = transforms[boneIndex] * world;
16         effect.View = cameraView;
17         effect.Projection = cameraProjection;
18     }
19 
20     mesh.Draw();
21 }

覃:“不是,工作了”

View Code

陶:“你们怎么在一道的呦”,陶昕然显然对之话题呢很感兴趣。

可这与才盼底Model.Draw的代码并不相同。实际上,XNA为了简化操作,已经以ModelMeshPart的每个Effect放到了ModelMesh的Effects集合中,只需要遍历这个集就好,而随便需重新遍历ModelMeshPart,再得到Effect了。所以上述代码可以简化为如下的代码:

深:“他同自身哥是朋友,我高中的时刻,他来我家玩,就认了,然后便于同步了”

 1 Matrix world = Matrix.CreateWorld(Vector3.Zero, Vector3.Forward, Vector3.Up);
 2 
 3 Matrix[] transforms = new Matrix[model.Bones.Count];
 4 this.model.CopyAbsoluteBoneTransformsTo(transforms);
 5 
 6 foreach (ModelMesh mesh in model.Meshes)
 7 {
 8     Int32 boneIndex = mesh.ParentBone.Index;
 9     
10     foreach (BasicEffect effect in mesh.Effects)
11     {
12         effect.EnableDefaultLighting();
13         effect.World = transforms[boneIndex] * world;
14         effect.View = cameraView;
15         effect.Projection = cameraProjection;
16     }
17 
18     mesh.Draw();
19 }

徐:“哇,不错哦”

 

远大:“徐沫沫,你谈话了几不行婚恋?”

【二、BasicEffect效果的装置】

徐:“一次啊”

首先用ILSpy查看下BasicEffect的EnableDefaultLighting()的代码:

杨:“现在尚于齐为?”

public void EnableDefaultLighting()
{
    this.LightingEnabled = true;
    this.AmbientLightColor = EffectHelpers.EnableDefaultLighting(this.light0, this.light1, this.light2);
}

暂缓:“没有,毕业时了,你吧?”

内this.light0-2为BasicEffect的DirectionalLight0-2,即BasicEffect可以上的老三只光源。而EffectHelpers的EnableDefaultLighting是这样勾画的:

杨:“我吗一个啊,现在还当协同,我们初中同学,初中毕业我们便当一齐了”

刘:“他事先表白的也罢?”

 1 internal static Vector3 EnableDefaultLighting(DirectionalLight light0, DirectionalLight light1, DirectionalLight light2)
 2 {
 3     light0.Direction = new Vector3(-0.5265408f, -0.5735765f, -0.6275069f);
 4     light0.DiffuseColor = new Vector3(1f, 0.9607844f, 0.8078432f);
 5     light0.SpecularColor = new Vector3(1f, 0.9607844f, 0.8078432f);
 6     light0.Enabled = true;
 7     light1.Direction = new Vector3(0.7198464f, 0.3420201f, 0.6040227f);
 8     light1.DiffuseColor = new Vector3(0.9647059f, 0.7607844f, 0.4078432f);
 9     light1.SpecularColor = Vector3.Zero;
10     light1.Enabled = true;
11     light2.Direction = new Vector3(0.4545195f, -0.7660444f, 0.4545195f);
12     light2.DiffuseColor = new Vector3(0.3231373f, 0.3607844f, 0.3937255f);
13     light2.SpecularColor = new Vector3(0.3231373f, 0.3607844f, 0.3937255f);
14     light2.Enabled = true;
15     return new Vector3(0.05333332f, 0.09882354f, 0.1819608f);
16 }

杨:“也不算是谁先表白的,我们互相爱慕,毕业约在一块打,然后我说,要无我们当齐吧,他说好,然后就是于一块了,”

View Code

芷苓:“哇,听在仿佛死灿烂啊,初中就于联合,真好!”

可观看于启用默认光照里实际是受条件光AmbientLightColor以及三束定向光(包括光线的势头、漫反射颜色与镜面反射颜色)设置了事先定义好之颜色,并启用了这些光源,这三羁绊定向光的水彩(Light1的漫反射光的颜色如下,但彼镜面反射光的颜色为黑色)和趋势大约如下。

杨:“其实,在同步三年差不多了,已经没什么激情之痛感了,就变得不行寻常了。徐沫沫,你们怎么分了?”

缓缓:“唉,分了即是分开了,他冲腿,就这样,没什么好说的”

生图第一单吗启用了默认光照后底范(上同篇稿子被的dude),第二、三、四单呢单纯启用默认光照的环境光及0、1、2叔束缚定向光后的型,第五个也没启用默认光照的型(如同上亦然首产生的效应等同):

芷苓:“只能说他瞎”。

暂缓:“呦,看来您呢是发故事之女校友,来来来,说有公的故事”。

自然,在许多情况下(比如户外的太阳等),我们特需要一个光源,届时我们如果禁用(DirectionalLight*.Enabled
= false)其他两个定向光即可,当然我们或许还欲修改光源的颜料等等。

芷苓:“我尚未啊故事,只是听着你们说这些,觉得好优质”。

而外使用EnableDefaultLighting,BasicEffect还提供了比较丰富的参数可以安装。首先来拘禁下上述例子中Effect默认的性能:

陶:“你没有出口过恋爱也?”

芷苓:“没有”。

中跟光线有关的:

陶:“喜欢的人头到底起吧”。

  • LightingEnabled:是否被光照(默认也false)。
  • PreferPerPixelLighting:是否开启逐像素的光照(默认为false,为逐顶点光照),逐像素光照相对于逐点光照效果还好,但速度为重缓慢,同时还索要显卡支持Pixel
    Shader Model 2.0,如果显卡不支持之言辞会活动使用逐顶点光照代替。
  • AmbientLightColor:环境光颜色(默认为Vector3.Zero)。为了当有光照模型(模型中的普照互不影响)中加强真实感,引入了环境光的定义。环境单纯不指任何光源,但那震慑所有物体。
  • DiffuseColor:漫反射颜色(默认为Vector3.One)。光线照到物体后,物体进行漫反射,其颜色和光线的自由化有关。
  • SpecularColor:镜面反射颜色。光线照交物体后,物体进行全反射,其颜色不仅和光线的矛头有关,还与观(相机)的自由化有关。
  • EmissiveColor:放射颜色(默认为Vector3.Zero)。放射光是凭借物体发出的光明,但每当有的光照模型中,实际上不会见针对另外物体产生震慑。
  • DirectionalLight0、DirectionalLight1、DirectionalLight2:三束定向光(每束都连光线的势头、漫反射颜色跟镜面反射颜色)。

芷苓:“有了,但是他近乎不爱好自,所以我常有没表白过,也未曾叫表白过”。

中需注意的是,在XNA中,颜色之蕴藏并无是采取的Color(ARGB或ABGR),而是用的Vector3(或Vector4)。对于Vector3,其x、y、z三个重存储的个别是R、G、B分别除以255之浮点值(Vector4的w分量存储的是Alpha通道除以255底浮点值),所以Vector3.Zero即为黑色,而Vector3.One为白色。当然XNA也提供了一个Color类,并且Color也供了供了一直换为Vector3(或Vector4)的方式ToVector3()(或ToVector4())。

杨:“喜欢将去表白,要勇于,像我同一”。

除此之外,BasicEffect还支持设置雾的意义:

芷苓:“好,以后自己尝试”。

  • FogEnabled:是否打开雾的职能(默认也false)。
  • FogColor:雾的水彩(默认为Vector3.Zero)。
  • FogStart:雾距离相机的始发(最近)值(默认为0.0F),这个离内的物不深受雾的影响。
  • FogEnd:雾距离相机的收(最远)值(默认为1.0F),这个距离外的物了看无干净。

男生宿舍

也就是说,雾以会见于去相机(FogStart –
FogEnd)的地方有,这个离要依据物体所当的岗位决定。设Distance为体距离相机的距离,则Distance<FogStart<FogEnd时,物体不叫雾的震慑,与从不雾时一样;当FogStart<FogEnd<Distance时,物体完全看无干净(即物体全部为雾的颜料);当FogStart<Distance<FogEnd时,物体受雾的熏陶,物体离FogEnd越走近则更是看无清。

男生宿舍的同学等而没有那么早睡觉,他们还于各自忙碌在温馨之政工。周岸军从班会回到宿舍后,上网浏览新闻,随后开始了外尽干部式的演说:“你们看,就只有是咱班,女生数量就是咱男生的相同倍增,男女比例严重失调,这是同样种植社会气象,值得深思啊”。

例如当人的模子在(0, 0, 0),相机在(120, 120,
120)处,雾的水彩吗Gray。下图第一独为没加雾的功用,第二单呢FogStart –
FogEnd为200 – 300,第三个也1 – 300,第四只呢1 – 100。

“你是想说,我们就是当学找不女对象,是吧”王洋刚洗完澡出来,指出了这种景象指向母校男生的重要性影响。“不了如李子毅这样条件的,无论是什么环境下都不怕交不至女性对象”。王洋将目光转移到了李子毅身上。

“是啊,不感兴趣”,正在玩手机的李子毅不留心的报了平句子。

 

王洋:“我们班的陶昕然漂亮而发气派,感觉与公特别充实哦”。

【三、XNA的用户输入】

李子毅还是未留意的报了句:“一般吧”。

当默认生成XNA程序中的Update方法里,有一个落GamePad的状态,当用户1的GamePad按下了“Back”键后将见面退出程序。微软对用户输入的支撑都在Microsoft.Xna.Framework.Input中,除了GamePad之外,微软还支持获取Keyboard、Mouse这片种植的状态。此外在Microsoft.Xna.Framework.Input.Touch中,还有TouchPanel可以取得触摸的状态。与GamePad相同,其他的这些状态为都是经过微软供给类中之GetState()方法进行得。

王洋:“不是吧,我要是取消刚刚说之口舌了,你就眼光,即使女生是男生的同等倍,你啊会见找不交女性对象的”。

譬如要取键盘和鼠标的状态,我们好透过如下方式:

李子毅:“无所谓”。

KeyboardState kbState = Keyboard.GetState();
MouseState mouseState = Mouse.GetState();

王洋带在八卦的响声问道:“你切莫见面是好男生吧”。

对判断键盘的按键,可以经过如下的办法赢得是否仍下了指定按键:

李子毅终于生出硌反应的掉:“去你的”。

Boolean pressed = kbState.IsKeyDown(Keys.Enter);

王洋继续他的发言:“其实喜欢男生也不在乎,只要是的确好就是尽,我们本是高居什么都能接受的一时,话说,你们尚未哪位想在高等学校里谈场恋爱的也罢?”

苟对鼠标的按键,则用看清按键的ButtonState才得以,例如判断鼠标左键是否按下:

还当玩耍里血战的吴浩答了句:“我要是打,其他与我无关,妹子啊起戏有趣”。

Boolean pressed = (mouseState.LeftButton == ButtonState.Pressed);

尹鹏:“我是否当此地呆下去还无自然为,找什么妹子,别耽误别人”。

除去,如果一旦看清鼠标是否在程序区域外,可以透过如下的道判断

周岸军:“我们且是同班,我们设相互团结友爱,互帮互助,兔子不吃窝边草,这句话你没有耳闻过吧?”。

if (this.GraphicsDevice.Viewport.Bounds.Contains(mouseState.X, mouseState.Y))
{
    //TODO
}

王洋:“书记说得是”。

虽然于大部分状下,如果为用户操作鼠标的言语会当程序外展示一个自定义的指针。但有时写单稍程序,为了简单希望直接用系统的指针,我们可以以次的即兴位置(构造方法、Initialize甚至Update也只是)写如下的代码,就得展示鼠标指针了,反的则足以藏:

周岸军:“不过,我及想了解你们来无出女对象?”

this.IsMouseVisible = true;

刚挂断电话的石新坤:“书记,这事你为如管什么”。

 

周岸军:“了解舍友的情状况,也有助于我们增强同窗情谊啊”。

【四、XNA界面的显示方式】

石新坤:“我生,另一个学的”。

默认情况下,运行XNA的先后会活动为800*480底分辨率显示,若要改显示的分辨率,其实非常简单,仅需在Game的构造方法中添加如下代码即可:

“我发过”马宏烨获得在吉他,略带忧郁谈谈的游说,这个忧郁的色与正于班会上阳光非常男孩的影像了两样。

graphics.PreferredBackBufferWidth = 1024;
graphics.PreferredBackBufferHeight = 768;

吴浩刚好得了了同等商厦打:“我还结合了邪”。

这样XNA的次第即使可知随我们设定的分辨率显示了。除此之外,如果我们愿意XNA的次第会全屏显示,我们尚得增长如下的代码:

石新坤:“卧槽,什么时候的从业,恭喜啊”。

graphics.IsFullScreen = true;

吴浩:“游戏里,结了怪频繁了”。吴浩指了赖他的电脑游戏界面。

当我们还好吃用户来切换全屏与窗口化,但是这行代码写在Update()中是不起作用的,不过XNA提供另外一个术,就是graphics.ToggleFullScreen()。例如我们需要依照F键进行全屏与窗口化的切换,可以编制如下的代码:

公纷纷给了他一个赞誉:“I  服了  U”。

KeyboardState kbState = Keyboard.GetState();
if (kbState.IsKeyDown(Keys.F))
{
    graphics.ToggleFullScreen();
}

森人口都说,学校里之卧谈会是无与伦比能增长相互之间感情,了解各自故事之移位。因为当您睡在床上,在登睡眠状态前,你会转换得专程放松、变得软,也就算便于说发生过多故事,抒发出多当光天化日莫克顺风表达的感情。

 

芷苓没有想到,原本只是简短的聊天,最后会爆出大家这么多之故事葡京游戏网址。似乎每个人都出或幸福、或心酸的故事,而芷苓却招来不至有关自己之故事,显得那么苍白。

【相关链接】

实在,关于爱情、关于青春、关于冀,每个人犹见面生出谈得来的故事,有些故事就起,有些故事冥冥之中总会赶来。

  1. Model
    Class:http://msdn.microsoft.com/en-us/library/Microsoft.Xna.Framework.Graphics.Model.aspx
  2. Models, meshes, parts, and
    bones:http://blogs.msdn.com/b/shawnhar/archive/2006/11/20/models-meshes-parts-and-bones.aspx
  3. What Is a Model
    Bone?:http://msdn.microsoft.com/en-us/library/dd904249.aspx
  4. BasicEffect
    Lighting:http://rbwhitaker.wikidot.com/basic-effect-lighting
  5. BasicEffect Fog:http://rbwhitaker.wikidot.com/basic-effect-fog
  6. 合学WP7 XNA游戏开发(七.
    3d基本光源):http://www.cnblogs.com/randylee/archive/2011/03/09/1978312.html
  7. 【D3D11游玩编程】学习笔记十二:光照模型:http://blog.csdn.net/bonchoix/article/details/8430561

〔校园〕《新闻101》(3)