wpf知识点
【篇一:wpf知识点】
本文的主要内容是自己使用wpf开发以来,本人对相关知识的梳理,仅为个人的总结,对很多事物的理解依然在探索阶段,总会有谬误和更佳的开发方式,如能提出宝贵建议,感激不尽。
虽然本人并不只专注于wpf,还喜欢各类编程语言,但估计在今后1,2年内依然会继续经常使用wpf开发。
想来想去,时间一长,很多东西还是整理并记录下来为好,遂决定从发布此文以后,开始慢慢积累,随着个人知识的扩展和理解,本文可能会不断添加或者更新内容,然而也会尽可能保留对同一概念前后不同的理解。
wpf搞了快一年,除了去年在上家公司主导开发过一个比较大的wpf项目(已经商业化),其他都是小打小闹的软件。在我看来
wpf的优点是:
1. 可以相对比较容易的写出完全定制化的界面。
2.特有的mvvm设计模式可以完美的分离 ui设计(view层) 和 业务逻辑(model层)。
wpf的缺点是:
1. 学习成本比较高(我指的是真正精通,你和我说就拖拖控件生成个事件写个方法,当个处理工具,那都不用学了)
新的概念非常多,容易混淆,本人耐性还是很好的,但依然常常连续好多天不停的折腾,折腾到开始喷ms为何这样设计。
2. 不能跨平台。过一阵子去研究下mono。
3. 由于本身的复杂性,bug有时隐藏的比较深。
4. 坑很多,复杂的项目下很多坑必须得自己跳,官方文档大多数时候并不能解决实际问题,网上搜索的资料参差不齐,很难查到自己想要的,为了解决大坑最开始常常需要去理解一大堆从天而降的概念。国外下载的demo有时会复杂的过分,csdn上的很多源代码又太不专业 我就吐槽下。
目前为止,我依然没有解决的问题:
a.图片占用内存太大,在图片很多并且实时刷新速度很快的时候,如果不写代码手动释放资源,内存就会暴涨至崩溃。而同样的功能改用winform实现就只占用很小的内存。
b. 数据虚拟化面板在xp或部分win7电脑上显示为空白。只能替换为普通面板。
c. 窗体设置为允许透明时,webbrowser显示为空白。(目前查到和尝试的方案没有完美解决的)我的办法是换成第三方浏览器内核,比如cef,但是使用 javascript 内外通信又是很麻烦的事情。不然就是放弃窗体透明
近期又开始使用wpf写一个程序,同时希望能利用这次开发,将之前wpf相关的知识做一个整合,重新理解概念,丢弃不好的,探索更加舒服好用的,并将已知的融会贯通,尽可能用最 优雅 的方式去实现功能。
那么我们开始吧。
wpf相关技术一定要弄清楚的知识点,先列个大纲,按照我个人建议的学习顺序排序。
1. 理解xaml相关窗体设计的原理。
a. 逻辑树结构非常类似html,但更加麻烦。
b.可以使用xamlpad查看可视树结构。
c.理解style类似于css,并可以通过随时更换资源字典以达到更换主题或者换肤的目的。
2. 触发器(trigger),最常用的是属性触发器和数据触发器。
a. 需要知道触发器主要是用于视觉交互的。
b. 属性触发器是控件本身的某个属性值发生改变,比如ismouseover=true的时候,会触发可视内容比如背景色 发生变化。
c. 数据触发器是在数据模板(datatemplete)中,当某个业务数据发生变化改变时,会触发可视内容发生变化。
3. 为了创建形态各异的界面,实现各种神奇的效果,需要学习wpf绘图。
a. 使用图形,包括:直线,矩形,椭圆,贝塞尔曲线,path(最强大的路径)
b. 应用滤镜效果,effect比较简单,但是导入和开发外部滤镜,一直没有研究。
c. 使用变形。有平移,旋转,缩放,扭曲等基本变形,以及矩阵变形。(要注意的是:每种变形既可以放在呈现变形中,也可以放在布局变形中,需要区分二者的区别。呈现变形只是看到的样子变化了,实际位置和形状都没变。布局变形是真的变化,会在变形的同时不断对其他控件重新进行布局计算。)
4. 学习使用xaml创建简单的动画
a.尝试使用3类触发器触发动画的发生
b. 使用visualstatusmanager来应用动画
c.如无必要,尽量避免通过写代码的方式创建动画
d.(扩展:使用blend创建并组合出复杂的动画。)
5. 依赖属性和附加属性。
a.要学会如何自定义我们自己扩展的依赖属性和附加属性。
b.所谓依赖属性,从功能上讲:就是一个普通的属性,附带了可以绑定到任意对象的其他属性上的功能。所谓绑定就是:一个值变化,另外一个值跟着变化的。这样可以省去大量的界面效果相关的后台代码,并使界面和业务代码分离成为可能。
c. 依赖属性可用于继承一个现有控件或者自定义控件,并为其扩展属性。缺点是这些属性不能复用,是控件自己专属的。
d. 附加属性是一种特殊的依赖属性。有两种用法,一种继承现有类,并进行定义,实现的效果如同canvas.left。
一种新建类,主要用于为了不进行大量继承的前提下,给现有控件扩展额外的属性。是一种很好的 组合模式 思维。
6. 模板。主要了解:controltemplete,datatemplete
a.controltemplete 是用来重写现有控件的可视结构的,一般和依赖属性和附加属性结合,加上绑定,控件可以获得很好的扩展。
b. datatemplete 主要用于定义数据对象的可视化结构的。既然是数据对象,最好要有个数据类型,即在datatype中定义。
c. 模板在wpf起着巨大的作用。控件模板可以很容易写出任意形态任意效果的外观,数据模板使得view层和viewmodel层很好的分离。请一定要注意,起初我对这样的概念不屑一顾,其实就是没明白什么意思。后来我才懂:就因为数据模板的存在,使得代码中几乎再也不用出现控件对象了。
d. 推荐模式在模板中的运用,利用自动创建的模板,经常会看到part_xxx,不明白怎么回事? 看基类的特性中,会有templatepart,这其实是一种推荐的设计模式,用于提示后来的开发者,告诉你控件组成的必要元素:名称和类型。也就是说,你可以重写控件模板,但是如果要实现控件自身的核心功能,一定要保留一个名为part_xxx的某个类型的控件才行。
7. mvvm设计模式,最方便学习此模式的是mvvmlight框架,可以直接在nuget中下载。
a. model - view - viewmodel。不同于mvc,mvp等设计模式, mvvm最主要的特点是实现ui(view)和业务(model)的分离。而viewmodel应该同时负责表现逻辑和业务逻辑。这在开发时尤其有用,另外可以同时快速创建设计用的viewmodel,以便设计阶段即可以模拟出完全真实的使用效果,因为view层对应的viewmodel可以很容易的切换。
b. 本人并非设计模式的过渡崇拜者,然而只要让代码生产力持续保持比较高的效率,就是好的方法。很多时候只要不影响大局,在codebehind中写一些代码是无可厚非的。
c. mvvmlight框架下,有很好用的eventtocommand,可以将任何事件直接转化为命令,在我看来这使得ui和业务分离的更加彻底。
d. mvvmlight下的消息机制,messenger 也是个很好用的东东,可以实现本无关联的viewmodel间的通信,让他们继续无关联下去。另外也可以用于导航。
e. viewmodel 让 model 更加适合于 view。注意两点:一. viewmodel 不需要知道 view 中有什么,换句话说,viewmodel 中不要引用view中的控件。
二.view 中不要直接引用 model,而是借助viewmodel,想要用model怎么做? 比如:persionviewmodel 里有个公有的 persion 类型的属性 persion, view的datacontext是 persionviewmodel,绑定时写 {binding path=persion.name} 即可。
8. 可以附加在控件上的行为 (behavior)
a. 行为,还有上面刚说的 触发器,eventtocommand,都是一种附加属性。这样就很好理解了。通常理解的附加属性,只是一一个数据类型的值,既然扩展成了一个行为这么复杂的数据类型,目的主要是为了实现各种行为效果的重用,然而行为的封装是最完整的。
9. 要反复深刻理解装饰器相关 adorner, decorator, adornerdecorator
a. 从简单开始,最好懂的是 decorator,如果这个词感到陌生,那么border就不陌生了,边框嘛,一个东西,外面套个边而已。
然而decorator是border的基类而已。可以扩展它,然而我目前还没有遇到继承decorator的应用场景。
b. 再说adorner,这才是真正的装饰器,本身没有可视结构,它的存在就是要你继承它,并设计它的可视样式,如何继承,网上一大堆教程,最直观的理解就是:在控件自身上面,蒙了一层额外的装饰,用于交互性的提示与操作。
比如:光标,旋转钮,调整大小,表头的排序箭头 等等。需要什么就画什么,恩恩,这个很重要。
c. 理解了前面两个,再来说最后一个,看起来好复杂好高大上的样子, 其实很简单, 按我的理解: 这就是一个双面胶,用来粘贴 decorator 和 adorner。微软需要在控件上面有个容器,用来放 adorner,这个容器最好从控件的最边缘开始,控件的最边缘,自然是 decorator了,ok,那么再包裹一个东西,就可以放 adorner了, 于是这个东西的名字叫做 adornerdecorator,上面有个叫做 adornerlayer的东西可以让adorner直接add。
d. 事实上,只有adornerdecorator和scrollcontentpresenter具有adornerlayer,所以,想要自己加装饰器的时候,不要忘记在模板里面套一个 adornerdeocrator 哦。尤其像我这种经常写自定义窗体的,窗体的contentpresenter 外面套个adornerdecorator 是 必不能忘的。
10. 路由事件和命令
a. 如果想要写出来的wpf程序在复杂的界面中不会出现莫名其妙的问题,那么一定要弄懂路由事件和路由命令的概念。
所谓路由,有三种烂大街的方式:隧道,冒泡,直接。
顾名思义:隧道,标签从外向内响应事件。
冒泡,标签从内向外相应事件。
直接,只能从定义元素监听元素的直接事件,写别的地方没用。
b. 路由事件是定义在哪一层监听事件,而不是点击哪一层会执行事件,目的自然是 一夫当关万夫莫开 ,比如冒泡路由,n多的控件都可能响应某一鼠标事件,那么只需要在集合控件上面 监听这一事件就可以了(附加事件)。
在 响应事件处理中,再拿到实际命中的 控件就可以了。
当然,这个时候我往往是直接取命中控件的datacontext,直接转化为viewmodel,操作数据层。
c.其实这个路由事件机制和html中 javascript 的事件机制非常非常类似,addeventlistener的第三个参数 usecapture 用来控制 是否是 bubbling(冒泡)方式。我也常常会用 jquery 中的 delegate 来做类似的事情,以便监听未来产生的子元素相关的事件。
d. 可以在路由事件中标记 handler = true。来阻止事件继续路由下去。
然而 实际上 即使这样设置,路由事件依然在继续传递。
因为用 addhandler 显式 挂接路由事件处理程序,可以定义路由事件即使被处理依然会执行。即设置handledeventstoo = true。
这里分析,相信 handler ||handledeventstoo 为真时,即会执行事件处理程序。
e. 自定义路由事件,类似于注册依赖属性。其中可以定义路由类型等等。
f. 说来说去,需要强调的是, preview名称开头的事件是隧道方式,代表了事件是从外向内传递的。不带preview的事件是冒泡方式,是从内向外传递的。同一名称的事件preview先执行。这是个形象的反弹,球弹进去再弹出来,这个过程球可以被人抓住。
g. 路由命令在我看来,因其天生的缺陷与限制,应用的比较少。我一般使用 mvvmlight 的 relaycommand,当然,如果项目没必要引入mvvmlight时,自己自定义也可以。
讲了半天的理论,都是这不到一年wpf开发的体会,接下来开始实践内容部分。以后自己实现了感觉不错的东西,就会列在下面分享。
【篇二:wpf知识点】
!-- lights, meshgeometry3d and diffusematerial objects are added to the modelvisual3d. -- directionallight color=#ffffffff direction=3,-4,5 / !-- define a red cone. -- geometrymodel3d geometrymodel3d.geometry meshgeometry3d positions=0.293893 -0.5 0.404509 0.475528 -0.5 0.154509 0 0.5 0 0.475528 -0.5 0.154509 0 0.5 0 0 0.5 0 0.475528 -0.5 0.154509 0.475528 -0.5 -0.154509 0 0.5 0 0.475528 -0.5 -0.154509 0 0.5 0 0 0.5 0 0.475528 -0.5 -0.154509 0.293893 -0.5 -0.404509 0 0.5 0 0.293893 -0.5 -0.404509 0 0.5 0 0 0.5 0 0.293893 -0.5 -0.404509 0 -0.5 -0.5 0 0.5 0 0 -0.5 -0.5 0 0.5 0 0 0.5 0 0 -0.5 -0.5 -0.293893 -0.5 -0.404509 0 0.5 0 -0.293893 -0.5 -0.404509 0 0.5 0 0 0.5 0 -0.293893 -0.5 -0.404509 -0.475528 -0.5 -0.154509 0 0.5 0 -0.475528 -0.5 -0.154509 0 0.5 0 0 0.5 0 -0.475528 -0.5 -0.154509 -0.475528 -0.5 0.154509 0 0.5 0 -0.475528 -0.5 0.154509 0 0.5 0 0 0.5 0 -0.475528 -0.5 0.154509 -0.293892 -0.5 0.404509 0 0.5 0 -0.293892 -0.5 0.404509 0 0.5 0 0 0.5 0 -0.293892 -0.5 0.404509 0 -0.5 0.5 0 0.5 0 0 -0.5 0.5 0 0.5 0 0 0.5 0 0 -0.5 0.5 0.293893 -0.5 0.404509 0 0.5 0 0.293893 -0.5 0.404509 0 0.5 0 0 0.5 0 normals=0.7236065,0.4472139,0.5257313 0.2763934,0.4472138,0.8506507 0.5308242,0.4294462,0.7306172 0.2763934,0.4472138,0.8506507 0,0.4294458,0.9030925 0.5308242,0.4294462,0.7306172 0.2763934,0.4472138,0.8506507 -0.2763934,0.4472138,0.8506507 0,0.4294458,0.9030925 -0.2763934,0.4472138,0.8506507 -0.5308242,0.4294462,0.7306172 0,0.4294458,0.9030925 -0.2763934,0.4472138,0.8506507 -0.7236065,0.4472139,0.5257313 -0.5308242,0.4294462,0.7306172 -0.7236065,0.4472139,0.5257313 -0.858892,0.429446,0.279071 -0.5308242,0.4294462,0.7306172 -0.7236065,0.4472139,0.5257313 -0.8944269,0.4472139,0 -0.858892,0.429446,0.279071 -0.8944269,0.4472139,0 -0.858892,0.429446,-0.279071 -0.858892,0.429446,0.279071 -0.8944269,0.4472139,0 -0.7236065,0.4472139,-0.5257313 -0.858892,0.429446,-0.279071 -0.7236065,0.4472139,-0.5257313 -0.5308242,0.4294462,-0.7306172 -0.858892,0.429446,-0.279071 -0.7236065,0.4472139,-0.5257313 -0.2763934,0.4472138,-0.8506507 -0.5308242,0.4294462,-0.7306172 -0.2763934,0.4472138,-0.8506507 0,0.4294458,-0.9030925 -0.5308242,0.4294462,-0.7306172 -0.2763934,0.4472138,-0.8506507 0.2763934,0.4472138,-0.8506507 0,0.4294458,-0.9030925 0.2763934,0.4472138,-0.8506507 0.5308249,0.4294459,-0.7306169 0,0.4294458,-0.9030925 0.2763934,0.4472138,-0.8506507 0.7236068,0.4472141,-0.5257306 0.5308249,0.4294459,-0.7306169 0.7236068,0.4472141,-0.5257306 0.8588922,0.4294461,-0.27907 0.5308249,0.4294459,-0.7306169 0.7236068,0.4472141,-0.5257306 0.8944269,0.4472139,0 0.8588922,0.4294461,-0.27907 0.8944269,0.4472139,0 0.858892,0.429446,0.279071 0.8588922,0.4294461,-0.27907 0.8944269,0.4472139,0 0.7236065,0.4472139,0.5257313 0.858892,0.429446,0.279071 0.7236065,0.4472139,0.5257313 0.5308242,0.4294462,0.7306172 0.858892,0.429446,0.279071 triangleindices=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 / /geometrymodel3d.geometry geometrymodel3d.material diffusematerial diffusematerial.brush solidcolorbrush color=red opacity=1.0/ /diffusematerial.brush /diffusematerial /geometrymodel3d.material /geometrymodel3d /model3dgroup.children /model3dgroup /modelvisual3d.content /modelvisual3d /viewport3d.children /viewport3d /grid /usercontrol
make a 3d cube with pictures on its sides with xaml and c#
3d开发首先要把三维坐标系搞清楚,才能构建出想要的3d model,才能把灯光合理的照在3d模型上(环境光除外)得到不同的灯光效果,才能指定合适的相机(camera)位置从而看到自己想要看到3d投影。
3d开发中所有的几何体最终都是由一系列的三角形来组成的。所以在您吧三维坐标系高清的前提下,您还需要考虑把您的3d模型分解成三角形。听来就很繁琐,幸运的是现在有一些辅助类帮助大家来处理这些三角形的分解,而您所做的就是提供关键点的坐标系。
由于wpf 3d 是基于direct 3d,和wpf 2d一样直接利用显卡渲染的,并且默认开启了全景反锯齿(有个条件,需要你的显卡支持 兼容)。
3d开发和2d开发复杂了很多,考虑的东西多了不少。但为了那更真实的,更炫酷的效果,这一切都值得您去学习。
祝各位在3d开发的旅途,一路愉快!
【篇三:wpf知识点】
引言现在物联网概念这么火,如果监控的信息能够实时在手机的客服端中以3d形式展示给我们,那种体验大家可以发挥自己的想象。
那生活中我们还有很多地方用到这些,如上图所示的kinect 在医疗上的应用,当然还有体感游戏等等。
3d 用来增加视觉效果,给人以更加直观,真实的感觉。
3d如此美妙,那我们在wpf中又该从何处入手开启我们的3d编程旅程?
wpf中3d开发技术的基础知识应该有以下几点:
3d开发基础知识 wpf中3d开发的基础元素(elements) wpf中3d变换和动画 常用辅助类 3d开发基础知识 坐标系 coodinate systemwpf中二维图形的坐标系将原点定位在呈现区域(通常是屏幕)的左上角。
在二维系统中,x 轴上的正值朝右,y 轴上的正值朝下。而在三维坐标系中,原点位于呈现区域的中心,x 轴上的正值朝右,但是 y 轴上的正值朝上,z 轴上的正值从原点向外朝向观察者。传统的二维和三维坐标系表示形式如下图
由这些轴定义的空间是三维对象在 wpf 中的固定参考框架。
当您在该空间中生成模型并创建光源和照相机以查看这些模型时,一定要在向每个模型应用变换时,将固定参考框架或“全局空间”与您为该模型创建的局部参考框架区分开。
另请记住,根据光源和照相机设置,全局空间中的对象可能会看上去完全不同或者根本不可见,但是照相机的位置不会改变对象在全局空间中的位置。
3d的世界都是三角形的王国如下图:
在3d的世界里所有的东西都是用一些列的“三角形”来描述的。那你一定会问为什么是“三角形”?
其实就是三点确定一个平面,在一个平面上做计算最简单,考虑的因素最少。如果用三维空间中大于三个点来做渲染基本单位,那么如果这些点不在同一个平面上的话,渲染计算是相当复杂的。
3d 对象的表面叫做网格(mesh),一个网格是由许多3d 点来定义的,这些点叫做顶点(vertices)。这些顶点通过缠绕模式(winding pattern)连接在一起组成一个一个的三角形(facet)(如下图箭头所示)。
三角形(facet)又分为“前”和“后”两面,能看到的部分为前面,看不到的部分为后面。
那怎么判定是前面还是后面?
如果三角形的三个点顺时针方向组成的面那么这个面就是前面。如下图
按照0,1,2的顺序三个点组成了的这个面是上面我们可以看到
目前主流(direct3d and/or opengl)都会把三角形分为两个面(前面和后面)。
为帮助大家记忆(facet)“前面”的三维坐标,大拇指是z+的方向正对着我们(及前面图示中up方向),食指是y+方向,而中指是y+方向。(+表示正数的方向)
wpf 3d的关键元素(elements)3d 画布要画画总的有个画布,wpf中呈现3d也需要一个类似功能的东西。viewport3d(投影3d场景的平面)是wpf中的3d画布,类于2d中的canvas。其实wpf中也有一个名字开起来类似的东东viewbox ,不过和3d没啥关系,它处理的都是2d的。
viewport3d children… /viewport3d 该图形系统将 viewport3d 视为一个像 wpf 中的许多其他元素一样的二维可视化元素。
viewport3d充当三维场景中的窗口(即视区)。
更准确地说,它是三维场景所投影到的图面。
相机处理二维对象的开发人员习惯于将绘图基元置于二维屏幕上。
当您创建三维场景时,一定要记住您实际上是要创建三维对象的二维表示形式。
由于三维场景的外观会因观察者的观察位置不同而异,因此您必须指定观察位置。而观察位置就是由相机(camera 类)来为三维场景指定的。
另一种理解三维场景在二维图上的描述方法就是,将3d场景投影到一个2d平面的表面。如下图:
从坐标系的角度来看下我们的projectioncamera(透视相机)和3d模型的位置,以及2d 投影屏幕的位置关系:
更详细的图解如下:
projectioncamera 的 nearplanedistance 和 farplanedistance 属性限制照相机的投影范围。由于照相机可以位于场景中的任何位置,因此照相机实际上可能会位于模型内部或者紧靠模型,这使正确区分对象变得很困难。
通过 nearplanedistance,可以指定一个距离照相机的最小距离,超过该距离后即不绘制对象。
相反,使用 farplanedistance,可以指定一个距离照相机的距离(即,在超过该距离后将不绘制对象),从而确保因距离太远而无法识别的对象将不包括在场景中。
对比wpf中两种相机
perspectivecamera 可以指定不同的投影及其属性以更改观察者查看三维模型的方式。
orthographiccamera 指定三维模型到二维可视化图面上的正投影与其他照相机一样,它指定位置、观察方向和“向上”方向。
但是,与 perspectivecamera 不同的是,orthographiccamera 描述了不包括透视收缩的投影。或者说orthographiccamera 描述了一个侧面平行的取景框,而不是侧面汇集在场景中一点的取景框。
下图演示使用perspectivecamera 和 orthographiccamera 查看同一模型时的不同效果。
灯光和现实生活中一样,如果没有光我们将什么也看不到。因此我们需要在我们的场景中至少放置一盏灯来照亮我们场景中的模型。
wpf中支持不同类型的光源,如下:
ambientlight(环境光) 它所提供的环境光会照亮所有的对象,而不考虑对象的位置或方向。
directionallight(平行光) 像远处的光源那样照亮(如太阳光)。将方向光的 direction 指定为 vector3d,但是没有为方向光指定位置。
pointlight(点光源) 像近处的光源那样照亮。
pointlight 具有一个位置并从该位置投射光。
场景中的对象是根据对象相对于光源的位置和距离而被照亮的。
pointlightbase 公开 range 属性,该属性确定一个距离,超过该距离后模型将无法由光源照亮。
pointlight 还公开了多个衰减属性,这些属性确定光源的亮度如何随距离的增加而减小。
您可以为光源的衰减指定恒定、线性或二次内插算法。
spotlight(聚光灯) 从 pointlight 继承。
spotlight 的照亮方式与 pointlight 类似,但是它既具有位置又具有方向。
它们在 innerconeangle 和 outerconeangle 属性所设置的锥形区域(以度为单位指定)中投射光。
下图展示了各种光源的情况:
光源是 model3d 对象,因此您可以转换光源对象并对光源属性(包括位置、颜色、方向和范围)进行动画处理。
组合灯光的效果
ambient color : red difusse color : red3d模型说了半天啦,怎么主角还没出现了 ??
对,所有的一切都服务于我们的3d model。
model3d 是三维对象的抽象基类。若要生成三维场景,需要一些要查看的对象,而且构成场景图的对象必须派生自 model3d。
目前,wpf 支持用 geometrymodel3d 对几何形状进行建模。
此模型的 geometry 属性采用网格基元。
要生成模型,首先生成一个基元或网格。
三维基元是一系列构成单个三维实体的顶点。
大多数三维系统都提供在最简单的闭合图(由三个顶点定义的三角形)上建模的基元。
由于三角形的三个点在一个平面上,因此您可以继续添加三角形,以便对网格这样较为复杂的形状建模。
wpf 三维系统目前提供 meshgeometry3d 类,使用该类可以指定任何几何形状;它目前不支持预定义的三维基元(如球体和立方体)。
首先通过将三角形顶点的列表指定为它的positions 属性来创建 meshgeometry3d。
每个顶点都指定为 point3d。
(在可扩展应用程序标记语言 (xaml) 中,将该属性指定为三个一组的数字列表,每组中的三个数字表示每个顶点的坐标)。根据网格的几何形状,网格可能会由多个三角形组成,其中的一些三角形共用相同的角(顶点)。
若要正确地绘制网格,wpf 需要有关哪些顶点由哪些三角形共用的信息。
可以通过指定具有 triangleindices 属性的三角形索引列表来提供此信息。
此列表指定在 positions 列表中指定的点将按哪种顺序确定三角形。
材质(material )我们生活在多彩的世界中,也不能让我们的3d模型如此单调,这时我们就用到了材质。
在二维中,可以使用 brush 类来向屏幕中的区域应用颜色、图案、渐变或其他可视化内容。
但是,三维对象的外观是照明模型的功能,而不只是应用于它们的颜色或图案。
实际对象的图面质量不同,它们反射光的方式也会有所不同:光亮的图面与粗糙或不光滑的图面看上去不同,某些对象似乎可以吸收光,而某些对象似乎能够发光。
您可以向三维对象应用与应用于二维对象的完全相同的画笔,但是您不能直接应用它们。
material 的具体子类用来确定模型图面的某些外观特征,每个子类还提供一个可以向其传递 solidcolorbrush、tilebrush 或 visualbrush 的 brush 属性。
diffusematerial 使用 diffusematerial 与直接针对二维模型使用画笔非常相似;模型表面不反射光,就好像是自发光一样。使用 diffusematerial 与直接针对二维模型使用画笔非常相似;模型表面不反射光,就好像是自发光一样 specularmaterial 可以通过为 specularpower 属性指定一个值来设置系统将为纹理的反射特质(或“发光”)建议的度数。
emissivematerial 可以指定将应用纹理,就好像模型所发出的光与画笔的颜色相同。这不会使模型成为光源;但是,它参与阴影设置的方式将不同于用 diffusematerial 或 specularmaterial 设置纹理时的情况。
为进一步提高性能,可以从场景中精选 geometrymodel3d 的背面(由于它们相对于照相机位于模型的背面,因此您将看不到这些面)。若要指定要应用于模型(如飞机)背面的material,请设置模型的 backmaterial 属性。
为了实现某些图面质量(如发光或发射效果),您可能希望向模型连续应用几个不同的画笔。
可以使用 materialgroup 类来应用和重用多个 material。
materialgroup 的子级在多个呈现过程中按照从头到尾的顺序来应用。
wpf中3d变换和动画变换当您创建模型时,它们在场景中具有固定的位置。为了在场景中移动、旋转这些模型或者更改这些模型的大小而更改用来定义模型本身的顶点是不切实际的。
相反,您可以像在二维模型一样应用转换。
每个模型对象都有一个可用来对模型进行移动、重定向或调整大小的 transform 属性。
当您应用转换时,实际上是按照由transform 属性指定的向量或值来偏移模型的所有点。
也就是说变换了定义模型的坐标系(“模型空间”)而模型所在的整个场景的坐标系(“全局空间”)却没有改变,从而实现了3d模型的变换。
动画wpf 三维实现与二维图形参与同一个计时和动画系统。也就是说,要对三维场景进行动画处理,也就是对其模型的属性进行动画处理。
可以直接对基元的属性进行动画处理,但是通常很容易更改模型位置或外观的变换进行动画处理。
由于可以向 model3dgroup 对象及其各个模型应用转换,因此可以向 model3dgroup 中某个对象应用一组动画,也可以向这一组子对象应用一组动画。
还可以通过对场景的照明属性进行动画处理来实现各种可视化效果。
最后,您可以选择通过对照相机的位置或视野进行动画处理来对投影本身进行动画处理。
要对 wpf 中的对象进行动画处理,可以创建时间线、定义动画(实际上是随着时间的推移而更改某个属性值)并指定要向其应用动画的属性。
由于三维场景中的所有对象都是viewport3d 的子节点,因此要应用于场景的任何动画所面向的属性都是 viewport3d 的属性。
常用辅助类 helixtoolkit 3dtool slimdx 实例usercontrol x: >make a 3d cube with pictures on its sides with xaml and c# 源码
总结3d开发首先要把三维坐标系搞清楚,才能构建出想要的3d model,才能把灯光合理的照在3d模型上(环境光除外)得到不同的灯光效果,才能指定合适的相机(camera)位置从而看到自己想要看到3d投影。
3d开发中所有的几何体最终都是由一系列的三角形来组成的。所以在您吧三维坐标系高清的前提下,您还需要考虑把您的3d模型分解成三角形。听来就很繁琐,幸运的是现在有一些辅助类帮助大家来处理这些三角形的分解,而您所做的就是提供关键点的坐标系。
由于wpf 3d 是基于direct 3d,和wpf 2d一样直接利用显卡渲染的,并且默认开启了全景反锯齿(有个条件,需要你的显卡支持 兼容wddm-compliant)。
3d开发和2d开发复杂了很多,考虑的东西多了不少。但为了那更真实的,更炫酷的效果,这一切都值得您去学习。
祝各位在3d开发的旅途,一路愉快!
参考wpf 3d article, tutorial with chart graphics c# code
wpf-3d-primer
getting started with 3d in wpf
三维图形概述
rendering transparent 3d surfaces in wpf with c#
本文来源:https://www.2haoxitong.net/k/doc/f518798715791711cc7931b765ce0508763275cd.html
文档为doc格式