Laden...

Erster versuch in Direct3D

Erstellt von inek vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.816 Views
inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren
Erster versuch in Direct3D

Hallo zusammen, bin gerade dabei mich das erste mal mit Direct3D auseinander zu setzen.

kann mir bitte jemand mal krz erläutern, warum ich mit folgendem code ausgerechnet ein quadrat und ausgerechnet einen farbverlauf bekomme.

mein presentParameter :


m_oPresentParameters = new PresentParameters();
           
            m_oPresentParameters.SwapEffect = SwapEffect.Discard;
            m_oPresentParameters.Windowed = true;
            m_oDevice = new Device(0, DeviceType.Reference, this, CreateFlags.SoftwareVertexProcessing,m_oPresentParameters);
       

mein vertex :



                //vertex Buffer erstellen
                VertexBuffer oVertexBuffer = new VertexBuffer(typeof(CustomVertex.TransformedColored), 4, form.RenderDevice, Usage.SoftwareProcessing, CustomVertex.TransformedColored.Format, Pool.Managed);
                
                
                CustomVertex.TransformedColored[] oVerts = null;


                oVerts = (CustomVertex.TransformedColored[])oVertexBuffer.Lock(0, LockFlags.None);
                
                oVerts[0].X = 50; 
                oVerts[0].Y = form.ClientSize.Height - 50;
                oVerts[0].Color = Color.Red.ToArgb();

                oVerts[1].X = 50; 
                oVerts[1].Y = 50;
                oVerts[1].Color = Color.Blue.ToArgb();

                oVerts[2].X = form.ClientSize.Width-50;
                oVerts[2].Y = form.ClientSize.Height-50;
                oVerts[2].Color = Color.Green.ToArgb();

                oVerts[3].X = form.ClientSize.Width-50;
                oVerts[3].Y = 50;
                oVerts[3].Color = Color.Yellow.ToArgb();


Render ()



public void Render(RenderDelegate oDelegate)
        {
            if (m_oDevice == null)
                return;

            m_oDevice.Clear(ClearFlags.Target, Color.Blue, 1.0f, 0);
            m_oDevice.BeginScene();

            if (oDelegate != null)
                oDelegate();
            
            m_oDevice.EndScene();
            m_oDevice.Present();
        }


inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren

niemand nen tipp für mich ??
🙁

K
593 Beiträge seit 2007
vor 15 Jahren

Also um das mal grob anzuschneiden..^^ Also wie du mit GDI+ oder ähnlich nen Punkt zeichnest weißt du hoffentlich?^^ Bei DirectX was du in diesem Falle benutzt arbeitet man grundsätzlich mit Vertexen. Indirekt bei GDI+ auch aber davon siehst du nicht viel.

  • Warum ein Quadrat?
    Weil du erstellst 4 Vertexe(ist die mehrzahl so?) denen du koordinaten in form eines Quadrates gibst.
                oVerts[0].X = 50;
                oVerts[0].Y = form.ClientSize.Height - 50;

Bedeutet also: Da ist ein VertexArray und das erste ( die 0 wie immer im Array) kriegt die Koordinate X = 50 und Y = form.ClientSize.Height - 50 sprich dieser punkt landet unten links in deinem form.

  • Warum der Farbverlauf?
    Weil du 4 Vertexe mit verschiedenen farben hast. Beispiel Vertex Nr 0
oVerts[0].Color = Color.Red.ToArgb();

Bedeutet also: Der Vertex hat unten Links die Farbe rot.

  • Warum ist dann nicht nur ein Punkt Rot?

Weil ein Vertex ein "gesamt Object ist" um es verständlich auszudrücken ist es ein Control was Ecken kanten und sonst was hat, nur wesentlich flexibler.

Ich hoffe du hast es grob verstanden ^^

Gruß Daniel

inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren

danke erstmal für deine beschreibung...

dennoch habe ich folgendes noch nicht ganz verstanden...

  • Warum ist dann nicht nur ein Punkt Rot?

Weil ein Vertex ein "gesamt Object ist" um es verständlich auszudrücken ist es ein Control was Ecken kanten und sonst was hat, nur wesentlich flexibler

