I'd like to draw a sprite bitmap with SlimDX Direct3D10, but I'm stuck at this problem, where I can see my image on screen, but it gets stretched depending on the window size.
The issue looks like this:
I got the same general idea of drawing sprites in Direct3D9 and Direct2D working fine, because there I simply resize the RenderTarget or reinitialize the Device with a new BackBuffer.
How do I fix this, so that the sprite remains the same dimensions independent from window size?
I'm seeing two potential issues:
- I don't know if and how I need to set the different Transforms to adjust for window size (I'd rather resize the backbuffer, and only transform sprites for positioning and scaling)
- I suppose I need to update the backbuffer or do something in the form's resize event.
Here is my rendering code:
using DiscSim;
using SlimDX;
using SlimDX.Direct3D10;
using SlimDX.DXGI;
using System.Windows.Forms;
using System.Drawing;
using Device = SlimDX.Direct3D10.Device;
using Vector2 = SlimDX.Vector2;
using Resource = SlimDX.Direct3D10.Resource;
namespace DiscSimSlimDX
{
class Camera_DX10 : Camera
{
private RenderTargetView renderTarget;
private Device device;
private SwapChain swapChain;
private Sprite sprite;
private SpriteInstance[] spriteInstances;
public Camera_DX10(ISimulation simulation, Form form, string spritePath)
: base(simulation, form, spritePath)
{
var swapChainDescription = new SwapChainDescription()
{
BufferCount = 1,
ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm),
IsWindowed = true,
OutputHandle = form.Handle,
SampleDescription = new SampleDescription(1, 0),
Flags = SwapChainFlags.AllowModeSwitch,
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput
};
Device.CreateWithSwapChain(null,
DriverType.Hardware,
DeviceCreationFlags.Debug,
swapChainDescription,
out device,
out swapChain);
using (var backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0))
{
renderTarget = new RenderTargetView(device, backBuffer);
RenderTargetViewDescription r = renderTarget.Description;
}
device.OutputMerger.SetTargets(renderTarget);
device.Rasterizer.SetViewports(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0, 1));
device.OutputMerger.BlendState = BlendState.FromDescription(device,
new BlendStateDescription()
{
IsAlphaToCoverageEnabled = true,
});
sprite = new Sprite(device, 512 * 512); // How big should the buffer size be?
sprite.ProjectionTransform = Matrix.Identity; // ?
sprite.ViewTransform = Matrix.Identity; // ?
ShaderResourceView texView = ShaderResourceView.FromFile(device, "Resources/World.png");
var spriteInstance = new SpriteInstance(texView, Vector2.Zero, new Vector2(1, 1));
spriteInstance.Transform = Matrix.Identity; // ?
spriteInstances = new SpriteInstance[1] { spriteInstance };
form.ResizeEnd += (s, e) =>
{
// How do I resize the backbuffer or what do I need to do
// to adjust for the new window size?
};
}
public override void Draw()
{
device.ClearRenderTargetView(renderTarget, Color.Black);
sprite.Begin(SpriteFlags.None);
sprite.DrawBuffered(spriteInstances);
sprite.End();
swapChain.Present(0, PresentFlags.None);
}
}
}