I was having problems getting textures to display properly on trapezoids (quad with one side smaller as if viewed from a perspective) in C# Managed DirectX. I ended up solving it with a custom shader (not the solution I was looking for, but the only one so far that works). However now the problem is that all the primitives rendered with the custom shader lag one or maybe a few frames behind the other primitives. The key sections of code are outlined below:
Vertex Shader:
float4x4 WorldViewProj;
struct VSData
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
};
void Raw_VertexShader(in VSData IN, out VSData OUT)
{
OUT.Position = mul(IN.Position, WorldViewProj);
OUT.TexCoord = float2(IN.Position.x, IN.Position.z);
}
technique StretchTexture
{
pass
{
VertexShader = compile vs_3_0 Raw_VertexShader();
}
}
Render():
//apply shader
manager.CPolyVertexShader.Technique = "StretchTexture";
manager.CPolyVertexShader.Begin(0);
manager.CPolyVertexShader.BeginPass();
//set shader's transformation matrix
manager.CPolyVertexShader.SetValue(manager.hWorldViewProj, device.Transform.World * device.Transform.View * device.Transform.Projection);
//draw the triangles
device.DrawIndexedUserPrimitives(PrimitiveType.TriangleList, 0, CPolyIndices.Length, CPolyTriangles, CPolyIndices, true, CPolyVerts);
//deapply the shader
manager.CPolyVertexShader.EndPass();
manager.CPolyVertexShader.End();
manager is a class that handles the Direct3D device. CPolyIndices is the index array. CPolyVerts is the vertex array. CPolyTriangles is the number of triangles to render.
As you can see, before it renders, it sets WorldViewProj to the matrix already assigned to the device, so the default shader and custom shader must be using the same transformation matrix. Indeed, it doesn't render in the wrong place, it just renders where it was supposed to be a few frames ago (it's tough to tell exactly how many frames behind it is, but it looks like about 3).
If I simply comment out the lines where it turns the custom shader on and off between draws, the problem goes away. This is the first time I've tried using custom shaders and the default shader in the same render cycle, so it's possible I missed something that I wasn't even aware of. Anyone heard of this before?
I think your problem is that you set the value inside the Begin and BeginPass scope. Begin means that the cpu applies the current state of the pipeline. Including shader variables.
You should move your setvalue before begineffect, or call something like yourshader.Apply()