• 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类,他为我们导入一些资源,并把它转化为材质供程序使用。

  • 相关阅读:
    深入解读kubernetes网络基本原理
    Go!Go!Go!设计模式-组合设计模式
    Go!Go!Go!设计模式-创建型模式(简单工厂,工厂方法,抽象工厂)
    Linux内核之磁盘和分区
    Docker容器网络基础
    chart仓库之创建-入库-使用(helm,helm-push,chartmuseum)
    Go语言完整解析Go!Go!Go!(一)数据类型 之 Channel & Goroutine
    k8s爬坑集锦[网络问题]-服务无法访问
    数字证书的原理与应用&爬坑
    ingress的用法与原理
  • 原文地址:https://www.cnblogs.com/crkay/p/1854233.html
Copyright © 2020-2023  润新知