Windows Form und DirectX Form verknüpfen?

xaitech

Mitglied
Hallo,
ich sitze zur Zeit an einer kleinen DirectX Demo für die Uni. Nun möchte ich meine 800x600Pixel große DirectX-Form in eine neue Hauptform integrieren. Wie es zum Beispiel in Cinema4D ist...unten links der Frame mit der Objektansicht und drum herum einige Klappboxen usw.
Wie geht das? Also wie kann ich meine DirectX-Form in ein normales Windows-Form integrieren.

Danke


Nachtrag: Ich habe selber eine Antwort auf mein Problem gefunden. Das Zauberwort heisst MDI (Mulitple Document Interface). Sieht aus als wenn es laufen würde....
Es soll das noch SDI geben. Weiss jemand, wo da der Unterschied ist?


xai
 
Zuletzt bearbeitet:

broetchen

Erfahrenes Mitglied
Wenn MDI multiple document interface heißt, müsste, logisch hergeleitet, SDI single document interface bedeuten und somit das ganz normale Fenster sein.

Zu deinem Problem:
Was du noch machen könntest, wäre ein Panel auf deine Form zu legen und dorthinein zu rendern. Das habe ich einmal gemacht und nach eni paar umbauarbeiten (wegen dem Rendern) hat's super geklappt.

Ich häng dir einfach mal mein Projekt dran, es hier zu erläutern würde nämlich zu lange dauern.

mfg broetchen
 

Anhänge

  • MyMeshViewer.zip
    114,4 KB · Aufrufe: 105

broetchen

