⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d3dutil.cs

📁 Particle System Test Application on C#
💻 CS
📖 第 1 页 / 共 2 页
字号:
			// End drag mode
			internaldragging = false;
		}
	}




    /// <summary>
    /// Fired when the containers mouse is moving
    /// </summary>
	private void OnContainerMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
	{
		if (e.Button == System.Windows.Forms.MouseButtons.Left)
		{
			if (internaldragging)
			{
				// recompute nowQuat
				Vector3 vCur = ScreenToVector(e.X, e.Y);
				Quaternion qAxisToAxis = GraphicsUtility.D3DXQuaternionAxisToAxis(internalvectorDown, vCur);
				internalnowQuat = internaldownQuat;
				internalnowQuat = Quaternion.Multiply(internalnowQuat,qAxisToAxis);
				internalrotationDelta = Matrix.RotationQuaternion(qAxisToAxis);
			}
			else
				internalrotationDelta = Matrix.Identity;

			internalrotationMatrix = Matrix.RotationQuaternion(internalnowQuat);
			internaldragging = true;
		}

		if ((e.Button == System.Windows.Forms.MouseButtons.Right) || (e.Button == System.Windows.Forms.MouseButtons.Middle))
		{
			// Normalize based on size of window and bounding sphere radius
			float fDeltaX = (saveMouseX-e.X) * internalradiusTranslation / internalWidth;
			float fDeltaY = (saveMouseY-e.Y) * internalradiusTranslation / internalHeight;

			if (e.Button == System.Windows.Forms.MouseButtons.Right)
			{
				internaltranslationDelta = Matrix.Translation(-2 * fDeltaX, 2 * fDeltaY, 0.0f);
				internaltranslationMatrix = Matrix.Multiply(internaltranslationMatrix, internaltranslationDelta);
			}
			if (e.Button == System.Windows.Forms.MouseButtons.Middle)
			{
				internaltranslationDelta = Matrix.Translation(0.0f, 0.0f, 5 * fDeltaY);
				internaltranslationMatrix = Matrix.Multiply(internaltranslationMatrix, internaltranslationDelta);
			}

			// Store mouse coordinate
			saveMouseX = e.X;
			saveMouseY = e.Y;
		}
	}

	#region Various properties of the class
	public float Radius
	{
		set
		{ internalradiusTranslation = value; }
	}
	public bool RightHanded
	{
		get { return internaluseRightHanded; }
		set { internaluseRightHanded = value; }
	}
	public Matrix RotationMatrix
	{
		get { return internalrotationMatrix; }
	}
	public Matrix RotationDeltaMatrix
	{
		get { return internalrotationDelta; }
	}
	public Matrix TranslationMatrix
	{
		get { return internaltranslationMatrix; }
	}
	public Matrix TranslationDeltaMatrix
	{
		get { return internaltranslationDelta; }
	}
	public bool IsBeingDragged
	{
		get { return internaldragging; }
	}
	#endregion
}




/// <summary>
/// Handles our meshes
/// </summary>
public class GraphicsMesh : IDisposable
{
	private string fileName = null;
	private Mesh systemMemoryMesh = null; // SysMem mesh, lives through resize
	private Mesh localMemoryMesh = null; // Local mesh, rebuilt on resize
	private Direct3D.Material[] materials = null;
	private Texture[] textures = null;
	private bool isUsingMeshMaterials = true;
	private VertexBuffer systemMemoryVertexBuffer = null;
	private VertexBuffer localMemoryVertexBuffer = null;
	private IndexBuffer systemMemoryIndexBuffer = null;
	private IndexBuffer localMemoryIndexBuffer = null;




    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="filename">The initial filename</param>
	public GraphicsMesh(string filename)
	{
		fileName = filename;
	}
    public GraphicsMesh() : this ("CD3DFile_Mesh") {}




    /// <summary>
    /// The system memory mesh
    /// </summary>
	public Mesh SystemMesh
	{
		get { return systemMemoryMesh; }
	}




    /// <summary>
    /// The local memory mesh
    /// </summary>
	public Mesh LocalMesh
	{
		get { return localMemoryMesh; }
	}




    /// <summary>
    /// Should we use the mesh materials
    /// </summary>
	public bool IsUsingMaterials
	{
		set { isUsingMeshMaterials = value; }
	}




