Allgemeine Frage zu einem Mesh
-
Ein Mesh ist ja ein Körper im 3 dimensionalen Raum. dieser kann entweder mit Mesh.XXX oder aus einer.x file geladen werden.
Programmiersprache soll c# sein und mit Direct3D
Allgemein gefragt,
was ist performanter:
Meshes direkt zeichnen
oder
alle meshes in einem vertexpuffer zusammenfassen und mit drawprimitiv arbeiten
oder
jedem Mesh einen Vertexbuffer geben und den stream ändern und dann zeichnenals dazugehörige Frage in diesem kontext sehe ich :
Wie wird derjenige Mesh platziert?
Ich kenn zwar device.transform.world aber das wird mir denk ich zu langsam wenn die anzahl der meshes zunimmt.
wichtige zusatzinformation hierbei ist das das zielsystem xpembedded ist wo warscheinlich eine grafigkarte mit shared memory drin ist.
kann mir jemand bei der entscheidung einen tipp geben, besonders auch wegen der positionierung?
vielen dank..
Gruss Trider
-
erstmal lesen.
wenn du zum zeichnen jedes objektes sowieso die renderstates aendern musst, hast du auch keinen nutzen davon, wenn sie in einem buffer liegen.
shared memory spart dir lediglich bustrafic beim initialisieren und updaten.
-
so tief will ich gar nicht in die 3d programmierung rein.
kurz mal zum überblick :
- Ich habe koordinatensätze x,y,z,winkel
- an jede dieser positionen wird ein Cylinder gesetzt
- Kamera soll sich drum drehen könnendie 3 Punkte sind mal die basics. Im prinzip geht es mir nur darum, den Cylinder mesh zu positionieren und zwar so, das er 1. wenig speicher frisst und 2. performant ist wenn weis got wieviele Cylinder gesetzt werden. Die Position soll für das erste einem fixiert bleiben. eine drag and drop methode für einzelne meshes hab ich schon und funktioniert auch.
Ich wollt hier eure erfahrungen in performance erhalten, wenn ich diese objekte einfach nur zeichne und danach nicht mehr verändere...
irgend welche vorschläge?
Vertexbuffer - ja/nein
transform.world - ja/nein
absolute positionierung - ja/neinps, die kann ich einen mesh nicht auf 0/0/0 positionieren ohne transform.world? ich find keinen befehl dafür...
Gruss Trider
-
Trider schrieb:
so tief will ich gar nicht in die 3d programmierung rein.
wir beantworten ja nur deine tiefgehenden fragen.
Ich wollt hier eure erfahrungen in performance erhalten, wenn ich diese objekte einfach nur zeichne und danach nicht mehr verändere...
irgend welche vorschläge?
ja, erst das ganze zum laufen bringen, dann profiler laufen lassen, dann performance bottlenecks beheben, nicht andersrum indem du dir moegliche performanceprobleme (ohne ahnung zu haben;) ) ausdenkst, sie dann virtuell zu beheben versuchst und dann implementierst.
Vertexbuffer - ja
transform.world - ja
absolute positionierung - neinps, die kann ich einen mesh nicht auf 0/0/0 positionieren ohne transform.world? ich find keinen befehl dafür...
...weil du keine transformation ohne matrix durchfuehren kannst und somit du die matrix auf identity setzen musst.
-
ich hab schon mehrere versionen ausprobiert, war aber nie mit einer richtig zufrieden, weil ich auch erst alle möglichkeiten ausprobieren wollte.
Mein akzeptablester bisheriger versuch sieht so aus :
Mesh [] meshes; Color [] meshColors = new Color [] { Color.Green, Color.Orange, Color.Purple, Color.Pink, Color.Violet, Color.Blue, Color.Yellow, Color.Brown, Color.Aquamarine }; Vector3 [] meshLocations; meshes = new Mesh[numberOfMeshes]; meshLocations = new Vector3[numberOfMeshes]; for (int i = 0; i < numberOfMeshes; i++) { GraphicsStream vertexData; meshes[i] = Mesh.Cylinder(device, 1.0f, 1.0f, 1.0f, 32, 16); meshLocations[i] = new Vector3(((i % 3) * 2) - 2, ((i / 3) * 2) - 2, i); VertexBufferDescription description = meshes[i].VertexBuffer.Description; vertexData = meshes[i].VertexBuffer.Lock (0, 0, LockFlags.ReadOnly); Geometry.ComputeBoundingBox(vertexData, meshes[i].NumberVertices,description.VertexFormat, out meshBoundingBoxMinValues[i], out meshBoundingBoxMaxValues[i]); meshes[i].VertexBuffer.Unlock(); } protected override void OnPaint(PaintEventArgs e) { Material material = new Material(); device.BeginScene(); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); for (int i = 0; i < numberOfMeshes; i++) { if (activeMesh == meshes[i]) material.Ambient = Color.Red; else material.Ambient = meshColors[i]; [b]device.Transform.World = Matrix.Translation(meshLocations[i]);[/b] device.Material = material; meshes[i].DrawSubset(0); } device.EndScene(); device.Present(); }so und jetzt kommt die gute frage zum schluss

