/// <summary> /// Gets the back buffer data. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="subimage">The rectangle representing the sub-image. Null value means to grab the whole back buffer.</param> /// <param name="data">The data.</param> /// <param name="startIndex">The starting index in the array.</param> /// <param name="elementCount">The number of eleemnts to read</param> public override void GetBackBufferData <T>(Rectangle?subimage, T[] data, int startIndex, int elementCount) { if (_backBuffer.Disposed) { throw new ObjectDisposedException(GetType().Name); } //Throws null or out of range exception D3D10Helper.CheckArrayBounds(data, startIndex, elementCount); //Calc subresource dimensions int width = _presentParams.BackBufferWidth; int height = _presentParams.BackBufferHeight; //Get the dimensions, if its null we copy the whole texture Rectangle rect; if (subimage.HasValue) { rect = subimage.Value; CheckRectangle(rect, width, height); } else { rect = new Rectangle(0, 0, width, height); } if (elementCount > rect.Width * rect.Height) { throw new ArgumentOutOfRangeException("elementCount", "Number of elements to read is larger than contained in the specified subimage."); } //Create staging CreateStaging(); try { int row = rect.Y; int col = rect.X; int rectWidth = rect.Width; int rectHeight = rect.Height; //Do resource copy if (row == 0 && col == 0 && rectWidth == width && rectHeight == height) { _graphicsDevice.CopyResource(_backBuffer, _staging); } else { D3D.ResourceRegion region = new D3D.ResourceRegion(); region.Left = col; region.Right = col + rectWidth; region.Top = row; region.Bottom = row + rectHeight; region.Front = 0; region.Back = 1; _graphicsDevice.CopySubresourceRegion(_backBuffer, 0, region, _staging, 0, col, row, 0); } SDX.DataRectangle dataRect = _staging.Map(0, D3D.MapMode.Read, D3D.MapFlags.None); SDX.DataStream ds = dataRect.Data; int elemSize = MemoryHelper.SizeOf <T>(); int formatSize = D3D10Helper.FormatSize(_presentParams.BackBufferFormat); int pitch = dataRect.Pitch; int index = startIndex; int count = elementCount; //Compute the actual number of elements based on the format size and the element size we're copying the bytes into int actWidth = (int)MathHelper.Floor(rectWidth * (formatSize / elemSize)); //Go row by row for (int i = row; i < height; i++) { //Set the position ds.Position = (i * pitch) + (col * formatSize); //Break if we've run out of elements or on the very last row that isn't complete if (count <= 0) { break; } else if (count < actWidth) { ds.ReadRange <T>(data, index, count); break; } //Otherwise, copy the whole row and increment/decrement the index and count ds.ReadRange <T>(data, index, actWidth); index += actWidth; count -= actWidth; } _staging.Unmap(0); } catch (Exception e) { throw new TeslaException("Error reading from D3D10 Texture2D.", e); } }
/// <summary> /// Sets the data to the texture. /// </summary> /// <typeparam name="T">Type of data in the array.</typeparam> /// <param name="data">Array of data.</param> /// <param name="mipLevel">Mip map level to access.</param> /// <param name="subimage">Rectangle representing a sub-image of the 2D texture to write to, if null the whole image is written to.</param> /// <param name="startIndex">Starting index in the array to start reading from.</param> /// <param name="elementCount">Number of elements to write.</param> /// <exception cref="System.ArgumentException">Thrown if the format byte size of the type to write and the texture do not match, the subimage /// dimensions are invalid, or if the total size to write and the total size in the texture do not match</exception> /// <exception cref="Tesla.Core.TeslaException">Thrown if there was an error writing to the texture.</exception> public override void SetData <T>(T[] data, int mipLevel, Math.Rectangle?subimage, int startIndex, int elementCount) { if (_texture2D == null || _texture2D.Disposed) { throw new ObjectDisposedException(GetType().Name); } if (mipLevel < 0 || mipLevel >= _mipCount) { throw new ArgumentOutOfRangeException("mipLevel", String.Format("Mip level is out of range. Must be between 0 and {0}.", _mipCount.ToString())); } //Throws null or out of range exception D3D10Helper.CheckArrayBounds(data, startIndex, elementCount); int formatSize = D3D10Helper.FormatSize(base.Format); SurfaceFormat format = base.Format; int elemSize = MemoryHelper.SizeOf <T>(); CheckSizes(formatSize, elemSize); //Calc subresource dimensions int width = (int)MathHelper.Max(1, base.Width >> mipLevel); int height = (int)MathHelper.Max(1, base.Height >> mipLevel); //Get the dimensions, if its null we copy the whole texture Rectangle rect; if (subimage.HasValue) { rect = subimage.Value; CheckRectangle(rect, ref width, ref height); } else { rect = new Rectangle(0, 0, width, height); } CheckTotalSize(base.Format, ref formatSize, ref width, ref height, elemSize, elementCount); //Create staging for non-dynamic textures if (_usage == D3D.ResourceUsage.Default) { CreateStaging(); } try { if (_usage == D3D.ResourceUsage.Default) { SDX.DataRectangle dataRect = _staging.Map(mipLevel, D3D.MapMode.Write, D3D.MapFlags.None); SDX.DataStream ds = dataRect.Data; int row = rect.Y; int col = rect.X; int pitch = dataRect.Pitch; int index = startIndex; int count = elementCount; //Compute the actual number of elements based on the format size and the element size we're copying the bytes into int actWidth = (int)MathHelper.Floor(width * (formatSize / elemSize)); //Go row by row for (int i = row; i < height; i++) { //Set the position ds.Position = (i * pitch) + (col * formatSize); //Break if we've run out of elements or on the very last row that isn't complete if (count <= 0) { break; } else if (count < actWidth) { ds.WriteRange <T>(data, index, count); break; } //Otherwise, copy the whole row and increment/decrement the index and count ds.WriteRange <T>(data, index, actWidth); index += actWidth; count -= actWidth; } _staging.Unmap(mipLevel); //Do resource copy if (format == SurfaceFormat.DXT1 || format == SurfaceFormat.DXT3 || format == SurfaceFormat.DXT5) { _graphicsDevice.CopyResource(_staging, _texture2D); } else { D3D.ResourceRegion region = new D3D.ResourceRegion(); region.Left = col; region.Right = col + width; region.Top = row; region.Bottom = row + height; region.Front = 0; region.Back = 1; _graphicsDevice.CopySubresourceRegion(_staging, mipLevel, region, _texture2D, mipLevel, col, row, 0); } } else { SDX.DataRectangle dataRect = _texture2D.Map(mipLevel, D3D.MapMode.WriteDiscard, D3D.MapFlags.None); SDX.DataStream ds = dataRect.Data; int row = rect.Y; int col = rect.X; int pitch = dataRect.Pitch; int index = startIndex; int count = elementCount; //Compute the actual number of elements based on the format size and the element size we're copying the bytes into int actWidth = (int)MathHelper.Floor(width * (formatSize / elemSize)); //Go row by row for (int i = row; i < height; i++) { //Set the position ds.Position = (i * pitch) + (col * formatSize); //Break if we've run out of elements or on the very last row that isn't complete if (count <= 0) { break; } else if (count < actWidth) { ds.WriteRange <T>(data, index, count); break; } //Otherwise, copy the whole row and increment/decrement the index and count ds.WriteRange <T>(data, index, actWidth); index += actWidth; count -= actWidth; } _texture2D.Unmap(mipLevel); } } catch (Exception e) { throw new TeslaException("Error writing to D3D10 Texture2D.", e); } }
//creation functions public Terrain(int q, StreamReader file) { quadSize = q; //loading effect effect = ResourceManager.mainManager.LoadEffect("Resources\\Effects\\Terrain.fx", ResourceManager.mainManager.GetDefaultEffectPool()); technique = effect.GetTechniqueByName("Render"); pass = technique.GetPassByIndex(0); //creating layout D3D10.InputElement[] elements = new SlimDX.Direct3D10.InputElement[1]; elements[0] = new SlimDX.Direct3D10.InputElement("TEXCOORD", 0, SlimDX.DXGI.Format.R32G32_Float, 0, 0, D3D10.InputClassification.PerVertexData, 0); layout = new SlimDX.Direct3D10.InputLayout(Game.gameClass.GetDevice(), elements, pass.Description.Signature); //loading texture D3D10.ImageLoadInformation load = new SlimDX.Direct3D10.ImageLoadInformation(); load.BindFlags = D3D10.BindFlags.ShaderResource; load.CpuAccessFlags = D3D10.CpuAccessFlags.None; load.MipLevels = 1; load.Usage=D3D10.ResourceUsage.Default; load.OptionFlags = D3D10.ResourceOptionFlags.None; load.FilterFlags = D3D10.FilterFlags.Point; load.Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm; normalTexture = D3D10.Texture2D.FromFile(Game.gameClass.GetDevice(), Path.GetDirectoryName(Game.gameClass.GetLvLFilePath()) + "\\normals.png", load); Globals.mapSize = normalTexture.Description.Width; if (Game.gameClass.GetEngineState() != EngineState.play) { D3D10.Texture2DDescription desc = new SlimDX.Direct3D10.Texture2DDescription(); desc.ArraySize = 1; desc.BindFlags = D3D10.BindFlags.None; desc.CpuAccessFlags = D3D10.CpuAccessFlags.Write; desc.Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm; desc.Height = Globals.mapSize; desc.Width = Globals.mapSize; desc.Usage = D3D10.ResourceUsage.Staging; desc.MipLevels = 1; SlimDX.DXGI.SampleDescription sampleDescription = new SlimDX.DXGI.SampleDescription(); sampleDescription.Count = 1; sampleDescription.Quality = 0; desc.SampleDescription = sampleDescription; normalTexUpdater = new SlimDX.Direct3D10.Texture2D(Game.gameClass.GetDevice(), desc); normalData = normalTexUpdater.Map(0, D3D10.MapMode.Write, D3D10.MapFlags.DoNotWait); normalTexUpdater.Unmap(0); } // LoadTextureArray(file); //setting up vertices and creating vertex buffer LoadVertexInfo(); CreateVertexBuffer(); //constant buffer variables effect.GetVariableByName("mapSize").AsScalar().Set(Globals.mapSize); using(D3D10.ShaderResourceView normalView=new D3D10.ShaderResourceView(Game.gameClass.GetDevice(),normalTexture)) effect.GetVariableByName("normalMap").AsResource().SetResource(normalView); // using (D3D10.ShaderResourceView texturesView = new D3D10.ShaderResourceView(Game.gameClass.GetDevice(), textures)) // effect.GetVariableByName("textures").AsResource().SetResource(texturesView); orientations=effect.GetVariableByName("orientations").AsVector(); // effect.GetVariableByName("texCoordMul").AsScalar().Set(TextureInfo.texCoordMul); heightMul = effect.GetVariableByName("heightMul").AsScalar(); heightMul.Set(Globals.heightMultiplier); //handles edit mode if (Game.gameClass.GetEngineState() != EngineState.play) { techniqueEdit = effect.GetTechniqueByName("Edit"); passEdit = techniqueEdit.GetPassByIndex(0); mousePick = effect.GetVariableByName("mousePick").AsVector(); pickOptions = effect.GetVariableByName("pickOpt").AsVector(); } Globals.SetMap(map); }