2016-06-04 4 views
0

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.

+0

Pourquoi diable voudrait-on utiliser DX9 en 2016? –

+0

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. –

Répondre

0

Je ne pouvais pas réaliser mon rêve en fournissant un soutien shader dans mon projet (Sega Genesis Emulator)

I utilisé à la place d'un cadre appelé ReShade, en substance, il permet la sortie d'un DirectX activé l'application d'avoir son render interceptés Par un pilote modifié (d3d9.dll), ce hook permet de charger des shaders précompilés en utilisant une variante de HLSL. Il vous suffit de supprimer le pilote dans le répertoire des applications, puis tous les appels à DirectX sont gérés par ce pilote.

J'ai eu des résultats instantanément.

Resahde Website

0

Vous n'avez pas défini les variables uniformes/shaders, vous ne devriez donc pas vous attendre à une sortie sensible. J'imagine que je devrais avoir uIntensity à 0 donc vous devriez obtenir des scanlines extrêmes, mais je suppose que cela pourrait aussi être 1.0 (auquel cas vous ne le verriez pas.) Puis encore, si votre fenêtre est réduite de 50% après application de scanlines , vous pourriez ne pas voir les lignes de balayage. En bref, ne testez pas avec un pixel shader plus simple. Testez avec un pixel shader qui renvoie float4 (1,0,0,1) ;.

+0

Merci. Malheureusement fournir les paramètres attendus est toujours ahurissant pour moi (je n'ai jamais traité avec les shaders - Ever) J'ai plutôt utilisé un cadre - ReShade, qui m'a donné des résulats instantanés –