2016-06-04 23 views
0

Итак, я очень новичок в разработке с DirectX, я медленно туда попал ... Но!Применение пикселя Shader к текстуре внутри спрайта с помощью 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; 

Вот Шейдер - его не мое, а одно, которое я использую для тестирования.

// 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, и все у меня есть, Pixel Buffer.

Пожалуйста, будьте нежны, поскольку этот материал DirectX для меня очень новый.

+0

Почему, черт возьми, кто-то использует DX9 в 2016 году? –

+0

Его для эмулятора Sega Genesis (проект самообучения) 1. Мне было проще, 2. Обратная совместимость. Я сделал проводник d3d11, но простота использования с D3D9 перевешивала преимущества использования чего-либо более актуального. –

ответ

0

Я не мог исполнить свою мечту в обеспечении поддержки шейдеров в моем проекте (Sega Genesis Emulator)

вместо этого я использовал базу под названием Reshade, в сущности, это позволяет выход из приложения DirectX позволил иметь свой рендер перехвачены измененным драйвером (d3d9.dll), этот крючок позволяет загружать предварительно скомпилированные шейдеры, используя переменную HLSL.

Вы просто бросаете драйвер в каталог приложений, тогда все вызовы DirectX управляются этим драйвером.

У меня были результаты мгновенно.

Resahde Website

0

Вы не установили переменные униформы/шейдера, чтобы не ожидать ожидаемого результата. Думаю, я ожидал бы, что uIntensity будет 0, поэтому вы должны получить экстремальные строки сканирования, но я думаю, что это тоже может быть 1.0 (в этом случае вы его не увидите). Затем снова, если ваше окно будет уменьшено на 50% после применения строк сканирования , вы можете не видеть строки сканирования.

Короче говоря, не тестируйте с помощью такого более простого пиксельного шейдера. Тест с пиксельным шейдером, который возвращает float4 (1,0,0,1) ;.

+0

Спасибо. К сожалению, при условии, что ожидаемые параметры по-прежнему остаются ошеломляющими для меня (я никогда не сталкивался с шейдерами - когда-либо) Вместо этого я использовал фреймворк - ReShade, который дал мне мгновенные результаты –

 Смежные вопросы

  • Нет связанных вопросов^_^