Erfahrenes Mitglied
Ich hab keine Ahnung :(

Wahrscheinlich an der Version deines SDK. Ich hab die Version, die bei meinem Buch dabei war. Als ich einmal upgedatet habe, hat auch nix mehr funtkioniert.

Es kann also gut sein, dass man da ein bisschen herummanipulieren muss!?
 

xaitech

Mitglied
Hallo,
danke für die Antworten und das Beispiel. Ich werde mal versuchen es auch mit einem Panel nachzubauen.

Ich habe bei mir auch zwei Fehler in deinem Quellcode gefunden, weiss aber nicht, ob es jetzt an meinem DirectX liegt.

Zeile 841-843 sollte hier durch ersetzt werden:
-----------------------------------------------------
float objectRadius = 0.0f;
Vector3 objectCenter = new Vector3();
VertexBuffer vb = mesh.VertexBuffer;

GraphicsStream vertexData = vb.Lock(0, 0, LockFlags.None);
objectRadius = Geometry.ComputeBoundingSphere(vertexData, mesh.NumberVertices, mesh.VertexFormat, out objectCenter);
vb.Unlock();
------------------------------------------------------


Zeile 890:
-----------------------------------------------------
auskommentieren....SupportsDirectionalLights gibt es in meiner(neusten) DirectX9 SDK Version nicht.
-----------------------------------------------------


Hab noch ein anderes Problem. Und zwar möchte ich mehrere Meshes Rendern und durch Mausklick die unterschiedlichen Meshes einzelnd drehen und verschieben. Wie bekomm ich das hin?
 

hafwil

Grünschnabel
Hallo!

Hab noch ein anderes Problem. Und zwar möchte ich mehrere Meshes Rendern und durch Mausklick die unterschiedlichen Meshes einzelnd drehen und verschieben. Wie bekomm ich das hin?

Ich hab ungefähr dasselbe Problem... Ich weiss nicht, wie ich rausbekomme, auf welches Mesh geklickt wurde. Habe bereits eine Menge gegoogelt, aber nichts gefunden. Ich hoffe hier kann mir einer weiter helfen, bzw. @xaitech: hast du schon eine lösung gefunden, und könntest die hier posten?

Vielen Dank für Eure Hilfe!

Willi
 

Alexander Schuc

crazy-weasel
xaitech hat gesagt.:
Hallo,
ich sitze zur Zeit an einer kleinen DirectX Demo für die Uni. Nun möchte ich meine 800x600Pixel große DirectX-Form in eine neue Hauptform integrieren. Wie es zum Beispiel in Cinema4D ist...unten links der Frame mit der Objektansicht und drum herum einige Klappboxen usw.
Wie geht das? Also wie kann ich meine DirectX-Form in ein normales Windows-Form integrieren.

Danke


Nachtrag: Ich habe selber eine Antwort auf mein Problem gefunden. Das Zauberwort heisst MDI (Mulitple Document Interface). Sieht aus als wenn es laufen würde....
Es soll das noch SDI geben. Weiss jemand, wo da der Unterschied ist?


xai

MDI - Mehrere Formulare "leben" in einem Hauptformular. (http://www.causeway.co.uk/tutorial/cpro/tutor/mdi.gif)
SDI - Jedes Formular wird extra auf deinem Desktop angezeigt. Wie zum Beispiel mehrere Explorer Fenster.

Wegen deinem Problem. Warum renderst du nicht einfach in ein Panel?
Beim Konstruktor von Device anstatt eines Fensters einfach das Panel angeben. (3ter Parameter des Konstruktors.)

Device Konstruktor

MfG,
Alex

edit: Ah ok, Brötchen hats eh erwähnt.
 

xaitech

Mitglied
Hallo!
Hab das mit dem Panel auch schon gemacht :) Trotzdem danke.

Es bleibt noch die Frage, wie ich bzw. auch der hafwil per Mouseclick Objekte aus der DirectX-Umgebung anwählen können. Das Verschieben ist dann kein Problem mehr.´

Eine Idee von mir wäre, einzelne Objekte mit verschiedenen Farben in einem Buffer zu Rendern und den Farbwert unter dem MouseCursor abzufragen. Weiss aber nicht ob das so klappen könnte? Jemand ne idee, ob sich das einfach bewerkstelligen lässt?

mfg
xai

P.S. Da muss es doch in DirectX eine Methode für geben...MouseIntersection() oder so?
 
Zuletzt bearbeitet:

hafwil

Grünschnabel
Hallo!

Hab jetzt was gefunden:

http://www.toymaker.info/Games/html/picking.html

Habe dies nach C# umgewandelt:

Variablen:

private static Microsoft.DirectX.Direct3D.Device device;

private static Microsoft.DirectX.Vector3 mouseVector;

private static Microsoft.DirectX.Matrix projMatrix;
private static Microsoft.DirectX.Matrix viewMatrix;

private static Microsoft.DirectX.Vector3 rayDir;
private static Microsoft.DirectX.Vector3 rayOrigin;

private static int width;
private static int height;

private static int posX;
private static int posY;

Funktion:

public static void getRay(Device device, int xPos, int yPos)
{
CMousePicking.device = device;

projMatrix = device.GetTransform(TransformType.Projection);
viewMatrix = device.GetTransform(TransformType.View);
height = device.Viewport.Height;
width = device.Viewport.Width;

posX = xPos;
posY = yPos;

mouseVector.X = ( ( ( 2.0f * posX ) / width ) - 1 ) / projMatrix.M11;
mouseVector.Y = -( ( ( 2.0f * posY ) / height ) - 1 ) / projMatrix.M22;
mouseVector.Z = 1.0f;

Microsoft.DirectX.Matrix invertedViewMatrix = Microsoft.DirectX.Matrix.Invert(viewMatrix);

// Transform the screen space pick ray into 3D space
rayDir.X = mouseVector.X*invertedViewMatrix.M11 + mouseVector.Y*invertedViewMatrix.M21 + mouseVector.Z*invertedViewMatrix.M31;
rayDir.Y = mouseVector.X*invertedViewMatrix.M12 + mouseVector.Y*invertedViewMatrix.M22 + mouseVector.Z*invertedViewMatrix.M32;
rayDir.Z = mouseVector.X*invertedViewMatrix.M13 + mouseVector.Y*invertedViewMatrix.M23 + mouseVector.Z*invertedViewMatrix.M33;

rayOrigin.X = invertedViewMatrix.M41;
rayOrigin.Y = invertedViewMatrix.M42;
rayOrigin.Z = invertedViewMatrix.M43;
}


Das kann man jetzt so verwenden:

private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
CMousePicking.getRay(device, e.X, e.Y);
Microsoft.DirectX.Direct3D.IntersectInformation tempInfo;
Microsoft.DirectX.Direct3D.IntersectInformation[] tempInfo2;

// Use inverse of matrix
Microsoft.DirectX.Matrix matInverse = Matrix.Invert(device.GetTransform(TransformType.World));

// Transform ray origin and direction by inv matrix
Microsoft.DirectX.Vector3 rayObjOrigin,rayObjDirection;

rayObjOrigin = Vector3.TransformCoordinate(CMousePicking.RayOrigin, matInverse);
rayObjDirection = Vector3.TransformNormal(CMousePicking.RayDirection,matInverse);
rayObjDirection = Vector3.Normalize(rayObjDirection);

if (myMesh.Intersect(rayObjOrigin, rayObjDirection, out tempInfo, out tempInfo2))
{
// Mesh wurde angeklickt
}
}

Hab das probiert und es funktioniert! Die Klasse CMousePicking sollte dann auch noch
das mit rayObjOrigin usw. erledigen, hab die Klasse jetzt aber nur schnell hingeschrieben,
um zu testen, ob die Transformation 2D -> 3D funktioniert! Würde mich noch über andere
Lösungsvorschläge freuen ;-)

MFG Willi