wie bekomm ich miene Meshes absolut positioniert (ohne transform.world) und wie bekomm ich sie dann in den Vertexbuffer.
Ich weis das ist sehr nah an einem Beispiel dran welche es im netz zu saugen gibt, aber mein endprogramm ist auf dieser Basis aufgebaut. deshalb muss ich mich darüber gut informieren, nur mit selber suchen komm ich nicht mehr weiter, deswegen wende ich mich an das Forum hier. Ich weis das ich nicht viel ahnung von direct3d hab. Aber generelles bis akzeptables verständniss von c# und vektorrechnung ist definitv vorhanden.
Wenn mir also einer weiterhelfen möchte, würde mich das echt freun, ansonsten muss ich weitersuchen und/oder auf anderen foren posten...
danke nochmal für eure bisherige hilfe, die mir auch schon einiges gebracht hat

Gruss Trider
-
Trider schrieb:
wie bekomm ich miene Meshes absolut positioniert (ohne transform.world) und wie bekomm ich sie dann in den Vertexbuffer.
naja.. emm.. indem du sie an die gewuenschte stelle transformierst und dann in den buffer schreibst?
aber wozu machst du das, statt es mit transform.world zu machen?
-
das ist vielleicht einfach, nur wenn man nirgends dazu beispiele findet und sich noch nie mit der materie auseinander gesetzt hat is das etwas unbekannt

Also Ziel ist es :
- ein koordinaten system anzeigen
- in ihm werden 10 - 100 - 10'000 Cylinder dargestellt. (dies dient zur räumlichen darstellung eines Körpers der verkauft oder konstruiert werden soll)
- das zielsystem ist ein sehr langsamer pc mit shared memory als grafigkarten speicher -> ich brauch alles auf bester performance
- einzelanwahl der cylinder (mache ich mit boxboundprobe atm) um sie je nach bedarf manuell zu verschieben
- bewegen der Kamera um die erstellten cylinder (damit ich auch was vom 3d habe hehe)
- cylinder müssen solid oder wired sein, evtl 2 farbig eine farbe oben andere unten.... (muss evtl mit 2 cylindern geregelt werden, damit man sie auch ausblenden kann wenn man sie nicht brauch. Sprich also entweder oberteil oder unterteil oder beides zusammen....)Zukunftsaussicht (ca in 2 jahren lol)
- verbinden der cylinder mit einem festen körper
- dieser körper soll aufschneidbar seinund dazu habe ich bereits eine vorlage welche auf vc++ vs1.5 geschrieben wurde. Ich will das ding auf c# d3d neu entwickeln... Die datenhaltung usw ist kein problem, nur das zeichnen im 3d raum macht mir noch sorgen da ich nie gross mit d3d oder sonstigen 3d engines gearbeitet habe.
Aus diesem grund bin ich viel am ausprobieren. alle methoden von denen ich geredet habe, hab ich schonmal ausprobiert, ich weis nur nicht ob sie performant sind, deswegen frag ich *G*
mit diesen informationen, was würdet ihr mit empfehlen zu benutzen? ich mein damit die techniken... nachfragen werd ich schon wenn ich was im netz nicht finde

