- Main Page
- Packages
- Classes
- Files

- File List
- File Members

# D:/guillaume/guillara/3D/DXGfx/DXGfxLib/Water.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.Generic;
    00019 using System.Text;
    00020 using System.IO;
    00021 using System.Drawing;
    00022 using Microsoft.DirectX;
    00023 using Microsoft.DirectX.Direct3D;
    00024 using Microsoft.Samples.DirectX.UtilityToolkit;
    00025
    00026 namespace DXGfxLib
    00027 {
    00031     public class Water : TexturedPlane
    00032     {
    00036         private Texture bumpMap = null;
    00040                 private Matrix bumpMapMatrix = Matrix.Zero;
    00041
    00045         public Texture waterTexture = null;
    00046
    00047         public Plane reflectPlane;
    00048
    00049         public Water()
    00050         {
    00051         }
    00052
    00053         public Water(int width, int heigth, int numVertX, int numVertZ, string texturefile)
    00054         {
    00055             if (DXGfxManager.GetGlobalInstance().d3dDevice == null)
    00056             {
    00057                 throw new Exception("DXGfxManager.d3dDevice is null, creation of water is impossible without a valid device!");
    00058             }
    00059             Init(DXGfxManager.GetGlobalInstance().d3dDevice, width, heigth, numVertX, numVertZ, texturefile);
    00060         }
    00061
    00072         public Water(Device d3ddevice, int width, int heigth, int numVertX, int numVertZ, string texturefile)
    00073         {
    00074             Init(d3ddevice, width, heigth, numVertX, numVertZ, texturefile);
    00075         }
    00076
    00077         public override void Init(Device d3ddevice, int width, int heigth, int numVertX, int numVertZ, string texturefile)
    00078         {
    00079
    00080             base.Init(d3ddevice, width, heigth, numVertX, numVertZ, texturefile);
    00081
    00082             // First load our texture.
    00083             if (File.Exists(texturefile))
    00084             {
    00085                 waterTexture = ResourceCache.GetGlobalInstance().CreateTextureFromFile(d3ddevice, texturefile);
    00086             }
    00087             else
    00088             {
    00089                 throw new ArgumentException("File :" + texturefile + "doesn't not exist");
    00090             }
    00091
    00092             bumpMap = this.CreateBumpMap(d3ddevice, 256, 256, Format.V8U8);
    00093
    00094             reflectPlane = Microsoft.DirectX.Plane.FromPointNormal(new Vector3(0, 0, 0), new Vector3(0, 1, 0));
    00095         }
    00096
    00097         public override void LoadFromFile(Device d3ddevice, string fileName)
    00098         {
    00099             Init(d3ddevice, 2000, 2000, 10, 10, fileName);
    00100         }
    00101
    00108         public override void Update(Frustrum frustrum, double appTime, float elapsedTime)
    00109                 {
    00110             base.Update(frustrum, appTime, elapsedTime);
    00111
    00112                         // Setup the bump matrix
    00113                         // Min r is 0.04 if amplitude is 32 to miss temporal aliasing
    00114                         // Max r is 0.16 for amplitude is 8 to miss spatial aliasing
    00115                         float r = 0.04f;
    00116             bumpMapMatrix.M11 = r * (float)System.Math.Cos(appTime * 2.0f);
    00117             bumpMapMatrix.M12 = -r * (float)System.Math.Sin(appTime * 2.0f);
    00118             bumpMapMatrix.M21 = r * (float)System.Math.Sin(appTime * 2.0f);
    00119             bumpMapMatrix.M22 = r * (float)System.Math.Cos(appTime * 2.0f);
    00120
    00121             Matrix invMatView = Matrix.Invert(frustrum.matView);
    00122             Vector3 pos = MathUtil.ExtractPosition(invMatView);
    00123             Vector3 ypr = MathUtil.YawPitchRollFromMat(invMatView);
    00124
    00125             Matrix desiredWorldMat = Matrix.RotationYawPitchRoll(ypr.X, 0, 0);
    00126             desiredWorldMat.M41 = pos.X;
    00127             desiredWorldMat.M43 = pos.Y;
    00128
    00129             worldMat = desiredWorldMat;
    00130                 }
    00131
    00136         public override void Draw(Device d3ddevice)
    00137         {
    00138             // The way we built our water, it does look down, let's change that.
    00139             Matrix useMat = Matrix.Multiply(Matrix.RotationX((float)(Math.PI)), worldMat);
    00140             d3ddevice.SetTransform(TransformType.World, useMat);
    00141
    00142             // Set up texture stage 0's states for the bumpmap
    00143             d3ddevice.SetTexture(0, bumpMap);
    00144             d3ddevice.SamplerState[0].AddressU = TextureAddress.Clamp;
    00145             d3ddevice.SamplerState[0].AddressV = TextureAddress.Clamp;
    00146             d3ddevice.TextureState[0].BumpEnvironmentMaterial00 = bumpMapMatrix.M11;
    00147             d3ddevice.TextureState[0].BumpEnvironmentMaterial01 = bumpMapMatrix.M12;
    00148             d3ddevice.TextureState[0].BumpEnvironmentMaterial10 = bumpMapMatrix.M21;
    00149             d3ddevice.TextureState[0].BumpEnvironmentMaterial11 = bumpMapMatrix.M22;
    00150             d3ddevice.TextureState[0].ColorOperation = TextureOperation.BumpEnvironmentMap;
    00151             d3ddevice.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
    00152             d3ddevice.TextureState[0].ColorArgument2 = TextureArgument.Current;
    00153
    00154
    00155             d3ddevice.SetTexture(1, waterTexture);
    00156
    00157             d3ddevice.TextureState[1].ColorArgument1 = TextureArgument.TextureColor;
    00158             d3ddevice.TextureState[1].ColorOperation = TextureOperation.SelectArg1;
    00159
    00160                         // Set up projected texture coordinates
    00161                         // tu = (0.8x + 0.5z) / z
    00162                         // tv = (0.8y - 0.5z) / z
    00163                         Matrix mat = Matrix.Zero;
    00164                         mat.M11 = 0.8f; mat.M12 = 0.0f; mat.M13 = 0.0f;
    00165                         mat.M21 = 0.0f; mat.M22 = 0.8f; mat.M23 = 0.0f;
    00166                         mat.M31 = 0.5f; mat.M32 =-0.5f; mat.M33 = 1.0f;
    00167                         mat.M41 = 0.0f; mat.M42 = 0.0f; mat.M43 = 0.0f;
    00168
    00169             d3ddevice.Transform.Texture1 = mat;
    00170             d3ddevice.TextureState[1].TextureTransform = TextureTransform.Count3 | TextureTransform.Projected;
    00171             d3ddevice.TextureState[1].TextureCoordinateIndex = (int)TextureCoordinateIndex.CameraSpacePosition | 1;
    00172
    00173                         d3ddevice.VertexFormat = CustomVertex.PositionTextured.Format;
    00174             d3ddevice.SetTransform(TransformType.World, useMat);
    00175             originalMesh.DrawSubset(0);
    00176                         d3ddevice.SamplerState[0].AddressU = TextureAddress.Wrap;
    00177                         d3ddevice.SamplerState[0].AddressV = TextureAddress.Wrap;
    00178                         d3ddevice.TextureState[0].ColorOperation = TextureOperation.Modulate;
    00179                         d3ddevice.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
    00180                         d3ddevice.TextureState[0].ColorArgument2 = TextureArgument.Current;
    00181                         d3ddevice.TextureState[1].ColorOperation = TextureOperation.Disable;
    00182                 }
    00183
    00187                 private Texture CreateBumpMap(Device d3ddevice, int width, int height, Format bumpformat)
    00188                 {
    00189                         Texture bumpMapTexture = null;
    00190
    00191                         // Check if the device can create the format
    00192                         //                      if (Manager.CheckDeviceFormat(Caps.AdapterOrdinal, Caps.DeviceType, graphicsSettings.DisplayMode.Format, 0, ResourceType.Textures, bumpformat) == false)
    00193                         //                              return null;
    00194
    00195                         // Create the bumpmap texture
    00196                         bumpMapTexture = new Microsoft.DirectX.Direct3D.Texture(d3ddevice, width, height, 1, 0, bumpformat, Pool.Managed);
    00197
    00198                         int pitch;
    00199                         // Lock the surface and write in some bumps for the waves
    00200                         GraphicsStream dst = bumpMapTexture.LockRectangle(0, 0, out pitch);
    00201
    00202                         byte bumpUCoord, bumpVCoord;
    00203                         for (int y=0; y<height; y++)
    00204                         {
    00205                                 for (int x=0; x<width; x++)
    00206                                 {
    00207                                         float fx = x/(float)width - 0.5f;
    00208                                         float fy = y/(float)height - 0.5f;
    00209
    00210                                         float r = (float)System.Math.Sqrt(fx*fx + fy*fy);
    00211
    00212                     // 300 - 150 - 140
    00213                                         bumpUCoord  = (byte)(64 * (float)System.Math.Cos(1200.0f * r) * (float)System.Math.Exp(-r * 5.0f));
    00214                                         bumpUCoord += (byte)(32 * (float)System.Math.Cos(950.0f * (fx + fy)));
    00215                                         bumpUCoord += (byte)(16 * (float)System.Math.Cos(690.0f * (fx * 0.85f - fy)));
    00216
    00217                                         bumpVCoord  = (byte)(64 * (float)System.Math.Sin(1200.0f * r) * (float)System.Math.Exp(-r * 5.0f));
    00218                                         bumpVCoord += (byte)(32 * (float)System.Math.Sin(950.0f * (fx + fy)));
    00219                                         bumpVCoord += (byte)(16 * (float)System.Math.Sin(690.0f * (fx * 0.85f - fy)));
    00220
    00221                                         dst.Write(bumpUCoord);
    00222                                         dst.Write(bumpVCoord);
    00223                                 }
    00224                         }
    00225                         bumpMapTexture.UnlockRectangle(0);
    00226                         return bumpMapTexture;
    00227                 }
    00228     }
    00229 }