I want to create a texture and to render to its surface but I have a problem: When the texture size is to big (more than 263x263 pixel ARGB), no primitive is rendered in the surface (I just can see the color used during the Clear operation).
Here is my code:
private void Form1_Load(object sender, EventArgs e)
{
// Setting up DirectX
PresentParameters pp = new PresentParameters()
{
BackBufferCount = 1,
Windowed = true,
SwapEffect = SwapEffect.Discard,
BackBufferWidth = ClientSize.Width,
BackBufferHeight = ClientSize.Height,
};
d3d = new Direct3D();
device = new Device(d3d, 0, DeviceType.Hardware, Handle, CreateFlags.HardwareVertexProcessing, pp);
TexturedVertex.SetVertexDeclaration(device);
// Creating a triangle
triangleBuffer = new VertexBuffer(device, 3 * Marshal.SizeOf(typeof(TexturedVertex)), Usage.WriteOnly, VertexFormat.None, Pool.Managed);
var stream1 = triangleBuffer.Lock(0, 0, LockFlags.None);
stream1.WriteRange(new[] {
new TexturedVertex( -2, -2, 0, 0, 0 ),
new TexturedVertex( 0, 2, 0, 1, 0),
new TexturedVertex( 2, -2, 0, 1, 1),
});
triangleBuffer.Unlock();
// Creating a rect
rectBuffer = new VertexBuffer(device, 4 * Marshal.SizeOf(typeof(TexturedVertex)), Usage.WriteOnly, VertexFormat.None, Pool.Managed);
var stream2 = rectBuffer.Lock(0, 0, LockFlags.None);
stream2.WriteRange(new[] {
new TexturedVertex( -2, -2, 0, 0, 0 ),
new TexturedVertex( -2, 2, 0, 0, 1),
new TexturedVertex( 2, -2, 0, 1, 0),
new TexturedVertex( 2, 2, 0, 1, 1),
});
TexturedVertex.SetVertexDeclaration(device);
rectBuffer.Unlock();
// Creating a render texture
int w = 262;
Texture texture = new Texture(device, w, w, 0, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default);
Surface surface = texture.GetSurfaceLevel(0);
Surface buffer = device.GetRenderTarget(0);
device.SetRenderTarget(0, surface);
device.SetTransform(TransformState.Projection, Matrix.OrthoOffCenterLH(-4, 4, -4, 4, 0, 100));
device.SetTransform(TransformState.View, Matrix.Identity);
device.SetTransform(TransformState.World, Matrix.Identity);
device.Clear(ClearFlags.Target, new Color4(Color.Green), 0, 0);
device.BeginScene();
device.SetStreamSource(0, triangleBuffer, 0, Marshal.SizeOf(typeof(TexturedVertex)));
device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 3);
device.EndScene();
device.Present();
device.SetRenderTarget(0, buffer);
// Setting current texture and material
device.SetTexture(0, texture);
Material mat = new Material();
mat.Ambient = mat.Diffuse = mat.Emissive = Color.White;
device.Material = mat;
// Setting the projection, view and transform matrix
device.SetTransform(TransformState.Projection, Matrix.OrthoOffCenterLH(-4, 4, -4, 4, 0, 100));
device.SetTransform(TransformState.View, Matrix.Identity);
device.SetTransform(TransformState.World, Matrix.Identity);
// Setting handler
this.KeyDown += new KeyEventHandler(Form1_KeyDown);
this.Paint += new PaintEventHandler(Form1_Paint);
}
void Form1_Paint(object sender, PaintEventArgs e)
{
device.Clear(ClearFlags.Target, new Color4(Color.Purple), 0, 0);
device.BeginScene();
device.SetStreamSource(0, rectBuffer, 0, Marshal.SizeOf(typeof(TexturedVertex)));
//device.SetStreamSource(0, triangleBuffer, 0, Marshal.SizeOf(typeof(TexturedVertex)));
device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 4);
device.EndScene();
device.Present();
}
I guess your form's client size is 262 pixel wide or high.
In the presentational parameters you limit your backbuffer and z buffer to this size. You need another Z buffer, matching the size of the texture you want to render, and you need to set it to be used, and then switched back to the original.
Surface oldDepthBuffer = device.DepthStencilSurface;
Texture db = new Texture(device, w, w, 1, Usage.DepthStencil, oldDepthBuffer.Description.Format, Pool.Default);
Surface myDepthBuffer = db.GetSurfaceLevel(0);
device.SetRenderTarget(0, surface);
device.DepthStencilSurface = myDepthBuffer;
// RENDER to texture
device.DepthStencilSurface = oldDepthBuffer;