Entwickler-Ecke

Multimedia / Grafik - Text in DirectX


Xion - Mi 24.05.06 14:04
Titel: Text in DirectX
Hi

Soviel ich weiß, kann man in DirectX keine Texte schreiben, oder? Ne andre Möglichkeit wären bmps, die ich dann als Texture drauflege. Aber wie kann ich die bmps zusammenfügen (z.B. Image1.Picture.LoadfromFile('X.bmp','I.bmp','O.bmp','N.bmp'); ).
Und wie kann ich das dann von TPicture nach IDIRECT3DTEXTURE8 konvertieren?

Xion


F34r0fTh3D4rk - Mi 24.05.06 14:29

du benutzt directx direkt ? also du benutzt nicht undelphix ?

ansonsten musst du das mit bildern machen, aber ich glaube directx8 hat da schon eigene routinen für


Xion - Mi 24.05.06 14:43

habe eine Funktion bei http://www.vb-fun.de/cgi-bin/loadframe.pl?ID=vb/tipps/tip0401.shtml gefunden (DrawText). Die Funktion will haben:

hDC: HDC, lpString: PChar, nCount: integer, var lpRect: TRect, uFormat: Cardinal

was bedeuten die einzelnen Parameter?


Xion - Mi 24.05.06 15:18

habs jetzt so


Delphi-Quelltext
1:
2:
3:
4:
    Rect.Left:=100;  //Rect: TRect
    Rect.Top:=100;
    DeskDC:=Form1.Handle;
    DrawText(DeskDC,'Hallo',Length('Hallo'),Rect,DT_LEFT); //DeskDC: HDC


kompiliert zwar, zeigt aber nix an


Stoney - Mi 24.05.06 15:31

Da fehlt noch die Länge und Breite des Rechtecks und die Umwandlung des Strings in einen PChar.
Zum Beispiel so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
    Rect.Left:=100;  //Rect: TRect
    Rect.Top:=100;
    Rect.Width := 100;
    Rect.Height := 100;
    DeskDC:=Form1.Handle;
    DrawText(DeskDC,PChar('Hallo'),Length('Hallo'),Rect,DT_LEFT); //DeskDC: HDC


Edit:
Allerdings bezweifle ich, das Funktion den beschriebenen Effekt liefert, weil weder das DirectX-Surface noch die Schriftart oder die Farbe des Textes angegeben werden muss.
P.S.: Deine Signatur gefällt mir. ;)


Xion - Mi 24.05.06 15:34

TRect hat seltsamerweise kein Width und Height :gruebel: ich glaube das problem liegt mehr beim Form1.Handle; ich glaube das muss was andres sein


Xion - Do 25.05.06 11:03

habs jetzt so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
    DeskDC:=GetDC(DeskDC);
    Rect.Left:=100;
    Rect.Top:=100;
    Rect.Right:=200;
    Rect.Bottom:=200;
    DrawText(DeskDC,PChar('Hallo'),Length('Hallo'),Rect,DT_LEFT);


aber:
1. es flackert ohne ende.
2. wie kann ich farbe+font ändern?

EDIT: zu 1: wie kann ich den Text auf den Device malen und nicht direkt?


EDIT2: hab folgendes bei Google gefunden:

SetTextColor(DeskDC,clLime); //SchriftFarbe
SetBkMode(DeskDC, TRANSPARENT); //Hintergrundfarbe
SelectObject(DeskDC, CreateFont(-12, 0, 0, 0, 0, 0, 0, 0, ANSI_CHARSET, //Schriftart
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
'Verdana'));


Stoney - Do 25.05.06 11:34

user profile iconXion hat folgendes geschrieben:

1. es flackert ohne ende.

Probier mal in die FormCreate-Prozedur folgendes einzutragen:

Delphi-Quelltext
1:
Form1.DoubleBuffered := True;                    

Möglicherweise verschwindet dann das Flackern.


Xion - Do 25.05.06 11:36

