gr_tut10_screenshot.jpg

LightingFragments.cs

#region Using directives

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;
using Microsoft.DirectX.Direct3D;

using JadEngine;
using JadEngine.Video;
using JadEngine.Core;
using JadEngine.Mathematics;
using JadEngine.Scene;
using JadEngine.Scene.MD5;
using JadEngine.Physics;
using JadEngine.Particles;
using JadEngine.Sound;
using JadEngine.Tools;
using JadEngine.Import;
using JadEngine.Input;

#endregion

namespace Tutorial
{
	/// <summary>
	/// This tutorial will show you the use of some "lighting fragments" through material scripts.
	/// Also you'll be able to change the properties of the lighting fragment.
	/// </summary>
	public class LightingFragments : JApplication
	{
		#region Fields

		/// <summary>
		/// Indicates if the help must be shown in the screen or not
		/// </summary>
		bool showHelp = true;

		/// <summary>
		/// TODO
		/// </summary>
		JMeshObject model;

		/// <summary>
		/// TODO
		/// </summary>
		int selParam;

		/// <summary>
		/// TODO
		/// </summary>		
		int selParamType;

		/// <summary>
		/// TODO
		/// </summary>
		int selParamIndex;

		/// <summary>
		/// TODO
		/// </summary>
		int selParamVectorCount;

		/// <summary>
		/// TODO
		/// </summary>
		int nMaterial;

		/// <summary>
		/// TODO
		/// </summary>
		JMaterial[] materials;

		/// <summary>
		/// TODO
		/// </summary>
		JCameraFirstPerson userCamera;

		#endregion

		#region Methods

		/// <summary>
		/// The engine calls this method after creating the device
		/// </summary>
		/// <param name="form">Form used as window</param>
		/// <returns>True if everything went right</returns>
		public override bool InitGame(Form form)
		{
			// Create the fonts and texture objects
			Jad.AfterCreateDevice();

			// Load default textures, scenes, shaders,...
			Jad.LoadCreateInHouse();

			#region Material creation

			// Create the materials we'll use for our model
			// This materials are loaded from the material scripts you can find in the "base/materials/tutorials" folder
			nMaterial = 0;
			materials = new JMaterial[4];
			materials[0] = Jad.Scene.Materials.Load("green_metal.material");
			materials[1] = Jad.Scene.Materials.Load("velvet.material");
			materials[2] = Jad.Scene.Materials.Load("grey_plastic.material");
			materials[3] = Jad.Scene.Materials.Load("anisotropic.material");
			materials[3].WorldSpaceNormals = true;

			#endregion

			#region MeshObject creation

			// Load our mesh object
			Jad.Import.Load("TorusKnot.haddd");
			// Get a reference of our mesh object
			model = Jad.Import.MeshObjects[0];
			// Assign a material to the mesh object
			model.Material[0] = materials[nMaterial];

			#endregion

			#region Light

			// Create an omni light
			JDirectLight light = (JDirectLight) Jad.Scene.Lights.Create("light", JLightType.Directional);

			// Set its angles
			light.Transform.Angles = new Vector3(Geometry.DegreeToRadian(45.0f), 0.0f, 0.0f);

			// Position
			light.Transform.Position = new Vector3(0, 5.0f, -5.0f);

			// Intensity
			light.Multiplier = 1.0f;

			// Attenuation
			light.Attenuation.Type = JLightAttenuationType.None;

			// Color
			light.Color = JColor.White;

			// The light affects the diffuse component of the material
			light.AffectDiffuse = true;

			// The light affects the specular component of the material
			light.AffectSpecular = true;

			// Don´t generate shadows
			light.CastShadows = false;

			// Falloff & HotSpot, don't affect directional (nor omni) lights but we use them
			// because are needed for building the light frustum (for the gizmo)
			light.FallOff = 15.0f;
			light.HotSpot = 20.0f;

			// Put ambient light
			Jad.Scene.Lights.Ambient = new JColor(0.0f, 0.0f, 0.0f);

			#endregion

			#region Camera parameters

			// Set some camera parameters
			userCamera = (JCameraFirstPerson) Jad.Scene.Camera;
			userCamera.Transform.Position = new Vector3(0.0f, 0.0f, -10.0f);
			userCamera.Speed = 5.0f;

			#endregion

			selParam = 0;
			selParamType = SelParamType(model.Material[0].Layers[0].ShaderParams, out selParamIndex, out selParamVectorCount);

			// Everything is set, start the engine
			Jad.Begin();

			// Create input class to manage the keyboard and the mouse
			Jad.CreateInput();

			return true;
		}

