private void CreateIndexBuffer() { // Why 36 * sizeof(short) ? : See above there are 36 Indices * sizeof(short) : short = 16bits = 2 bytes _indexBuffer = new Buffer(_dxDevice, 36 * sizeof(short), ResourceUsage.Dynamic, BindFlags.IndexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); DataStream indexStream = _indexBuffer.Map(MapMode.WriteDiscard, MapFlags.None); indexStream.WriteRange(new short[] { 3,1,0, // Top Face 1 Triangle 1 2,1,3, // Triangle 2 0,5,4, // Front Face 2 Triangle 3 1,5,0, // Triangle 4 3,4,7, // Left Side Face 3 Triangle 5 0,4,3, // Triangle 6 1,6,5, // Right Side Face 4 Triangle 7 2,6,1, // Triangle 8 2,7,6, // Back Face 5 Triangle 9 3,7,2, // Triangle 10 6,4,5, // Bottom Face 6 Triangle 11 7,4,6, // Triangle 12 }); _indexBuffer.Unmap(); }
public static void DrawInstancedSpheres(GraphicsDeviceManager gdm, List <Matrix> instances) { Model sphere = WorldData.GetObject("sphereInstanced.mesh") as Model; D3D10.Buffer indexBuffer = sphere.MeshObj.GetDeviceIndexBuffer(); D3D10.Buffer vertextBuffer = sphere.MeshObj.GetDeviceVertexBuffer(0); Shader e = WorldData.GetObject("Instanced.fx") as Shader; EffectTechnique t = e.EffectObj.GetTechniqueByName("RenderInstanced"); InputLayout l = ShaderHelper.ConstructInputLayout(MeshInputElements10.PositionOnlyInstanced, t.GetPassByIndex(0).Description.Signature); BufferDescription bd = new BufferDescription(); bd.SizeInBytes = System.Runtime.InteropServices.Marshal.SizeOf(instances[0]) * instances.Count; bd.Usage = ResourceUsage.Dynamic; bd.CpuAccessFlags = CpuAccessFlags.Write; bd.BindFlags = BindFlags.VertexBuffer; D3D10.Buffer instanceData = new D3D10.Buffer(gdm.Direct3D10.Device, bd); DataStream ds = instanceData.Map(MapMode.WriteDiscard, SlimDX.Direct3D10.MapFlags.None); ds.Position = 0; ds.WriteRange(instances.ToArray()); instanceData.Unmap(); Game.Device.InputAssembler.SetInputLayout(l); Game.Device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertextBuffer, 16, 0), new VertexBufferBinding(instanceData, System.Runtime.InteropServices.Marshal.SizeOf(instances[0]), 0)); Game.Device.InputAssembler.SetIndexBuffer(indexBuffer, Format.R16_UInt, 0); Game.Device.InputAssembler.SetPrimitiveTopology(PrimitiveTopology.TriangleList); e.GetVar("WorldViewProj").AsMatrix().SetMatrix(Camera.ViewMatrix * Camera.ProjectionMatrix); t.GetPassByIndex(0).Apply(); Game.Device.DrawIndexedInstanced((sphere.Mesh3d.attrTable[0].FaceCount * 3), instances.Count, 0, 0, 0); //Game.Device.DrawIndexed((sphere.attrTable[0].FaceCount * 3) * 2, 0, 0); indexBuffer.Dispose(); vertextBuffer.Dispose(); sphere.Dispose(); }
// Create VertexBuffer private void CreateVertexBuffer() { // 8 * 32 WHY ? : 1 Float = 4bytes, so Vector4(floatX,floatY,floatZ,floatW) = 4 float = 16 bytes. // See above there are 8 vertices and each Vertex contain 2 * Vector4. Then 8 * (16 bytes + 16 bytes) = 8 * 32 // _vertexBuffer = new Buffer(_dxDevice, 8 * 32, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); /* vertexStream.WriteRange(new[] * { * // Color ((R)ed, (G)reen, (B)lue, (A)lpha) *Note Alpha used to blending (Transparency) * * // Position X Y Z W and Color R G B A * new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // First Square Vertex 1 (0) * new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Vertex 2 (1) * new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Vertex 3 (2) * new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Vertex 4 (3) * * new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // Second Square Vertex 5 (4) * new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // Vertex 6 (5) * new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // Vertex 7 (6) * new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f) // Vertex 8 (7) * });*/ var numVertices = 8; var numFaces = 12; _vertexBuffer = new Buffer(_dxDevice, numVertices * Vertex.Size, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); DataStream vertexStream = _vertexBuffer.Map(MapMode.WriteDiscard, MapFlags.None); vertexStream.WriteRange(new[] { new Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f), new Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f), new Vertex(1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f), new Vertex(1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f), new Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), new Vertex(1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f), new Vertex(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f), new Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f) }); _vertexBuffer.Unmap(); }
public void Update(KinectFrame frame, KinectCameraInfo cameraInfo) { if (!_initialized) { Init(frame, cameraInfo); } // update texture if (_imageTexture != null) { var imageRect = _imageTexture.Map(0, MapMode.WriteDiscard, MapFlags.None); var imageMap = frame.ImageMap; var imagePtr = 0; // need to convert from RGB24 to RGBA32 for (int v = 0; v < _yRes; v++) { for (int u = 0; u < _xRes; u++) { byte r = imageMap[imagePtr++]; byte g = imageMap[imagePtr++]; byte b = imageMap[imagePtr++]; byte a = 255; int argb = (a << 24) + (b << 16) + (g << 8) + r; imageRect.Data.Write(argb); } } _imageTexture.Unmap(0); } // update depth map if (_depthMapBuffer != null) { DataStream depthStream = _depthMapBuffer.Map(MapMode.WriteDiscard, MapFlags.None); depthStream.WriteRange(frame.DepthMap); _depthMapBuffer.Unmap(); } }
public override void Setup(Device device, ShaderLibrary shaderLibrary, string basePath) { this._MaterialLoader.Setup(device, basePath, this.Block.Material); string vertexShaderName; string pixelShaderName; var small = this.Block.HasBigVertices == false; if (this.Block.Mode == 4) { vertexShaderName = small ? "skinnedgeneraleyegloss" : "skinnedgeneraleyegloss8"; pixelShaderName = "skinnedgeneraleyegloss"; } else if (this.Block.Mode == 1) { vertexShaderName = small ? "skinnedgeneral" : "skinnedgeneral8"; pixelShaderName = "skinnedgeneralhair"; } else { vertexShaderName = small ? "skinnedgeneral" : "skinnedgeneral8"; pixelShaderName = "skinnedgeneral"; } if (this.Block.HasBigVertices == false) { this._ShaderLoader.Setup( device, shaderLibrary.GetVertexShaderData(vertexShaderName), shaderLibrary.GetFragmentShaderData(pixelShaderName), new[] { new InputElement("POSITION", 0, DXGI.Format.R32G32B32_Float, 0, 0, IC.PerVertexData, 0), new InputElement("TEXCOORD", 1, DXGI.Format.R8G8B8A8_UNorm, 12, 0, IC.PerVertexData, 0), new InputElement("TEXCOORD", 2, DXGI.Format.R8G8B8A8_UInt, 16, 0, IC.PerVertexData, 0), new InputElement("COLOR", 0, DXGI.Format.R8G8B8A8_UNorm, 0, 1, IC.PerVertexData, 0), new InputElement("COLOR", 1, DXGI.Format.R8G8B8A8_UNorm, 4, 1, IC.PerVertexData, 0), new InputElement("COLOR", 2, DXGI.Format.R8G8B8A8_UNorm, 8, 1, IC.PerVertexData, 0), new InputElement("TEXCOORD", 0, DXGI.Format.R32G32_Float, 12, 1, IC.PerVertexData, 0), }); var vertexBuffer = new Buffer(device, 20 * this.Block.VertexData0Small.Count, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); using (var stream = vertexBuffer.Map(MapMode.WriteDiscard, MapFlags.None)) { stream.WriteRange(this.Block.VertexData0Small.ToArray()); vertexBuffer.Unmap(); } this._VertexData0Buffer = vertexBuffer; } else { this._ShaderLoader.Setup( device, shaderLibrary.GetVertexShaderData(vertexShaderName), shaderLibrary.GetFragmentShaderData(pixelShaderName), new[] { new InputElement("POSITION", 0, DXGI.Format.R32G32B32_Float, 0, 0, IC.PerVertexData, 0), new InputElement("TEXCOORD", 1, DXGI.Format.R8G8B8A8_UNorm, 12, 0, IC.PerVertexData, 0), new InputElement("TEXCOORD", 2, DXGI.Format.R8G8B8A8_UNorm, 16, 0, IC.PerVertexData, 0), new InputElement("TEXCOORD", 3, DXGI.Format.R8G8B8A8_UInt, 20, 0, IC.PerVertexData, 0), new InputElement("TEXCOORD", 4, DXGI.Format.R8G8B8A8_UInt, 24, 0, IC.PerVertexData, 0), new InputElement("COLOR", 0, DXGI.Format.R8G8B8A8_UNorm, 0, 1, IC.PerVertexData, 0), new InputElement("COLOR", 1, DXGI.Format.R8G8B8A8_UNorm, 4, 1, IC.PerVertexData, 0), new InputElement("COLOR", 2, DXGI.Format.R8G8B8A8_UNorm, 8, 1, IC.PerVertexData, 0), new InputElement("TEXCOORD", 0, DXGI.Format.R32G32_Float, 12, 1, IC.PerVertexData, 0), }); var vertexBuffer = new Buffer(device, 28 * this.Block.VertexData0Big.Count, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); using (var stream = vertexBuffer.Map(MapMode.WriteDiscard, MapFlags.None)) { stream.WriteRange(this.Block.VertexData0Big.ToArray()); vertexBuffer.Unmap(); } this._VertexData0Buffer = vertexBuffer; } // Extra Buffer { var extraBuffer = new Buffer(device, 20 * this.Block.VertexData1.Count, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); using (var stream = extraBuffer.Map(MapMode.WriteDiscard, MapFlags.None)) { stream.WriteRange(this.Block.VertexData1.ToArray()); extraBuffer.Unmap(); } this._VertexData1Buffer = extraBuffer; } // Index Buffer { var indexBuffer = new Buffer(device, 2 * this.Block.Faces.Count, ResourceUsage.Dynamic, BindFlags.IndexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); using (var stream = indexBuffer.Map(MapMode.WriteDiscard, MapFlags.None)) { stream.WriteRange(this.Block.Faces.ToArray()); indexBuffer.Unmap(); } this._IndexBuffer = indexBuffer; } // Constant Buffer { this._VertexShaderConstantBuffer1 = new ConstantBuffer <VertexShaderGlobals>(device); this._PixelShaderConstantBuffer0 = new ConstantBuffer <PixelShaderGlobalConstants>(device); this._PixelShaderConstantBuffer1 = new ConstantBuffer <PixelShaderInstanceConstants>(device); this._PixelShaderConstantBuffer2 = new ConstantBuffer <PixelShaderMaterialConstants>(device); this._PixelShaderConstantBuffer4 = new ConstantBuffer <PixelShaderBooleans>(device); } }
// Create VertexBuffer private void CreateVertexBuffer() { // 8 * 32 WHY ? : 1 Float = 4bytes, so Vector4(floatX,floatY,floatZ,floatW) = 4 float = 16 bytes. // See above there are 8 vertices and each Vertex contain 2 * Vector4. Then 8 * (16 bytes + 16 bytes) = 8 * 32 // _vertexBuffer = new Buffer(_dxDevice, 8 * 32, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); /* vertexStream.WriteRange(new[] { // Color ((R)ed, (G)reen, (B)lue, (A)lpha) *Note Alpha used to blending (Transparency) // Position X Y Z W and Color R G B A new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // First Square Vertex 1 (0) new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Vertex 2 (1) new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Vertex 3 (2) new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Vertex 4 (3) new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // Second Square Vertex 5 (4) new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // Vertex 6 (5) new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // Vertex 7 (6) new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f) // Vertex 8 (7) });*/ var numVertices = 8; var numFaces = 12; _vertexBuffer = new Buffer(_dxDevice, numVertices * Vertex.Size, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); DataStream vertexStream = _vertexBuffer.Map(MapMode.WriteDiscard, MapFlags.None); vertexStream.WriteRange(new[] { new Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f), new Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f), new Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f), new Vertex( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f), new Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), new Vertex( 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f), new Vertex( 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f), new Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f) }); _vertexBuffer.Unmap(); }
public void Reset() { Destroy(); using (Factory factory = new Factory()) { SlimDX.Direct3D10.Device.CreateWithSwapChain(factory.GetAdapter(0), DriverType.Hardware, DeviceCreationFlags.None, new SwapChainDescription { BufferCount = 2, IsWindowed = true, OutputHandle = renderTarget.Handle, Usage = Usage.RenderTargetOutput, SampleDescription = new SampleDescription(1, 0), ModeDescription = new ModeDescription(renderTarget.Width, renderTarget.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm) }, out device, out swapChain); } using (Texture2D backBuffer = Texture2D.FromSwapChain <Texture2D>(swapChain, 0)) { renderTargetView = new RenderTargetView(device, backBuffer); } device.OutputMerger.SetTargets(renderTargetView); bsd = new BlendStateDescription(); bsd.AlphaBlendOperation = BlendOperation.Add; bsd.BlendOperation = BlendOperation.Add; bsd.SourceBlend = BlendOption.SourceAlpha; bsd.DestinationBlend = BlendOption.InverseSourceAlpha; bsd.SourceAlphaBlend = BlendOption.SourceAlpha; bsd.DestinationAlphaBlend = BlendOption.InverseSourceAlpha; bsd.SetWriteMask(0, ColorWriteMaskFlags.All); bsd.IsAlphaToCoverageEnabled = true; bsd.SetBlendEnable(0, true); device.OutputMerger.BlendSampleMask = -1; device.OutputMerger.BlendFactor = new Color4(0, 0, 0, 0); device.OutputMerger.BlendState = BlendState.FromDescription(device, bsd); viewport = new Viewport(0, 0, renderTarget.Width, renderTarget.Height); device.Rasterizer.SetViewports(viewport); BufferDescription bd = new BufferDescription(4 * Marshal.SizeOf(typeof(Vertex)), ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); vertexBuffer = new SlimDX.Direct3D10.Buffer(device, bd); Vertex[] vertexData = new Vertex[4]; vertexData[0].pos = new Vector3(-1, -1, 0); vertexData[0].texCoord = new Vector2(0, 1); vertexData[1].pos = new Vector3(-1, 1, 0); vertexData[1].texCoord = new Vector2(0, 0); vertexData[2].pos = new Vector3(1, -1, 0); vertexData[2].texCoord = new Vector2(1, 1); vertexData[3].pos = new Vector3(1, 1, 0); vertexData[3].texCoord = new Vector2(1, 0); DataStream vbStream = vertexBuffer.Map(MapMode.WriteDiscard, SlimDX.Direct3D10.MapFlags.None); vbStream.WriteRange(vertexData); vertexBuffer.Unmap(); System.Reflection.Assembly thisExe; thisExe = System.Reflection.Assembly.GetExecutingAssembly(); Stream file = thisExe.GetManifestResourceStream("DirectXEmu.Video.Shaders.SimpleRender.fx"); effect = Effect.FromStream(device, file, "fx_4_0"); file.Close(); EffectTechnique technique; if (smoothOutput) { technique = effect.GetTechniqueByName("RenderSmooth"); } else { technique = effect.GetTechniqueByName("Render"); } pass = technique.GetPassByIndex(0); ShaderSignature signature = pass.Description.Signature; inputLayout = new InputLayout(device, signature, new[] { new InputElement("POSITION", 0, SlimDX.DXGI.Format.R32G32B32_Float, 0, 0), new InputElement("TEXCOORD", 0, SlimDX.DXGI.Format.R32G32_Float, 12, 0) }); texture = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.Write, Format = Format.R8G8B8A8_UNorm, Height = imageScaler.ResizedY, Width = imageScaler.ResizedX, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Dynamic }); textureView = new ShaderResourceView(device, texture); effect.GetVariableByName("tex2d").AsResource().SetResource(textureView); LoadCharSheet(); }
/// <summary> /// Writes data from the array to the index buffer. /// </summary> /// <typeparam name="T">The type of data in the index buffer - int or short.</typeparam> /// <param name="data">Array to copy the data from</param> /// <param name="startIndex">Starting index in the array at which to start copying from</param> /// <param name="elementCount">Number of indices to write</param> /// <param name="offsetInBytes">Offset from the start of the index buffer at which to start writing at</param> /// <param name="writeOptions">Write options, used only if this is a dynamic buffer. None, discard, no overwrite</param> /// <remarks>See implementors for exceptions that may occur.</remarks> public override void SetData <T>(T[] data, int startIndex, int elementCount, int offsetInBytes, DataWriteOptions writeOptions) { if (_buffer == null || _buffer.Disposed) { throw new ObjectDisposedException(GetType().Name); } //Throws null or out of range exception D3D10Helper.CheckArrayBounds(data, startIndex, elementCount); int numBytes = MemoryHelper.SizeOf <T>(); int ibSize = base.IndexCount * ((base.IndexFormat == IndexFormat.SixteenBits) ? 2 : 4); int dataSize = elementCount * numBytes; if (offsetInBytes < 0 || offsetInBytes > ibSize) { throw new ArgumentOutOfRangeException("offsetInBytes", "Byte offset is out of range."); } if ((offsetInBytes + dataSize) > ibSize) { throw new ArgumentOutOfRangeException("data", "Byte offset and the number of elements to write will cause a buffer overflow."); } bool usesStaging = false; if (base.BufferUsage == ResourceUsage.Static || writeOptions == DataWriteOptions.None) { CreateStaging(); usesStaging = true; } try { if (usesStaging) { using (SDX.DataStream ds = _staging.Map(D3D.MapMode.Write, D3D.MapFlags.None)) { ds.Position = offsetInBytes; ds.WriteRange <T>(data, startIndex, elementCount); _staging.Unmap(); //If we're writing to the entire IB just copy the whole thing if (offsetInBytes == 0 && startIndex == 0 && dataSize == ibSize) { _graphicsDevice.CopyResource(_staging, _buffer); } else { D3D.ResourceRegion region = new D3D.ResourceRegion(); region.Left = offsetInBytes; region.Right = offsetInBytes + dataSize; region.Front = region.Top = 0; region.Back = region.Bottom = 1; _graphicsDevice.CopySubresourceRegion(_staging, 0, region, _buffer, 0, offsetInBytes, 0, 0); } } } else { D3D.MapMode mode = (writeOptions == DataWriteOptions.Discard) ? D3D.MapMode.WriteDiscard : D3D.MapMode.WriteNoOverwrite; using (SDX.DataStream ds = _buffer.Map(mode, D3D.MapFlags.None)) { ds.Position = offsetInBytes; ds.WriteRange <T>(data, startIndex, elementCount); _buffer.Unmap(); } } } catch (Exception e) { throw new TeslaException("Error writing to D3D10 Buffer.", e); } }
/// <summary> /// Sets the vertex data from an array source. /// </summary> /// <typeparam name="T">The type of data in the vertex buffer.</typeparam> /// <param name="data">Array that holds the vertex data</param> /// <param name="startIndex">Starting index of the element in the array at which to start copying from</param> /// <param name="elementCount">Number of elements to copy from the array</param> /// <param name="offsetInBytes">Offset in bytes from the beginning of the vertex buffer to the data.</param> /// <param name="vertexStride">Size of an element in bytes.</param> /// <param name="writeOptions">Writing options for the vertex buffer. None, discard, or no overwrite.</param> /// <exception cref="System.ObjectDisposedException">Thrown if Dispose() has been called.</exception> /// <exception cref="System.InvalidOperationException">Thrown if the write options are incompatible with the resource usage of the buffer.</exception> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the data's vertex stride is too small, the offset in bytes is out of range, /// or the byte offset and number of elements to write will cause overflow.</exception> /// <exception cref="Tesla.Core.TeslaException">Thrown if there was an error writing to the buffer.</exception> public override void SetData <T>(T[] data, int startIndex, int elementCount, int offsetInBytes, int vertexStride, DataWriteOptions writeOptions) { if (_buffer == null || _buffer.Disposed) { throw new ObjectDisposedException(GetType().Name); } //Throw an error if an invalid write options is specified if (base.BufferUsage == ResourceUsage.Static && writeOptions != DataWriteOptions.None) { throw new InvalidOperationException("Can only specify write options other than DataWriteOptions.None for dynamic vertex buffers."); } //Check if array bounds are out of range D3D10Helper.CheckArrayBounds(data, startIndex, elementCount); VertexDeclaration vertexDecl = base.VertexDeclaration; int vertexCount = base.VertexCount; int vbSize = vertexCount * vertexDecl.VertexStride; int elemSize = MemoryHelper.SizeOf <T>(); int dataSize = elementCount * elemSize; int vertexStep = vertexStride; if (vertexStride != 0) { vertexStep -= elemSize; if (vertexStep < 0) { throw new ArgumentOutOfRangeException("vertexStride", "Vertex stride is too small for requested data size."); } //If we get this far, we need to make sure the actual bytes we're going to look at matches up, //since we can grab specific parts of a vertex and not the whole thing if (elementCount > 1) { dataSize = ((elementCount - 1) * vertexStep) + dataSize; } } //Prevent overflow out of range errors if ((offsetInBytes < 0) || (offsetInBytes > vbSize)) { throw new ArgumentOutOfRangeException("offsetInbytes", "Byte offset is out of range."); } if ((offsetInBytes + dataSize) > vbSize) { throw new ArgumentOutOfRangeException("data", "Byte offset and elements to write will cause in buffer overflow."); } //Create scratch buffer, if it hasn't been created already bool usesStaging = false; if (base.BufferUsage == ResourceUsage.Static || writeOptions == DataWriteOptions.None) { CreateStaging(); usesStaging = true; } try { if (usesStaging) { //If we're not going to be writing the entire vertex structure, we need to first //copy the contents of the affected vertex data into the staging buffer if (vertexStep != vertexStride) { //If we're going to be working with all the verts, no need to copy a subresource region if (offsetInBytes == 0 && startIndex == 0 && vertexCount == data.Length) { _graphicsDevice.CopyResource(_buffer, _staging); } else { D3D.ResourceRegion region = new D3D.ResourceRegion(); region.Left = offsetInBytes; region.Right = offsetInBytes + dataSize; region.Front = region.Top = 0; region.Back = region.Bottom = 1; _graphicsDevice.CopySubresourceRegion(_buffer, 0, region, _staging, 0, offsetInBytes, 0, 0); } } using (SDX.DataStream ds = _staging.Map(D3D.MapMode.Read, D3D.MapFlags.None)) { //If the step is zero, that means we're dealing with the entire vertex and not a subset of it if (vertexStep == 0) { ds.Position = offsetInBytes; ds.WriteRange <T>(data, startIndex, elementCount); } else { ds.Position = offsetInBytes; int count = elementCount - 1; int index = startIndex; ds.Write <T>(data[index++]); while (count > 0) { ds.Position += vertexStep; ds.Write <T>(data[index]); count--; index++; } } _staging.Unmap(); //If we're writing to the entire VB just copy the whole thing if (offsetInBytes == 0 && startIndex == 0 && dataSize == vbSize) { _graphicsDevice.CopyResource(_staging, _buffer); } else { D3D.ResourceRegion region = new D3D.ResourceRegion(); region.Left = offsetInBytes; region.Right = offsetInBytes + dataSize; region.Front = region.Top = 0; region.Back = region.Bottom = 1; _graphicsDevice.CopySubresourceRegion(_staging, 0, region, _buffer, 0, offsetInBytes, 0, 0); } } //Dynamic vertex buffers only } else { D3D.MapMode mode = (writeOptions == DataWriteOptions.Discard) ? D3D.MapMode.WriteDiscard : D3D.MapMode.WriteNoOverwrite; using (SDX.DataStream ds = _buffer.Map(mode, D3D.MapFlags.None)) { //If the step is zero, that means we're dealing with the entire vertex and not a subset of it if (vertexStep == 0) { ds.Position = offsetInBytes; ds.WriteRange <T>(data, startIndex, elementCount); } else { ds.Position = offsetInBytes; int count = elementCount - 1; int index = startIndex; ds.Write <T>(data[index++]); while (count > 0) { ds.Position += vertexStep; ds.Write <T>(data[index]); count--; index++; } } _buffer.Unmap(); } } } catch (Exception e) { throw new TeslaException("Error reading from D3D10 Buffer.", e); } }
/// <summary> /// Convienence method that takes an array of data buffers, each representing a vertex element (in the order /// declared by the vertex declaration), and writes all of the data to the vertex buffer. The buffers must match /// the vertex declaration as well as the byte sizes of each element and all be of the same length. /// </summary> /// <param name="data">Array of databuffers representing the vertex data.</param> /// <exception cref="System.ArgumentNullException">Thrown if data is null.</exception> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the number of buffers do not match the number /// of vertex elements, or if the number of vertices in each buffer does not match the vertex count, /// or if there is a byte size mismatch of any kind.</exception> public override void SetInterleavedData(params DataBuffer[] data) { if (_buffer == null || _buffer.Disposed) { throw new ObjectDisposedException(GetType().Name); } if (data == null || data.Length == 0) { throw new ArgumentNullException("data", "Data cannot be null."); } VertexDeclaration vertexDecl = base.VertexDeclaration; int vertexCount = base.VertexCount; //Verify if the incoming vertex streams match right with the supplied vertex declaration VertexElement[] elems = vertexDecl.VertexElements; if (elems.Length != data.Length) { throw new ArgumentOutOfRangeException("data", "Number of vertex streams do not match up the number of declared vertex elements."); } int totalSizeInBytes = 0; int vertexStride = 0; for (int i = 0; i < data.Length; i++) { DataBuffer db = data[i]; VertexElement element = elems[i]; int vSizeInBytes = db.ElementSizeInBytes; int vCount = db.SizeInBytes / vSizeInBytes; if (vCount != vertexCount) { throw new ArgumentOutOfRangeException("data", "Vertex count mismatch, buffers must be of same length."); } if (vSizeInBytes != VertexDeclaration.GetVertexElementSize(element.Format)) { throw new ArgumentOutOfRangeException("data", "Supplied vertex buffer element size mismatch with actual vertex element size."); } totalSizeInBytes += db.SizeInBytes; vertexStride += vSizeInBytes; db.Position = 0; } if (totalSizeInBytes != vertexDecl.VertexStride * vertexCount) { throw new ArgumentOutOfRangeException("data", "Vertex data must match the size of the vertex buffer in bytes!"); } CreateStaging(); try { using (SDX.DataStream interleaved = _staging.Map(D3D.MapMode.Write, D3D.MapFlags.None)) { byte[] vertex = new byte[vertexStride]; for (int i = 0; i < vertexCount; i++) { int startIndex = 0; for (int j = 0; j < data.Length; j++) { DataBuffer db = data[j]; int elementSize = db.ElementSizeInBytes; db.Get(vertex, startIndex, elementSize); startIndex += elementSize; } interleaved.Write(vertex, 0, vertexStride); } _staging.Unmap(); //Copy entire resource _graphicsDevice.CopyResource(_staging, _buffer); } } catch (Exception e) { throw new TeslaException("Error writing to D3D10 Buffer.", e); } }
private void render() { clearRenderTargets(); RenderObjects objs = extractor.Scene; extractor.ExtractNext = true; foreach (var obj in objs.Objs) { using (MeshResource mesh = (MeshResource)obj.Key.Acquire()) { device.InputAssembler.SetPrimitiveTopology(mesh.primitiveTopology); device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(mesh.vertexBuffer, mesh.elementSize, 0)); device.InputAssembler.SetVertexBuffers(1, new VertexBufferBinding(instanceBuffer, 16 * 4 + sizeof(float), 0)); if (mesh.indexed) { device.InputAssembler.SetIndexBuffer(mesh.indexBuffer, mesh.indexFormat, 0); } foreach (var matRes in obj.Value) { using (MaterialResource material = (MaterialResource)matRes.Key.Acquire()) { var vertData = from RenderObject mat in matRes.Value select new { model = mat.model * objs.Camera, mat.frame }; var matArray = vertData.ToArray(); /* * for(int i = 0; i < posArray.Length; ++i) * { * posArray[i].model = posArray[i].model * objs.Camera; * } * */ using (var effect = material.AcquireEffect()) { foreach (var constant in material.Constants) { dynamic value = constant.Value; var variable = effect.Value.GetVariableByName(constant.Key); if (value is float) { variable.AsScalar().Set(value); } else if (value is Vector2 || value is Vector3 || value is Vector4) { variable.AsVector().Set(value); } /* * switch ((string)constant.Value.GetType().Name) * { * default: * throw new NotSupportedException("Constant type: " + constant.Value.GetType() + ) * break; * } * .*/ } //effect.Value.GetVariableByName("frameDimensions").AsVector().Set(material.frameDimensions); using (var textures = material.AcquireTextures()) { foreach (var texture in textures) { effect.Value.GetVariableByName(texture.Key).AsResource().SetResource(texture.Value.texture); } EffectTechnique tech = effect.Value.GetTechniqueByName("Full"); for (int i = 0; i < tech.Description.PassCount; ++i) { EffectPass pass = tech.GetPassByIndex(i); List <InputElement> elems = new List <InputElement>(mesh.inputLayout); elems.AddRange(elem); using (InputLayout layout = new InputLayout(device, pass.Description.Signature, elems.ToArray())) { device.InputAssembler.SetInputLayout(layout); for (int j = 0; j < matArray.Length; j += InstanceCount) { int curInstanceCount; using (DataStream stream = instanceBuffer.Map(MapMode.WriteDiscard, SlimDX.Direct3D10.MapFlags.None)) { curInstanceCount = Math.Min(InstanceCount, matArray.Length - j); for (int k = 0; k < curInstanceCount; ++k) { stream.Write <Matrix>(matArray[j + k].model); stream.Write <float>(matArray[j + k].frame); } // stream.WriteRange<Matrix>(posArray, j, curInstanceCount); instanceBuffer.Unmap(); } pass.Apply(); if (mesh.indexed) { device.DrawIndexedInstanced(mesh.indexCount, curInstanceCount, 0, 0, 0); } else { device.DrawInstanced(mesh.elementCount, curInstanceCount, 0, 0); } } } } } } } } } } calcPerformanceMetrics(); renderDebugOutput(); swapChain.Present(0, PresentFlags.None); }