kannste bitte versuchen mir das noch etwas zu verdeutlichen ?

K
593 Beiträge seit 2007
vor 15 Jahren

Hmm .. du hast ein Panel sagen wir mal .. und um das Panel zu zeichen wird nur der obere linke der untere linke der obere Rechte und der untere Rechte Punkt bestimmt und dann gezeichnet .. bei dem Vertex ist das ungefährt genau so .. du hast ein "Vertex Object" Wo halt die Punkte gezeichnet werden aber dann ein "gesamt Object" rauskommt

N
335 Beiträge seit 2006
vor 15 Jahren

Hallo inek,

Du kannst dir das so vorstellen:
Ein Vertex ist ein Punkt / Ortsvektor zu einem Punkt im 3D-Raum.
In deinem Code erzeugst du vier Vertices, die ein Quadrat beschreiben (das sieht man an den Koordinaten).
Die Vertices werden in einem VertexBuffer gespeichert. Das ist im Prinzip eine Liste mit Vertices, die an verschiedenen Orten im Speicher abgelegt werden kann (im AGP-Speicher, im System RAM oder im RAM der Grafikkarte).
Die Grafikkarte ist auf Dreiecke optimiert, d.h. sie zeichnet Dreiecke am schnellsten (sag ich jetzt mal pauschal, zur einfachen Verdeutlichung).
Irgendwo in deinem Code müsste ein Aufruf dieser Art sein:

m_oDevice.DrawPrimitives( /* Parameter */ );

Hier wird das Zeichnen (Draw) gestartet. Als Quelle hast du deine Vertices in dem erstellten VertexBuffer gesetzt (mit SetStreamSource() ).
Zusammenfassend heißt das also: Du hast Vertices erstellt und in einen Buffer gesteckt. Den Buffer als Quelle für die Grafikkarte eingestellt und das Zeichnen gestartet.

In deinem DrawPrimitives()-Aufruf müsstest du einen Parameter haben, der so lautet: PrimitiveType.TriangleStrip. Das bestimmt, welches Primitiv (welche Form) aus den Vertices gezeichnet werden soll. Die Vertices sind nämlich nur Eckpunkte (wie Kaji schon erklärte) einer Form.
In deinem Fall möchtest du Triangle (=Dreiecke) zeichnen. Nun gibt es dafür mehrer Modi: Fan, Strip und List.
List bedeutet, dass jedes Dreieck immer 3 Punkte zum Zeichnen braucht (das ist ja auch logisch).
Strip heißt, dass das erste Dreieck 3 Punkte benötigt, für das nächste Dreieck aber die letzten beiden Punkte vom ersten Dreieck und ein neuer vierter Punkt verwendet werden (du hast 4 Punkte / Vertices angegeben).

Also werden jetzt zwei Dreiecke gezeichnet, die zusammen ein Quadrat ergeben.
Die Vertices haben bei dir außer der Position noch eine Farbe. Diese wird als Diffuse-Farbe verwendet (gibt die sichtbare Farbe an). Das heißt eine Ecke hat z.B. bei dir die Farbe rot.
Da ein Dreieck eine Fläche ist, müssen die restlichen Pixel innerhalb des Dreiecks auch eine Farbe bekommen. Und an dieser Stelle wird linear interpoliert ("Überblenden") zwischen den Farben der Vertices. Deshalb bekommst du einen Farbverlauf.

Ich empfehle dir ein paar Tutorials oder Bücher über diese Dinge zu lesen!
Hier auf mycsharp.de gibt es auch Direct3D Tutorials (schau mal bei den Artikeln).

Mfg NeuroCoder

inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren

Perfekte erläuterungen...

Ich danke euch beiden...

habs jtzt verstanden..

Ich habe mir das Buch
"Managed DirectX und C#" gekauft..

da wird das mit der interpolation aber absolut gar nicht erwähnt...

Danke nochmal...

BTW: Spitzen Forum... bisher immer super Hilfe bekommen.

inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren

eine frage dazu hab ich aber noch...

ich möchte gerne bilder einer analogen kamera anzeigen lassen.

denke das ich das über texturen machen muss oder ?

