- Main Page
- Packages
- Classes
- Files

- File List
- File Members

# D:/guillaume/guillara/3D/DXGfx/Backup/Editor/3DView.cs

Go to the documentation of this file.

    00001 //BSD License
    00002 //DXGfx® - http://www.eteractions.com
    00003 //Copyright (c) 2005
    00004 //by Guillaume Randon
    00005 //Permission is hereby granted, free of charge, to any person obtaining a copy of this software
    00006 //and associated documentation files (the "Software"), to deal in the Software without restriction,
    00007 //including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
    00008 //and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
    00009 //subject to the following conditions:
    00010 //The above copyright notice and this permission notice shall be included in all copies or substantial
    00011 //portions of the Software.
    00012 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
    00013 //INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
    00014 //AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    00015 //DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    00016 //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    00017 using System;
    00018 using System.Collections;
    00019 using System.Collections.Generic;
    00020 using System.Text;
    00021 using System.Diagnostics;
    00022 using Microsoft.DirectX;
    00023 using Microsoft.DirectX.Direct3D;
    00024 using Microsoft.Samples.DirectX.UtilityToolkit;
    00025 using Microsoft.DirectX.DirectSound;
    00026 using DXGfxLib;
    00027 using Game;
    00028 using System.ComponentModel;
    00029 using System.Drawing;
    00030 using System.Windows.Forms;
    00031
    00032 namespace Editor
    00033 {
    00034     public partial class TDView : UserControl, IFrameworkCallback, IDeviceCreation
    00035     {
    00036         // Variables
    00037         private Framework sampleFramework = null; // Framework for samples
    00038         private Microsoft.DirectX.Direct3D.Font statsFont = null; // Font for drawing text
    00039         private Sprite textSprite = null; // Sprite for batching text calls
    00040         //private ModelViewerCamera camera = new ModelViewerCamera(); // A model viewing camera
    00041         private FreeCamera camera = new FreeCamera();
    00042         private bool isHelpShowing = true; // If true, renders the UI help text
    00043         private Dialog hud = null; // dialog for standard controls
    00044         private Dialog missionUi = null;
    00045         private Matrix worldCenter;
    00046
    00047         // HUD Ui Control constants
    00048         private const int ToggleFullscreen = 1;
    00049         private const int ToggleReference = 3;
    00050         private const int ChangeDevice = 4;
    00051
    00052         // DXGfxLib related variables
    00053         public OutDoorScene outdoorScene;
    00054         //private Matrix computedViewMat;
    00055         private const int MissionText = 1;
    00056
    00057         // Wordl related variables
    00058         private Tiger tiger;
    00059         private Vegetals veg;
    00060         private double lastAIUpdate = 0.0f;
    00061         private Hashtable worldEntities = new Hashtable();
    00062
    00063         // Need a soundDevice in order to be able to play sounds.
    00064         private Microsoft.DirectX.DirectSound.Device soundDevice = null;
    00065
    00066         // We want to be aware of the Mediator, as UI can impact what is drawn and click on scene can impact UI.
    00067         private Mediator mediator = null;
    00068
    00069         public bool play = false;
    00070
    00071         private StateBlock defaultState = null;
    00072
    00073         VertexBuffer pickRayVBuff = null;
    00074
    00078         private bool readyToGo = false;
    00079
    00080         public bool ReadyToGo
    00081         {
    00082             get { return readyToGo; }
    00083             set { readyToGo = value; }
    00084         }
    00085
    00086         public TDView()
    00087         {
    00088             InitializeComponent();
    00089
    00090             sampleFramework = new Framework();
    00091
    00092             // Create dialogs
    00093             hud = new Dialog(sampleFramework);
    00094             missionUi = new Dialog(sampleFramework);
    00095
    00096             DXGfxManager.GetGlobalInstance().Init(sampleFramework);
    00097
    00098
    00099
    00100             sampleFramework.Disposing += new EventHandler(OnDestroyDevice);
    00101             sampleFramework.DeviceLost += new EventHandler(OnLostDevice);
    00102             sampleFramework.DeviceCreated += new DeviceEventHandler(OnCreateDevice);
    00103             sampleFramework.DeviceReset += new DeviceEventHandler(OnResetDevice);
    00104
    00105             sampleFramework.SetWndProcCallback(new WndProcCallback(OnMsgProc));
    00106
    00107             sampleFramework.SetCallbackInterface(this);
    00108
    00109             InitializeApplication();
    00110
    00111             sampleFramework.SetWindow(this, this, this, true);
    00112
    00113             InitSound();
    00114
    00115             sampleFramework.CreateDevice(0, true, Framework.DefaultSizeWidth, Framework.DefaultSizeHeight, this);
    00116         }
    00117
    00118         public void LetItRun()
    00119         {
    00120             sampleFramework.MainLoop();
    00121         }
    00122
    00126         public void InitializeApplication()
    00127         {
    00128             int y = 10;
    00129
    00130             // Initialize the HUD
    00131             Microsoft.Samples.DirectX.UtilityToolkit.Button fullScreen = hud.AddButton(ToggleFullscreen, "Toggle full screen", 35, y, 125, 22);
    00132             Microsoft.Samples.DirectX.UtilityToolkit.Button toggleRef = hud.AddButton(ToggleReference, "Toggle reference (F3)", 35, y += 24, 125, 22);
    00133             Microsoft.Samples.DirectX.UtilityToolkit.Button changeDevice = hud.AddButton(ChangeDevice, "Change Device (F2)", 35, y += 24, 125, 22);
    00134             // Hook the button events for when these items are clicked
    00135             fullScreen.Click += new EventHandler(OnFullscreenClicked);
    00136             toggleRef.Click += new EventHandler(OnRefClicked);
    00137             changeDevice.Click += new EventHandler(OnChangeDevicClicked);
    00138
    00139             // Our own UI
    00140             Microsoft.Samples.DirectX.UtilityToolkit.Button missionText = missionUi.AddButton(MissionText, "Salut!!", 0, 0, 170, 120);
    00141             missionText.Click += new EventHandler(missionText_Click);
    00142         }
    00143
    00148         public void SetMediator(Mediator mediator)
    00149         {
    00150             this.mediator = mediator;
    00151         }
    00152
    00159         public bool IsDeviceAcceptable(Microsoft.DirectX.Direct3D.Caps caps, Format adapterFormat, Format backBufferFormat, bool windowed)
    00160         {
    00162             //if (caps.PixelShaderVersion < new Version(1, 1))
    00163             //    return false;
    00164
    00166             //if (!Manager.CheckDeviceFormat(caps.AdapterOrdinal, caps.DeviceType, adapterFormat,
    00167             //    Usage.QueryPostPixelShaderBlending, ResourceType.Textures, backBufferFormat))
    00168             //    return false;
    00169
    00170             return true;
    00171         }
    00172
    00181         public void ModifyDeviceSettings(DeviceSettings settings, Microsoft.DirectX.Direct3D.Caps caps)
    00182         {
    00183 //            // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW
    00184 //            // then switch to SWVP.
    00185 //            if ((!caps.DeviceCaps.SupportsHardwareTransformAndLight) ||
    00186 //                (caps.VertexShaderVersion < new Version(1, 1)))
    00187 //            {
    00188 //                settings.BehaviorFlags = CreateFlags.SoftwareVertexProcessing;
    00189 //            }
    00190 //            else
    00191 //            {
    00192 //                settings.BehaviorFlags = CreateFlags.HardwareVertexProcessing;
    00193 //            }
    00194
    00195 //            // This application is designed to work on a pure device by not using
    00196 //            // any get methods, so create a pure device if supported and using HWVP.
    00197 //            if ((caps.DeviceCaps.SupportsPureDevice) &&
    00198 //                ((settings.BehaviorFlags & CreateFlags.HardwareVertexProcessing) != 0))
    00199 //                settings.BehaviorFlags |= CreateFlags.PureDevice;
    00200
    00201 //            // Debugging vertex shaders requires either REF or software vertex processing
    00202 //            // and debugging pixel shaders requires REF.
    00203 //#if(DEBUG_VS)
    00204 //            if (settings.DeviceType != DeviceType.Reference )
    00205 //            {
    00206 //                settings.BehaviorFlags &= ~CreateFlags.HardwareVertexProcessing;
    00207 //                settings.BehaviorFlags |= CreateFlags.SoftwareVertexProcessing;
    00208 //            }
    00209 //#endif
    00210 //#if(DEBUG_PS)
    00211               //settings.DeviceType = DeviceType.Reference;
    00212 //#endif
    00213
    00214 //            // For the first device created if its a REF device, optionally display a warning dialog box
    00215 //            if (settings.DeviceType == DeviceType.Reference)
    00216 //            {
    00217 //                Utility.DisplaySwitchingToRefWarning(sampleFramework, "Sample");
    00218 //            }
    00219         }
    00220
    00228         private void OnCreateDevice(object sender, DeviceEventArgs e)
    00229         {
    00230             // Initialize the stats font
    00231             statsFont = ResourceCache.GetGlobalInstance().CreateFont(e.Device, 15, 0, FontWeight.Bold, 1, false, CharacterSet.Default,
    00232                 Precision.Default, FontQuality.Default, PitchAndFamily.FamilyDoNotCare | PitchAndFamily.DefaultPitch
    00233                 , "Arial");
    00234
    00235             // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the
    00236             // shader debugger. Debugging vertex shaders requires either REF or software vertex
    00237             // processing, and debugging pixel shaders requires REF.  The
    00238             // ShaderFlags.Force*SoftwareNoOptimizations flag improves the debug experience in the
    00239             // shader debugger.  It enables source level debugging, prevents instruction
    00240             // reordering, prevents dead code elimination, and forces the compiler to compile
    00241             // against the next higher available software target, which ensures that the
    00242             // unoptimized shaders do not exceed the shader model limitations.  Setting these
    00243             // flags will cause slower rendering since the shaders will be unoptimized and
    00244             // forced into software.  See the DirectX documentation for more information about
    00245             // using the shader debugger.
    00246             ShaderFlags shaderFlags = ShaderFlags.NotCloneable;
    00247 #if(DEBUG_VS)
    00248             shaderFlags |= ShaderFlags.ForceVertexShaderSoftwareNoOptimizations;
    00249 #endif
    00250 #if(DEBUG_PS)
    00251             shaderFlags |= ShaderFlags.ForcePixelShaderSoftwareNoOptimizations;
    00252 #endif
    00253
    00254             // Before everything let's notify the DXGfxManager
    00255             DXGfxManager.GetGlobalInstance().OnCreateDevice(sender, e);
    00256
    00257             // Setup the camera's view parameters
    00258             camera.SetViewParameters(new Vector3(0.0f, 0.0f, -5.0f), Vector3.Empty);
    00259
    00260             pickRayVBuff = new VertexBuffer(e.Device, CustomVertex.PositionOnly.StrideSize * 2, Usage.Dynamic, CustomVertex.PositionOnly.Format, Pool.SystemMemory);
    00261         }
    00262
    00269         private void OnDestroyDevice(object sender, EventArgs e)
    00270         {
    00271         }
    00272
    00280         private void OnLostDevice(object sender, EventArgs e)
    00281         {
    00282             if (outdoorScene != null)
    00283             {
    00284                 outdoorScene.CleanOnLostDevice();
    00285             }
    00286
    00287             if (textSprite != null)
    00288             {
    00289                 textSprite.Dispose();
    00290                 textSprite = null;
    00291             }
    00292         }
    00293
    00301         private void OnResetDevice(object sender, DeviceEventArgs e)
    00302         {
    00303             SurfaceDescription desc = e.BackBufferDescription;
    00304             // Create a sprite to help batch calls when drawing many lines of text
    00305             textSprite = new Sprite(e.Device);
    00306
    00307             // Setup the camera's projection parameters
    00308             float aspectRatio = (float)desc.Width / (float)desc.Height;
    00309             camera.SetProjectionParameters((float)Math.PI / 4, aspectRatio, 0.1f, 1000.0f);
    00310             camera.SetViewParameters(new Vector3(0.0f, 5.0f, -30.0f), new Vector3(0.0f, 0.0f, 0.0f));
    00311             camera.IsPositionMovementEnabled = true;
    00312
    00313             DXGfxManager.GetGlobalInstance().OnDeviceReset(sender, e);
    00314
    00315             // Setup UI locations
    00316             hud.SetLocation(desc.Width - 170, 0);
    00317             hud.SetSize(170, 170);
    00318
    00319             // Scene call
    00320             if (outdoorScene != null)
    00321             {
    00322                 outdoorScene.DeviceChanged(e.Device);
    00323             }
    00324             missionUi.SetLocation(0, desc.Height - 120);
    00325             missionUi.SetSize(170, 120);
    00326         }
    00327
    00334         public void OnFrameMove(Microsoft.DirectX.Direct3D.Device device, double appTime, float elapsedTime)
    00335         {
    00336             // Update the camera's position based on user input
    00337             camera.FrameMove(elapsedTime);
    00338
    00339             // If we want object to move we have to use the camera worldmatrix!
    00340             //if (mediator.selectedNode != null)
    00341             //{
    00342             //    mediator.selectedNode.WorldMat = camera.WorldMatrix;
    00343             //}
    00344             // Let's update our tiger
    00345             double tmp = appTime - lastAIUpdate;
    00346
    00347             if (play)
    00348             {
    00349                 DXGfxManager.GetGlobalInstance().CurrentInputHandler.FrameMove(elapsedTime);
    00350                 DXGfxManager.GetGlobalInstance().CallEvaluation(appTime, elapsedTime);
    00351             }
    00352             //if (tmp > 10)
    00353             //{
    00354             //tiger.UpdateAI(appTime, elapsedTime);
    00355             //tiger.UpdateIA(elapsedTime, appTime);
    00356             //lastAIUpdate = appTime;
    00357             //}
    00358
    00359             //if (tiger.mission.missionCompleted)
    00360             //{
    00361             //    missionUi.GetButton(MissionText).SetText("Mission Completed!!");
    00362             //}
    00363             //switch (tiger.currentState)
    00364             //{
    00365             //    case State.Bois:
    00366             //        missionUi.GetButton(MissionText).SetText("Bois!!");
    00367             //        break;
    00368             //    case State.Dort:
    00369             //        missionUi.GetButton(MissionText).SetText("Dort!!");
    00370             //        break;
    00371             //    case State.Explore:
    00372             //        missionUi.GetButton(MissionText).SetText("Explore!!");
    00373             //        break;
    00374             //    case State.Fuit:
    00375             //        missionUi.GetButton(MissionText).SetText("Fuit!!");
    00376             //        break;
    00377             //    case State.Mange:
    00378             //        missionUi.GetButton(MissionText).SetText("Mange!!");
    00379             //        break;
    00380             //    default:
    00381             //        missionUi.GetButton(MissionText).SetText("Default!!");
    00382             //        break;
    00383             //}
    00384         }
    00385
    00392         protected override void OnPaint(PaintEventArgs e)
    00393         {
    00394             if(sampleFramework==null)
    00395                 return;
    00396             if(sampleFramework.Device==null)
    00397                 return;
    00398             Render(sampleFramework.Device, 0, 0);
    00399         }
    00400
    00401         protected override void OnPaintBackground(PaintEventArgs e)
    00402         {
    00403             // Just don't do anything !! base.OnPaintBackground(e);
    00404         }
    00405
    00412         public void OnFrameRender(Microsoft.DirectX.Direct3D.Device device, double appTime, float elapsedTime)
    00413         {
    00414             Render(device, appTime, elapsedTime);
    00415         }
    00416
    00417         private void Render(Microsoft.DirectX.Direct3D.Device device, double appTime, float elapsedTime)
    00418         {
    00419             // Clear the render target and the zbuffer and return
    00420             device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, 0x00424B79, 1.0f, 0);
    00421
    00422             bool beginSceneCalled = false;
    00423
    00424             if (defaultState == null)
    00425             {
    00426                 defaultState = new StateBlock(device, StateBlockType.All);
    00427                 defaultState.Capture();
    00428             }
    00429
    00430             defaultState.Apply();
    00431
    00432
    00433
    00434             if (outdoorScene == null)
    00435             {
    00436                 return;
    00437             }
    00438
    00439             // Get the world matrix
    00440             //Matrix worldMatrix = worldCenter * camera.WorldMatrix;
    00441             //computedViewMat = Matrix.Multiply(camera.WorldMatrix, camera.ViewMatrix);
    00442             Camera tmpCamera = null;
    00443             if (play)
    00444             {
    00445                 tmpCamera = DXGfxManager.GetGlobalInstance().CurrentCamera;
    00446             }
    00447             else
    00448             {
    00449                 tmpCamera = camera;
    00450             }
    00451
    00452
    00453             outdoorScene.Update(device, tmpCamera.ViewMatrix, tmpCamera.ProjectionMatrix, appTime, elapsedTime);
    00454
    00455
    00456             outdoorScene.RenderScene(device, outdoorScene.currentFrustrum);
    00457         }
    00458
    00459         public void InitSound()
    00460         {
    00461             soundDevice = new Microsoft.DirectX.DirectSound.Device();
    00462             soundDevice.SetCooperativeLevel(this.sampleFramework.Window.Handle, CooperativeLevel.Priority);
    00463         }
    00464
    00469         private void RenderText()
    00470         {
    00471             TextHelper txtHelper = new TextHelper(statsFont, textSprite, 15);
    00472
    00473             // Output statistics
    00474             txtHelper.Begin();
    00475             txtHelper.SetInsertionPoint(5, 5);
    00476             txtHelper.SetForegroundColor(System.Drawing.Color.Yellow);
    00477             txtHelper.DrawTextLine(sampleFramework.FrameStats);
    00478             txtHelper.DrawTextLine(sampleFramework.DeviceStats);
    00479
    00480             txtHelper.SetForegroundColor(System.Drawing.Color.White);
    00481
    00482             txtHelper.End();
    00483         }
    00484
    00491         public void OnKeyEvent(object sender, System.Windows.Forms.KeyEventArgs e)
    00492         {
    00493             switch (e.KeyCode)
    00494             {
    00495                 case System.Windows.Forms.Keys.F1:
    00496                     isHelpShowing = !isHelpShowing;
    00497                     break;
    00498             }
    00499         }
    00500
    00501         protected override void OnMouseDoubleClick(MouseEventArgs e)
    00502         {
    00503             base.OnMouseDoubleClick(e);
    00504
    00505             WorldLocation destinationLocation = new WorldLocation();
    00506
    00507             Vector2 point = new Vector2(e.X, e.Y);
    00508
    00509             Vector3 rayO; Vector3 rayD;
    00510
    00511             // Some work to do on the Viewport!!
    00512             Viewport viewport = sampleFramework.Device.Viewport;
    00513             viewport.Width = this.Width;
    00514             viewport.Height = this.Height;
    00515
    00516             if (play)
    00517             {
    00518                 DXGfxManager.GetGlobalInstance().height = this.Height;
    00519                 DXGfxManager.GetGlobalInstance().width = this.Width;
    00520                 DXGfxManager.GetGlobalInstance().CurrentInputHandler.OnMouseDoubleClick(e);
    00521             }
    00522             else
    00523             {
    00524                 MathUtil.RayFromScreenPos(viewport, camera.ProjectionMatrix, camera.ViewMatrix, point, out rayO, out rayD);
    00525                 List<SceneObject> theList = new List<SceneObject>();
    00526
    00527                 bool foundnothing = true;
    00528
    00529                 if (outdoorScene.Intersect(rayO, rayD, ref theList))
    00530                 {
    00531                     foreach (SceneObject obj in theList)
    00532                     {
    00533                         // TODO : Do we want the objet that we have selected to be selected in the editor?
    00534                     }
    00535                 }
    00536
    00537                 if (foundnothing)
    00538                 {
    00539                     // TODO : If no object is selected maybe we want the selected object to be put on ground where we have clicked.
    00540                     Vector3 clickedPosition = outdoorScene.PickEnvironmentPosition(viewport, camera.ProjectionMatrix, camera.ViewMatrix, point);
    00541
    00542                     if (mediator != null)
    00543                     {
    00544                         SceneNode selectedNode = mediator.selectedNode;
    00545
    00546                         if (selectedNode != null)
    00547                         {
    00548                             selectedNode.Position = clickedPosition;
    00549                         }
    00550                     }
    00551                 }
    00552
    00553                 // Let's put values in the pickRayVBuff
    00554                 CustomVertex.PositionOnly[] points = new CustomVertex.PositionOnly[2];
    00555                 points[0].Position = new Vector3(-10, -10, -10);
    00556                 points[1].Position = new Vector3(10, 10, 10);
    00557
    00558                 GraphicsStream stm = pickRayVBuff.Lock(0, 0, 0);
    00559                 stm.Write(points);
    00560                 pickRayVBuff.Unlock();
    00561             }
    00562         }
    00563
    00568         protected override void WndProc(ref Message m)
    00569         {
    00570             base.WndProc(ref m);
    00571
    00572             bool noFurtherProcessing = false;
    00573
    00574             OnMsgProc(m.HWnd,
    00575                 (Microsoft.Samples.DirectX.UtilityToolkit.NativeMethods.WindowMessage)m.Msg,
    00576                 m.WParam, m.LParam, ref noFurtherProcessing);
    00577         }
    00578
    00584         public IntPtr OnMsgProc(IntPtr hWnd, NativeMethods.WindowMessage msg, IntPtr wParam, IntPtr lParam, ref bool noFurtherProcessing)
    00585         {
    00586             // Give the dialog a chance to handle the message first
    00587             noFurtherProcessing = hud.MessageProc(hWnd, msg, wParam, lParam);
    00588             if (noFurtherProcessing)
    00589                 return IntPtr.Zero;
    00590
    00591             noFurtherProcessing = missionUi.MessageProc(hWnd, msg, wParam, lParam);
    00592             if (noFurtherProcessing)
    00593                 return IntPtr.Zero;
    00594
    00595             // Pass all remaining windows messages to camera so it can respond to user input
    00596             if (play)
    00597             {
    00598                 DXGfxManager.GetGlobalInstance().CurrentInputHandler.HandleMessages(hWnd, msg, wParam, lParam);
    00599             }
    00600             else
    00601             {
    00602                 camera.HandleMessages(hWnd, msg, wParam, lParam);
    00603             }
    00604
    00605             return IntPtr.Zero;
    00606         }
    00607
    00608         #region App Idle Events
    00610         public void OnApplicationIdle(object sender, EventArgs e)
    00611         {
    00612             while (AppStillIdle)
    00613             {
    00614                 // Render a frame during idle time (no messages are waiting)
    00615                 sampleFramework.Render3DEnvironment();
    00616             }
    00617         }
    00619         private bool AppStillIdle
    00620         {
    00621             get
    00622             {
    00623                 NativeMethods.Message msg;
    00624                 return !NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
    00625             }
    00626         }
    00627         #endregion
    00628
    00629         void missionText_Click(object sender, EventArgs e)
    00630         {
    00631             missionUi.GetButton(MissionText).SetText("Button Clicked!!");
    00632         }
    00633
    00635         private void OnChangeDevicClicked(object sender, EventArgs e)
    00636         {
    00637             sampleFramework.ShowSettingsDialog(!sampleFramework.IsD3DSettingsDialogShowing);
    00638         }
    00639
    00641         private void OnFullscreenClicked(object sender, EventArgs e)
    00642         {
    00643             sampleFramework.ToggleFullscreen();
    00644         }
    00645
    00647         private void OnRefClicked(object sender, EventArgs e)
    00648         {
    00649             sampleFramework.ToggleReference();
    00650         }
    00651     }
    00652 }