Jump to content

GPU Drawing - lines not 1px wide?


Recommended Posts

When I draw a 1px Black horizontal line, it comes out as a 2px Grey line.

I thought maybe StrokeTransformType.Hairline would solve the problem, but it did not.

 

Is there a workaround (other than disabling anti-aliasing)?

 

using IDeviceBrush blackBrush = deviceContext.CreateSolidColorBrush(Color.Black);
using IStrokeStyle strokeStyle = deviceContext.Factory.CreateStrokeStyle(
    StrokeStyleProperties.Default with { TransformType = StrokeTransformType.Hairline },
    Array.Empty<float>());

deviceContext.DrawLine(new Point2Float(0, 10), new Point2Float(100, 10), blackBrush, 1f, strokeStyle);

 

(September 25th, 2023)  Sorry about any broken images in my posts. I am aware of the issue.

bp-sig.png
My Gallery  |  My Plugin Pack

Layman's Guide to CodeLab

Link to comment
Share on other sites

you have to offset your drawing points by 0.5

 

search around... there's a code sample around here somewhere.

 

EDIT: found it...

 

ICommandList commandList = deviceContext.CreateCommandList();
using (commandList.UseBeginDraw(deviceContext))
{
	deviceContext.AntialiasMode = AntialiasMode.PerPrimitive;

	// GDI+ uses a default PixelOffsetMode of Half, which shifts all drawing calls by 0.5 pixels.
	// This produces good results for drawing antialiased primitives when supplying integer pixel
	// coordinates, but is technically the wrong way to do it. Direct2D does it the right way; if you
	// need a sharp antialiased line on pixel boundaries, you need to specify coordinates that are
	// at the center of pixels. The stroke is then drawn centered around those coordinates.
	// See here for more info: https://stackoverflow.com/a/10773729/1191082
	// So for converting to Direct2D, we either have to apply a transform, or adjust our drawing
	// calls by half-pixels when translating code that relied on PixelOffsetMode.Half.
	using (deviceContext.UseTranslateTransform(0.5f, 0.5f))
	{
		deviceContext.DrawLine(X1, Y1, X2, Y2, whiteBrush, whiteStrokeWidth, whiteStrokeStyle);
		// more drawing commands snipped...

		// The default GraphicsUnit for a System.Drawing.Font is Points, which are 1/72inch and scaled with
		// the user's global DPI/scaling setting.
		// When drawing with Direct2D/DirectWrite, the font size is specified as DIPs (device independent
		// pixels), and the DPI of the device context is always set to 96 when we're in Paint.NET (so,
		// 1 DIP = 1 pixel, even if your DPI settings are higher).
		// If we don't convert, font sizes are much smaller than the classic code that uses System.Drawing.
		float fontSize = (float)UIScaleFactor.Current.ConvertFontPointsToPixels(16);

		IDirectWriteFactory textFactory = this.Services.GetService<IDirectWriteFactory>();
		ITextFormat textFormat = textFactory.CreateTextFormat("Arial", null, FontWeight.Normal, FontStyle.Normal, FontStretch.Normal, fontSize);
		string text = direction + " " + angle.ToString() + "°";

		deviceContext.DrawText(text, textFormat, sourceBounds, blackBrush);
	}
}

 

Above is a snippet from my Level Horizon plugin.

  • Like 1
  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...