00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 using System;
00018 using System.Collections.Generic;
00019 using System.Text;
00020 using Microsoft.DirectX;
00021 using Microsoft.DirectX.Direct3D;
00022 using Microsoft.Samples.DirectX.UtilityToolkit;
00023 using System.Drawing;
00024
00025 namespace DXGfxLib
00026 {
00034 internal class Billboard : TexturedPlane, IComparable
00035 {
00036 public static Matrix currentFrameBillboardRot;
00037 public static double lastRotUpdate = -1;
00038
00043 public static StateBlock billboardRenderState = null;
00044
00052 public double distToNearPlane = 1000.0f;
00053
00064 public Billboard(Device d3ddevice, int width, int heigth, int numVertX, int numVertZ, string texturefile)
00065 :
00066 base(d3ddevice, width, heigth, numVertX, numVertZ, texturefile)
00067 {
00068 }
00069
00075 public Billboard(Device d3ddevice, Billboard srcBillBoard)
00076 : base(d3ddevice, srcBillBoard.width, srcBillBoard.heigth, srcBillBoard.numVertX, srcBillBoard.numVertZ, srcBillBoard.textureFileName)
00077 {
00078 }
00079
00086 public override int CompareTo(Object obj)
00087 {
00088 Billboard otherBillboard = obj as Billboard;
00089
00090 int retVal = 1;
00091
00092 if (obj != null)
00093 {
00094 if (distToNearPlane > otherBillboard.distToNearPlane)
00095 {
00096 retVal = -1;
00097 }
00098 }
00099 return retVal;
00100 }
00101
00112 public override void Update(Frustrum frustrum, double appTime, float elapsedTime)
00113 {
00114 if (lastRotUpdate != appTime)
00115 {
00116 Matrix billboard = frustrum.matView;
00117 billboard.M41 = 0.0f;
00118 billboard.M42 = 0.0f;
00119 billboard.M43 = 0.0f;
00120 Quaternion q = Quaternion.RotationMatrix(billboard);
00121 q.Invert();
00122 q.X = 0.0f;
00123 q.Z = 0.0f;
00124 q.Normalize();
00125
00126
00127 currentFrameBillboardRot = Matrix.RotationQuaternion(q);
00128 lastRotUpdate = appTime;
00129 }
00130
00131 worldMat.M11 = currentFrameBillboardRot.M11;
00132 worldMat.M12 = currentFrameBillboardRot.M12;
00133 worldMat.M13 = currentFrameBillboardRot.M13;
00134
00135 worldMat.M21 = currentFrameBillboardRot.M21;
00136 worldMat.M22 = currentFrameBillboardRot.M22;
00137 worldMat.M23 = currentFrameBillboardRot.M23;
00138
00139 worldMat.M31 = currentFrameBillboardRot.M31;
00140 worldMat.M32 = currentFrameBillboardRot.M32;
00141 worldMat.M33 = currentFrameBillboardRot.M33;
00142 distToNearPlane = MathUtil.SignedDistance(frustrum.NearPlane, Position);
00143
00144 base.Update(frustrum, appTime, elapsedTime);
00145 }
00146
00151 public override void Draw(Device device)
00152 {
00153 if (billboardRenderState == null)
00154 {
00155 device.Material = material;
00156
00157
00158 device.RenderState.AlphaBlendEnable = true;
00159
00160 device.RenderState.SourceBlend = Blend.SourceAlpha;
00161 device.RenderState.DestinationBlend = Blend.InvSourceAlpha;
00162
00163 device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;
00164 device.TextureState[0].AlphaOperation = TextureOperation.SelectArg1;
00165 device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
00166 device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
00167 device.TextureState[0].ColorOperation = TextureOperation.Modulate;
00168
00169 billboardRenderState = new StateBlock(device, StateBlockType.All);
00170 billboardRenderState.Capture();
00171 }
00172
00173 device.SetTexture(0, texture);
00174
00175 device.SetTransform(TransformType.World, worldMat);
00176
00177
00178 originalMesh.DrawSubset(0);
00179 }
00180 }
00181 }