ist es denn Möglich texturen aus nem bytearray zu erstellen ?? oder MUSS es ein fertiges bitmap sein.. ( muss ich erst ein bitmap aus den bytes erstellen ) ??

N
335 Beiträge seit 2006
vor 15 Jahren

Hallo inek,

Ja, du musst über Texturen gehen.
Hier ein paar Links dazu:
Bitmap aus Byte[]
http://www.tek-tips.com/viewthread.cfm?qid=1264492&page=10

Und Texturen in MDX: Managed Direct3D Tutorial

Mfg NeuroCoder

inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren

Hallo Neurocoder,

so wie ich das hier sehe, muss ich ja dann vorher das bitmap aus den bytes erstellen. is das nich wieder n totaler zeitverlust ??

wills ja mit direct3d machen um zeit und recourcen zu sparen..

habs vorher mit createBitmap gemacht..und das dann in ne picturebox kopiert, hat auch funktioniert, war nur viel zu langsam.. ( gehe hier von 32 kamerabildern, mit 25 fps aus)

Ich glaube ich habs.. kann doch auch


TextureLoader.FromStream(..);

nutzen oder ?? ( also die bytes vorher in nen stream packen)

K
593 Beiträge seit 2007
vor 15 Jahren

Hallo,

das funktioniert wenn in deinem Stream auch die Header-Daten für ein Bitmap vorhanden sind. Wenn der nicht vorhanden ist hier vielleicht eine kleine Hilfe.

Gruß Daniel

inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren

ist das dann die schnellst mögliche methode ??

K
593 Beiträge seit 2007
vor 15 Jahren

Ob es die schnellste ist weiß ich nicht genau aber sie ist recht schnell weil sie im Arbeitsspeicher arbeitet, viel schneller wirst du hardware technisch da nicht kommen 😉 also 25fps sind da normal locker drinne...

Gruß Daniel

inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren

also wenn ich den stream Übergebe, sagt der mir fehlerhafter parameter... denk das bedeutet dann das keine header informationen dabei sind...

hm..

inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren

villeicht kann mir jemand nen tip geben, wie ich meine bytes nutzen kann, bzw wie ich an meinen stream noch n header drann hänge

K
593 Beiträge seit 2007
vor 15 Jahren

siehe ein paar post hier drüber von mir da ist nen link zu nem Thread wo die Problematik mit dem Bitmap Header besprochen wird und wie es gemacht wird.

inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren

sorry aber ich versteh das nich ganz...

ich habe ja schon n bytearray nur halt ohne header.. kann ich den header denn an den vorhandenen array vorne dran hängen ??(wenn ja wie)

N
335 Beiträge seit 2006
vor 15 Jahren

Hallo inek,

MemoryStream erstellen. Header rein. Byte-Array rein. Freuen 🙂

Siehe dazu diese Links:
Bitmap aus Byte[] (schon von mir gepostet)
http://de.wikipedia.org/wiki/Windows_Bitmap

Mfg NeuroCoder

inek Themenstarter:in
182 Beiträge seit 2007
vor 15 Jahren

ja.. hab ich mir auch so gedacht.. aber wie mach ich den header und meine bytes rein ??
also so das dann beides im stream drinn is..

L
36 Beiträge seit 2006
vor 15 Jahren

Hallo Inek!

Was genau willst du eigentlich machen? "Einfach nur" die Bilder nehmen und mit Direct3D schneller darstellen weil die GDI-Komponenten so langsam sind, oder die 3D-Darstellung danach noch manipulieren und andere Objekte dazufügen?

N
335 Beiträge seit 2006
vor 15 Jahren

Hallo inek,

ja.. hab ich mir auch so gedacht.. aber wie mach ich den header und meine bytes rein ??

Habe dir doch schon das Vorgehen geschildert und Links geliefert. Wo liegt dein Problem?

Zuerst erstellst du dir einen Header (die Daten zu deinem Eingangsbild solltest du schon selber wissen: Bittiefe, Größe, etc.). Dann packst du den Header in einen MemoryStream. Dann schreibst du dahinter dein Byte-Array. Dann kannst du den Stream wie gewöhnlich als Bitmap laden.

Mfg NeuroCoder