port from perforce
This commit is contained in:
234
aiwaz/Aiwaz.Resources/SwapChain.cs
Normal file
234
aiwaz/Aiwaz.Resources/SwapChain.cs
Normal file
@@ -0,0 +1,234 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Aiwaz.Contracts;
|
||||
using System.Runtime.InteropServices;
|
||||
using Aiwaz.Core;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Aiwaz.Resources
|
||||
{
|
||||
[AiwazResource("SwapChain", "An output target for render operations, the output could be displayed directly into a window.")]
|
||||
public class SwapChain : RenderTarget, ISwapChain
|
||||
{
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
|
||||
[Serializable, StructLayout(LayoutKind.Sequential)]
|
||||
private struct RECT
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
|
||||
public RECT(int left_, int top_, int right_, int bottom_)
|
||||
{
|
||||
Left = left_;
|
||||
Top = top_;
|
||||
Right = right_;
|
||||
Bottom = bottom_;
|
||||
}
|
||||
|
||||
public int Height { get { return Bottom - Top; } }
|
||||
public int Width { get { return Right - Left; } }
|
||||
}
|
||||
|
||||
|
||||
private SlimDX.DXGI.SwapChainDescription swapChainDescription;
|
||||
private SlimDX.DXGI.SwapChain swapChain;
|
||||
|
||||
public SwapChain(IntPtr windowHandle)
|
||||
: this(windowHandle, 0, 0, 0, SlimDX.DXGI.Format.Unknown, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
public SwapChain(IntPtr windowHandle, int width, int height, int refreshRate, SlimDX.DXGI.Format format)
|
||||
: this (windowHandle, width, height, refreshRate, format, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
public SwapChain(IntPtr windowHandle, int width, int height, int refreshRate, SlimDX.DXGI.Format format, int multiSampleCount, int multiSampleQuality)
|
||||
: base()
|
||||
{
|
||||
VSync = true;
|
||||
|
||||
// get missing information
|
||||
if (multiSampleCount <= 0)
|
||||
multiSampleCount = 1;
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
RECT windowRect = new RECT();
|
||||
GetClientRect(windowHandle, out windowRect);
|
||||
if (width == 0)
|
||||
width = windowRect.Right - windowRect.Left;
|
||||
if (height == 0)
|
||||
height = windowRect.Bottom - windowRect.Top;
|
||||
}
|
||||
if (refreshRate == 0)
|
||||
refreshRate = 60; // 60Hz
|
||||
if (format == SlimDX.DXGI.Format.Unknown)
|
||||
format = SlimDX.DXGI.Format.R8G8B8A8_UNorm; // RGBA(X) 8Bit per channel -> 32Bit
|
||||
|
||||
swapChainDescription = new SlimDX.DXGI.SwapChainDescription()
|
||||
{
|
||||
BufferCount = 1,
|
||||
Usage = SlimDX.DXGI.Usage.RenderTargetOutput,
|
||||
OutputHandle = windowHandle,
|
||||
IsWindowed = true,
|
||||
ModeDescription = new SlimDX.DXGI.ModeDescription()
|
||||
{
|
||||
Width = width,
|
||||
Height = height,
|
||||
Format = (SlimDX.DXGI.Format)format,
|
||||
RefreshRate = new SlimDX.Rational(refreshRate, 1)
|
||||
},
|
||||
SampleDescription = new SlimDX.DXGI.SampleDescription()
|
||||
{
|
||||
Count = multiSampleCount,
|
||||
Quality = multiSampleQuality
|
||||
}
|
||||
};
|
||||
|
||||
this.multiSampleCount = multiSampleCount;
|
||||
this.multiSampleQuality = multiSampleQuality;
|
||||
|
||||
Console.WriteLine(string.Format("Creating SwapChain ({0}x{1}x{2} {3})..", width, height, refreshRate, format.ToString()));
|
||||
|
||||
swapChain = new SlimDX.DXGI.SwapChain(Engine.Factory, Engine.Device, swapChainDescription);
|
||||
if (swapChain == null)
|
||||
throw new InitializingFailedException(this.GetType().Name, "Unable to create internal swap chain.");
|
||||
|
||||
this.RetriveData();
|
||||
|
||||
this.ViewPort = new ViewPort()
|
||||
{
|
||||
Width = width,
|
||||
Height = height
|
||||
};
|
||||
}
|
||||
|
||||
public override int RenderTargetWidth
|
||||
{
|
||||
get { return swapChainDescription.ModeDescription.Width; }
|
||||
}
|
||||
|
||||
public override int RenderTargetHeight
|
||||
{
|
||||
get { return swapChainDescription.ModeDescription.Height; }
|
||||
}
|
||||
|
||||
public override SlimDX.DXGI.Format RenderTargetFormat
|
||||
{
|
||||
get { return swapChainDescription.ModeDescription.Format; }
|
||||
}
|
||||
|
||||
#region ISwapChain Members
|
||||
|
||||
public void Resize(int width, int height)
|
||||
{
|
||||
if (width <= 0 || height <= 0)
|
||||
{
|
||||
RECT windowRect = new RECT();
|
||||
GetClientRect(swapChainDescription.OutputHandle, out windowRect);
|
||||
if (width <= 0)
|
||||
width = windowRect.Right - windowRect.Left;
|
||||
if (height <= 0)
|
||||
height = windowRect.Bottom - windowRect.Top;
|
||||
}
|
||||
|
||||
if (swapChainDescription.ModeDescription.Width == width &&
|
||||
swapChainDescription.ModeDescription.Height == height)
|
||||
return;
|
||||
|
||||
var depthStencilBuffer = this.HasDepthStencilBuffer;
|
||||
|
||||
Engine.Device.ClearState();
|
||||
|
||||
this.HasDepthStencilBuffer = false;
|
||||
|
||||
if (this.DX10RenderTargetView != null)
|
||||
this.DX10RenderTargetView.Dispose();
|
||||
this.DX10RenderTargetView = null;
|
||||
|
||||
swapChain.ResizeBuffers(swapChainDescription.BufferCount, width, height, swapChainDescription.ModeDescription.Format, SlimDX.DXGI.SwapChainFlags.AllowModeSwitch);
|
||||
var desc = swapChainDescription.ModeDescription;
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
swapChainDescription.ModeDescription = desc;
|
||||
this.RetriveData();
|
||||
|
||||
this.HasDepthStencilBuffer = depthStencilBuffer;
|
||||
|
||||
this.ViewPort = new ViewPort()
|
||||
{
|
||||
Width = width,
|
||||
Height = height
|
||||
};
|
||||
}
|
||||
|
||||
public void Present()
|
||||
{
|
||||
swapChain.Present(VSync ? 1 : 0, SlimDX.DXGI.PresentFlags.None);
|
||||
}
|
||||
|
||||
public bool Fullscreen
|
||||
{
|
||||
get { return !swapChainDescription.IsWindowed; }
|
||||
set
|
||||
{
|
||||
if (swapChainDescription.IsWindowed == !value)
|
||||
return;
|
||||
swapChainDescription.IsWindowed = !value;
|
||||
|
||||
var hasDepthStencilBuffer = this.HasDepthStencilBuffer;
|
||||
Engine.Device.ClearState();
|
||||
this.HasDepthStencilBuffer = false;
|
||||
|
||||
if (this.DX10RenderTargetView != null)
|
||||
this.DX10RenderTargetView.Dispose();
|
||||
this.DX10RenderTargetView = null;
|
||||
|
||||
swapChain.SetFullScreenState(value, Engine.DeviceEnumerator.FindBestOutput(false).Output);
|
||||
this.RetriveData();
|
||||
|
||||
this.HasDepthStencilBuffer = hasDepthStencilBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
public bool VSync { get; set; }
|
||||
|
||||
private void RetriveData()
|
||||
{
|
||||
using (var backbufferTexture = SlimDX.Direct3D10.Texture2D.FromSwapChain<SlimDX.Direct3D10.Texture2D>(swapChain, 0))
|
||||
{
|
||||
DX10RenderTargetView = new SlimDX.Direct3D10.RenderTargetView(Engine.Device, backbufferTexture);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (swapChain != null)
|
||||
swapChain.Dispose();
|
||||
swapChain = null;
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override ICreationParams CreationParams
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public override ObservableCollection<IResource> Children
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user