Alternativa 3D Series – Tutorial 2 – Adding Material【翻译】

在第一篇文章中我们创建了一个简单的Alternativa 3D程序。编译后我们可以看到一个旋转的线框立方体。本篇文章我将向大家展示如何给立方体填充材质,让立方体看起来更美观。


Alternativa有三种标准材质类型:线框材质,填充材质和纹理材质。前面提到的线框材质可以显示模型的多边形边框。填充材质可以用颜色填充整个多边形模型,边框的显示和线框填充别无二致。最后的纹理材质可以用用一个2d图片填充整个模型。

本节的实例会用三种材质填充的上节做好的立方体。为达到更好的目的,我们需要创建一些按钮和滑动条来让用户操作。

 

代码
   
     
1 <? xml version = " 1.0 " encoding = " utf-8 " ?>
2   < mx:Application
3 xmlns:mx = " http://www.adobe.com/2006/mxml "
4 layout = " absolute "
5 xmlns:ns1 = " * "
6 width = " 600 "
7 height = " 400 "
8 color = " #FFFFFF "
9 backgroundGradientAlphas = " [1.0, 1.0] "
10 backgroundGradientColors = " [#FFFFFF, #C0C0C0] "
11 frameRate = " 100 " >
12
13 < ns1:EngineManager id = " engineManager " x = " 0 " y = " 0 " width = " 100% " height = " 100% " />
14 < mx:HSlider x = " 56 " y = " 147 " width = " 53 " id = " sliderRed " minimum = " 0 " maximum = " 255 " snapInterval = " 1 " change = " {ApplicationManager.Instance.onColorChanged()} " />
15 < mx:Label x = " 10 " y = " 147 " text = " Red " color = " #000000 " />
16 < mx:HSlider x = " 56 " y = " 199 " width = " 53 " id = " sliderBlue " minimum = " 0 " maximum = " 255 " snapInterval = " 1 " change = " {ApplicationManager.Instance.onColorChanged()} " />
17 < mx:Label x = " 10 " y = " 199 " text = " Blue " color = " #000000 " />
18 < mx:Image x = " 10 " y = " 10 " id = " imgAlternativa " source = " @Embed(source='../media/alternativa.jpg') " />
19 < mx:Image x = " 10 " y = " 340 " source = " @Embed(source='../media/thetechlabs.png') " />
20 < mx:Button x = " 10 " y = " 50 " label = " Wireframe " color = " #000000 " id = " btnWireframe " click = " {ApplicationManager.Instance.setWireMaterial()} " />
21 < mx:Button x = " 10 " y = " 80 " label = " Texture " color = " #000000 " id = " btnTexture " width = " 88 " click = " {ApplicationManager.Instance.setTextureMaterial()} " />
22 < mx:Button x = " 10 " y = " 110 " label = " Color Fill " color = " #000000 " width = " 88 " id = " btnColorFill " click = " {ApplicationManager.Instance.setFillMaterial()} " />
23 < mx:HSlider x = " 56 " y = " 173 " width = " 53 " id = " sliderGreen " minimum = " 0 " maximum = " 255 " snapInterval = " 1 " change = " {ApplicationManager.Instance.onColorChanged()} " />
24 < mx:Label x = " 10 " y = " 173 " text = " Green " color = " #000000 " />
25
26   </ mx:Application >

 

 


你会看到,我们可以用标准的flex组件来控制我们的3D程序。本例中我们会创建3个按钮(分别控制三种材质),3个滑动条(来定义红色,绿色和蓝色的线框和填充材质组件)和一些标签。滑动条改变事件可以触发程序调用ApplicationManager的setTextureMaterial方法。按钮的点击事件可以触发程序调用setWireMaterial, setFillMaterial 或 setTextureMaterial 方法,以改变立方体的材质。

 

