• Advertisement
Sign in to follow this  

SharpDX / Direct2D - Plotting pixels directly onto a bitmap or back buffer?

This topic is 1274 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm learning 3D math and rendering fundamentals and I want to draw my own lines and rasterize my own triangles as part of what I'm currently doing. As it's software-based rendering, I can manually implement the algorithms with which I draw by accessing my own raw byte array which will form the basis of a bitmap to be painted onto the Direct2D surface. What is the best way to manually construct my own bitmap from raw bytes and translate that to something painted on Direct2D surface? Below is the code I'm using to initialize my setup, and it works just fine, if I let Direct2D do all the work of drawing lines and triangles and so forth. I'm having trouble finding a way to get my own data printed onto the surface though.

var swapChainDesc = new SwapChainDescription()
{
	BufferCount = 2,
	Usage = Usage.RenderTargetOutput,
	OutputHandle = form.Handle,
	IsWindowed = true,
	ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm),
	SampleDescription = new SampleDescription(1, 0),
	Flags = SwapChainFlags.AllowModeSwitch,
	SwapEffect = SwapEffect.Discard
};
Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.BgraSupport, swapChainDesc, out _device, out _swapChain);
_backBuffer = Surface.FromSwapChain(_swapChain, 0);

using(var factory = new FactoryD2D())
{
	var dpi = factory.DesktopDpi;
	_renderTarget = new RenderTarget(factory, _backBuffer, new RenderTargetProperties()
	{
		DpiX = dpi.Width,
		DpiY = dpi.Height,
		MinLevel = SharpDX.Direct2D1.FeatureLevel.Level_DEFAULT,
		PixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Ignore),
		Type = RenderTargetType.Default,
		Usage = RenderTargetUsage.None
	});
}

I've tried constructing a DXGI Bitmap but I'm having trouble working out how to manipulate it. I've also tried calling Map() on the swapchain backbuffer in order to draw directly onto the backbuffer without having an intermediate bitmap, but I get an exception saying "the parameter is incorrect".

Share this post


Link to post
Share on other sites
Advertisement

I found a good way to do this, if it helps anyone. Seems to be relatively fast as well. I keep a raw byte array in memory and copy its contents to a bitmap which is then blitted to the render target when ready.

 

In the constructor:

_memory = new byte[Width * Height * 4];
_backBufferBmp = new Bitmap(_renderTarget, new Size2(Width, Height), new BitmapProperties(_renderTarget.PixelFormat));

Here's how I draw raw pixels:

public void DrawPoint(int x, int y)
{
	var i = (int)(Width * 4 * y + x * 4);
	_memory[i] = _fgColor.B;
	_memory[i+1] = _fgColor.G;
	_memory[i+2] = _fgColor.R;
	_memory[i+3] = _fgColor.A;
}

And finally, when the memory contents are ready to be displayed:

_backBufferBmp.CopyFromMemory(_memory, Width * 4);
_renderTarget.DrawBitmap(_backBufferBmp, 1f, BitmapInterpolationMode.Linear);

Works like a charm.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement