2012-05-26 11 views
9

enter image description herepiksele Direct2D

ciemnoszarym linie mają być czarne i jeden piksel:

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

jasnoszarego linie mają być czarno szerokości 0,5 pikseli:

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

Zamiast tego mają szerokość 2 pikseli. Jeśli poproszę o szerokość 2 pikseli, linia jest czarna, ale naturalnie o szerokości 2 pikseli.

Cel renderowania ma ten sam rozmiar co obszar klienta okna. Chciałbym uzyskać dokładność pikseli jak w GDI, jedną współrzędną = jeden piksel i czyste kolory ...

Dzięki.

Odpowiedz

13

Direct2D jest poprawnie renderowania. Kiedy podasz mu współrzędne pikseli, takie jak (100, 120), odnosi się do górnego i lewego narożnika elementu piksela, który rozciąga się od współrzędnych pikseli (100, 120) do (101, 121) (góra/lewo są włączone, prawo/dół są wyłączne). Ponieważ jest to prosta linia pozioma, skutecznie uzyskujesz wypełniony prostokąt od (99,5, 119,5) - (300,5, 120,5). Ponieważ krawędzie tego rozlewają się na sąsiednie piksele, dlatego uzyskujesz "2-pikselową szerokość" linii przy "niewłaściwej" jasności. Musisz myśleć w kategoriach piksela współrzędnych (punkty bez obszaru) i pikseli elementów (fizyczne punkty na ekranie o powierzchni 1x1, lub tylko 1 oczywiście).

Jeśli chcesz narysować linię prostą, która obejmuje piksele (100, 120) do (300, 120), powinieneś skorzystać z sugestii SemMike dotyczącej używania renderowania alikwotowego (co jest świetne w przypadku linii prostych!), Lub możesz użyć przesunięcia o pół piksela (ponieważ strokeWidth = 1; dla innych wartości strokeWidths, ustaw wartość strokeWidth/2). Rysunek od (100,5, 120,5) - (299,5, 120,5) o szerokości obrysu 1,0 da ci to, czego szukasz. Udar ten rozciąga się wokół określonych przez ciebie współrzędnych pikseli, więc otrzymasz "wypełniony prostokąt" nad elementami piksela (100, 120) - (300, 121). I znowu, jest to ekskluzywny zakres, więc "y = 121" nie jest faktycznie wypełniony, ani nie jest x = 300.

Jeśli zastanawiasz się, dlaczego tak się nie dzieje z czymś podobnym do GDI, to dlatego, że nie renderuje antyaliasingu, więc wszystko zawsze przyciąga do elementów pikselowych. Jeśli zastanawiasz się, dlaczego tak się nie dzieje podczas korzystania z WPF podczas korzystania z kształtów, dzieje się tak dlatego, że używa ona zaokrąglania układu (UseLayoutRounding) i przyciągania pikseli. Direct2D nie zapewnia tych usług, ponieważ jest to API o relatywnie niskim poziomie.

+0

Dzięki za wyjaśnienie, ma sens. Czy tęsknię za tym w dokumentach MSDN gdzieś na Direct2D, czy też nie ma go tam i powinienem wiedzieć? "Rysowanie z (100,5, 120,5) - (299,5, 120,5) o szerokości obrysu 1,0 da ci to, czego szukasz" Jeśli dobrze cię zrozumiem, będzie to (100,5, 120,5) - (300,5, 120,5) . W przeciwnym razie pominięty zostanie ostatni piksel linii. Przy okazji, "sugestia SemMike": ten sam facet, odpowiadałem na własne pytanie ... – SemMike

+0

Niezależnie od tego, czy używasz 299.5, czy 300.5, zależy od tego, czy chcesz mieć linię szeroką na 200 pikseli czy linię 201px. Prawdopodobnie nie jest tak w dokumentach, ponieważ jest dość standardowy dla nowoczesnych interfejsów graficznych 2D, ale jest też trochę nieoczywisty i zaawansowany, a często ludzie, którzy pracują nad zaawansowanymi materiałami, zapominają o tym, czego nie wiedzieli, zanim zostali to zaawansowane. Uważam, że pomaga to myśleć jak arkusz papieru w siatce. Tam, gdzie przecinają się poziome i pionowe linie są współrzędne pikseli całkowitych, a kwadraty pomiędzy nimi są "fizycznymi" elementami pikseli. –

5

Możesz grać z pRenderTarget->DrawLine(Point2F(100-0.5, 120-0.5), Point2F(300-0.5, 120-0.5), blackbrush, 1), ale szybko staje się trudne. Najprostszym jest:

pRenderTarget->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); 

Mam nadzieję, że ktoś pomoże ...

+0

Nie polecam omijania poprawnego obrazu psychicznego. W chwili, w której potrzebujesz antyaliasów lub narysuj kształt, który nie jest linią wyrównaną do osi, twój kod (napisany na niewłaściwym mentalnym założeniu) wprowadzi Cię w błąd. To jest standardowa rzecz, tak samo dla GDI +. – jnm2

+0

Z wyjątkiem DX11, współrzędne texela są zorientowane w środkowym punkcie, więc nie jest tak "standardowy" jak kiedyś. –

Powiązane problemy