Donc, je suis très nouveau dans le développement avec DirectX, j'arrive lentement là-bas ... Mais!Appliquer un pixel Shader à une texture dans un sprite avec SlimDX Direct3D9
J'ai ceci qui instancie l'exécution de Direct3D9, crée un périphérique et charge un Pixel Shader. - Je peux confirmer que le pixel shader est chargé comme 1) ça marche dans d'autres applications que je n'ai pas développées. 2) Je peux casser et voir que toutes les différentes porperties sont disponibles et 3) aucune erreur n'est signalée.
Voici la configuration.
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;
Voici le Shader - ce n'est pas le mien mais celui que j'utilise pour tester.
// 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
Maintenant, je pensais que le moment où vous chargez un Shader il est appliqué à toutes les sorties rendu, mais il est évident que je me trompe. Vous trouverez ci-dessous ce qui se passe chaque 2-5 millisecondes - toutes les vidéos sont restituées à l'écran pour que tout le contenu de D3D fonctionne, mais le pixel shader chargé ne fait aucune différence.
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));
}
}
}
Je sais que je manque quelques trucs - mais tous les exemples que je suis venu à travers avec beaucoup de rendu et wireframes aussi bien - je le rendu des images à partir d'un Lib natif et tout ce que j'ai est le tampon Pixel.
S'il vous plaît soyez gentil car ce truc DirectX est tout nouveau pour moi.
Pourquoi diable voudrait-on utiliser DX9 en 2016? –
Son pour un émulateur Sega Genesis (projet d'auto-enseignement) 1. Je l'ai trouvé plus facile, 2. Rétrocompatibilité. J'ai fait l'explorateur d3d11 mais la facilité d'utilisation avec D3D9 l'emportait sur les avantages d'utiliser quoi que ce soit de plus courant. –