2016-06-04 14 views
0

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.

+0

Warum zum Teufel sollte jemand DX9 im Jahr 2016 verwenden? –

+0

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

Antwort

0

Ich konnte nicht mein Traum erfüllen Shader-Unterstützung in meinem Projekt (Sega Genesis Emulator)

I verwendet stattdessen einen Rahmen genannt ReShade im Wesentlichen ermöglicht es Ausgabe von einer DirectX-fähige Anwendung bei der Bereitstellung seiner render abgefangen haben Durch einen modifizierten Treiber (d3d9.dll) ermöglicht dieser Hook das Laden vorkompilierter Shader mit einer HLSL-Variante.

Sie den Treiber einfach im Anwendungsverzeichnis löschen, dann werden alle Aufrufe von DirectX von diesem Treiber verwaltet.

Ich hatte sofort Ergebnisse.

Resahde Website

0

Sie haben die Uniformen/Shader-Variablen nicht gesetzt, so dass Sie keine vernünftige Ausgabe erwarten sollten. Ich denke, ich würde erwarten, dass uIntensity 0 ist, also sollten Sie extreme Scanlinien bekommen, aber ich denke, es könnte auch 1.0 sein (in diesem Fall würden Sie es nicht sehen.) Wenn Ihr Fenster nach dem Anwenden von Scanlinien um 50% verkleinert wird Möglicherweise sehen Sie die Scanlinien nicht.

Kurz gesagt, testen Sie nicht mit solch einem einfacheren Pixelshader. Testen Sie mit einem Pixelshader, der float4 (1,0,0,1); zurückgibt.

+0

Danke. Leider ist das Bereitstellen der erwarteten Parameter für mich immer noch überwältigend (ich habe mich noch nie mit Shadern beschäftigt - Ever) Ich habe stattdessen ein Framework verwendet - ReShade, das mir sofortige Ergebnisse lieferte –