    /// <summary>
    /// Creates a new mesh
    /// </summary>
    /// <param name="device">The device used to create the mesh</param>
    /// <param name="filename">the file to load</param>
	public void Create(Device device, string filename)
	{
		string strPath = null;
		GraphicsStream adjacencyBuffer;
		ExtendedMaterial[] Mat;

		if (device != null)
		{
			device.DeviceLost += new System.EventHandler(this.InvalidateDeviceObjects);
			device.Disposing += new System.EventHandler(this.InvalidateDeviceObjects);
			device.DeviceReset += new System.EventHandler(this.RestoreDeviceObjects);
		}

		// Find the path for the file, and convert it to ANSI (for the D3DX API)
		strPath = DXUtil.FindMediaFile(null, filename);

		// Load the mesh
		systemMemoryMesh =  Mesh.FromFile(strPath, MeshFlags.SystemMemory, device, out adjacencyBuffer, out Mat);

		// Optimize the mesh for performance
		systemMemoryMesh.OptimizeInPlace(MeshFlags.OptimizeCompact | MeshFlags.OptimizeAttrSort | MeshFlags.OptimizeVertexCache, adjacencyBuffer);

		textures = new Texture[Mat.Length];
		materials = new Direct3D.Material[Mat.Length];

		for (int i=0; i<Mat.Length; i++)
		{
			materials[i] = Mat[i].Material3D;
			// Set the ambient color for the material (D3DX does not do this)
			materials[i].Ambient = materials[i].Diffuse;
     
			if (Mat[i].TextureFilename != null)
			{
				// Create the texture
				string texturefilename = DXUtil.FindMediaFile(null, Mat[i].TextureFilename);
				textures[i] = TextureLoader.FromFile(device, texturefilename);
			}
		}

		adjacencyBuffer.Close();
		adjacencyBuffer = null;
	}




    /// <summary>
    /// Set the flexible vertex format
    /// </summary>
	public void SetVertexFormat(Device device, VertexFormats format)
	{
		Mesh pTempSysMemMesh = null;
		Mesh pTempLocalMesh  = null;

		if (systemMemoryMesh != null)
		{
			pTempSysMemMesh = systemMemoryMesh.Clone(MeshFlags.SystemMemory, format, device);
		}
		if (localMemoryMesh != null)
		{
			try
			{
				pTempLocalMesh = localMemoryMesh.Clone(0, format, device);
			}
			catch (Exception e)
			{
				pTempSysMemMesh.Dispose();
				pTempSysMemMesh = null;
				throw e;
			}
		}

		if (systemMemoryMesh != null)
			systemMemoryMesh.Dispose();
		systemMemoryMesh = null;

		if (localMemoryMesh != null)
			localMemoryMesh.Dispose();
		localMemoryMesh = null;

		// Clean up any vertex/index buffers
		DisposeLocalBuffers(true, true);

		if (pTempSysMemMesh != null) systemMemoryMesh = pTempSysMemMesh;
		if (pTempLocalMesh != null) localMemoryMesh  = pTempLocalMesh;

		// Compute normals in case the meshes have them
		if (systemMemoryMesh != null)
			systemMemoryMesh.ComputeNormals();
		if (localMemoryMesh != null)
			localMemoryMesh.ComputeNormals();
	}




    /// <summary>
    /// Restore the device objects after the device was reset
    /// </summary>
	public void RestoreDeviceObjects(object sender, EventArgs e)
	{
		if (null == systemMemoryMesh)
			throw new ArgumentException();

		Device device = (Device)sender;
		// Make a local memory version of the mesh. Note: because we are passing in
		// no flags, the default behavior is to clone into local memory.
		localMemoryMesh = systemMemoryMesh.Clone(0, systemMemoryMesh.VertexFormat, device);
		// Clean up any vertex/index buffers
		DisposeLocalBuffers(false, true);

	}




    /// <summary>
    /// Invalidate our local mesh
    /// </summary>
	public void InvalidateDeviceObjects(object sender, EventArgs e)
	{
		if (localMemoryMesh != null)
			localMemoryMesh.Dispose();
		localMemoryMesh = null;
		// Clean up any vertex/index buffers
		DisposeLocalBuffers(false, true);
	}




    /// <summary>
    /// Get the vertex buffer assigned to the system mesh
    /// </summary>
	public VertexBuffer SystemVertexBuffer
	{
		get
		{
			if (systemMemoryVertexBuffer != null)
				return systemMemoryVertexBuffer;

			if (systemMemoryMesh == null)
				return null;
			
			systemMemoryVertexBuffer = systemMemoryMesh.VertexBuffer;
			return systemMemoryVertexBuffer;
		}
	}




