mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2026-06-11 12:06:16 +08:00
R26_dev8 - First public commit
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
using SharpDX.Direct3D11;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public interface DXForm
|
||||
{
|
||||
//unfortunately this can't be made a base class for the main render forms, because the
|
||||
//form designer causes an error when inheriting from a form in the same project, if
|
||||
//the architecture is set to x64. really annoying!
|
||||
//So, i've used an interface instead, since really just some of the form properties
|
||||
//and a couple of extra methods (these callbacks) are needed by DXManager.
|
||||
|
||||
Form Form { get; }
|
||||
|
||||
|
||||
void InitScene(Device device);
|
||||
void CleanupScene();
|
||||
void RenderScene(DeviceContext context);
|
||||
void BuffersResized(int w, int h);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.DXGI;
|
||||
using Color = SharpDX.Color;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using DriverType = SharpDX.Direct3D.DriverType;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public class DXManager
|
||||
{
|
||||
private DXForm dxform;
|
||||
|
||||
public Device device { get; private set; }
|
||||
public DeviceContext context { get; private set; }
|
||||
public SwapChain swapchain { get; private set; }
|
||||
public Texture2D backbuffer { get; private set; }
|
||||
public Texture2D depthbuffer { get; private set; }
|
||||
public RenderTargetView targetview { get; private set; }
|
||||
public DepthStencilView depthview { get; private set; }
|
||||
|
||||
private volatile bool Running = false;
|
||||
private volatile bool Rendering = false;
|
||||
private volatile bool Resizing = false;
|
||||
private object syncroot = new object(); //for thread safety
|
||||
public int multisamplecount { get; private set; } = 4; //should be a setting..
|
||||
public int multisamplequality { get; private set; } = 0; //should be a setting...
|
||||
public Color clearcolour { get; private set; } = new Color(0.2f, 0.4f, 0.6f, 1.0f); //gross
|
||||
private System.Drawing.Size beginSize;
|
||||
private ViewportF Viewport;
|
||||
private bool autoStartLoop = false;
|
||||
|
||||
public bool Init(DXForm form, bool autostart = true)
|
||||
{
|
||||
dxform = form;
|
||||
autoStartLoop = autostart;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
SwapChainDescription scd = new SwapChainDescription()
|
||||
{
|
||||
BufferCount = 2,
|
||||
Flags = SwapChainFlags.None,
|
||||
IsWindowed = true,
|
||||
ModeDescription = new ModeDescription(
|
||||
form.Form.ClientSize.Width,
|
||||
form.Form.ClientSize.Height,
|
||||
new Rational(0, 0),
|
||||
Format.R8G8B8A8_UNorm),
|
||||
OutputHandle = form.Form.Handle,
|
||||
SampleDescription = new SampleDescription(multisamplecount, multisamplequality),
|
||||
SwapEffect = SwapEffect.Discard,
|
||||
Usage = Usage.RenderTargetOutput
|
||||
};
|
||||
|
||||
FeatureLevel[] levels = new FeatureLevel[] { FeatureLevel.Level_10_0 };
|
||||
|
||||
DeviceCreationFlags flags = DeviceCreationFlags.None;
|
||||
//#if DEBUG
|
||||
// flags = DeviceCreationFlags.Debug;
|
||||
//#endif
|
||||
Device dev = null;
|
||||
SwapChain sc = null;
|
||||
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
Device.CreateWithSwapChain(DriverType.Hardware, flags, levels, scd, out dev, out sc);
|
||||
success = true;
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (!success)
|
||||
{
|
||||
multisamplecount = 1;
|
||||
multisamplequality = 0;
|
||||
scd.SampleDescription = new SampleDescription(1, 0); //try no AA
|
||||
try
|
||||
{
|
||||
Device.CreateWithSwapChain(DriverType.Hardware, flags, levels, scd, out dev, out sc);
|
||||
success = true;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
throw new Exception("CodeWalker was unable to initialise the graphics device. Please ensure your system meets the minimum requirements and that your graphics drivers and DirectX are up to date.");
|
||||
}
|
||||
|
||||
device = dev;
|
||||
swapchain = sc;
|
||||
|
||||
|
||||
var factory = swapchain.GetParent<Factory>(); //ignore windows events...
|
||||
factory.MakeWindowAssociation(form.Form.Handle, WindowAssociationFlags.IgnoreAll);
|
||||
|
||||
|
||||
|
||||
context = device.ImmediateContext;
|
||||
|
||||
|
||||
|
||||
CreateRenderBuffers();
|
||||
|
||||
|
||||
|
||||
dxform.Form.Load += Dxform_Load;
|
||||
dxform.Form.FormClosing += Dxform_FormClosing;
|
||||
dxform.Form.ClientSizeChanged += Dxform_ClientSizeChanged;
|
||||
dxform.Form.ResizeBegin += DxForm_ResizeBegin;
|
||||
dxform.Form.ResizeEnd += DxForm_ResizeEnd;
|
||||
|
||||
if (autostart)
|
||||
{
|
||||
dxform.InitScene(device);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Unable to initialise DirectX11.\n" + ex.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Cleanup()
|
||||
{
|
||||
Running = false;
|
||||
int count = 0;
|
||||
while (Rendering && (count < 1000))
|
||||
{
|
||||
Thread.Sleep(1); //try to gracefully exit...
|
||||
count++;
|
||||
}
|
||||
|
||||
dxform.CleanupScene();
|
||||
|
||||
//dipose of all objects
|
||||
if (depthview != null) depthview.Dispose();
|
||||
if (depthbuffer != null) depthbuffer.Dispose();
|
||||
if (targetview != null) targetview.Dispose();
|
||||
if (backbuffer != null) backbuffer.Dispose();
|
||||
if (swapchain != null) swapchain.Dispose();
|
||||
if (device != null) device.Dispose();
|
||||
|
||||
GC.Collect();
|
||||
}
|
||||
private void CreateRenderBuffers()
|
||||
{
|
||||
if (targetview != null) targetview.Dispose();
|
||||
if (backbuffer != null) backbuffer.Dispose();
|
||||
if (depthview != null) depthview.Dispose();
|
||||
if (depthbuffer != null) depthbuffer.Dispose();
|
||||
|
||||
|
||||
backbuffer = Texture2D.FromSwapChain<Texture2D>(swapchain, 0);
|
||||
targetview = new RenderTargetView(device, backbuffer);
|
||||
|
||||
depthbuffer = new Texture2D(device, new Texture2DDescription()
|
||||
{
|
||||
Format = Format.D32_Float,
|
||||
ArraySize = 1,
|
||||
MipLevels = 1,
|
||||
Width = backbuffer.Description.Width,
|
||||
Height = backbuffer.Description.Height,
|
||||
SampleDescription = new SampleDescription(multisamplecount, 0),
|
||||
Usage = ResourceUsage.Default,
|
||||
BindFlags = BindFlags.DepthStencil,
|
||||
CpuAccessFlags = CpuAccessFlags.None,
|
||||
OptionFlags = ResourceOptionFlags.None
|
||||
});
|
||||
|
||||
depthview = new DepthStencilView(device, depthbuffer);
|
||||
|
||||
Viewport.Width = (float)backbuffer.Description.Width;
|
||||
Viewport.Height = (float)backbuffer.Description.Height;
|
||||
Viewport.MinDepth = 0.0f;
|
||||
Viewport.MaxDepth = 1.0f;
|
||||
Viewport.X = 0;
|
||||
Viewport.Y = 0;
|
||||
}
|
||||
private void Resize()
|
||||
{
|
||||
if (Resizing) return;
|
||||
Monitor.Enter(syncroot);
|
||||
|
||||
int width = dxform.Form.ClientSize.Width;
|
||||
int height = dxform.Form.ClientSize.Height;
|
||||
|
||||
if (targetview != null) targetview.Dispose();
|
||||
if (backbuffer != null) backbuffer.Dispose();
|
||||
|
||||
swapchain.ResizeBuffers(1, width, height, Format.Unknown, SwapChainFlags.AllowModeSwitch);
|
||||
|
||||
CreateRenderBuffers();
|
||||
|
||||
Monitor.Exit(syncroot);
|
||||
|
||||
dxform.BuffersResized(width, height);
|
||||
}
|
||||
|
||||
private void Dxform_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (autoStartLoop)
|
||||
{
|
||||
StartRenderLoop();
|
||||
}
|
||||
}
|
||||
private void Dxform_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
private void Dxform_ClientSizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
Resize();
|
||||
}
|
||||
private void DxForm_ResizeBegin(object sender, EventArgs e)
|
||||
{
|
||||
beginSize = dxform.Form.ClientSize;
|
||||
Resizing = true;
|
||||
}
|
||||
private void DxForm_ResizeEnd(object sender, EventArgs e)
|
||||
{
|
||||
Resizing = false;
|
||||
if (dxform.Form.ClientSize != beginSize)
|
||||
{
|
||||
Resize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
dxform.InitScene(device);
|
||||
StartRenderLoop();
|
||||
}
|
||||
private void StartRenderLoop()
|
||||
{
|
||||
Running = true;
|
||||
new Thread(new ThreadStart(RenderLoop)).Start();
|
||||
}
|
||||
private void RenderLoop()
|
||||
{
|
||||
while (Running)
|
||||
{
|
||||
while (Resizing)
|
||||
{
|
||||
swapchain.Present(1, PresentFlags.None); //just flip buffers when resizing; don't draw
|
||||
}
|
||||
while (dxform.Form.WindowState == FormWindowState.Minimized)
|
||||
{
|
||||
Thread.Sleep(10); //don't hog CPU when minimised
|
||||
if (dxform.Form.IsDisposed) return; //if closed while minimised
|
||||
}
|
||||
|
||||
Rendering = true;
|
||||
if(!Monitor.TryEnter(syncroot, 50))
|
||||
{
|
||||
Thread.Sleep(10); //don't hog CPU when not able to render...
|
||||
continue;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
try
|
||||
{
|
||||
context.OutputMerger.SetRenderTargets(depthview, targetview);
|
||||
context.Rasterizer.SetViewport(0, 0, dxform.Form.ClientSize.Width, dxform.Form.ClientSize.Height);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error setting main render target!\n" + ex.ToString());
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
if (dxform.Form.IsDisposed)
|
||||
{
|
||||
Monitor.Exit(syncroot);
|
||||
Rendering = false;
|
||||
return; //the form was closed... stop!!
|
||||
}
|
||||
|
||||
dxform.RenderScene(context);
|
||||
|
||||
try
|
||||
{
|
||||
swapchain.Present(1, PresentFlags.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error presenting swap chain!\n" + ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
Monitor.Exit(syncroot);
|
||||
Rendering = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ClearRenderTarget(DeviceContext ctx)
|
||||
{
|
||||
ctx.ClearRenderTargetView(targetview, clearcolour);
|
||||
ctx.ClearDepthStencilView(depthview, DepthStencilClearFlags.Depth, 1.0f, 0);
|
||||
}
|
||||
public void ClearDepth(DeviceContext ctx)
|
||||
{
|
||||
ctx.ClearDepthStencilView(depthview, DepthStencilClearFlags.Depth, 1.0f, 0);
|
||||
}
|
||||
public void SetDefaultRenderTarget(DeviceContext ctx)
|
||||
{
|
||||
ctx.OutputMerger.SetRenderTargets(depthview, targetview);
|
||||
ctx.Rasterizer.SetViewport(Viewport);
|
||||
//ctx.Rasterizer.State = RasterizerStateSolid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.DXGI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using Resource = SharpDX.Direct3D11.Resource;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using SharpDX.Mathematics.Interop;
|
||||
using SharpDX.Direct3D;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public static class DXUtility
|
||||
{
|
||||
|
||||
public static Buffer CreateBuffer(Device device, int size, ResourceUsage usage, BindFlags bindFlags, CpuAccessFlags cpuAccessFlags, ResourceOptionFlags miscFlags, int structByteStride)
|
||||
{
|
||||
BufferDescription desc = new BufferDescription();
|
||||
desc.SizeInBytes = size;
|
||||
desc.Usage = usage;
|
||||
desc.BindFlags = bindFlags;
|
||||
desc.CpuAccessFlags = cpuAccessFlags;
|
||||
desc.OptionFlags = miscFlags;
|
||||
desc.StructureByteStride = structByteStride;
|
||||
|
||||
Buffer b = new Buffer(device, desc);
|
||||
|
||||
//D3D11_SUBRESOURCE_DATA srd;
|
||||
//srd.pSysMem = data;
|
||||
//ComPtr<ID3D11Buffer> b;
|
||||
|
||||
//Try(DXManager::GetDevice()->CreateBuffer(&desc, data != nullptr? &srd : nullptr, &b), name);
|
||||
//DXManager::AddVramUsage(size);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
public static Texture2D CreateTexture2D(Device device, int width, int height, int mipLevels, int arraySize, Format format, int sampleCount, int sampleQuality, ResourceUsage usage, BindFlags bindFlags, CpuAccessFlags cpuAccessFlags, ResourceOptionFlags miscFlags)
|
||||
{
|
||||
Texture2DDescription td = new Texture2DDescription();
|
||||
td.Width = width;
|
||||
td.Height = height;
|
||||
td.MipLevels = mipLevels;
|
||||
td.ArraySize = arraySize;
|
||||
td.Format = format;
|
||||
td.SampleDescription = new SampleDescription(sampleCount, sampleQuality);
|
||||
td.Usage = usage;
|
||||
td.BindFlags = bindFlags;
|
||||
td.CpuAccessFlags = cpuAccessFlags;
|
||||
td.OptionFlags = miscFlags;
|
||||
Texture2D t = new Texture2D(device, td);
|
||||
return t;
|
||||
}
|
||||
//static ComPtr<ID3D11Texture2D> CreateTexture2D(UINT width, UINT height, UINT mipLevels, UINT arraySize, DXGI_FORMAT format, UINT sampleCount, UINT sampleQuality, D3D11_USAGE usage, UINT bindFlags, UINT cpuAccessFlags, UINT miscFlags, const void* data, const string& name)
|
||||
//{
|
||||
// D3D11_TEXTURE2D_DESC td;
|
||||
// td.Width = width;
|
||||
// td.Height = height;
|
||||
// td.MipLevels = mipLevels;
|
||||
// td.ArraySize = arraySize;
|
||||
// td.Format = format;
|
||||
// td.SampleDesc.Count = sampleCount;
|
||||
// td.SampleDesc.Quality = sampleQuality;
|
||||
// td.Usage = usage;
|
||||
// td.BindFlags = bindFlags;
|
||||
// td.CPUAccessFlags = cpuAccessFlags;
|
||||
// td.MiscFlags = miscFlags;
|
||||
// D3D11_SUBRESOURCE_DATA srd;
|
||||
// srd.pSysMem = data;
|
||||
// srd.SysMemPitch = 1;
|
||||
// srd.SysMemSlicePitch = 0;
|
||||
// ComPtr<ID3D11Texture2D> t;
|
||||
// Try(DXManager::GetDevice()->CreateTexture2D(&td, data != nullptr ? &srd : nullptr, &t), name);
|
||||
// DXManager::AddVramUsage(ElementSize(format) * width * height * arraySize);
|
||||
// return t;
|
||||
//}
|
||||
|
||||
|
||||
public static SamplerState CreateSamplerState(Device device, TextureAddressMode addressU, TextureAddressMode addressV, TextureAddressMode addressW, RawColor4 border, Comparison comparisonFunc, Filter filter, int maxAnisotropy, float maxLOD, float minLOD, float mipLODBias)
|
||||
{
|
||||
SamplerStateDescription smpDesc = new SamplerStateDescription();
|
||||
smpDesc.AddressU = addressU;
|
||||
smpDesc.AddressV = addressV;
|
||||
smpDesc.AddressW = addressW;
|
||||
smpDesc.BorderColor = border;
|
||||
smpDesc.ComparisonFunction = comparisonFunc;
|
||||
smpDesc.Filter = filter;
|
||||
smpDesc.MaximumAnisotropy = maxAnisotropy;
|
||||
smpDesc.MaximumLod = maxLOD;
|
||||
smpDesc.MinimumLod = minLOD;
|
||||
smpDesc.MipLodBias = mipLODBias;
|
||||
SamplerState smp = new SamplerState(device, smpDesc);
|
||||
return smp;
|
||||
}
|
||||
public static SamplerState CreateSamplerState(Device device, TextureAddressMode address, RawColor4 border, Comparison comparisonFunc, Filter filter, int maxAnisotropy, float maxLOD, float minLOD, float mipLODBias)
|
||||
{
|
||||
return CreateSamplerState(device, address, address, address, border, comparisonFunc, filter, maxAnisotropy, maxLOD, minLOD, mipLODBias);
|
||||
}
|
||||
|
||||
public static ShaderResourceView CreateShaderResourceView(Device device, Resource resource, Format format, ShaderResourceViewDimension viewDimension, int mipLevels, int mostDetailedMip, int arraySize, int firstArraySlice)
|
||||
{
|
||||
ShaderResourceViewDescription srvd = new ShaderResourceViewDescription();
|
||||
srvd.Format = format;
|
||||
srvd.Dimension = viewDimension;
|
||||
switch (viewDimension)
|
||||
{
|
||||
case ShaderResourceViewDimension.Buffer:// D3D11_SRV_DIMENSION_BUFFER:
|
||||
srvd.Buffer.ElementOffset = mipLevels;
|
||||
srvd.Buffer.ElementWidth = ElementSize(format);
|
||||
srvd.Buffer.ElementCount = arraySize;
|
||||
srvd.Buffer.FirstElement = firstArraySlice;
|
||||
break;
|
||||
case ShaderResourceViewDimension.Texture2D:// D3D11_SRV_DIMENSION_TEXTURE2D:
|
||||
srvd.Texture2D.MipLevels = mipLevels;
|
||||
srvd.Texture2D.MostDetailedMip = mostDetailedMip;
|
||||
break;
|
||||
case ShaderResourceViewDimension.Texture2DArray:// D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
|
||||
srvd.Texture2DArray.MipLevels = mipLevels;
|
||||
srvd.Texture2DArray.MostDetailedMip = mostDetailedMip;
|
||||
srvd.Texture2DArray.ArraySize = arraySize;
|
||||
srvd.Texture2DArray.FirstArraySlice = firstArraySlice;
|
||||
break;
|
||||
case ShaderResourceViewDimension.TextureCube:// D3D11_SRV_DIMENSION_TEXTURECUBE:
|
||||
srvd.TextureCube.MipLevels = mipLevels;
|
||||
srvd.TextureCube.MostDetailedMip = mostDetailedMip;
|
||||
break;
|
||||
case ShaderResourceViewDimension.Texture3D:// D3D11_SRV_DIMENSION_TEXTURE3D:
|
||||
srvd.Texture3D.MipLevels = mipLevels;
|
||||
srvd.Texture3D.MostDetailedMip = mostDetailedMip;
|
||||
break;
|
||||
default:
|
||||
throw new Exception(); //not implemented....
|
||||
}
|
||||
ShaderResourceView srv = new ShaderResourceView(device, resource, srvd);
|
||||
return srv;
|
||||
}
|
||||
|
||||
public static UnorderedAccessView CreateUnorderedAccessView(Device device, Resource resource, Format format, UnorderedAccessViewDimension viewDimension, int firstElement, int numElements, UnorderedAccessViewBufferFlags flags, int mipSlice)
|
||||
{
|
||||
UnorderedAccessViewDescription uavd = new UnorderedAccessViewDescription();
|
||||
uavd.Format = format;
|
||||
uavd.Dimension = viewDimension;
|
||||
|
||||
switch(viewDimension)
|
||||
{
|
||||
case UnorderedAccessViewDimension.Texture1D:
|
||||
uavd.Texture1D.MipSlice = mipSlice;
|
||||
break;
|
||||
case UnorderedAccessViewDimension.Texture1DArray:
|
||||
uavd.Texture1DArray.MipSlice = mipSlice;
|
||||
uavd.Texture1DArray.ArraySize = numElements;
|
||||
uavd.Texture1DArray.FirstArraySlice = firstElement;
|
||||
break;
|
||||
case UnorderedAccessViewDimension.Texture2D:
|
||||
uavd.Texture2D.MipSlice = mipSlice;
|
||||
break;
|
||||
case UnorderedAccessViewDimension.Texture2DArray:
|
||||
uavd.Texture2DArray.MipSlice = mipSlice;
|
||||
uavd.Texture2DArray.ArraySize = numElements;
|
||||
uavd.Texture2DArray.FirstArraySlice = firstElement;
|
||||
break;
|
||||
case UnorderedAccessViewDimension.Texture3D:
|
||||
uavd.Texture3D.MipSlice = mipSlice;
|
||||
uavd.Texture3D.WSize = numElements;
|
||||
uavd.Texture3D.FirstWSlice = firstElement;
|
||||
break;
|
||||
case UnorderedAccessViewDimension.Buffer:
|
||||
uavd.Buffer.ElementCount = numElements;
|
||||
uavd.Buffer.FirstElement = firstElement;
|
||||
uavd.Buffer.Flags = flags;
|
||||
break;
|
||||
case UnorderedAccessViewDimension.Unknown:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
var uav = new UnorderedAccessView(device, resource, uavd);
|
||||
return uav;
|
||||
}
|
||||
|
||||
|
||||
public static RenderTargetView CreateRenderTargetView(Device device, Resource renderTarget, Format format, RenderTargetViewDimension viewDimension, int mipSlice, int arraySize, int firstArraySlice)
|
||||
{
|
||||
RenderTargetView rtv;
|
||||
RenderTargetViewDescription rtvd = new RenderTargetViewDescription();
|
||||
rtvd.Format = format;
|
||||
rtvd.Dimension = viewDimension;
|
||||
switch(viewDimension)
|
||||
{
|
||||
case RenderTargetViewDimension.Buffer:// D3D11_RTV_DIMENSION_BUFFER:
|
||||
rtvd.Buffer.ElementOffset = mipSlice;
|
||||
rtvd.Buffer.ElementWidth = arraySize* ElementSize(format);// arraySize; //assume square buffer... is this the width?
|
||||
rtvd.Buffer.FirstElement = 0*ElementSize(format);//firstArraySlice;
|
||||
rtvd.Buffer.ElementCount = arraySize;//*arraySize*ElementSize(format); //does this represent the height??
|
||||
break;
|
||||
case RenderTargetViewDimension.Texture2D:// D3D11_RTV_DIMENSION_TEXTURE2D:
|
||||
rtvd.Texture2D.MipSlice = mipSlice;
|
||||
break;
|
||||
case RenderTargetViewDimension.Texture2DArray:// D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
|
||||
rtvd.Texture2DArray.MipSlice = mipSlice;
|
||||
rtvd.Texture2DArray.ArraySize = arraySize;
|
||||
rtvd.Texture2DArray.FirstArraySlice = firstArraySlice;
|
||||
break;
|
||||
case RenderTargetViewDimension.Texture2DMultisampled:// D3D11_RTV_DIMENSION_TEXTURE2DMS:
|
||||
break;
|
||||
case RenderTargetViewDimension.Texture2DMultisampledArray:// D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
|
||||
rtvd.Texture2DMSArray.ArraySize = arraySize;
|
||||
rtvd.Texture2DMSArray.FirstArraySlice = firstArraySlice;
|
||||
break;
|
||||
case RenderTargetViewDimension.Texture3D:// D3D11_RTV_DIMENSION_TEXTURE3D:
|
||||
rtvd.Texture3D.MipSlice = mipSlice;
|
||||
rtvd.Texture3D.DepthSliceCount = arraySize;
|
||||
rtvd.Texture3D.FirstDepthSlice = firstArraySlice;
|
||||
break;
|
||||
}
|
||||
rtv = new RenderTargetView(device, renderTarget, rtvd);
|
||||
return rtv;
|
||||
}
|
||||
|
||||
|
||||
public static DepthStencilView CreateDepthStencilView(Device device, Texture2D depthStencil, Format format, DepthStencilViewDimension viewDimension)
|
||||
{
|
||||
DepthStencilViewDescription dsvd = new DepthStencilViewDescription();
|
||||
dsvd.Format = format;
|
||||
dsvd.Flags = 0;
|
||||
dsvd.Dimension = viewDimension;
|
||||
dsvd.Texture2D.MipSlice = 0;
|
||||
DepthStencilView dsv = new DepthStencilView(device, depthStencil, dsvd);
|
||||
return dsv;
|
||||
}
|
||||
public static DepthStencilView CreateDepthStencilView(Device device, Texture2D depthStencil, Format format, int arraySlice)
|
||||
{
|
||||
DepthStencilViewDescription dsvd = new DepthStencilViewDescription();
|
||||
dsvd.Format = format;
|
||||
dsvd.Flags = 0;
|
||||
dsvd.Dimension = DepthStencilViewDimension.Texture2DArray;// D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
|
||||
dsvd.Texture2DArray.ArraySize = 1;
|
||||
dsvd.Texture2DArray.FirstArraySlice = arraySlice;
|
||||
dsvd.Texture2DArray.MipSlice = 0;
|
||||
DepthStencilView dsv = new DepthStencilView(device, depthStencil, dsvd);
|
||||
return dsv;
|
||||
}
|
||||
|
||||
|
||||
public static DepthStencilState CreateDepthStencilState(Device device, bool depthEnable, DepthWriteMask writeMask, Comparison func, bool stencilEnable, byte stencilReadMask, byte stencilWriteMask, DepthStencilOperationDescription frontFace, DepthStencilOperationDescription backFace)
|
||||
{
|
||||
DepthStencilStateDescription dsd;
|
||||
dsd.IsDepthEnabled = depthEnable;
|
||||
dsd.DepthWriteMask = writeMask;
|
||||
dsd.DepthComparison = func;
|
||||
dsd.IsStencilEnabled = stencilEnable;
|
||||
dsd.StencilReadMask = stencilReadMask;
|
||||
dsd.StencilWriteMask = stencilWriteMask;
|
||||
dsd.FrontFace = frontFace;
|
||||
dsd.BackFace = backFace;
|
||||
DepthStencilState s = new DepthStencilState(device, dsd);
|
||||
return s;
|
||||
}
|
||||
public static DepthStencilState CreateDepthStencilState(Device device, bool depthEnable, DepthWriteMask writeMask)
|
||||
{
|
||||
DepthStencilOperationDescription frontFace = new DepthStencilOperationDescription();
|
||||
DepthStencilOperationDescription backFace = new DepthStencilOperationDescription();
|
||||
bool stencil = false;//depthEnable;
|
||||
byte rm = 0;
|
||||
byte wm = 0;
|
||||
if (stencil)
|
||||
{
|
||||
rm = 0xFF;
|
||||
wm = 0xFF;
|
||||
// Stencil operations if pixel is front-facing
|
||||
frontFace.FailOperation = StencilOperation.Keep;// D3D11_STENCIL_OP_KEEP;
|
||||
frontFace.DepthFailOperation = StencilOperation.Increment;// D3D11_STENCIL_OP_INCR;
|
||||
frontFace.PassOperation = StencilOperation.Keep;// D3D11_STENCIL_OP_KEEP;
|
||||
frontFace.Comparison = Comparison.Always;// D3D11_COMPARISON_ALWAYS;
|
||||
|
||||
// Stencil operations if pixel is back-facing
|
||||
backFace.FailOperation = StencilOperation.Keep;// D3D11_STENCIL_OP_KEEP;
|
||||
backFace.DepthFailOperation = StencilOperation.Decrement;// D3D11_STENCIL_OP_DECR;
|
||||
backFace.PassOperation = StencilOperation.Keep;// D3D11_STENCIL_OP_KEEP;
|
||||
backFace.Comparison = Comparison.Always;// D3D11_COMPARISON_ALWAYS;
|
||||
}
|
||||
|
||||
return CreateDepthStencilState(device, depthEnable, writeMask, Comparison.LessEqual, stencil, rm, wm, frontFace, backFace);
|
||||
}
|
||||
|
||||
|
||||
public static RasterizerState CreateRasterizerState(Device device, FillMode fillMode, CullMode cullMode, bool depthClipEnable, bool scissorEnable, bool multisampleEnable, int depthBias, float depthBiasClamp, float slopeScaledDepthBias)
|
||||
{
|
||||
RasterizerStateDescription drd = new RasterizerStateDescription();
|
||||
drd.FillMode = fillMode; //D3D11_FILL_MODE FillMode;
|
||||
drd.CullMode = cullMode;//D3D11_CULL_MODE CullMode;
|
||||
drd.IsFrontCounterClockwise = false; //BOOL FrontCounterClockwise;
|
||||
drd.DepthBias = depthBias; //INT DepthBias;
|
||||
drd.DepthBiasClamp = depthBiasClamp;//FLOAT DepthBiasClamp;
|
||||
drd.SlopeScaledDepthBias = slopeScaledDepthBias;//FLOAT SlopeScaledDepthBias;
|
||||
drd.IsDepthClipEnabled = depthClipEnable;//BOOL DepthClipEnable;
|
||||
drd.IsScissorEnabled = scissorEnable;//BOOL ScissorEnable;
|
||||
drd.IsMultisampleEnabled = multisampleEnable;//BOOL MultisampleEnable;
|
||||
drd.IsAntialiasedLineEnabled = false;//BOOL AntialiasedLineEnable;
|
||||
RasterizerState rs = new RasterizerState(device, drd);
|
||||
return rs;
|
||||
}
|
||||
public static RasterizerState CreateRasterizerState(Device device, FillMode fillMode, CullMode cullMode, bool depthClipEnable, bool scissorEnable, bool multisampleEnable)
|
||||
{
|
||||
return CreateRasterizerState(device, fillMode, cullMode, depthClipEnable, scissorEnable, multisampleEnable, 0, 0.0f, 0.0f);
|
||||
}
|
||||
public static RasterizerState CreateRasterizerState(Device device, FillMode fillMode, CullMode cullMode, bool depthClipEnable, bool multisampleEnable)
|
||||
{
|
||||
return CreateRasterizerState(device, fillMode, cullMode, depthClipEnable, false, multisampleEnable);
|
||||
}
|
||||
public static RasterizerState CreateRasterizerState(Device device, bool depthClipEnable, bool multisampleEnable)
|
||||
{
|
||||
return CreateRasterizerState(device, FillMode.Solid, CullMode.Back, depthClipEnable, false, multisampleEnable);
|
||||
}
|
||||
|
||||
public static BlendState CreateBlendState(Device device, bool blendEnable, BlendOperation op, BlendOption src, BlendOption dst, BlendOperation opAlpha, BlendOption srcAlpha, BlendOption dstAlpha, ColorWriteMaskFlags writeMask)
|
||||
{
|
||||
BlendStateDescription bsd = new BlendStateDescription();
|
||||
//ZeroMemory(&bsd, sizeof(bsd));
|
||||
bsd.RenderTarget[0].IsBlendEnabled = blendEnable;
|
||||
bsd.RenderTarget[0].BlendOperation = op;
|
||||
bsd.RenderTarget[0].SourceBlend = src;
|
||||
bsd.RenderTarget[0].DestinationBlend = dst;
|
||||
bsd.RenderTarget[0].AlphaBlendOperation = opAlpha;
|
||||
bsd.RenderTarget[0].SourceAlphaBlend = srcAlpha;
|
||||
bsd.RenderTarget[0].DestinationAlphaBlend = dstAlpha;
|
||||
bsd.RenderTarget[0].RenderTargetWriteMask = writeMask;
|
||||
BlendState bs = new BlendState(device, bsd);
|
||||
return bs;
|
||||
}
|
||||
|
||||
|
||||
public static int ElementSize(Format format)
|
||||
{
|
||||
//FormatHelper.SizeOfInBytes?
|
||||
switch (format)
|
||||
{
|
||||
case Format.R32G32B32A32_Typeless:
|
||||
case Format.R32G32B32A32_Float:
|
||||
case Format.R32G32B32A32_UInt:
|
||||
case Format.R32G32B32A32_SInt:
|
||||
return 16;
|
||||
|
||||
case Format.R32G32B32_Typeless:
|
||||
case Format.R32G32B32_Float:
|
||||
case Format.R32G32B32_UInt:
|
||||
case Format.R32G32B32_SInt:
|
||||
return 12;
|
||||
|
||||
case Format.R16G16B16A16_Typeless:
|
||||
case Format.R16G16B16A16_Float:
|
||||
case Format.R16G16B16A16_UNorm:
|
||||
case Format.R16G16B16A16_UInt:
|
||||
case Format.R16G16B16A16_SNorm:
|
||||
case Format.R16G16B16A16_SInt:
|
||||
case Format.R32G32_Typeless:
|
||||
case Format.R32G32_Float:
|
||||
case Format.R32G32_UInt:
|
||||
case Format.R32G32_SInt:
|
||||
case Format.R32G8X24_Typeless:
|
||||
case Format.D32_Float_S8X24_UInt:
|
||||
case Format.R32_Float_X8X24_Typeless:
|
||||
case Format.X32_Typeless_G8X24_UInt:
|
||||
return 8;
|
||||
|
||||
case Format.R10G10B10A2_Typeless:
|
||||
case Format.R10G10B10A2_UNorm:
|
||||
case Format.R10G10B10A2_UInt:
|
||||
case Format.R11G11B10_Float:
|
||||
case Format.R8G8B8A8_Typeless:
|
||||
case Format.R8G8B8A8_UNorm:
|
||||
case Format.R8G8B8A8_UNorm_SRgb:
|
||||
case Format.R8G8B8A8_UInt:
|
||||
case Format.R8G8B8A8_SNorm:
|
||||
case Format.R8G8B8A8_SInt:
|
||||
case Format.R16G16_Typeless:
|
||||
case Format.R16G16_Float:
|
||||
case Format.R16G16_UNorm:
|
||||
case Format.R16G16_UInt:
|
||||
case Format.R16G16_SNorm:
|
||||
case Format.R16G16_SInt:
|
||||
case Format.R32_Typeless:
|
||||
case Format.D32_Float:
|
||||
case Format.R32_Float:
|
||||
case Format.R32_UInt:
|
||||
case Format.R32_SInt:
|
||||
case Format.R24G8_Typeless:
|
||||
case Format.D24_UNorm_S8_UInt:
|
||||
case Format.R24_UNorm_X8_Typeless:
|
||||
case Format.X24_Typeless_G8_UInt:
|
||||
case Format.B8G8R8A8_UNorm:
|
||||
case Format.B8G8R8X8_UNorm:
|
||||
return 4;
|
||||
|
||||
case Format.R8G8_Typeless:
|
||||
case Format.R8G8_UNorm:
|
||||
case Format.R8G8_UInt:
|
||||
case Format.R8G8_SNorm:
|
||||
case Format.R8G8_SInt:
|
||||
case Format.R16_Typeless:
|
||||
case Format.R16_Float:
|
||||
case Format.D16_UNorm:
|
||||
case Format.R16_UNorm:
|
||||
case Format.R16_UInt:
|
||||
case Format.R16_SNorm:
|
||||
case Format.R16_SInt:
|
||||
case Format.B5G6R5_UNorm:
|
||||
case Format.B5G5R5A1_UNorm:
|
||||
return 2;
|
||||
|
||||
case Format.R8_Typeless:
|
||||
case Format.R8_UNorm:
|
||||
case Format.R8_UInt:
|
||||
case Format.R8_SNorm:
|
||||
case Format.R8_SInt:
|
||||
case Format.A8_UNorm:
|
||||
return 1;
|
||||
|
||||
// Compressed format; http://msdn2.microsoft.com/en-us/library/bb694531(VS.85).aspx
|
||||
case Format.BC2_Typeless:
|
||||
case Format.BC2_UNorm:
|
||||
case Format.BC2_UNorm_SRgb:
|
||||
case Format.BC3_Typeless:
|
||||
case Format.BC3_UNorm:
|
||||
case Format.BC3_UNorm_SRgb:
|
||||
case Format.BC5_Typeless:
|
||||
case Format.BC5_UNorm:
|
||||
case Format.BC5_SNorm:
|
||||
return 16;
|
||||
|
||||
// Compressed format; http://msdn2.microsoft.com/en-us/library/bb694531(VS.85).aspx
|
||||
case Format.R1_UNorm:
|
||||
case Format.BC1_Typeless:
|
||||
case Format.BC1_UNorm:
|
||||
case Format.BC1_UNorm_SRgb:
|
||||
case Format.BC4_Typeless:
|
||||
case Format.BC4_UNorm:
|
||||
case Format.BC4_SNorm:
|
||||
return 8;
|
||||
|
||||
// Compressed format; http://msdn2.microsoft.com/en-us/library/bb694531(VS.85).aspx
|
||||
case Format.R9G9B9E5_Sharedexp:
|
||||
return 4;
|
||||
|
||||
// These are compressed, but bit-size information is unclear.
|
||||
case Format.R8G8_B8G8_UNorm:
|
||||
case Format.G8R8_G8B8_UNorm:
|
||||
return 4;
|
||||
|
||||
case Format.Unknown:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,376 @@
|
||||
using SharpDX.Direct3D11;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using CodeWalker.World;
|
||||
using System.Collections.Concurrent;
|
||||
using CodeWalker.GameFiles;
|
||||
using System.Threading;
|
||||
using CodeWalker.Properties;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public class RenderableCache
|
||||
{
|
||||
public DateTime LastUpdate = DateTime.Now;
|
||||
public DateTime LastUnload = DateTime.Now;
|
||||
public double CacheTime = Settings.Default.GPUCacheTime;// 10.0; //seconds to keep something that's not used
|
||||
public double UnloadTime = Settings.Default.GPUCacheFlushTime;// 0.1; //seconds between running unload cycles
|
||||
public int MaxItemsPerLoop = 1; //to keep things flowing
|
||||
public bool ItemsStillPending = false; //whether or not we need another content thread loop
|
||||
|
||||
public long TotalGraphicsMemoryUse
|
||||
{
|
||||
get
|
||||
{
|
||||
//return (GeometryCacheUse + TextureCacheUse + BoundCompCacheUse + InstanceCacheUse);
|
||||
return (renderables.CacheUse + textures.CacheUse + boundcomps.CacheUse + instbatches.CacheUse);
|
||||
}
|
||||
}
|
||||
public int LoadedRenderableCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return renderables.CurrentLoadedCount;// loadedRenderables.Count;
|
||||
}
|
||||
}
|
||||
public int LoadedTextureCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return textures.CurrentLoadedCount;// loadedTextures.Count;
|
||||
}
|
||||
}
|
||||
public int MemCachedRenderableCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return renderables.CurrentCacheCount;// cacheRenderables.Count;
|
||||
}
|
||||
}
|
||||
public int MemCachedTextureCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return textures.CurrentCacheCount;// cacheTextures.Count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private RenderableCacheLookup<DrawableBase, Renderable> renderables = new RenderableCacheLookup<DrawableBase, Renderable>(Settings.Default.GPUGeometryCacheSize, Settings.Default.GPUCacheTime);
|
||||
private RenderableCacheLookup<Texture, RenderableTexture> textures = new RenderableCacheLookup<Texture, RenderableTexture>(Settings.Default.GPUTextureCacheSize, Settings.Default.GPUCacheTime);
|
||||
private RenderableCacheLookup<BoundComposite, RenderableBoundComposite> boundcomps = new RenderableCacheLookup<BoundComposite, RenderableBoundComposite>(Settings.Default.GPUBoundCompCacheSize, Settings.Default.GPUCacheTime);
|
||||
private RenderableCacheLookup<YmapGrassInstanceBatch, RenderableInstanceBatch> instbatches = new RenderableCacheLookup<YmapGrassInstanceBatch, RenderableInstanceBatch>(67108864, Settings.Default.GPUCacheTime); //64MB - todo: make this a setting
|
||||
private RenderableCacheLookup<YmapDistantLODLights, RenderableDistantLODLights> distlodlights = new RenderableCacheLookup<YmapDistantLODLights, RenderableDistantLODLights>(33554432, Settings.Default.GPUCacheTime); //32MB - todo: make this a setting
|
||||
private RenderableCacheLookup<BasePathData, RenderablePathBatch> pathbatches = new RenderableCacheLookup<BasePathData, RenderablePathBatch>(536870912 /*33554432*/, Settings.Default.GPUCacheTime); // 512MB /*32MB*/ - todo: make this a setting
|
||||
private RenderableCacheLookup<WaterQuad, RenderableWaterQuad> waterquads = new RenderableCacheLookup<WaterQuad, RenderableWaterQuad>(4194304, Settings.Default.GPUCacheTime); //4MB - todo: make this a setting
|
||||
|
||||
|
||||
private object updateSyncRoot = new object();
|
||||
|
||||
private Device currentDevice;
|
||||
|
||||
|
||||
public void OnDeviceCreated(Device device)
|
||||
{
|
||||
currentDevice = device;
|
||||
}
|
||||
public void OnDeviceDestroyed()
|
||||
{
|
||||
currentDevice = null;
|
||||
|
||||
renderables.Clear();
|
||||
textures.Clear();
|
||||
boundcomps.Clear();
|
||||
instbatches.Clear();
|
||||
distlodlights.Clear();
|
||||
pathbatches.Clear();
|
||||
waterquads.Clear();
|
||||
}
|
||||
|
||||
public void ContentThreadProc()
|
||||
{
|
||||
if (currentDevice == null) return; //can't do anything with no device
|
||||
|
||||
Monitor.Enter(updateSyncRoot);
|
||||
|
||||
|
||||
//load the queued items if possible
|
||||
int renderablecount = renderables.LoadProc(currentDevice, MaxItemsPerLoop);
|
||||
int texturecount = textures.LoadProc(currentDevice, MaxItemsPerLoop);
|
||||
int boundcompcount = boundcomps.LoadProc(currentDevice, MaxItemsPerLoop);
|
||||
int instbatchcount = instbatches.LoadProc(currentDevice, MaxItemsPerLoop);
|
||||
int distlodlightcount = distlodlights.LoadProc(currentDevice, MaxItemsPerLoop);
|
||||
int pathbatchcount = pathbatches.LoadProc(currentDevice, MaxItemsPerLoop);
|
||||
int waterquadcount = waterquads.LoadProc(currentDevice, MaxItemsPerLoop);
|
||||
|
||||
|
||||
ItemsStillPending = (renderablecount >= MaxItemsPerLoop) ||
|
||||
(texturecount >= MaxItemsPerLoop) ||
|
||||
(boundcompcount >= MaxItemsPerLoop) ||
|
||||
(instbatchcount >= MaxItemsPerLoop) ||
|
||||
(distlodlightcount >= MaxItemsPerLoop) ||
|
||||
(pathbatchcount >= MaxItemsPerLoop) ||
|
||||
(waterquadcount >= MaxItemsPerLoop);
|
||||
|
||||
|
||||
//todo: change this to unload only when necessary (ie when something is loaded)
|
||||
var now = DateTime.Now;
|
||||
var deltat = (now - LastUpdate).TotalSeconds;
|
||||
var unloadt = (now - LastUnload).TotalSeconds;
|
||||
if ((unloadt > UnloadTime) && (deltat < 0.25)) //don't try the unload on every loop... or when really busy
|
||||
{
|
||||
|
||||
//unload items that haven't been used in longer than the cache period.
|
||||
renderables.UnloadProc();
|
||||
textures.UnloadProc();
|
||||
boundcomps.UnloadProc();
|
||||
instbatches.UnloadProc();
|
||||
distlodlights.UnloadProc();
|
||||
pathbatches.UnloadProc();
|
||||
waterquads.UnloadProc();
|
||||
|
||||
LastUnload = DateTime.Now;
|
||||
}
|
||||
|
||||
|
||||
LastUpdate = DateTime.Now;
|
||||
|
||||
Monitor.Exit(updateSyncRoot);
|
||||
}
|
||||
|
||||
public void RenderThreadSync()
|
||||
{
|
||||
renderables.RenderThreadSync();
|
||||
textures.RenderThreadSync();
|
||||
boundcomps.RenderThreadSync();
|
||||
instbatches.RenderThreadSync();
|
||||
distlodlights.RenderThreadSync();
|
||||
pathbatches.RenderThreadSync();
|
||||
waterquads.RenderThreadSync();
|
||||
}
|
||||
|
||||
public Renderable GetRenderable(DrawableBase drawable)
|
||||
{
|
||||
return renderables.Get(drawable);
|
||||
}
|
||||
public RenderableTexture GetRenderableTexture(Texture texture)
|
||||
{
|
||||
return textures.Get(texture);
|
||||
}
|
||||
public RenderableBoundComposite GetRenderableBoundComp(BoundComposite boundcomp)
|
||||
{
|
||||
return boundcomps.Get(boundcomp);
|
||||
}
|
||||
public RenderableInstanceBatch GetRenderableInstanceBatch(YmapGrassInstanceBatch batch)
|
||||
{
|
||||
return instbatches.Get(batch);
|
||||
}
|
||||
public RenderableDistantLODLights GetRenderableDistantLODLights(YmapDistantLODLights lights)
|
||||
{
|
||||
return distlodlights.Get(lights);
|
||||
}
|
||||
public RenderablePathBatch GetRenderablePathBatch(BasePathData pathdata)
|
||||
{
|
||||
return pathbatches.Get(pathdata);
|
||||
}
|
||||
public RenderableWaterQuad GetRenderableWaterQuad(WaterQuad quad)
|
||||
{
|
||||
return waterquads.Get(quad);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Invalidate(BasePathData path)
|
||||
{
|
||||
lock (updateSyncRoot)
|
||||
{
|
||||
pathbatches.Invalidate(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public abstract class RenderableCacheItem<TKey>
|
||||
{
|
||||
public TKey Key;
|
||||
public volatile bool IsLoaded = false;
|
||||
public volatile bool LoadQueued = false;
|
||||
public long LastUseTime = 0;
|
||||
//public DateTime LastUseTime { get; set; }
|
||||
public long DataSize { get; set; }
|
||||
|
||||
public abstract void Init(TKey key);
|
||||
public abstract void Load(Device device);
|
||||
public abstract void Unload();
|
||||
}
|
||||
|
||||
public class RenderableCacheLookup<TKey, TVal> where TVal: RenderableCacheItem<TKey>, new()
|
||||
{
|
||||
private ConcurrentStack<TVal> itemsToLoad = new ConcurrentStack<TVal>();
|
||||
private ConcurrentStack<TVal> itemsToUnload = new ConcurrentStack<TVal>();
|
||||
private LinkedList<TVal> loadeditems = new LinkedList<TVal>();
|
||||
private Dictionary<TKey, TVal> cacheitems = new Dictionary<TKey, TVal>();
|
||||
public long CacheLimit;
|
||||
public long CacheUse = 0;
|
||||
public double CacheTime;
|
||||
public int LoadedCount = 0;//temporary, per loop
|
||||
|
||||
public RenderableCacheLookup(long limit, double time)
|
||||
{
|
||||
CacheLimit = limit;
|
||||
CacheTime = time;
|
||||
}
|
||||
|
||||
public int CurrentLoadedCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return loadeditems.Count;
|
||||
}
|
||||
}
|
||||
public int CurrentCacheCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return cacheitems.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
TVal item;
|
||||
while (itemsToLoad.TryPop(out item))
|
||||
{ }
|
||||
foreach (TVal rnd in loadeditems)
|
||||
{
|
||||
rnd.Unload();
|
||||
}
|
||||
loadeditems.Clear();
|
||||
cacheitems.Clear();
|
||||
while (itemsToUnload.TryPop(out item))
|
||||
{ }
|
||||
}
|
||||
|
||||
|
||||
public int LoadProc(Device device, int maxitemsperloop)
|
||||
{
|
||||
TVal item;
|
||||
LoadedCount = 0;
|
||||
while (itemsToLoad.TryPop(out item))
|
||||
{
|
||||
if (item.IsLoaded) continue; //don't load it again...
|
||||
LoadedCount++;
|
||||
long gcachefree = CacheLimit - CacheUse;
|
||||
if (gcachefree > item.DataSize)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.Load(device);
|
||||
loadeditems.AddLast(item);
|
||||
Interlocked.Add(ref CacheUse, item.DataSize);
|
||||
}
|
||||
catch //(Exception ex)
|
||||
{
|
||||
//todo: error handling...
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item.LoadQueued = false; //can try load it again later..
|
||||
}
|
||||
if (LoadedCount >= maxitemsperloop) break;
|
||||
}
|
||||
return LoadedCount;
|
||||
}
|
||||
|
||||
public void UnloadProc()
|
||||
{
|
||||
//unload items that haven't been used in longer than the cache period.
|
||||
var now = DateTime.Now;
|
||||
var rnode = loadeditems.First;
|
||||
while (rnode != null)
|
||||
{
|
||||
var lu = DateTime.FromBinary(Interlocked.Read(ref rnode.Value.LastUseTime));
|
||||
if ((now - lu).TotalSeconds > CacheTime)
|
||||
{
|
||||
var nextnode = rnode.Next;
|
||||
itemsToUnload.Push(rnode.Value);
|
||||
loadeditems.Remove(rnode);
|
||||
rnode = nextnode;
|
||||
}
|
||||
else
|
||||
{
|
||||
rnode = rnode.Next;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void RenderThreadSync()
|
||||
{
|
||||
TVal item;
|
||||
while (itemsToUnload.TryPop(out item))
|
||||
{
|
||||
if ((item.Key != null) && (cacheitems.ContainsKey(item.Key)))
|
||||
{
|
||||
cacheitems.Remove(item.Key);
|
||||
}
|
||||
item.Unload();
|
||||
item.LoadQueued = false;
|
||||
Interlocked.Add(ref CacheUse, -item.DataSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public TVal Get(TKey key)
|
||||
{
|
||||
if (key == null) return null;
|
||||
TVal item = null;
|
||||
if (!cacheitems.TryGetValue(key, out item))
|
||||
{
|
||||
item = new TVal();
|
||||
item.Init(key);
|
||||
cacheitems.Add(key, item);
|
||||
}
|
||||
Interlocked.Exchange(ref item.LastUseTime, DateTime.Now.ToBinary());
|
||||
if ((!item.IsLoaded) && (!item.LoadQueued))// ||
|
||||
{
|
||||
item.LoadQueued = true;
|
||||
itemsToLoad.Push(item);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
public void Invalidate(TKey key)
|
||||
{
|
||||
if (key == null) return;
|
||||
TVal item = null;
|
||||
if (!cacheitems.TryGetValue(key, out item)) return;
|
||||
if (item == null) return;
|
||||
|
||||
if ((item.Key != null) && (cacheitems.ContainsKey(item.Key)))
|
||||
{
|
||||
|
||||
cacheitems.Remove(item.Key);
|
||||
|
||||
item.Unload();
|
||||
item.LoadQueued = false;
|
||||
Interlocked.Add(ref CacheUse, -item.DataSize);
|
||||
Interlocked.Exchange(ref item.LastUseTime, DateTime.Now.AddHours(-1).ToBinary());
|
||||
|
||||
loadeditems.Remove(item);//slow...
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,885 @@
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.DXGI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using SharpDX;
|
||||
using CodeWalker.GameFiles;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
|
||||
public struct BasicShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public Vector4 WindVector;
|
||||
}
|
||||
public struct BasicShaderVSEntityVars
|
||||
{
|
||||
public Vector4 CamRel;
|
||||
public Quaternion Orientation;
|
||||
public uint HasSkeleton;
|
||||
public uint HasTransforms;
|
||||
public uint TintPaletteIndex;
|
||||
public uint Pad1;
|
||||
public Vector3 Scale;
|
||||
public uint IsInstanced;
|
||||
}
|
||||
public struct BasicShaderVSModelVars
|
||||
{
|
||||
public Matrix Transform;
|
||||
}
|
||||
public struct BasicShaderVSGeomVars
|
||||
{
|
||||
public uint EnableTint;
|
||||
public float TintYVal;
|
||||
public uint IsDecal;
|
||||
public uint EnableWind;
|
||||
public Vector4 WindOverrideParams;
|
||||
}
|
||||
public struct BasicShaderPSSceneVars
|
||||
{
|
||||
public ShaderGlobalLightParams GlobalLights;
|
||||
public uint EnableShadows;
|
||||
public uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct
|
||||
public uint RenderModeIndex; //colour/texcoord index
|
||||
public uint RenderSamplerCoord; //which texcoord to use in single texture mode
|
||||
}
|
||||
public struct BasicShaderPSGeomVars
|
||||
{
|
||||
public uint EnableTexture;
|
||||
public uint EnableTint;
|
||||
public uint EnableNormalMap;
|
||||
public uint EnableSpecMap;
|
||||
public uint EnableDetailMap;
|
||||
public uint IsDecal;
|
||||
public uint IsEmissive;
|
||||
public uint IsDistMap;
|
||||
public float bumpiness;
|
||||
public float AlphaScale;
|
||||
public float HardAlphaBlend;
|
||||
public float useTessellation;
|
||||
public Vector4 detailSettings;
|
||||
public Vector3 specMapIntMask;
|
||||
public float specularIntensityMult;
|
||||
public float specularFalloffMult;
|
||||
public float specularFresnel;
|
||||
public float wetnessMultiplier;
|
||||
public uint SpecOnly;
|
||||
}
|
||||
public struct BasicShaderInstGlobalMatrix
|
||||
{
|
||||
public Vector4 Row1;
|
||||
public Vector4 Row2;
|
||||
public Vector4 Row3;
|
||||
}
|
||||
public struct BasicShaderInstGlobals
|
||||
{
|
||||
public BasicShaderInstGlobalMatrix M0;
|
||||
public BasicShaderInstGlobalMatrix M1;
|
||||
public BasicShaderInstGlobalMatrix M2;
|
||||
public BasicShaderInstGlobalMatrix M3;
|
||||
public BasicShaderInstGlobalMatrix M4;
|
||||
public BasicShaderInstGlobalMatrix M5;
|
||||
public BasicShaderInstGlobalMatrix M6;
|
||||
public BasicShaderInstGlobalMatrix M7;
|
||||
}
|
||||
public struct BasicShaderInstLocals
|
||||
{
|
||||
public Vector3 vecBatchAabbMin;
|
||||
public float instPad0;
|
||||
public Vector3 vecBatchAabbDelta;
|
||||
public float instPad1;
|
||||
public Vector4 vecPlayerPos;
|
||||
public Vector2 _vecCollParams;
|
||||
public Vector2 instPad2;
|
||||
public Vector4 fadeAlphaDistUmTimer;
|
||||
public Vector4 uMovementParams;
|
||||
public Vector4 _fakedGrassNormal;
|
||||
public Vector3 gScaleRange;
|
||||
public float instPad3;
|
||||
public Vector4 gWindBendingGlobals;
|
||||
public Vector2 gWindBendScaleVar;
|
||||
public float gAlphaTest;
|
||||
public float gAlphaToCoverageScale;
|
||||
public Vector3 gLodFadeInstRange;
|
||||
public uint gUseComputeShaderOutputBuffer;
|
||||
}
|
||||
|
||||
public class BasicShader : Shader, IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader basicvspnct;
|
||||
VertexShader basicvspncct;
|
||||
VertexShader basicvspncctt;
|
||||
VertexShader basicvspnccttt;
|
||||
VertexShader basicvspnctx;
|
||||
VertexShader basicvspncctx;
|
||||
VertexShader basicvspncttx;
|
||||
VertexShader basicvspnccttx;
|
||||
VertexShader basicvspnctttx;
|
||||
VertexShader basicvspncctttx;
|
||||
VertexShader basicvsbox;
|
||||
VertexShader basicvssphere;
|
||||
VertexShader basicvscapsule;
|
||||
VertexShader basicvscylinder;
|
||||
PixelShader basicps;
|
||||
GpuVarsBuffer<BasicShaderVSSceneVars> VSSceneVars;
|
||||
GpuVarsBuffer<BasicShaderVSEntityVars> VSEntityVars;
|
||||
GpuVarsBuffer<BasicShaderVSModelVars> VSModelVars;
|
||||
GpuVarsBuffer<BasicShaderVSGeomVars> VSGeomVars;
|
||||
GpuVarsBuffer<BasicShaderPSSceneVars> PSSceneVars;
|
||||
GpuVarsBuffer<BasicShaderPSGeomVars> PSGeomVars;
|
||||
GpuVarsBuffer<BasicShaderInstGlobals> InstGlobalVars;
|
||||
GpuVarsBuffer<BasicShaderInstLocals> InstLocalVars;
|
||||
SamplerState texsampler;
|
||||
SamplerState texsampleranis;
|
||||
SamplerState texsamplertnt;
|
||||
SamplerState texsamplertntyft;
|
||||
UnitCube cube; //for collision box render
|
||||
UnitSphere sphere; //for collision sphere render
|
||||
UnitCapsule capsule; //for collision capsule render
|
||||
UnitCylinder cylinder; //for collision cylinder render
|
||||
|
||||
public bool AnisotropicFilter = false;
|
||||
public bool DecalMode = false;
|
||||
public float AlphaScale = 1.0f;
|
||||
public Vector4 WindVector = Vector4.Zero;
|
||||
public WorldRenderMode RenderMode = WorldRenderMode.Default;
|
||||
public int RenderVertexColourIndex = 1;
|
||||
public int RenderTextureCoordIndex = 1;
|
||||
public int RenderTextureSamplerCoord = 1;
|
||||
public MetaName RenderTextureSampler = MetaName.DiffuseSampler;
|
||||
public bool SpecularEnable = true;
|
||||
|
||||
|
||||
|
||||
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
|
||||
|
||||
public BasicShader(Device device)
|
||||
{
|
||||
byte[] vspnctbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCT.cso");
|
||||
byte[] vspncctbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCT.cso");
|
||||
byte[] vspnccttbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCTT.cso");
|
||||
byte[] vspncctttbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCTTT.cso");
|
||||
byte[] vspnctxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCTX.cso");
|
||||
byte[] vspncctxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCTX.cso");
|
||||
byte[] vspncttxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCTTX.cso");
|
||||
byte[] vspnccttxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCTTX.cso");
|
||||
byte[] vspnctttxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCTTTX.cso");
|
||||
byte[] vspncctttxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCTTTX.cso");
|
||||
byte[] vsboxbytes = File.ReadAllBytes("Shaders\\BasicVS_Box.cso");
|
||||
byte[] vsspherebytes = File.ReadAllBytes("Shaders\\BasicVS_Sphere.cso");
|
||||
byte[] vscapsulebytes = File.ReadAllBytes("Shaders\\BasicVS_Capsule.cso");
|
||||
byte[] vscylinderbytes = File.ReadAllBytes("Shaders\\BasicVS_Cylinder.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\BasicPS.cso");
|
||||
|
||||
basicvspnct = new VertexShader(device, vspnctbytes);
|
||||
basicvspncct = new VertexShader(device, vspncctbytes);
|
||||
basicvspncctt = new VertexShader(device, vspnccttbytes);
|
||||
basicvspnccttt = new VertexShader(device, vspncctttbytes);
|
||||
basicvspnctx = new VertexShader(device, vspnctxbytes);
|
||||
basicvspncctx = new VertexShader(device, vspncctxbytes);
|
||||
basicvspncttx = new VertexShader(device, vspncttxbytes);
|
||||
basicvspnccttx = new VertexShader(device, vspnccttxbytes);
|
||||
basicvspnctttx = new VertexShader(device, vspnctttxbytes);
|
||||
basicvspncctttx = new VertexShader(device, vspncctttxbytes);
|
||||
basicvsbox = new VertexShader(device, vsboxbytes);
|
||||
basicvssphere = new VertexShader(device, vsspherebytes);
|
||||
basicvscapsule = new VertexShader(device, vscapsulebytes);
|
||||
basicvscylinder = new VertexShader(device, vscylinderbytes);
|
||||
basicps = new PixelShader(device, psbytes);
|
||||
|
||||
VSSceneVars = new GpuVarsBuffer<BasicShaderVSSceneVars>(device);
|
||||
VSEntityVars = new GpuVarsBuffer<BasicShaderVSEntityVars>(device);
|
||||
VSModelVars = new GpuVarsBuffer<BasicShaderVSModelVars>(device);
|
||||
VSGeomVars = new GpuVarsBuffer<BasicShaderVSGeomVars>(device);
|
||||
PSSceneVars = new GpuVarsBuffer<BasicShaderPSSceneVars>(device);
|
||||
PSGeomVars = new GpuVarsBuffer<BasicShaderPSGeomVars>(device);
|
||||
InstGlobalVars = new GpuVarsBuffer<BasicShaderInstGlobals>(device);
|
||||
InstLocalVars = new GpuVarsBuffer<BasicShaderInstLocals>(device);
|
||||
|
||||
InitInstGlobalVars();
|
||||
|
||||
|
||||
//supported layouts - requires Position, Normal, Colour, Texcoord
|
||||
layouts.Add(VertexType.Default, new InputLayout(device, vspnctbytes, VertexTypeDefault.GetLayout()));
|
||||
layouts.Add(VertexType.PNCH2, new InputLayout(device, vspnctbytes, VertexTypePNCH2.GetLayout()));
|
||||
|
||||
layouts.Add(VertexType.PCCNCT, new InputLayout(device, vspncctbytes, VertexTypePCCNCT.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCCT, new InputLayout(device, vspncctbytes, VertexTypePCCNCCT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCT, new InputLayout(device, vspncctbytes, VertexTypePNCCT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTT, new InputLayout(device, vspnccttbytes, VertexTypePNCCTT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTTT, new InputLayout(device, vspncctttbytes, VertexTypePNCCTTTT.GetLayout()));
|
||||
|
||||
|
||||
//normalmap layouts - requires Position, Normal, Colour, Texcoord, Tangent (X)
|
||||
layouts.Add(VertexType.DefaultEx, new InputLayout(device, vspnctxbytes, VertexTypeDefaultEx.GetLayout()));
|
||||
layouts.Add(VertexType.PCCH2H4, new InputLayout(device, vspnctxbytes, VertexTypePCCH2H4.GetLayout()));
|
||||
|
||||
layouts.Add(VertexType.PCCNCTX, new InputLayout(device, vspncctxbytes, VertexTypePCCNCTX.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCCTX, new InputLayout(device, vspncctxbytes, VertexTypePCCNCCTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTX, new InputLayout(device, vspncctxbytes, VertexTypePNCCTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTX, new InputLayout(device, vspncttxbytes, VertexTypePNCTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTX, new InputLayout(device, vspnccttxbytes, VertexTypePNCCTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTX_2, new InputLayout(device, vspnccttxbytes, VertexTypePNCCTTX_2.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCCTTX, new InputLayout(device, vspnccttxbytes, VertexTypePCCNCCTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTTX, new InputLayout(device, vspnctttxbytes, VertexTypePNCTTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTTX_2, new InputLayout(device, vspnctttxbytes, VertexTypePNCTTTX_2.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTTX_3, new InputLayout(device, vspnctttxbytes, VertexTypePNCTTTX_3.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTTTX, new InputLayout(device, vspnctttxbytes, VertexTypePNCTTTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTTX, new InputLayout(device, vspncctttxbytes, VertexTypePNCCTTTX.GetLayout()));
|
||||
|
||||
|
||||
layouts.Add(VertexType.PCCNCTT, new InputLayout(device, vspnccttbytes, VertexTypePCCNCTT.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCTTX, new InputLayout(device, vspnccttxbytes, VertexTypePCCNCTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCTTT, new InputLayout(device, vspncctttbytes, VertexTypePCCNCTTT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTT, new InputLayout(device, vspnctbytes, VertexTypePNCTT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTT, new InputLayout(device, vspnctbytes, VertexTypePNCTTT.GetLayout()));
|
||||
|
||||
|
||||
|
||||
texsampler = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipLinear,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
texsampleranis = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.Anisotropic,
|
||||
MaximumAnisotropy = 8,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
texsamplertnt = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Clamp,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.White,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipPoint,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
texsamplertntyft = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.White,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipPoint,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
|
||||
|
||||
cube = new UnitCube(device, vsboxbytes, false, false, true);
|
||||
sphere = new UnitSphere(device, vsspherebytes, 4);
|
||||
capsule = new UnitCapsule(device, vscapsulebytes, 4);
|
||||
cylinder = new UnitCylinder(device, vscylinderbytes, 8);
|
||||
}
|
||||
|
||||
private void InitInstGlobalVars()
|
||||
{
|
||||
var m0 = Matrix3x3.RotationZ(0.00f * (float)Math.PI);
|
||||
var m1 = Matrix3x3.RotationZ(0.25f * (float)Math.PI);
|
||||
var m2 = Matrix3x3.RotationZ(0.50f * (float)Math.PI);
|
||||
var m3 = Matrix3x3.RotationZ(0.75f * (float)Math.PI);
|
||||
var m4 = Matrix3x3.RotationZ(1.00f * (float)Math.PI);
|
||||
var m5 = Matrix3x3.RotationZ(1.25f * (float)Math.PI);
|
||||
var m6 = Matrix3x3.RotationZ(1.50f * (float)Math.PI);
|
||||
var m7 = Matrix3x3.RotationZ(1.75f * (float)Math.PI);
|
||||
|
||||
InstGlobalVars.Vars.M0.Row1 = new Vector4(m0.Row1, 1);
|
||||
InstGlobalVars.Vars.M0.Row2 = new Vector4(m0.Row2, 1);
|
||||
InstGlobalVars.Vars.M0.Row3 = new Vector4(m0.Row3, 1);
|
||||
InstGlobalVars.Vars.M1.Row1 = new Vector4(m1.Row1, 1);
|
||||
InstGlobalVars.Vars.M1.Row2 = new Vector4(m1.Row2, 1);
|
||||
InstGlobalVars.Vars.M1.Row3 = new Vector4(m1.Row3, 1);
|
||||
InstGlobalVars.Vars.M2.Row1 = new Vector4(m2.Row1, 1);
|
||||
InstGlobalVars.Vars.M2.Row2 = new Vector4(m2.Row2, 1);
|
||||
InstGlobalVars.Vars.M2.Row3 = new Vector4(m2.Row3, 1);
|
||||
InstGlobalVars.Vars.M3.Row1 = new Vector4(m3.Row1, 1);
|
||||
InstGlobalVars.Vars.M3.Row2 = new Vector4(m3.Row2, 1);
|
||||
InstGlobalVars.Vars.M3.Row3 = new Vector4(m3.Row3, 1);
|
||||
InstGlobalVars.Vars.M4.Row1 = new Vector4(m4.Row1, 1);
|
||||
InstGlobalVars.Vars.M4.Row2 = new Vector4(m4.Row2, 1);
|
||||
InstGlobalVars.Vars.M4.Row3 = new Vector4(m4.Row3, 1);
|
||||
InstGlobalVars.Vars.M5.Row1 = new Vector4(m5.Row1, 1);
|
||||
InstGlobalVars.Vars.M5.Row2 = new Vector4(m5.Row2, 1);
|
||||
InstGlobalVars.Vars.M5.Row3 = new Vector4(m5.Row3, 1);
|
||||
InstGlobalVars.Vars.M6.Row1 = new Vector4(m6.Row1, 1);
|
||||
InstGlobalVars.Vars.M6.Row2 = new Vector4(m6.Row2, 1);
|
||||
InstGlobalVars.Vars.M6.Row3 = new Vector4(m6.Row3, 1);
|
||||
InstGlobalVars.Vars.M7.Row1 = new Vector4(m7.Row1, 1);
|
||||
InstGlobalVars.Vars.M7.Row2 = new Vector4(m7.Row2, 1);
|
||||
InstGlobalVars.Vars.M7.Row3 = new Vector4(m7.Row3, 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void SetVertexShader(DeviceContext context, VertexType type)
|
||||
{
|
||||
VertexShader vs = basicvspnct;
|
||||
switch (type)
|
||||
{
|
||||
case VertexType.Default:
|
||||
case VertexType.PNCH2:
|
||||
case VertexType.PNCTT:
|
||||
case VertexType.PNCTTT:
|
||||
vs = basicvspnct;
|
||||
break;
|
||||
case VertexType.PCCNCT:
|
||||
case VertexType.PCCNCCT:
|
||||
case VertexType.PNCCT:
|
||||
vs = basicvspncct;
|
||||
break;
|
||||
case VertexType.PNCCTT://not used?
|
||||
case VertexType.PCCNCTT:
|
||||
vs = basicvspncctt;
|
||||
break;
|
||||
case VertexType.PNCCTTTT://not used?
|
||||
case VertexType.PCCNCTTT:
|
||||
vs = basicvspnccttt;
|
||||
break;
|
||||
case VertexType.DefaultEx:
|
||||
case VertexType.PCCH2H4:
|
||||
vs = basicvspnctx;
|
||||
break;
|
||||
|
||||
case VertexType.PCCNCTX:
|
||||
case VertexType.PCCNCCTX:
|
||||
case VertexType.PNCCTX:
|
||||
vs = basicvspncctx;
|
||||
break;
|
||||
|
||||
case VertexType.PNCTTX:
|
||||
vs = basicvspncttx;
|
||||
break;
|
||||
|
||||
case VertexType.PNCCTTX://not used?
|
||||
case VertexType.PNCCTTX_2://not used?
|
||||
case VertexType.PCCNCCTTX://not used?
|
||||
case VertexType.PCCNCTTX:
|
||||
vs = basicvspnccttx;
|
||||
break;
|
||||
|
||||
case VertexType.PNCTTTX:
|
||||
case VertexType.PNCTTTX_2:
|
||||
case VertexType.PNCTTTX_3:
|
||||
case VertexType.PNCTTTTX: //not using last texcoords!
|
||||
vs = basicvspnctttx;
|
||||
break;
|
||||
|
||||
case VertexType.PNCCTTTX://not used?
|
||||
vs = basicvspncctttx;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
context.VertexShader.Set(vs);
|
||||
}
|
||||
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.PixelShader.Set(basicps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
InputLayout l;
|
||||
if (layouts.TryGetValue(type, out l))
|
||||
{
|
||||
SetVertexShader(context, type);
|
||||
context.InputAssembler.InputLayout = l;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
uint rendermode = 0;
|
||||
uint rendermodeind = 1;
|
||||
|
||||
SpecularEnable = lights.SpecularEnabled;
|
||||
|
||||
switch (RenderMode)
|
||||
{
|
||||
case WorldRenderMode.VertexNormals:
|
||||
rendermode = 1;
|
||||
break;
|
||||
case WorldRenderMode.VertexTangents:
|
||||
rendermode = 2;
|
||||
break;
|
||||
case WorldRenderMode.VertexColour:
|
||||
rendermode = 3;
|
||||
rendermodeind = (uint)RenderVertexColourIndex;
|
||||
break;
|
||||
case WorldRenderMode.TextureCoord:
|
||||
rendermode = 4;
|
||||
rendermodeind = (uint)RenderTextureCoordIndex;
|
||||
break;
|
||||
case WorldRenderMode.SingleTexture:
|
||||
rendermode = 8;//direct mode
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSceneVars.Vars.WindVector = WindVector;
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 0);
|
||||
|
||||
PSSceneVars.Vars.GlobalLights = lights.Params;
|
||||
PSSceneVars.Vars.EnableShadows = (shadowmap != null) ? 1u : 0u;
|
||||
PSSceneVars.Vars.RenderMode = rendermode;
|
||||
PSSceneVars.Vars.RenderModeIndex = rendermodeind;
|
||||
PSSceneVars.Vars.RenderSamplerCoord = (uint)RenderTextureSamplerCoord;
|
||||
PSSceneVars.Update(context);
|
||||
PSSceneVars.SetPSCBuffer(context, 0);
|
||||
|
||||
if (shadowmap != null)
|
||||
{
|
||||
shadowmap.SetFinalRenderResources(context);
|
||||
}
|
||||
|
||||
if (!InstGlobalVars.Flag) //on the first frame, update the instance globals
|
||||
{
|
||||
InstGlobalVars.Update(context);
|
||||
InstGlobalVars.Flag = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = rend.Orientation;
|
||||
VSEntityVars.Vars.Scale = rend.Scale;
|
||||
VSEntityVars.Vars.HasSkeleton = rend.Renderable.HasSkeleton ? 1u : 0;
|
||||
VSEntityVars.Vars.HasTransforms = rend.Renderable.HasTransforms ? 1u : 0;
|
||||
VSEntityVars.Vars.TintPaletteIndex = rend.TintPaletteIndex;
|
||||
VSEntityVars.Vars.IsInstanced = 0;
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 2);
|
||||
}
|
||||
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
if (!model.UseTransform) return;
|
||||
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
|
||||
VSModelVars.Update(context);
|
||||
VSModelVars.SetVSCBuffer(context, 3);
|
||||
}
|
||||
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
RenderableTexture texture = null;
|
||||
RenderableTexture tintpal = null;
|
||||
RenderableTexture bumptex = null;
|
||||
RenderableTexture spectex = null;
|
||||
RenderableTexture detltex = null;
|
||||
bool isdistmap = false;
|
||||
|
||||
float tntpalind = 0.0f;
|
||||
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
|
||||
{
|
||||
if (RenderMode == WorldRenderMode.Default)
|
||||
{
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
if (itex == null) continue;
|
||||
switch (ihash)
|
||||
{
|
||||
case MetaName.DiffuseSampler:
|
||||
texture = itex;
|
||||
break;
|
||||
case MetaName.BumpSampler:
|
||||
bumptex = itex;
|
||||
break;
|
||||
case MetaName.SpecSampler:
|
||||
spectex = itex;
|
||||
break;
|
||||
case MetaName.DetailSampler:
|
||||
detltex = itex;
|
||||
break;
|
||||
case MetaName.TintPaletteSampler:
|
||||
tintpal = itex;
|
||||
if (tintpal.Key != null)
|
||||
{
|
||||
//this is slightly dodgy but VSEntityVars should have the correct value in it...
|
||||
tntpalind = (VSEntityVars.Vars.TintPaletteIndex + 0.5f) / tintpal.Key.Height;
|
||||
}
|
||||
break;
|
||||
case MetaName.distanceMapSampler:
|
||||
texture = itex;
|
||||
isdistmap = true;
|
||||
break;
|
||||
case MetaName.heightSampler:
|
||||
case MetaName.EnvironmentSampler:
|
||||
break;
|
||||
case MetaName.FlowSampler:
|
||||
case MetaName.FogSampler:
|
||||
case MetaName.FoamSampler:
|
||||
if (texture == null) texture = itex;
|
||||
break;
|
||||
default:
|
||||
if (texture == null) texture = itex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (RenderMode == WorldRenderMode.SingleTexture)
|
||||
{
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
if (ihash == RenderTextureSampler)
|
||||
{
|
||||
texture = itex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool usediff = ((texture != null) && (texture.ShaderResourceView != null));
|
||||
bool usebump = ((bumptex != null) && (bumptex.ShaderResourceView != null));
|
||||
bool usespec = ((spectex != null) && (spectex.ShaderResourceView != null));
|
||||
bool usedetl = ((detltex != null) && (detltex.ShaderResourceView != null));
|
||||
bool usetint = ((tintpal != null) && (tintpal.ShaderResourceView != null));
|
||||
|
||||
uint tintflag = 0;
|
||||
if (usetint) tintflag = 1;
|
||||
|
||||
uint windflag = geom.EnableWind ? 1u : 0u;
|
||||
uint emflag = geom.IsEmissive ? 1u : 0u;
|
||||
var shaderName = geom.DrawableGeom.Shader.Name;
|
||||
var shaderFile = geom.DrawableGeom.Shader.FileName;
|
||||
switch (shaderFile.Hash)
|
||||
{
|
||||
case 2245870123: //trees_normal_diffspec_tnt.sps
|
||||
case 3334613197: //trees_tnt.sps
|
||||
case 1229591973://{trees_normal_spec_tnt.sps}
|
||||
if (usetint) tintflag = 2; //use 2nd vertex colour channel for tint...
|
||||
break;
|
||||
case 3880384844://{decal_spec_only.sps}w
|
||||
case 600733812://{decal_amb_only.sps}
|
||||
case 2842248626://{spec_decal.sps}
|
||||
case 2457676400://{reflect_decal.sps}
|
||||
case 2706821972://{mirror_decal.sps}
|
||||
//if (RenderMode == WorldRenderMode.Default) usediff = false;
|
||||
break;
|
||||
}
|
||||
|
||||
uint pstintflag = tintflag;
|
||||
if (VSEntityVars.Vars.IsInstanced>0)
|
||||
{
|
||||
pstintflag = 1;
|
||||
switch (shaderFile.Hash)
|
||||
{
|
||||
case 916743331: //{grass_batch.sps}
|
||||
windflag = 1;
|
||||
break;
|
||||
case 3833671083://{normal_spec_batch.sps}
|
||||
windflag = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PSGeomVars.Vars.EnableTexture = usediff ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableTint = pstintflag;
|
||||
PSGeomVars.Vars.EnableNormalMap = usebump ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableSpecMap = usespec ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableDetailMap = usedetl ? 1u : 0u;
|
||||
PSGeomVars.Vars.IsDecal = DecalMode ? 1u : 0u;
|
||||
PSGeomVars.Vars.IsEmissive = emflag;
|
||||
PSGeomVars.Vars.IsDistMap = isdistmap ? 1u : 0u;
|
||||
PSGeomVars.Vars.bumpiness = geom.bumpiness;
|
||||
PSGeomVars.Vars.AlphaScale = isdistmap ? 1.0f : AlphaScale;
|
||||
PSGeomVars.Vars.HardAlphaBlend = 0.0f; //todo: cutouts flag!
|
||||
PSGeomVars.Vars.useTessellation = 0.0f;
|
||||
PSGeomVars.Vars.detailSettings = geom.detailSettings;
|
||||
PSGeomVars.Vars.specMapIntMask = geom.specMapIntMask;
|
||||
PSGeomVars.Vars.specularIntensityMult = SpecularEnable ? geom.specularIntensityMult : 0.0f;
|
||||
PSGeomVars.Vars.specularFalloffMult = geom.specularFalloffMult;
|
||||
PSGeomVars.Vars.specularFresnel = geom.specularFresnel;
|
||||
PSGeomVars.Vars.wetnessMultiplier = geom.wetnessMultiplier;
|
||||
PSGeomVars.Vars.SpecOnly = geom.SpecOnly ? 1u : 0u;
|
||||
PSGeomVars.Update(context);
|
||||
PSGeomVars.SetPSCBuffer(context, 2);
|
||||
|
||||
VSGeomVars.Vars.EnableTint = tintflag;
|
||||
VSGeomVars.Vars.TintYVal = tntpalind;
|
||||
VSGeomVars.Vars.IsDecal = DecalMode ? 1u : 0u;
|
||||
VSGeomVars.Vars.EnableWind = windflag;
|
||||
VSGeomVars.Vars.WindOverrideParams = geom.WindOverrideParams;
|
||||
VSGeomVars.Update(context);
|
||||
VSGeomVars.SetVSCBuffer(context, 4);
|
||||
|
||||
context.VertexShader.SetSampler(0, geom.IsFragment ? texsamplertntyft : texsamplertnt);
|
||||
context.PixelShader.SetSampler(0, AnisotropicFilter ? texsampleranis : texsampler);
|
||||
if (usediff)
|
||||
{
|
||||
texture.SetPSResource(context, 0);
|
||||
}
|
||||
if (usebump)
|
||||
{
|
||||
bumptex.SetPSResource(context, 2);
|
||||
}
|
||||
if (usespec)
|
||||
{
|
||||
spectex.SetPSResource(context, 3);
|
||||
}
|
||||
if (usedetl)
|
||||
{
|
||||
detltex.SetPSResource(context, 4);
|
||||
}
|
||||
if (usetint)
|
||||
{
|
||||
tintpal.SetVSResource(context, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetInstanceVars(DeviceContext context, RenderableInstanceBatch batch)
|
||||
{
|
||||
var gb = batch.Key;
|
||||
|
||||
VSEntityVars.Vars.CamRel = new Vector4(gb.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = Quaternion.Identity;
|
||||
VSEntityVars.Vars.Scale = Vector3.One;
|
||||
VSEntityVars.Vars.HasSkeleton = 0;
|
||||
VSEntityVars.Vars.HasTransforms = 0;
|
||||
VSEntityVars.Vars.TintPaletteIndex = 0;
|
||||
VSEntityVars.Vars.IsInstanced = 1;
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 2);
|
||||
|
||||
InstGlobalVars.SetVSCBuffer(context, 5);
|
||||
|
||||
InstLocalVars.Vars.vecBatchAabbMin = gb.AABBMin;
|
||||
InstLocalVars.Vars.vecBatchAabbDelta = gb.AABBMax - gb.AABBMin;
|
||||
InstLocalVars.Vars.vecPlayerPos = new Vector4(gb.Position - gb.CamRel, 1.0f);
|
||||
InstLocalVars.Vars._vecCollParams = new Vector2(2.0f, -3.0f);//range, offset
|
||||
InstLocalVars.Vars.fadeAlphaDistUmTimer = new Vector4(0.0f);
|
||||
InstLocalVars.Vars.uMovementParams = new Vector4(0.0f);
|
||||
InstLocalVars.Vars._fakedGrassNormal = new Vector4(Vector3.Normalize(-gb.CamRel), 0.0f);
|
||||
InstLocalVars.Vars.gScaleRange = gb.Batch.ScaleRange;
|
||||
InstLocalVars.Vars.gWindBendingGlobals = new Vector4(WindVector.X, WindVector.Y, 1.0f, 1.0f);
|
||||
InstLocalVars.Vars.gWindBendScaleVar = new Vector2(WindVector.Z, WindVector.W);
|
||||
InstLocalVars.Vars.gAlphaTest = 0.0f;
|
||||
InstLocalVars.Vars.gAlphaToCoverageScale = 1.0f;
|
||||
InstLocalVars.Vars.gLodFadeInstRange = new Vector3(gb.Batch.LodInstFadeRange, gb.Batch.LodFadeStartDist, gb.Batch.lodDist);
|
||||
InstLocalVars.Vars.gUseComputeShaderOutputBuffer = 0;
|
||||
InstLocalVars.Update(context);
|
||||
InstLocalVars.SetVSCBuffer(context, 6);
|
||||
|
||||
|
||||
context.VertexShader.SetShaderResource(2, batch.GrassInstanceBuffer.SRV);
|
||||
}
|
||||
|
||||
|
||||
public void RenderBoundGeom(DeviceContext context, RenderableBoundGeometryInst inst)
|
||||
{
|
||||
|
||||
|
||||
VSEntityVars.Vars.CamRel = new Vector4(inst.Inst.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = inst.Inst.Orientation;
|
||||
VSEntityVars.Vars.Scale = inst.Inst.Scale;
|
||||
VSEntityVars.Vars.HasSkeleton = 0;
|
||||
VSEntityVars.Vars.HasTransforms = 0; //todo! bounds transforms..?
|
||||
VSEntityVars.Vars.TintPaletteIndex = 0;
|
||||
VSEntityVars.Vars.IsInstanced = 0;
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 2);
|
||||
|
||||
PSGeomVars.Vars.EnableTexture = 0;
|
||||
PSGeomVars.Vars.EnableTint = 0;
|
||||
PSGeomVars.Vars.EnableNormalMap = 0;
|
||||
PSGeomVars.Vars.EnableSpecMap = 0;
|
||||
PSGeomVars.Vars.EnableDetailMap = 0;
|
||||
PSGeomVars.Vars.IsDecal = 0;
|
||||
PSGeomVars.Vars.IsEmissive = 0;
|
||||
PSGeomVars.Vars.IsDistMap = 0;
|
||||
PSGeomVars.Vars.bumpiness = 0;
|
||||
PSGeomVars.Vars.AlphaScale = 1;
|
||||
PSGeomVars.Vars.HardAlphaBlend = 0;
|
||||
PSGeomVars.Vars.useTessellation = 0;
|
||||
PSGeomVars.Vars.detailSettings = Vector4.Zero;
|
||||
PSGeomVars.Vars.specMapIntMask = Vector3.Zero;
|
||||
PSGeomVars.Vars.specularIntensityMult = 1.0f;
|
||||
PSGeomVars.Vars.specularFalloffMult = 1.0f;
|
||||
PSGeomVars.Vars.specularFresnel = 1.0f;
|
||||
PSGeomVars.Vars.wetnessMultiplier = 0.0f;
|
||||
PSGeomVars.Vars.SpecOnly = 0;
|
||||
PSGeomVars.Update(context);
|
||||
PSGeomVars.SetPSCBuffer(context, 2);
|
||||
|
||||
VSGeomVars.Vars.EnableTint = 0;
|
||||
VSGeomVars.Vars.TintYVal = 0.0f;
|
||||
VSGeomVars.Vars.IsDecal = 0;
|
||||
VSGeomVars.Vars.EnableWind = 0;
|
||||
VSGeomVars.Vars.WindOverrideParams = Vector4.Zero;
|
||||
VSGeomVars.Update(context);
|
||||
VSGeomVars.SetVSCBuffer(context, 4);
|
||||
|
||||
|
||||
if (inst.Geom.VertexBuffer != null) //render the triangles
|
||||
{
|
||||
SetVertexShader(context, VertexType.Default);
|
||||
SetInputLayout(context, VertexType.Default);
|
||||
inst.Geom.RenderTriangles(context);
|
||||
}
|
||||
|
||||
//render the boxes
|
||||
if (inst.Geom.BoxBuffer != null)
|
||||
{
|
||||
context.VertexShader.Set(basicvsbox);
|
||||
context.VertexShader.SetShaderResource(1, inst.Geom.BoxBuffer.SRV);
|
||||
cube.DrawInstanced(context, inst.Geom.BoxBuffer.StructCount);
|
||||
}
|
||||
|
||||
//render the spheres
|
||||
if (inst.Geom.SphereBuffer != null)
|
||||
{
|
||||
context.VertexShader.Set(basicvssphere);
|
||||
context.VertexShader.SetShaderResource(1, inst.Geom.SphereBuffer.SRV);
|
||||
sphere.DrawInstanced(context, inst.Geom.SphereBuffer.StructCount);
|
||||
}
|
||||
|
||||
//render the capsules
|
||||
if (inst.Geom.CapsuleBuffer != null)
|
||||
{
|
||||
context.VertexShader.Set(basicvscapsule);
|
||||
context.VertexShader.SetShaderResource(1, inst.Geom.CapsuleBuffer.SRV);
|
||||
capsule.DrawInstanced(context, inst.Geom.CapsuleBuffer.StructCount);
|
||||
}
|
||||
|
||||
//render the cylinders
|
||||
if (inst.Geom.CylinderBuffer != null)
|
||||
{
|
||||
context.VertexShader.Set(basicvscylinder);
|
||||
context.VertexShader.SetShaderResource(1, inst.Geom.CylinderBuffer.SRV);
|
||||
cylinder.DrawInstanced(context, inst.Geom.CylinderBuffer.StructCount);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.PixelShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetConstantBuffer(1, null); //shadowmap
|
||||
context.PixelShader.SetConstantBuffer(1, null); //shadowmap
|
||||
context.PixelShader.SetShaderResource(1, null);//shadowmap
|
||||
context.PixelShader.SetSampler(1, null); //shadowmap
|
||||
context.VertexShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(3, null);
|
||||
context.PixelShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(4, null);
|
||||
context.VertexShader.SetConstantBuffer(5, null);
|
||||
context.VertexShader.SetConstantBuffer(6, null);
|
||||
context.VertexShader.SetSampler(0, null);
|
||||
context.PixelShader.SetSampler(0, null);
|
||||
context.PixelShader.SetShaderResource(0, null);
|
||||
context.PixelShader.SetShaderResource(2, null);
|
||||
context.PixelShader.SetShaderResource(3, null);
|
||||
context.PixelShader.SetShaderResource(4, null);
|
||||
context.VertexShader.SetShaderResource(0, null);
|
||||
context.VertexShader.SetShaderResource(1, null);
|
||||
context.VertexShader.SetShaderResource(2, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
|
||||
cube.Dispose();
|
||||
sphere.Dispose();
|
||||
capsule.Dispose();
|
||||
cylinder.Dispose();
|
||||
|
||||
texsampler.Dispose();
|
||||
texsampleranis.Dispose();
|
||||
texsamplertnt.Dispose();
|
||||
|
||||
foreach (InputLayout layout in layouts.Values)
|
||||
{
|
||||
layout.Dispose();
|
||||
}
|
||||
layouts.Clear();
|
||||
|
||||
VSSceneVars.Dispose();
|
||||
VSEntityVars.Dispose();
|
||||
VSModelVars.Dispose();
|
||||
VSGeomVars.Dispose();
|
||||
PSSceneVars.Dispose();
|
||||
PSGeomVars.Dispose();
|
||||
InstGlobalVars.Dispose();
|
||||
InstLocalVars.Dispose();
|
||||
|
||||
basicps.Dispose();
|
||||
basicvspnct.Dispose();
|
||||
basicvspncct.Dispose();
|
||||
basicvspncctt.Dispose();
|
||||
basicvspnccttt.Dispose();
|
||||
basicvspnctx.Dispose();
|
||||
basicvspncctx.Dispose();
|
||||
basicvspncttx.Dispose();
|
||||
basicvspnccttx.Dispose();
|
||||
basicvspnctttx.Dispose();
|
||||
basicvspncctttx.Dispose();
|
||||
basicvsbox.Dispose();
|
||||
basicvssphere.Dispose();
|
||||
basicvscapsule.Dispose();
|
||||
basicvscylinder.Dispose();
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D11;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using CodeWalker.GameFiles;
|
||||
using System.IO;
|
||||
using SharpDX.DXGI;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
|
||||
public struct BoundingSphereVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public Matrix ViewInv;
|
||||
public float SegmentCount;
|
||||
public float VertexCount;
|
||||
public float Pad1;
|
||||
public float Pad2;
|
||||
}
|
||||
public struct BoundingSphereVSSphereVars
|
||||
{
|
||||
public Vector3 Center;
|
||||
public float Radius;
|
||||
}
|
||||
public struct BoundingBoxVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
}
|
||||
public struct BoundingBoxVSBoxVars
|
||||
{
|
||||
public Quaternion Orientation;
|
||||
public Vector4 BBMin;
|
||||
public Vector4 BBRng; //max-min
|
||||
public Vector3 CamRel;
|
||||
public float Pad1;
|
||||
public Vector3 Scale;
|
||||
public float Pad2;
|
||||
}
|
||||
public struct BoundsPSColourVars
|
||||
{
|
||||
public Vector4 Colour;
|
||||
}
|
||||
|
||||
|
||||
public class BoundsShader : Shader, IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
BoundsShaderMode mode = BoundsShaderMode.Sphere;
|
||||
VertexShader spherevs;
|
||||
VertexShader boxvs;
|
||||
PixelShader boundsps;
|
||||
|
||||
GpuVarsBuffer<BoundingSphereVSSceneVars> VSSphereSceneVars;
|
||||
GpuVarsBuffer<BoundingSphereVSSphereVars> VSSphereVars;
|
||||
GpuVarsBuffer<BoundingBoxVSSceneVars> VSBoxSceneVars;
|
||||
GpuVarsBuffer<BoundingBoxVSBoxVars> VSBoxVars;
|
||||
GpuVarsBuffer<BoundsPSColourVars> PSColourVars;
|
||||
|
||||
int SegmentCount = 64;
|
||||
int VertexCount = 65;
|
||||
UnitCube cube;
|
||||
|
||||
public BoundsShader(Device device)
|
||||
{
|
||||
byte[] spherevsbytes = File.ReadAllBytes("Shaders\\BoundingSphereVS.cso");
|
||||
byte[] boxvsbytes = File.ReadAllBytes("Shaders\\BoundingBoxVS.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\BoundsPS.cso");
|
||||
|
||||
spherevs = new VertexShader(device, spherevsbytes);
|
||||
boxvs = new VertexShader(device, boxvsbytes);
|
||||
boundsps = new PixelShader(device, psbytes);
|
||||
|
||||
VSSphereSceneVars = new GpuVarsBuffer<BoundingSphereVSSceneVars>(device);
|
||||
VSSphereVars = new GpuVarsBuffer<BoundingSphereVSSphereVars>(device);
|
||||
VSBoxSceneVars = new GpuVarsBuffer<BoundingBoxVSSceneVars>(device);
|
||||
VSBoxVars = new GpuVarsBuffer<BoundingBoxVSBoxVars>(device);
|
||||
PSColourVars = new GpuVarsBuffer<BoundsPSColourVars>(device);
|
||||
|
||||
cube = new UnitCube(device, boxvsbytes, false, true, false);
|
||||
}
|
||||
|
||||
|
||||
public void SetMode(BoundsShaderMode m)
|
||||
{
|
||||
mode = m;
|
||||
}
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
default:
|
||||
case BoundsShaderMode.Sphere:
|
||||
context.VertexShader.Set(spherevs);
|
||||
break;
|
||||
case BoundsShaderMode.Box:
|
||||
context.VertexShader.Set(boxvs);
|
||||
break;
|
||||
}
|
||||
context.PixelShader.Set(boundsps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
//switch (mode)
|
||||
//{
|
||||
// default:
|
||||
// case BoundsShaderMode.Sphere:
|
||||
// context.InputAssembler.InputLayout = null;
|
||||
// break;
|
||||
// case BoundsShaderMode.Box:
|
||||
// context.InputAssembler.InputLayout = cube.InputLayout;
|
||||
// break;
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
default:
|
||||
case BoundsShaderMode.Sphere:
|
||||
VSSphereSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSphereSceneVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix);
|
||||
VSSphereSceneVars.Vars.SegmentCount = (float)SegmentCount;
|
||||
VSSphereSceneVars.Vars.VertexCount = (float)VertexCount;
|
||||
VSSphereSceneVars.Update(context);
|
||||
VSSphereSceneVars.SetVSCBuffer(context, 0);
|
||||
break;
|
||||
case BoundsShaderMode.Box:
|
||||
VSBoxSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSBoxSceneVars.Update(context);
|
||||
VSBoxSceneVars.SetVSCBuffer(context, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSphereVars(DeviceContext context, Vector3 center, float radius)
|
||||
{
|
||||
VSSphereVars.Vars.Center = center;
|
||||
VSSphereVars.Vars.Radius = radius;
|
||||
VSSphereVars.Update(context);
|
||||
VSSphereVars.SetVSCBuffer(context, 1);
|
||||
}
|
||||
|
||||
public void SetBoxVars(DeviceContext context, Vector3 camrel, Vector3 bbmin, Vector3 bbmax, Quaternion orientation, Vector3 scale)
|
||||
{
|
||||
VSBoxVars.Vars.Orientation = orientation;
|
||||
VSBoxVars.Vars.BBMin = new Vector4(bbmin, 0.0f);
|
||||
VSBoxVars.Vars.BBRng = new Vector4(bbmax - bbmin, 0.0f);
|
||||
VSBoxVars.Vars.CamRel = camrel;
|
||||
VSBoxVars.Vars.Scale = scale;
|
||||
VSBoxVars.Update(context);
|
||||
VSBoxVars.SetVSCBuffer(context, 1);
|
||||
}
|
||||
|
||||
public void SetColourVars(DeviceContext context, Vector4 colour)
|
||||
{
|
||||
PSColourVars.Vars.Colour = colour;
|
||||
PSColourVars.Update(context);
|
||||
PSColourVars.SetPSCBuffer(context, 0);
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
//don't use this one
|
||||
}
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
//don't use this
|
||||
}
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
//don't use this
|
||||
}
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetConstantBuffer(1, null);
|
||||
context.PixelShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
|
||||
public void DrawSphere(DeviceContext context)
|
||||
{
|
||||
context.InputAssembler.InputLayout = null;
|
||||
context.InputAssembler.SetIndexBuffer(null, Format.Unknown, 0);
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineStrip;
|
||||
context.Draw(VertexCount, 0);
|
||||
}
|
||||
|
||||
public void DrawBox(DeviceContext context)
|
||||
{
|
||||
cube.Draw(context);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
|
||||
VSSphereSceneVars.Dispose();
|
||||
VSSphereVars.Dispose();
|
||||
VSBoxSceneVars.Dispose();
|
||||
VSBoxVars.Dispose();
|
||||
PSColourVars.Dispose();
|
||||
|
||||
cube.Dispose();
|
||||
|
||||
boundsps.Dispose();
|
||||
boxvs.Dispose();
|
||||
spherevs.Dispose();
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum BoundsShaderMode
|
||||
{
|
||||
None = 0,
|
||||
Sphere = 1,
|
||||
Box = 2,
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.DXGI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using SharpDX;
|
||||
using CodeWalker.GameFiles;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
|
||||
public struct CableShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
}
|
||||
public struct CableShaderVSEntityVars
|
||||
{
|
||||
public Vector4 CamRel;
|
||||
public Quaternion Orientation;
|
||||
public uint HasSkeleton;
|
||||
public uint HasTransforms;
|
||||
public uint TintPaletteIndex;
|
||||
public uint Pad1;
|
||||
public Vector3 Scale;
|
||||
public uint IsInstanced;
|
||||
}
|
||||
public struct CableShaderVSModelVars
|
||||
{
|
||||
public Matrix Transform;
|
||||
}
|
||||
public struct CableShaderVSGeomVars
|
||||
{
|
||||
public uint EnableTint;
|
||||
public float TintYVal;
|
||||
public uint IsDecal;
|
||||
public uint Pad5;
|
||||
}
|
||||
public struct CableShaderPSSceneVars
|
||||
{
|
||||
public ShaderGlobalLightParams GlobalLights;
|
||||
public uint EnableShadows;
|
||||
public uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct
|
||||
public uint RenderModeIndex; //colour/texcoord index
|
||||
public uint RenderSamplerCoord; //which texcoord to use in single texture mode
|
||||
}
|
||||
public struct CableShaderPSGeomVars
|
||||
{
|
||||
public uint EnableTexture;
|
||||
public uint EnableTint;
|
||||
public uint Pad100;
|
||||
public uint Pad101;
|
||||
}
|
||||
|
||||
public class CableShader : Shader, IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader vs;
|
||||
PixelShader ps;
|
||||
GpuVarsBuffer<CableShaderVSSceneVars> VSSceneVars;
|
||||
GpuVarsBuffer<CableShaderVSEntityVars> VSEntityVars;
|
||||
GpuVarsBuffer<CableShaderVSModelVars> VSModelVars;
|
||||
GpuVarsBuffer<CableShaderVSGeomVars> VSGeomVars;
|
||||
GpuVarsBuffer<CableShaderPSSceneVars> PSSceneVars;
|
||||
GpuVarsBuffer<CableShaderPSGeomVars> PSGeomVars;
|
||||
SamplerState texsampler;
|
||||
|
||||
public WorldRenderMode RenderMode = WorldRenderMode.Default;
|
||||
public int RenderVertexColourIndex = 1;
|
||||
public int RenderTextureCoordIndex = 1;
|
||||
public int RenderTextureSamplerCoord = 1;
|
||||
public MetaName RenderTextureSampler = MetaName.DiffuseSampler;
|
||||
|
||||
|
||||
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
|
||||
|
||||
public CableShader(Device device)
|
||||
{
|
||||
byte[] vsbytes = File.ReadAllBytes("Shaders\\CableVS.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\CablePS.cso");
|
||||
|
||||
vs = new VertexShader(device, vsbytes);
|
||||
ps = new PixelShader(device, psbytes);
|
||||
|
||||
|
||||
VSSceneVars = new GpuVarsBuffer<CableShaderVSSceneVars>(device);
|
||||
VSEntityVars = new GpuVarsBuffer<CableShaderVSEntityVars>(device);
|
||||
VSModelVars = new GpuVarsBuffer<CableShaderVSModelVars>(device);
|
||||
VSGeomVars = new GpuVarsBuffer<CableShaderVSGeomVars>(device);
|
||||
PSSceneVars = new GpuVarsBuffer<CableShaderPSSceneVars>(device);
|
||||
PSGeomVars = new GpuVarsBuffer<CableShaderPSGeomVars>(device);
|
||||
|
||||
|
||||
//supported layout - requires Position, Normal, Colour, Texcoord
|
||||
layouts.Add(VertexType.Default, new InputLayout(device, vsbytes, VertexTypeDefault.GetLayout()));
|
||||
|
||||
|
||||
|
||||
texsampler = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipLinear,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void SetVertexShader(DeviceContext context, VertexType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case VertexType.Default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
context.VertexShader.Set(vs);
|
||||
}
|
||||
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.PixelShader.Set(ps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
InputLayout l;
|
||||
if (layouts.TryGetValue(type, out l))
|
||||
{
|
||||
SetVertexShader(context, type);
|
||||
context.InputAssembler.InputLayout = l;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
uint rendermode = 0;
|
||||
uint rendermodeind = 1;
|
||||
|
||||
switch (RenderMode)
|
||||
{
|
||||
case WorldRenderMode.VertexNormals:
|
||||
rendermode = 1;
|
||||
break;
|
||||
case WorldRenderMode.VertexTangents:
|
||||
rendermode = 2;
|
||||
break;
|
||||
case WorldRenderMode.VertexColour:
|
||||
rendermode = 3;
|
||||
rendermodeind = (uint)RenderVertexColourIndex;
|
||||
break;
|
||||
case WorldRenderMode.TextureCoord:
|
||||
rendermode = 4;
|
||||
rendermodeind = (uint)RenderTextureCoordIndex;
|
||||
break;
|
||||
case WorldRenderMode.SingleTexture:
|
||||
rendermode = 8;//direct mode
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 0);
|
||||
|
||||
PSSceneVars.Vars.GlobalLights = lights.Params;
|
||||
PSSceneVars.Vars.EnableShadows = (shadowmap != null) ? 1u : 0u;
|
||||
PSSceneVars.Vars.RenderMode = rendermode;
|
||||
PSSceneVars.Vars.RenderModeIndex = rendermodeind;
|
||||
PSSceneVars.Vars.RenderSamplerCoord = (uint)RenderTextureSamplerCoord;
|
||||
PSSceneVars.Update(context);
|
||||
PSSceneVars.SetPSCBuffer(context, 0);
|
||||
|
||||
if (shadowmap != null)
|
||||
{
|
||||
shadowmap.SetFinalRenderResources(context);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = rend.Orientation;
|
||||
VSEntityVars.Vars.Scale = rend.Scale;
|
||||
VSEntityVars.Vars.HasSkeleton = rend.Renderable.HasSkeleton ? 1u : 0;
|
||||
VSEntityVars.Vars.HasTransforms = rend.Renderable.HasTransforms ? 1u : 0;
|
||||
VSEntityVars.Vars.TintPaletteIndex = rend.TintPaletteIndex;
|
||||
VSEntityVars.Vars.IsInstanced = 0;
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 2);
|
||||
}
|
||||
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
if (!model.UseTransform) return;
|
||||
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
|
||||
VSModelVars.Update(context);
|
||||
VSModelVars.SetVSCBuffer(context, 3);
|
||||
}
|
||||
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
RenderableTexture texture = null; // ((geom.Textures != null) && (geom.Textures.Length > 0)) ? geom.Textures[0] : null;
|
||||
|
||||
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
|
||||
{
|
||||
|
||||
if (RenderMode == WorldRenderMode.Default)
|
||||
{
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
switch (ihash)
|
||||
{
|
||||
case MetaName.DiffuseSampler:
|
||||
texture = itex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////fallback try get first texture... eventaully remove this! (helps with water for now)
|
||||
//int index = 0;
|
||||
//while (((texture == null) || (texture.Texture2D == null)) && (index < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[index];
|
||||
// index++;
|
||||
//}
|
||||
}
|
||||
else if (RenderMode == WorldRenderMode.SingleTexture)
|
||||
{
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
if (ihash == RenderTextureSampler)
|
||||
{
|
||||
texture = itex;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool usediff = ((texture != null) && (texture.Texture2D != null) && (texture.ShaderResourceView != null));
|
||||
|
||||
PSGeomVars.Vars.EnableTexture = usediff ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableTint = 0u;
|
||||
PSGeomVars.Update(context);
|
||||
PSGeomVars.SetPSCBuffer(context, 2);
|
||||
|
||||
VSGeomVars.Vars.EnableTint = 0u;
|
||||
VSGeomVars.Vars.TintYVal = 0u;
|
||||
VSGeomVars.Vars.IsDecal = 0u;
|
||||
VSGeomVars.Update(context);
|
||||
VSGeomVars.SetVSCBuffer(context, 4);
|
||||
|
||||
|
||||
//context.VertexShader.SetSampler(0, texsampler);
|
||||
context.PixelShader.SetSampler(0, texsampler);
|
||||
//context.PixelShader.SetSampler(1, texsamplerc);
|
||||
if (usediff)
|
||||
{
|
||||
texture.SetPSResource(context, 0);
|
||||
//context.PixelShader.SetShaderResource(0, difftex.ShaderResourceView);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.PixelShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetConstantBuffer(1, null); //shadowmap
|
||||
context.PixelShader.SetConstantBuffer(1, null); //shadowmap
|
||||
context.PixelShader.SetShaderResource(1, null);//shadowmap
|
||||
context.PixelShader.SetSampler(1, null); //shadowmap
|
||||
context.VertexShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(3, null);
|
||||
context.PixelShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(4, null);
|
||||
context.VertexShader.SetSampler(0, null);
|
||||
context.PixelShader.SetSampler(0, null);
|
||||
context.PixelShader.SetShaderResource(0, null);
|
||||
context.VertexShader.SetShaderResource(0, null);
|
||||
context.VertexShader.SetShaderResource(1, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
|
||||
|
||||
if (texsampler != null)
|
||||
{
|
||||
texsampler.Dispose();
|
||||
texsampler = null;
|
||||
}
|
||||
|
||||
foreach (InputLayout layout in layouts.Values)
|
||||
{
|
||||
layout.Dispose();
|
||||
}
|
||||
layouts.Clear();
|
||||
|
||||
VSSceneVars.Dispose();
|
||||
VSEntityVars.Dispose();
|
||||
VSModelVars.Dispose();
|
||||
VSGeomVars.Dispose();
|
||||
PSSceneVars.Dispose();
|
||||
PSGeomVars.Dispose();
|
||||
|
||||
|
||||
ps.Dispose();
|
||||
vs.Dispose();
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using CodeWalker.GameFiles;
|
||||
using CodeWalker.World;
|
||||
using SharpDX.Direct3D11;
|
||||
using System.IO;
|
||||
using SharpDX;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public struct CloudsShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public Matrix ViewInv;
|
||||
}
|
||||
public struct CloudsShaderVSEntityVars
|
||||
{
|
||||
public Vector4 CamRel;
|
||||
public Quaternion Orientation;
|
||||
public Vector4 Scale;
|
||||
}
|
||||
public struct CloudsShaderVSModelVars
|
||||
{
|
||||
public Matrix Transform;
|
||||
}
|
||||
public struct CloudsShaderPSSceneVars
|
||||
{
|
||||
public Vector4 LightDirection;
|
||||
public uint EnableHDR;
|
||||
public uint Pad0;
|
||||
public uint Pad1;
|
||||
public uint Pad2;
|
||||
}
|
||||
public struct CloudsShaderCloudsLocals
|
||||
{
|
||||
public Vector3 gSkyColor; // Offset: 0 Size: 12 [unused]
|
||||
public float gPad00;
|
||||
public Vector3 gEastMinusWestColor; // Offset: 16 Size: 12 [unused]
|
||||
public float gPad01;
|
||||
public Vector3 gWestColor; // Offset: 32 Size: 12 [unused]
|
||||
public float gPad02;
|
||||
public Vector3 gSunDirection; // Offset: 48 Size: 12
|
||||
public float gPad03;
|
||||
public Vector3 gSunColor; // Offset: 64 Size: 12
|
||||
public float gPad04;
|
||||
public Vector3 gCloudColor; // Offset: 80 Size: 12 [unused]
|
||||
public float gPad05;
|
||||
public Vector3 gAmbientColor; // Offset: 96 Size: 12 [unused]
|
||||
public float gPad06;
|
||||
public Vector3 gBounceColor; // Offset: 112 Size: 12 [unused]
|
||||
public float gPad07;
|
||||
public Vector4 gDensityShiftScale; // Offset: 128 Size: 16 [unused]
|
||||
public Vector4 gScatterG_GSquared_PhaseMult_Scale;// Offset: 144 Size: 16
|
||||
public Vector4 gPiercingLightPower_Strength_NormalStrength_Thickness;// Offset: 160 Size: 16
|
||||
public Vector3 gScaleDiffuseFillAmbient; // Offset: 176 Size: 12 [unused]
|
||||
public float gPad08;
|
||||
public Vector3 gWrapLighting_MSAARef; // Offset: 192 Size: 12 [unused]
|
||||
public float gPad09;
|
||||
public Vector4 gNearFarQMult; // Offset: 208 Size: 16 [unused]
|
||||
public Vector3 gAnimCombine; // Offset: 224 Size: 12 [unused]
|
||||
public float gPad10;
|
||||
public Vector3 gAnimSculpt; // Offset: 240 Size: 12 [unused]
|
||||
public float gPad11;
|
||||
public Vector3 gAnimBlendWeights; // Offset: 256 Size: 12 [unused]
|
||||
public float gPad12;
|
||||
public Vector4 gUVOffsetArr0; // Offset: 272 Size: 32
|
||||
public Vector4 gUVOffsetArr1; // Offset: 272 Size: 32
|
||||
public Matrix gCloudViewProj; // Offset: 304 Size: 64
|
||||
public Vector4 gCameraPos; // Offset: 368 Size: 16
|
||||
public Vector2 gUVOffset1; // Offset: 384 Size: 8
|
||||
public Vector2 gUVOffset2; // Offset: 392 Size: 8
|
||||
public Vector2 gUVOffset3; // Offset: 400 Size: 8
|
||||
public Vector2 gRescaleUV1; // Offset: 408 Size: 8
|
||||
public Vector2 gRescaleUV2; // Offset: 416 Size: 8
|
||||
public Vector2 gRescaleUV3; // Offset: 424 Size: 8
|
||||
public float gSoftParticleRange; // Offset: 432 Size: 4 [unused]
|
||||
public float gEnvMapAlphaScale; // Offset: 436 Size: 4 [unused]
|
||||
public Vector2 cloudLayerAnimScale1; // Offset: 440 Size: 8
|
||||
public Vector2 cloudLayerAnimScale2; // Offset: 448 Size: 8
|
||||
public Vector2 cloudLayerAnimScale3; // Offset: 456 Size: 8
|
||||
};
|
||||
|
||||
|
||||
public class CloudsShader : Shader, IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader vs;
|
||||
PixelShader ps;
|
||||
|
||||
GpuVarsBuffer<CloudsShaderCloudsLocals> CloudsLocalVars;
|
||||
GpuVarsBuffer<CloudsShaderVSSceneVars> VSSceneVars;
|
||||
GpuVarsBuffer<CloudsShaderVSEntityVars> VSEntityVars;
|
||||
GpuVarsBuffer<CloudsShaderVSModelVars> VSModelVars;
|
||||
GpuVarsBuffer<CloudsShaderPSSceneVars> PSSceneVars;
|
||||
|
||||
SamplerState texsampler;
|
||||
SamplerState texsampleranis;
|
||||
InputLayout layout;
|
||||
|
||||
public bool EnableHDR { get; set; }
|
||||
public bool AnisotropicFilter = false;
|
||||
|
||||
public CloudsShader(Device device)
|
||||
{
|
||||
byte[] vsbytes = File.ReadAllBytes("Shaders\\CloudsVS.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\CloudsPS.cso");
|
||||
|
||||
vs = new VertexShader(device, vsbytes);
|
||||
ps = new PixelShader(device, psbytes);
|
||||
|
||||
CloudsLocalVars = new GpuVarsBuffer<CloudsShaderCloudsLocals>(device);
|
||||
VSSceneVars = new GpuVarsBuffer<CloudsShaderVSSceneVars>(device);
|
||||
VSEntityVars = new GpuVarsBuffer<CloudsShaderVSEntityVars>(device);
|
||||
VSModelVars = new GpuVarsBuffer<CloudsShaderVSModelVars>(device);
|
||||
PSSceneVars = new GpuVarsBuffer<CloudsShaderPSSceneVars>(device);
|
||||
|
||||
layout = new InputLayout(device, vsbytes, VertexTypeDefaultEx.GetLayout());
|
||||
|
||||
texsampler = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipLinear,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
texsampleranis = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.Anisotropic,
|
||||
MaximumAnisotropy = 8,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
}
|
||||
|
||||
public void UpdateCloudsLocals(Clouds clouds, ShaderGlobalLights lights)
|
||||
{
|
||||
|
||||
CloudsLocalVars.Vars.gSunDirection = lights.CurrentSunDir;
|
||||
CloudsLocalVars.Vars.gSunColor = ((Vector4)lights.Params.LightDirColour).XYZ();
|
||||
CloudsLocalVars.Vars.gUVOffset1 = clouds.AnimOverrides.UVOffset1;
|
||||
CloudsLocalVars.Vars.gUVOffset2 = clouds.AnimOverrides.UVOffset2;
|
||||
CloudsLocalVars.Vars.gUVOffset3 = clouds.AnimOverrides.UVOffset3;
|
||||
CloudsLocalVars.Vars.gRescaleUV1 = clouds.AnimOverrides.RescaleUV1;
|
||||
CloudsLocalVars.Vars.gRescaleUV2 = clouds.AnimOverrides.RescaleUV2;
|
||||
CloudsLocalVars.Vars.gRescaleUV3 = clouds.AnimOverrides.RescaleUV3;
|
||||
CloudsLocalVars.Vars.cloudLayerAnimScale1 = clouds.AnimOverrides.cloudLayerAnimScale1;
|
||||
CloudsLocalVars.Vars.cloudLayerAnimScale2 = clouds.AnimOverrides.cloudLayerAnimScale2;
|
||||
CloudsLocalVars.Vars.cloudLayerAnimScale3 = clouds.AnimOverrides.cloudLayerAnimScale3;
|
||||
CloudsLocalVars.Vars.gUVOffsetArr0 = Vector4.Zero;
|
||||
CloudsLocalVars.Vars.gUVOffsetArr1 = Vector4.Zero;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.Set(vs);
|
||||
context.PixelShader.Set(ps);
|
||||
}
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
CloudsLocalVars.Update(context);
|
||||
CloudsLocalVars.SetVSCBuffer(context, 0);
|
||||
CloudsLocalVars.SetPSCBuffer(context, 0);
|
||||
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSceneVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix);
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 1);
|
||||
|
||||
PSSceneVars.Vars.LightDirection = new Vector4(lights.Params.LightDir, 0.0f);
|
||||
PSSceneVars.Vars.EnableHDR = EnableHDR ? 1u : 0u;
|
||||
PSSceneVars.Update(context);
|
||||
PSSceneVars.SetPSCBuffer(context, 1);
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = rend.Orientation;
|
||||
VSEntityVars.Vars.Scale = new Vector4(rend.Scale, 1.0f);
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 2);
|
||||
}
|
||||
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
//currently not used..
|
||||
//if (!model.UseTransform) return;
|
||||
//VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
|
||||
//VSModelVars.Update(context);
|
||||
//VSModelVars.SetVSCBuffer(context, 3);
|
||||
}
|
||||
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
|
||||
switch (geom.DrawableGeom.Shader.FileName.Hash)
|
||||
{
|
||||
case 4103916155://{clouds_animsoft.sps}
|
||||
case 1097000161://{clouds_altitude.sps}
|
||||
case 1481470665://{clouds_soft.sps}
|
||||
case 2184108982://{clouds_fast.sps}
|
||||
case 4192928948://{clouds_anim.sps}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RenderableTexture DensitySampler = null;
|
||||
RenderableTexture NormalSampler = null;
|
||||
RenderableTexture DetailDensitySampler = null;
|
||||
RenderableTexture DetailNormalSampler = null;
|
||||
RenderableTexture DetailDensity2Sampler = null;
|
||||
RenderableTexture DetailNormal2Sampler = null;
|
||||
RenderableTexture DepthMapTexSampler = null;
|
||||
|
||||
|
||||
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
|
||||
{
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
switch (ihash)
|
||||
{
|
||||
case MetaName.DensitySampler:
|
||||
DensitySampler = itex;
|
||||
break;
|
||||
case MetaName.normalSampler:
|
||||
NormalSampler = itex;
|
||||
break;
|
||||
case MetaName.DetailDensitySampler:
|
||||
DetailDensitySampler = itex;
|
||||
break;
|
||||
case MetaName.DetailNormalSampler:
|
||||
DetailNormalSampler = itex;
|
||||
break;
|
||||
case MetaName.DetailDensity2Sampler:
|
||||
DetailDensity2Sampler = itex;
|
||||
break;
|
||||
case MetaName.DetailNormal2Sampler:
|
||||
DetailNormal2Sampler = itex;
|
||||
break;
|
||||
case MetaName.DepthMapTexSampler:
|
||||
DepthMapTexSampler = itex;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool usedens = ((DensitySampler != null) && (DensitySampler.ShaderResourceView != null));
|
||||
bool usenorm = ((NormalSampler != null) && (NormalSampler.ShaderResourceView != null));
|
||||
bool usedden = ((DetailDensitySampler != null) && (DetailDensitySampler.ShaderResourceView != null));
|
||||
bool usednrm = ((DetailNormalSampler != null) && (DetailNormalSampler.ShaderResourceView != null));
|
||||
bool useddn2 = ((DetailDensity2Sampler != null) && (DetailDensity2Sampler.ShaderResourceView != null));
|
||||
bool usednm2 = ((DetailNormal2Sampler != null) && (DetailNormal2Sampler.ShaderResourceView != null));
|
||||
bool usedept = ((DepthMapTexSampler != null) && (DepthMapTexSampler.ShaderResourceView != null));
|
||||
|
||||
if (usedens)
|
||||
{
|
||||
DensitySampler.SetPSResource(context, 0);
|
||||
}
|
||||
if (usenorm)
|
||||
{
|
||||
NormalSampler.SetPSResource(context, 1);
|
||||
}
|
||||
if (usedden)
|
||||
{
|
||||
DetailDensitySampler.SetPSResource(context, 2);
|
||||
}
|
||||
if (usednrm)
|
||||
{
|
||||
DetailNormalSampler.SetPSResource(context, 3);
|
||||
}
|
||||
if (useddn2)
|
||||
{
|
||||
DetailDensity2Sampler.SetPSResource(context, 4);
|
||||
}
|
||||
if (usednm2)
|
||||
{
|
||||
DetailNormal2Sampler.SetPSResource(context, 5);
|
||||
}
|
||||
if (usedept)
|
||||
{
|
||||
DepthMapTexSampler.SetPSResource(context, 6);
|
||||
}
|
||||
|
||||
context.PixelShader.SetSampler(0, AnisotropicFilter ? texsampleranis : texsampler);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
if (type != VertexType.DefaultEx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
context.InputAssembler.InputLayout = layout;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.PixelShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetConstantBuffer(1, null);
|
||||
context.PixelShader.SetConstantBuffer(1, null);
|
||||
context.VertexShader.SetConstantBuffer(2, null);
|
||||
context.PixelShader.SetSampler(0, null);
|
||||
context.PixelShader.SetShaderResource(0, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
disposed = true;
|
||||
|
||||
|
||||
texsampler.Dispose();
|
||||
|
||||
layout.Dispose();
|
||||
|
||||
CloudsLocalVars.Dispose();
|
||||
VSSceneVars.Dispose();
|
||||
VSEntityVars.Dispose();
|
||||
VSModelVars.Dispose();
|
||||
PSSceneVars.Dispose();
|
||||
|
||||
ps.Dispose();
|
||||
vs.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using CodeWalker.GameFiles;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D11;
|
||||
using System.IO;
|
||||
using SharpDX.DXGI;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public struct DistantLightsShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public Matrix ViewInv;
|
||||
public Vector3 CamPos;
|
||||
public float Pad0;
|
||||
}
|
||||
|
||||
public class DistantLightsShader : Shader
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader lightsvs;
|
||||
PixelShader lightsps;
|
||||
|
||||
InputLayout layout;
|
||||
|
||||
SamplerState texsampler;
|
||||
|
||||
UnitQuad quad;
|
||||
|
||||
GpuVarsBuffer<DistantLightsShaderVSSceneVars> VSSceneVars;
|
||||
|
||||
|
||||
public DistantLightsShader(Device device)
|
||||
{
|
||||
byte[] vsbytes = File.ReadAllBytes("Shaders\\DistantLightsVS.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\DistantLightsPS.cso");
|
||||
|
||||
lightsvs = new VertexShader(device, vsbytes);
|
||||
lightsps = new PixelShader(device, psbytes);
|
||||
|
||||
layout = new InputLayout(device, vsbytes, new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0),
|
||||
});
|
||||
|
||||
|
||||
texsampler = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Clamp,
|
||||
AddressV = TextureAddressMode.Clamp,
|
||||
AddressW = TextureAddressMode.Clamp,
|
||||
BorderColor = Color.Transparent,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipLinear,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
|
||||
|
||||
quad = new UnitQuad(device);
|
||||
|
||||
VSSceneVars = new GpuVarsBuffer<DistantLightsShaderVSSceneVars>(device);
|
||||
|
||||
}
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.Set(lightsvs);
|
||||
context.PixelShader.Set(lightsps);
|
||||
SetInputLayout(context, VertexType.PT);
|
||||
}
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
context.InputAssembler.InputLayout = layout;
|
||||
return true;
|
||||
}
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSceneVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix);
|
||||
VSSceneVars.Vars.CamPos = camera.Position;
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 0);
|
||||
}
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
}
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
}
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
}
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetShaderResource(0, null);
|
||||
context.PixelShader.SetShaderResource(0, null);
|
||||
context.PixelShader.SetSampler(0, null);
|
||||
}
|
||||
|
||||
|
||||
public void RenderBatch(DeviceContext context, RenderableDistantLODLights lights)
|
||||
{
|
||||
context.VertexShader.SetShaderResource(0, lights.InstanceBuffer.SRV);
|
||||
context.PixelShader.SetShaderResource(0, lights.Texture.ShaderResourceView);
|
||||
context.PixelShader.SetSampler(0, texsampler);
|
||||
|
||||
quad.DrawInstanced(context, lights.InstanceCount);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
|
||||
VSSceneVars.Dispose();
|
||||
|
||||
quad.Dispose();
|
||||
|
||||
texsampler.Dispose();
|
||||
|
||||
layout.Dispose();
|
||||
|
||||
//VSSceneVars.Dispose();
|
||||
|
||||
lightsps.Dispose();
|
||||
lightsvs.Dispose();
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D11;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using CodeWalker.GameFiles;
|
||||
using System.IO;
|
||||
using SharpDX.DXGI;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
|
||||
public struct MarkerShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public Matrix ViewInv;
|
||||
public Vector4 ScreenScale; //xy = 1/wh
|
||||
}
|
||||
public struct MarkerShaderVSMarkerVars
|
||||
{
|
||||
public Vector4 CamRel;
|
||||
public Vector2 Size;
|
||||
public Vector2 Offset;
|
||||
}
|
||||
|
||||
public class MarkerShader : Shader, IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader markervs;
|
||||
PixelShader markerps;
|
||||
|
||||
GpuVarsBuffer<MarkerShaderVSSceneVars> VSSceneVars;
|
||||
GpuVarsBuffer<MarkerShaderVSMarkerVars> VSMarkerVars;
|
||||
|
||||
SamplerState texsampler;
|
||||
|
||||
InputLayout layout;
|
||||
|
||||
|
||||
public MarkerShader(Device device)
|
||||
{
|
||||
byte[] vsbytes = File.ReadAllBytes("Shaders\\MarkerVS.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\MarkerPS.cso");
|
||||
|
||||
markervs = new VertexShader(device, vsbytes);
|
||||
markerps = new PixelShader(device, psbytes);
|
||||
|
||||
VSSceneVars = new GpuVarsBuffer<MarkerShaderVSSceneVars>(device);
|
||||
VSMarkerVars = new GpuVarsBuffer<MarkerShaderVSMarkerVars>(device);
|
||||
|
||||
layout = new InputLayout(device, vsbytes, new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0),
|
||||
});
|
||||
|
||||
texsampler = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Clamp,
|
||||
AddressV = TextureAddressMode.Clamp,
|
||||
AddressW = TextureAddressMode.Clamp,
|
||||
BorderColor = Color.Transparent,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipLinear,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.Set(markervs);
|
||||
context.PixelShader.Set(markerps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
context.InputAssembler.InputLayout = layout;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSceneVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix);
|
||||
VSSceneVars.Vars.ScreenScale = new Vector4(0.5f / camera.Width, 0.5f / camera.Height, camera.Width, camera.Height);
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 0);
|
||||
}
|
||||
|
||||
public void SetMarkerVars(DeviceContext context, Vector3 camrel, Vector2 size, Vector2 offset)
|
||||
{
|
||||
VSMarkerVars.Vars.CamRel = new Vector4(camrel, 0.0f);
|
||||
VSMarkerVars.Vars.Size = size;
|
||||
VSMarkerVars.Vars.Offset = offset;
|
||||
VSMarkerVars.Update(context);
|
||||
VSMarkerVars.SetVSCBuffer(context, 1);
|
||||
}
|
||||
|
||||
public void SetTexture(DeviceContext context, ShaderResourceView srv)
|
||||
{
|
||||
context.PixelShader.SetSampler(0, texsampler);
|
||||
context.PixelShader.SetShaderResource(0, srv);
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
//don't use this one
|
||||
}
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
//don't use this
|
||||
}
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
//don't use this
|
||||
}
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetConstantBuffer(1, null);
|
||||
context.PixelShader.SetSampler(0, null);
|
||||
context.PixelShader.SetShaderResource(0, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
|
||||
if (texsampler != null)
|
||||
{
|
||||
texsampler.Dispose();
|
||||
texsampler = null;
|
||||
}
|
||||
|
||||
layout.Dispose();
|
||||
|
||||
VSSceneVars.Dispose();
|
||||
VSMarkerVars.Dispose();
|
||||
|
||||
markerps.Dispose();
|
||||
markervs.Dispose();
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D11;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using CodeWalker.GameFiles;
|
||||
using System.IO;
|
||||
using SharpDX.DXGI;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
|
||||
public struct PathShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public Vector4 CameraPos;
|
||||
public Vector4 LightColour;
|
||||
}
|
||||
|
||||
|
||||
public class PathShader : Shader, IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader boxvs;
|
||||
PixelShader boxps;
|
||||
VertexShader dynvs;
|
||||
VertexShader vs;
|
||||
PixelShader ps;
|
||||
|
||||
GpuVarsBuffer<PathShaderVSSceneVars> VSSceneVars;
|
||||
|
||||
InputLayout layout;
|
||||
|
||||
UnitCube cube;
|
||||
|
||||
bool UseDynamicVerts = false;
|
||||
GpuCBuffer<VertexTypePC> vertices; //for selection polys/lines use
|
||||
|
||||
|
||||
public PathShader(Device device)
|
||||
{
|
||||
byte[] boxvsbytes = File.ReadAllBytes("Shaders\\PathBoxVS.cso");
|
||||
byte[] boxpsbytes = File.ReadAllBytes("Shaders\\PathBoxPS.cso");
|
||||
byte[] dynvsbytes = File.ReadAllBytes("Shaders\\PathDynVS.cso");
|
||||
byte[] vsbytes = File.ReadAllBytes("Shaders\\PathVS.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\PathPS.cso");
|
||||
|
||||
|
||||
boxvs = new VertexShader(device, boxvsbytes);
|
||||
boxps = new PixelShader(device, boxpsbytes);
|
||||
dynvs = new VertexShader(device, dynvsbytes);
|
||||
vs = new VertexShader(device, vsbytes);
|
||||
ps = new PixelShader(device, psbytes);
|
||||
|
||||
VSSceneVars = new GpuVarsBuffer<PathShaderVSSceneVars>(device);
|
||||
|
||||
layout = new InputLayout(device, vsbytes, VertexTypePC.GetLayout());
|
||||
|
||||
cube = new UnitCube(device, boxvsbytes, true, false, true);
|
||||
|
||||
vertices = new GpuCBuffer<VertexTypePC>(device, 1000); //should be more than needed....
|
||||
}
|
||||
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
if (UseDynamicVerts)
|
||||
{
|
||||
context.VertexShader.Set(dynvs);
|
||||
//context.InputAssembler.SetVertexBuffers(0, null);
|
||||
context.InputAssembler.SetIndexBuffer(null, Format.Unknown, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.VertexShader.Set(vs);
|
||||
}
|
||||
context.PixelShader.Set(ps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
if (UseDynamicVerts)
|
||||
{
|
||||
context.InputAssembler.InputLayout = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.InputAssembler.InputLayout = layout;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSceneVars.Vars.CameraPos = new Vector4(camera.Position, 0.0f);
|
||||
VSSceneVars.Vars.LightColour = new Vector4(1.0f, 1.0f, 1.0f, lights.HdrIntensity * 2.0f);
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 0);
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
//don't use this one
|
||||
}
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
//don't use this
|
||||
}
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
//don't use this
|
||||
}
|
||||
|
||||
|
||||
public void RenderBatches(DeviceContext context, List<RenderablePathBatch> batches, Camera camera, ShaderGlobalLights lights)
|
||||
{
|
||||
UseDynamicVerts = false;
|
||||
SetShader(context);
|
||||
SetInputLayout(context, VertexType.PC);
|
||||
SetSceneVars(context, camera, null, lights);
|
||||
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetIndexBuffer(null, Format.R16_UInt, 0);
|
||||
for (int i = 0; i < batches.Count; i++)
|
||||
{
|
||||
var pbatch = batches[i];
|
||||
|
||||
if (pbatch.TriangleVertexBuffer == null) continue;
|
||||
if (pbatch.TriangleVertexCount == 0) continue;
|
||||
|
||||
context.InputAssembler.SetVertexBuffers(0, pbatch.TriangleVBBinding);
|
||||
context.Draw(pbatch.TriangleVertexCount, 0);
|
||||
}
|
||||
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
|
||||
context.InputAssembler.SetIndexBuffer(null, Format.R16_UInt, 0);
|
||||
for (int i = 0; i < batches.Count; i++)
|
||||
{
|
||||
var pbatch = batches[i];
|
||||
|
||||
if (pbatch.PathVertexBuffer == null) continue;
|
||||
if (pbatch.PathVertexCount == 0) continue;
|
||||
|
||||
context.InputAssembler.SetVertexBuffers(0, pbatch.PathVBBinding);
|
||||
context.Draw(pbatch.PathVertexCount, 0);
|
||||
}
|
||||
|
||||
|
||||
context.VertexShader.Set(boxvs);
|
||||
context.PixelShader.Set(boxps);
|
||||
|
||||
VSSceneVars.SetVSCBuffer(context, 0);
|
||||
|
||||
foreach (var batch in batches)
|
||||
{
|
||||
if (batch.NodeBuffer == null) continue;
|
||||
|
||||
context.VertexShader.SetShaderResource(0, batch.NodeBuffer.SRV);
|
||||
|
||||
cube.DrawInstanced(context, batch.Nodes.Length);
|
||||
}
|
||||
|
||||
UnbindResources(context);
|
||||
}
|
||||
|
||||
public void RenderTriangles(DeviceContext context, List<VertexTypePC> verts, Camera camera, ShaderGlobalLights lights)
|
||||
{
|
||||
UseDynamicVerts = true;
|
||||
SetShader(context);
|
||||
SetInputLayout(context, VertexType.PC);
|
||||
SetSceneVars(context, camera, null, lights);
|
||||
|
||||
vertices.Clear();
|
||||
foreach (var vert in verts)
|
||||
{
|
||||
vertices.Add(vert);
|
||||
}
|
||||
vertices.Update(context);
|
||||
vertices.SetVSResource(context, 0);
|
||||
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
|
||||
context.Draw(vertices.CurrentCount, 0);
|
||||
}
|
||||
|
||||
public void RenderLines(DeviceContext context, List<VertexTypePC> verts, Camera camera, ShaderGlobalLights lights)
|
||||
{
|
||||
UseDynamicVerts = true;
|
||||
SetShader(context);
|
||||
SetInputLayout(context, VertexType.PC);
|
||||
SetSceneVars(context, camera, null, lights);
|
||||
|
||||
vertices.Clear();
|
||||
foreach (var vert in verts)
|
||||
{
|
||||
vertices.Add(vert);
|
||||
}
|
||||
vertices.Update(context);
|
||||
vertices.SetVSResource(context, 0);
|
||||
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
|
||||
context.Draw(vertices.CurrentCount, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetShaderResource(0, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
disposed = true;
|
||||
|
||||
VSSceneVars.Dispose();
|
||||
|
||||
vertices.Dispose();
|
||||
|
||||
layout.Dispose();
|
||||
cube.Dispose();
|
||||
|
||||
ps.Dispose();
|
||||
vs.Dispose();
|
||||
dynvs.Dispose();
|
||||
boxvs.Dispose();
|
||||
boxps.Dispose();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,688 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using SharpDX.Direct3D11;
|
||||
using System.IO;
|
||||
using CodeWalker.GameFiles;
|
||||
using CodeWalker.World;
|
||||
using SharpDX;
|
||||
using SharpDX.DXGI;
|
||||
using SharpDX.Mathematics.Interop;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
|
||||
public struct PostProcessorReduceCSVars
|
||||
{
|
||||
public uint dimx;
|
||||
public uint dimy;
|
||||
public uint Width;
|
||||
public uint Height;
|
||||
}
|
||||
public struct PostProcessorLumBlendCSVars
|
||||
{
|
||||
public Vector4 blend;
|
||||
}
|
||||
public struct PostProcessorFilterSampleWeights
|
||||
{
|
||||
public Vector4 avSampleWeights00; //[15];
|
||||
public Vector4 avSampleWeights01;
|
||||
public Vector4 avSampleWeights02;
|
||||
public Vector4 avSampleWeights03;
|
||||
public Vector4 avSampleWeights04;
|
||||
public Vector4 avSampleWeights05;
|
||||
public Vector4 avSampleWeights06;
|
||||
public Vector4 avSampleWeights07;
|
||||
public Vector4 avSampleWeights08;
|
||||
public Vector4 avSampleWeights09;
|
||||
public Vector4 avSampleWeights10;
|
||||
public Vector4 avSampleWeights11;
|
||||
public Vector4 avSampleWeights12;
|
||||
public Vector4 avSampleWeights13;
|
||||
public Vector4 avSampleWeights14;
|
||||
|
||||
public Vector4 Get(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
default:
|
||||
case 0: return avSampleWeights00;
|
||||
case 1: return avSampleWeights01;
|
||||
case 2: return avSampleWeights02;
|
||||
case 3: return avSampleWeights03;
|
||||
case 4: return avSampleWeights04;
|
||||
case 5: return avSampleWeights05;
|
||||
case 6: return avSampleWeights06;
|
||||
case 7: return avSampleWeights07;
|
||||
case 8: return avSampleWeights08;
|
||||
case 9: return avSampleWeights09;
|
||||
case 10: return avSampleWeights10;
|
||||
case 11: return avSampleWeights11;
|
||||
case 12: return avSampleWeights12;
|
||||
case 13: return avSampleWeights13;
|
||||
case 14: return avSampleWeights14;
|
||||
}
|
||||
}
|
||||
public void Set(int i, Vector4 v)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: avSampleWeights00 = v; break;
|
||||
case 1: avSampleWeights01 = v; break;
|
||||
case 2: avSampleWeights02 = v; break;
|
||||
case 3: avSampleWeights03 = v; break;
|
||||
case 4: avSampleWeights04 = v; break;
|
||||
case 5: avSampleWeights05 = v; break;
|
||||
case 6: avSampleWeights06 = v; break;
|
||||
case 7: avSampleWeights07 = v; break;
|
||||
case 8: avSampleWeights08 = v; break;
|
||||
case 9: avSampleWeights09 = v; break;
|
||||
case 10: avSampleWeights10 = v; break;
|
||||
case 11: avSampleWeights11 = v; break;
|
||||
case 12: avSampleWeights12 = v; break;
|
||||
case 13: avSampleWeights13 = v; break;
|
||||
case 14: avSampleWeights14 = v; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public struct PostProcessorFilterBPHCSVars
|
||||
{
|
||||
public PostProcessorFilterSampleWeights avSampleWeights;
|
||||
public uint outputwidth;
|
||||
public float finverse;
|
||||
public int inputsize0;
|
||||
public int inputsize1;
|
||||
}
|
||||
public struct PostProcessorFilterVCSVars
|
||||
{
|
||||
public PostProcessorFilterSampleWeights avSampleWeights;
|
||||
public int outputsize0;
|
||||
public int outputsize1;
|
||||
public int inputsize0;
|
||||
public int inputsize1;
|
||||
}
|
||||
public struct PostProcessorFinalPSVars
|
||||
{
|
||||
public Vector4 invPixelCount;
|
||||
}
|
||||
|
||||
|
||||
public class PostProcessor
|
||||
{
|
||||
ComputeShader ReduceTo1DCS;
|
||||
ComputeShader ReduceTo0DCS;
|
||||
ComputeShader LumBlendCS;
|
||||
ComputeShader BloomFilterBPHCS;
|
||||
ComputeShader BloomFilterVCS;
|
||||
PixelShader CopyPixelsPS;
|
||||
VertexShader FinalPassVS;
|
||||
PixelShader FinalPassPS;
|
||||
UnitQuad FinalPassQuad;
|
||||
InputLayout FinalPassLayout;
|
||||
GpuVarsBuffer<PostProcessorReduceCSVars> ReduceCSVars;
|
||||
GpuVarsBuffer<PostProcessorLumBlendCSVars> LumBlendCSVars;
|
||||
GpuVarsBuffer<PostProcessorFilterBPHCSVars> FilterBPHCSVars;
|
||||
GpuVarsBuffer<PostProcessorFilterVCSVars> FilterVCSVars;
|
||||
GpuVarsBuffer<PostProcessorFinalPSVars> FinalPSVars;
|
||||
|
||||
GpuTexture Primary;
|
||||
|
||||
GpuBuffer<float> Reduction0;
|
||||
GpuBuffer<float> Reduction1;
|
||||
|
||||
GpuBuffer<float> LumBlendResult;
|
||||
|
||||
GpuBuffer<Vector4> Bloom0;
|
||||
GpuBuffer<Vector4> Bloom1;
|
||||
GpuTexture Bloom;
|
||||
|
||||
SamplerState SampleStatePoint;
|
||||
SamplerState SampleStateLinear;
|
||||
BlendState BlendState;
|
||||
long WindowSizeVramUsage = 0;
|
||||
int Width = 0;
|
||||
int Height = 0;
|
||||
ViewportF Viewport;
|
||||
bool Multisampled = false;
|
||||
bool EnableBloom = true;
|
||||
float ElapsedTime = 0.0f;
|
||||
public float LumBlendSpeed = 1.0f;
|
||||
|
||||
bool CS_FULL_PIXEL_REDUCTION = false;
|
||||
|
||||
public long VramUsage
|
||||
{
|
||||
get
|
||||
{
|
||||
return WindowSizeVramUsage;
|
||||
}
|
||||
}
|
||||
|
||||
RawViewportF[] vpOld = new RawViewportF[15];
|
||||
|
||||
public PostProcessor(DXManager dxman)
|
||||
{
|
||||
var device = dxman.device;
|
||||
|
||||
byte[] bReduceTo1DCS = File.ReadAllBytes("Shaders\\PPReduceTo1DCS.cso");
|
||||
byte[] bReduceTo0DCS = File.ReadAllBytes("Shaders\\PPReduceTo0DCS.cso");
|
||||
byte[] bLumBlendCS = File.ReadAllBytes("Shaders\\PPLumBlendCS.cso");
|
||||
byte[] bBloomFilterBPHCS = File.ReadAllBytes("Shaders\\PPBloomFilterBPHCS.cso");
|
||||
byte[] bBloomFilterVCS = File.ReadAllBytes("Shaders\\PPBloomFilterVCS.cso");
|
||||
byte[] bCopyPixelsPS = File.ReadAllBytes("Shaders\\PPCopyPixelsPS.cso");
|
||||
byte[] bFinalPassVS = File.ReadAllBytes("Shaders\\PPFinalPassVS.cso");
|
||||
byte[] bFinalPassPS = File.ReadAllBytes("Shaders\\PPFinalPassPS.cso");
|
||||
|
||||
ReduceTo1DCS = new ComputeShader(device, bReduceTo1DCS);
|
||||
ReduceTo0DCS = new ComputeShader(device, bReduceTo0DCS);
|
||||
LumBlendCS = new ComputeShader(device, bLumBlendCS);
|
||||
BloomFilterBPHCS = new ComputeShader(device, bBloomFilterBPHCS);
|
||||
BloomFilterVCS = new ComputeShader(device, bBloomFilterVCS);
|
||||
CopyPixelsPS = new PixelShader(device, bCopyPixelsPS);
|
||||
FinalPassVS = new VertexShader(device, bFinalPassVS);
|
||||
FinalPassPS = new PixelShader(device, bFinalPassPS);
|
||||
FinalPassQuad = new UnitQuad(device, true);
|
||||
FinalPassLayout = new InputLayout(device, bFinalPassVS, new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0),
|
||||
});
|
||||
|
||||
|
||||
ReduceCSVars = new GpuVarsBuffer<PostProcessorReduceCSVars>(device);
|
||||
LumBlendCSVars = new GpuVarsBuffer<PostProcessorLumBlendCSVars>(device);
|
||||
FilterBPHCSVars = new GpuVarsBuffer<PostProcessorFilterBPHCSVars>(device);
|
||||
FilterVCSVars = new GpuVarsBuffer<PostProcessorFilterVCSVars>(device);
|
||||
FinalPSVars = new GpuVarsBuffer<PostProcessorFinalPSVars>(device);
|
||||
|
||||
TextureAddressMode a = TextureAddressMode.Clamp;
|
||||
Color4 b = new Color4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
Comparison c = Comparison.Always;
|
||||
SampleStatePoint = DXUtility.CreateSamplerState(device, a, b, c, Filter.MinMagMipPoint, 0, 1.0f, 1.0f, 0.0f);
|
||||
SampleStateLinear = DXUtility.CreateSamplerState(device, a, b, c, Filter.MinMagMipLinear, 0, 1.0f, 1.0f, 0.0f);
|
||||
|
||||
BlendState = DXUtility.CreateBlendState(device, false, BlendOperation.Add, BlendOption.One, BlendOption.Zero, BlendOperation.Add, BlendOption.One, BlendOption.Zero, ColorWriteMaskFlags.All);
|
||||
|
||||
GetSampleWeights(ref FilterVCSVars.Vars.avSampleWeights, 3.0f, 1.25f); //init sample weights
|
||||
FilterBPHCSVars.Vars.avSampleWeights = FilterVCSVars.Vars.avSampleWeights;
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
DisposeBuffers();
|
||||
|
||||
if (BlendState != null)
|
||||
{
|
||||
BlendState.Dispose();
|
||||
BlendState = null;
|
||||
}
|
||||
if (SampleStateLinear != null)
|
||||
{
|
||||
SampleStateLinear.Dispose();
|
||||
SampleStateLinear = null;
|
||||
}
|
||||
if (SampleStatePoint != null)
|
||||
{
|
||||
SampleStatePoint.Dispose();
|
||||
SampleStatePoint = null;
|
||||
}
|
||||
if (FinalPSVars != null)
|
||||
{
|
||||
FinalPSVars.Dispose();
|
||||
FinalPSVars = null;
|
||||
}
|
||||
if (FilterVCSVars != null)
|
||||
{
|
||||
FilterVCSVars.Dispose();
|
||||
FilterVCSVars = null;
|
||||
}
|
||||
if (FilterBPHCSVars != null)
|
||||
{
|
||||
FilterBPHCSVars.Dispose();
|
||||
FilterBPHCSVars = null;
|
||||
}
|
||||
if (LumBlendCSVars != null)
|
||||
{
|
||||
LumBlendCSVars.Dispose();
|
||||
LumBlendCSVars = null;
|
||||
}
|
||||
if (ReduceCSVars != null)
|
||||
{
|
||||
ReduceCSVars.Dispose();
|
||||
ReduceCSVars = null;
|
||||
}
|
||||
if (FinalPassLayout != null)
|
||||
{
|
||||
FinalPassLayout.Dispose();
|
||||
FinalPassLayout = null;
|
||||
}
|
||||
if (FinalPassQuad != null)
|
||||
{
|
||||
FinalPassQuad.Dispose();
|
||||
FinalPassQuad = null;
|
||||
}
|
||||
if (FinalPassPS != null)
|
||||
{
|
||||
FinalPassPS.Dispose();
|
||||
FinalPassPS = null;
|
||||
}
|
||||
if (FinalPassVS != null)
|
||||
{
|
||||
FinalPassVS.Dispose();
|
||||
FinalPassVS = null;
|
||||
}
|
||||
if (CopyPixelsPS != null)
|
||||
{
|
||||
CopyPixelsPS.Dispose();
|
||||
CopyPixelsPS = null;
|
||||
}
|
||||
if (BloomFilterVCS != null)
|
||||
{
|
||||
BloomFilterVCS.Dispose();
|
||||
BloomFilterVCS = null;
|
||||
}
|
||||
if (BloomFilterBPHCS != null)
|
||||
{
|
||||
BloomFilterBPHCS.Dispose();
|
||||
BloomFilterBPHCS = null;
|
||||
}
|
||||
if (LumBlendCS != null)
|
||||
{
|
||||
LumBlendCS.Dispose();
|
||||
LumBlendCS = null;
|
||||
}
|
||||
if (ReduceTo0DCS != null)
|
||||
{
|
||||
ReduceTo0DCS.Dispose();
|
||||
ReduceTo0DCS = null;
|
||||
}
|
||||
if (ReduceTo1DCS != null)
|
||||
{
|
||||
ReduceTo1DCS.Dispose();
|
||||
ReduceTo1DCS = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnWindowResize(DXManager dxman)
|
||||
{
|
||||
DisposeBuffers();
|
||||
|
||||
var device = dxman.device;
|
||||
|
||||
|
||||
int sc = dxman.multisamplecount;
|
||||
int sq = dxman.multisamplequality;
|
||||
Multisampled = (sc > 1);
|
||||
|
||||
int uw = Width = dxman.backbuffer.Description.Width;
|
||||
int uh = Height = dxman.backbuffer.Description.Height;
|
||||
Viewport = new ViewportF();
|
||||
Viewport.Width = (float)uw;
|
||||
Viewport.Height = (float)uh;
|
||||
Viewport.MinDepth = 0.0f;
|
||||
Viewport.MaxDepth = 1.0f;
|
||||
Viewport.X = 0.0f;
|
||||
Viewport.Y = 0.0f;
|
||||
|
||||
|
||||
Format f = Format.R32G32B32A32_Float;
|
||||
Format df = Format.D32_Float;
|
||||
|
||||
|
||||
Primary = new GpuTexture(device, uw, uh, f, sc, sq, true, df);
|
||||
WindowSizeVramUsage += Primary.VramUsage;
|
||||
|
||||
|
||||
int rc = (int)(Math.Ceiling(uw / 8.0f) * Math.Ceiling(uh / 8.0f));
|
||||
|
||||
Reduction0 = new GpuBuffer<float>(device, 1, rc);
|
||||
Reduction1 = new GpuBuffer<float>(device, 1, rc);
|
||||
WindowSizeVramUsage += sizeof(float) * rc * 2;
|
||||
|
||||
LumBlendResult = new GpuBuffer<float>(device, 1, 1);
|
||||
WindowSizeVramUsage += sizeof(float); //because 4 bytes matter
|
||||
|
||||
int tw = uw / 8;
|
||||
int th = uh / 8;
|
||||
rc = tw * th;
|
||||
f = Format.R8G8B8A8_UNorm;
|
||||
|
||||
Bloom0 = new GpuBuffer<Vector4>(device, 1, rc);
|
||||
Bloom1 = new GpuBuffer<Vector4>(device, 1, rc);
|
||||
WindowSizeVramUsage += /*sizeof(V4F)*/ 16 * rc * 2;
|
||||
|
||||
Bloom = new GpuTexture(device, tw, th, f, 1, 0, false, df);
|
||||
WindowSizeVramUsage += Bloom.VramUsage;
|
||||
|
||||
|
||||
}
|
||||
public void DisposeBuffers()
|
||||
{
|
||||
if (Bloom != null)
|
||||
{
|
||||
Bloom.Dispose();
|
||||
Bloom = null;
|
||||
}
|
||||
if (Bloom0 != null)
|
||||
{
|
||||
Bloom0.Dispose();
|
||||
Bloom0 = null;
|
||||
}
|
||||
if (Bloom1 != null)
|
||||
{
|
||||
Bloom1.Dispose();
|
||||
Bloom1 = null;
|
||||
}
|
||||
if (LumBlendResult != null)
|
||||
{
|
||||
LumBlendResult.Dispose();
|
||||
LumBlendResult = null;
|
||||
}
|
||||
if (Reduction0 != null)
|
||||
{
|
||||
Reduction0.Dispose();
|
||||
Reduction0 = null;
|
||||
}
|
||||
if (Reduction1 != null)
|
||||
{
|
||||
Reduction1.Dispose();
|
||||
Reduction1 = null;
|
||||
}
|
||||
if (Primary != null)
|
||||
{
|
||||
Primary.Dispose();
|
||||
Primary = null;
|
||||
}
|
||||
WindowSizeVramUsage = 0;
|
||||
}
|
||||
|
||||
public void Clear(DeviceContext context)
|
||||
{
|
||||
Color4 clearColour = new Color4(0.2f, 0.4f, 0.6f, 0.0f);
|
||||
//Color4 clearColour = new Color4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
Primary.Clear(context, clearColour);
|
||||
}
|
||||
public void ClearDepth(DeviceContext context)
|
||||
{
|
||||
Primary.ClearDepth(context);
|
||||
}
|
||||
public void SetPrimary(DeviceContext context)
|
||||
{
|
||||
Primary.SetRenderTarget(context);
|
||||
context.Rasterizer.SetViewport(Viewport);
|
||||
}
|
||||
|
||||
public void Render(DXManager dxman, float elapsed)
|
||||
{
|
||||
ElapsedTime = elapsed;
|
||||
|
||||
var context = dxman.context;
|
||||
|
||||
if (Multisampled)
|
||||
{
|
||||
int sr = 0;// D3D11CalcSubresource(0, 0, 1);
|
||||
context.ResolveSubresource(Primary.TextureMS, sr, Primary.Texture, sr, Format.R32G32B32A32_Float);
|
||||
}
|
||||
|
||||
context.OutputMerger.SetRenderTargets((RenderTargetView)null);
|
||||
|
||||
ProcessLuminance(context);
|
||||
ProcessBloom(context);
|
||||
|
||||
dxman.SetDefaultRenderTarget(context);
|
||||
context.OutputMerger.SetBlendState(BlendState, null, 0xFFFFFFFF);
|
||||
FinalPass(context);
|
||||
}
|
||||
|
||||
|
||||
private void ProcessLuminance(DeviceContext context)
|
||||
{
|
||||
uint dimx, dimy;
|
||||
if (CS_FULL_PIXEL_REDUCTION)
|
||||
{
|
||||
dimx = (uint)(Math.Ceiling(Width / 8.0f));
|
||||
dimx = (uint)(Math.Ceiling(dimx / 2.0f));
|
||||
dimy = (uint)(Math.Ceiling(Height / 8.0f));
|
||||
dimy = (uint)(Math.Ceiling(dimy / 2.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
dimx = (uint)(Math.Ceiling(81.0f / 8.0f)); //ToneMappingTexSize = (int)pow(3.0f, NUM_TONEMAP_TEXTURES-1);
|
||||
dimy = dimx;
|
||||
}
|
||||
|
||||
ReduceCSVars.Vars.dimx = dimx;
|
||||
ReduceCSVars.Vars.dimy = dimy;
|
||||
ReduceCSVars.Vars.Width = (uint)Width;
|
||||
ReduceCSVars.Vars.Height = (uint)Height;
|
||||
ReduceCSVars.Update(context);
|
||||
|
||||
Compute(context, ReduceTo1DCS, ReduceCSVars.Buffer, Reduction0.UAV, (int)dimx, (int)dimy, 1, Primary.SRV);
|
||||
|
||||
uint dim = dimx * dimy;
|
||||
uint nNumToReduce = dim;
|
||||
dim = (uint)(Math.Ceiling(dim / 128.0f));
|
||||
if (nNumToReduce > 1)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
ReduceCSVars.Vars.dimx = nNumToReduce;
|
||||
ReduceCSVars.Vars.dimy = dim;
|
||||
ReduceCSVars.Vars.Width = 0;
|
||||
ReduceCSVars.Vars.Height = 0;
|
||||
ReduceCSVars.Update(context);
|
||||
|
||||
Compute(context, ReduceTo0DCS, ReduceCSVars.Buffer, Reduction1.UAV, (int)dim, 1, 1, Reduction0.SRV);
|
||||
|
||||
nNumToReduce = dim;
|
||||
dim = (uint)(Math.Ceiling(dim / 128.0f));
|
||||
|
||||
if (nNumToReduce == 1) break;
|
||||
|
||||
var r0 = Reduction0;
|
||||
Reduction0 = Reduction1;
|
||||
Reduction1 = r0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var r0 = Reduction0;
|
||||
Reduction0 = Reduction1;
|
||||
Reduction1 = r0;
|
||||
}
|
||||
|
||||
LumBlendCSVars.Vars.blend = new Vector4(Math.Min(ElapsedTime * LumBlendSpeed, 1.0f));
|
||||
LumBlendCSVars.Update(context);
|
||||
|
||||
Compute(context, LumBlendCS, LumBlendCSVars.Buffer, LumBlendResult.UAV, 1, 1, 1, Reduction1.SRV);
|
||||
|
||||
}
|
||||
private void ProcessBloom(DeviceContext context)
|
||||
{
|
||||
if (EnableBloom)
|
||||
{
|
||||
|
||||
// Bright pass and horizontal blur
|
||||
|
||||
ShaderResourceView view = Primary.SRV;
|
||||
|
||||
ShaderResourceView[] aRViews = { view, LumBlendResult.SRV };
|
||||
//BloomFilterShaderVars cbFilter;
|
||||
//GetSampleWeights(cbFilter.avSampleWeights, 3.0f, 1.25f);
|
||||
FilterBPHCSVars.Vars.outputwidth = (uint)(Width / 8);
|
||||
if (CS_FULL_PIXEL_REDUCTION)
|
||||
{
|
||||
FilterBPHCSVars.Vars.finverse = 1.0f / (Width * Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
FilterBPHCSVars.Vars.finverse = 1.0f / (81 * 81); //(ToneMappingTexSize*ToneMappingTexSize);
|
||||
}
|
||||
FilterBPHCSVars.Vars.inputsize0 = (int)Width;
|
||||
FilterBPHCSVars.Vars.inputsize1 = (int)Height;
|
||||
FilterBPHCSVars.Update(context);
|
||||
|
||||
int x = (int)(Math.Ceiling((float)FilterBPHCSVars.Vars.outputwidth / (128 - 7 * 2)));
|
||||
int y = (Height / 8);
|
||||
Compute(context, BloomFilterBPHCS, FilterBPHCSVars.Buffer, Bloom1.UAV, x, y, 1, view, LumBlendResult.SRV);
|
||||
|
||||
// Vertical blur
|
||||
FilterVCSVars.Vars.outputsize0 = (int)(Width / 8);
|
||||
FilterVCSVars.Vars.outputsize1 = (int)(Height / 8);
|
||||
FilterVCSVars.Vars.inputsize0 = (int)(Width / 8);
|
||||
FilterVCSVars.Vars.inputsize1 = (int)(Height / 8);
|
||||
FilterVCSVars.Update(context);
|
||||
x = Width / 8;
|
||||
y = (int)(Math.Ceiling((float)FilterVCSVars.Vars.outputsize1 / (128 - 7 * 2)));
|
||||
|
||||
Compute(context, BloomFilterVCS, FilterVCSVars.Buffer, Bloom0.UAV, x, y, 1, Bloom1.SRV, LumBlendResult.SRV);
|
||||
}
|
||||
|
||||
CopyPixels(context, Width / 8, Height / 8, Bloom0.SRV, Bloom.RTV);
|
||||
|
||||
}
|
||||
private void FinalPass(DeviceContext context)
|
||||
{
|
||||
context.Rasterizer.SetViewport(Viewport);
|
||||
context.VertexShader.Set(FinalPassVS);
|
||||
context.PixelShader.Set(FinalPassPS);
|
||||
|
||||
context.PixelShader.SetShaderResources(0, Primary.SRV, LumBlendResult.SRV, EnableBloom ? Bloom.SRV : null);
|
||||
|
||||
if (CS_FULL_PIXEL_REDUCTION)
|
||||
{
|
||||
//pcbCS[0] = 1.0f / (Width * Height);
|
||||
FinalPSVars.Vars.invPixelCount = new Vector4(1.0f / (Width * Height));
|
||||
}
|
||||
else
|
||||
{
|
||||
//pcbCS[0] = 1.0f / (81 * 81); //ToneMappingTexSize*ToneMappingTexSize
|
||||
FinalPSVars.Vars.invPixelCount = new Vector4(1.0f / (81 * 81));
|
||||
}
|
||||
FinalPSVars.Update(context);
|
||||
FinalPSVars.SetPSCBuffer(context, 0);
|
||||
|
||||
context.PixelShader.SetSamplers(0, SampleStatePoint, SampleStateLinear);
|
||||
|
||||
context.InputAssembler.InputLayout = FinalPassLayout;
|
||||
FinalPassQuad.Draw(context);
|
||||
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
context.PixelShader.SetShaderResources(0, null, null, null);
|
||||
context.PixelShader.SetSamplers(0, null, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private float GaussianDistribution(float x, float y, float rho)
|
||||
{
|
||||
float g = 1.0f / (float)Math.Sqrt(2.0f * 3.14159265f * rho * rho);
|
||||
g *= (float)Math.Exp(-(x * x + y * y) / (2 * rho * rho));
|
||||
return g;
|
||||
}
|
||||
private void GetSampleWeights(ref PostProcessorFilterSampleWeights w, float fDeviation, float fMultiplier)
|
||||
{
|
||||
// Fill the center texel
|
||||
float weight = 1.0f * GaussianDistribution(0, 0, fDeviation);
|
||||
w.Set(7, new Vector4(weight, weight, weight, 1.0f));
|
||||
|
||||
// Fill the right side
|
||||
for (int i = 1; i < 8; i++)
|
||||
{
|
||||
weight = fMultiplier * GaussianDistribution((float)i, 0, fDeviation);
|
||||
w.Set(7 - i, new Vector4(weight, weight, weight, 1.0f));
|
||||
}
|
||||
|
||||
// Copy to the left side
|
||||
for (int i = 8; i < 15; i++)
|
||||
{
|
||||
w.Set(i, w.Get(14 - i));
|
||||
}
|
||||
|
||||
// Debug convolution kernel which doesn't transform input data
|
||||
/*ZeroMemory( avColorWeight, sizeof(D3DXVECTOR4)*15 );
|
||||
w.Set(7, new Vector4( 1, 1, 1, 1 ));*/
|
||||
}
|
||||
|
||||
|
||||
private void Compute(DeviceContext context, ComputeShader cs, Buffer constantBuffer, UnorderedAccessView unorderedAccessView, int X, int Y, int Z, params ShaderResourceView[] resourceViews)
|
||||
{
|
||||
context.ComputeShader.Set(cs);
|
||||
context.ComputeShader.SetShaderResources(0, resourceViews);
|
||||
context.ComputeShader.SetUnorderedAccessView(0, unorderedAccessView);
|
||||
|
||||
if (constantBuffer != null)
|
||||
{
|
||||
//make sure buffer is updated first...
|
||||
//D3D11_MAPPED_SUBRESOURCE mappedResource;
|
||||
//dc->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
||||
//memcpy(mappedResource.pData, constantData, constantDataSize);
|
||||
//dc->Unmap(constantBuffer, 0);
|
||||
context.ComputeShader.SetConstantBuffer(0, constantBuffer); //dc->CSSetConstantBuffers(0, 1, &constantBuffer);
|
||||
}
|
||||
|
||||
context.Dispatch(X, Y, Z);
|
||||
|
||||
ShaderResourceView[] ppSRVNULL = { null, null, null };
|
||||
context.ComputeShader.SetUnorderedAccessView(0, null);
|
||||
context.ComputeShader.SetShaderResources(0, 3, ppSRVNULL);
|
||||
context.ComputeShader.SetConstantBuffer(0, null);
|
||||
}
|
||||
|
||||
private void CopyPixels(DeviceContext context, int w, int h, ShaderResourceView fromSRV, RenderTargetView toRTV)
|
||||
{
|
||||
context.VertexShader.Set(FinalPassVS);
|
||||
context.PixelShader.Set(CopyPixelsPS);
|
||||
|
||||
ShaderResourceView[] aRViews = { fromSRV };
|
||||
context.PixelShader.SetShaderResource(0, fromSRV);
|
||||
|
||||
RenderTargetView[] aRTViews = { toRTV };
|
||||
context.OutputMerger.SetRenderTargets(toRTV);
|
||||
|
||||
//D3D11_MAPPED_SUBRESOURCE mappedResource;
|
||||
//dc->Map(ReduceCSVars.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
||||
//UINT* p = (UINT*)mappedResource.pData;
|
||||
//p[0] = w;
|
||||
//p[1] = h;
|
||||
//dc->Unmap(ReduceCSVars.Get(), 0);
|
||||
//ID3D11Buffer* ppCB[1] = { ReduceCSVars.Get() };
|
||||
//dc->PSSetConstantBuffers(0, 1, ppCB);
|
||||
ReduceCSVars.Vars.dimx = (uint)w;
|
||||
ReduceCSVars.Vars.dimy = (uint)h;
|
||||
ReduceCSVars.Update(context);
|
||||
ReduceCSVars.SetPSCBuffer(context, 0);
|
||||
|
||||
//DrawFullScreenQuad11( pd3dImmediateContext, g_pDumpBufferPS, dwWidth, dwHeight );
|
||||
//ViewportF[] vpOld = new ViewportF[15];// [D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX];
|
||||
//UINT nViewPorts = 1;
|
||||
//dc->RSGetViewports(&nViewPorts, vpOld);
|
||||
context.Rasterizer.GetViewports(vpOld);
|
||||
|
||||
// Setup the viewport to match the backbuffer
|
||||
ViewportF vp;
|
||||
vp.Width = (float)Width;
|
||||
vp.Height = (float)Height;
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.X = 0;
|
||||
vp.Y = 0;
|
||||
context.Rasterizer.SetViewport(vp);
|
||||
|
||||
context.InputAssembler.InputLayout = FinalPassLayout;
|
||||
FinalPassQuad.Draw(context);
|
||||
|
||||
|
||||
context.Rasterizer.SetViewports(vpOld); //reverting viewports maybe not necessary...
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using CodeWalker.GameFiles;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D11;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public abstract class Shader
|
||||
{
|
||||
|
||||
public abstract void SetShader(DeviceContext context);
|
||||
public abstract bool SetInputLayout(DeviceContext context, VertexType type);
|
||||
public abstract void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights);
|
||||
public abstract void SetEntityVars(DeviceContext context, ref RenderableInst rend);
|
||||
public abstract void SetModelVars(DeviceContext context, RenderableModel model);
|
||||
public abstract void SetGeomVars(DeviceContext context, RenderableGeometry geom);
|
||||
public abstract void UnbindResources(DeviceContext context);
|
||||
|
||||
//public abstract void Dispose();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,351 @@
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.DXGI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using SharpDX;
|
||||
using CodeWalker.GameFiles;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
|
||||
public struct ShadowShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public Vector4 WindVector;
|
||||
}
|
||||
public struct ShadowShaderVSEntityVars
|
||||
{
|
||||
public Vector4 CamRel;
|
||||
public Quaternion Orientation;
|
||||
public uint HasSkeleton;
|
||||
public uint HasTransforms;
|
||||
public uint TintPaletteIndex;
|
||||
public uint Pad1;
|
||||
public Vector3 Scale;
|
||||
public uint Pad2;
|
||||
}
|
||||
public struct ShadowShaderVSModelVars
|
||||
{
|
||||
public Matrix Transform;
|
||||
}
|
||||
//public struct ShadowShaderVSGeomVars
|
||||
//{
|
||||
// public uint EnableTint;
|
||||
// public float TintYVal;
|
||||
// public uint IsDecal;
|
||||
// public uint Pad5;
|
||||
//}
|
||||
public struct ShadowShaderGeomVars
|
||||
{
|
||||
public uint EnableTexture;
|
||||
public uint EnableTint;
|
||||
public uint IsDecal;
|
||||
public uint EnableWind;
|
||||
public Vector4 WindOverrideParams;
|
||||
}
|
||||
|
||||
public class ShadowShader : Shader, IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader shadowvs;
|
||||
PixelShader shadowps;
|
||||
|
||||
GpuVarsBuffer<ShadowShaderVSSceneVars> VSSceneVars;
|
||||
GpuVarsBuffer<ShadowShaderVSEntityVars> VSEntityVars;
|
||||
GpuVarsBuffer<ShadowShaderVSModelVars> VSModelVars;
|
||||
GpuVarsBuffer<ShadowShaderGeomVars> GeomVars;
|
||||
|
||||
SamplerState texsampler;
|
||||
SamplerState texsamplerc;
|
||||
//public bool DecalMode = false;
|
||||
|
||||
public Vector4 WindVector { get; set; }
|
||||
|
||||
|
||||
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
|
||||
|
||||
public ShadowShader(Device device)
|
||||
{
|
||||
byte[] vsbytes = File.ReadAllBytes("Shaders\\ShadowVS.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\ShadowPS.cso");
|
||||
|
||||
shadowvs = new VertexShader(device, vsbytes);
|
||||
shadowps = new PixelShader(device, psbytes);
|
||||
|
||||
|
||||
VSSceneVars = new GpuVarsBuffer<ShadowShaderVSSceneVars>(device);
|
||||
VSEntityVars = new GpuVarsBuffer<ShadowShaderVSEntityVars>(device);
|
||||
VSModelVars = new GpuVarsBuffer<ShadowShaderVSModelVars>(device);
|
||||
GeomVars = new GpuVarsBuffer<ShadowShaderGeomVars>(device);
|
||||
|
||||
|
||||
//supported layouts - requires Position, Normal, Colour, Texcoord
|
||||
layouts.Add(VertexType.Default, new InputLayout(device, vsbytes, VertexTypeDefault.GetLayout()));
|
||||
layouts.Add(VertexType.DefaultEx, new InputLayout(device, vsbytes, VertexTypeDefaultEx.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCT, new InputLayout(device, vsbytes, VertexTypePNCCT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTTT, new InputLayout(device, vsbytes, VertexTypePNCCTTTT.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCCTTX, new InputLayout(device, vsbytes, VertexTypePCCNCCTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCCT, new InputLayout(device, vsbytes, VertexTypePCCNCCT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTTX, new InputLayout(device, vsbytes, VertexTypePNCTTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTTX_2, new InputLayout(device, vsbytes, VertexTypePNCTTTX_2.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTTX_3, new InputLayout(device, vsbytes, VertexTypePNCTTTX_3.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTTTX, new InputLayout(device, vsbytes, VertexTypePNCTTTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTX, new InputLayout(device, vsbytes, VertexTypePNCTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTX, new InputLayout(device, vsbytes, VertexTypePNCCTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTX_2, new InputLayout(device, vsbytes, VertexTypePNCCTTX_2.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTTX, new InputLayout(device, vsbytes, VertexTypePNCCTTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCCTX, new InputLayout(device, vsbytes, VertexTypePCCNCCTX.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCTX, new InputLayout(device, vsbytes, VertexTypePCCNCTX.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCT, new InputLayout(device, vsbytes, VertexTypePCCNCT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTT, new InputLayout(device, vsbytes, VertexTypePNCCTT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTX, new InputLayout(device, vsbytes, VertexTypePNCCTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCH2, new InputLayout(device, vsbytes, VertexTypePNCH2.GetLayout()));
|
||||
layouts.Add(VertexType.PCCH2H4, new InputLayout(device, vsbytes, VertexTypePCCH2H4.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCTT, new InputLayout(device, vsbytes, VertexTypePCCNCTT.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCTTX, new InputLayout(device, vsbytes, VertexTypePCCNCTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PCCNCTTT, new InputLayout(device, vsbytes, VertexTypePCCNCTTT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTT, new InputLayout(device, vsbytes, VertexTypePNCTT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTT, new InputLayout(device, vsbytes, VertexTypePNCTTT.GetLayout()));
|
||||
|
||||
|
||||
|
||||
texsampler = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipLinear,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
texsamplerc = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Clamp,
|
||||
AddressV = TextureAddressMode.Clamp,
|
||||
AddressW = TextureAddressMode.Clamp,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipPoint,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.Set(shadowvs);
|
||||
context.PixelShader.Set(shadowps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
InputLayout l;
|
||||
if (layouts.TryGetValue(type, out l))
|
||||
{
|
||||
context.InputAssembler.InputLayout = l;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
}
|
||||
public void SetSceneVars(DeviceContext context, Matrix shadowviewproj)
|
||||
{
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(shadowviewproj);
|
||||
VSSceneVars.Vars.WindVector = WindVector;
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 0);
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = rend.Orientation;
|
||||
VSEntityVars.Vars.Scale = rend.Scale;
|
||||
VSEntityVars.Vars.HasSkeleton = rend.Renderable.HasSkeleton ? 1u : 0;
|
||||
VSEntityVars.Vars.HasTransforms = rend.Renderable.HasTransforms ? 1u : 0;
|
||||
VSEntityVars.Vars.TintPaletteIndex = rend.TintPaletteIndex;
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 1);
|
||||
}
|
||||
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
if (!model.UseTransform) return;
|
||||
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
|
||||
VSModelVars.Update(context);
|
||||
VSModelVars.SetVSCBuffer(context, 2);
|
||||
}
|
||||
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
RenderableTexture texture = null; // ((geom.Textures != null) && (geom.Textures.Length > 0)) ? geom.Textures[0] : null;
|
||||
//RenderableTexture tintpal = null;
|
||||
|
||||
//float tntpalind = 0.0f;
|
||||
|
||||
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
|
||||
{
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
switch (ihash)
|
||||
{
|
||||
case MetaName.DiffuseSampler:
|
||||
case MetaName.TextureSampler_layer0:
|
||||
case MetaName.TextureSampler_layer1:
|
||||
case MetaName.TextureSampler_layer2:
|
||||
case MetaName.TextureSampler_layer3:
|
||||
texture = itex;
|
||||
break;
|
||||
}
|
||||
if (texture != null) break;
|
||||
}
|
||||
|
||||
////try get default diffuse texture
|
||||
//if ((geom.DiffuseSampler >= 0) && (geom.DiffuseSampler < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[geom.DiffuseSampler];
|
||||
//}
|
||||
//if ((texture == null) && (geom.TextureSampler_layer0 >= 0) && (geom.TextureSampler_layer0 < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[geom.TextureSampler_layer0];
|
||||
//}
|
||||
//if ((texture == null) && (geom.TextureSampler_layer1 >= 0) && (geom.TextureSampler_layer1 < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[geom.TextureSampler_layer1];
|
||||
//}
|
||||
//if ((texture == null) && (geom.TextureSampler_layer2 >= 0) && (geom.TextureSampler_layer2 < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[geom.TextureSampler_layer2];
|
||||
//}
|
||||
//if ((texture == null) && (geom.TextureSampler_layer3 >= 0) && (geom.TextureSampler_layer3 < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[geom.TextureSampler_layer3];
|
||||
//}
|
||||
|
||||
//fallback try get first texture... eventaully remove this! (helps with water for now)
|
||||
int index = 0;
|
||||
while (((texture == null)) && (index < geom.RenderableTextures.Length))
|
||||
{
|
||||
texture = geom.RenderableTextures[index];
|
||||
index++;
|
||||
}
|
||||
|
||||
|
||||
//if ((geom.PaletteTexture >= 0) && (geom.PaletteTexture < geom.Textures.Length))
|
||||
//{
|
||||
// tintpal = geom.Textures[geom.PaletteTexture];
|
||||
// if (tintpal.Texture != null)
|
||||
// {
|
||||
// //this is slightly dodgy but vsentvarsdata should have the correct value in it...
|
||||
// tntpalind = (vsentvarsdata.TintPaletteIndex + 0.5f) / tintpal.Texture.Height;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
bool usediff = ((texture != null) && (texture.ShaderResourceView != null));
|
||||
|
||||
|
||||
uint windflag = 0;
|
||||
var shaderFile = geom.DrawableGeom.Shader.FileName;
|
||||
switch (shaderFile.Hash)
|
||||
{
|
||||
case 2245870123: //trees_normal_diffspec_tnt.sps
|
||||
case 3334613197: //trees_tnt.sps
|
||||
case 1229591973://{trees_normal_spec_tnt.sps}
|
||||
case 2322653400://{trees.sps}
|
||||
case 3192134330://{trees_normal.sps}
|
||||
case 1224713457://{trees_normal_spec.sps}
|
||||
case 4265705004://{trees_normal_diffspec.sps}
|
||||
windflag = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
GeomVars.Vars.EnableTexture = usediff ? 1u : 0u;
|
||||
GeomVars.Vars.EnableTint = 0u;// usetint ? 1u : 0u;
|
||||
GeomVars.Vars.IsDecal = 0u;// DecalMode ? 1u : 0u;
|
||||
GeomVars.Vars.EnableWind = windflag;
|
||||
GeomVars.Vars.WindOverrideParams = geom.WindOverrideParams;
|
||||
GeomVars.Update(context);
|
||||
GeomVars.SetPSCBuffer(context, 0);
|
||||
GeomVars.SetVSCBuffer(context, 3);
|
||||
|
||||
context.VertexShader.SetSampler(0, texsamplerc);
|
||||
context.PixelShader.SetSampler(0, texsampler);
|
||||
//context.PixelShader.SetSampler(1, texsamplerc);
|
||||
if (usediff)
|
||||
{
|
||||
texture.SetPSResource(context, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetConstantBuffer(1, null);
|
||||
context.VertexShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(3, null);
|
||||
context.PixelShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetSampler(0, null);
|
||||
context.PixelShader.SetSampler(0, null);
|
||||
context.PixelShader.SetShaderResource(0, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
|
||||
if (texsampler != null)
|
||||
{
|
||||
texsampler.Dispose();
|
||||
texsampler = null;
|
||||
}
|
||||
|
||||
foreach (InputLayout layout in layouts.Values)
|
||||
{
|
||||
layout.Dispose();
|
||||
}
|
||||
layouts.Clear();
|
||||
|
||||
VSSceneVars.Dispose();
|
||||
VSEntityVars.Dispose();
|
||||
VSModelVars.Dispose();
|
||||
GeomVars.Dispose();
|
||||
|
||||
|
||||
shadowps.Dispose();
|
||||
shadowvs.Dispose();
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
using SharpDX;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using SharpDX.Direct3D11;
|
||||
using System.IO;
|
||||
using CodeWalker.GameFiles;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
|
||||
public struct SkydomeShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public Matrix ViewInv;
|
||||
}
|
||||
public struct SkydomeShaderVSEntityVars
|
||||
{
|
||||
public Vector4 CamRel;
|
||||
public Quaternion Orientation;
|
||||
}
|
||||
public struct SkydomeShaderVSModelVars
|
||||
{
|
||||
public Matrix Transform;
|
||||
}
|
||||
public struct SkydomeShaderPSSceneVars
|
||||
{
|
||||
public Vector4 LightDirection;
|
||||
public uint EnableHDR;
|
||||
public uint Pad0;
|
||||
public uint Pad1;
|
||||
public uint Pad2;
|
||||
}
|
||||
|
||||
public struct SkydomeShaderVSSunMoonVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public Matrix ViewInv;
|
||||
public Vector4 CamRel;
|
||||
public Vector2 Size;
|
||||
public Vector2 Offset;
|
||||
}
|
||||
public struct SkydomeShaderPSSunMoonVars
|
||||
{
|
||||
public Vector4 Colour;
|
||||
}
|
||||
|
||||
|
||||
public struct SkydomeShaderSkySystemLocals
|
||||
{
|
||||
public Vector4 azimuthEastColor; // Offset: 0 Size: 12
|
||||
public Vector4 azimuthWestColor; // Offset: 16 Size: 12
|
||||
public Vector3 azimuthTransitionColor; // Offset: 32 Size: 12
|
||||
public float azimuthTransitionPosition; // Offset: 44 Size: 4
|
||||
public Vector4 zenithColor; // Offset: 48 Size: 12
|
||||
public Vector4 zenithTransitionColor; // Offset: 64 Size: 12
|
||||
public Vector4 zenithConstants; // Offset: 80 Size: 16
|
||||
public Vector4 skyPlaneColor; // Offset: 96 Size: 16 [unused]
|
||||
public Vector4 skyPlaneParams; // Offset: 112 Size: 16 [unused]
|
||||
public float hdrIntensity; // Offset: 128 Size: 4
|
||||
public Vector3 sunColor; // Offset: 132 Size: 12
|
||||
public Vector4 sunColorHdr; // Offset: 144 Size: 12
|
||||
public Vector4 sunDiscColorHdr; // Offset: 160 Size: 12 [unused]
|
||||
public Vector4 sunConstants; // Offset: 176 Size: 16
|
||||
public Vector4 sunDirection; // Offset: 192 Size: 12
|
||||
public Vector4 sunPosition; // Offset: 208 Size: 12 [unused]
|
||||
public Vector4 cloudBaseMinusMidColour; // Offset: 224 Size: 12
|
||||
public Vector4 cloudMidColour; // Offset: 240 Size: 12
|
||||
public Vector4 cloudShadowMinusBaseColourTimesShadowStrength;// Offset: 256 Size: 12
|
||||
public Vector4 cloudDetailConstants; // Offset: 272 Size: 16
|
||||
public Vector4 cloudConstants1; // Offset: 288 Size: 16
|
||||
public Vector4 cloudConstants2; // Offset: 304 Size: 16
|
||||
public Vector4 smallCloudConstants; // Offset: 320 Size: 16
|
||||
public Vector4 smallCloudColorHdr; // Offset: 336 Size: 12
|
||||
public Vector4 effectsConstants; // Offset: 352 Size: 16
|
||||
public float horizonLevel; // Offset: 368 Size: 4
|
||||
public Vector3 speedConstants; // Offset: 372 Size: 12
|
||||
public float starfieldIntensity; // Offset: 384 Size: 4
|
||||
public Vector3 moonDirection; // Offset: 388 Size: 12
|
||||
public Vector3 moonPosition; // Offset: 400 Size: 12 [unused]
|
||||
public float moonIntensity; // Offset: 412 Size: 4 [unused]
|
||||
public Vector4 lunarCycle; // Offset: 416 Size: 12
|
||||
public Vector3 moonColor; // Offset: 432 Size: 12
|
||||
public float noiseFrequency; // Offset: 444 Size: 4 [unused]
|
||||
public float noiseScale; // Offset: 448 Size: 4 [unused]
|
||||
public float noiseThreshold; // Offset: 452 Size: 4 [unused]
|
||||
public float noiseSoftness; // Offset: 456 Size: 4 [unused]
|
||||
public float noiseDensityOffset; // Offset: 460 Size: 4 [unused]
|
||||
public Vector4 noisePhase; // Offset: 464 Size: 8 [unused]
|
||||
}
|
||||
|
||||
|
||||
public class SkydomeShader : Shader, IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader skyvs;
|
||||
PixelShader skyps;
|
||||
VertexShader sunvs;
|
||||
PixelShader sunps;
|
||||
VertexShader moonvs;
|
||||
PixelShader moonps;
|
||||
|
||||
GpuVarsBuffer<SkydomeShaderSkySystemLocals> SkyLocalVars;
|
||||
GpuVarsBuffer<SkydomeShaderVSSceneVars> VSSceneVars;
|
||||
GpuVarsBuffer<SkydomeShaderVSEntityVars> VSEntityVars;
|
||||
GpuVarsBuffer<SkydomeShaderVSModelVars> VSModelVars;
|
||||
GpuVarsBuffer<SkydomeShaderPSSceneVars> PSSceneVars;
|
||||
|
||||
GpuVarsBuffer<SkydomeShaderVSSunMoonVars> VSSunMoonVars;
|
||||
GpuVarsBuffer<SkydomeShaderPSSunMoonVars> PSSunMoonVars;
|
||||
|
||||
|
||||
SamplerState texsampler;
|
||||
|
||||
InputLayout skylayout;
|
||||
InputLayout sunlayout;
|
||||
InputLayout moonlayout;
|
||||
|
||||
UnitDisc sundisc;
|
||||
UnitQuad moonquad;
|
||||
|
||||
public bool EnableHDR { get; set; }
|
||||
|
||||
|
||||
public SkydomeShader(Device device)
|
||||
{
|
||||
byte[] skyvsbytes = File.ReadAllBytes("Shaders\\SkydomeVS.cso");
|
||||
byte[] skypsbytes = File.ReadAllBytes("Shaders\\SkydomePS.cso");
|
||||
byte[] sunvsbytes = File.ReadAllBytes("Shaders\\SkySunVS.cso");
|
||||
byte[] sunpsbytes = File.ReadAllBytes("Shaders\\SkySunPS.cso");
|
||||
byte[] moonvsbytes = File.ReadAllBytes("Shaders\\SkyMoonVS.cso");
|
||||
byte[] moonpsbytes = File.ReadAllBytes("Shaders\\SkyMoonPS.cso");
|
||||
|
||||
skyvs = new VertexShader(device, skyvsbytes);
|
||||
skyps = new PixelShader(device, skypsbytes);
|
||||
sunvs = new VertexShader(device, sunvsbytes);
|
||||
sunps = new PixelShader(device, sunpsbytes);
|
||||
moonvs = new VertexShader(device, moonvsbytes);
|
||||
moonps = new PixelShader(device, moonpsbytes);
|
||||
|
||||
SkyLocalVars = new GpuVarsBuffer<SkydomeShaderSkySystemLocals>(device);
|
||||
VSSceneVars = new GpuVarsBuffer<SkydomeShaderVSSceneVars>(device);
|
||||
VSEntityVars = new GpuVarsBuffer<SkydomeShaderVSEntityVars>(device);
|
||||
VSModelVars = new GpuVarsBuffer<SkydomeShaderVSModelVars>(device);
|
||||
PSSceneVars = new GpuVarsBuffer<SkydomeShaderPSSceneVars>(device);
|
||||
|
||||
VSSunMoonVars = new GpuVarsBuffer<SkydomeShaderVSSunMoonVars>(device);
|
||||
PSSunMoonVars = new GpuVarsBuffer<SkydomeShaderPSSunMoonVars>(device);
|
||||
|
||||
sundisc = new UnitDisc(device, 30, true);
|
||||
sunlayout = new InputLayout(device, sunvsbytes, sundisc.GetLayout());
|
||||
skylayout = new InputLayout(device, skyvsbytes, VertexTypePTT.GetLayout());
|
||||
|
||||
moonquad = new UnitQuad(device, true);
|
||||
moonlayout = new InputLayout(device, moonvsbytes, moonquad.GetLayout());
|
||||
|
||||
texsampler = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipLinear,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.Set(skyvs);
|
||||
context.PixelShader.Set(skyps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
if (type != VertexType.PTT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
context.InputAssembler.InputLayout = skylayout;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateSkyLocals(Weather weather, ShaderGlobalLights lights)
|
||||
{
|
||||
var wv = weather.CurrentValues;
|
||||
|
||||
float skyhdr = EnableHDR ? wv.skyHdr : Math.Min(wv.skyHdr, 1.8f);
|
||||
float sunhdr = EnableHDR ? wv.skySunHdr : Math.Min(wv.skySunHdr, 4.8f); //NO HDR - turn it down!!!
|
||||
float scathdr = EnableHDR ? wv.skySunScatterInten : Math.Min(wv.skySunScatterInten, 1.8f);
|
||||
Vector3 suncolhdr = wv.skySunCol * sunhdr;
|
||||
Vector4 azecol = wv.skyAzimuthEastCol;
|
||||
Vector4 azwcol = wv.skyAzimuthWestCol;
|
||||
Vector4 aztcol = wv.skyAzimuthTransitionCol;
|
||||
Vector4 zencol = wv.skyZenithCol;
|
||||
Vector4 zetcol = wv.skyZenithTransitionCol;
|
||||
Vector4 plncol = wv.skyPlane;
|
||||
|
||||
SkyLocalVars.Vars.azimuthEastColor = azecol;
|
||||
SkyLocalVars.Vars.azimuthWestColor = azwcol;
|
||||
SkyLocalVars.Vars.azimuthTransitionColor = aztcol.XYZ();
|
||||
SkyLocalVars.Vars.azimuthTransitionPosition = wv.skyAzimuthTransition;
|
||||
SkyLocalVars.Vars.zenithColor = zencol;
|
||||
SkyLocalVars.Vars.zenithTransitionColor = zetcol;
|
||||
SkyLocalVars.Vars.zenithConstants = wv.skyZenithTransition;
|
||||
SkyLocalVars.Vars.skyPlaneColor = plncol;
|
||||
SkyLocalVars.Vars.skyPlaneParams = Vector4.Zero;
|
||||
SkyLocalVars.Vars.hdrIntensity = skyhdr;
|
||||
SkyLocalVars.Vars.sunColor = wv.skySunCol;
|
||||
SkyLocalVars.Vars.sunColorHdr = new Vector4(suncolhdr, sunhdr);
|
||||
SkyLocalVars.Vars.sunDiscColorHdr = new Vector4(wv.skySunDiscCol, wv.skySunDiscSize);
|
||||
//SkyLocalVars.Vars.sunConstants = new Vector4(wv.skySunMie, scathdr);
|
||||
//SkyLocalVars.Vars.sunConstants.X = wv.skySunMie.X; //mie phase
|
||||
//SkyLocalVars.Vars.sunConstants.Y = wv.skySunMie.Y; //mie scatter
|
||||
//SkyLocalVars.Vars.sunConstants.Z = 0.5f / wv.skySunInfluenceRadius;// * 0.01f; // 0.0025f; //mie size/"range"
|
||||
//SkyLocalVars.Vars.sunConstants.W = wv.skySunMie.Z;// * scathdr; //mie hdr intensity
|
||||
SkyLocalVars.Vars.sunConstants.X = wv.skySunMie.X * wv.skySunMie.Y; //mie phase
|
||||
SkyLocalVars.Vars.sunConstants.Y = wv.skySunMie.Y;// 1.0f /wv.skySunMie.Y;// 1.7f;// wv.skySunMie.Y; //mie scatter
|
||||
SkyLocalVars.Vars.sunConstants.Z = 0.00003f * wv.skySunInfluenceRadius;// * wv.skySunMie.X;// wv.skySunMie.Z;///720.0f;// * 0.01f; // 0.0025f; //mie size/"range"
|
||||
SkyLocalVars.Vars.sunConstants.W = wv.skySunMie.Z;// * scathdr; //mie intensity multiplier
|
||||
SkyLocalVars.Vars.sunDirection = new Vector4(-lights.CurrentSunDir, 0);// wv.sunDirection, 0);
|
||||
SkyLocalVars.Vars.sunPosition = new Vector4(-lights.CurrentSunDir, 0); //not used
|
||||
SkyLocalVars.Vars.cloudBaseMinusMidColour = Vector4.Zero;
|
||||
SkyLocalVars.Vars.cloudMidColour = Vector4.Zero;
|
||||
SkyLocalVars.Vars.cloudShadowMinusBaseColourTimesShadowStrength = Vector4.Zero;
|
||||
SkyLocalVars.Vars.cloudDetailConstants = Vector4.Zero;
|
||||
SkyLocalVars.Vars.cloudConstants1 = Vector4.Zero;
|
||||
SkyLocalVars.Vars.cloudConstants2 = Vector4.Zero;
|
||||
SkyLocalVars.Vars.smallCloudConstants = Vector4.Zero;
|
||||
SkyLocalVars.Vars.smallCloudColorHdr = Vector4.Zero;
|
||||
SkyLocalVars.Vars.effectsConstants = Vector4.Zero;
|
||||
SkyLocalVars.Vars.horizonLevel = 0;
|
||||
SkyLocalVars.Vars.speedConstants = Vector3.Zero;
|
||||
SkyLocalVars.Vars.starfieldIntensity = wv.skyStarsIten * 5.0f; //makes stars brighter....
|
||||
SkyLocalVars.Vars.moonDirection = wv.moonDirection;
|
||||
SkyLocalVars.Vars.moonPosition = Vector3.Zero;//need to update this?
|
||||
SkyLocalVars.Vars.moonIntensity = wv.skyMoonIten;
|
||||
SkyLocalVars.Vars.lunarCycle = Vector4.Zero;
|
||||
SkyLocalVars.Vars.moonColor = wv.skyMoonCol;
|
||||
SkyLocalVars.Vars.noiseFrequency = 0;
|
||||
SkyLocalVars.Vars.noiseScale = 0;
|
||||
SkyLocalVars.Vars.noiseThreshold = 0;
|
||||
SkyLocalVars.Vars.noiseSoftness = 0;
|
||||
SkyLocalVars.Vars.noiseDensityOffset = 0;
|
||||
SkyLocalVars.Vars.noisePhase = Vector4.Zero;
|
||||
}
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
SkyLocalVars.Update(context);
|
||||
SkyLocalVars.SetVSCBuffer(context, 0);
|
||||
SkyLocalVars.SetPSCBuffer(context, 0);
|
||||
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSceneVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix);
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 1);
|
||||
|
||||
PSSceneVars.Vars.LightDirection = new Vector4(lights.Params.LightDir, 0.0f);
|
||||
PSSceneVars.Vars.EnableHDR = EnableHDR ? 1u : 0u;
|
||||
PSSceneVars.Update(context);
|
||||
PSSceneVars.SetPSCBuffer(context, 1);
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = rend.Orientation;
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 2);
|
||||
}
|
||||
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
if (!model.UseTransform) return;
|
||||
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
|
||||
VSModelVars.Update(context);
|
||||
VSModelVars.SetVSCBuffer(context, 3);
|
||||
}
|
||||
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
//don't use this version
|
||||
}
|
||||
|
||||
public void SetTextures(DeviceContext context, RenderableTexture starfield)
|
||||
{
|
||||
if (starfield != null)
|
||||
{
|
||||
context.PixelShader.SetSampler(0, texsampler);
|
||||
starfield.SetPSResource(context, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.PixelShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetConstantBuffer(1, null);
|
||||
context.PixelShader.SetConstantBuffer(1, null);
|
||||
context.VertexShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(3, null);
|
||||
context.PixelShader.SetSampler(0, null);
|
||||
context.PixelShader.SetShaderResource(0, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void RenderSun(DeviceContext context, Camera camera, Weather weather, ShaderGlobalLights lights)
|
||||
{
|
||||
|
||||
context.VertexShader.Set(sunvs);
|
||||
context.PixelShader.Set(sunps);
|
||||
|
||||
VSSunMoonVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSunMoonVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix);
|
||||
VSSunMoonVars.Vars.CamRel = new Vector4(lights.CurrentSunDir, 0);
|
||||
VSSunMoonVars.Vars.Size = new Vector2(weather.CurrentValues.skySunDiscSize * 0.008f);
|
||||
VSSunMoonVars.Vars.Offset = Vector2.Zero;
|
||||
VSSunMoonVars.Update(context);
|
||||
VSSunMoonVars.SetVSCBuffer(context, 0);
|
||||
|
||||
PSSunMoonVars.Vars.Colour = new Vector4(weather.CurrentValues.skySunDiscCol * weather.CurrentValues.skySunHdr, 1);
|
||||
PSSunMoonVars.Update(context);
|
||||
PSSunMoonVars.SetPSCBuffer(context, 0);
|
||||
|
||||
context.InputAssembler.InputLayout = sunlayout;
|
||||
sundisc.Draw(context);
|
||||
}
|
||||
|
||||
public void RenderMoon(DeviceContext context, Camera camera, Weather weather, ShaderGlobalLights lights, RenderableTexture moontex)
|
||||
{
|
||||
context.VertexShader.Set(moonvs);
|
||||
context.PixelShader.Set(moonps);
|
||||
|
||||
|
||||
Quaternion ori = Quaternion.Invert(Quaternion.LookAtRH(Vector3.Zero, lights.CurrentMoonDir, lights.MoonAxis));
|
||||
Matrix omat = ori.ToMatrix();
|
||||
|
||||
|
||||
VSSunMoonVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSunMoonVars.Vars.ViewInv = Matrix.Transpose(omat);// camera.ViewInvMatrix);
|
||||
VSSunMoonVars.Vars.CamRel = new Vector4(lights.CurrentMoonDir, 0);
|
||||
VSSunMoonVars.Vars.Size = new Vector2(weather.CurrentValues.skyMoonDiscSize * 0.008f);
|
||||
VSSunMoonVars.Vars.Offset = Vector2.Zero;
|
||||
VSSunMoonVars.Update(context);
|
||||
VSSunMoonVars.SetVSCBuffer(context, 0);
|
||||
|
||||
PSSunMoonVars.Vars.Colour = new Vector4(weather.CurrentValues.skyMoonCol * weather.CurrentValues.skyMoonIten, weather.CurrentValues.skyMoonIten);
|
||||
PSSunMoonVars.Update(context);
|
||||
PSSunMoonVars.SetPSCBuffer(context, 0);
|
||||
|
||||
context.PixelShader.SetSampler(0, texsampler);
|
||||
moontex.SetPSResource(context, 0);
|
||||
|
||||
context.InputAssembler.InputLayout = moonlayout;
|
||||
moonquad.Draw(context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
disposed = true;
|
||||
|
||||
texsampler.Dispose();
|
||||
|
||||
sundisc.Dispose();
|
||||
moonquad.Dispose();
|
||||
|
||||
skylayout.Dispose();
|
||||
sunlayout.Dispose();
|
||||
moonlayout.Dispose();
|
||||
|
||||
VSSunMoonVars.Dispose();
|
||||
PSSunMoonVars.Dispose();
|
||||
|
||||
SkyLocalVars.Dispose();
|
||||
VSSceneVars.Dispose();
|
||||
VSEntityVars.Dispose();
|
||||
VSModelVars.Dispose();
|
||||
PSSceneVars.Dispose();
|
||||
|
||||
skyps.Dispose();
|
||||
skyvs.Dispose();
|
||||
sunps.Dispose();
|
||||
sunvs.Dispose();
|
||||
moonps.Dispose();
|
||||
moonvs.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,645 @@
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.DXGI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using SharpDX;
|
||||
using CodeWalker.GameFiles;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
|
||||
public struct TerrainShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
}
|
||||
public struct TerrainShaderVSEntityVars
|
||||
{
|
||||
public Vector4 CamRel;
|
||||
public Quaternion Orientation;
|
||||
public uint HasSkeleton;
|
||||
public uint HasTransforms;
|
||||
public uint TintPaletteIndex;
|
||||
public uint Pad1;
|
||||
public Vector3 Scale;
|
||||
public uint Pad2;
|
||||
}
|
||||
public struct TerrainShaderVSModelVars
|
||||
{
|
||||
public Matrix Transform;
|
||||
}
|
||||
public struct TerrainShaderVSGeomVars
|
||||
{
|
||||
public uint EnableTint;
|
||||
public float TintYVal;
|
||||
public uint Pad4;
|
||||
public uint Pad5;
|
||||
}
|
||||
public struct TerrainShaderPSSceneVars
|
||||
{
|
||||
public ShaderGlobalLightParams GlobalLights;
|
||||
public uint EnableShadows;
|
||||
public uint RenderMode; //0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct
|
||||
public uint RenderModeIndex; //colour/texcoord index
|
||||
public uint RenderSamplerCoord; //which texcoord to use in single texture mode
|
||||
}
|
||||
public struct TerrainShaderPSGeomVars
|
||||
{
|
||||
public uint EnableTexture0;
|
||||
public uint EnableTexture1;
|
||||
public uint EnableTexture2;
|
||||
public uint EnableTexture3;
|
||||
public uint EnableTexture4;
|
||||
public uint EnableTextureMask;
|
||||
public uint EnableNormalMap;
|
||||
public uint ShaderName;
|
||||
public uint EnableTint;
|
||||
public uint EnableVertexColour;
|
||||
public float bumpiness;
|
||||
public uint Pad102;
|
||||
}
|
||||
|
||||
public class TerrainShader : Shader, IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader pncctvs;
|
||||
VertexShader pnccttvs;
|
||||
VertexShader pnccttxvs;
|
||||
VertexShader pncctttxvs;
|
||||
VertexShader pncctxvs;
|
||||
VertexShader pnctttxvs;
|
||||
VertexShader pncttxvs;
|
||||
PixelShader terrainps;
|
||||
GpuVarsBuffer<TerrainShaderVSSceneVars> VSSceneVars;
|
||||
GpuVarsBuffer<TerrainShaderVSEntityVars> VSEntityVars;
|
||||
GpuVarsBuffer<TerrainShaderVSModelVars> VSModelVars;
|
||||
GpuVarsBuffer<TerrainShaderVSGeomVars> VSGeomVars;
|
||||
GpuVarsBuffer<TerrainShaderPSSceneVars> PSSceneVars;
|
||||
GpuVarsBuffer<TerrainShaderPSGeomVars> PSGeomVars;
|
||||
SamplerState texsampler;
|
||||
SamplerState texsampleranis;
|
||||
SamplerState texsamplertnt;
|
||||
public bool AnisotropicFilter = false;
|
||||
public WorldRenderMode RenderMode = WorldRenderMode.Default;
|
||||
public int RenderVertexColourIndex = 1;
|
||||
public int RenderTextureCoordIndex = 1;
|
||||
public int RenderTextureSamplerCoord = 1;
|
||||
public MetaName RenderTextureSampler = MetaName.DiffuseSampler;
|
||||
|
||||
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
|
||||
|
||||
|
||||
public TerrainShader(Device device)
|
||||
{
|
||||
byte[] vspncct = File.ReadAllBytes("Shaders\\TerrainVS_PNCCT.cso");
|
||||
byte[] vspncctt = File.ReadAllBytes("Shaders\\TerrainVS_PNCCTT.cso");
|
||||
byte[] vspnccttx = File.ReadAllBytes("Shaders\\TerrainVS_PNCCTTX.cso");
|
||||
byte[] vspncctttx = File.ReadAllBytes("Shaders\\TerrainVS_PNCCTTTX.cso");
|
||||
byte[] vspncctx = File.ReadAllBytes("Shaders\\TerrainVS_PNCCTX.cso");
|
||||
byte[] vspnctttx = File.ReadAllBytes("Shaders\\TerrainVS_PNCTTTX.cso");
|
||||
byte[] vspncttx = File.ReadAllBytes("Shaders\\TerrainVS_PNCTTX.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\TerrainPS.cso");
|
||||
|
||||
pncctvs = new VertexShader(device, vspncct);
|
||||
pnccttvs = new VertexShader(device, vspncctt);
|
||||
pnccttxvs = new VertexShader(device, vspnccttx);
|
||||
pncctttxvs = new VertexShader(device, vspncctttx);
|
||||
pncctxvs = new VertexShader(device, vspncctx);
|
||||
pnctttxvs = new VertexShader(device, vspnctttx);
|
||||
pncttxvs = new VertexShader(device, vspncttx);
|
||||
terrainps = new PixelShader(device, psbytes);
|
||||
|
||||
VSSceneVars = new GpuVarsBuffer<TerrainShaderVSSceneVars>(device);
|
||||
VSEntityVars = new GpuVarsBuffer<TerrainShaderVSEntityVars>(device);
|
||||
VSModelVars = new GpuVarsBuffer<TerrainShaderVSModelVars>(device);
|
||||
VSGeomVars = new GpuVarsBuffer<TerrainShaderVSGeomVars>(device);
|
||||
PSSceneVars = new GpuVarsBuffer<TerrainShaderPSSceneVars>(device);
|
||||
PSGeomVars = new GpuVarsBuffer<TerrainShaderPSGeomVars>(device);
|
||||
|
||||
//supported layouts - requires Position, Normal, Colour, Texcoord
|
||||
layouts.Add(VertexType.PNCCT, new InputLayout(device, vspncct, VertexTypePNCCT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTT, new InputLayout(device, vspncctt, VertexTypePNCCTT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTX, new InputLayout(device, vspncttx, VertexTypePNCTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCTTTX_3, new InputLayout(device, vspnctttx, VertexTypePNCTTTX_3.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTX, new InputLayout(device, vspncctx, VertexTypePNCCTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTX, new InputLayout(device, vspnccttx, VertexTypePNCCTTX.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTX_2, new InputLayout(device, vspnccttx, VertexTypePNCCTTX_2.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTTX, new InputLayout(device, vspncctttx, VertexTypePNCCTTTX.GetLayout()));
|
||||
|
||||
|
||||
|
||||
texsampler = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipLinear,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
texsampleranis = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.Anisotropic,
|
||||
MaximumAnisotropy = 8,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
texsamplertnt = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.White,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipPoint,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void SetVertexShader(DeviceContext context, uint shaderhash)
|
||||
{
|
||||
//no longer used.
|
||||
|
||||
|
||||
//PNCCT terrain_cb_w_4lyr_lod (terrain_cb_w_4lyr_lod.sps)
|
||||
//PNCCTT terrain_cb_w_4lyr_2tex_blend_lod (terrain_cb_w_4lyr_2tex_blend_lod.sps)
|
||||
//PNCTTX terrain_cb_w_4lyr_cm (terrain_cb_w_4lyr_cm.sps)
|
||||
//PNCTTX terrain_cb_w_4lyr_cm_tnt (terrain_cb_w_4lyr_cm_tnt.sps)
|
||||
//PNCTTTX_3 terrain_cb_w_4lyr_cm_pxm (terrain_cb_w_4lyr_cm_pxm.sps)
|
||||
//PNCTTTX_3 terrain_cb_w_4lyr_cm_pxm_tnt (terrain_cb_w_4lyr_cm_pxm_tnt.sps)
|
||||
//PNCCTX terrain_cb_w_4lyr (terrain_cb_w_4lyr.sps)
|
||||
//PNCCTX terrain_cb_w_4lyr_spec (terrain_cb_w_4lyr_spec.sps)
|
||||
//PNCCTTX terrain_cb_w_4lyr_2tex (terrain_cb_w_4lyr_2tex.sps)
|
||||
//PNCCTTX terrain_cb_w_4lyr_2tex_blend (terrain_cb_w_4lyr_2tex_blend.sps)
|
||||
//PNCCTTX_2 terrain_cb_w_4lyr_pxm (terrain_cb_w_4lyr_pxm.sps)
|
||||
//PNCCTTX_2 terrain_cb_w_4lyr_pxm_spm (terrain_cb_w_4lyr_pxm_spm.sps)
|
||||
//PNCCTTX_2 terrain_cb_w_4lyr_spec_pxm (terrain_cb_w_4lyr_spec_pxm.sps)
|
||||
//PNCCTTTX terrain_cb_w_4lyr_2tex_pxm (terrain_cb_w_4lyr_2tex_pxm.sps)
|
||||
//PNCCTTTX terrain_cb_w_4lyr_2tex_blend_pxm (terrain_cb_w_4lyr_2tex_blend_pxm.sps)
|
||||
//PNCCTTTX terrain_cb_w_4lyr_2tex_blend_pxm_spm (terrain_cb_w_4lyr_2tex_blend_pxm_spm.sps)
|
||||
|
||||
|
||||
VertexType vt = VertexType.Default;
|
||||
switch (shaderhash)
|
||||
{
|
||||
case 295525123: //terrain_cb_w_4lyr_cm (terrain_cb_w_4lyr_cm.sps) vt: PNCTTX
|
||||
case 417637541: //terrain_cb_w_4lyr_cm_tnt (terrain_cb_w_4lyr_cm_tnt.sps) vt: PNCTTX
|
||||
vt = VertexType.PNCTTX;
|
||||
break;
|
||||
case 3965214311: //terrain_cb_w_4lyr_cm_pxm_tnt (terrain_cb_w_4lyr_cm_pxm_tnt.sps) vt: PNCTTTX_3
|
||||
case 4186046662: //terrain_cb_w_4lyr_cm_pxm (terrain_cb_w_4lyr_cm_pxm.sps) vt: PNCTTTX_3
|
||||
vt = VertexType.PNCTTTX; //cs6_08_struct08
|
||||
break;
|
||||
case 3051127652: //terrain_cb_w_4lyr (terrain_cb_w_4lyr.sps) vt: PNCCTX
|
||||
case 646532852: //terrain_cb_w_4lyr_spec (terrain_cb_w_4lyr_spec.sps) vt: PNCCTX
|
||||
vt = VertexType.PNCCTX; //hw1_07_grnd_c..
|
||||
break;
|
||||
case 2535953532: //terrain_cb_w_4lyr_2tex_blend_lod (terrain_cb_w_4lyr_2tex_blend_lod.sps) vt: PNCCTT
|
||||
vt = VertexType.PNCCTT; //cs1_12_riverbed1_lod..
|
||||
break;
|
||||
case 137526804: //terrain_cb_w_4lyr_lod (terrain_cb_w_4lyr_lod.sps) vt: PNCCT
|
||||
vt = VertexType.PNCCT; //brdgeplatform_01_lod..
|
||||
break;
|
||||
case 2316006813: //terrain_cb_w_4lyr_2tex_blend (terrain_cb_w_4lyr_2tex_blend.sps) vt: PNCCTTX
|
||||
case 3112820305: //terrain_cb_w_4lyr_2tex (terrain_cb_w_4lyr_2tex.sps) vt: PNCCTTX
|
||||
case 2601000386: //terrain_cb_w_4lyr_spec_pxm (terrain_cb_w_4lyr_spec_pxm.sps) vt: PNCCTTX_2
|
||||
case 4105814572: //terrain_cb_w_4lyr_pxm (terrain_cb_w_4lyr_pxm.sps) vt: PNCCTTX_2
|
||||
case 3400824277: //terrain_cb_w_4lyr_pxm_spm (terrain_cb_w_4lyr_pxm_spm.sps) vt: PNCCTTX_2
|
||||
vt = VertexType.PNCCTTX; //ch2_04_land02b, ch2_06_terrain01a .. vb_35_beacha
|
||||
break;
|
||||
case 653544224: //terrain_cb_w_4lyr_2tex_blend_pxm_spm (terrain_cb_w_4lyr_2tex_blend_pxm_spm.sps) vt: PNCCTTTX
|
||||
case 2486206885: //terrain_cb_w_4lyr_2tex_blend_pxm (terrain_cb_w_4lyr_2tex_blend_pxm.sps) vt: PNCCTTTX
|
||||
case 1888432890: //terrain_cb_w_4lyr_2tex_pxm (terrain_cb_w_4lyr_2tex_pxm.sps) vt: PNCCTTTX
|
||||
vt = VertexType.PNCCTTTX; //ch1_04b_vineland01..
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetVertexShader(context, vt);
|
||||
}
|
||||
private void SetVertexShader(DeviceContext context, VertexType type)
|
||||
{
|
||||
VertexShader vs = pnccttxvs;
|
||||
switch (type)
|
||||
{
|
||||
case VertexType.PNCCT: vs = pncctvs; break;
|
||||
case VertexType.PNCCTT: vs = pnccttvs; break;
|
||||
case VertexType.PNCTTX: vs = pncttxvs; break;
|
||||
case VertexType.PNCTTTX_3: vs = pnctttxvs; break;
|
||||
case VertexType.PNCCTX: vs = pncctxvs; break;
|
||||
case VertexType.PNCCTTX: vs = pnccttxvs; break;
|
||||
case VertexType.PNCCTTX_2: vs = pnccttxvs; break;
|
||||
case VertexType.PNCCTTTX: vs = pncctttxvs; break;
|
||||
}
|
||||
context.VertexShader.Set(vs);
|
||||
}
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.PixelShader.Set(terrainps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
InputLayout l;
|
||||
if (layouts.TryGetValue(type, out l))
|
||||
{
|
||||
SetVertexShader(context, type); //need to use the correct VS.
|
||||
context.InputAssembler.InputLayout = l;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
uint rendermode = 0;
|
||||
uint rendermodeind = 1;
|
||||
|
||||
switch (RenderMode)
|
||||
{
|
||||
case WorldRenderMode.VertexNormals:
|
||||
rendermode = 1;
|
||||
break;
|
||||
case WorldRenderMode.VertexTangents:
|
||||
rendermode = 2;
|
||||
break;
|
||||
case WorldRenderMode.VertexColour:
|
||||
rendermode = 3;
|
||||
rendermodeind = (uint)RenderVertexColourIndex;
|
||||
break;
|
||||
case WorldRenderMode.TextureCoord:
|
||||
rendermode = 4;
|
||||
rendermodeind = (uint)RenderTextureCoordIndex;
|
||||
break;
|
||||
case WorldRenderMode.SingleTexture:
|
||||
switch (RenderTextureSampler)
|
||||
{
|
||||
case MetaName.DiffuseSampler:
|
||||
rendermode = 5;
|
||||
break;
|
||||
case MetaName.BumpSampler:
|
||||
rendermode = 6;
|
||||
break;
|
||||
case MetaName.SpecSampler:
|
||||
rendermode = 7;
|
||||
break;
|
||||
default:
|
||||
rendermode = 8;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 0);
|
||||
|
||||
|
||||
PSSceneVars.Vars.GlobalLights = lights.Params;
|
||||
PSSceneVars.Vars.EnableShadows = (shadowmap != null) ? 1u : 0u;
|
||||
PSSceneVars.Vars.RenderMode = rendermode;
|
||||
PSSceneVars.Vars.RenderModeIndex = rendermodeind;
|
||||
PSSceneVars.Vars.RenderSamplerCoord = (uint)RenderTextureSamplerCoord;
|
||||
PSSceneVars.Update(context);
|
||||
PSSceneVars.SetPSCBuffer(context, 0);
|
||||
|
||||
if (shadowmap != null)
|
||||
{
|
||||
shadowmap.SetFinalRenderResources(context);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = rend.Orientation;
|
||||
VSEntityVars.Vars.Scale = rend.Scale;
|
||||
VSEntityVars.Vars.HasSkeleton = rend.Renderable.HasSkeleton ? 1u : 0;
|
||||
VSEntityVars.Vars.HasTransforms = rend.Renderable.HasTransforms ? 1u : 0;
|
||||
VSEntityVars.Vars.TintPaletteIndex = rend.TintPaletteIndex;
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 2);
|
||||
}
|
||||
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
if (!model.UseTransform) return;
|
||||
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
|
||||
VSModelVars.Update(context);
|
||||
VSModelVars.SetVSCBuffer(context, 3);
|
||||
}
|
||||
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
RenderableTexture texture0 = null;
|
||||
RenderableTexture texture1 = null;
|
||||
RenderableTexture texture2 = null;
|
||||
RenderableTexture texture3 = null;
|
||||
RenderableTexture texture4 = null;
|
||||
RenderableTexture texturemask = null;
|
||||
RenderableTexture tintpal = null;
|
||||
RenderableTexture normals0 = null;
|
||||
RenderableTexture normals1 = null;
|
||||
RenderableTexture normals2 = null;
|
||||
RenderableTexture normals3 = null;
|
||||
RenderableTexture normals4 = null;
|
||||
float tntpalind = 0.0f;
|
||||
bool usevc = true;
|
||||
|
||||
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
|
||||
{
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
switch (ihash)
|
||||
{
|
||||
case MetaName.DiffuseSampler:
|
||||
texture0 = itex;
|
||||
break;
|
||||
case MetaName.TextureSampler_layer0:
|
||||
texture1 = itex;
|
||||
break;
|
||||
case MetaName.TextureSampler_layer1:
|
||||
texture2 = itex;
|
||||
break;
|
||||
case MetaName.TextureSampler_layer2:
|
||||
texture3 = itex;
|
||||
break;
|
||||
case MetaName.TextureSampler_layer3:
|
||||
texture4 = itex;
|
||||
break;
|
||||
case MetaName.BumpSampler:
|
||||
normals0 = itex;
|
||||
break;
|
||||
case MetaName.BumpSampler_layer0:
|
||||
normals1 = itex;
|
||||
break;
|
||||
case MetaName.BumpSampler_layer1:
|
||||
normals2 = itex;
|
||||
break;
|
||||
case MetaName.BumpSampler_layer2:
|
||||
normals3 = itex;
|
||||
break;
|
||||
case MetaName.BumpSampler_layer3:
|
||||
normals4 = itex;
|
||||
break;
|
||||
case MetaName.lookupSampler:
|
||||
texturemask = itex;
|
||||
break;
|
||||
case MetaName.TintPaletteSampler:
|
||||
tintpal = itex;
|
||||
if (tintpal.Key != null)
|
||||
{
|
||||
//this is slightly dodgy but vsentvarsdata should have the correct value in it...
|
||||
tntpalind = (VSEntityVars.Vars.TintPaletteIndex + 0.5f) / tintpal.Key.Height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if ((geom.DiffuseSampler >= 0) && (geom.DiffuseSampler < geom.Textures.Length))
|
||||
//{
|
||||
// texture0 = geom.Textures[geom.DiffuseSampler];
|
||||
//}
|
||||
//if ((geom.TextureSampler_layer0 >= 0) && (geom.TextureSampler_layer0 < geom.Textures.Length))
|
||||
//{
|
||||
// texture1 = geom.Textures[geom.TextureSampler_layer0];
|
||||
//}
|
||||
//if ((geom.TextureSampler_layer1 >= 0) && (geom.TextureSampler_layer1 < geom.Textures.Length))
|
||||
//{
|
||||
// texture2 = geom.Textures[geom.TextureSampler_layer1];
|
||||
//}
|
||||
//if ((geom.TextureSampler_layer2 >= 0) && (geom.TextureSampler_layer2 < geom.Textures.Length))
|
||||
//{
|
||||
// texture3 = geom.Textures[geom.TextureSampler_layer2];
|
||||
//}
|
||||
//if ((geom.TextureSampler_layer3 >= 0) && (geom.TextureSampler_layer3 < geom.Textures.Length))
|
||||
//{
|
||||
// texture4 = geom.Textures[geom.TextureSampler_layer3];
|
||||
//}
|
||||
//if ((geom.BumpSampler >= 0) && (geom.BumpSampler < geom.Textures.Length))
|
||||
//{
|
||||
// normals0 = geom.Textures[geom.BumpSampler];
|
||||
//}
|
||||
//if ((geom.BumpSampler_layer0 >= 0) && (geom.BumpSampler_layer0 < geom.Textures.Length))
|
||||
//{
|
||||
// normals1 = geom.Textures[geom.BumpSampler_layer0];
|
||||
//}
|
||||
//if ((geom.BumpSampler_layer1 >= 0) && (geom.BumpSampler_layer1 < geom.Textures.Length))
|
||||
//{
|
||||
// normals2 = geom.Textures[geom.BumpSampler_layer1];
|
||||
//}
|
||||
//if ((geom.BumpSampler_layer2 >= 0) && (geom.BumpSampler_layer2 < geom.Textures.Length))
|
||||
//{
|
||||
// normals3 = geom.Textures[geom.BumpSampler_layer2];
|
||||
//}
|
||||
//if ((geom.BumpSampler_layer3 >= 0) && (geom.BumpSampler_layer3 < geom.Textures.Length))
|
||||
//{
|
||||
// normals4 = geom.Textures[geom.BumpSampler_layer3];
|
||||
//}
|
||||
//if ((geom.lookupSampler >= 0) && (geom.lookupSampler < geom.Textures.Length))
|
||||
//{
|
||||
// texturemask = geom.Textures[geom.lookupSampler];
|
||||
//}
|
||||
//if ((geom.TintPaletteSampler >= 0) && (geom.TintPaletteSampler < geom.Textures.Length))
|
||||
//{
|
||||
// tintpal = geom.Textures[geom.TintPaletteSampler];
|
||||
// if (tintpal.Texture != null)
|
||||
// {
|
||||
// //this is slightly dodgy but vsentvarsdata should have the correct value in it...
|
||||
// tntpalind = (vsentvarsdata.TintPaletteIndex + 0.5f) / tintpal.Texture.Height;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (RenderMode == WorldRenderMode.SingleTexture)
|
||||
{
|
||||
usevc = false;
|
||||
switch (RenderTextureSampler)
|
||||
{
|
||||
case MetaName.DiffuseSampler:
|
||||
case MetaName.BumpSampler:
|
||||
case MetaName.SpecSampler:
|
||||
break;
|
||||
default:
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
if (ihash == RenderTextureSampler)
|
||||
{
|
||||
texture0 = itex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//int directtexind = geom.GetTextureSamplerIndex(RenderTextureSampler);
|
||||
//if ((directtexind >= 0) && (directtexind < geom.Textures.Length))
|
||||
//{
|
||||
// texture0 = geom.Textures[directtexind];
|
||||
//}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool usediff0 = ((texture0 != null) && (texture0.ShaderResourceView != null));
|
||||
bool usediff1 = ((texture1 != null) && (texture1.ShaderResourceView != null));
|
||||
bool usediff2 = ((texture2 != null) && (texture2.ShaderResourceView != null));
|
||||
bool usediff3 = ((texture3 != null) && (texture3.ShaderResourceView != null));
|
||||
bool usediff4 = ((texture4 != null) && (texture4.ShaderResourceView != null));
|
||||
bool usemask = ((texturemask != null) && (texturemask.ShaderResourceView != null));
|
||||
bool usetint = ((tintpal != null) && (tintpal.ShaderResourceView != null));
|
||||
bool usenm = (((normals0 != null) && (normals0.ShaderResourceView != null)) || ((normals1 != null) && (normals1.ShaderResourceView != null)));
|
||||
|
||||
|
||||
float bumpiness = 1.0f;
|
||||
if (usenm)
|
||||
{
|
||||
bumpiness = geom.bumpiness;
|
||||
}
|
||||
|
||||
|
||||
PSGeomVars.Vars.EnableTexture0 = usediff0 ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableTexture1 = usediff1 ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableTexture2 = usediff2 ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableTexture3 = usediff3 ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableTexture4 = usediff4 ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableTextureMask = usemask ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableNormalMap = usenm ? 1u : 0u;
|
||||
PSGeomVars.Vars.ShaderName = geom.DrawableGeom.Shader.Name.Hash;
|
||||
PSGeomVars.Vars.EnableTint = usetint ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableVertexColour = usevc ? 1u : 0u;
|
||||
PSGeomVars.Vars.bumpiness = bumpiness;//
|
||||
PSGeomVars.Update(context);
|
||||
PSGeomVars.SetPSCBuffer(context, 2);
|
||||
|
||||
VSGeomVars.Vars.EnableTint = usetint ? 1u : 0u;
|
||||
VSGeomVars.Vars.TintYVal = tntpalind;
|
||||
VSGeomVars.Update(context);
|
||||
VSGeomVars.SetVSCBuffer(context, 4);
|
||||
|
||||
|
||||
context.VertexShader.SetSampler(0, texsamplertnt);
|
||||
context.PixelShader.SetSampler(0, AnisotropicFilter ? texsampleranis : texsampler);
|
||||
|
||||
if (usediff0) texture0.SetPSResource(context, 0);
|
||||
if (usediff1) texture1.SetPSResource(context, 2);
|
||||
if (usediff2) texture2.SetPSResource(context, 3);
|
||||
if (usediff3) texture3.SetPSResource(context, 4);
|
||||
if (usediff4) texture4.SetPSResource(context, 5);
|
||||
if (usemask) texturemask.SetPSResource(context, 6);
|
||||
if (usetint) tintpal.SetVSResource(context, 0);
|
||||
if (normals0 != null) normals0.SetPSResource(context, 7);
|
||||
if (normals1 != null) normals1.SetPSResource(context, 8);
|
||||
if (normals2 != null) normals2.SetPSResource(context, 9);
|
||||
if (normals3 != null) normals3.SetPSResource(context, 10);
|
||||
if (normals4 != null) normals4.SetPSResource(context, 11);
|
||||
|
||||
}
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.PixelShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetConstantBuffer(1, null); //shadowmap
|
||||
context.PixelShader.SetConstantBuffer(1, null); //shadowmap
|
||||
context.PixelShader.SetShaderResource(1, null);//shadowmap
|
||||
context.PixelShader.SetSampler(1, null); //shadowmap
|
||||
context.VertexShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(3, null);
|
||||
context.PixelShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(4, null);
|
||||
context.VertexShader.SetSampler(0, null);
|
||||
context.PixelShader.SetSampler(0, null);
|
||||
context.VertexShader.SetShaderResource(0, null);
|
||||
context.PixelShader.SetShaderResource(0, null);
|
||||
context.PixelShader.SetShaderResource(2, null);
|
||||
context.PixelShader.SetShaderResource(3, null);
|
||||
context.PixelShader.SetShaderResource(4, null);
|
||||
context.PixelShader.SetShaderResource(5, null);
|
||||
context.PixelShader.SetShaderResource(6, null);
|
||||
context.PixelShader.SetShaderResource(7, null);
|
||||
context.PixelShader.SetShaderResource(8, null);
|
||||
context.PixelShader.SetShaderResource(9, null);
|
||||
context.PixelShader.SetShaderResource(10, null);
|
||||
context.PixelShader.SetShaderResource(11, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
|
||||
if (texsampler != null)
|
||||
{
|
||||
texsampler.Dispose();
|
||||
texsampler = null;
|
||||
}
|
||||
if (texsampleranis != null)
|
||||
{
|
||||
texsampleranis.Dispose();
|
||||
texsampleranis = null;
|
||||
}
|
||||
if (texsamplertnt != null)
|
||||
{
|
||||
texsamplertnt.Dispose();
|
||||
texsamplertnt = null;
|
||||
}
|
||||
|
||||
foreach (InputLayout layout in layouts.Values)
|
||||
{
|
||||
layout.Dispose();
|
||||
}
|
||||
layouts.Clear();
|
||||
|
||||
VSSceneVars.Dispose();
|
||||
VSEntityVars.Dispose();
|
||||
VSModelVars.Dispose();
|
||||
VSGeomVars.Dispose();
|
||||
PSSceneVars.Dispose();
|
||||
PSGeomVars.Dispose();
|
||||
|
||||
terrainps.Dispose();
|
||||
pncctvs.Dispose();
|
||||
pnccttvs.Dispose();
|
||||
pnccttxvs.Dispose();
|
||||
pncctttxvs.Dispose();
|
||||
pncctxvs.Dispose();
|
||||
pnctttxvs.Dispose();
|
||||
pncttxvs.Dispose();
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.DXGI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using SharpDX;
|
||||
using CodeWalker.GameFiles;
|
||||
using CodeWalker.World;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
|
||||
public struct TreesLodShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
}
|
||||
public struct TreesLodShaderVSEntityVars
|
||||
{
|
||||
public Vector4 CamRel;
|
||||
public Quaternion Orientation;
|
||||
public uint HasSkeleton;
|
||||
public uint HasTransforms;
|
||||
public uint Pad0;
|
||||
public uint Pad1;
|
||||
public Vector3 Scale;
|
||||
public uint Pad2;
|
||||
}
|
||||
public struct TreesLodShaderVSModelVars
|
||||
{
|
||||
public Matrix Transform;
|
||||
}
|
||||
public struct TreesLodShaderVSGeometryVars
|
||||
{
|
||||
public Vector4 AlphaTest;
|
||||
public Vector4 AlphaScale;
|
||||
public Vector4 UseTreeNormals;
|
||||
public Vector4 treeLod2Normal;
|
||||
public Vector4 treeLod2Params;
|
||||
}
|
||||
public struct TreesLodShaderPSSceneVars
|
||||
{
|
||||
public ShaderGlobalLightParams GlobalLights;
|
||||
}
|
||||
public struct TreesLodShaderPSEntityVars
|
||||
{
|
||||
public uint EnableTexture;
|
||||
public uint Pad1;
|
||||
public uint Pad2;
|
||||
public uint Pad3;
|
||||
}
|
||||
|
||||
public class TreesLodShader : Shader, IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader basicvs;
|
||||
PixelShader basicps;
|
||||
GpuVarsBuffer<TreesLodShaderVSSceneVars> VSSceneVars;
|
||||
GpuVarsBuffer<TreesLodShaderVSEntityVars> VSEntityVars;
|
||||
GpuVarsBuffer<TreesLodShaderVSModelVars> VSModelVars;
|
||||
GpuVarsBuffer<TreesLodShaderVSGeometryVars> VSGeomVars;
|
||||
GpuVarsBuffer<TreesLodShaderPSSceneVars> PSSceneVars;
|
||||
GpuVarsBuffer<TreesLodShaderPSEntityVars> PSEntityVars;
|
||||
SamplerState texsampler;
|
||||
|
||||
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
|
||||
|
||||
|
||||
public TreesLodShader(Device device)
|
||||
{
|
||||
byte[] vsbytes = File.ReadAllBytes("Shaders\\TreesLodVS.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\TreesLodPS.cso");
|
||||
|
||||
basicvs = new VertexShader(device, vsbytes);
|
||||
basicps = new PixelShader(device, psbytes);
|
||||
|
||||
VSSceneVars = new GpuVarsBuffer<TreesLodShaderVSSceneVars>(device);
|
||||
VSEntityVars = new GpuVarsBuffer<TreesLodShaderVSEntityVars>(device);
|
||||
VSModelVars = new GpuVarsBuffer<TreesLodShaderVSModelVars>(device);
|
||||
VSGeomVars = new GpuVarsBuffer<TreesLodShaderVSGeometryVars>(device);
|
||||
PSSceneVars = new GpuVarsBuffer<TreesLodShaderPSSceneVars>(device);
|
||||
PSEntityVars = new GpuVarsBuffer<TreesLodShaderPSEntityVars>(device);
|
||||
|
||||
//layouts.Add(VertexType.PNCCT, new InputLayout(device, vsbytes, VertexTypePNCCT.GetLayout()));
|
||||
layouts.Add(VertexType.PNCCTTTT, new InputLayout(device, vsbytes, VertexTypePNCCTTTT.GetLayout()));
|
||||
|
||||
|
||||
|
||||
texsampler = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipLinear,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.Set(basicvs);
|
||||
context.PixelShader.Set(basicps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
InputLayout l;
|
||||
if (layouts.TryGetValue(type, out l))
|
||||
{
|
||||
context.InputAssembler.InputLayout = l;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 0);
|
||||
|
||||
PSSceneVars.Vars.GlobalLights = lights.Params;
|
||||
PSSceneVars.Update(context);
|
||||
PSSceneVars.SetPSCBuffer(context, 0);
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = rend.Orientation;
|
||||
VSEntityVars.Vars.Scale = rend.Scale;
|
||||
VSEntityVars.Vars.HasSkeleton = rend.Renderable.HasSkeleton ? 1u : 0;
|
||||
VSEntityVars.Vars.HasTransforms = rend.Renderable.HasTransforms ? 1u : 0;
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 1);
|
||||
}
|
||||
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
if (!model.UseTransform) return;
|
||||
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
|
||||
VSModelVars.Update(context);
|
||||
VSModelVars.SetVSCBuffer(context, 2);
|
||||
}
|
||||
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
RenderableTexture texture = null; // ((geom.Textures != null) && (geom.Textures.Length > 0)) ? geom.Textures[0] : null;
|
||||
|
||||
//trees_lod2
|
||||
//PNCCTTTT: texcoord2 seems to be 0-1 for the billboard, vertex pos is billboard root.
|
||||
//param for billboard dir... (treeLod2Normal)
|
||||
|
||||
//trees_lod
|
||||
//PNCCT:
|
||||
|
||||
|
||||
if (geom.VertexType != VertexType.PNCCTTTT)
|
||||
{ }
|
||||
|
||||
var shader = geom.DrawableGeom.Shader;
|
||||
if (shader.Name.Hash == 1874959840)
|
||||
{
|
||||
|
||||
int nparams = 0;
|
||||
MetaName[] hashes = null;
|
||||
ShaderParameter[] sparams = null;
|
||||
|
||||
if (shader.ParametersList != null)
|
||||
{
|
||||
nparams = shader.ParametersList.Hashes.Length;
|
||||
hashes = shader.ParametersList.Hashes;
|
||||
sparams = shader.ParametersList.Parameters;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nparams; i++)
|
||||
{
|
||||
var h = shader.ParametersList.Hashes[i];
|
||||
switch (h)
|
||||
{
|
||||
case MetaName.AlphaTest: VSGeomVars.Vars.AlphaTest = (Vector4)sparams[i].Data; break;
|
||||
case MetaName.AlphaScale: VSGeomVars.Vars.AlphaScale = (Vector4)sparams[i].Data; break;
|
||||
case MetaName.UseTreeNormals: VSGeomVars.Vars.UseTreeNormals = (Vector4)sparams[i].Data; break;
|
||||
case MetaName.treeLod2Normal: VSGeomVars.Vars.treeLod2Normal = (Vector4)sparams[i].Data; break;
|
||||
case MetaName.treeLod2Params: VSGeomVars.Vars.treeLod2Params = (Vector4)sparams[i].Data; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
VSGeomVars.Vars.AlphaTest = Vector4.Zero;
|
||||
VSGeomVars.Vars.AlphaScale = Vector4.Zero;
|
||||
VSGeomVars.Vars.UseTreeNormals = Vector4.Zero;
|
||||
VSGeomVars.Vars.treeLod2Normal = Vector4.Zero;
|
||||
VSGeomVars.Vars.treeLod2Params = Vector4.Zero;
|
||||
}
|
||||
|
||||
VSGeomVars.Update(context);
|
||||
VSGeomVars.SetVSCBuffer(context, 3);
|
||||
|
||||
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
|
||||
{
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
switch (ihash)
|
||||
{
|
||||
case MetaName.DiffuseSampler:
|
||||
texture = itex;
|
||||
break;
|
||||
}
|
||||
if (texture != null) break;
|
||||
}
|
||||
|
||||
////try get default diffuse texture
|
||||
//if ((geom.DiffuseSampler >= 0) && (geom.DiffuseSampler < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[geom.DiffuseSampler];
|
||||
//}
|
||||
//if ((texture == null) && (geom.TextureSampler_layer0 >= 0) && (geom.TextureSampler_layer0 < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[geom.TextureSampler_layer0];
|
||||
//}
|
||||
//if ((texture == null) && (geom.TextureSampler_layer1 >= 0) && (geom.TextureSampler_layer1 < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[geom.TextureSampler_layer1];
|
||||
//}
|
||||
//if ((texture == null) && (geom.TextureSampler_layer2 >= 0) && (geom.TextureSampler_layer2 < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[geom.TextureSampler_layer2];
|
||||
//}
|
||||
//if ((texture == null) && (geom.TextureSampler_layer3 >= 0) && (geom.TextureSampler_layer3 < geom.Textures.Length))
|
||||
//{
|
||||
// texture = geom.Textures[geom.TextureSampler_layer3];
|
||||
//}
|
||||
|
||||
//fallback try get first texture...
|
||||
int index = 0;
|
||||
while (((texture == null) || (texture.Texture2D == null)) && (index < geom.RenderableTextures.Length))
|
||||
{
|
||||
texture = geom.RenderableTextures[index];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool usediff = ((texture != null) && (texture.Texture2D != null) && (texture.ShaderResourceView != null));
|
||||
PSEntityVars.Vars.EnableTexture = usediff ? 1u : 0u;
|
||||
PSEntityVars.Update(context);
|
||||
PSEntityVars.SetPSCBuffer(context, 1);
|
||||
|
||||
if (usediff)
|
||||
{
|
||||
context.PixelShader.SetSampler(0, texsampler);
|
||||
//context.PixelShader.SetShaderResource(0, difftex.ShaderResourceView);
|
||||
texture.SetPSResource(context, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.PixelShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetConstantBuffer(1, null);
|
||||
context.VertexShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(3, null);
|
||||
context.PixelShader.SetConstantBuffer(1, null);
|
||||
context.PixelShader.SetSampler(0, null);
|
||||
context.PixelShader.SetShaderResource(0, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
|
||||
if (texsampler != null)
|
||||
{
|
||||
texsampler.Dispose();
|
||||
texsampler = null;
|
||||
}
|
||||
|
||||
foreach (InputLayout layout in layouts.Values)
|
||||
{
|
||||
layout.Dispose();
|
||||
}
|
||||
layouts.Clear();
|
||||
|
||||
VSSceneVars.Dispose();
|
||||
VSEntityVars.Dispose();
|
||||
VSModelVars.Dispose();
|
||||
VSGeomVars.Dispose();
|
||||
PSSceneVars.Dispose();
|
||||
PSEntityVars.Dispose();
|
||||
|
||||
basicps.Dispose();
|
||||
basicvs.Dispose();
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,564 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using CodeWalker.GameFiles;
|
||||
using CodeWalker.World;
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX;
|
||||
using System.IO;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public struct WaterShaderVSSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public Vector4 WaterVector;
|
||||
public float ScaledTime;
|
||||
public float ScnPad0;
|
||||
public float ScnPad1;
|
||||
public float ScnPad2;
|
||||
}
|
||||
public struct WaterShaderVSEntityVars
|
||||
{
|
||||
public Vector4 CamRel;
|
||||
public Quaternion Orientation;
|
||||
public Vector3 Scale;
|
||||
public uint EntPad0;
|
||||
}
|
||||
public struct WaterShaderVSGeomVars
|
||||
{
|
||||
public Vector4 WaterParams;
|
||||
public uint EnableFlow;
|
||||
public uint ShaderMode;
|
||||
public uint GeoPad1;
|
||||
public uint GeoPad2;
|
||||
public float RippleSpeed;
|
||||
public float GeoPad3;
|
||||
public float GeoPad4;
|
||||
public float GeoPad5;
|
||||
}
|
||||
public struct WaterShaderPSSceneVars
|
||||
{
|
||||
public ShaderGlobalLightParams GlobalLights;
|
||||
public uint EnableShadows;
|
||||
public uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct
|
||||
public uint RenderModeIndex; //colour/texcoord index
|
||||
public uint RenderSamplerCoord; //which texcoord to use in single texture mode
|
||||
public uint EnableWaterbumps;//if the waterbump textures are ready..
|
||||
public uint EnableFogtex; //if the fog texture is ready
|
||||
public uint ScnPad1;
|
||||
public uint ScnPad2;
|
||||
public Vector4 gFlowParams;
|
||||
public Vector4 CameraPos;
|
||||
public Vector4 WaterFogParams; //xy = base location, zw = inverse size
|
||||
}
|
||||
public struct WaterShaderPSGeomVars
|
||||
{
|
||||
public uint EnableTexture;
|
||||
public uint EnableBumpMap;
|
||||
public uint EnableFoamMap;
|
||||
public uint ShaderMode;
|
||||
public float SpecularIntensity;
|
||||
public float SpecularFalloff;
|
||||
public float GeoPad1;
|
||||
public float GeoPad2;
|
||||
public float WaveOffset; //for terrainfoam
|
||||
public float WaterHeight; //for terrainfoam
|
||||
public float WaveMovement; //for terrainfoam
|
||||
public float HeightOpacity; //for terrainfoam
|
||||
public float RippleSpeed;
|
||||
public float RippleScale;
|
||||
public float RippleBumpiness;
|
||||
public float GeoPad3;
|
||||
}
|
||||
|
||||
|
||||
public class WaterShader : Shader
|
||||
{
|
||||
bool disposed = false;
|
||||
|
||||
VertexShader vspt;
|
||||
VertexShader vspct;
|
||||
VertexShader vspnct;
|
||||
VertexShader vspnctx;
|
||||
PixelShader ps;
|
||||
|
||||
GpuVarsBuffer<WaterShaderVSSceneVars> VSSceneVars;
|
||||
GpuVarsBuffer<WaterShaderVSEntityVars> VSEntityVars;
|
||||
GpuVarsBuffer<WaterShaderVSGeomVars> VSGeomVars;
|
||||
GpuVarsBuffer<WaterShaderPSSceneVars> PSSceneVars;
|
||||
GpuVarsBuffer<WaterShaderPSGeomVars> PSGeomVars;
|
||||
|
||||
SamplerState texsampler;
|
||||
SamplerState texsampleranis;
|
||||
SamplerState texsamplerflow;
|
||||
|
||||
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
|
||||
|
||||
|
||||
public bool AnisotropicFilter = false;
|
||||
public WorldRenderMode RenderMode = WorldRenderMode.Default;
|
||||
public int RenderVertexColourIndex = 1;
|
||||
public int RenderTextureCoordIndex = 1;
|
||||
public int RenderTextureSamplerCoord = 1;
|
||||
public MetaName RenderTextureSampler = MetaName.DiffuseSampler;
|
||||
public double CurrentRealTime = 0;
|
||||
public float CurrentElapsedTime = 0;
|
||||
public bool SpecularEnable = true;
|
||||
|
||||
|
||||
public RenderableTexture waterbump { get; set; }
|
||||
public RenderableTexture waterbump2 { get; set; }
|
||||
public RenderableTexture waterfog { get; set; }
|
||||
|
||||
|
||||
//check dt1_21_reflproxy and dt1_05_reflproxy
|
||||
|
||||
|
||||
public WaterShader(Device device)
|
||||
{
|
||||
byte[] vsptbytes = File.ReadAllBytes("Shaders\\WaterVS_PT.cso");
|
||||
byte[] vspctbytes = File.ReadAllBytes("Shaders\\WaterVS_PCT.cso");
|
||||
byte[] vspnctbytes = File.ReadAllBytes("Shaders\\WaterVS_PNCT.cso");
|
||||
byte[] vspnctxbytes = File.ReadAllBytes("Shaders\\WaterVS_PNCTX.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\WaterPS.cso");
|
||||
|
||||
|
||||
vspt = new VertexShader(device, vsptbytes);
|
||||
vspct = new VertexShader(device, vspctbytes);
|
||||
vspnct = new VertexShader(device, vspnctbytes);
|
||||
vspnctx = new VertexShader(device, vspnctxbytes);
|
||||
ps = new PixelShader(device, psbytes);
|
||||
|
||||
VSSceneVars = new GpuVarsBuffer<WaterShaderVSSceneVars>(device);
|
||||
VSEntityVars = new GpuVarsBuffer<WaterShaderVSEntityVars>(device);
|
||||
VSGeomVars = new GpuVarsBuffer<WaterShaderVSGeomVars>(device);
|
||||
PSSceneVars = new GpuVarsBuffer<WaterShaderPSSceneVars>(device);
|
||||
PSGeomVars = new GpuVarsBuffer<WaterShaderPSGeomVars>(device);
|
||||
|
||||
layouts.Add(VertexType.PT, new InputLayout(device, vsptbytes, VertexTypePT.GetLayout()));
|
||||
layouts.Add(VertexType.PCT, new InputLayout(device, vspctbytes, VertexTypePCT.GetLayout()));
|
||||
layouts.Add(VertexType.Default, new InputLayout(device, vspnctbytes, VertexTypeDefault.GetLayout()));
|
||||
layouts.Add(VertexType.DefaultEx, new InputLayout(device, vspnctxbytes, VertexTypeDefaultEx.GetLayout()));
|
||||
|
||||
texsampler = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipLinear,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
texsampleranis = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Wrap,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.Black,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.Anisotropic,
|
||||
MaximumAnisotropy = 8,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
texsamplerflow = new SamplerState(device, new SamplerStateDescription()
|
||||
{
|
||||
AddressU = TextureAddressMode.Clamp,
|
||||
AddressV = TextureAddressMode.Wrap,
|
||||
AddressW = TextureAddressMode.Wrap,
|
||||
BorderColor = Color.White,
|
||||
ComparisonFunction = Comparison.Always,
|
||||
Filter = Filter.MinMagMipPoint,
|
||||
MaximumAnisotropy = 1,
|
||||
MaximumLod = float.MaxValue,
|
||||
MinimumLod = 0,
|
||||
MipLodBias = 0,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void SetVertexShader(DeviceContext context, VertexType type)
|
||||
{
|
||||
VertexShader vs = vspnct;
|
||||
switch (type)
|
||||
{
|
||||
case VertexType.PT:
|
||||
vs = vspt;
|
||||
break;
|
||||
case VertexType.PCT:
|
||||
vs = vspct;
|
||||
break;
|
||||
case VertexType.Default:
|
||||
vs = vspnct;
|
||||
break;
|
||||
case VertexType.DefaultEx:
|
||||
vs = vspnctx;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
context.VertexShader.Set(vs);
|
||||
}
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.PixelShader.Set(ps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
InputLayout l;
|
||||
if (layouts.TryGetValue(type, out l))
|
||||
{
|
||||
SetVertexShader(context, type);
|
||||
context.InputAssembler.InputLayout = l;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
uint rendermode = 0;
|
||||
uint rendermodeind = 1;
|
||||
|
||||
SpecularEnable = lights.SpecularEnabled;
|
||||
|
||||
switch (RenderMode)
|
||||
{
|
||||
case WorldRenderMode.VertexNormals:
|
||||
rendermode = 1;
|
||||
break;
|
||||
case WorldRenderMode.VertexTangents:
|
||||
rendermode = 2;
|
||||
break;
|
||||
case WorldRenderMode.VertexColour:
|
||||
rendermode = 3;
|
||||
rendermodeind = (uint)RenderVertexColourIndex;
|
||||
break;
|
||||
case WorldRenderMode.TextureCoord:
|
||||
rendermode = 4;
|
||||
rendermodeind = (uint)RenderTextureCoordIndex;
|
||||
break;
|
||||
case WorldRenderMode.SingleTexture:
|
||||
rendermode = 8;//direct mode
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
float phspd = 4.0f;
|
||||
float phspdi = 1.0f / phspd;
|
||||
float phspdh = phspd * 0.5f;
|
||||
float t = (float)(CurrentRealTime - (Math.Floor(CurrentRealTime * 0.001) * 1000.0))*1.0f;
|
||||
float ta = t * 2.0f;
|
||||
float tb = ta + (phspdh);
|
||||
float t1 = (ta * phspdi - (float)Math.Floor(ta * phspdi)) * phspd;
|
||||
float t2 = (tb * phspdi - (float)Math.Floor(tb * phspdi)) * phspd;
|
||||
float s1 = ((t1 < phspdh) ? t1 : phspd - t1) * phspdi * 1.0f;
|
||||
float s2 = ((t2 < phspdh) ? t2 : phspd - t2) * phspdi * 1.0f;
|
||||
//float s1 = ((float)Math.Cos(t1 * phspdi * Math.PI * 2) + 1.0f) * 0.5f;
|
||||
//float s2 = ((float)Math.Cos(t2 * phspdi * Math.PI * 2) + 1.0f) * 0.5f;
|
||||
|
||||
float gFlowX = t1*0.5f;
|
||||
float gFlowY = t2*0.5f;
|
||||
float gFlowZ = s1;
|
||||
float gFlowW = s2;
|
||||
|
||||
|
||||
Vector2 fogtexMin = new Vector2(-4000.0f, -4000.0f); //aka water quads min/max
|
||||
Vector2 fogtexMax = new Vector2(4500.0f, 8000.0f);
|
||||
Vector2 fogtexInv = 1.0f / (fogtexMax - fogtexMin);
|
||||
|
||||
|
||||
bool usewaterbumps = (waterbump != null) && (waterbump.ShaderResourceView != null) && (waterbump2 != null) && (waterbump2.ShaderResourceView != null);
|
||||
bool usefogtex = (waterfog != null) && (waterfog.ShaderResourceView != null);
|
||||
|
||||
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
VSSceneVars.Vars.WaterVector = Vector4.Zero;
|
||||
VSSceneVars.Vars.ScaledTime = t * 0.1f;
|
||||
VSSceneVars.Update(context);
|
||||
VSSceneVars.SetVSCBuffer(context, 0);
|
||||
|
||||
PSSceneVars.Vars.GlobalLights = lights.Params;
|
||||
PSSceneVars.Vars.EnableShadows = (shadowmap != null) ? 1u : 0u;
|
||||
PSSceneVars.Vars.RenderMode = rendermode;
|
||||
PSSceneVars.Vars.RenderModeIndex = rendermodeind;
|
||||
PSSceneVars.Vars.RenderSamplerCoord = (uint)RenderTextureSamplerCoord;
|
||||
PSSceneVars.Vars.EnableWaterbumps = usewaterbumps ? 1u : 0u;
|
||||
PSSceneVars.Vars.EnableFogtex = usefogtex ? 1u : 0u;
|
||||
PSSceneVars.Vars.gFlowParams = new Vector4(gFlowX, gFlowY, gFlowZ, gFlowW);
|
||||
PSSceneVars.Vars.CameraPos = new Vector4(camera.Position, 0.0f);
|
||||
PSSceneVars.Vars.WaterFogParams = new Vector4(fogtexMin, fogtexInv.X, fogtexInv.Y);
|
||||
PSSceneVars.Update(context);
|
||||
PSSceneVars.SetPSCBuffer(context, 0);
|
||||
|
||||
if (shadowmap != null)
|
||||
{
|
||||
shadowmap.SetFinalRenderResources(context);
|
||||
}
|
||||
if (usewaterbumps)
|
||||
{
|
||||
context.PixelShader.SetShaderResource(4, waterbump.ShaderResourceView);
|
||||
context.PixelShader.SetShaderResource(5, waterbump2.ShaderResourceView);
|
||||
}
|
||||
if (usefogtex)
|
||||
{
|
||||
context.PixelShader.SetShaderResource(6, waterfog.ShaderResourceView);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = rend.Orientation;
|
||||
VSEntityVars.Vars.Scale = rend.Scale;
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 2);
|
||||
}
|
||||
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
RenderableTexture texture = null;
|
||||
RenderableTexture bumptex = null;
|
||||
RenderableTexture flowtex = null;
|
||||
RenderableTexture foamtex = null;
|
||||
RenderableTexture fogtex = null;
|
||||
|
||||
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
|
||||
{
|
||||
if (RenderMode == WorldRenderMode.Default)
|
||||
{
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
if (itex == null) continue;
|
||||
switch (ihash)
|
||||
{
|
||||
case MetaName.DiffuseSampler:
|
||||
texture = itex;
|
||||
break;
|
||||
case MetaName.BumpSampler:
|
||||
bumptex = itex;
|
||||
break;
|
||||
case MetaName.FlowSampler:
|
||||
flowtex = itex;
|
||||
break;
|
||||
case MetaName.FoamSampler:
|
||||
foamtex = itex;
|
||||
break;
|
||||
case MetaName.FogSampler:
|
||||
fogtex = itex;
|
||||
break;
|
||||
default:
|
||||
if (texture == null) texture = itex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (RenderMode == WorldRenderMode.SingleTexture)
|
||||
{
|
||||
for (int i = 0; i < geom.RenderableTextures.Length; i++)
|
||||
{
|
||||
var itex = geom.RenderableTextures[i];
|
||||
var ihash = geom.TextureParamHashes[i];
|
||||
if (ihash == RenderTextureSampler)
|
||||
{
|
||||
texture = itex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool usediff = ((texture != null) && (texture.ShaderResourceView != null));
|
||||
bool usebump = ((bumptex != null) && (bumptex.ShaderResourceView != null));
|
||||
bool useflow = ((flowtex != null) && (flowtex.ShaderResourceView != null));
|
||||
bool usefoam = ((foamtex != null) && (foamtex.ShaderResourceView != null));
|
||||
bool usefog = ((fogtex != null) && (fogtex.ShaderResourceView != null));
|
||||
|
||||
uint shaderMode = 0;
|
||||
var shaderFile = geom.DrawableGeom.Shader.FileName;
|
||||
switch (shaderFile.Hash)
|
||||
{
|
||||
case 1529202445://{water_river.sps}
|
||||
case 4064804434://{water_riverlod.sps}
|
||||
case 2871265627://{water_riverocean.sps}
|
||||
case 1507348828://{water_rivershallow.sps}
|
||||
case 3945561843://{water_fountain.sps}
|
||||
case 4234404348://{water_shallow.sps}
|
||||
case 1077877097://{water_poolenv.sps}
|
||||
break;
|
||||
case 1471966282://{water_decal.sps} (should this be in decal batch?)
|
||||
case 3053856997://{water_riverfoam.sps}
|
||||
shaderMode = 1;
|
||||
break;
|
||||
case 3066724854://{water_terrainfoam.sps}
|
||||
shaderMode = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
PSGeomVars.Vars.EnableTexture = usediff ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableBumpMap = usebump ? 1u : 0u;
|
||||
PSGeomVars.Vars.EnableFoamMap = usefoam ? 1u : 0u;
|
||||
PSGeomVars.Vars.ShaderMode = shaderMode;
|
||||
PSGeomVars.Vars.SpecularIntensity = SpecularEnable ? 1.0f : 0.0f;// geom.specularIntensityMult;
|
||||
PSGeomVars.Vars.SpecularFalloff = 1.0f;// geom.specularFalloffMult;
|
||||
PSGeomVars.Vars.WaveOffset = geom.WaveOffset; //for terrainfoam
|
||||
PSGeomVars.Vars.WaterHeight = geom.WaterHeight; //for terrainfoam
|
||||
PSGeomVars.Vars.WaveMovement = geom.WaveMovement; //for terrainfoam
|
||||
PSGeomVars.Vars.HeightOpacity = geom.HeightOpacity; //for terrainfoam
|
||||
PSGeomVars.Vars.RippleSpeed = geom.RippleSpeed;
|
||||
PSGeomVars.Vars.RippleScale = geom.RippleScale;
|
||||
PSGeomVars.Vars.RippleBumpiness = geom.RippleBumpiness;
|
||||
PSGeomVars.Update(context);
|
||||
PSGeomVars.SetPSCBuffer(context, 2);
|
||||
|
||||
VSGeomVars.Vars.EnableFlow = useflow ? 1u : 0u;
|
||||
VSGeomVars.Vars.ShaderMode = shaderMode;
|
||||
VSGeomVars.Vars.WaterParams = Vector4.Zero;
|
||||
VSGeomVars.Vars.RippleSpeed = geom.RippleSpeed;
|
||||
VSGeomVars.Update(context);
|
||||
VSGeomVars.SetVSCBuffer(context, 3);
|
||||
|
||||
context.VertexShader.SetSampler(0, texsamplerflow);
|
||||
context.PixelShader.SetSampler(0, AnisotropicFilter ? texsampleranis : texsampler);
|
||||
if (usediff)
|
||||
{
|
||||
texture.SetPSResource(context, 0);
|
||||
}
|
||||
if (usebump)
|
||||
{
|
||||
bumptex.SetPSResource(context, 2);
|
||||
}
|
||||
if (usefoam)
|
||||
{
|
||||
foamtex.SetPSResource(context, 3);
|
||||
}
|
||||
if (useflow)
|
||||
{
|
||||
flowtex.SetVSResource(context, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void RenderWaterQuad(DeviceContext context, RenderableWaterQuad quad)
|
||||
{
|
||||
SetInputLayout(context, VertexType.PCT);
|
||||
|
||||
VSEntityVars.Vars.CamRel = new Vector4(quad.CamRel, 0.0f);
|
||||
VSEntityVars.Vars.Orientation = Quaternion.Identity;
|
||||
VSEntityVars.Vars.Scale = Vector3.One;
|
||||
VSEntityVars.Update(context);
|
||||
VSEntityVars.SetVSCBuffer(context, 2);
|
||||
|
||||
|
||||
PSGeomVars.Vars.EnableTexture = 0;
|
||||
PSGeomVars.Vars.EnableBumpMap = 0;
|
||||
PSGeomVars.Vars.EnableFoamMap = 0;
|
||||
PSGeomVars.Vars.ShaderMode = 0; //normal water render
|
||||
PSGeomVars.Vars.SpecularIntensity = SpecularEnable ? 4.2f : 0.0f;// geom.specularIntensityMult;
|
||||
PSGeomVars.Vars.SpecularFalloff = 1600.0f;// geom.specularFalloffMult;
|
||||
PSGeomVars.Vars.WaveOffset = 0.0f;// geom.WaveOffset; //for terrainfoam
|
||||
PSGeomVars.Vars.WaterHeight = 0.0f;// geom.WaterHeight; //for terrainfoam
|
||||
PSGeomVars.Vars.WaveMovement = 0.0f;// geom.WaveMovement; //for terrainfoam
|
||||
PSGeomVars.Vars.HeightOpacity = 0.0f;// geom.HeightOpacity; //for terrainfoam
|
||||
PSGeomVars.Vars.RippleSpeed = 2.1f;// geom.RippleSpeed;
|
||||
PSGeomVars.Vars.RippleScale = 0.02f;// geom.RippleScale;
|
||||
PSGeomVars.Vars.RippleBumpiness = 4.5f;// geom.RippleBumpiness;
|
||||
PSGeomVars.Update(context);
|
||||
PSGeomVars.SetPSCBuffer(context, 2);
|
||||
|
||||
VSGeomVars.Vars.EnableFlow = 0; //no flow for water quads...
|
||||
VSGeomVars.Vars.ShaderMode = 0; //normal water
|
||||
VSGeomVars.Vars.WaterParams = Vector4.Zero;
|
||||
VSGeomVars.Vars.RippleSpeed = 1.0f;// geom.RippleSpeed;
|
||||
VSGeomVars.Update(context);
|
||||
VSGeomVars.SetVSCBuffer(context, 3);
|
||||
|
||||
context.VertexShader.SetSampler(0, texsamplerflow);
|
||||
context.PixelShader.SetSampler(0, AnisotropicFilter ? texsampleranis : texsampler);
|
||||
|
||||
quad.Render(context);
|
||||
}
|
||||
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.PixelShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetConstantBuffer(1, null); //shadowmap
|
||||
context.PixelShader.SetConstantBuffer(1, null); //shadowmap
|
||||
context.PixelShader.SetShaderResource(1, null);//shadowmap
|
||||
context.PixelShader.SetSampler(1, null); //shadowmap
|
||||
context.VertexShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(3, null);
|
||||
context.PixelShader.SetConstantBuffer(2, null);
|
||||
context.VertexShader.SetConstantBuffer(4, null);
|
||||
context.VertexShader.SetConstantBuffer(5, null);
|
||||
context.VertexShader.SetConstantBuffer(6, null);
|
||||
context.VertexShader.SetSampler(0, null);
|
||||
context.PixelShader.SetSampler(0, null);
|
||||
context.PixelShader.SetShaderResource(0, null);
|
||||
context.PixelShader.SetShaderResource(2, null);
|
||||
context.PixelShader.SetShaderResource(3, null);
|
||||
context.PixelShader.SetShaderResource(4, null);
|
||||
context.PixelShader.SetShaderResource(5, null);
|
||||
context.VertexShader.SetShaderResource(0, null);
|
||||
context.VertexShader.SetShaderResource(1, null);
|
||||
context.VertexShader.SetShaderResource(2, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
|
||||
texsampler.Dispose();
|
||||
texsampleranis.Dispose();
|
||||
texsamplerflow.Dispose();
|
||||
|
||||
foreach (InputLayout layout in layouts.Values)
|
||||
{
|
||||
layout.Dispose();
|
||||
}
|
||||
layouts.Clear();
|
||||
|
||||
VSSceneVars.Dispose();
|
||||
VSEntityVars.Dispose();
|
||||
VSGeomVars.Dispose();
|
||||
PSSceneVars.Dispose();
|
||||
PSGeomVars.Dispose();
|
||||
|
||||
ps.Dispose();
|
||||
vspt.Dispose();
|
||||
vspct.Dispose();
|
||||
vspnct.Dispose();
|
||||
vspnctx.Dispose();
|
||||
|
||||
disposed = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,617 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using CodeWalker.GameFiles;
|
||||
using CodeWalker.World;
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX;
|
||||
using System.IO;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public struct WidgetShaderSceneVars
|
||||
{
|
||||
public Matrix ViewProj;
|
||||
public uint Mode; //0=Vertices, 1=Arc
|
||||
public float Size; //world units
|
||||
public float SegScale; //arc angle / number of segments
|
||||
public float SegOffset; //angle offset of arc
|
||||
public Vector3 CamRel; //center position
|
||||
public uint CullBack; //culls pixels behind 0,0,0
|
||||
public Color4 Colour; //colour for arc
|
||||
public Vector3 Axis1; //axis 1 of arc
|
||||
public float WidgetPad2;
|
||||
public Vector3 Axis2; //axis 2 of arc
|
||||
public float WidgetPad3;
|
||||
}
|
||||
|
||||
|
||||
public class WidgetShader : Shader
|
||||
{
|
||||
VertexShader vs;
|
||||
PixelShader ps;
|
||||
|
||||
GpuVarsBuffer<WidgetShaderSceneVars> SceneVars;
|
||||
GpuCBuffer<WidgetShaderVertex> Vertices;
|
||||
|
||||
|
||||
public WidgetShader(Device device)
|
||||
{
|
||||
byte[] vsbytes = File.ReadAllBytes("Shaders\\WidgetVS.cso");
|
||||
byte[] psbytes = File.ReadAllBytes("Shaders\\WidgetPS.cso");
|
||||
|
||||
vs = new VertexShader(device, vsbytes);
|
||||
ps = new PixelShader(device, psbytes);
|
||||
|
||||
SceneVars = new GpuVarsBuffer<WidgetShaderSceneVars>(device);
|
||||
|
||||
Vertices = new GpuCBuffer<WidgetShaderVertex>(device, 150); //should be more than needed....
|
||||
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
Vertices.Dispose();
|
||||
SceneVars.Dispose();
|
||||
ps.Dispose();
|
||||
vs.Dispose();
|
||||
}
|
||||
|
||||
public override void SetShader(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.Set(vs);
|
||||
context.PixelShader.Set(ps);
|
||||
}
|
||||
|
||||
public override bool SetInputLayout(DeviceContext context, VertexType type)
|
||||
{
|
||||
context.InputAssembler.InputLayout = null;
|
||||
context.InputAssembler.SetIndexBuffer(null, SharpDX.DXGI.Format.Unknown, 0);
|
||||
return true;
|
||||
}
|
||||
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
|
||||
{
|
||||
SceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
|
||||
SceneVars.Update(context);
|
||||
SceneVars.SetVSCBuffer(context, 0);
|
||||
|
||||
}
|
||||
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
|
||||
{
|
||||
}
|
||||
public override void SetModelVars(DeviceContext context, RenderableModel model)
|
||||
{
|
||||
}
|
||||
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
|
||||
{
|
||||
}
|
||||
|
||||
public override void UnbindResources(DeviceContext context)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(0, null);
|
||||
context.VertexShader.SetShaderResource(0, null);
|
||||
context.VertexShader.Set(null);
|
||||
context.PixelShader.Set(null);
|
||||
}
|
||||
|
||||
|
||||
public void DrawDefaultWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size)
|
||||
{
|
||||
SetShader(context);
|
||||
SetInputLayout(context, VertexType.Default);
|
||||
|
||||
SceneVars.Vars.Mode = 0; //vertices mode
|
||||
SceneVars.Vars.CamRel = camrel;
|
||||
SetSceneVars(context, cam, null, null);
|
||||
|
||||
Vector3 xdir = ori.Multiply(Vector3.UnitX);
|
||||
Vector3 ydir = ori.Multiply(Vector3.UnitY);
|
||||
Vector3 zdir = ori.Multiply(Vector3.UnitZ);
|
||||
Color4 xcolour = new Color4(0.8f, 0.0f, 0.0f, 1.0f);
|
||||
Color4 ycolour = new Color4(0.8f, 0.0f, 0.0f, 1.0f);
|
||||
Color4 zcolour = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
Vector3[] axes = { xdir, ydir, zdir };
|
||||
Vector3[] sides = { ydir, xdir, xdir };
|
||||
Color4[] colours = { xcolour, ycolour, zcolour };
|
||||
|
||||
float linestart = 0.0f * size;
|
||||
float lineend = 1.0f * size;
|
||||
float arrowstart = 0.9f * size;
|
||||
float arrowend = 1.0f * size;
|
||||
float arrowrad = 0.05f * size;
|
||||
|
||||
//draw lines...
|
||||
Vertices.Clear();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
WidgetAxis sa = (WidgetAxis)(1 << i);
|
||||
Color4 axcol = colours[i];
|
||||
|
||||
//main axis lines
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
|
||||
|
||||
//arrow heads
|
||||
Vector3 astart = axes[i] * arrowstart;
|
||||
Vector3 aend = axes[i] * arrowend;
|
||||
Vector3 aside = sides[i] * arrowrad;
|
||||
Vertices.Add(new WidgetShaderVertex(aend, axcol));
|
||||
Vertices.Add(new WidgetShaderVertex(astart + aside, axcol));
|
||||
Vertices.Add(new WidgetShaderVertex(aend, axcol));
|
||||
Vertices.Add(new WidgetShaderVertex(astart - aside, axcol));
|
||||
}
|
||||
|
||||
Vertices.Update(context);
|
||||
Vertices.SetVSResource(context, 0);
|
||||
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
|
||||
context.Draw(Vertices.CurrentCount, 0);
|
||||
|
||||
UnbindResources(context);
|
||||
}
|
||||
|
||||
public void DrawPositionWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size, WidgetAxis selax)
|
||||
{
|
||||
SetShader(context);
|
||||
SetInputLayout(context, VertexType.Default);
|
||||
|
||||
SceneVars.Vars.Mode = 0; //vertices mode
|
||||
SceneVars.Vars.CamRel = camrel;
|
||||
SetSceneVars(context, cam, null, null);
|
||||
|
||||
Vector3 xdir = ori.Multiply(Vector3.UnitX);
|
||||
Vector3 ydir = ori.Multiply(Vector3.UnitY);
|
||||
Vector3 zdir = ori.Multiply(Vector3.UnitZ);
|
||||
Color4 xcolour = new Color4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
Color4 ycolour = new Color4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
Color4 zcolour = new Color4(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
Color4 selaxcol = new Color4(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
Color4 selplcol = new Color4(1.0f, 1.0f, 0.0f, 0.5f);
|
||||
|
||||
Vector3[] axes = { xdir, ydir, zdir };
|
||||
Vector3[] sides1 = { ydir, zdir, xdir };
|
||||
Vector3[] sides2 = { zdir, xdir, ydir };
|
||||
WidgetAxis[] sideax1 = { WidgetAxis.Y, WidgetAxis.Z, WidgetAxis.X };
|
||||
WidgetAxis[] sideax2 = { WidgetAxis.Z, WidgetAxis.X, WidgetAxis.Y };
|
||||
Color4[] colours = { xcolour, ycolour, zcolour };
|
||||
Color4[] coloursdark = { xcolour * 0.5f, ycolour * 0.5f, zcolour * 0.5f };
|
||||
for (int i = 0; i < 3; i++) coloursdark[i].Alpha = 1.0f;
|
||||
|
||||
float linestart = 0.2f * size;
|
||||
float lineend = 1.0f * size;
|
||||
float sideval = 0.4f * size;
|
||||
float arrowstart = 1.0f * size;
|
||||
float arrowend = 1.33f * size;
|
||||
float arrowrad = 0.06f * size;
|
||||
|
||||
float hexx = 0.5f;
|
||||
float hexy = 0.86602540378443864676372317075294f; //sqrt(0.75)
|
||||
Vector2[] arrowv =
|
||||
{
|
||||
new Vector2(-1, 0) * arrowrad,
|
||||
new Vector2(-hexx, hexy) * arrowrad,
|
||||
new Vector2(hexx, hexy) * arrowrad,
|
||||
new Vector2(1, 0) * arrowrad,
|
||||
new Vector2(hexx, -hexy) * arrowrad,
|
||||
new Vector2(-hexx, -hexy) * arrowrad,
|
||||
new Vector2(-1, 0) * arrowrad
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//draw lines...
|
||||
Vertices.Clear();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
WidgetAxis sa = (WidgetAxis)(1 << i);
|
||||
bool axsel = ((selax & sa) > 0);
|
||||
Color4 axcol = axsel ? selaxcol : colours[i];
|
||||
|
||||
//axis side square lines
|
||||
Vector3 ax = axes[i] * sideval;
|
||||
Vector3 s1 = sides1[i] * sideval;
|
||||
Vector3 s2 = sides2[i] * sideval;
|
||||
Color4 sc1 = (axsel && ((selax & sideax1[i]) > 0)) ? selaxcol : colours[i];
|
||||
Color4 sc2 = (axsel && ((selax & sideax2[i]) > 0)) ? selaxcol : colours[i];
|
||||
Vertices.Add(new WidgetShaderVertex(ax, sc1));
|
||||
Vertices.Add(new WidgetShaderVertex(ax + s1, sc1));
|
||||
Vertices.Add(new WidgetShaderVertex(ax, sc2));
|
||||
Vertices.Add(new WidgetShaderVertex(ax + s2, sc2));
|
||||
|
||||
//main axis lines - draw after side lines to be on top
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
|
||||
}
|
||||
|
||||
Vertices.Update(context);
|
||||
Vertices.SetVSResource(context, 0);
|
||||
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
|
||||
context.Draw(Vertices.CurrentCount, 0);
|
||||
|
||||
|
||||
|
||||
//draw triangles...
|
||||
Vertices.Clear();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
//axis arrows - kind of inefficient, but meh
|
||||
Vector3 aend = axes[i] * arrowend;
|
||||
Vector3 astart = axes[i] * arrowstart;
|
||||
for (int n = 0; n < 6; n++)
|
||||
{
|
||||
Vector2 a1 = arrowv[n];
|
||||
Vector2 a2 = arrowv[n + 1];
|
||||
Vector3 ap1 = astart + sides1[i] * a1.Y + sides2[i] * a1.X;
|
||||
Vector3 ap2 = astart + sides1[i] * a2.Y + sides2[i] * a2.X;
|
||||
Vertices.Add(new WidgetShaderVertex(aend, colours[i]));
|
||||
Vertices.Add(new WidgetShaderVertex(ap1, colours[i]));
|
||||
Vertices.Add(new WidgetShaderVertex(ap2, colours[i]));
|
||||
Vertices.Add(new WidgetShaderVertex(astart, coloursdark[i]));
|
||||
Vertices.Add(new WidgetShaderVertex(ap2, coloursdark[i]));
|
||||
Vertices.Add(new WidgetShaderVertex(ap1, coloursdark[i]));
|
||||
}
|
||||
|
||||
//selection planes
|
||||
WidgetAxis sa = (WidgetAxis)(1 << i);
|
||||
if (((selax & sa) > 0))
|
||||
{
|
||||
Vector3 ax = axes[i] * sideval;
|
||||
for (int n = i + 1; n < 3; n++)
|
||||
{
|
||||
WidgetAxis tsa = (WidgetAxis)(1 << n);
|
||||
if (((selax & tsa) > 0))
|
||||
{
|
||||
Vector3 tax = axes[n] * sideval;
|
||||
Vertices.Add(new WidgetShaderVertex(Vector3.Zero, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(ax, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(tax, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(tax + ax, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(tax, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(ax, selplcol));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vertices.Update(context);
|
||||
Vertices.SetVSResource(context, 0);
|
||||
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
|
||||
context.Draw(Vertices.CurrentCount, 0);
|
||||
|
||||
UnbindResources(context);
|
||||
}
|
||||
|
||||
public void DrawRotationWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size, WidgetAxis selax, WidgetAxis drawax)
|
||||
{
|
||||
SetShader(context);
|
||||
SetInputLayout(context, VertexType.Default);
|
||||
|
||||
|
||||
SceneVars.Vars.Mode = 0; //vertices mode
|
||||
SceneVars.Vars.CamRel = camrel;
|
||||
SetSceneVars(context, cam, null, null);
|
||||
|
||||
Vector3 xdir = ori.Multiply(Vector3.UnitX);
|
||||
Vector3 ydir = ori.Multiply(Vector3.UnitY);
|
||||
Vector3 zdir = ori.Multiply(Vector3.UnitZ);
|
||||
Color4 xcolour = new Color4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
Color4 ycolour = new Color4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
Color4 zcolour = new Color4(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
Color4 icolour = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
Color4 ocolour = new Color4(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
Color4 scolour = new Color4(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
|
||||
Vector3[] axes = { xdir, ydir, zdir };
|
||||
Vector3[] sides = { ydir, xdir, xdir };
|
||||
Color4[] colours = { xcolour, ycolour, zcolour };
|
||||
|
||||
float linestart = 0.0f * size;
|
||||
float lineend = 0.3f * size;
|
||||
float ocircsize = 1.0f * size;
|
||||
float icircsize = 0.75f * size;
|
||||
|
||||
//draw lines...
|
||||
Vertices.Clear();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
WidgetAxis sa = (WidgetAxis)(1 << i);
|
||||
bool axsel = ((selax & sa) > 0);
|
||||
Color4 axcol = axsel ? colours[i] : icolour;
|
||||
|
||||
//main axis lines
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
|
||||
}
|
||||
|
||||
Vertices.Update(context);
|
||||
Vertices.SetVSResource(context, 0);
|
||||
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
|
||||
context.Draw(Vertices.CurrentCount, 0);
|
||||
|
||||
|
||||
|
||||
//linestrip for arcs and circles
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineStrip;
|
||||
|
||||
Vector3 sdir = Vector3.Normalize(camrel);
|
||||
//if (cam.IsMapView || cam.IsOrthographic)
|
||||
//{
|
||||
// sdir = cam.ViewDirection;
|
||||
//}
|
||||
float ad1 = Math.Abs(Vector3.Dot(sdir, Vector3.UnitY));
|
||||
float ad2 = Math.Abs(Vector3.Dot(sdir, Vector3.UnitZ));
|
||||
Vector3 ax1 = Vector3.Normalize(Vector3.Cross(sdir, (ad1 > ad2) ? Vector3.UnitY : Vector3.UnitZ));
|
||||
Vector3 ax2 = Vector3.Normalize(Vector3.Cross(sdir, ax1));
|
||||
|
||||
//drawing circles
|
||||
int segcount = 40;
|
||||
int vertcount = segcount + 1;
|
||||
SceneVars.Vars.Mode = 1; //arc mode
|
||||
SceneVars.Vars.SegScale = ((float)Math.PI) * 2.0f / segcount; //arc angle / number of segments
|
||||
SceneVars.Vars.SegOffset = 0.0f; //angle offset of arc
|
||||
SceneVars.Vars.Axis1 = ax1; //axis 1 of arc
|
||||
SceneVars.Vars.Axis2 = ax2; //axis 2 of arc
|
||||
SceneVars.Vars.CullBack = 0; //culls pixels behind 0,0,0
|
||||
|
||||
//outer circle
|
||||
if (drawax == WidgetAxis.XYZ)
|
||||
{
|
||||
SceneVars.Vars.Size = ocircsize; //world units
|
||||
SceneVars.Vars.Colour = (selax == WidgetAxis.XYZ) ? scolour : ocolour; //colour for arc
|
||||
SetSceneVars(context, cam, null, null);
|
||||
context.Draw(vertcount, 0);
|
||||
}
|
||||
|
||||
//inner circle
|
||||
SceneVars.Vars.Size = icircsize; //world units
|
||||
SceneVars.Vars.Colour = icolour; //colour for arc
|
||||
SetSceneVars(context, cam, null, null);
|
||||
context.Draw(vertcount, 0);
|
||||
|
||||
|
||||
//drawing arcs - culling done in PS
|
||||
SceneVars.Vars.Size = icircsize; //world units
|
||||
SceneVars.Vars.CullBack = 1; //culls pixels behind 0,0,0
|
||||
|
||||
if ((drawax & WidgetAxis.X) != 0)
|
||||
{
|
||||
SceneVars.Vars.SegOffset = 0.0f; //angle offset of arc
|
||||
SceneVars.Vars.Axis1 = ydir; //axis 1 of arc
|
||||
SceneVars.Vars.Axis2 = zdir; //axis 2 of arc
|
||||
SceneVars.Vars.Colour = (selax == WidgetAxis.X) ? scolour : xcolour; //colour for arc
|
||||
SetSceneVars(context, cam, null, null);
|
||||
context.Draw(vertcount, 0);
|
||||
}
|
||||
|
||||
if ((drawax & WidgetAxis.Y) != 0)
|
||||
{
|
||||
SceneVars.Vars.SegOffset = 0.0f; //angle offset of arc
|
||||
SceneVars.Vars.Axis1 = xdir; //axis 1 of arc
|
||||
SceneVars.Vars.Axis2 = zdir; //axis 2 of arc
|
||||
SceneVars.Vars.Colour = (selax == WidgetAxis.Y) ? scolour : ycolour; //colour for arc
|
||||
SetSceneVars(context, cam, null, null);
|
||||
context.Draw(vertcount, 0);
|
||||
}
|
||||
|
||||
if ((drawax & WidgetAxis.Z) != 0)
|
||||
{
|
||||
SceneVars.Vars.SegOffset = 0.0f; //angle offset of arc
|
||||
SceneVars.Vars.Axis1 = xdir; //axis 1 of arc
|
||||
SceneVars.Vars.Axis2 = ydir; //axis 2 of arc
|
||||
SceneVars.Vars.Colour = (selax == WidgetAxis.Z) ? scolour : zcolour; //colour for arc
|
||||
SetSceneVars(context, cam, null, null);
|
||||
context.Draw(vertcount, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
UnbindResources(context);
|
||||
}
|
||||
|
||||
public void DrawScaleWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size, WidgetAxis selax)
|
||||
{
|
||||
SetShader(context);
|
||||
SetInputLayout(context, VertexType.Default);
|
||||
|
||||
SceneVars.Vars.Mode = 0; //vertices mode
|
||||
SceneVars.Vars.CamRel = camrel;
|
||||
SetSceneVars(context, cam, null, null);
|
||||
|
||||
Vector3 xdir = ori.Multiply(Vector3.UnitX);
|
||||
Vector3 ydir = ori.Multiply(Vector3.UnitY);
|
||||
Vector3 zdir = ori.Multiply(Vector3.UnitZ);
|
||||
Color4 xcolour = new Color4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
Color4 ycolour = new Color4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
Color4 zcolour = new Color4(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
Color4 selaxcol = new Color4(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
Color4 selplcol = new Color4(1.0f, 1.0f, 0.0f, 0.5f);
|
||||
|
||||
Vector3[] axes = { xdir, ydir, zdir };
|
||||
Vector3[] sides1 = { ydir, zdir, xdir };
|
||||
Vector3[] sides2 = { zdir, xdir, ydir };
|
||||
WidgetAxis[] sideax1 = { WidgetAxis.Y, WidgetAxis.Z, WidgetAxis.X };
|
||||
WidgetAxis[] sideax2 = { WidgetAxis.Z, WidgetAxis.X, WidgetAxis.Y };
|
||||
Color4[] colours = { xcolour, ycolour, zcolour };
|
||||
Color4[] coloursn = { ycolour, zcolour, xcolour };
|
||||
Color4[] coloursdark = { xcolour * 0.5f, ycolour * 0.5f, zcolour * 0.5f };
|
||||
for (int i = 0; i < 3; i++) coloursdark[i].Alpha = 1.0f;
|
||||
|
||||
float linestart = 0.0f * size;
|
||||
float lineend = 1.33f * size;
|
||||
float innertri = 0.7f * size;
|
||||
float outertri = 1.0f * size;
|
||||
float cubestart = 1.28f * size;
|
||||
float cubeend = 1.33f * size;
|
||||
float cubesize = 0.025f * size;
|
||||
|
||||
//draw lines...
|
||||
Vertices.Clear();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
WidgetAxis sa = (WidgetAxis)(1 << i);
|
||||
bool axsel = ((selax & sa) > 0);
|
||||
Color4 axcol = axsel ? selaxcol : colours[i];
|
||||
|
||||
WidgetAxis triaxn = sideax1[i];
|
||||
bool trisel = axsel && ((selax & triaxn) > 0);
|
||||
Color4 tricol = trisel ? selaxcol : colours[i];
|
||||
Color4 trincol = trisel ? selaxcol : coloursn[i];
|
||||
|
||||
Vector3 inner1 = axes[i] * innertri;
|
||||
Vector3 inner2 = sides1[i] * innertri;
|
||||
Vector3 innera = (inner1 + inner2) * 0.5f;
|
||||
Vector3 outer1 = axes[i] * outertri;
|
||||
Vector3 outer2 = sides1[i] * outertri;
|
||||
Vector3 outera = (outer1 + outer2) * 0.5f;
|
||||
|
||||
//triangle axis lines
|
||||
Vertices.Add(new WidgetShaderVertex(inner1, tricol));
|
||||
Vertices.Add(new WidgetShaderVertex(innera, tricol));
|
||||
Vertices.Add(new WidgetShaderVertex(innera, trincol));
|
||||
Vertices.Add(new WidgetShaderVertex(inner2, trincol));
|
||||
Vertices.Add(new WidgetShaderVertex(outer1, tricol));
|
||||
Vertices.Add(new WidgetShaderVertex(outera, tricol));
|
||||
Vertices.Add(new WidgetShaderVertex(outera, trincol));
|
||||
Vertices.Add(new WidgetShaderVertex(outer2, trincol));
|
||||
|
||||
//main axis lines - draw after side lines to be on top
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
|
||||
}
|
||||
|
||||
Vertices.Update(context);
|
||||
Vertices.SetVSResource(context, 0);
|
||||
|
||||
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
|
||||
context.Draw(Vertices.CurrentCount, 0);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//draw triangles...
|
||||
Vertices.Clear();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
//axis end cubes - kind of inefficient, but meh
|
||||
Vector3 cend = axes[i] * cubeend;
|
||||
Vector3 cstart = axes[i] * cubestart;
|
||||
Vector3 cside1 = sides1[i] * cubesize;
|
||||
Vector3 cside2 = sides2[i] * cubesize;
|
||||
Vector3 cv1 = cstart + cside1 - cside2;
|
||||
Vector3 cv2 = cstart - cside1 - cside2;
|
||||
Vector3 cv3 = cend + cside1 - cside2;
|
||||
Vector3 cv4 = cend - cside1 - cside2;
|
||||
Vector3 cv5 = cstart + cside1 + cside2;
|
||||
Vector3 cv6 = cstart - cside1 + cside2;
|
||||
Vector3 cv7 = cend + cside1 + cside2;
|
||||
Vector3 cv8 = cend - cside1 + cside2;
|
||||
Color4 col = colours[i];
|
||||
Color4 cold = coloursdark[i];
|
||||
Vertices.Add(new WidgetShaderVertex(cv1, cold));
|
||||
Vertices.Add(new WidgetShaderVertex(cv2, cold));
|
||||
Vertices.Add(new WidgetShaderVertex(cv5, cold));
|
||||
Vertices.Add(new WidgetShaderVertex(cv5, cold));
|
||||
Vertices.Add(new WidgetShaderVertex(cv2, cold));
|
||||
Vertices.Add(new WidgetShaderVertex(cv6, cold));
|
||||
Vertices.Add(new WidgetShaderVertex(cv3, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv4, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv7, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv7, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv4, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv8, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv1, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv2, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv3, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv3, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv2, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv4, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv5, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv6, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv7, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv7, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv6, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv8, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv1, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv5, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv3, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv3, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv5, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv7, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv2, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv6, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv4, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv4, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv6, col));
|
||||
Vertices.Add(new WidgetShaderVertex(cv8, col));
|
||||
|
||||
|
||||
//selection triangles
|
||||
if (selax == WidgetAxis.XYZ)
|
||||
{
|
||||
//all axes - just draw inner triangle
|
||||
Vertices.Add(new WidgetShaderVertex(Vector3.Zero, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * innertri, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(sides1[i] * innertri, selplcol));
|
||||
}
|
||||
else
|
||||
{
|
||||
WidgetAxis sa = (WidgetAxis)(1 << i);
|
||||
WidgetAxis na = sideax1[i];
|
||||
if (((selax & sa) > 0) && ((selax & na) > 0))
|
||||
{
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * innertri, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(sides1[i] * innertri, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * outertri, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(axes[i] * outertri, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(sides1[i] * innertri, selplcol));
|
||||
Vertices.Add(new WidgetShaderVertex(sides1[i] * outertri, selplcol));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vertices.Update(context);
|
||||
Vertices.SetVSResource(context, 0);
|
||||
|
||||
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
|
||||
context.Draw(Vertices.CurrentCount, 0);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UnbindResources(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public struct WidgetShaderVertex
|
||||
{
|
||||
public Vector4 Position;
|
||||
public Color4 Colour;
|
||||
|
||||
public WidgetShaderVertex(Vector3 p, Color4 c)
|
||||
{
|
||||
Position = new Vector4(p, 0.0f);
|
||||
Colour = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpDX.DXGI;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public class GpuVarsBuffer<T> where T:struct //shader vars buffer helper!
|
||||
{
|
||||
public int Size;
|
||||
public Buffer Buffer;
|
||||
public T Vars;
|
||||
public bool Flag;//for external use
|
||||
public GpuVarsBuffer(Device device)
|
||||
{
|
||||
Size = System.Runtime.InteropServices.Marshal.SizeOf<T>();// (sizeof(T));
|
||||
Buffer = new Buffer(device, Size, ResourceUsage.Dynamic, BindFlags.ConstantBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0);// //DXUtility::CreateShaderVarsBuffer(Size, name);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
if (Buffer != null)
|
||||
{
|
||||
Buffer.Dispose();
|
||||
Buffer = null;
|
||||
}
|
||||
}
|
||||
public void Update(DeviceContext context)
|
||||
{
|
||||
var dataBox = context.MapSubresource(Buffer, 0, MapMode.WriteDiscard, MapFlags.None);
|
||||
Utilities.Write(dataBox.DataPointer, ref Vars);
|
||||
context.UnmapSubresource(Buffer, 0);
|
||||
}
|
||||
public void SetVSCBuffer(DeviceContext context, int slot)
|
||||
{
|
||||
context.VertexShader.SetConstantBuffer(slot, Buffer);
|
||||
}
|
||||
public void SetPSCBuffer(DeviceContext context, int slot)
|
||||
{
|
||||
context.PixelShader.SetConstantBuffer(slot, Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public class GpuSBuffer<T> where T : struct //for static struct data as resource view
|
||||
{
|
||||
public int StructSize;
|
||||
public int StructCount;
|
||||
public int BufferSize;
|
||||
public Buffer Buffer;
|
||||
public ShaderResourceView SRV;
|
||||
public GpuSBuffer(Device device, T[] data)
|
||||
{
|
||||
StructCount = data.Length;
|
||||
StructSize = System.Runtime.InteropServices.Marshal.SizeOf<T>();// (sizeof(T));
|
||||
BufferSize = StructCount * StructSize;
|
||||
//var ds = new DataStream(new DataPointer()
|
||||
Buffer = Buffer.Create<T>(device, BindFlags.ShaderResource, data, BufferSize, ResourceUsage.Default, CpuAccessFlags.None, ResourceOptionFlags.BufferStructured, StructSize);
|
||||
//Buffer = new Buffer(device, BufferSize, ResourceUsage.Default, BindFlags.ShaderResource, CpuAccessFlags.None, ResourceOptionFlags.BufferStructured, StructSize);
|
||||
SRV = DXUtility.CreateShaderResourceView(device, Buffer, SharpDX.DXGI.Format.Unknown, SharpDX.Direct3D.ShaderResourceViewDimension.Buffer, 0, 0, StructCount, 0);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
if (SRV != null)
|
||||
{
|
||||
SRV.Dispose();
|
||||
SRV = null;
|
||||
}
|
||||
if (Buffer != null)
|
||||
{
|
||||
Buffer.Dispose();
|
||||
Buffer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class GpuCBuffer<T> where T : struct //Dynamic GPU buffer of items updated by CPU
|
||||
{
|
||||
public int StructSize;
|
||||
public int StructCount;
|
||||
public int BufferSize;
|
||||
public int CurrentCount;
|
||||
public Buffer Buffer;
|
||||
public ShaderResourceView SRV;
|
||||
public List<T> Data;
|
||||
public T[] DataArray;
|
||||
|
||||
public GpuCBuffer(Device device, int count)
|
||||
{
|
||||
StructCount = count;
|
||||
StructSize = System.Runtime.InteropServices.Marshal.SizeOf<T>();// (sizeof(T));
|
||||
BufferSize = StructCount * StructSize;
|
||||
//Buffer = Buffer.Create<T>(device, BindFlags.ShaderResource, null, BufferSize, ResourceUsage.Dynamic, CpuAccessFlags.Write, ResourceOptionFlags.BufferStructured, StructSize);
|
||||
Buffer = new Buffer(device, BufferSize, ResourceUsage.Dynamic, BindFlags.ShaderResource, CpuAccessFlags.Write, ResourceOptionFlags.BufferStructured, StructSize);
|
||||
SRV = DXUtility.CreateShaderResourceView(device, Buffer, SharpDX.DXGI.Format.Unknown, SharpDX.Direct3D.ShaderResourceViewDimension.Buffer, 0, 0, StructCount, 0);
|
||||
Data = new List<T>(count);
|
||||
DataArray = new T[count];
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
if (SRV != null)
|
||||
{
|
||||
SRV.Dispose();
|
||||
SRV = null;
|
||||
}
|
||||
if (Buffer != null)
|
||||
{
|
||||
Buffer.Dispose();
|
||||
Buffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Data.Clear();
|
||||
CurrentCount = 0;
|
||||
}
|
||||
public bool Add(T item)
|
||||
{
|
||||
if (CurrentCount < StructCount)
|
||||
{
|
||||
Data.Add(item);
|
||||
CurrentCount++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Update(DeviceContext context)
|
||||
{
|
||||
for (int i = 0; i < CurrentCount; i++)
|
||||
{
|
||||
DataArray[i] = Data[i];
|
||||
}
|
||||
var dataBox = context.MapSubresource(Buffer, 0, MapMode.WriteDiscard, MapFlags.None);
|
||||
Utilities.Write(dataBox.DataPointer, DataArray, 0, CurrentCount);
|
||||
context.UnmapSubresource(Buffer, 0);
|
||||
}
|
||||
|
||||
public void SetVSResource(DeviceContext context, int slot)
|
||||
{
|
||||
context.VertexShader.SetShaderResource(slot, SRV);
|
||||
}
|
||||
public void SetPSResource(DeviceContext context, int slot)
|
||||
{
|
||||
context.PixelShader.SetShaderResource(slot, SRV);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class GpuBuffer<T> where T : struct //Dynamic GPU buffer of items updated by compute shader
|
||||
{
|
||||
public int StructSize;
|
||||
public int StructCount;
|
||||
public int ItemTotalSize;
|
||||
public int ItemCount;
|
||||
public int Size;
|
||||
public Buffer Buffer;
|
||||
public ShaderResourceView SRV;
|
||||
public UnorderedAccessView UAV;
|
||||
|
||||
public GpuBuffer(Device device, int itemSize, int itemCount)
|
||||
{
|
||||
StructSize = System.Runtime.InteropServices.Marshal.SizeOf<T>();// sizeof(T)),
|
||||
StructCount = itemCount * itemSize;
|
||||
ItemTotalSize = itemSize * StructSize;
|
||||
ItemCount = itemCount;
|
||||
Size = StructSize * itemSize * itemCount;
|
||||
Buffer = DXUtility.CreateBuffer(device, Size, ResourceUsage.Default, BindFlags.ShaderResource | BindFlags.UnorderedAccess, 0, ResourceOptionFlags.BufferStructured, StructSize);
|
||||
SRV = DXUtility.CreateShaderResourceView(device, Buffer, Format.Unknown, ShaderResourceViewDimension.Buffer, 0, 0, StructCount, 0);
|
||||
UAV = DXUtility.CreateUnorderedAccessView(device, Buffer, Format.Unknown, UnorderedAccessViewDimension.Buffer, 0, StructCount, 0, 0);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
if (UAV != null)
|
||||
{
|
||||
UAV.Dispose();
|
||||
UAV = null;
|
||||
}
|
||||
if (SRV != null)
|
||||
{
|
||||
SRV.Dispose();
|
||||
SRV = null;
|
||||
}
|
||||
if (Buffer != null)
|
||||
{
|
||||
Buffer.Dispose();
|
||||
Buffer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class GpuTexture //texture and render targets (depth, MS).
|
||||
{
|
||||
public Texture2D Texture;
|
||||
public Texture2D TextureMS;
|
||||
public Texture2D Depth;
|
||||
public Texture2D DepthMS;
|
||||
public RenderTargetView RTV;
|
||||
public DepthStencilView DSV;
|
||||
public RenderTargetView MSRTV;
|
||||
public DepthStencilView MSDSV;
|
||||
public ShaderResourceView SRV;
|
||||
public int VramUsage;
|
||||
public bool Multisampled;
|
||||
public bool UseDepth;
|
||||
|
||||
public void Init(Device device, int w, int h, Format f, int sc, int sq, bool depth, Format df)
|
||||
{
|
||||
VramUsage = 0;
|
||||
Multisampled = (sc > 1);
|
||||
UseDepth = depth;
|
||||
ResourceUsage u = ResourceUsage.Default;
|
||||
BindFlags b = BindFlags.RenderTarget | BindFlags.ShaderResource;
|
||||
RenderTargetViewDimension rtvd = RenderTargetViewDimension.Texture2D;
|
||||
ShaderResourceViewDimension srvd = ShaderResourceViewDimension.Texture2D;// D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
int fs = DXUtility.ElementSize(f);
|
||||
int wh = w * h;
|
||||
BindFlags db = BindFlags.DepthStencil;// D3D11_BIND_DEPTH_STENCIL;
|
||||
DepthStencilViewDimension dsvd = DepthStencilViewDimension.Texture2D;
|
||||
|
||||
Texture = DXUtility.CreateTexture2D(device, w, h, 1, 1, f, 1, 0, u, b, 0, 0);
|
||||
RTV = DXUtility.CreateRenderTargetView(device, Texture, f, rtvd, 0, 0, 0);
|
||||
SRV = DXUtility.CreateShaderResourceView(device, Texture, f, srvd, 1, 0, 0, 0);
|
||||
VramUsage += (wh * fs);
|
||||
|
||||
if (Multisampled)
|
||||
{
|
||||
b = BindFlags.RenderTarget;
|
||||
rtvd = RenderTargetViewDimension.Texture2DMultisampled;
|
||||
dsvd = DepthStencilViewDimension.Texture2DMultisampled;
|
||||
|
||||
TextureMS = DXUtility.CreateTexture2D(device, w, h, 1, 1, f, sc, sq, u, b, 0, 0);
|
||||
MSRTV = DXUtility.CreateRenderTargetView(device, TextureMS, f, rtvd, 0, 0, 0);
|
||||
VramUsage += (wh * fs);
|
||||
|
||||
if (depth)
|
||||
{
|
||||
DepthMS = DXUtility.CreateTexture2D(device, w, h, 1, 1, df, sc, sq, u, db, 0, 0);
|
||||
MSDSV = DXUtility.CreateDepthStencilView(device, DepthMS, df, dsvd);
|
||||
VramUsage += (wh * DXUtility.ElementSize(df));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (depth)
|
||||
{
|
||||
Depth = DXUtility.CreateTexture2D(device, w, h, 1, 1, df, sc, sq, u, db, 0, 0);
|
||||
DSV = DXUtility.CreateDepthStencilView(device, Depth, df, dsvd);
|
||||
VramUsage += (wh * DXUtility.ElementSize(df));
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
if (SRV != null)
|
||||
{
|
||||
SRV.Dispose();
|
||||
SRV = null;
|
||||
}
|
||||
if (MSDSV != null)
|
||||
{
|
||||
MSDSV.Dispose();
|
||||
MSDSV = null;
|
||||
}
|
||||
if (MSRTV != null)
|
||||
{
|
||||
MSRTV.Dispose();
|
||||
MSRTV = null;
|
||||
}
|
||||
if (DSV != null)
|
||||
{
|
||||
DSV.Dispose();
|
||||
DSV = null;
|
||||
}
|
||||
if (RTV != null)
|
||||
{
|
||||
RTV.Dispose();
|
||||
RTV = null;
|
||||
}
|
||||
if (DepthMS != null)
|
||||
{
|
||||
DepthMS.Dispose();
|
||||
DepthMS = null;
|
||||
}
|
||||
if (Depth != null)
|
||||
{
|
||||
Depth.Dispose();
|
||||
Depth = null;
|
||||
}
|
||||
if (TextureMS != null)
|
||||
{
|
||||
TextureMS.Dispose();
|
||||
TextureMS = null;
|
||||
}
|
||||
if (Texture != null)
|
||||
{
|
||||
Texture.Dispose();
|
||||
Texture = null;
|
||||
}
|
||||
}
|
||||
public GpuTexture(Device device, int w, int h, Format f, int sc, int sq, bool depth, Format df)
|
||||
{
|
||||
Init(device, w, h, f, sc, sq, depth, df);
|
||||
}
|
||||
public GpuTexture(Device device, int w, int h, Format f, int sc, int sq)
|
||||
{
|
||||
Init(device, w, h, f, sc, sq, false, Format.Unknown);
|
||||
}
|
||||
public GpuTexture(Device device, int w, int h, Format f)
|
||||
{
|
||||
Init(device, w, h, f, 1, 0, false, Format.Unknown);
|
||||
}
|
||||
|
||||
public void Clear(DeviceContext context, Color4 colour)
|
||||
{
|
||||
if (Multisampled)
|
||||
{
|
||||
context.ClearRenderTargetView(MSRTV, colour);
|
||||
if (UseDepth)
|
||||
{
|
||||
context.ClearDepthStencilView(MSDSV, DepthStencilClearFlags.Depth, 1.0f, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.ClearRenderTargetView(RTV, colour);
|
||||
if (UseDepth)
|
||||
{
|
||||
context.ClearDepthStencilView(DSV, DepthStencilClearFlags.Depth, 1.0f, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearDepth(DeviceContext context)
|
||||
{
|
||||
if (!UseDepth) return;
|
||||
if (Multisampled)
|
||||
{
|
||||
context.ClearDepthStencilView(MSDSV, DepthStencilClearFlags.Depth, 1.0f, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.ClearDepthStencilView(DSV, DepthStencilClearFlags.Depth, 1.0f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetRenderTarget(DeviceContext context)
|
||||
{
|
||||
if (Multisampled)
|
||||
{
|
||||
context.OutputMerger.SetRenderTargets(UseDepth ? MSDSV : null, MSRTV);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.OutputMerger.SetRenderTargets(UseDepth ? DSV : null, RTV);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.Mathematics.Interop;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public class RenderTargetSwitch
|
||||
{
|
||||
|
||||
RenderTargetView[] OrigRenderTargetViewArr;
|
||||
DepthStencilView OrigDepthStencilView;
|
||||
RasterizerState OrigRasterizerState;
|
||||
RawViewportF[] OrigViewports;
|
||||
bool IsReset = true;
|
||||
//bool ResetOnDestroy = false;
|
||||
int RenderTargetCount = 1;
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (OrigRenderTargetViewArr != null)
|
||||
{
|
||||
for (int i = 0; i < RenderTargetCount; i++)
|
||||
{
|
||||
if (OrigRenderTargetViewArr[i] != null)
|
||||
{
|
||||
OrigRenderTargetViewArr[i].Dispose();
|
||||
}
|
||||
}
|
||||
OrigRenderTargetViewArr = null;
|
||||
}
|
||||
if (OrigDepthStencilView != null)
|
||||
{
|
||||
OrigDepthStencilView.Dispose();
|
||||
OrigDepthStencilView = null;
|
||||
}
|
||||
if (OrigRasterizerState != null)
|
||||
{
|
||||
OrigRasterizerState.Dispose();
|
||||
OrigRasterizerState = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Set(DeviceContext context)
|
||||
{
|
||||
Dispose();
|
||||
|
||||
OrigRenderTargetViewArr = context.OutputMerger.GetRenderTargets(RenderTargetCount, out OrigDepthStencilView);
|
||||
OrigViewports = context.Rasterizer.GetViewports<RawViewportF>();
|
||||
OrigRasterizerState = context.Rasterizer.State;
|
||||
|
||||
//OrigRenderTargetViewArr = new RenderTargetView[RenderTargetCount];
|
||||
//uint origNumViewports = 1;
|
||||
//dc->OMGetRenderTargets(RenderTargetCount, OrigRenderTargetViewArr, &OrigDepthStencilView);
|
||||
//dc->RSGetViewports(&origNumViewports, &OrigViewport);
|
||||
//dc->RSGetState(&OrigRasterizerState);
|
||||
|
||||
IsReset = false;
|
||||
}
|
||||
public void Reset(DeviceContext context)
|
||||
{
|
||||
if (IsReset) return;
|
||||
|
||||
context.OutputMerger.SetRenderTargets(OrigDepthStencilView, OrigRenderTargetViewArr);
|
||||
context.Rasterizer.State = OrigRasterizerState;
|
||||
context.Rasterizer.SetViewports(OrigViewports);
|
||||
|
||||
//auto dc = DXManager::GetDeviceContext();
|
||||
//dc->OMSetRenderTargets(RenderTargetCount, OrigRenderTargetViewArr, OrigDepthStencilView);
|
||||
//dc->RSSetState(OrigRasterizerState);
|
||||
//dc->RSSetViewports(1, &OrigViewport);
|
||||
|
||||
IsReset = true;
|
||||
|
||||
Dispose();
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,268 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D;
|
||||
using SharpDX.Direct3D11;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using SharpDX.DXGI;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public class UnitCapsule
|
||||
{
|
||||
private Buffer VertexBuffer { get; set; }
|
||||
private Buffer IndexBuffer { get; set; }
|
||||
private InputLayout InputLayout { get; set; }
|
||||
private VertexBufferBinding vbbinding;
|
||||
private int indexcount;
|
||||
|
||||
private struct SphTri
|
||||
{
|
||||
public int v1;
|
||||
public int v2;
|
||||
public int v3;
|
||||
public SphTri(int i1, int i2, int i3)
|
||||
{
|
||||
v1 = i1;
|
||||
v2 = i2;
|
||||
v3 = i3;
|
||||
}
|
||||
}
|
||||
|
||||
public UnitCapsule(Device device, byte[] vsbytes, int detail)
|
||||
{
|
||||
|
||||
InputLayout = new InputLayout(device, vsbytes, new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||
//new InputElement("NORMAL", 0, Format.R32G32B32A32_Float, 16, 0),
|
||||
});
|
||||
|
||||
|
||||
|
||||
List<Vector4> verts = new List<Vector4>();
|
||||
Dictionary<Vector4, int> vdict = new Dictionary<Vector4, int>();
|
||||
List<SphTri> curtris = new List<SphTri>();
|
||||
//List<SphTri> nxttris = new List<SphTri>();
|
||||
|
||||
verts.Add(new Vector4(0.0f, -1.0f, 0.0f, 0.0f));//top end
|
||||
verts.Add(new Vector4(0.0f, 1.0f, 0.0f, 1.0f));//bottom end
|
||||
|
||||
//detail = nlats each hemisphere
|
||||
//nlons = detail*4
|
||||
|
||||
int nlats = detail;
|
||||
int nlons = detail * 4;
|
||||
int firstlat = 1 - nlats;
|
||||
int lastlat = nlats-1;
|
||||
int lastlon = nlons - 1;
|
||||
int vertsperlon = 2 + (nlats - 1) * 2;
|
||||
float latrng = 1.0f / (detail);
|
||||
float lonrng = 1.0f / (nlons);
|
||||
float halfpi = (float)(0.5 * Math.PI);
|
||||
float twopi = (float)(2.0 * Math.PI);
|
||||
|
||||
for (int lon = 0; lon < nlons; lon++)
|
||||
{
|
||||
float tlon = lon * lonrng;
|
||||
float rlon = tlon * twopi;
|
||||
float lonx = (float)Math.Sin(rlon);
|
||||
float lonz = (float)Math.Cos(rlon);
|
||||
for (int lat = firstlat; lat < nlats; lat++)
|
||||
{
|
||||
float tlat = lat * latrng;
|
||||
float rlat = tlat * halfpi;
|
||||
float laty = (float)Math.Sin(rlat);
|
||||
float latxz = (float)Math.Cos(rlat);
|
||||
float hemi = (lat > 0) ? 1.0f : 0.0f;
|
||||
|
||||
verts.Add(new Vector4(lonx * latxz, laty, lonz * latxz, hemi));
|
||||
|
||||
if (lat == 0)
|
||||
{
|
||||
verts.Add(new Vector4(lonx * latxz, laty, lonz * latxz, 1.0f)); //split at the "equator"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int lon = 0; lon < nlons; lon++)
|
||||
{
|
||||
int i0 = 2 + lon * vertsperlon;//top row
|
||||
int i1 = i0 + vertsperlon;
|
||||
int i2 = i1 - 1;//bottom row
|
||||
int i3 = i2 + vertsperlon;
|
||||
|
||||
if (lon == lastlon)
|
||||
{
|
||||
i1 = 2;
|
||||
i3 = 1 + vertsperlon;
|
||||
}
|
||||
|
||||
curtris.Add(new SphTri(0, i1, i0)); //top cap triangles
|
||||
|
||||
for (int lat = firstlat; lat <= lastlat; lat++)
|
||||
{
|
||||
int offs = lat - firstlat;
|
||||
int f1 = i0 + offs;
|
||||
int f2 = f1 + vertsperlon;
|
||||
int f3 = f1 + 1;
|
||||
if (lon == lastlon)
|
||||
{
|
||||
f2 = 2 + offs;
|
||||
}
|
||||
int f4 = f2 + 1;
|
||||
curtris.Add(new SphTri(f1, f2, f3));
|
||||
curtris.Add(new SphTri(f3, f2, f4)); //fill the rest
|
||||
}
|
||||
|
||||
curtris.Add(new SphTri(1, i2, i3)); //bottom cap triangles
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region cube version (unfinished)
|
||||
/* cube version
|
||||
|
||||
verts.Add(new Vector4(-1.0f, 0.0f, 0.0f, 0.0f));
|
||||
verts.Add(new Vector4(1.0f, 0.0f, 0.0f, 0.0f));
|
||||
verts.Add(new Vector4(0.0f, -1.0f, 0.0f, 0.0f));
|
||||
verts.Add(new Vector4(0.0f, 1.0f, 0.0f, 1.0f));//bottom end
|
||||
verts.Add(new Vector4(0.0f, 0.0f, -1.0f, 0.0f));
|
||||
verts.Add(new Vector4(0.0f, 0.0f, 1.0f, 0.0f));
|
||||
|
||||
verts.Add(new Vector4(-1.0f, 0.0f, 0.0f, 1.0f));//0==6 - bottom equator split
|
||||
verts.Add(new Vector4(1.0f, 0.0f, 0.0f, 1.0f));//1==7
|
||||
verts.Add(new Vector4(0.0f, 0.0f, -1.0f, 1.0f));//4==8
|
||||
verts.Add(new Vector4(0.0f, 0.0f, 1.0f, 1.0f));//5==9
|
||||
|
||||
curtris.Add(new SphTri(0, 4, 2));
|
||||
curtris.Add(new SphTri(4, 1, 2));
|
||||
curtris.Add(new SphTri(1, 5, 2));
|
||||
curtris.Add(new SphTri(5, 0, 2));
|
||||
|
||||
curtris.Add(new SphTri(8, 6, 3));//split halves - Y axis
|
||||
curtris.Add(new SphTri(7, 8, 3));
|
||||
curtris.Add(new SphTri(9, 7, 3));
|
||||
curtris.Add(new SphTri(6, 9, 3));
|
||||
|
||||
for (int i = 0; i < verts.Count; i++)
|
||||
{
|
||||
vdict[verts[i]] = i;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < detail; i++)
|
||||
{
|
||||
nxttris.Clear();
|
||||
foreach (var tri in curtris)
|
||||
{
|
||||
Vector4 v1 = verts[tri.v1];
|
||||
Vector4 v2 = verts[tri.v2];
|
||||
Vector4 v3 = verts[tri.v3];
|
||||
Vector4 s1 = new Vector4(Vector3.Normalize((v1 + v2).XYZ()), v1.W);
|
||||
Vector4 s2 = new Vector4(Vector3.Normalize((v2 + v3).XYZ()), v1.W);
|
||||
Vector4 s3 = new Vector4(Vector3.Normalize((v3 + v1).XYZ()), v1.W);
|
||||
int i1, i2, i3;
|
||||
if (!vdict.TryGetValue(s1, out i1))
|
||||
{
|
||||
i1 = verts.Count;
|
||||
verts.Add(s1);
|
||||
vdict[s1] = i1;
|
||||
}
|
||||
if (!vdict.TryGetValue(s2, out i2))
|
||||
{
|
||||
i2 = verts.Count;
|
||||
verts.Add(s2);
|
||||
vdict[s2] = i2;
|
||||
}
|
||||
if (!vdict.TryGetValue(s3, out i3))
|
||||
{
|
||||
i3 = verts.Count;
|
||||
verts.Add(s3);
|
||||
vdict[s3] = i3;
|
||||
}
|
||||
nxttris.Add(new SphTri(tri.v1, i1, i3));
|
||||
nxttris.Add(new SphTri(tri.v2, i2, i1));
|
||||
nxttris.Add(new SphTri(tri.v3, i3, i2));
|
||||
nxttris.Add(new SphTri(i1, i2, i3));
|
||||
}
|
||||
var cur = curtris;
|
||||
curtris = nxttris;
|
||||
nxttris = cur;
|
||||
}
|
||||
*/
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
List<uint> idata = new List<uint>();
|
||||
foreach (var tri in curtris)
|
||||
{
|
||||
idata.Add((uint)tri.v1);
|
||||
idata.Add((uint)tri.v2);
|
||||
idata.Add((uint)tri.v3);
|
||||
}
|
||||
|
||||
|
||||
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, verts.ToArray());
|
||||
vbbinding = new VertexBufferBinding(VertexBuffer, 16, 0);
|
||||
|
||||
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, idata.ToArray());
|
||||
indexcount = idata.Count;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void Draw(DeviceContext context)
|
||||
{
|
||||
context.InputAssembler.InputLayout = InputLayout;
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
|
||||
context.DrawIndexed(indexcount, 0, 0);
|
||||
}
|
||||
|
||||
public void DrawInstanced(DeviceContext context, int count)
|
||||
{
|
||||
context.InputAssembler.InputLayout = InputLayout;
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
|
||||
context.DrawIndexedInstanced(indexcount, count, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (VertexBuffer != null)
|
||||
{
|
||||
VertexBuffer.Dispose();
|
||||
VertexBuffer = null;
|
||||
}
|
||||
if (IndexBuffer != null)
|
||||
{
|
||||
IndexBuffer.Dispose();
|
||||
IndexBuffer = null;
|
||||
}
|
||||
if (InputLayout != null)
|
||||
{
|
||||
InputLayout.Dispose();
|
||||
InputLayout = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D;
|
||||
using SharpDX.Direct3D11;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using SharpDX.DXGI;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public class UnitCube
|
||||
{
|
||||
private Buffer VertexBuffer { get; set; }
|
||||
private Buffer IndexBuffer { get; set; }
|
||||
private InputLayout InputLayout { get; set; }
|
||||
private VertexBufferBinding vbbinding;
|
||||
private bool issigned;
|
||||
private bool islines;
|
||||
private bool isnormals;
|
||||
private int indexcount;
|
||||
|
||||
public UnitCube(Device device, byte[] vsbytes, bool signed, bool lines, bool normals)
|
||||
{
|
||||
issigned = signed;
|
||||
islines = lines;
|
||||
isnormals = normals;
|
||||
|
||||
if (normals)
|
||||
{
|
||||
InputLayout = new InputLayout(device, vsbytes, new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||
new InputElement("NORMAL", 0, Format.R32G32B32A32_Float, 16, 0),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
InputLayout = new InputLayout(device, vsbytes, new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (signed)
|
||||
{
|
||||
if (normals)
|
||||
{
|
||||
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, new[]
|
||||
{
|
||||
//position (x4), normal (x3)
|
||||
//-Z face
|
||||
-1.0f, -1.0f, -1.0f, 1.0f, 0.0f,0.0f,-1.0f,0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f,0.0f,-1.0f,0.0f,
|
||||
-1.0f, 1.0f, -1.0f, 1.0f, 0.0f,0.0f,-1.0f,0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f,0.0f,-1.0f,0.0f,
|
||||
//+Z face
|
||||
-1.0f, -1.0f, 1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f,
|
||||
-1.0f, 1.0f, 1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f,
|
||||
//-Y face
|
||||
-1.0f, -1.0f, -1.0f, 1.0f, 0.0f,-1.0f,0.0f,0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f,-1.0f,0.0f,0.0f,
|
||||
-1.0f, -1.0f, 1.0f, 1.0f, 0.0f,-1.0f,0.0f,0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f,-1.0f,0.0f,0.0f,
|
||||
//+Y face
|
||||
-1.0f, 1.0f, -1.0f, 1.0f, 0.0f,1.0f,0.0f,0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f,1.0f,0.0f,0.0f,
|
||||
-1.0f, 1.0f, 1.0f, 1.0f, 0.0f,1.0f,0.0f,0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,1.0f,0.0f,0.0f,
|
||||
//-X face
|
||||
-1.0f, -1.0f, -1.0f, 1.0f, -1.0f,0.0f,0.0f,0.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f,0.0f,0.0f,0.0f,
|
||||
-1.0f, -1.0f, 1.0f, 1.0f, -1.0f,0.0f,0.0f,0.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f,0.0f,0.0f,0.0f,
|
||||
//+X face
|
||||
1.0f, -1.0f, -1.0f, 1.0f, 1.0f,0.0f,0.0f,0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f,0.0f,0.0f,0.0f,
|
||||
1.0f, -1.0f, 1.0f, 1.0f, 1.0f,0.0f,0.0f,0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,0.0f,0.0f,0.0f,
|
||||
});
|
||||
vbbinding = new VertexBufferBinding(VertexBuffer, 32, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, new[]
|
||||
{
|
||||
//position (x4)
|
||||
-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
|
||||
-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
|
||||
-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
});
|
||||
vbbinding = new VertexBufferBinding(VertexBuffer, 16, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (normals)
|
||||
{
|
||||
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, new[]
|
||||
{
|
||||
//position (x4), normal (x3)
|
||||
//-Z face
|
||||
0.0f, 0.0f, 0.0f, 1.0f, 0.0f,0.0f,-1.0f,0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,0.0f,-1.0f,0.0f,
|
||||
0.0f, 1.0f, 0.0f, 1.0f, 0.0f,0.0f,-1.0f,0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,0.0f,-1.0f,0.0f,
|
||||
//+Z face
|
||||
0.0f, 0.0f, 1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f,
|
||||
0.0f, 1.0f, 1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f,
|
||||
//-Y face
|
||||
0.0f, 0.0f, 0.0f, 1.0f, 0.0f,-1.0f,0.0f,0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,-1.0f,0.0f,0.0f,
|
||||
0.0f, 0.0f, 1.0f, 1.0f, 0.0f,-1.0f,0.0f,0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,-1.0f,0.0f,0.0f,
|
||||
//+Y face
|
||||
0.0f, 1.0f, 0.0f, 1.0f, 0.0f,1.0f,0.0f,0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,1.0f,0.0f,0.0f,
|
||||
0.0f, 1.0f, 1.0f, 1.0f, 0.0f,1.0f,0.0f,0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,1.0f,0.0f,0.0f,
|
||||
//-X face
|
||||
0.0f, 0.0f, 0.0f, 1.0f, -1.0f,0.0f,0.0f,0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f,0.0f,0.0f,0.0f,
|
||||
0.0f, 0.0f, 1.0f, 1.0f, -1.0f,0.0f,0.0f,0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f,0.0f,0.0f,0.0f,
|
||||
//+X face
|
||||
1.0f, 0.0f, 0.0f, 1.0f, 1.0f,0.0f,0.0f,0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,0.0f,0.0f,0.0f,
|
||||
1.0f, 0.0f, 1.0f, 1.0f, 1.0f,0.0f,0.0f,0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,0.0f,0.0f,0.0f,
|
||||
});
|
||||
vbbinding = new VertexBufferBinding(VertexBuffer, 32, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, new[]
|
||||
{
|
||||
//position (x4)
|
||||
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
});
|
||||
vbbinding = new VertexBufferBinding(VertexBuffer, 16, 0);
|
||||
}
|
||||
}
|
||||
if (lines)
|
||||
{
|
||||
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, new uint[]
|
||||
{
|
||||
0,1,1,3,3,2,2,0,
|
||||
4,5,5,7,7,6,6,4,
|
||||
0,4,1,5,3,7,2,6,
|
||||
});
|
||||
indexcount = 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (normals)
|
||||
{
|
||||
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, new uint[]
|
||||
{
|
||||
0,2,1,1,2,3,
|
||||
4,5,6,5,7,6,
|
||||
8,9,10,9,11,10,
|
||||
12,14,13,13,14,15,
|
||||
16,18,17,17,18,19,
|
||||
20,21,22,21,23,22
|
||||
});
|
||||
indexcount = 36;
|
||||
}
|
||||
else
|
||||
{
|
||||
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, new uint[]
|
||||
{
|
||||
0,2,1,1,2,3,
|
||||
4,5,6,5,7,6,
|
||||
//todo: other faces
|
||||
});
|
||||
indexcount = 12; //36..
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void Draw(DeviceContext context)
|
||||
{
|
||||
context.InputAssembler.InputLayout = InputLayout;
|
||||
|
||||
if (islines)
|
||||
{
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineList;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
}
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, SharpDX.DXGI.Format.R32_UInt, 0);
|
||||
|
||||
context.DrawIndexed(indexcount, 0, 0);
|
||||
}
|
||||
|
||||
public void DrawInstanced(DeviceContext context, int count)
|
||||
{
|
||||
context.InputAssembler.InputLayout = InputLayout;
|
||||
|
||||
if (islines)
|
||||
{
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineList;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
}
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, SharpDX.DXGI.Format.R32_UInt, 0);
|
||||
|
||||
context.DrawIndexedInstanced(indexcount, count, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (VertexBuffer != null)
|
||||
{
|
||||
VertexBuffer.Dispose();
|
||||
VertexBuffer = null;
|
||||
}
|
||||
if (IndexBuffer != null)
|
||||
{
|
||||
IndexBuffer.Dispose();
|
||||
IndexBuffer = null;
|
||||
}
|
||||
if (InputLayout != null)
|
||||
{
|
||||
InputLayout.Dispose();
|
||||
InputLayout = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D;
|
||||
using SharpDX.Direct3D11;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using SharpDX.DXGI;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public class UnitCylinder
|
||||
{
|
||||
private Buffer VertexBuffer { get; set; }
|
||||
private Buffer IndexBuffer { get; set; }
|
||||
private InputLayout InputLayout { get; set; }
|
||||
private VertexBufferBinding vbbinding;
|
||||
private int indexcount;
|
||||
|
||||
private struct SphTri
|
||||
{
|
||||
public int v1;
|
||||
public int v2;
|
||||
public int v3;
|
||||
public SphTri(int i1, int i2, int i3)
|
||||
{
|
||||
v1 = i1;
|
||||
v2 = i2;
|
||||
v3 = i3;
|
||||
}
|
||||
}
|
||||
|
||||
public UnitCylinder(Device device, byte[] vsbytes, int detail)
|
||||
{
|
||||
|
||||
InputLayout = new InputLayout(device, vsbytes, new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||
new InputElement("NORMAL", 0, Format.R32G32B32A32_Float, 16, 0),
|
||||
});
|
||||
|
||||
|
||||
|
||||
List<Vector4> verts = new List<Vector4>();
|
||||
Dictionary<Vector4, int> vdict = new Dictionary<Vector4, int>();
|
||||
List<SphTri> curtris = new List<SphTri>();
|
||||
//List<SphTri> nxttris = new List<SphTri>();
|
||||
|
||||
verts.Add(new Vector4(0.0f, 0.0f, 0.0f, 0.0f));//top end (translated by VS!)
|
||||
verts.Add(new Vector4(0.0f, -1.0f, 0.0f, 0.0f));//top normal
|
||||
verts.Add(new Vector4(0.0f, 0.0f, 0.0f, 1.0f));//bottom end
|
||||
verts.Add(new Vector4(0.0f, 1.0f, 0.0f, 1.0f));//bottom normal
|
||||
|
||||
int nlons = detail * 4;
|
||||
int lastlon = nlons - 1;
|
||||
float latrng = 1.0f / (detail);
|
||||
float lonrng = 1.0f / (nlons);
|
||||
float twopi = (float)(2.0 * Math.PI);
|
||||
|
||||
for (int lon = 0; lon < nlons; lon++)
|
||||
{
|
||||
float tlon = lon * lonrng;
|
||||
float rlon = tlon * twopi;
|
||||
float lonx = (float)Math.Sin(rlon);
|
||||
float lonz = (float)Math.Cos(rlon);
|
||||
|
||||
verts.Add(new Vector4(lonx, 0.0f, lonz, 0.0f));//0
|
||||
verts.Add(new Vector4(0.0f, -1.0f, 0.0f, 0.0f));//top normal
|
||||
verts.Add(new Vector4(lonx, 0.0f, lonz, 0.0f));//1
|
||||
verts.Add(new Vector4(lonx, 0.0f, lonz, 0.0f));//side normal
|
||||
verts.Add(new Vector4(lonx, 0.0f, lonz, 1.0f));//2
|
||||
verts.Add(new Vector4(lonx, 0.0f, lonz, 0.0f));//side normal
|
||||
verts.Add(new Vector4(lonx, 0.0f, lonz, 1.0f));//3
|
||||
verts.Add(new Vector4(0.0f, 1.0f, 0.0f, 0.0f));//bottom normal
|
||||
}
|
||||
|
||||
for (int lon = 0; lon < nlons; lon++)
|
||||
{
|
||||
int i0 = 2 + lon * 4;// vertsperlon;//top row
|
||||
int i1 = i0 + 4;// vertsperlon;
|
||||
int i2 = i0 + 3;//bottom row
|
||||
int i3 = i2 + 4;// vertsperlon;
|
||||
int f1 = i0 + 1;
|
||||
int f2 = f1 + 4;// vertsperlon;
|
||||
|
||||
if (lon == lastlon)
|
||||
{
|
||||
i1 = 2;
|
||||
i3 = 5;// 1 + vertsperlon;
|
||||
f2 = 3;// + offs;
|
||||
}
|
||||
|
||||
|
||||
curtris.Add(new SphTri(0, i1, i0)); //top cap triangles
|
||||
|
||||
curtris.Add(new SphTri(f1, f2, f1+1));
|
||||
curtris.Add(new SphTri(f1+1, f2, f2+1)); //fill the rest
|
||||
|
||||
curtris.Add(new SphTri(1, i2, i3)); //bottom cap triangles
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
List<uint> idata = new List<uint>();
|
||||
foreach (var tri in curtris)
|
||||
{
|
||||
idata.Add((uint)tri.v1);
|
||||
idata.Add((uint)tri.v2);
|
||||
idata.Add((uint)tri.v3);
|
||||
}
|
||||
|
||||
|
||||
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, verts.ToArray());
|
||||
vbbinding = new VertexBufferBinding(VertexBuffer, 32, 0);
|
||||
|
||||
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, idata.ToArray());
|
||||
indexcount = idata.Count;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void Draw(DeviceContext context)
|
||||
{
|
||||
context.InputAssembler.InputLayout = InputLayout;
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
|
||||
context.DrawIndexed(indexcount, 0, 0);
|
||||
}
|
||||
|
||||
public void DrawInstanced(DeviceContext context, int count)
|
||||
{
|
||||
context.InputAssembler.InputLayout = InputLayout;
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
|
||||
context.DrawIndexedInstanced(indexcount, count, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (VertexBuffer != null)
|
||||
{
|
||||
VertexBuffer.Dispose();
|
||||
VertexBuffer = null;
|
||||
}
|
||||
if (IndexBuffer != null)
|
||||
{
|
||||
IndexBuffer.Dispose();
|
||||
IndexBuffer = null;
|
||||
}
|
||||
if (InputLayout != null)
|
||||
{
|
||||
InputLayout.Dispose();
|
||||
InputLayout = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D;
|
||||
using SharpDX.Direct3D11;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using SharpDX.DXGI;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public class UnitDisc
|
||||
{
|
||||
public int SegmentCount { get; set; }
|
||||
public int IndexCount { get; set; }
|
||||
public Buffer VertexBuffer { get; set; }
|
||||
public Buffer IndexBuffer { get; set; }
|
||||
|
||||
private VertexBufferBinding vbbinding;
|
||||
|
||||
public UnitDisc(Device device, int segmentCount, bool invert = false)
|
||||
{
|
||||
SegmentCount = segmentCount;
|
||||
List<Vector3> verts = new List<Vector3>();
|
||||
List<uint> inds = new List<uint>();
|
||||
verts.Add(Vector3.Zero);
|
||||
float incr = (float)Math.PI * 2.0f / segmentCount;
|
||||
for (int i = 0; i < segmentCount; i++)
|
||||
{
|
||||
float a = incr * i;
|
||||
float px = (float)Math.Sin(a);
|
||||
float py = (float)Math.Cos(a);
|
||||
verts.Add(new Vector3(px, py, 0));
|
||||
}
|
||||
for (int i = 0; i < segmentCount; i++)
|
||||
{
|
||||
uint ci = (uint)((i == 0) ? segmentCount : i);
|
||||
uint ni = (uint)i + 1;
|
||||
inds.Add(0);
|
||||
inds.Add(invert ? ni : ci);
|
||||
inds.Add(invert ? ci : ni);
|
||||
}
|
||||
IndexCount = inds.Count;
|
||||
|
||||
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, verts.ToArray());
|
||||
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, inds.ToArray());
|
||||
vbbinding = new VertexBufferBinding(VertexBuffer, 12, 0);
|
||||
}
|
||||
|
||||
|
||||
public void Draw(DeviceContext context)
|
||||
{
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
context.DrawIndexed(IndexCount, 0, 0);
|
||||
}
|
||||
public void DrawInstanced(DeviceContext context, int instcount)
|
||||
{
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
context.DrawIndexedInstanced(IndexCount, instcount, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (VertexBuffer != null)
|
||||
{
|
||||
VertexBuffer.Dispose();
|
||||
VertexBuffer = null;
|
||||
}
|
||||
if (IndexBuffer != null)
|
||||
{
|
||||
IndexBuffer.Dispose();
|
||||
IndexBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public InputElement[] GetLayout()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D;
|
||||
using SharpDX.Direct3D11;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using SharpDX.DXGI;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public class UnitQuad
|
||||
{
|
||||
public Buffer VertexBuffer { get; set; }
|
||||
public Buffer IndexBuffer { get; set; }
|
||||
|
||||
private VertexBufferBinding vbbinding;
|
||||
|
||||
public UnitQuad(Device device, bool invert = false)
|
||||
{
|
||||
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, new[]
|
||||
{
|
||||
//position (x4), texture (x2)
|
||||
-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
||||
//new Vector4(-1.0f, -1.0f, 0.0f, 1.0f), new Vector4(1.0f, -1.0f, 0.0f, 1.0f),
|
||||
//new Vector4(-1.0f, 1.0f, 0.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
|
||||
//new Vector4(-0.5f, -0.5f, 0.5f, 1.0f), new Vector4(0.5f, -0.5f, 0.5f, 1.0f),
|
||||
//new Vector4(-0.5f, 0.5f, 0.5f, 1.0f), new Vector4(0.5f, 0.5f, 0.5f, 1.0f),
|
||||
});
|
||||
if (invert)
|
||||
{
|
||||
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, new[]
|
||||
{
|
||||
0u,1u,2u,1u,3u,2u
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, new[]
|
||||
{
|
||||
0u,2u,1u,1u,2u,3u
|
||||
});
|
||||
}
|
||||
|
||||
vbbinding = new VertexBufferBinding(VertexBuffer, 24, 0);
|
||||
}
|
||||
|
||||
|
||||
public void Draw(DeviceContext context)
|
||||
{
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
context.DrawIndexed(6, 0, 0);
|
||||
}
|
||||
public void DrawInstanced(DeviceContext context, int instcount)
|
||||
{
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
context.DrawIndexedInstanced(6, instcount, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (VertexBuffer != null)
|
||||
{
|
||||
VertexBuffer.Dispose();
|
||||
VertexBuffer = null;
|
||||
}
|
||||
if (IndexBuffer != null)
|
||||
{
|
||||
IndexBuffer.Dispose();
|
||||
IndexBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public InputElement[] GetLayout()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D;
|
||||
using SharpDX.Direct3D11;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using Buffer = SharpDX.Direct3D11.Buffer;
|
||||
using SharpDX.DXGI;
|
||||
|
||||
namespace CodeWalker.Rendering
|
||||
{
|
||||
public class UnitSphere
|
||||
{
|
||||
private Buffer VertexBuffer { get; set; }
|
||||
private Buffer IndexBuffer { get; set; }
|
||||
private InputLayout InputLayout { get; set; }
|
||||
private VertexBufferBinding vbbinding;
|
||||
private int indexcount;
|
||||
|
||||
private struct SphTri
|
||||
{
|
||||
public int v1;
|
||||
public int v2;
|
||||
public int v3;
|
||||
public SphTri(int i1,int i2, int i3)
|
||||
{
|
||||
v1 = i1;
|
||||
v2 = i2;
|
||||
v3 = i3;
|
||||
}
|
||||
}
|
||||
|
||||
public UnitSphere(Device device, byte[] vsbytes, int detail)
|
||||
{
|
||||
|
||||
InputLayout = new InputLayout(device, vsbytes, new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||
//new InputElement("NORMAL", 0, Format.R32G32B32A32_Float, 16, 0),
|
||||
});
|
||||
|
||||
|
||||
|
||||
List<Vector3> verts = new List<Vector3>();
|
||||
Dictionary<Vector3, int> vdict = new Dictionary<Vector3, int>();
|
||||
List<SphTri> curtris = new List<SphTri>();
|
||||
List<SphTri> nxttris = new List<SphTri>();
|
||||
|
||||
verts.Add(new Vector3(-1.0f, 0.0f, 0.0f));
|
||||
verts.Add(new Vector3(1.0f, 0.0f, 0.0f));
|
||||
verts.Add(new Vector3(0.0f, -1.0f, 0.0f));
|
||||
verts.Add(new Vector3(0.0f, 1.0f, 0.0f));
|
||||
verts.Add(new Vector3(0.0f, 0.0f, -1.0f));
|
||||
verts.Add(new Vector3(0.0f, 0.0f, 1.0f));
|
||||
curtris.Add(new SphTri(0, 4, 2));
|
||||
curtris.Add(new SphTri(4, 1, 2));
|
||||
curtris.Add(new SphTri(1, 5, 2));
|
||||
curtris.Add(new SphTri(5, 0, 2));
|
||||
curtris.Add(new SphTri(4, 0, 3));
|
||||
curtris.Add(new SphTri(1, 4, 3));
|
||||
curtris.Add(new SphTri(5, 1, 3));
|
||||
curtris.Add(new SphTri(0, 5, 3));
|
||||
|
||||
for (int i = 0; i < verts.Count; i++)
|
||||
{
|
||||
vdict[verts[i]] = i;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < detail; i++)
|
||||
{
|
||||
nxttris.Clear();
|
||||
foreach (var tri in curtris)
|
||||
{
|
||||
Vector3 v1 = verts[tri.v1];
|
||||
Vector3 v2 = verts[tri.v2];
|
||||
Vector3 v3 = verts[tri.v3];
|
||||
Vector3 s1 = Vector3.Normalize(v1 + v2);
|
||||
Vector3 s2 = Vector3.Normalize(v2 + v3);
|
||||
Vector3 s3 = Vector3.Normalize(v3 + v1);
|
||||
int i1, i2, i3;
|
||||
if (!vdict.TryGetValue(s1, out i1))
|
||||
{
|
||||
i1 = verts.Count;
|
||||
verts.Add(s1);
|
||||
vdict[s1] = i1;
|
||||
}
|
||||
if (!vdict.TryGetValue(s2, out i2))
|
||||
{
|
||||
i2 = verts.Count;
|
||||
verts.Add(s2);
|
||||
vdict[s2] = i2;
|
||||
}
|
||||
if (!vdict.TryGetValue(s3, out i3))
|
||||
{
|
||||
i3 = verts.Count;
|
||||
verts.Add(s3);
|
||||
vdict[s3] = i3;
|
||||
}
|
||||
nxttris.Add(new SphTri(tri.v1, i1, i3));
|
||||
nxttris.Add(new SphTri(tri.v2, i2, i1));
|
||||
nxttris.Add(new SphTri(tri.v3, i3, i2));
|
||||
nxttris.Add(new SphTri(i1, i2, i3));
|
||||
}
|
||||
var cur = curtris;
|
||||
curtris = nxttris;
|
||||
nxttris = cur;
|
||||
}
|
||||
|
||||
|
||||
List<Vector4> vdata = new List<Vector4>();
|
||||
foreach (var vert in verts)
|
||||
{
|
||||
vdata.Add(new Vector4(vert, 1.0f));
|
||||
}
|
||||
|
||||
List<uint> idata = new List<uint>();
|
||||
foreach (var tri in curtris)
|
||||
{
|
||||
idata.Add((uint)tri.v1);
|
||||
idata.Add((uint)tri.v2);
|
||||
idata.Add((uint)tri.v3);
|
||||
}
|
||||
|
||||
|
||||
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, vdata.ToArray());
|
||||
vbbinding = new VertexBufferBinding(VertexBuffer, 16, 0);
|
||||
|
||||
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, idata.ToArray());
|
||||
indexcount = idata.Count;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void Draw(DeviceContext context)
|
||||
{
|
||||
context.InputAssembler.InputLayout = InputLayout;
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
|
||||
context.DrawIndexed(indexcount, 0, 0);
|
||||
}
|
||||
|
||||
public void DrawInstanced(DeviceContext context, int count)
|
||||
{
|
||||
context.InputAssembler.InputLayout = InputLayout;
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
|
||||
context.DrawIndexedInstanced(indexcount, count, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (VertexBuffer != null)
|
||||
{
|
||||
VertexBuffer.Dispose();
|
||||
VertexBuffer = null;
|
||||
}
|
||||
if (IndexBuffer != null)
|
||||
{
|
||||
IndexBuffer.Dispose();
|
||||
IndexBuffer = null;
|
||||
}
|
||||
if (InputLayout != null)
|
||||
{
|
||||
InputLayout.Dispose();
|
||||
InputLayout = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user