使用SlimDX.Windows.RenderForm,我想动态创建一个美国地图的纹理,将该纹理复制到其他两个纹理中,然后在每个纹理上绘制唯一的雷达数据。然后,我将把这两个纹理传递给每个被绘制在自己的Windows.Forms.Panel上。这样,用户将能够,例如,查看基础反射率和基础速度并排在两个面板。现在,我已经成功地在纹理上生成了我的美国地图。但是当我试图把它渲染到面板上时,我会变黑(顺便说一句,我清晰的颜色是柔和的灰色,而不是黑色)。
编辑:经过一些操作之后,我修改了我的代码,以获取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);
}发布于 2014-06-14 10:47:31
这里有很多东西。
首先,每个渲染器创建一个设备,这是不必要的,您可以在同一设备上呈现所有内容。
要创建设备,请执行以下操作:
Device device = new Device(DriverType.Hardware,DeviceCreationFlags.Debug);然后您可以使用相同的设备创建多个交换链(每个面板一个)。
SwapChain swapchain = new SwapChain(device.Factory, device, chainDescription);第二个问题,您的四边形缺少纹理坐标,所以您将无法显示纹理使用它。请注意,您当然只需要每个设备一个四位数,您不需要一个每个渲染器。
DataStream data = new DataStream(20 * 4, true, true);
data.Write(new Vector3(-0.9f, -0.9f, 0.0f));
data.Write(new Vector2(0.0f,1.0f));
data.Write(new Vector3(-0.9f, 0.9f, 0.0f));
data.Write(new Vector2(0.0f,0.0f));
data.Write(new Vector3(0.9f, -0.9f, 0.0f));
data.Write(new Vector2(1.0f,1.0f));
data.Write(new Vector3(0.9f, 0.9f, 0.0f));
data.Write(new Vector2(1.0f,0.0f));
data.Position = 0;您的输入布局已经考虑到纹理坐标,所以您不需要修改它。
接下来,在顶点着色器中不使用任何投影矩阵,所以除非您计划这样做,否则可以忽略该代码。
最后,使用单个设备,确保设备上下文调用在呈现函数中,例如:
public override void Render(int inCount = -1)
{
Context.OutputMerger.SetTargets(RenderTarget);
Context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, 12, 0));
Context.InputAssembler.SetIndexBuffer(indexBuffer, Format.R32_UInt, 0);
Context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
Context.InputAssembler.InputLayout = Layout;
Context.VertexShader.Set(VertexShader);
Context.PixelShader.Set(PixelShader);
Context.PixelShader.SetSampler(SamplerState, 0);
Context.VertexShader.SetConstantBuffer(MatrixBuffer, 0);
Context.PixelShader.SetShaderResource(resourceView, 0);
Context.DrawIndexed(4, 0, 0);
}最后,您当然需要在着色器中传递纹理坐标,以便正确地对纹理进行采样:
struct vsInput
{
float4 position: POSITION;
float2 texCoord: TEXCOORD0;
};
struct psInput
{
float4 posScreen : SV_POSITION;
float2 texCoord : TEXCOORD0;
};
Texture2D texture : register(t0);
SamplerState linearSampler : register(s0);
psInput VS(vsInput input)
{
psInput output;
output.posScreen = input.position;
output.texCoord = input.texCoord;
return output;
}
float4 PS(psInput input): SV_Target
{
return texture.Sample(linearSampler, input.texCoord);
}https://stackoverflow.com/questions/24212019
复制相似问题