    /// <summary>
    /// Get the vertex buffer assigned to the Local mesh
    /// </summary>
	public VertexBuffer LocalVertexBuffer
	{
		get
		{
			if (localMemoryVertexBuffer != null)
				return localMemoryVertexBuffer;

			if (localMemoryMesh == null)
				return null;
			
			localMemoryVertexBuffer = localMemoryMesh.VertexBuffer;
			return localMemoryVertexBuffer;
		}
	}




    /// <summary>
    /// Get the Index buffer assigned to the system mesh
    /// </summary>
	public IndexBuffer SystemIndexBuffer
	{
		get
		{
			if (systemMemoryIndexBuffer != null)
				return systemMemoryIndexBuffer;

			if (systemMemoryMesh == null)
				return null;

			systemMemoryIndexBuffer = systemMemoryMesh.IndexBuffer;
			return systemMemoryIndexBuffer;
		}
	}




    /// <summary>
    /// Get the Index buffer assigned to the Local mesh
    /// </summary>
	public IndexBuffer LocalIndexBuffer
	{
		get
		{
			if (localMemoryIndexBuffer != null)
				return localMemoryIndexBuffer;

			if (localMemoryMesh == null)
				return null;

			localMemoryIndexBuffer = localMemoryMesh.IndexBuffer;
			return localMemoryIndexBuffer;
		}
	}




    /// <summary>
    /// Clean up any resources
    /// </summary>
	public void Dispose()
	{
		if (textures != null)
		{
			for (int i = 0; i<textures.Length; i++)
			{
				if (textures[i] != null)
					textures[i].Dispose();
				textures[i] = null;
			}
			textures = null;
		}

		// Clean up any vertex/index buffers
		DisposeLocalBuffers(true, true);

		// Clean up any memory
		if (systemMemoryMesh != null)
			systemMemoryMesh.Dispose();
		systemMemoryMesh = null;

		// In case the finalizer hasn't been called yet.
		GC.SuppressFinalize(this);
	}




    /// <summary>
    /// Actually draw the mesh
    /// </summary>
    /// <param name="device">The device used to draw</param>
    /// <param name="canDrawOpaque">Can draw the opaque parts of the mesh</param>
    /// <param name="canDrawAlpha">Can draw the alpha parts of the mesh</param>
	public void Render(Device device, bool canDrawOpaque, bool canDrawAlpha)
	{
		if (null == localMemoryMesh)
			throw new ArgumentException();

		RenderStates rs = device.RenderState;
		// Frist, draw the subsets without alpha
		if (canDrawOpaque)
		{
			for (int i=0; i<materials.Length; i++)
			{
				if (isUsingMeshMaterials)
				{
					if (canDrawAlpha)
					{
						if (materials[i].Diffuse.A < 0xff)
							continue;
					}
					device.Material = materials[i];
					device.SetTexture(0, textures[i]);
				}
				localMemoryMesh.DrawSubset(i);
			}
		}

		// Then, draw the subsets with alpha
		if (canDrawAlpha && isUsingMeshMaterials)
		{
			// Enable alpha blending
			rs.AlphaBlendEnable = true;
			rs.SourceBlend = Blend.SourceAlpha;
			rs.DestinationBlend = Blend.InvSourceAlpha;
			for (int i=0; i<materials.Length; i++)
			{
				if (materials[i].Diffuse.A == 0xff)
					continue;

				// Set the material and texture
				device.Material = materials[i];
				device.SetTexture(0, textures[i]);
				localMemoryMesh.DrawSubset(i);
			}
			// Restore state
			rs.AlphaBlendEnable = false;
		}
	}




    /// <summary>
    /// Draw the mesh with opaque and alpha 
    /// </summary>
    public void Render(Device device)
	{
		Render(device, true, true);
	}




    /// <summary>
    /// Cleans up the local vertex buffers/index buffers
    /// </summary>
    /// <param name="systemBuffers"></param>
    /// <param name="localBuffers"></param>
	private void DisposeLocalBuffers(bool systemBuffers, bool localBuffers)
	{
		if (systemBuffers)
		{
			if (systemMemoryIndexBuffer != null)
				systemMemoryIndexBuffer.Dispose();
			systemMemoryIndexBuffer = null;

			if (systemMemoryVertexBuffer != null)
				systemMemoryVertexBuffer.Dispose();
			systemMemoryVertexBuffer = null;
		}
		if (localBuffers)
		{
			if (localMemoryIndexBuffer != null)
				localMemoryIndexBuffer.Dispose();
			localMemoryIndexBuffer = null;

			if (localMemoryVertexBuffer != null)
				localMemoryVertexBuffer.Dispose();
			localMemoryVertexBuffer = null;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -