Hallo Hat jemand von euch eine Ahnung, woher ich eine 3D Rendering Bibliothek bekommen könnte, die folgenden Anforderungen genügt?: -Rendern von Objekten bestehend aus verbundenen Punkten (Flächen mit Texturen sind nicht zwingend nötig, ein "Stabgerüst" würde reichen!) -Geschrieben in C, C++ wäre auch ok aber C ist mir lieber -Opensource (nur zum Basteln, nix mit kommerziell) -Schön wäre, wenn es nicht hochoptimiert ist, sondern so geschrieben dass es nachvollziehbar ist. -Muss weder schnell noch schlank sein, ich habe einen STM32F4, und das LCD hat nur 64*96 Pixel, S/W ohne Graustufen... Vielen Dank, Sean PS: Falls es so etwas nicht gibt, immer nur her mit jeglichen Tutorials oder Ansätzen, die helfen könnten das selbst zu programmieren.
Sowas zum Beispiel: http://blogs.msdn.com/b/davrous/archive/2013/06/13/tutorial-series-learning-how-to-write-a-3d-soft-engine-from-scratch-in-c-typescript-or-javascript.aspx Stichwort: 3D Software Rendering.
Axel Jäger schrieb: > Sowas zum Beispiel: > http://blogs.msdn.com/b/davrous/archive/2013/06/13/tutorial-series-learning-how-to-write-a-3d-soft-engine-from-scratch-in-c-typescript-or-javascript.aspx > > Stichwort: 3D Software Rendering. Danke, eigentlich sieht das ja super aus, wenn nur das eine Problem nicht wäre: Da wird SharpDX verwendet, und mir ist nicht ganz klar WAS das SharpDX alles macht? Weil wenn es nur Punkte und Linien zeichnen wäre wäre es ja ok, aber es ist ja eben mehr. Gibt es da eine schnelle Lösung, oder muss ich halt einfach jede Funktion anschauen und Portieren?
@Axel Jäger (axeljaeger) Ich habe mir das jetzt mal genauer angeschaut, und denke, dass ich das grundsätzlich auch implementieren könnte. Mein Problem ist aber der letzte Schritt (die Matrix um die Perspektive, Öffnungswinkel der Kamera und Ausrichtung selbiger anzuwenden). Die wird nämlich bei allem was ich finden konnte, auch in den Tutorials immer mittels einer Lib berechnet, welche nicht für uC gemacht ist. Selber schreiben sollte ja eigentlich gehen, aber ich finde nirgends eine "Formel" um das zu berechnen. Weiss da jemand mehr? LG, Sean
Wenn Du mit "Formel" die 3D nach 2D Projektion meinst, das ist ein einfacher Dreisatz: x_bildschirm = x_3d * entfernung_auge_bildschirm / z_3d Entsprechend gilt die Berechnung für y. Mit Festkomma-Arithmetik auf dem Microcontroller muss man etwas shiften. Erfahrungsgemäß benötigt man mindestens 16 Bit Genauigkeit. Siehe auch hier: http://www.arcsynthesis.org/gltut/Positioning/Tut04%20Perspective%20Projection.html Oliver
Mit einem controller ? Entweder sind die zu rechnenden Formen trivial, oder der controller hat einiges an dampf
Дуссель дук schrieb: > Mit einem controller ? Entweder sind die zu rechnenden Formen trivial, > oder der controller hat einiges an dampf Ja hat schon ordentlich Dampf, ist ein STM32F4 mit 168MHz, 32 Bit.
Da gabs mal ne wolfenstein 3d Demo fuer Die r0ket. Weis grad net wie viel "Dampf" die hat, aber hier sind die sourcen:https://github.com/gasman/wolfy
Lukas Straub schrieb: > Da gabs mal ne wolfenstein 3d Demo fuer Die r0ket. Weis grad net wie > viel "Dampf" die hat, aber hier sind die > sourcen:https://github.com/gasman/wolfy Nicht schlecht! Erinnert mich an meine Star Wars: Dark Forces Zeit als Schueler damals mit dem anschliessenden Versuch, die Levels automatisch in 3DS max zu parsen und zu bauen... (Starb aus Zeitgruenden, aber funktionierte)
Lukas Straub schrieb: > Da gabs mal ne wolfenstein 3d Demo fuer Die r0ket. Weis grad net wie > viel "Dampf" die hat, aber hier sind die > sourcen:https://github.com/gasman/wolfy Das ist aber leider eine Raycasting-Engine, nicht was ich suche (kann kein "echtes 3D") Ich habe jetzt aber mal ein kleines Programm geschrieben, welches einen Würfel rotieren lässt. Rendering funktioniert soweit gut, aber der Würfel wird beim Drehen plattgedrückt :( Ich mache das folgendermassen: Jedes Frame rufe ich folgendes auf:
1 | |
2 | vector3.z=500; |
3 | |
4 | translate(&vertice1, vector3); |
5 | translate(&vertice2, vector3); |
6 | translate(&vertice3, vector3); |
7 | translate(&vertice4, vector3); |
8 | translate(&vertice5, vector3); |
9 | translate(&vertice6, vector3); |
10 | translate(&vertice7, vector3); |
11 | translate(&vertice8, vector3); |
12 | |
13 | rotate_y(&vertice1, angle); |
14 | rotate_y(&vertice2, angle); |
15 | rotate_y(&vertice3, angle); |
16 | rotate_y(&vertice4, angle); |
17 | rotate_y(&vertice5, angle); |
18 | rotate_y(&vertice6, angle); |
19 | rotate_y(&vertice7, angle); |
20 | rotate_y(&vertice8, angle); |
21 | |
22 | rotate_x(&vertice1, angle); |
23 | rotate_x(&vertice2, angle); |
24 | rotate_x(&vertice3, angle); |
25 | rotate_x(&vertice4, angle); |
26 | rotate_x(&vertice5, angle); |
27 | rotate_x(&vertice6, angle); |
28 | rotate_x(&vertice7, angle); |
29 | rotate_x(&vertice8, angle); |
30 | |
31 | |
32 | vector3.z=-500; |
33 | |
34 | translate(&vertice1, vector3); |
35 | translate(&vertice2, vector3); |
36 | translate(&vertice3, vector3); |
37 | translate(&vertice4, vector3); |
38 | translate(&vertice5, vector3); |
39 | translate(&vertice6, vector3); |
40 | translate(&vertice7, vector3); |
41 | translate(&vertice8, vector3); |
Ausgangsposition ist, dass der Mittelpunkt des Würfels sich auf 0,0,-500 befindet. Er wird dann auf den Nullpunkt geschoben, rotiert und zurückbewegt. Rotieren mache ich folgendermassen:
1 | void rotate_x(vertice *vertice_ptr, int angle) |
2 | {
|
3 | float sinangle = 0.0174524; |
4 | float cosangle = 0.9998477; |
5 | vertice_ptr -> y = cosangle * (vertice_ptr -> y) - sinangle * (vertice_ptr -> z); |
6 | vertice_ptr -> z = cosangle * (vertice_ptr -> z) + sinangle * (vertice_ptr -> y); |
7 | |
8 | }
|
9 | void rotate_y(vertice *vertice_ptr, int angle) |
10 | {
|
11 | float sinangle = 0.05547298; |
12 | float cosangle = 0.99846019; |
13 | vertice_ptr -> x = cosangle * (vertice_ptr -> x) + sinangle * (vertice_ptr -> z); |
14 | vertice_ptr -> z = cosangle * (vertice_ptr -> z) - sinangle * (vertice_ptr -> x); |
15 | |
16 | }
|
Also noch keine Matritzen, und Sinus/Kosinus als Konstanten. Alle Koordinaten sind Floats. Auf dem Video sieht man was mit dem Würfel passiert, sorry für die schlechte Qualität, aber das LCD lässt sich nicht gerne filmen. Ich kann sonst schon noch den ganzen Code anhängen, aber eigentlich muss es an dem Teil bzw. einem grundlegenden Denkfehler liegen. Der Rest des Codes ist vermutlich nur verwirrend (schön ist der nicht...) Danke für eure Hilfe, Sean
Hat sich erledigt! Hier noch die Lösung, falls jemand ein ähnliches Problem hat: Wenn man das so berechnet, wird "vertice_ptr -> y" bearbeitet, bevor es im 2. Befehl verwendet wird. Dadurch entsteht ein riesiger Fehler!
1 | void rotate_x(vertice *vertice_ptr, int angle) |
2 | {
|
3 | float sinangle = 0.0174524; |
4 | float cosangle = 0.9998477; |
5 | vertice_ptr -> y = cosangle * (vertice_ptr -> y) - sinangle * (vertice_ptr -> z); |
6 | vertice_ptr -> z = cosangle * (vertice_ptr -> z) + sinangle * (vertice_ptr -> y); |
7 | }
|
Richtig wäre es so:
1 | void rotate_x(vertice *vertice_ptr, int angle) |
2 | {
|
3 | float sinangle = 0.0174524; |
4 | float cosangle = 0.9998477; |
5 | float y = cosangle * (vertice_ptr -> y) - sinangle * (vertice_ptr -> z); |
6 | vertice_ptr -> z = cosangle * (vertice_ptr -> z) + sinangle * (vertice_ptr -> y); |
7 | vertice_ptr -> y = y; |
8 | }
|
In dem fall bleibt "vertice_ptr -> y" unverändert bis am Schluss. Wenn man es richtig macht, also mit Matrizen dann erübrigt sich das eh. Trotzdem Danke, Sean
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.