private void GenerateTargetMips() { for (int i = 0; i < _targetsToMipMapCount; i++) { RenderTargetBinding binding = _targetsToMipMap[i]; //Gen cube mips if (binding.IsRenderTargetCube) { RenderTargetCube rcube = binding.RenderTargetCube; D3D10Helper.CheckDisposed(rcube); if (rcube.MipCount > 1) { D3D10TextureCubeImplementation impl = rcube.Implementation as D3D10TextureCubeImplementation; _graphicsDevice.GenerateMips(impl.D3D10ShaderResourceView); } //Gen 2D tex mips } else { RenderTarget2D r2d = binding.RenderTarget2D; D3D10Helper.CheckDisposed(r2d); if (r2d.MipCount > 1) { D3D10Texture2DImplementation impl = r2d.Implementation as D3D10Texture2DImplementation; _graphicsDevice.GenerateMips(impl.D3D10ShaderResourceView); } } } }
/// <summary> /// Creates a new render target Cube implementation. All render targets are themselves textures. /// </summary> /// <param name="size">Size of the target (width/height are the same)</param> /// <param name="genMipMaps">True if mipmaps should be generated</param> /// <param name="format">Surface format</param> /// <param name="depthFormat">Depth format. For Multi-RenderTarget (MRT) usage, the depth buffer from the first render target /// set on the device will be used for all proceeding targets assigned.</param> /// <param name="multiSampleCount">Multisample count</param> /// <param name="usage">The target usage.</param> /// <returns>Render target Cube implementation</returns> public TextureCubeImplementation CreateRenderTargetCubeImplementation(int size, bool genMipMaps, SurfaceFormat format, DepthFormat depthFormat, int multiSampleCount, RenderTargetUsage usage) { D3D10TextureCubeImplementation impl = new D3D10TextureCubeImplementation(_renderer, size, genMipMaps, format, depthFormat, multiSampleCount, usage); SetGraphicsID(impl); return(impl); }
/// <summary> /// Creates a new texture cube implementation. /// </summary> /// <param name="size">Size (width/height) of the cube texture</param> /// <param name="genMipmap">True if mipmaps should be generated</param> /// <param name="format">Surface format</param> /// <param name="data">DataBuffer to populate from, if null an empty texture is generated.</param> /// <returns> /// Texture cube implementation /// </returns> public TextureCubeImplementation CreateTextureCubeImplementation(int size, bool genMipmap, SurfaceFormat format, DataBuffer[] data) { D3D10TextureCubeImplementation impl = new D3D10TextureCubeImplementation(_renderer, size, genMipmap, format, data); SetGraphicsID(impl); return(impl); }
/// <summary> /// Flushes the collection's state to the device, only textures that have been /// changed since the last draw call will get sent. /// </summary> internal void FlushState() { //Return if we haven't even touched these states, so we don't have to loop over them. if (!_shortCircuitUpdate) { return; } for (int i = 0; i < _maxTextures; i++) { //If state is dirty, grab the contents and send to the device if (_dirtyMark[i]) { //Clear the dirty bit _dirtyMark[i] = false; D3D.ShaderResourceView shaderResource = null; Texture value = _textures[i]; //Get shader resource if (value != null) { D3D10Helper.CheckDisposed(value); switch (value.Dimensions) { case TextureDimensions.One: D3D10Texture1DImplementation impl1D = value.Implementation as D3D10Texture1DImplementation; shaderResource = impl1D.D3D10ShaderResourceView; break; case TextureDimensions.Two: D3D10Texture2DImplementation impl2D = value.Implementation as D3D10Texture2DImplementation; shaderResource = impl2D.D3D10ShaderResourceView; break; case TextureDimensions.Three: D3D10Texture3DImplementation impl3D = value.Implementation as D3D10Texture3DImplementation; shaderResource = impl3D.D3D10ShaderResourceView; break; case TextureDimensions.Cube: D3D10TextureCubeImplementation implCube = value.Implementation as D3D10TextureCubeImplementation; shaderResource = implCube.D3D10ShaderResourceView; break; } } //Set shader resource (or null) if (_vertexTex) { _graphicsDevice.VertexShader.SetShaderResource(shaderResource, i); } else { _graphicsDevice.PixelShader.SetShaderResource(shaderResource, i); } } } _shortCircuitUpdate = false; }
public void SetRenderTargets(RenderTargetBinding[] targets) { D3D10Helper.CheckDisposed(_graphicsDevice); if (targets == null || targets.Length == 0) { //Clear targets ClearTargets(); //Set the swapchain's targets to the device, unbinding the current ones SetBackBufferTargets(); //Generate mip maps of previously bounded targets GenerateTargetMips(); } else { //If we have a larger array than the max targets possible, throw an exception if (targets.Length > _currentRenderTargets.Length) { throw new ArgumentOutOfRangeException("Cannot bind more than 8 targets at a time."); } //Clear targets ClearTargets(); D3D.RenderTargetView rtv; D3D.DepthStencilView dsv = null; DepthFormat depthFormat = DepthFormat.None; int width = 0; int height = 0; int samples = 0; int pixelDepth = 0; for (int i = 0; i < targets.Length; i++) { RenderTargetBinding binding = targets[i]; RenderTargetUsage usage = RenderTargetUsage.DiscardContents; if (binding.IsRenderTargetCube) { D3D10TextureCubeImplementation cubeImpl = binding.RenderTargetCube.Implementation as D3D10TextureCubeImplementation; D3D10Helper.CheckDisposed(cubeImpl); rtv = cubeImpl.GetRenderTargetView(binding.CubeMapFace); usage = cubeImpl.TargetUsage; if (i == 0) { width = cubeImpl.Size; height = cubeImpl.Size; dsv = cubeImpl.D3D10DepthStencilView; depthFormat = cubeImpl.DepthFormat; samples = cubeImpl.MultiSampleCount; pixelDepth = D3D10Helper.FormatSize(cubeImpl.Format); } else { if (cubeImpl.Size != width || cubeImpl.Size != height || cubeImpl.MultiSampleCount != samples || D3D10Helper.FormatSize(cubeImpl.Format) != pixelDepth) { throw new ArgumentException("All render target dimensions must match."); } } } else { D3D10Texture2DImplementation texImpl = binding.RenderTarget2D.Implementation as D3D10Texture2DImplementation; D3D10Helper.CheckDisposed(texImpl); rtv = texImpl.D3D10RenderTargetVew; usage = texImpl.TargetUsage; if (i == 0) { width = texImpl.Width; height = texImpl.Height; dsv = texImpl.D3D10DepthStencilView; depthFormat = texImpl.DepthFormat; samples = texImpl.MultiSampleCount; pixelDepth = D3D10Helper.FormatSize(texImpl.Format); } else { if (texImpl.Width != width || texImpl.Height != height || texImpl.MultiSampleCount != samples || D3D10Helper.FormatSize(texImpl.Format) != pixelDepth) { throw new ArgumentException("All render target dimensions, sample count, and bit depth must match."); } } } //Set the targets to the arrays, after we're done processing we set them all at once _currentRenderTargets[i] = binding; _views[i] = rtv; _currentRenderTargetCount++; //Check usage, if we're using a target that isn't preserve contents, //then we clear the target. if (usage != RenderTargetUsage.PreserveContents) { _graphicsDevice.ClearRenderTargetView(rtv, new SlimDX.Color4(1.0f, 0, 0, 0)); if (i == 0 && dsv != null) { D3D.DepthStencilClearFlags flags = D3D.DepthStencilClearFlags.Depth; if (depthFormat == DepthFormat.Depth24Stencil8) { flags |= D3D.DepthStencilClearFlags.Stencil; } _graphicsDevice.ClearDepthStencilView(dsv, flags, 1.0f, 0); } } } //Bind targets if (dsv != null) { _graphicsDevice.OutputMerger.SetTargets(dsv, _views); } else { _graphicsDevice.OutputMerger.SetTargets(_views); } //Generate mip maps of previously bounded targets GenerateTargetMips(); //Note: What if a user binds a target here that was previously bound, //is generating mip maps on a bound target ok? I don't know if //a user would even want to do that... } }
/// <summary> /// Clears the active targets, or back buffer if there are none. /// </summary> /// <param name="options"></param> /// <param name="color"></param> /// <param name="depth"></param> /// <param name="stencil"></param> public void ClearTargets(ClearOptions options, Color color, float depth, int stencil) { D3D10Helper.CheckDisposed(_graphicsDevice); SlimDX.Color4 sc; D3D10Helper.Convert(ref color, out sc); if (_currentRenderTargetCount == 0 && _activeBackBuffer != null) { D3D10Helper.CheckDisposed(_activeBackBuffer); if (_activeBackBuffer.D3D10DepthStencilView != null) { if (((options & ClearOptions.Depth) == ClearOptions.Depth) && ((options & ClearOptions.Stencil) == ClearOptions.Stencil)) { _graphicsDevice.ClearDepthStencilView(_activeBackBuffer.D3D10DepthStencilView, D3D.DepthStencilClearFlags.Depth | D3D.DepthStencilClearFlags.Stencil, depth, (byte)stencil); } else if ((options & ClearOptions.Depth) == ClearOptions.Depth) { _graphicsDevice.ClearDepthStencilView(_activeBackBuffer.D3D10DepthStencilView, D3D.DepthStencilClearFlags.Depth, depth, (byte)stencil); } else if ((options & ClearOptions.Stencil) == ClearOptions.Stencil) { _graphicsDevice.ClearDepthStencilView(_activeBackBuffer.D3D10DepthStencilView, D3D.DepthStencilClearFlags.Stencil, depth, (byte)stencil); } } if ((_activeBackBuffer.D3D10RenderTargetView != null) && ((options & ClearOptions.Target) == ClearOptions.Target)) { _graphicsDevice.ClearRenderTargetView(_activeBackBuffer.D3D10RenderTargetView, sc); } } else { for (int i = 0; i < _currentRenderTargetCount; i++) { RenderTargetBinding binding = _currentRenderTargets[i]; D3D.DepthStencilView dsv = null; D3D.RenderTargetView rtv = null; if (!binding.IsRenderTargetCube) { D3D10Texture2DImplementation impl2D = binding.RenderTarget2D.Implementation as D3D10Texture2DImplementation; D3D10Helper.CheckDisposed(impl2D); dsv = impl2D.D3D10DepthStencilView; rtv = impl2D.D3D10RenderTargetVew; } else { D3D10TextureCubeImplementation implcube = binding.RenderTargetCube.Implementation as D3D10TextureCubeImplementation; D3D10Helper.CheckDisposed(implcube); dsv = implcube.D3D10DepthStencilView; rtv = implcube.GetRenderTargetView(binding.CubeMapFace); } if (dsv != null) { if (((options & ClearOptions.Depth) == ClearOptions.Depth) && ((options & ClearOptions.Stencil) == ClearOptions.Stencil)) { _graphicsDevice.ClearDepthStencilView(dsv, D3D.DepthStencilClearFlags.Depth | D3D.DepthStencilClearFlags.Stencil, depth, (byte)stencil); } else if ((options & ClearOptions.Depth) == ClearOptions.Depth) { _graphicsDevice.ClearDepthStencilView(dsv, D3D.DepthStencilClearFlags.Depth, depth, (byte)stencil); } else if ((options & ClearOptions.Stencil) == ClearOptions.Stencil) { _graphicsDevice.ClearDepthStencilView(dsv, D3D.DepthStencilClearFlags.Stencil, depth, (byte)stencil); } } if ((rtv != null) && ((options & ClearOptions.Target) == ClearOptions.Target)) { _graphicsDevice.ClearRenderTargetView(rtv, sc); } } } }