一、本篇要点
续文章创建自己的primitives,在之前这篇文章中,我们介绍了如何自制balder中基本体的过程,我们一步步完善基本体,从最开始的只有线构成,到接下来的实体,到最后的具有颜色的实体,本篇将在此基础上,结合之前对balder内的基本体的贴图过程,我们来看看它们之间有什么区别,又有什么相同之处。
二、温故知新
在之前,我们已经讲到过,如要对3D模型进行贴图,那么你需要用到DiffuseMap属性,在我之前的文章中,主要是通过xaml进行声明式的引用到了本地资源,而另一种方式则是在后台代码中加载资源文件,生成ImageMap对象,进行对DiffuseMap的赋值即可,虽然之前文章中没写具体过程,但是在文章的评论中已经和一位朋友以讨论的方式给出的过程,另外,Nowpaper前辈也在他的这篇文章中http://www.cnblogs.com/nowpaper/archive/2011/01/23/1942354.html,给出了详细过程。请参考之~接下来,我就假设你已经明白并且已经成功的给balder内基本体成功贴图。除此之外,也假设你已经会自己做自己的基本体了,如果都ok了,那么继续往下看,马上就进入正题(废话好像有点多,年纪大了没办法)。
三、给自己的基本体进行贴图操作
先打开上次完成的那个工程,我上次做的是一个三棱锥,当然,你做的可能还有更高级复杂些,反正有现成的就行,如果没有的话就得动手从开始做了,这里就不再多讲之前的知识了,好了,还记得在上次中我们是这样开始的:
1.public class MyMesh:Geometry 我们的基本体继承了Geometry类
2.然后我们的所以操作都在 public override void Prepare(Balder.Display.Viewport viewport)函数中进行的
3...
第三步就是今天要做的了,之前我们已经封装了三个函数,一个用来产生顶点,一个用来产生线,一个用来产生面。那我们今天再加一个,再一个产生纹理,然后取个名字叫做:private void GenerateTextureCoordinates()
然后,先上代码
1 private void GenerateTextureCoordinates()
2 {
3 FullDetailLevel.AllocateTextureCoordinates(4);
4 FullDetailLevel.SetTextureCoordinate(0, new TextureCoordinate(0, 1));
5 FullDetailLevel.SetTextureCoordinate(1, new TextureCoordinate(1, 1));
6 FullDetailLevel.SetTextureCoordinate(2, new TextureCoordinate(1, 0));
7 FullDetailLevel.SetTextureCoordinate(3, new TextureCoordinate(0, 0));
8
9 FullDetailLevel.SetFaceTextureCoordinateIndex(0, 0, 1, 2);
10 FullDetailLevel.SetFaceTextureCoordinateIndex(1, 0, 2, 3);
11 FullDetailLevel.SetFaceTextureCoordinateIndex(2, 0, 1, 2);
12 FullDetailLevel.SetFaceTextureCoordinateIndex(3, 0, 2, 3);
13
14
15
16 }
这就是今天的关键,如果,你没有这一步操作,也就是没有生成纹理,那么你的贴图操作就会失败,当然,如果你有纹理生成,但是中间过程出错,那么贴图的结果会令你大吃一惊。在生成纹理的方法中,主要用到了三个东西:
1.FullDetailLevel.AllocateTextureCoordinates()
2. FullDetailLevel.SetTextureCoordinate()
3.FullDetailLevel.SetFaceTextureCoordinateIndex()
你看着是不是觉得有点眼熟?没错,它们长得和之前我们处理顶点,线和面的那些个家伙确实有点像,那么它们到底是怎么用的呢?就以对三棱锥的纹理生成为例子,首先,我们需要做的是分配纹理一些顶点,这里我们的三棱锥是四个顶点所以我们就这样做:
FullDetailLevel.AllocateTextureCoordinates(4);
接着,我们来设置纹理的坐标:
FullDetailLevel.SetTextureCoordinate(0, new TextureCoordinate(0, 1));
FullDetailLevel.SetTextureCoordinate(1, new TextureCoordinate(1, 1));
FullDetailLevel.SetTextureCoordinate(2, new TextureCoordinate(1, 0));
FullDetailLevel.SetTextureCoordinate(3, new TextureCoordinate(0, 0));
里面有两个参数,前一个是纹理坐标的索引,在下一个方法中将会使用它们,而第二个参数是一个 TextureCoordinate对象,这里我通俗的讲,纹理其实就是一幅二维的图像(当然是个人理解,不一定正确),当我们把本地的图片贴到基本体上去时,就是通过纹理来进行测量,纹理坐标就是图片中每一个像素的坐标,举个例子:
比如把一个纹理的都整个设置给了一个primitive,然后(0.5, 0.7)这个点的颜色就是(0.5*texture_width, 0.7*texture_height)的颜色值,当然啦,如果取出来的坐标不是一个整数,那么就最近取一个点的色值了。 通过这种方法达到给primitive中的每个点赋值来达到显示效果。所以,这里我们打算把整个纹理给基本体,所以,纹理的坐标是第0个坐标(0,1),第一个坐标(1,1),第二个坐标(1,0),第三个坐标(0,0)。
接下来,我们就通过使用上面的纹理坐标来进行映射:
FullDetailLevel.SetFaceTextureCoordinateIndex(0, 0, 1, 2);
FullDetailLevel.SetFaceTextureCoordinateIndex(1, 0, 2, 3);
FullDetailLevel.SetFaceTextureCoordinateIndex(2, 0, 1, 2);
FullDetailLevel.SetFaceTextureCoordinateIndex(3, 0, 2, 3);
这里我们对三棱锥的四个面进行了映射,如果你把其中的一句注释掉,你就会发现有一个面的贴图就会失败,不信可以试试。完成这些后,把这个函数也加到Prepare中调用,其余就不多讲了,我对这些也是外行,真怕讲错,大家如果还是不清楚的地方可以查看纹理相关的资料,我如有讲得不对的地方,希望大家提出来,我必定虚心接受,不知不觉又熬夜了,今天偷懒下,不发运行效果了,就截个图了,实在是太困了,准备睡觉:)效果见下面: