gr_tut17_screenshot.jpg

JTutorial17.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 Microsoft.DirectX.DirectInput;
	
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;
	
#endregion
	
namespace Tutorial
{
	/// <summary>
	/// This tutorial will show you how to create particle effects. Also you'll create instances
	/// of some particle effects so only one of them will be calculated. This will speed up the render process.
	/// You'll see also you how to create a camera that will follow a path and how to record this cinematic to images
	/// so later you can create a demostration video if you would.
	/// </summary>
	public class JTutorial : JApplication
	{
		#region Fields
	
		/// <summary>
		/// Indicates if the help must be shown in the screen or not
		/// </summary>
		bool showHelp = true;
	
		/// <summary>
		/// TODO
		/// </summary>
		JCameraFirstPerson userCamera;
	
		/// <summary>
		/// TODO
		/// </summary>
		JCameraSelfDriven pathCamera;
	
		/// <summary>
		/// TODO
		/// </summary>
		JOmniLight omni01;
	
		/// <summary>
		/// TODO
		/// </summary>
		JOmniLight omni02;
	
		/// <summary>
		/// TODO
		/// </summary>
		JMeshObject lightHandle01;
	
		/// <summary>
		/// TODO
		/// </summary>
		JMeshObject lightHandle02;
	
		#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();
	
			// Set the fixed mode, so the engine works at a fixed number of frames per second
			Jad.Timer.FixedMode = true;
			Jad.Timer.FixedModeFPS = 1.0f / 30.0f;    // 30 fps 
	
			#region Camera creation
	
			// Create a camera that will follow the path stored in the file particles.camera
			// placed in the "base/cameras/tutorials" folder.
			pathCamera = Jad.Scene.Cameras.CreateSelfDriven("particles", false);
	
			// Set some camera parameters
			Jad.Scene.Camera.FarPlane = 30.0f;
			Jad.Scene.Camera.Position = new Vector3(0.0f, 2.0f, 5.0f);
			Jad.Scene.Camera.Angles = new Vector3(0.0f, (float) Math.PI, 0.0f);
			Jad.Scene.Camera.FOV = Geometry.DegreeToRadian(75.0f);
			((JCameraFirstPerson) Jad.Scene.Camera).Speed = 3.0f;
	
			#endregion
	
			#region Scene creation
	
			// Load our scene
			Jad.Import.Load("particles");
	
			// Reference to some mesh objects we'll use later
			lightHandle01 = (JMeshObject) Jad.Scene.MeshObjects["lighthandle01"]; //NOTE: See the real source code for this tutorial, the wiki screwed this line
			lightHandle01.Pivot = new Vector3(0.0f, 2.0f, 0.0f);
			lightHandle02 = (JMeshObject) Jad.Scene.MeshObjects["lighthandle02"]; //NOTE: See the real source code for this tutorial, the wiki screwed this line
			lightHandle02.Pivot = new Vector3(0.0f, 2.0f, 0.0f);
	
			// Reference to the lights we'll use later
			omni01 = (JOmniLight) Jad.Scene.Lights["omni01"];
			omni01.Pivot = new Vector3(0.0f, 4.0f, 0.0f);
			omni02 = (JOmniLight) Jad.Scene.Lights["omni02"];
			omni02.Pivot = new Vector3(0.0f, 4.0f, 0.0f);
	
			#endregion
	
			#region Particle effects creation
	
			// Load the particle effects for the swinging lights from the "base/particles" folder
			JParticleEffect pFX01 = Jad.Scene.Particles.Create("pfx01", "test01");
			JParticleEffect pFX02 = Jad.Scene.Particles.Create("pfx02", "test01");
	
			// Attach these partcile effects to out lights. This way the particle effect will
			// inherit the light transformation
			pFX01.Attach(omni01);
			pFX02.Attach(omni02);
	
			// Create the particle effect for our candles. This time, instead of create one copy for each
			// candle, we instanciate one copy so the particle effect is calculated once for the four candles
			JParticleEffect pFXCandle = Jad.Scene.Particles.Create("pfx03", "candle_fire");
			// Set particle effect position
			pFXCandle.Position = new Vector3(1.144f, 1.98f, -6.52347f);
			// We want our particles to be emitted upwards but the default emission axis
			// is the particle system Z local axis so we have to rotate it around X so
			// the Z local axis points along the Y world axis
			pFXCandle.RotateX((float) (-Math.PI / 2));
			// Now add three instances with their respective positions. Keep in mind that
			// we can create instances only if the only thing that differences one
			// particle effect from another is the position
			pFXCandle.AddInstance(new Vector3(-1.237f, 1.98f, -6.52347f));
			pFXCandle.AddInstance(new Vector3(-4.45f, 2.21f, 3.47105f));
			pFXCandle.AddInstance(new Vector3(4.468f, 2.21f, 3.47105f));
	
			#endregion
	
			// 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 Action()
		{
			// Exit the app?
			if (Jad.Input.Keyboard.KeyPressed(Key.Escape)) return false;
	
			// Show/Hide help text
			if (Jad.Input.Keyboard.KeyTouch(Key.F1)) showHelp = !showHelp;
	
			// If we are recording...
			if (Jad.VideoRecorder.Enabled)
			{
				// ...and the camera animation reach the end, stop the recording
				if (pathCamera.Path.CurrentKey >= pathCamera.Path.NumberOfKeys)
				{
					// Disable video recording
					Jad.VideoRecorder.Enabled = false;
	
					// Restore first person camera
					Jad.Scene.Camera = userCamera;
	
					// Disable soft shadow volumes
					Jad.Scene.Shadows.ShadowMode = JShadowMode.None;
				}
			}
	
			// Start recording?
			if (Jad.Input.Keyboard.KeyTouch(Key.F5))
			{
				if (!Jad.VideoRecorder.Enabled)
				{
					// Enable soft shadow volumes
					Jad.Scene.Shadows.Stencil.DepthPass = true;
					Jad.Scene.Shadows.ShadowMode = JShadowMode.StencilVolume;
					Jad.Scene.Shadows.SoftShadows = true;
	
					// Init recording. The result will be a list of PNG images for each frame
					// This images will be places in the "screenshots" folder
					Jad.VideoRecorder.Init();
	
					// Save the current camera. It'll be restored later.
					userCamera = Jad.Scene.Camera as JCameraFirstPerson;

					// Set our travelling camera as the current camera
					Jad.Scene.Camera = pathCamera;
				}
			}
	
			// 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.KeyTouch(Key.G))
				Jad.Scene.ShowGizmos = !Jad.Scene.ShowGizmos;
	
			// Rotate the light and their handles that hang from the ceil. Because we attached
			// the particle effects to the lights, these will follow the light as expected
			float angle = Geometry.DegreeToRadian(30.0f * (float) Math.Sin(Jad.Timer.Time * 1.0f));
			lightHandle01.RotateX(angle);
			omni01.Angles = lightHandle01.Angles;
			lightHandle02.RotateZ(angle);
			omni02.Angles = lightHandle02.Angles;
	
			// Everything was right, continue
			return true;
		}
	
		/// <summary>
		/// Render method
		/// </summary>
		public override void Render()
		{
			// Prepare the scene to start the render
			Jad.Scene.Begin();
	
			// Render all the scene elements
			Jad.Scene.Render();
	
			// Do the post-production
			Jad.Scene.ProcessPostProduction();
	
			// Render various things of the scene (gizmos, axes, names,...)
			Jad.Scene.RenderMiscellaneous();
	
			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();
	
				if (Jad.VideoRecorder.Enabled)
					font.RenderLine(string.Format("Frame: {0} of {1}", pathCamera.Path.CurrentKey + 1, pathCamera.Path.NumberOfKeys), 0, JColor.White);
	
				else
				{
					font.RenderLine(Jad.Version + ". Press ESC to exit. Press G to Show/Hide Gizmos. F1 show/hide text", 0, JColor.Yellow);
					font.RenderLine("Press F5 to start video recording", 0, JColor.White);
					font.RenderLine(Jad.Video.Render.Stats.Fps + " FPS", 0, JColor.White);
				}
	
				// End fonts rendering
				Jad.Video.Fonts.End();
			}
	
			// End the scene
			Jad.Scene.End();
		}
	
		#endregion
	}
}

JMain.cs

#region Using directives
	
using System;
using System.IO;
	
#endregion
	
namespace Tutorial
{
	/// <summary>
	/// Class that holds the main method. It´s the application entry point
	/// </summary>
	public class JMain
	{
		#region Methods
	
		/// <summary>
		/// Application entry point
		/// </summary>
		[STAThreadAttribute]
		static void Main()
		{
			// Set the engine base directory (where the configuration.xml file is located)
			JadEngine.Core.JPath.ChangeDirectory();
	
			// Create a new file where we´ll write console output
			StreamWriter sw = new StreamWriter("out.txt");
	
			// Redirect console output to this file
			Console.SetOut(sw);
	
			// Create the application object
			JTutorial main = new JTutorial();
	
			// Start the application
			main.Start();
	
			// Close console output file
			sw.Close();
		}
	
		#endregion
	}
}

Last edited Jul 24, 2006 at 3:48 PM by Vicente, version 4

Comments

Vicente Jul 21, 2006 at 6:31 PM 
A remark about the tutorial, 2 lines are marked with the following comment:

"//NOTE: See the real source code for this tutorial, the wiki screwed this line"

That´s because the string used in the Jad.Scene.MeshObjects["X"] uses a character that the wiki has as reserved character (the _), so it took it out.

Be careful if you paste that code directly, that lines will crash.