Gruss Trider
-
Trider schrieb:
das ist vielleicht einfach, nur wenn man nirgends dazu beispiele findet und sich noch nie mit der materie auseinander gesetzt hat is das etwas unbekannt

naja, du meintest du kennst dich mit vektorrechnung aus, da faellt mir nicht wirklich ein wo das problem liegen koennte... objekt transformieren? objekt in einen VertexBuffer kopieren?

Aus diesem grund bin ich viel am ausprobieren. alle methoden von denen ich geredet habe, hab ich schonmal ausprobiert, ich weis nur nicht ob sie performant sind, deswegen frag ich *G*
darum geht es aber bei meiner frage nach dem sinn. Hast du geprueft wo das performanceproblem ist? wenn nicht, dann kann es sein dass du jetzt stunden/tage optimierst ohne dass sich etwas aendert, also
erst profilen
dann optimieren!mit diesen informationen, was würdet ihr mit empfehlen zu benutzen? ich mein damit die techniken... nachfragen werd ich schon wenn ich was im netz nicht finde

rauszufinden wo das problem liegt, bevor du es behebst.
jeder andere rat waere ein schuss ins blaue, ich kann dir zwar gerne sagen was du machen sollst, aber in 2wochen bist du hier und sagst es hat nichts gebracht und fuehlst dich von mir gebashed

also sag uns konkret wo das problem liegt.
-
bevor ich anfange ein grundgerüst zu erstellen, würde ich gern alle methoden, einen mesh zu platzieren ausprobiert haben um abzuwägen welche methode am besten und schnellsten ist.
Bisher hab ich :
- device.transform.world
- ausrechnen der vertices an der richtigen position
- laden aus einer .x dateidie einzigst interessante methode hierbei war das transformieren der welt. Da ich erfahren habe das ich die meshes auch absolut positionieren kann. Warum ich mich so für die absolute positionierung interessiere, ist das ich den rechenaufwand gern testen würde zwischen transform world (hier müssen alle objekte bewegt werden um ein einzelnes objekt zu positionieren) und absoluter positionierung.
sinn dahinter ist danach auch zu testen wie ich die Kamera realisiere und welcher rechenaufwand hierbei hierbei grösser ist : kamera um das objekt drehn(mein favorit) oder transform world.
momentan hänge ich an der absoluten positionierung die ich absolut nicht realisieren kann. Ebenso der vertex buffer. Ich kann mich zwar mit matrizen aus aber nicht direkt mit dem vertexbuffer und dessen flags und optionen *G*.
also :
1. wie positioniere ich Mesh.Cylinder ohne teansform world, damit ich es mit transform world vergleichen kann.
2. wie pack ich das dann in den vertexbuffer. Und kann ich evtl alle objekte in einen packen oder muss ich für jedes objekt einen anlegen? (ich denk es geht in einen rein, weil man bei dem zeichenbefehl index und länge angeben kann.)
das wärs fürs erste
nächtes problem kommt mit der kamera oder löst sich mit eurer antwort hier schon *G*Gruss Trider
-
du hast bisher 5x die gleiche frage formuliert.
alle aspekte dieser frage sind bereits beantwortet.
details zur implementation findest du zb in der dokumentation deines directx-sdks.
-
ich weis das ich es anders formuliert habe, nur bisher habe ich viele tutorials durchgenommen und evtl immer die falschen, da ich die absolute positionierung nicht gefunden habe. es würde mir ja reichen wenn man mir sagt :
1. mesh.vertexbuffer (mach das damit)
2. danach mache das mit dem buffer
3. worauf du dann die koordinaten eingeben kannstirgend sowas in der richtung. Ich habe nunmal noch nicht so viel erfahrung mit directx sodass ich sowas einfach auf ein stichwort realisieren kann. ich arbeite mich seit 3 wochen erst ein und das auch nicht den ganzen tag.
zum beispiel hab ich grad eben erfahren das erst ab directx10 mehrere zeichenbefehle beim rendern performanter werden. Also hat sich das mit dem 20'000 mal transform world schon erledigt. Also werd ich jetzt einen oder mehrere vertexbuffer anlegen und die objekte dort positionieren. nur leider hab ich noch keinen plan wie ich das da reinbekomm... vielleicht kann mir da ein ein beispiel oder tutorial weiterhelfen...
Gruss Trider
-
Trider schrieb:
ich weis das ich es anders formuliert habe, nur bisher habe ich viele tutorials durchgenommen und evtl immer die falschen, da ich die absolute positionierung nicht gefunden habe. es würde mir ja reichen wenn man mir sagt :
1. du transformierst die vertices an die gewuenschte position mit trivialer matritzenrechnung*vector
2. du kopierst das in einen VertexBuffer wie jedes andere mesh auch
3. du renderst diese Vertexbuffer wie immer, nur dass du den world transform auf identity laesst.
-
ok danke.
werd ich mal versuchen umzusetzen. ich werd natürlich mit einem objekt im vertexbuffer anfangen. Ich habe aber auch schon gelesen das man mehrere meshes in einen buffer schreiben kann und dann über die position im buffer auf das dementsprechende mesh zugreifen kann.
Wieviele einezlne meshes würdet ihr mir empfehlen in einen vertexbuffer reinzupacken? wie gesagt es können ca 10 - 20'000 oder mehr meshes sein. (ein Mesh hierbei ist ein einfacher cylinder mit einer länge von 2 - 20)
ich denk ich habs was du gemeint hast...
ist es sowas? :
tubeMesh = Mesh.Cylinder(dev, 1.0f,1.0f, 2f, 32, 16); //VertexBuffer vertexBufferx = tubeMesh.VertexBuffer; VertexBuffer meshVB = tubeMesh.VertexBuffer; CustomVertex.PositionNormal[] data = (CustomVertex.PositionNormal[])meshVB.Lock(0, typeof(CustomVertex.PositionNormal), LockFlags.None, tubeMesh.NumberVertices);wenn ja dann danke für den tipp

