像素

2012-05-26 16 views
9

enter image description here像素

深灰色線應該是黑色和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中的像素精度,一個座標=一個像素和純色......

謝謝。

回答

13

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。

+0

感謝您的解釋,是有道理的。我是否在Direct2D的MSDN文檔中錯過了這個文檔,或者它不在那裏,我應該知道? 「從(100.5,120.5) - (299.5,120.5)中抽出,筆畫寬度爲1.0會讓你找到你想要的東西」如果我正確理解你,那將是(100.5,120.5) - (300.5,120.5) 。否則,該行的最後一個像素被省略。順便說一下,「SemMike的建議」:同一個人,我回答我自己的問題...... – SemMike

+0

您是否使用299.5或300.5取決於您想要200px寬線還是201px線。這可能不在文檔中,因爲它對現代2D圖形API來說是相當標準的東西,但它也有點不明顯和先進,並且通常從事高級工作的人往往會忘記他們之前不知道的東西那先進。 我覺得它有助於將它想象爲一張網格紙。水平線和垂直線相交的地方是整數像素座標,它們之間的平方是「物理」像素單元。 –

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); 

希望它可以幫助別人......

+0

我不建議避免正確的心理圖片。一旦你需要抗鋸齒或繪製一個不是軸對齊線的形狀,你的代碼(寫在一個不正確的心理假設上)會讓你困惑。這是標準的東西,GDI +也是如此。 – jnm2

+0

除DX11以外,texel座標以中點爲導向,所以它不像以前那樣「標準」。 –