【发布时间】:2014-06-13 18:45:56
【问题描述】:
使用 SlimDX.Windows.RenderForm,我想动态创建美国地图的纹理,将该纹理复制到其他 2 个纹理,然后在每个纹理上绘制独特的雷达数据。然后我将传递这 2 个纹理,每个纹理都在其自己的 Windows.Forms.Panel 上绘制。这样,用户将能够例如在 2 个面板中并排查看基本反射率和基本速度。现在,我已经成功地将我的美国地图生成到纹理上。但是当我尝试将它渲染到面板时,我得到了黑色(顺便说一句,我的清晰颜色是柔和的灰色,而不是黑色)。
编辑:经过一番尝试,我修改了我的代码以获取 TextureRenderer 正在使用的纹理,将其转换为流,并在 RuntimeRenderer 的设备下创建一个新的纹理。现在我有一个柔和的灰色正方形,里面有一个黄色正方形(与我用于顶点的 -0.9、-0.9... 0.9、0.9 兼容)。我知道新的纹理是正确的,但正方形仍然是黄色的。
这是我的代码:
using SlimDX;
using SlimDX.D3DCompiler;
using SlimDX.Direct3D11;
using SlimDX.DXGI;
using SlimDX.Windows;
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using Device = SlimDX.Direct3D11.Device;
using Buffer = SlimDX.Direct3D11.Buffer;
using Resource = SlimDX.Direct3D11.Resource;
using Format = SlimDX.DXGI.Format;
using MapFlags = SlimDX.Direct3D11.MapFlags;
namespace Radar
{
abstract public class Renderer
{
protected Device mDevice = null;
protected SwapChain mSwapChain = null;
protected RenderTargetView RenderTarget { get; set; }
public Device Device { get { return mDevice; } protected set { mDevice = value; } }
public DeviceContext Context { get { return Device.ImmediateContext; } }
protected SwapChain SwapChain { get { return mSwapChain; } set { mSwapChain = value; } }
protected int RenderTargetIndex { get; set; }
protected VertexShader VertexShader { get; set; }
protected PixelShader PixelShader { get; set; }
protected Buffer VertexBuffer { get; set; }
protected Buffer MatrixBuffer { get; set; }
protected InputLayout Layout { get; set; }
protected ShaderSignature InputSignature { get; set; }
protected SamplerState SamplerState { get; set; }
protected void CreateDevice(IntPtr inHandle)
{
SwapChainDescription chainDescription = new SwapChainDescription()
{
BufferCount = 2,
Usage = Usage.RenderTargetOutput,
OutputHandle = inHandle,
IsWindowed = true,
ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm),
SampleDescription = new SampleDescription(1, 0),
Flags = SwapChainFlags.AllowModeSwitch,
SwapEffect = SwapEffect.Discard
};
Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, chainDescription, out mDevice, out mSwapChain);
}
protected void SetupViewport(int inWidth, int inHeight)
{
Viewport viewport = new Viewport(0.0f, 0.0f, inWidth, inHeight);
Context.OutputMerger.SetTargets(RenderTarget);
Context.Rasterizer.SetViewports(viewport);
}
public void Clear()
{
Context.ClearRenderTargetView(RenderTarget, new Color4(0.117f, 0.117f, 0.117f));
}
public void Present()
{
SwapChain.Present(0, PresentFlags.None);
}
public virtual void Dispose()
{
SamplerState.Dispose();
VertexBuffer.Dispose();
Layout.Dispose();
InputSignature.Dispose();
VertexShader.Dispose();
PixelShader.Dispose();
RenderTarget.Dispose();
SwapChain.Dispose();
Device.Dispose();
}
public class RenderTargetParameters
{
public int Width { get; set; }
public int Height { get; set; }
public IntPtr Handle { get; set; }
public RenderTargetParameters()
{
Width = 0;
Height = 0;
Handle = new IntPtr(0);
}
}
// the inCount parameter is used in the TextureRenderer, but not in the code I've given
public abstract void Render(int inCount = -1);
public abstract void Prepare(string inShaderName = null);
}
// I use this to render the texture. This is working fine
public class TextureRenderer : Renderer
{
.
.
.
}
public class RuntimeRenderer : Renderer
{
public TextureRenderer TextureRenderer { get; protected set; }
public RuntimeRenderer(RenderTargetParameters inParms, ref TextureRenderer inTextureRenderer)
{
CreateDevice(inParms.Handle);
TextureRenderer = inTextureRenderer;
// I save to a file to make sure the texture is what it should be (and it is)
TextureRenderer.Save();
using (Resource resource = Resource.FromSwapChain<Texture2D>(SwapChain, 0))
RenderTarget = new RenderTargetView(Device, resource);
SetupViewport(inParms.Width, inParms.Height);
using (var factory = SwapChain.GetParent<Factory>())
factory.SetWindowAssociation(inParms.Handle, WindowAssociationFlags.IgnoreAltEnter);
}
public override void Prepare(string inShaderName)
{
DataStream data = new DataStream(12 * 4, true, true);
data.Write(new Vector3(-0.9f, -0.9f, 0.0f));
data.Write(new Vector3(-0.9f, 0.9f, 0.0f));
data.Write(new Vector3(0.9f, -0.9f, 0.0f));
data.Write(new Vector3(0.9f, 0.9f, 0.0f));
data.Position = 0;
DataStream indices = new DataStream(sizeof(int) * 4, true, true);
indices.Write(0);
indices.Write(1);
indices.Write(2);
indices.Write(3);
indices.Position = 0;
VertexBuffer = new Buffer(Device, data, (int)data.Length, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
Buffer indexBuffer = new Buffer(Device, indices, (int)indices.Length, ResourceUsage.Default, BindFlags.IndexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
Context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, 12, 0));
Context.InputAssembler.SetIndexBuffer(indexBuffer, Format.R32_UInt, 0);
Context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
using (ShaderBytecode bytecode = ShaderBytecode.CompileFromFile("ShaderFX.fx", "SimpleVertexShader", "vs_5_0", ShaderFlags.Debug, EffectFlags.None))
{
InputSignature = ShaderSignature.GetInputSignature(bytecode);
VertexShader = new VertexShader(Device, bytecode);
}
using (ShaderBytecode bytecode = ShaderBytecode.CompileFromFile("ShaderFX.fx", "SimplePixelShader", "ps_5_0", ShaderFlags.Debug, EffectFlags.None))
PixelShader = new PixelShader(Device, bytecode);
InputElement[] inputEl = new InputElement[2];
inputEl[0].SemanticName = "POSITION";
inputEl[0].SemanticIndex = 0;
inputEl[0].Format = Format.R32G32B32_Float;
inputEl[0].Slot = 0;
inputEl[0].AlignedByteOffset = 0;
inputEl[0].Classification = InputClassification.PerVertexData;
inputEl[0].InstanceDataStepRate = 0;
inputEl[1].SemanticName = "TEXCOORD";
inputEl[1].SemanticIndex = 0;
inputEl[1].Format = Format.R32G32_Float;
inputEl[1].Slot = 0;
inputEl[1].AlignedByteOffset = InputElement.AppendAligned;
inputEl[1].Classification = InputClassification.PerVertexData;
inputEl[1].InstanceDataStepRate = 0;
Layout = new InputLayout(Device, InputSignature, inputEl);
BufferDescription matrixDescription = new BufferDescription()
{
Usage = ResourceUsage.Dynamic,
SizeInBytes = sizeof(float) * 16 * 3,
BindFlags = BindFlags.ConstantBuffer,
CpuAccessFlags = CpuAccessFlags.Write,
OptionFlags = ResourceOptionFlags.None,
StructureByteStride = 0
};
MatrixBuffer = new Buffer(Device, matrixDescription);
ShaderResourceViewDescription resourceViewDescription = new ShaderResourceViewDescription()
{
Format = TextureRenderer.Texture.Description.Format,
Dimension = ShaderResourceViewDimension.Texture2D,
MipLevels = TextureRenderer.Texture.Description.MipLevels,
MostDetailedMip = 0
};
ShaderResourceView resourceView = new ShaderResourceView(Device, TextureRenderer.Texture, resourceViewDescription);
SamplerDescription samplerDescription = new SamplerDescription()
{
Filter = Filter.MinMagMipLinear,
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
MipLodBias = 0.0f,
MaximumAnisotropy = 1,
ComparisonFunction = Comparison.Always,
BorderColor = new Color4(0, 0, 0, 0),
MinimumLod = 0,
MaximumLod = 99999
};
SamplerState = SamplerState.FromDescription(Device, samplerDescription);
Context.InputAssembler.InputLayout = Layout;
Context.VertexShader.Set(VertexShader);
Context.PixelShader.Set(PixelShader);
Context.PixelShader.SetSampler(SamplerState, 0);
Vector3 position = new Vector3(0.0f, 0.0f, 10.0f);
Vector3 target = new Vector3(0.0f, 0.0f, 0.0f);
Matrix view = Matrix.LookAtLH(position, target, Vector3.UnitY);
Matrix projection = Matrix.PerspectiveFovLH((float)(Math.PI / 4.0), 1.0f, 0.0f, 100.0f);
Matrix world = Matrix.Identity;
DataBox dataBox = Context.MapSubresource(MatrixBuffer, MapMode.WriteDiscard, MapFlags.None);
dataBox.Data.Write(world);
dataBox.Data.Write(view);
dataBox.Data.Write(projection);
Context.UnmapSubresource(MatrixBuffer, 0);
Context.VertexShader.SetConstantBuffer(MatrixBuffer, 0);
Context.PixelShader.SetShaderResource(resourceView, 0);
}
public override void Render(int inCount = -1)
{
Context.DrawIndexed(4, 0, 0);
}
}
}
这是我的着色器文件 (ShaderFX.fx):
float4 VShader(float4 position : POSITION) : SV_POSITION
{
return position;
}
float4 PShader_Counties(float4 position : SV_POSITION) : SV_Target
{
return float4(0.5f, 0.5f, 0.5f, 1.0f);
}
float4 PShader_States(float4 position : SV_POSITION) : SV_Target
{
return float4(0.883f, 0.883f, 0.883f, 1.0f);
}
struct VertexShaderInput
{
float2 pos : POSITION;
};
struct PixelShaderInput
{
float4 pos : SV_POSITION;
};
PixelShaderInput SimpleVertexShader(VertexShaderInput input)
{
PixelShaderInput vertexShaderOutput;
vertexShaderOutput.pos = float4(input.pos, 0.5f, 1.0f);
return vertexShaderOutput;
}
float4 SimplePixelShader(PixelShaderInput input) : SV_TARGET
{
return float4(1.0f, 1.0f, 0.0f, 1.0f);
}
【问题讨论】:
标签: winforms directx-11 slimdx