Autor Beitrag
Nova
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Mo 04.07.05 20:35 
Hallo zusammen,

ich wollte mir grundsätzlich ein bisschen Wissen zum Thema 3D aneignen und wollte diesbezüglich eine ganz kleine Engine in Delphi schreiben, mit der ich selbst allerlei kleine Dinge ausprobieren kann.

Ich habe mir gedacht vielleicht kann ich ja einfach die TImage Komponente erweitern und eine Engine draufsetzen. Also habe ich eine neue Komponente entworfen, die TImage als Basis benutzt.
Das wollte ich quasi als Window Output für die Engine benutzen, damit ich die "Grund-Zeichnen-Befehle" von Canvas benutzen kann. Wollte mich halt eher auf das 3D Technische konzentrieren als auf Zeichen Routinen.

Soooo, problem ist jetzt leider nur dass ich eine rekursive Render Funktion geschrieben habe die - natürlich - einen Stack Überlauf produziert. Meine Frage ist jetzt ob mir jemand einen Tip geben könnte wie ich die Render Prozedur so verändern könnte, dass sie halt dieses Problem nicht verursacht sondern einfach nur verdammt viel FPS hat wenn nichts passiert *g*

Meine Render Prozedur sieht im Moment so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
procedure TNovaEngine.Render();
begin
  Canvas.Brush.Color := clWhite;
  Canvas.Pen.Color := clWhite;
  Canvas.Rectangle(0,0,Width,Height);
  
  Application.ProcessMessages;
  

  FFrames := FFrames + 1;
  QueryPerformanceCounter(DEnde);
  QueryPerformanceFrequency(DFreq);
  
  Dauer := (DEnde - DStart) / DFreq;
  
  if(Dauer>1then
  begin
    QueryPerformanceCounter(DStart);
    FLastFps := FFps;
    FFps := round(FFrames/Dauer);
  end;
  
  if(FShowFps) then
  begin
    if(FLastFps <> FFps) then Canvas.TextOut(5,5,'[Fps: '+inttostr(FFps)+']');
  end;
  
  if(FActive) then Render();
end;


Ich hoffe mir kann jemand helfen, oder bin ich mit diesem Ansatz völlig auf dem Holzweg?
Bitte beachtet, dass dies nur ein Test für mich selbst sein soll um die 3D Welt besser verstehen zu können. Also wie Ebenen funktionieren, Polygone dreidimensional wirkend gezeichnet und solche grundlegende Sachen mathematisch gelöst werden können. Es geht also nicht darum, dass dieser Weg der optimalste sein soll, wenn er halbwegs ordentlich funktioniert bin ich schon glücklich :)
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Di 05.07.05 08:49 
Also ich habe nicht so ganz verstanden was du damit vor hast. Aber für 3D ist eine 2D Canvas ja nicht ganz so das Richtige. Oder hast du etwa vor deine 3D Objekte selber zu rendern? Für richtiges 3D kann ich dir nur OpenGL empfehlen und dazu benötigst du normal nur ein Handle eines Fensters. Da würde auch schon ein stink normales Panel für ausreichen.

Aber zu deiner Renderschleife. Dein Problem bei der Schleife ist, dass sie sich immer weiter in den Callstack gräbt. Und dann Mittels Application.ProcessMessages zu sorgen, dass das Fenster Reaktionen zeigt ist so ziemlich der Unvorteilhafteste Weg den du nehmen kann.

Du musst dafür Sorgen, dass deine Renderprocedur von Außerhalb aufgerufen wird. Es bietet sich an, dass du das Event Application.OnIdle benutzt. Das wird dann aufgerufen, wenn deine Anwendung nichts zu tun hat. Dabei musst du aber darauf achten, dass du im Event den Parameter Done auf False setzt. Sonst wird sie nicht kontinuierlich aufgerufen.

PS: Ich würde evtl. deine "Engine" so aufbauen, dass diese nicht direkt mit einem TImage verbunden ist. Sondern eher so, dass sie auf ein TCanvas zeichnest. Das kann ja dann das den Forms sein. Oder das eines TImages, TPanels (was im original nur nicht sichtbar ist) oder eines TBitmaps welches irgendwo im Speicher liegt. Aber ich habe auch nicht ganz verstanden was du vor hast.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
Nova Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Di 05.07.05 17:09 
Hey Lossy,

danke für deine Antwort, ich werde den OnIdle Weg mal ausprobieren.

Zu deiner Frage was ich vorhabe, ja ich will meine eigene "Engine" schreiben und die Objekte selber rendern, aber die Anführungszeichen bei "Engine" sind ganz dick, weil es soll bei weitem keine konkurrenzfähige Sache werden. Ich habe einfach nur nach etwas gesucht was Pixel zeichnen kann, damit ich die ganzen Render Prozeduren selber schreiben kann.

Es geht mir halt darum das mathematische zu verstehen, daher habe ich nach einer möglichst einfachen Variante für mich gesucht (Linien Zeichnen usw is ja schon in Canvas drin) damit ich mich auf das 3D gerechne konzentrieren kann.

Klar kann ich OpenGL nutzen, habe ich auch schon oft gemacht. Mir ging es jetzt darum das prinzip von Matrix-transformationen, Vektorrechnungen im R3 und all diesen Low-Level-Hardcore-3D-Kram zu verstehen :)
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Mi 06.07.05 08:40 
Okay. Dann kann ich natürlich verstehen, dass du auf Hardware verzichten möchtest. Noch eines zum Zeichnen. Wenn du lediglich nur Linien und vereinzelte Pixel zeichnen möchtest kannst du dich voll und ganz auf die Canvas verlassen. Solltest du aber sehr viele Pixelaktionen durchführen wollen so würde ich von der Eigenschaft Pixels aber definitiv Abstand nehmen. Dann lieber mittels Scanlines selber in dem Speicher rumschreiben. In einige Fällen kann es sogar sinnvoll sein sich selber einen Speicherbereich zu reservieren und in diesem dann zu malen und das dann letzten Endes nur in die Scanlines reinzukopieren.

Wenn du konkret weist was du zeichnen willst, dann würde es sich mit sicherheit lohnen ein Testprogramm zu erstellen in dem du alle möglichen Wege des Zeichnens einmal ausprobierst und den schnellsten Weg suchst. So hatte ich das zu mindestens mal gemacht.

PS: Es gibt auch zwei Arten von Bitmaps. Die einen Hardwareabhängig (DDB) und die anderen Hardwareunabhängig (DIB). Die DDBs sind mitunter auch ein ganzes Stück schneller als die DIBs da die DIBs überwiegend per Software gezeichnen werden. Oder du schaust dir mal GDI+ an. Das ist vom Funktionsumfang wesentlich erweitert worden und viel langsamer kann es auch nicht sein. ;-)

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.