Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

20.02.2011, 05:38

Koordinaten Umrechnen?

Hallo ich habe ein kleines Problem da ich leider nicht ganz so fit bin was das umrechnen von Koordinaten angeht.

Um folgendes geht es:

Ich habe eine Texture die ich 2-Dimensional auf den Bildschirm Rendere (Für das Interface von meinem Spiel).
Und ich habe ein 3D Objekt das logischweise über 3D-Koordinaten verfügt.

Nun möchte ich die 2D Texture immer so auf dem Bildschirm verschieben das die Textur immer über dem 3D Objekt "schwebt".

Und zwar soll das ganze ein Nameplate sein (Das 3D Objekt ist die Spielerfigur eines Gegnerischen Spielers und über seinem Kopf soll sein Name angezeigt werden)

Also soll sich die Textur sowohl verschieben wenn ich mich Umsehe (Bei dem Spiel handelt es sich um einen Ego-Shooter) und wenn ich mich Bewege. Also so das wie gesagt die Textur immer genau über dem Kopf der Spielerfigur ist.


Ich hoffe das mir jemand ein par Tips geben kann. Vielen Dank.

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

2

20.02.2011, 06:15

Das ist eigentlich recht simpel. Um Koordinaten zwischen (3D-)Weltkoordinaten und (2D-)Bildschirmkoordinaten umzurechnen kannst du die ModelView Matrix verwenden.


D.h. du kannst die Position des Nametag zunächst in 3D bestimmen. (z.B. ala Position der Figur + (0, 200, 0)).

Die Position schiebst du dann einmal durch die ModelView Matrix und du erhälst die Position des Nametag in Bildschirmkoordinaten.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

20.02.2011, 10:34

Ganz so einfach ist es leider nicht. Du musst die Position durch die ModelViewProjection Matrix schieben und bekommst daraus einen Punkt im Clipspace den du nun homogenisieren musst (alles durch w dividieren). Danach hast du die homogenen Gerätekoordinaten (der Viewport erstreckt sich dort von (-1, 1) (links oben) bis (1, -1) (rechts unten). Die kannst du dann in Pixelkoordinaten umrechnen (einfache Skalierung + Verschiebung).
Wenn du das nicht selber machen willst (auch wenns nicht so schwer is wies nun vielleicht klingt) kannst du dazu z.B. D3DXVec3Project() oder gluProject() verwenden.

4

20.02.2011, 18:05

Also Danke erstmal.

habe es jetzt mit der D3DXVec3Project Funktion versucht. Leider ohne erfolg:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
D3DVIEWPORT9 pViewport;
D3DXMATRIX pWorldMatrix,pCameraMatrix,pProjection;

ss_r.D3DDevice->GetViewport(&pViewport);
ss_r.D3DDevice->GetTransform(D3DTS_WORLD,&pWorldMatrix);
ss_r.D3DDevice->GetTransform(D3DTS_VIEW,&pCameraMatrix);
ss_r.D3DDevice->GetTransform(D3DTS_PROJECTION,&pProjection);

D3DXVec3Project(&vTargetPosition,sPlayer.vPosition,&pViewport,&pProjection,&pCameraMatrix,&pWorldMatrix);
DrawNameplate(ss_n.m_NetworkPlayerList[i].cUsername,vTargetPosition.x,vTargetPosition.y);


Die Position meines Nameplates ändert sich leider nicht abhängig von der Modellposition.

Edit: Habe gerade nochmal genau nachgesehen und habe festgestellt das die Position sich schon ändert. Aber nur sehr geringfügig (Sprich Model wandert von der linken Bildschirmhälfte auf die Rechte und der Nameplate bewegt sich um nen halben cm)

Wenn ich die Kamera bewege hat das dafür aber wirklich überhaupt keine Auswirkungen.

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »Coldsoul« (20.02.2011, 20:46)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

20.02.2011, 21:53

Und deine Matritzen sind auch wirklich die gleichen die in DrawNameplate() verwendet werden?

6

20.02.2011, 22:11

Ja es sind die selben.

Folgendes steht (gekürzt aufs wesentliche) in der DrawNameplate:

C#-Quelltext

1
2
3
4
5
6
7
8
float fPositionX = ((fX / (ss_r.m_iWindowX / 8.0f)) - 4.0f);
float fPositionY = ((fY / (ss_r.m_iWindowY / 6.0f)) - 3.0f);
   
D3DXMatrixTranslation(&TransMatrix, fPositionX,fPositionY, 0.0f);
ss_r.D3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)(&(TransMatrix)));
  
ss_r.D3DDevice->SetTexture(0,g_pNumber[0]);
ss_r.D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,2,&m_VertexList[iSymbol].m_Vertex,sizeof(SVertex));

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

20.02.2011, 22:12

Da setzt du aber eine andere Worldmatrix!?

8

20.02.2011, 22:52

Hmm naja ok da haste recht. Nur wie ändere ich die Position sonst wenn nicht so?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

20.02.2011, 23:17

Oh, sry, ich dachte du willst die Bildschirmkoordinaten (also Pixelkoordinaten) einer 3D Position berechnen!? Wenn du nur ein Billboard platzieren willst tust du das am Besten im Viewspace wie xardias geschrieben hat. Dazu nimmst du eben einfach die relative Position des Schildes zum Objekt (also die Position in Objektkoordinaten) und transformierst diese mit der World und View Matrix des Objekts. Damit bekommst du die Position im Viewspace. Nun renderst du dein Schild an diese Position (die Viewmatrix dabei auf Identitiy setzen).

10

20.02.2011, 23:29

Ich weiß das ist jetzt vileicht etwas viel verlangt aber könntest du mir ein kleines Codebeispiel geben wie das auszusehen hat?

Werbeanzeige