代码
   
     
1 package
2 {
3 import alternativa.engine3d.materials.FillMaterial;
4 import alternativa.engine3d.materials.TextureMaterial;
5 import alternativa.engine3d.materials.WireMaterial;
6 import alternativa.utils.ColorUtils;
7
8 import flash.display.BlendMode;
9
10 import mx.core.Application;
11
12 /**
13 * The ApplicationManager holds all program related logic.
14 */
15 public class ApplicationManager
16 {
17 protected static const WIREFRAME: int = 1 ;
18 protected static const TEXTURE: int = 2 ;
19 protected static const FILL: int = 3 ;
20 protected static var instance:ApplicationManager = null ;
21 protected var currentMaterial: int = 0 ;
22 protected var rotatingBox:RotatingBox = null ;
23
24 public static function get Instance():ApplicationManager
25 {
26 if (instance == null )
27 instance = new ApplicationManager();
28 return instance;
29 }
30
31 public function ApplicationManager()
32 {
33
34 }
35
36 public function startupApplicationManager():ApplicationManager
37 {
38 // create a new instance of the rotating box
39   rotatingBox = new RotatingBox().startupRotatingBox();
40 // give the box a wireframe material by default
41   setWireMaterial();
42 // tell the camera to look at the box
43 Application.application.engineManager.cameraController.lookAt(rotatingBox.model.coords);
44
45 return this ;
46 }
47
48 public function setWireMaterial(): void
49 {
50 currentMaterial = WIREFRAME;
51 rotatingBox.model.cloneMaterialToAllSurfaces( new WireMaterial( 1 , getCurrentColor()));
52 }
53
54 public function setTextureMaterial(): void
55 {
56 currentMaterial = TEXTURE;
57 rotatingBox.model.cloneMaterialToAllSurfaces( new TextureMaterial(ResourceManager.Texture1_Tex));
58 }
59
60 public function setFillMaterial(): void
61 {
62 currentMaterial = FILL;
63 rotatingBox.model.cloneMaterialToAllSurfaces( new FillMaterial(getCurrentColor(), 1 , BlendMode.NORMAL, 2 , 0x000000 ));
64 }
65
66 public function onColorChanged(): void
67 {
68 // reapply the current texture, taking into account the new color
69 switch (currentMaterial)
70 {
71 case WIREFRAME:
72 setWireMaterial();
73 break ;
74 case FILL:
75 setFillMaterial();
76 break ;
77 }
78 }
79
80 /**
81 * Returns a uint reprensenting the color specified by the 3 sliders in the main GUI
82 */
83 protected function getCurrentColor():uint
84 {
85 return ColorUtils.rgb(Application.application.sliderRed.value, Application.application.sliderGreen.value, Application.application.sliderBlue.value);
86 }
87 }
88 }

 

ApplicationManager类又多了很多代码,这些新的代码用来设置立方体的材质。我们引入了一个新的属性——currentMaterial,它的值根据我们设给立方体的材质类型发生改变。
你可以在setWireMaterial, setFillMaterial 和 etTextureMaterial 三个方法中看到这个属性。在这三个方法中我们会调用cloneMaterialToAllSurfaces方法来给立方体设置各种材质。


onColorChanged方法,会在用户改变滑动条修改颜色值时被调用,该方法会根据currentMaterial的当前值来给立方体设置不同材质颜色。细心的你可能会注意到在WireMaterial和FillMaterial的构造函数中都会调用getCurrentColor方法,该方法会返回一个用户滑动选择改变的uint颜色值。


TextureMaterial类有所不同,他可以用一张图片作为材质,而我们如何获得这种材质呢?往下看

 

代码
   
     
1 package
2 {
3 import alternativa.types.Texture;
4
5 /**
6 * ResourceManager is where we embed and create the resources needed by our application
7 */
8 public class ResourceManager
9 {
10 [Embed(source = " ../media/texture1.jpg " )]
11 public static const Texture1:Class;
12 public static const Texture1_Tex:Texture = new Texture( new Texture1().bitmapData, " Texture1_Tex " );
13 }
14 }

 

 


为获得材质,我们引入了一个新类——ResourceManager. 在这个类中我们导入了一些资源。大家看[Embed(source="../media/texture1.jpg")]。这一行的作用是嵌入一张图片资源。嵌入的这张图片会在Texture类中使用到。然后我们把Texture赋值给TextureMaterial,然后供我们的立方体使用。


总结:大家可以看到,我们根据上节的基础,很容易的创建了一个新的Alternativa 程序。EngineManager, BaseObject 和MeshObject类都没发生变化。(实际上MeshObject的model属性发生了些许变化,由原来的继承自:Object3D,变成了继承自:Mesh).ApplicationManager仅做了些许变动。同时我们引入了ResourceManager类,他为我们导入一些资源,并把它转化为材质供程序使用。

你可能感兴趣的:(alter)