flackert immernoch. :(
ist ja auch (mehr oder weniger) klar. ich male meine schrift hin und dann meine 2D Objekte drüber, oder umgekehrt. kann so ja nix werden. aber wie kann ich beides kombinieren?

EDIT: vielleicht könnte man ja die schrift irgendwie nach Texture konvertieren.


Stoney - Do 25.05.06 11:52

user profile iconXion hat folgendes geschrieben:
flackert immernoch. :(
ist ja auch (mehr oder weniger) klar. ich male meine schrift hin und dann meine 2D Objekte drüber, oder umgekehrt. kann so ja nix werden. aber wie kann ich beides kombinieren?

EDIT: vielleicht könnte man ja die schrift irgendwie nach Texture konvertieren.


Ich kann mich vage daran erinnern, dass bei den Clootie-DirectX-Header [http://clootie.ru] Beispiele dabei sind, von denen eines zeigt, wie man einen Text ausgibt.
Kann aber sein, dass ich mir irre. Ich habe mich bisher nur wenig mit reiner DirectX-Programmierung auseinandergesetzt.
Von deiner Anfangsidee, jeden Buchstaben einzeln zu speichern und nacheinander zu laden wollte ich dir noch abraten: Das erzeugt zu viele Texturenwechsel, was sich negativ auf die Framesrate auswirkt.


Xion - Do 25.05.06 14:59


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
   DeskDC:=GetDC(DeskDC);
   SetTextColor(DeskDC,QuadratText[A].Color);
   SetBkMode(DeskDC, TRANSPARENT);
   SelectObject(DeskDC,QuadratText[A].Font);
   if DrawText(DeskDC,PChar(QuadratText[A].Text),Length(QuadratText[A].Text),QuadratText[A].Rect,DT_NOCLIP)>0 then
    Windows.Beep(100,1)
   else
    Windows.Beep(2000,1)


dieser Code ist interessant. Es piept abwechselnd hoch/tief => funktion funzt nicht/funzt. Nach ner Weile (ca. 10 sec) funzt die funtion gar nicht mehr. warum?

@Stoney: Der Link hat mir wenig geholfen, die Funktionen benötigen andere Units und mehr Kenntnisse als ich hab ;) Außerden brauchen die Texte ja gar nich 3D zu sein.

EDIT: Das ganze ist in einer for Schleife mit a:=0 to 19 entsprechend dem array.


Stoney - Do 25.05.06 16:29

user profile iconXion hat folgendes geschrieben:

@Stoney: Der Link hat mir wenig geholfen, die Funktionen benötigen andere Units und mehr Kenntnisse als ich hab ;) Außerden brauchen die Texte ja gar nich 3D zu sein.


Orthogonale Projektion - und schon wird ein 3D-Text in Windeseile 2D ;)
Wie meinst du andere Units? Die offiziellen DirectX-Header für Delphi/FreePascal sind von Clootie, und zwar seit DirectX 8. (Und scheinbar benutzt du auch DirectX 8.) Oder beziehst du dich auf etwas anderes ("Helferunits" z.B., die zusätzliche Funktionen bereitstellen oder wrappen)?
Hier hab ich noch ein paar weitere Links gesammelt:
SelfDXD [http://www.minfos.de/selfdxd/index.html]: Eine Dokumentation für DirectX 8
DirectX8-Tutorial [http://www.dsdt.info/tutorials/direct3d]: Zeigt, wie eine einfache Objekte gezeichnet werden können. Darauf kannst du den Text zeichnen lassen.

Ich weiß zwar nicht genau auf welchen Wissensstand du dich befindest, aber DirectX direkt aufzurufen ist für Einsteiger nicht unbedingt einfach. Du benötigst auf jeden Fall Grundkenntnisse in Object Pascal. Eine Option ist es, statt der VCL die WinAPI zu benutzen. Grundkenntnisse über den sogenannten "Game-Loop" (API) oder wie ApplicationOnIdle (VCL) ausgenutzt werden kann, musst du auch haben; Renderevents in einen Timer zu platzieren ist groß fahrlässig.

Für einen Anfänger ist es besser, einen Wrapper oder ein Framework zu benutzen. Hier mal eine kleine Liste aktueller und guter DirectX-Wrapper für Delphi:
(Un)DelphiX [http://www.micrel.cz/Dx/]
Asphyre [http://www.afterwarp.net/]
DanJetX [http://dan.mirg.ru/]
Die Wrapper machen solche Sachen wie Textausgabe unglaublich einfach.


Xion - Fr 26.05.06 14:39

user profile iconStoney hat folgendes geschrieben:

Ich weiß zwar nicht genau auf welchen Wissensstand du dich befindest...


Noch ganz am Anfang ;)

hab da 2 Komponenten runtergeladen (TWPool,TW9DirectX). ich versuche erstmal, da durchzusteigen


Stoney - Fr 26.05.06 15:26

user profile iconXion hat folgendes geschrieben:

hab da 2 Komponenten runtergeladen (TWPool,TW9DirectX). ich versuche erstmal, da durchzusteigen


Hmm, ok. Dann benutzt du doch einen Wrapper: WDirectX.
Vielleicht solltest du dir als erstes das gesamte Komponentenpackage herunterladen: http://wdirectx.no-ip.com/
Auf dieser Seite findest du auch einige Beispiele dazu. Viel Spaß damit!


Xion - Fr 26.05.06 16:01

jup, werd ich haben ;)

thx für die hilfe