Also, ich bin sehr neu in der Entwicklung mit DirectX, ich komme langsam dahin ... Aber!Anwenden eines Pixel-Shaders auf eine Textur in einem Sprite mit SlimDX Direct3D9
Ich habe dies instanziiert die Direct3D9 Laufzeit, erstellt ein Gerät und lädt einen Pixel Shader. - Ich kann bestätigen, dass der Pixel-Shader geladen ist. 1) Es funktioniert in anderen Anwendungen, die nicht von mir entwickelt wurden. 2) Ich kann brechen und sehe, dass alle verschiedenen Funktionen verfügbar sind und 3) keine Fehler gemeldet werden.
Hier ist das Setup.
Direct3DInstance = new SlimDX.Direct3D9.Direct3D();
SlimDX.Direct3D9.PresentParameters PP = new SlimDX.Direct3D9.PresentParameters();
PP.Windowed = true;
PP.BackBufferHeight = PAN_Video.ClientSize.Height;
PP.BackBufferWidth = PAN_Video.ClientSize.Width;
PP.BackBufferCount = 0;
PP.BackBufferFormat = SlimDX.Direct3D9.Format.R5G6B5;
PP.PresentationInterval = SlimDX.Direct3D9.PresentInterval.Immediate;
PP.DeviceWindowHandle = PAN_Video.Handle;
Direct3DDevice = new SlimDX.Direct3D9.Device(Direct3DInstance, 0, SlimDX.Direct3D9.DeviceType.Hardware, PAN_Video.Handle, SlimDX.Direct3D9.CreateFlags.HardwareVertexProcessing, PP);
string error = null;
SlimDX.Direct3D9.ShaderBytecode SBC = SlimDX.Direct3D9.ShaderBytecode.Compile(File.ReadAllText(@"C:\Users\Marcus\Desktop\scanlines.txt"), null, null, "main", "ps_3_0", SlimDX.Direct3D9.ShaderFlags.UseLegacyD3DX9_31Dll, out error);
SlimDX.Direct3D9.PixelShader PS = new SlimDX.Direct3D9.PixelShader(Direct3DDevice, SBC);
Direct3DDevice.PixelShader = PS;
Hier ist der Shader - es ist nicht meins, aber ich benutze, um mit zu testen.
// hlslf output by Cg compiler
// cgc version 3.1.0013, build date Apr 18 2012
// command line args: -profile hlslf -po version=110
//vendor NVIDIA Corporation
//version 3.1.0.13
//profile hlslf
//program main_fragment
//semantic main_fragment.s_p : TEXUNIT0
//semantic uIntensity
//var sampler2D s_p : TEXUNIT0 : _s_p 0 : 2 : 1
//var float uIntensity : : _uIntensity : -1 : 1
//var float2 texcoord : $vin.TEXCOORD0 : TEXCOORD0 : 0 : 1
//var float2 wpos : $vin.WPOS : WPOS : 1 : 1
//var float4 main_fragment : $vout.COLOR : COLOR : -1 : 1
//default uIntensity = 100
#
pragma pack_matrix(row_major)
struct input
{
float2 _video_size;
float2 _texture_size;
float2 _output_size;
};
float _TMP1;
float _TMP0;
uniform float _uIntensity;
// main procedure, the original name was main_fragment
float4 main(in float2 _texcoord: TEXCOORD0, in float2 _wpos: VPOS, uniform sampler2D _s_p: TEXUNIT0): COLOR0
{
float4 _temp;
_temp = tex2D(_s_p, _texcoord);
_TMP0 = floor(_wpos.y/2.00000000000000000E000 f);
_TMP1 = floor(_wpos.y);
if(_TMP0 != _TMP1/2.00000000000000000E000 f)
{ // if begin
_temp.xyz = _temp.xyz * _uIntensity;
} // end if
return _temp;
} // main end
Nun, dachte ich, sobald Sie einen Shader laden Sie es auf alle gerenderte Ausgabe angewendet wird, aber natürlich bin ich falsch.
Unten ist, was passiert alle 2-5 Millisekunden - alle Video wird auf dem Bildschirm gerendert, so dass alle D3D Zeug funktioniert, aber der geladene Pixel-Shader macht keinen Unterschied.
Interface.VideoInfo VI = Interface.EX_GetVideoBuffer();
Direct3DDevice.Clear(SlimDX.Direct3D9.ClearFlags.Target, Color.Black, 1.0f, 0);
using (System.Drawing.Bitmap WindowsBMP = new System.Drawing.Bitmap(VI.Width, VI.Height, VI.Stride, System.Drawing.Imaging.PixelFormat.Format16bppRgb565, VI.Buffer))
{
BitmapData WindowsBPMData = WindowsBMP.LockBits(new Rectangle(0, 0, VI.Width, VI.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
byte[] Data = new byte[WindowsBPMData.Stride * WindowsBPMData.Height];
Marshal.Copy(WindowsBPMData.Scan0, Data, 0, Data.Length);
WindowsBMP.UnlockBits(WindowsBPMData);
using (SlimDX.Direct3D9.Texture TEX = new SlimDX.Direct3D9.Texture(Direct3DDevice, WindowsBPMData.Width, WindowsBPMData.Height, 0, SlimDX.Direct3D9.Usage.None, SlimDX.Direct3D9.Format.A8R8G8B8, SlimDX.Direct3D9.Pool.Managed))
{
DataRectangle DR = TEX.LockRectangle(0, SlimDX.Direct3D9.LockFlags.Discard);
DR.Data.Position = 0;
DR.Data.Write(Data, 0, Data.Length);
DR.Data.Close();
TEX.UnlockRectangle(0);
using (SlimDX.Direct3D9.Sprite S = new SlimDX.Direct3D9.Sprite(Direct3DDevice))
{
Direct3DDevice.BeginScene();
S.Begin(SlimDX.Direct3D9.SpriteFlags.None);
S.Draw(TEX, Color.Transparent);
S.End();
Direct3DDevice.EndScene();
Direct3DDevice.Present(new Rectangle(0, 0, WindowsBPMData.Width, WindowsBPMData.Height), new Rectangle(0, 0, PAN_Video.Width, PAN_Video.Height));
}
}
}
Ich weiß, dass ich ein paar Sachen bin fehlt - aber alle Beispiele, die ich habe über Deal mit Rendering-Wireframes kommen und gleich - ich bin Rendern von Bildern aus einem nativen Lib und alles, was ich habe, ist die Pixel-Buffer.
Bitte seien Sie vorsichtig, da dieses DirectX-Zeug für mich sehr neu ist.
Warum zum Teufel sollte jemand DX9 im Jahr 2016 verwenden? –
Es ist für einen Sega Genesis Emulator (selbstlernendes Projekt) 1. Ich fand es einfacher, 2. Rückwärtskompatibilität. Ich habe Explorer d3d11, aber die Benutzerfreundlichkeit mit D3D9 überwog die Vorteile der Verwendung von etwas aktueller. –