ps was würdest du mir raten wenn ich sag ich hab jetzt an die 20000 oder mehr von den objekten? mehrere buffers oder alles in einen oder oder?
Gruss Trider
-
Trider schrieb:
..
Wieviele einezlne meshes würdet ihr mir empfehlen in einen vertexbuffer reinzupacken?...
ps was würdest du mir raten wenn ich sag ich hab jetzt an die 20000 oder mehr von den objekten? mehrere buffers oder alles in einen oder oder?...
was lief den beim profilen bei dir am schnellsten? ich wuerd dir dann ehrlicherweise zu dem schnellsten raten.

du willst und willst einfach nicht profilen, sondern nur kristalkugel gelesen bekommen

-
wenn das demnach der richtige weg ist dann danke für den tipp das ich auf den weg gekommen bis

ich denk ich werd mich später mal wieder hier melden, da ich trotz aller anlaufschwierigkeiten sehr gute beratung erhalten habe.
Das soll keine drohung sein hehe
ich hab da noch eine frage wegen der Kamera. hab ich was an den parametern nicht verstanden oder warum kann ich mich nicht um mein objekt drehen?
dev.Transform.Projection = Matrix.PerspectiveFovLH(Geometry.DegreeToRadian(45.0f), (float)this.ClientSize.Width / this.ClientSize.Height, 0.1f, 100.0f); device.Transform.View = Matrix.LookAtLH( new Vector3(5.0f, 5.0f, 5.0f), new Vector3(), new Vector3(0, 1, 0));bei onMouseDown activiere ich ein Flag welches mir bei onMouseMove erlaubt den Vector von LookAtLH 5,5,5 zu transformieren mit rotate x,y und Z. ausserdem kommt noch ein zoom dazu. Die Mathematik dahinter habe ich verstanden nur irgendwas ist bei meiner initialisierung falsch.
ich kann mich aber nur um 90 Grad um das Objekt drehn. sieht hier jemand den fehler?
@rapso oder soll ich nen neuen thread aufmachen? das passt nicht mehr in das thema welches mitlerweile gelöst ist

Gruss Trider