		/// <summary>
		/// This method is called every frame and it´s where the input
		/// events and the game action must be placed
		/// </summary>
		/// <returns>True to continue, false to exit the application</returns>
		public override bool Update()
		{
			// Exit the app?
			if (Jad.Input.Keyboard[Key.Escape].Down) return false;

			if (Jad.Input.Keyboard[Key.F1].Pressed) /*Jad.Scene.ShowNames = */ showHelp = !showHelp;

			// If G key was pressed we activate / deactivate the gizmos
			// The diference between KeyTouch and KeyPressed is that KeyTouch only returns
			// true if the key was pressed for the first time and not when it´s down as in
			// KeyPressed

			// KeyTouch is like normal writting, returning true only once for every key press

			if (Jad.Input.Keyboard[Key.G].Pressed)
				Jad.Scene.ShowGizmos = !Jad.Scene.ShowGizmos;

			// Keys that change the current material assigned to our mesh object

			if (Jad.Input.Keyboard[Key.Left].Pressed)
			{
				nMaterial--;
				nMaterial = (nMaterial < 0) ? materials.Length - 1 : nMaterial;
				model.Material[0] = materials[nMaterial];
			}

			if (Jad.Input.Keyboard[Key.Right].Pressed)
			{
				nMaterial++;
				nMaterial = (nMaterial >= materials.Length) ? 0 : nMaterial;
				model.Material[0] = materials[nMaterial];
			}

			HandleParamsKeys(model.Material[0].Layers[0].ShaderParams);

			// Rotate the mesh object
			model.Transform.RotateRadians(Jad.Timer.Time * 0.5f, Jad.Timer.Time * 2.0f, Jad.Timer.Time);

			// Everything was right, continue
			return true;
		}

		/// <summary>
		/// Render method
		/// </summary>
		public override void Render()
		{
			JView backbuffer = Jad.Video.Views[0];

			// Render the Jad.Scene using the scene camera
			backbuffer.Render();

			if (showHelp)
			{
				// Get access to the 1st font. The engine creates a font by default
				JFont font = Jad.Video.Fonts[0];

				// Start fonts rendering
				Jad.Video.Fonts.Begin();

				// Help text
				font.RenderLine(Jad.Version + ". Press ESC to exit. Press G to Show/Hide Gizmos. F1 show/hide text", 0, JColor.Yellow);
				font.RenderLine("Press left/right cursors to cycle through available materials", 0, JColor.Yellow);
				font.RenderLine("Press up/down to change the current shader property to be changed", 0, JColor.Yellow);
				font.RenderLine("Press +/- numpad keys to increment/decrement the value of the current property", 0, JColor.Yellow);

				// Show frame rate
				font.RenderLine(Jad.Video.Views.CurrentView.Stats.Fps + " FPS", 0, JColor.White);

				// Show the current lighting shader properties
				font.RenderLine("", 0, JColor.White);
				font.RenderLine("-> Shader Params for '" + materials[nMaterial].Name + "' <-", 0, JColor.Yellow);
				font.RenderLine("", 0, JColor.White);
				RenderParams(model.Material[0].Layers[0].ShaderParams, font);

				// End fonts rendering
				Jad.Video.Fonts.End();
			}

			// Show the backbuffer
			backbuffer.Present();
		}

		/// <summary>
		/// TODO
		/// </summary>
		/// <param name="shaderParams">TODO</param>
		/// <returns>TODO</returns>
		int ParamCount(JShaderParams shaderParams)
		{
			return shaderParams.BoolList.Count + shaderParams.FloatList.Count + shaderParams.VectorList.Count;
		}

		/// <summary>
		/// TODO
		/// </summary>
		/// <param name="shaderParams">TODO</param>
		/// <param name="index">TODO</param>
		/// <param name="count">TODO</param>
		/// <returns>TODO</returns>
		int SelParamType(JShaderParams shaderParams, out int index, out int count)
		{
			bool found = false;
			int type = -1, curParam = 0;

			count = index = 0;
			foreach (JShaderParams.JBool theBool in shaderParams.BoolList)
			{
				found = (curParam == selParam);
				type = 0;
				if (!found) { curParam++; index++; }
			}

			if (!found)
			{
				index = 0;
				foreach (JShaderParams.JFloat theFloat in shaderParams.FloatList)
				{
					found = (curParam == selParam);
					type = 1;
					if (!found) { curParam++; index++; }
				}
			}

			if (!found)
			{
				index = 0;
				foreach (JShaderParams.JVector4 theVector in shaderParams.VectorList)
				{
					found = (curParam == selParam);
					type = 2;
					count = theVector.Count;
					if (!found) { curParam++; index++; }
				}
			}

			return type;
		}

		/// <summary>
		/// TODO
		/// </summary>
		/// <param name="shaderParams">TODO</param>
		/// <param name="font">TODO</param>
		void RenderParams(JShaderParams shaderParams, JFont font)
		{
			int curParam = 0;

			foreach (JShaderParams.JBool theBool in shaderParams.BoolList)
			{
				JColor color = (curParam == selParam) ? JColor.RedColor : JColor.GreenColor;
				font.RenderLine(string.Format("{0} = {1}", theBool.Name, theBool.Bool), 0, color);
				curParam++;
			}

			foreach (JShaderParams.JFloat theFloat in shaderParams.FloatList)
			{
				JColor color = (curParam == selParam) ? JColor.RedColor : JColor.GreenColor;
				font.RenderLine(string.Format(Jad.DecimalFormatInfo, "{0} = {1}", theFloat.Name, theFloat.Float), 0, color);
				curParam++;
			}

			foreach (JShaderParams.JVector4 theVector in shaderParams.VectorList)
			{
				string str = theVector.Name + " = ( ";

				if (theVector.Count >= 1)
					str += string.Format(Jad.DecimalFormatInfo, "{0}", theVector.Vector.X);
				if (theVector.Count >= 2)
					str += string.Format(Jad.DecimalFormatInfo, ", {0}", theVector.Vector.Y);
				if (theVector.Count >= 3)
					str += string.Format(Jad.DecimalFormatInfo, ", {0}", theVector.Vector.Z);
				if (theVector.Count == 4)
					str += string.Format(Jad.DecimalFormatInfo, ", {0}", theVector.Vector.W);

				str += " )";

				JColor color = (curParam == selParam) ? JColor.RedColor : JColor.GreenColor;
				font.RenderLine(str, 0, color);

				curParam++;
			}
		}

