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();
}
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.
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.
oVerts[0].Color = Color.Red.ToArgb();
Bedeutet also: Der Vertex hat unten Links die Farbe 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
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 ?
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
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
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.
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 ) ??
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
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)
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
also wenn ich den stream Übergebe, sagt der mir fehlerhafter parameter... denk das bedeutet dann das keine header informationen dabei sind...
hm..
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
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.
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)
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
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..
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?
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