[英]Apply pixel shader to video with DirectX
我需要将一个像素着色器应用于此代码(全屏四边形)。 我有FX文件。 程序是什么? (编辑完成:代码正常工作)
public int CompositeImage(IntPtr pD3DDevice, IntPtr pddsRenderTarget, AMMediaType pmtRenderTarget, long rtStart, long rtEnd, int dwClrBkGnd, VMR9VideoStreamInfo[] pVideoStreamInfo, int cStreams)
{
try
{
if (udevice != pD3DDevice)
{
InitCompositionDevice(pD3DDevice);
}
// will be creating managed object from those so increment ref count
Marshal.AddRef(pddsRenderTarget);
Marshal.AddRef(pVideoStreamInfo[0].pddsVideoSurface);
device.Clear(ClearFlags.Target, Color.Red, 1f, 0);
device.BeginScene();
// here the video frame will be stored
Texture capturedVideoTexture = null;
// this is the output surface
Surface renderTarget = new Surface(pddsRenderTarget);
// get the surface for the input video
Surface videoSurface = new Surface(pVideoStreamInfo[0].pddsVideoSurface);
// will use this rect for calculations
Rectangle videoSurfaceRect = new Rectangle(0, 0, videoSurface.Description.Width, videoSurface.Description.Height);
// create single layer texture from input video
capturedVideoTexture = new Texture(device, videoSurfaceRect.Width, videoSurfaceRect.Height, 1, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default);
// get its surface
Surface textureSurface = capturedVideoTexture.GetSurfaceLevel(0);
// will use this rect for calculations
Rectangle textureSurfaceRect = new Rectangle(0, 0, textureSurface.Description.Width, textureSurface.Description.Height);
// copy the whole video surface into the texture surface
device.StretchRectangle(videoSurface, videoSurfaceRect, textureSurface, textureSurfaceRect, TextureFilter.Linear);
// identity matreices for world projection and view
device.Transform.World = Matrix.Identity;
device.Transform.Projection = Matrix.Identity;
device.Transform.View = Matrix.Identity;
// setup viewport
Viewport view = new Viewport();
view.X = 0;
view.Y = 0;
view.Width = 1920;
view.Height = 1080;
view.MinZ = 0;
view.MaxZ = 1;
device.Viewport = view;
// writing will go to output surface
device.SetRenderTarget(0, renderTarget);
// nothing fancy of a vertex shader
device.VertexFormat = CustomVertex.PositionTextured.Format;
// use the texture while rendering
device.SetTexture(0, capturedVideoTexture);
//Bind our Vertex Buffer
device.SetStreamSource(0, vb, 0);
// setup and apply shader
ps.Begin(FX.None);
ps.BeginPass(0);
ps.SetValue("ScreenTexture", capturedVideoTexture);
//Render from our Vertex Buffer
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
ps.EndPass();
ps.End();
device.EndScene();
videoSurface.Dispose();
textureSurface.Dispose();
capturedVideoTexture.Dispose();
renderTarget.Dispose();
videoSurface = null;
renderTarget = null;
capturedVideoTexture = null;
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
return 0;
}
这是最终实现的效果:乌贼属关于VMR9视频:
现在剩下的就是3D内容的立体阴影着色器的代码:)
从视频帧创建纹理,然后LockRect它并复制数据。现在您拥有D3D9纹理中的数据。
加载像素着色器很容易。 使用D3DXCreateEffectFromFile 。
通过查看互联网上的任何教程,可以轻松学习渲染带有纹理的四边形。 试试这个:
http://www.drunkenhyena.com/cgi-bin/view_cpp_article.pl?chapter=2;article=30
如果您将其设置为正确,效果将自动应用于四边形。
编辑:从查看代码看,您不会设置世界,视图或投影矩阵。 你也没有设置视口。
首先,您应该将它们设置为所有矩阵以进行标识。 这意味着您传入的顶点将在没有任何更改的情况下在管道中移动。 然后你需要记住,“投影”空间从-1到1(从左到右从下到上)。
因此,您需要按如下方式定义四边形:
ver[0] = new CustomVertex.PositionTextured(-1, 1, 0, 0, 0);
ver[1] = new CustomVertex.PositionTextured(1, 1, 0, 1, 0);
ver[2] = new CustomVertex.PositionTextured(-1, -1, 0, 0, 1);
ver[3] = new CustomVertex.PositionTextured(1, 1, 0, 1, 0);
ver[4] = new CustomVertex.PositionTextured(1, -1, 0, 1, 1);
ver[5] = new CustomVertex.PositionTextured(-1, -1, 0, 0, 1);
然后,您需要按如下方式设置视口(这是一个C ++视口集,因为我还没有真正使用过C#):
D3DVIEWPORT9 vp;
vp.X = 0;
vp.Y = 0;
vp.Width = 1920;
vp.Height = 1080;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
pDevice->SetViewport( &vp );
此时我希望在屏幕上看到整个纹理。
顺便说一句我也不完全确定你在SetTextureStageState中做了什么......你只是说“选择Arg1”。 你是否正在将D3DTA_TEXTURE传递给COLOR ARG 1?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.