12

在此处输入图像描述

深灰色线应该是黑色和 1 像素宽:

pRT->DrawLine(Point2F(100, 120), Point2F(300, 120), blackbrush, 1);

浅灰色线应该是黑色和 0.5 像素宽:

pRT->DrawLine(Point2F(120, 130), Point2F(280, 130), blackbrush, 0.5);

相反,它们都是 2 像素宽。如果我要求 2 像素宽,这条线是黑色的,但自然是 2 像素宽。

渲染目标与窗口的客户区大小相同。我想要像 GDI 中那样的像素精度,一个坐标 = 一个像素和纯色......

谢谢。

4

2 回答 2

20

Direct2D 正在正确呈现。当你给它一个像素坐标比如 (100, 120) 时,它指的是像素元素的左上角,从像素坐标 (100, 120) 到 (101, 121) (包括上/左),右/下是排他的)。由于它是一条水平直线,因此您实际上得到了一个从 (99.5, 119.5) - (300.5, 120.5) 填充的矩形。由于该边缘溢出到相邻像素中,这就是为什么您在“错误”亮度下获得“2 像素宽度”线的原因。您必须考虑像素坐标(没有面积的点)和像素元素(屏幕上的物理点,面积为 1x1,或者当然只有 1)。

如果您想从像素 (100, 120) 到 (300, 120) 绘制一条直线,您应该使用 SemMike 的使用别名渲染的建议(这对直线非常有用!),或者您可以使用一半-像素偏移(因为 strokeWidth=1;对于其他 strokeWidths,按 strokeWidth/2 调整)。从 (100.5, 120.5) - (299.5, 120.5) 以 1.0 的笔划宽度绘制将得到你想要的东西。该笔画围绕您指定的像素坐标延伸,因此您将在像素元素 (100, 120) - (300, 121) 上获得“填充矩形”。再说一次,这是一个排他范围,所以 'y=121' 实际上并没有被填充,x=300 也没有。

如果你想知道为什么像 GDI 这样的东西不会发生这种情况,那是因为它不进行抗锯齿渲染,所以一切总是捕捉到像素元素。如果您想知道为什么 WPF 在使用 Shapes 时不会发生这种情况,那是因为它使用了布局舍入 (UseLayoutRounding) 和像素对齐。Direct2D 不提供这些服务,因为它是一个相对较低级别的 API。

于 2012-05-27T11:43:27.637 回答
5

你可以玩弄pRenderTarget->DrawLine(Point2F(100-0.5, 120-0.5), Point2F(300-0.5, 120-0.5), blackbrush, 1),但它很快就会变得棘手。最简单的是:

pRenderTarget->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);

希望它可以帮助某人...

于 2012-05-26T07:41:05.883 回答