gr_tut16_screenshot.jpg

PostproductionAndCamera.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 example will teach you to create postproduction effects, and add them to the scene.
	/// The bloom effect for example adds more intesity to the bright zones.
	/// It also shows how to create a camera, instead of using the ones that come with the engine.
	/// </summary>
	public class PostproductionAndCamera : JApplication
	{
		#region Internal Classes

		/// <summary>
		/// Class to define a simple camera that moves with the cursors
		/// and with the L, targets a node
		/// </summary>
		public class JMyOwnCamera : JCamera
		{
			#region Fields

			/// <summary>
			/// Used for translations
			/// </summary>
			float time;

			/// <summary>
			/// Flag for enable / disable look at
			/// </summary>
			bool lookAt;

			/// <summary>
			/// Target look at node
			/// </summary>
			JNode targetNode;

			/// <summary>
			/// Traslation speed
			/// </summary>
			float speed;

			#endregion

			#region Constructors

			/// <summary>
			/// default Constructor
			/// </summary>
			public JMyOwnCamera(string name, float speed, JNode target)
				: base(name, Jad.Scene.Cameras)
			{
				this.speed = speed;
				targetNode = target;
			}

			#endregion

			#region Properties

			/// <summary>
			/// Gets the look at flag
			/// </summary>
			public bool LookAtFlag
			{
				get { return lookAt; }
			}

			#endregion

			#region Methods

			/// <summary>
			/// Updates the camera
			/// </summary>
			public override void UpdateAction()
			{
				time = Jad.Timer.DeltaTime;

				// Position

				if (Jad.Input.Keyboard[Key.Left].Down)
					MoveX(-speed);

				if (Jad.Input.Keyboard[Key.Right].Down)
					MoveX(speed);

				if (Jad.Input.Keyboard[Key.Up].Down)
					MoveY(speed);

				if (Jad.Input.Keyboard[Key.Down].Down)
					MoveY(-speed);

				if (Jad.Input.Keyboard[Key.L].Pressed)
				{
					lookAt = !lookAt;

					if (lookAt) Transform.LookAt(targetNode);
					else
					{
						// when we are setting a target, the rotation values are lost
						// So we must get it
						float angX, angY, angZ; Vector3 pos;
						JMath.AnglesRadiansPositionFromMatrix(Transform.WorldTM, out angX, out angY, out angZ, out pos);
						Transform.Angles = new Vector3(angX, angY, angZ);
						Transform.Target = null;
					}
				}
			}

			/// <summary>
			/// Updates the camera
			/// </summary>
			protected override void Update()
			{
				base.Update();
			}

			/// <summary>
			/// Moves the camera on the x axis
			/// </summary>
			private void MoveX(float speed)
			{
				Transform.Position += speed * time * Right;
			}

			/// <summary>
			/// Moves the camera on the x axis
			/// </summary>
			private void MoveY(float speed)
			{
				Transform.Position += speed * time * Up;
			}

			#endregion
		}

		#endregion

		#region Fields

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

		/// <summary>
		/// Size of the blur
		/// </summary>
		string blurSize = "low";

		/// <summary>
		/// The high pass filter
		/// </summary>
		JPostFilterHighPass highPass;

		/// <summary>
		/// The post effect
		/// </summary>
		JPostProductionEffect post;

		/// <summary>
		/// The blur filters
		/// </summary>
		JPostFilterGaussianBlur horizontalBlur, verticalBlur;

		/// <summary>
		/// The model that will be drawn in the screen
		/// </summary>
		JMeshObject model;

		/// <summary>
		/// Special camera created
		/// </summary>
		JMyOwnCamera myOwnCamera;

		/// <summary>
		/// Indicates if the own camera should be used or not
		/// </summary>
		bool useOwnCamera;

		#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
			JMaterial material = Jad.Scene.Materials.Load("green_metal.material");

			#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] = material;

			//model.Hide = true;

			#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

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

			CreateBloomEffect();

			CreateRoom();

			// Create the new camera

			myOwnCamera = new JMyOwnCamera("my own camera", 2.0f, model);

			// Add it to the scene
			Jad.Scene.Cameras.Add(myOwnCamera);

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

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

			return true;
		}

		/// <summary>
		/// Creates the room of the scene
		/// </summary>
		void CreateRoom()
		{
			float size = 10f;

			JMesh cubeMesh = JMesh.CreateCube(size, size, size);

			// Invertimos las caras del cubo, porque queremos ponernos dentro de la habitación
			cubeMesh.IndexBuffer.InvertFaces();

			JMeshObject cube = Jad.Scene.MeshObjects.Create("room", false);

			cube.Mesh = cubeMesh;

			JMaterial[] material = new JMaterial[1];

			material[0] = Jad.Scene.Materials.Create();

			JMaterialLayer layer = new JMaterialLayer();

			material[0].AddLayer(layer);

			layer.DiffuseMap.Texture = Jad.Video.Textures.Create2D("brick_d", true);

			layer.DiffuseMap.UTile = layer.DiffuseMap.VTile = 4f;

			cube.Material = material;
		}

		/// <summary>
		/// Create the Bloom effect. Please note that this effect is built in
		/// the scene (Jad.BloomEffect) but created here for learning purposes
		/// </summary>
		public void CreateBloomEffect()
		{
			JPostProductionRT postRT;

			// Create a new effect, called Bloom
			post = new JPostProductionEffect("Bloom");

			// -----------------------------------------------------------------
			// We want to "protect" the active render target, because will be
			// used at the end of the effect
			// -----------------------------------------------------------------

			post.Add(new JPostFilterProtectPrimary(null, false));

			// The JPostProductionRT tells the engine what kind of RenderTarget
			// you need. The engine has full sized temporary rendertargets, and 50%
			// rendertargets. You can tell the engine that you only need a 10% of the
			// rendertarget, or that you will need a fixed rendertarget..

			// Here we are creating a postRT , with id=0 and percentage=1, that is,
			// get a full RenderTarget
			postRT = new JPostProductionRT(0, 1f);

			// I want the result on this RenderTarget
			postRT.FixedRenderTarget = Jad.Video.Views[0].RenderTargets.Glow;

			// Create the high pass filter, telling that the high value is greater or equal than 0.56 and the multiplier is equal to 0.5
			highPass = new JPostFilterHighPass(postRT, 0.56f, 0.7f);

			// Add it to the effect
			post.Add(highPass);

			// -----------------------------------------------------------------
			// Horizontal Gaussian Blur
			// -----------------------------------------------------------------

			postRT = new JPostProductionRT(1, 1f);

			// Tell the engine to set a target RenderTarget that will be 50% of the backbuffer
			// If you would do:
			// postRT = new JPostProductionRT(1, 0.5f);
			// the engine should return an RT that will be full sized(the same size like backbuffer)
			// but the texture coords would be 0.5, to use only the 50%
			// This is radically different than seting the FindRTPercentage=0.5, because with
			// this option the engine will set a RT that will be 50% of the backbuffer, but 
			// the texture coords will be 1
			postRT.FindRTPercentage = 0.5f;

			// Set the source texture
			postRT.Texture = Jad.Video.Views[0].RenderTargets.Glow;

			// Create the filter with the default values( 16 samples )
			horizontalBlur = new JPostFilterGaussianBlur(postRT, JBlurType.Horizontal);

			// Add id to the effect
			post.Add(horizontalBlur);

			// -----------------------------------------------------------------
			// 2º Gaussian Blur
			// -----------------------------------------------------------------

			postRT = new JPostProductionRT(2, 1f);

			postRT.FindRTPercentage = 0.5f;

			verticalBlur = new JPostFilterGaussianBlur(postRT, JBlurType.Vertical);

			post.Add(verticalBlur);

			// Set the att values
			horizontalBlur.GlowAttenuation = 0.7f;
			verticalBlur.GlowAttenuation = 0.7f;

			// -----------------------------------------------------------------
			// Now, we want to blend the original RT, ( locked by the JPostFilterProtectPrimary)
			// with the blurred
			// -----------------------------------------------------------------

			postRT = new JPostProductionRT(3, 1f);

			post.Add(new JPostFilterBlend(postRT));

			// We add the effect to the scene postproduction list
			Jad.Scene.PostProduction.Add(post);
		}

		/// <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) showHelp = !showHelp;

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

			// Change the size of the blurred RenderTarget
			if (Jad.Input.Keyboard[Key.O].Pressed)
			{
				if (horizontalBlur.PostProductionRT.FindRTPercentage == 0)
				{
					horizontalBlur.PostProductionRT.FindRTPercentage = 0.5f;

					blurSize = "low";
				}

				else
				{
					horizontalBlur.PostProductionRT.FindRTPercentage = 0;

					blurSize = "high";
				}

				verticalBlur.PostProductionRT.FindRTPercentage = horizontalBlur.PostProductionRT.FindRTPercentage;
			}

			// Enable/Disable the effect
			if (Jad.Input.Keyboard[Key.P].Pressed)
				post.Enabled = !post.Enabled;

			// If keys + - (from the numeric keyboard) were pressed, modify the high pass value

			if (Jad.Input.Keyboard[Key.NumPadPlus].Pressed)
				highPass.HighPassValue += 0.02f;

			if (Jad.Input.Keyboard[Key.NumPadMinus].Pressed)
				highPass.HighPassValue -= 0.02f;

			// Controls the brightness
			if (Jad.Input.Keyboard[Key.NumPad8].Pressed)
				horizontalBlur.GlowAttenuation += 0.1f;

			if (Jad.Input.Keyboard[Key.NumPad2].Pressed)
				horizontalBlur.GlowAttenuation -= 0.1f;

			verticalBlur.GlowAttenuation = horizontalBlur.GlowAttenuation;

			if (Jad.Input.Keyboard[Key.C].Pressed)
			{
				useOwnCamera = !useOwnCamera;

				if (useOwnCamera)
				{
					myOwnCamera.Transform.Position = Jad.Scene.Camera.Transform.Position;
					Jad.Scene.Camera = myOwnCamera;
				}

				else
					Jad.Scene.Camera = Jad.Scene.Cameras["jad_camera"];
			}

			// 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)
			{
				JFont font = Jad.Video.Fonts[0];

				Jad.Video.Fonts.Begin();

				font.RenderLine(Jad.Version + ". Press ESC to exit. Press G to Show/Hide Gizmos. F1 show/hide text", 0, JColor.Yellow);
				font.RenderLine(Jad.Video.Views.CurrentView.Stats.Fps + " FPS", 0, JColor.White);
				font.RenderLine("Effect ( P ): " + post.Enabled.ToString() + " / High pass value( Numpad + - to change ): " + highPass.HighPassValue.ToString("N2"), 0, JColor.White);
				font.RenderLine("Blur size ( O ): " + blurSize + " / Glow Attenuation (8,2): " + horizontalBlur.GlowAttenuation.ToString("N2"), 0, JColor.White);

				if (useOwnCamera)
					font.RenderLine("Custom camera ON (C) Use Arrow keys to move. Look ( L ): " + myOwnCamera.LookAtFlag.ToString(), 0, JColor.White);

				else
					font.RenderLine("Custom camera OFF (C)", 0, JColor.White);

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

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

		#endregion
	}
}

Last edited Mar 8, 2007 at 10:20 PM by Vicente, version 3

Comments

No comments yet.