		/// <summary>
		/// TODO
		/// </summary>
		/// <param name="shaderParams">TODO</param>
		void HandleParamsKeys(JShaderParams shaderParams)
		{
			float inc = 0.05f;
			if (Jad.Input.Keyboard[Key.LeftShift].Down)
			{
				inc = 0.5f;
				if (Jad.Input.Keyboard[Key.LeftControl].Down)
					inc = 1.0f;
			}

			if (Jad.Input.Keyboard[Key.Up].Pressed)
			{
				selParam--;
				selParam = Math.Max(0, Math.Min(selParam, ParamCount(shaderParams) - 1));
				selParamType = SelParamType(model.Material[0].Layers[0].ShaderParams, out selParamIndex, out selParamVectorCount);
			}
			else if (Jad.Input.Keyboard[Key.Down].Pressed)
			{
				selParam++;
				selParam = Math.Max(0, Math.Min(selParam, ParamCount(shaderParams) - 1));
				selParamType = SelParamType(model.Material[0].Layers[0].ShaderParams, out selParamIndex, out selParamVectorCount);
			}

			if (Jad.Input.Keyboard[Key.NumPad7].Pressed)
			{
				if (selParamType == 2)
				{
					JShaderParams.JVector4 theVector = shaderParams.VectorList[selParamIndex];
					Vector4 v = new Vector4(theVector.Vector.X + inc, theVector.Vector.Y, theVector.Vector.Z, theVector.Vector.W);
					shaderParams.VectorList[selParamIndex] = new JShaderParams.JVector4(theVector.Name, v, selParamVectorCount);
				}
			}
			else if (Jad.Input.Keyboard[Key.NumPad4].Pressed)
			{
				if (selParamType == 2)
				{
					JShaderParams.JVector4 theVector = shaderParams.VectorList[selParamIndex];
					Vector4 v = new Vector4(theVector.Vector.X - inc, theVector.Vector.Y, theVector.Vector.Z, theVector.Vector.W);
					shaderParams.VectorList[selParamIndex] = new JShaderParams.JVector4(theVector.Name, v, selParamVectorCount);
				}
			}

			if (Jad.Input.Keyboard[Key.NumPad8].Pressed)
			{
				if (selParamType == 2)
				{
					JShaderParams.JVector4 theVector = shaderParams.VectorList[selParamIndex];
					Vector4 v = new Vector4(theVector.Vector.X, theVector.Vector.Y + inc, theVector.Vector.Z, theVector.Vector.W);
					shaderParams.VectorList[selParamIndex] = new JShaderParams.JVector4(theVector.Name, v, selParamVectorCount);
				}
			}
			else if (Jad.Input.Keyboard[Key.NumPad5].Pressed)
			{
				if (selParamType == 2)
				{
					JShaderParams.JVector4 theVector = shaderParams.VectorList[selParamIndex];
					Vector4 v = new Vector4(theVector.Vector.X, theVector.Vector.Y - inc, theVector.Vector.Z, theVector.Vector.W);
					shaderParams.VectorList[selParamIndex] = new JShaderParams.JVector4(theVector.Name, v, selParamVectorCount);
				}
			}

			if (Jad.Input.Keyboard[Key.NumPad9].Pressed)
			{
				if (selParamType == 2)
				{
					JShaderParams.JVector4 theVector = shaderParams.VectorList[selParamIndex];
					Vector4 v = new Vector4(theVector.Vector.X, theVector.Vector.Y, theVector.Vector.Z + inc, theVector.Vector.W);
					shaderParams.VectorList[selParamIndex] = new JShaderParams.JVector4(theVector.Name, v, selParamVectorCount);
				}
			}
			else if (Jad.Input.Keyboard[Key.NumPad6].Pressed)
			{
				if (selParamType == 2)
				{
					JShaderParams.JVector4 theVector = shaderParams.VectorList[selParamIndex];
					Vector4 v = new Vector4(theVector.Vector.X, theVector.Vector.Y, theVector.Vector.Z - inc, theVector.Vector.W);
					shaderParams.VectorList[selParamIndex] = new JShaderParams.JVector4(theVector.Name, v, selParamVectorCount);
				}
			}
			else if (Jad.Input.Keyboard[Key.NumPadPlus].Pressed)
			{
				switch (selParamType)
				{
					case 0:
						JShaderParams.JBool theBool = shaderParams.BoolList[selParamIndex];
						shaderParams.BoolList[selParamIndex] = new JShaderParams.JBool(theBool.Name, !theBool.Bool);
						break;
					case 1:
						JShaderParams.JFloat theFloat = shaderParams.FloatList[selParamIndex];
						shaderParams.FloatList[selParamIndex] = new JShaderParams.JFloat(theFloat.Name, theFloat.Float + inc);
						break;
					case 2:
						JShaderParams.JVector4 theVector = shaderParams.VectorList[selParamIndex];
						Vector4 v = new Vector4(theVector.Vector.X, theVector.Vector.Y, theVector.Vector.Z, theVector.Vector.W + inc);
						shaderParams.VectorList[selParamIndex] = new JShaderParams.JVector4(theVector.Name, v, selParamVectorCount);
						break;
				}
			}
			else if (Jad.Input.Keyboard[Key.NumPadMinus].Pressed)
			{
				switch (selParamType)
				{
					case 0:
						JShaderParams.JBool theBool = shaderParams.BoolList[selParamIndex];
						shaderParams.BoolList[selParamIndex] = new JShaderParams.JBool(theBool.Name, !theBool.Bool);
						break;
					case 1:
						JShaderParams.JFloat theFloat = shaderParams.FloatList[selParamIndex];
						shaderParams.FloatList[selParamIndex] = new JShaderParams.JFloat(theFloat.Name, theFloat.Float - inc);
						break;
					case 2:
						JShaderParams.JVector4 theVector = shaderParams.VectorList[selParamIndex];
						Vector4 v = new Vector4(theVector.Vector.X, theVector.Vector.Y, theVector.Vector.Z, theVector.Vector.W - inc);
						shaderParams.VectorList[selParamIndex] = new JShaderParams.JVector4(theVector.Name, v, selParamVectorCount);
						break;
				}
			}
		}

		#endregion
	}
}

Last edited Mar 8, 2007 at 12:26 PM by Vicente, version 4

Comments

No comments yet.