Renderowanie dowolnego tekstu w XNA przy użyciu Windows API?

9

W komentarzu Andrew do mojego drugiego pytania zauważył, że możliwe jest renderowanie tekstu do Texture2D przy użyciu Windows API, zamiast rysowania tekstu bezpośrednio za pomocą SpriteBatch. Jak to się robi? Domyślam się, że jest krok pośredni przed zapisaniem danych obrazu do Texture2D.

Pytam, ponieważ pozwoliłoby mi to renderować znaki Unicode w locie, zamiast konieczności wstępnego renderowania wszystkich potrzebnych glifów za pomocą SpriteFont (zbyt wiele glifów w języku koreańskim i japońskim, aby ta droga była niemożliwa, niestety). Dzięki!

ThatsGobbles
źródło

Odpowiedzi:

4

Używając odbicia, możesz pobrać wskaźnik powierzchni Direct3D z Texture2D. Stamtąd można używać dowolnych interfejsów API, które mogą renderować na powierzchnię DX. Zrobiłem to niedawno, aby hostować zawartość XNA za pomocą D3DImage WPF (z obsługą kanału alfa). DirectWrite może renderować na powierzchnię DX, a może nawet będziesz mógł używać zarządzanych interfejsów API . Opakowania DirectX .NET w tym łączu obsługują tylko Direct3D 10 i 11, a nie Direct3D 9 (który XNA używa AFAIK). Jednak nadal możesz go uruchomić. Na marginesie, jeśli chcesz renderować grafikę wektorową, możesz zastosować podobne podejście do współpracy z Direct2D. Oczywiście nic z tego nie będzie działać na żadnej platformie obsługiwanej przez XNA innej niż Windows.

Mike Strobel
źródło
1
Chciałbym tylko zaznaczyć, że możesz także uzyskać uchwyt okna dla Xna i powiedzieć, aby zamiast tego renderował do panelu Win32. Następnie możesz użyć dowolnej metody, którą chcesz renderować na górze gry, ponieważ rysujesz backbuffer na kontrolce win32. Jest to bardzo brudne, ale działało dla mnie dobrze, kiedy połączyłem panel wprowadzania Tablet PC z XNA. Rezultatem było coś, co wyglądało na standardowe okno XNA, ale z niewidocznym rozpoznawaniem pisma ręcznego. Po prostu wyświetlałem pociągnięcia na xna. Oczywiście tekst / etykiety / przyciski też będą działać. Jednak nie próbowałem tego z WPF.
zfedoran
1
Wydaje mi się, że w twojej metodzie pojawią się problemy z „przestrzenią powietrzną”, Arriu. Czy byłeś w stanie renderować zawartość na górze okna XNA przy nienaruszonym kanale alfa? Ogólna zasada jest taka, że ​​piksel może być „własnością” tylko jednego graficznego interfejsu API, co powoduje problemy z przezroczystą lub półprzezroczystą zawartością. Jeśli dotyczy to również Twojej metody, problematyczne byłoby renderowanie tekstu na innym tle niż jednolity kolor tła.
Mike Strobel
Przepraszam, mogłem być trochę zagmatwany. Metoda, którą opisałem, polega jedynie na tym, że panel narysuje teksturę na tle. Podobne do sposobu, w jaki możesz powiedzieć obrazkowi, który obraz ma narysować. Ale zamiast tekstury / obrazu będącego plikiem jest to bufor buforowy xna. Nie rysowałem na panelu lub w oknie. Nie było więc problemów z „przestrzenią powietrzną”.
zfedoran
O, rozumiem. Twoje podejście jest bardzo podobne do sposobu, w jaki hostowałem zawartość XNA w WPF (używając D3DImage). Zamiast typowego źródła bitmapy źródłem obrazu jest powierzchnia XNA / Direct3D. Zgadzam się, że jest to najlepsze podejście, biorąc pod uwagę dostępne opcje - nie ma problemów z przestrzenią powietrzną, a wydajność jest całkiem dobra, ponieważ nie jest wymagane niepotrzebne kopiowanie / blitting.
Mike Strobel