2016-06-04 28 views
0

그래서 저는 DirectX로 개발하는 데 매우 익숙합니다. 천천히 거기에 있습니다 ...하지만!SlimDX Direct3D9를 사용하여 스프라이트 내의 텍스처에 픽셀 쉐이더 적용

나는 이것을 가지고 Direct3D9 런타임을 인스턴스화하고, 장치를 만들고, 픽셀 쉐이더를로드한다. - 픽셀 쉐이더가로드 된 것을 확인할 수 있습니다. 1) 제게 개발되지 않은 다른 응용 프로그램에서 작동합니다. 2) 나는 부서지기 쉬우 며 모든 다양한 특성을 사용할 수 있으며 3) 오류가보고되지 않음을 알 수 있습니다.

다음은 설정입니다.

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; 

여기 Shader가 있습니다.이 장치는 광산이 아니라 테스트 할 때 사용합니다.

// 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 

이제 Shader를로드 할 때 렌더링 된 모든 출력에 적용되지만 분명히 틀렸다고 생각했습니다.

다음은 모든 2-5 밀리 초마다 발생합니다. 모든 비디오가 화면에 렌더링되어 모든 D3D 작업이 작동하지만로드 된 픽셀 쉐이더는 아무런 차이가 없습니다.

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)); 
       } 
      } 

     } 

은 내가 몇 가지 물건을보고 싶어 알고있다 - 그러나 모든 예제는 내가 렌더링 와이어 프레임과 모두와 거래를 통해 온 - 기본 lib 디렉토리에서 내가 표현하고있어 이미지와 내가 가진 모든 픽셀 버퍼입니다.

이 DirectX에 관한 내용은 모두 새로운 것이므로 매우 신중해야합니다.

+0

왜 누군가가 2016 년에 DX9를 사용 했습니까? –

+0

Sega Genesis 에뮬레이터 용 (자체 교육 프로젝트) 1. 쉽게 찾을 수 있습니다. 2. 이전 버전과의 호환성. 익스플로러 d3d11을 사용했지만 D3D9의 사용 용이성이 더 많은 것을 사용하는 이점을 능가했습니다. –

답변

0

내 프로젝트에 쉐이더 지원을 제공하는 내 꿈을 성취 할 수 없습니다 (메가 드라이브 에뮬레이터)

내가 대신 그것이 차단 렌더링해야하는 DirectX를 사용 응용 프로그램에서 출력을 할 수 있습니다 본질적으로 ReShade라는 프레임 워크를 사용 수정 된 드라이버 (d3d9.dll)가이 훅을 사용하면 HLSL의 변형을 사용하여 미리 컴파일 된 쉐이더를로드 할 수 있습니다.

응용 프로그램 디렉토리에 드라이버를 놓기 만하면 DirectX에 대한 호출이이 드라이버에서 관리됩니다.

결과가 즉시 나타납니다.

Resahde Website

0

너는 현명한 출력을 기대해서는 안되기 때문에 uniforms/shader 변수를 설정하지 않았다. 나는 당신이 극단적 인 스캔 라인을 가져야하므로 uIntensity가 0이 될 것이라고 예상 할 것입니다. 그러나 1.0이 될 수도 있습니다 (이 경우에는 볼 수 없습니다). 그리고 다시, 스캔 라인을 적용한 후 윈도우 크기가 50 %로 축소 된 경우 , 당신은 scanlines을 보지 못할 수도 있습니다.

즉, 더 간단한 픽셀 쉐이더로 테스트하지 마십시오. float4 (1,0,0,1);을 반환하는 픽셀 쉐이더로 테스트하십시오.

+0

감사합니다. 불행히도 예상되는 매개 변수를 제공하는 것은 여전히 ​​마음이 아프다. (나는 결코 쉐이더를 다루지 않았다 - 지금까지) 대신 프레임 워크를 사용했다. ReShade는 즉각적인 재현을 주었다. –