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

📄 skybox.cs

📁 Introduction to 3d game engine design一书的源代码!
💻 CS
字号:
using System;
using System.Drawing;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace GameEngine
{
	/// <summary>
	/// Face class for SkyBox
	/// </summary>
	public class SkyFace : IDisposable
	{
	#region Attributes
		private CustomVertex.PositionNormalTextured[]  m_Corners;   
		private VertexBuffer m_VB = null;  // Vertex buffer
		private Texture      m_Texture; // image for face
		private bool         m_bValid = false;
		private string       m_sName;

		public bool Valid { get { return m_bValid; } }
	#endregion

		public SkyFace( string sName, SkyBox.Face face )
		{

			m_sName = sName;

			// create the vertices for the box
			m_Corners = new CustomVertex.PositionNormalTextured[4]; 

			switch ( face )
			{
			case SkyBox.Face.Top:
				m_Corners[0].X = -100.0f; 
				m_Corners[0].Y =  100.0f;
				m_Corners[0].Z = -100.0f;
				m_Corners[0].Tu = 0.0f;
				m_Corners[0].Tv = 1.0f;
				m_Corners[0].Nx = 0.0f;
				m_Corners[0].Ny = -1.0f;
				m_Corners[0].Nz = 0.0f;
				m_Corners[1].X =  100.0f; 
				m_Corners[1].Y =  100.0f;
				m_Corners[1].Z = -100.0f;
				m_Corners[1].Tu = 0.0f;
				m_Corners[1].Tv = 0.0f;
				m_Corners[1].Nx = 0.0f;
				m_Corners[1].Ny = -1.0f;
				m_Corners[1].Nz = 0.0f;
				m_Corners[2].X = -100.0f; 
				m_Corners[2].Y =  100.0f;
				m_Corners[2].Z =  100.0f;
				m_Corners[2].Tu = 1.0f;
				m_Corners[2].Tv = 1.0f;
				m_Corners[2].Nx = 0.0f;
				m_Corners[2].Ny = -1.0f;
				m_Corners[2].Nz = 0.0f;
				m_Corners[3].X =  100.0f; 
				m_Corners[3].Y =  100.0f;
				m_Corners[3].Z =  100.0f;
				m_Corners[3].Tu = 1.0f;
				m_Corners[3].Tv = 0.0f;
				m_Corners[3].Nx = 0.0f;
				m_Corners[3].Ny = -1.0f;
				m_Corners[3].Nz = 0.0f;
				break;
			case SkyBox.Face.Bottom:
				m_Corners[0].X = -100.0f; // nw
				m_Corners[0].Y = -100.0f;
				m_Corners[0].Z =  100.0f;
				m_Corners[0].Tu = 0.0f;
			   m_Corners[0].Tv = 0.0f;
				m_Corners[0].Nx = 0.0f;
				m_Corners[0].Ny = 1.0f;
				m_Corners[0].Nz = 0.0f;
				m_Corners[1].X =  100.0f; // ne
				m_Corners[1].Y = -100.0f;
				m_Corners[1].Z =  100.0f;
				m_Corners[1].Tu = 1.0f;
			   m_Corners[1].Tv = 1.0f;
				m_Corners[1].Nx = 0.0f;
				m_Corners[1].Ny = 1.0f;
				m_Corners[1].Nz = 0.0f;
				m_Corners[2].X = -100.0f; // sw
				m_Corners[2].Y = -100.0f;
				m_Corners[2].Z = -100.0f;
				m_Corners[2].Tu = 1.0f;
			   m_Corners[2].Tv = 0.0f;
				m_Corners[2].Nx = 0.0f;
				m_Corners[2].Ny = 1.0f;
				m_Corners[2].Nz = 0.0f;
				m_Corners[3].X =  100.0f; // se
				m_Corners[3].Y = -100.0f;
				m_Corners[3].Z = -100.0f;
			   m_Corners[3].Tu = 0.0f;
			   m_Corners[3].Tv = 1.0f;
				m_Corners[3].Nx = 0.0f;
				m_Corners[3].Ny = 1.0f;
				m_Corners[3].Nz = 0.0f;
				break;
			case SkyBox.Face.Front:
				m_Corners[0].X = -100.0f; // upper nw
				m_Corners[0].Y =  100.0f;
				m_Corners[0].Z =  100.0f;
				m_Corners[0].Tu = 0.0f;
			   m_Corners[0].Tv = 0.0f;
				m_Corners[0].Nx = 0.0f;
				m_Corners[0].Ny = 0.0f;
				m_Corners[0].Nz = -1.0f;
				m_Corners[1].X =  100.0f; // upper ne
				m_Corners[1].Y =  100.0f;
				m_Corners[1].Z =  100.0f;
				m_Corners[1].Tu = 1.0f;
			   m_Corners[1].Tv = 0.0f;
				m_Corners[1].Nx = 0.0f;
				m_Corners[1].Ny = 0.0f;
				m_Corners[1].Nz = -1.0f;
				m_Corners[2].X = -100.0f; // lower nw
				m_Corners[2].Y = -100.0f;
				m_Corners[2].Z =  100.0f;
			   m_Corners[2].Tu = 0.0f;
			   m_Corners[2].Tv = 1.0f;
				m_Corners[2].Nx = 0.0f;
				m_Corners[2].Ny = 0.0f;
				m_Corners[2].Nz = -1.0f;
				m_Corners[3].X =  100.0f; // lower ne
				m_Corners[3].Y = -100.0f;
				m_Corners[3].Z =  100.0f;
			   m_Corners[3].Tu = 1.0f;
			   m_Corners[3].Tv = 1.0f;
				m_Corners[3].Nx = 0.0f;
				m_Corners[3].Ny = 0.0f;
				m_Corners[3].Nz = -1.0f;
				break;
			case SkyBox.Face.Right:
				m_Corners[0].X = 100.0f; // upper ne
				m_Corners[0].Y = 100.0f;
				m_Corners[0].Z = 100.0f;
				m_Corners[0].Tu = 0.0f;
			   m_Corners[0].Tv = 0.0f;
				m_Corners[0].Nx = -1.0f;
				m_Corners[0].Ny = 0.0f;
				m_Corners[0].Nz = 0.0f;
				m_Corners[1].X =  100.0f; // upper se
				m_Corners[1].Y =  100.0f;
				m_Corners[1].Z = -100.0f;
				m_Corners[1].Tu = 1.0f;
			   m_Corners[1].Tv = 0.0f;
				m_Corners[1].Nx = -1.0f;
				m_Corners[1].Ny = 0.0f;
				m_Corners[1].Nz = 0.0f;
				m_Corners[2].X =  100.0f; // lower ne
				m_Corners[2].Y = -100.0f;
				m_Corners[2].Z =  100.0f;
			   m_Corners[2].Tu = 0.0f;
			   m_Corners[2].Tv = 1.0f;
				m_Corners[2].Nx = -1.0f;
				m_Corners[2].Ny = 0.0f;
				m_Corners[2].Nz = 0.0f;
				m_Corners[3].X =  100.0f; // lower se
				m_Corners[3].Y = -100.0f;
				m_Corners[3].Z = -100.0f;
			   m_Corners[3].Tu = 1.0f;
			   m_Corners[3].Tv = 1.0f;
				m_Corners[3].Nx = -1.0f;
				m_Corners[3].Ny = 0.0f;
				m_Corners[3].Nz = 0.0f;
				break;
			case SkyBox.Face.Back:
				m_Corners[0].X =  100.0f; // upper se
				m_Corners[0].Y =  100.0f;
				m_Corners[0].Z = -100.0f;
				m_Corners[0].Tu = 0.0f;
			   m_Corners[0].Tv = 0.0f;
				m_Corners[0].Nx = 0.0f;
				m_Corners[0].Ny = 0.0f;
				m_Corners[0].Nz = -1.0f;
				m_Corners[1].X = -100.0f; // upper sw
				m_Corners[1].Y =  100.0f;
				m_Corners[1].Z = -100.0f;
				m_Corners[1].Tu = 1.0f;
			   m_Corners[1].Tv = 0.0f;
				m_Corners[1].Nx = 0.0f;
				m_Corners[1].Ny = 0.0f;
				m_Corners[1].Nz = -1.0f;
				m_Corners[2].X =  100.0f; // lower se
				m_Corners[2].Y = -100.0f;
				m_Corners[2].Z = -100.0f;
			   m_Corners[2].Tu = 0.0f;
			   m_Corners[2].Tv = 1.0f;
				m_Corners[2].Nx = 0.0f;
				m_Corners[2].Ny = 0.0f;
				m_Corners[2].Nz = -1.0f;
				m_Corners[3].X = -100.0f; // lower sw
				m_Corners[3].Y = -100.0f;
				m_Corners[3].Z = -100.0f;
			   m_Corners[3].Tu = 1.0f;
			   m_Corners[3].Tv = 1.0f;
				m_Corners[3].Nx = 0.0f;
				m_Corners[3].Ny = 0.0f;
				m_Corners[3].Nz = -1.0f;
				break;
			case SkyBox.Face.Left:
				m_Corners[0].X = -100.0f; // upper south
				m_Corners[0].Y =  100.0f;
				m_Corners[0].Z = -100.0f;
				m_Corners[0].Tu = 0.0f;
				m_Corners[0].Tv = 0.0f;
				m_Corners[0].Nx = 1.0f;
				m_Corners[0].Ny = 0.0f;
				m_Corners[0].Nz = 0.0f;
				m_Corners[1].X = -100.0f; // upper north
				m_Corners[1].Y =  100.0f;
				m_Corners[1].Z =  100.0f;
				m_Corners[1].Tu = 1.0f;
				m_Corners[1].Tv = 0.0f;
				m_Corners[1].Nx = 1.0f;
				m_Corners[1].Ny = 0.0f;
				m_Corners[1].Nz = 0.0f;
				m_Corners[2].X = -100.0f; // lower south
				m_Corners[2].Y = -100.0f;
				m_Corners[2].Z = -100.0f;
				m_Corners[2].Tu = 0.0f;
				m_Corners[2].Tv = 1.0f;
				m_Corners[2].Nx = 1.0f;
				m_Corners[2].Ny = 0.0f;
				m_Corners[2].Nz = 0.0f;
				m_Corners[3].X = -100.0f; // lower north
				m_Corners[3].Y = -100.0f;
				m_Corners[3].Z =  100.0f;
				m_Corners[3].Tu = 1.0f;
				m_Corners[3].Tv = 1.0f;
				m_Corners[3].Nx = 1.0f;
				m_Corners[3].Ny = 0.0f;
				m_Corners[3].Nz = 0.0f;
				break;
			}

			// load the texture for the face
			try
			{
				m_Texture = GraphicsUtility.CreateTexture(CGameEngine.Device3D, sName); 
				m_bValid = true;
			}
			catch
			{
				Console.AddLine("Unable to create skybox texture for " + sName);
			}
			
			// Create a quad for rendering the face
			m_VB = new VertexBuffer( typeof(CustomVertex.PositionNormalTextured), 4,
				CGameEngine.Device3D, Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format,
				Pool.Default );

			m_VB.Created += new System.EventHandler(this.CreateQuad);
			CreateQuad(m_VB, null);

		}

		public void CreateQuad(object sender, EventArgs e)
		{
			VertexBuffer vb = (VertexBuffer)sender;

			// Copy tree mesh data into vertexbuffer
			vb.SetData(m_Corners, 0, 0);
		}

		public void Render()
		{
			if ( m_bValid ) 
			{
				Material mtrl = new Material();
				mtrl.Ambient = Color.White;
				mtrl.Diffuse = Color.White;
				CGameEngine.Device3D.Material = mtrl;
				CGameEngine.Device3D.SetStreamSource( 0, m_VB, 0 );
				CGameEngine.Device3D.VertexFormat = CustomVertex.PositionNormalTextured.Format;

				// Set the texture
				CGameEngine.Device3D.SetTexture(0, m_Texture );

				// Render the face
				CGameEngine.Device3D.DrawPrimitives( PrimitiveType.TriangleStrip, 0, 2 );
			}
		}

		public void Dispose()
		{
		    m_Texture.Dispose();

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

	/// <summary>
	/// Summary description for SkyBox.
	/// </summary>
	public class SkyBox : Object3D, IDisposable
	{
	#region Attributes
	    private SkyFace[] m_faces = new SkyFace[6];

		public enum Face { Top, Bottom, Front, Right, Back, Left }
	#endregion

		public SkyBox( string sFront, string sRight, string sBack, string sLeft, string sTop, string sBottom ) 
		        : base( "SkyBox" )
		{
			// create the faces for the box
			m_faces[0] = new SkyFace( sFront,  Face.Front );
			m_faces[1] = new SkyFace( sLeft,  Face.Right );
			m_faces[2] = new SkyFace( sBack,   Face.Back );
			m_faces[3] = new SkyFace( sRight,   Face.Left );
			m_faces[4] = new SkyFace( sTop,    Face.Top );
			m_faces[5] = new SkyFace( sBottom, Face.Bottom );
  
		}

		public override void Dispose()
		{
		    for ( int i = 0; i < 6; i++ )
			{
			    m_faces[i].Dispose();
			}
		}

		public override void Render( Camera cam )
		{
			try
			{
				// Set the matrix for normal viewing
				Matrix matWorld = new Matrix();
				matWorld = Matrix.Identity;

				// Center view matrix for skybox and disable zbuffer
				Matrix matView;
				matView = cam.View;
				matView.M41 = 0.0f; matView.M42 = -0.3f; matView.M43 = 0.0f;
				CGameEngine.Device3D.Transform.View = matView;

				CGameEngine.Device3D.Transform.World = matWorld;
				CGameEngine.Device3D.RenderState.ZBufferWriteEnable = false;
				CGameEngine.Device3D.RenderState.CullMode = Microsoft.DirectX.Direct3D.Cull.None;

				// pick faces based on camera attitude

				if ( cam.Pitch > 0.0f )
				{
					m_faces[4].Render();
				}
				else if ( cam.Pitch < 0.0f )
				{
					m_faces[5].Render();
				}

				if ( cam.Heading > 0.0f && cam.Heading < 180.0 )
				{
					m_faces[1].Render();
				}

				if ( cam.Heading > 270.0f || cam.Heading < 90.0 )
				{
					m_faces[0].Render();
				}

				if ( cam.Heading > 180.0f && cam.Heading < 360.0 )
				{
					m_faces[3].Render();
				}

				if ( cam.Heading > 90.0f && cam.Heading < 270.0 )
				{
					m_faces[2].Render();
				}

				// Restore the render states
				CGameEngine.Device3D.Transform.View = cam.View;
				CGameEngine.Device3D.RenderState.ZBufferWriteEnable = true;
			}
			catch (DirectXException d3de)
			{
				Console.AddLine("Unable to render skybox ");
				Console.AddLine(d3de.ErrorString);
			}
			catch ( Exception e )
			{
				Console.AddLine("Unable to render skybox ");
				Console.AddLine(e.Message);
			}
		}
	}
}

⌨️ 快捷键说明

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