首先,我是一个完整的 DirectX 菜鸟。我正在将位图加载到表面中,并且需要在显示之前对其应用 HLSL 效果。目标是在图像上显示实时效果。无论出于何种原因,图像显示但没有效果。
我认为这可能与我将表面拉伸到后缓冲区并规避效果有关,但我不知道如何解决它。最终,这个表面将包含一个立体图像对加上 Nvidia 的立体图像签名,以便它与 3D Vision 一起使用。虽然这对这个问题无关紧要,但它可以解释为什么我使用表面,而其他方法可能更好。
这是我的代码:
在表格中:
public partial class frmMain : Form
{
private Device device;
private Effect effect = null;
private Surface ImageSurface;
private Rectangle ImageSize;
public frmMain()
{
InitializeComponent();
}
public bool InitializeGraphics()
{
//Get Bitmap
Bitmap MyImage = (Bitmap)Bitmap.FromFile(@"C:\test\OD_1_L.jpg");
ImageSize = new Rectangle(0, 0, MyImage.Width, MyImage.Height);
//Set Presentation Parameters
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.AutoDepthStencilFormat = DepthFormat.D16;
presentParams.EnableAutoDepthStencil = true;
presentParams.BackBufferFormat = Format.A8R8G8B8;
presentParams.BackBufferCount = 1;
presentParams.BackBufferWidth = MyImage.Width;
presentParams.BackBufferHeight = MyImage.Height;
presentParams.PresentationInterval = PresentInterval.One;
bool canDoShaders = true;
//Determine whether or not the hardware can support shaders...
Caps hardware = Manager.GetDeviceCaps(0, DeviceType.Hardware);
if (hardware.VertexShaderVersion >= new Version(1, 1))
{
//Default to software processing
CreateFlags flags = CreateFlags.SoftwareVertexProcessing;
//Use hardware if it's available
if (hardware.DeviceCaps.SupportsHardwareTransformAndLight)
{
flags = CreateFlags.HardwareVertexProcessing;
}
//Use pure if it's available
if (hardware.DeviceCaps.SupportsPureDevice)
{
flags |= CreateFlags.PureDevice;
}
//Create Device
device = new Device(0, DeviceType.Hardware, this, flags, presentParams);
//Create effect
effect = Effect.FromFile(device, @"..\..\invert.fx", null, ShaderFlags.None, null);
effect.Technique = "InvertTechnique";
}
else
{
//No Shader Support
canDoShaders = false;
//Create a reference device
device = new Device(0, DeviceType.Reference, this, CreateFlags.SoftwareVertexProcessing, presentParams);
}
//Create Image Surface...
ImageSurface = Surface.FromBitmap(device, MyImage, Pool.Default);
return canDoShaders;
}
protected override void OnPaintBackground(PaintEventArgs e)
{
//do nothing
}
protected override void OnPaint(PaintEventArgs e)
{
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.CornflowerBlue, 1.0f, 0);
Surface backbuffer = device.GetBackBuffer(0, 0, BackBufferType.Mono);
device.BeginScene();
int numPasses = effect.Begin(0);
for (int i = 0; i < numPasses; i++)
{
effect.BeginPass(i);
device.StretchRectangle(ImageSurface, ImageSize, backbuffer, ImageSize, TextureFilter.None);
effect.EndPass();
}
effect.End();
device.EndScene();
device.Present();
this.Invalidate();
}
}
在着色器中:
sampler2D input : register(s0);
float inversionAmount : register(c0);
float4 Invert(float2 uv : TEXCOORD) : COLOR {
float4 color;
color = tex2D(input, uv.xy);
//this changes inversion
float4 inverted_color = 1 - color;
inverted_color.a = color.a;
inverted_color.rgb *= inverted_color.a;
return inverted_color;
}
technique InvertTechnique
{
pass P0
{
CullMode = None;
// shaders
VertexShader = null;
PixelShader = compile ps_1_1 Invert();
}
}