Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Di Jul 08, 2025 23:27

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Do Aug 24, 2006 17:36 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 23, 2006 17:48
Beiträge: 24
Hi!

Erstmal danke für die tollen Tutorials und v.a. für die DGLOpenGL.pas :)
Ich bin gerade dabei, eine 2D Delphi Anwendung zu schreiben, in der man Polygone verschieben, drehen und den Viewport zoomen können soll.
Leider hab ich auf meinem Rechner (2400+/1GB/TNT1,16MB,PCI/WIN2K,D7) Performanceprobleme beim Ausführen meines grundlegenden Basissystems (der unten genannte Record TContour hat dabei ~400 Points). Ich vermute also, dass ich irgendwas falsch angehe :roll:

Die bisherige Struktur sieht so aus:

Ich habe eine Klasse DGLViewport, die die Renderprocedure beinhaltet und ein dynamisches Array Items, welches Records vom Typ TEntity enthält:
Code:
  1.  
  2.   TPolyPoint3D=record
  3.     X,Y,Z,Bulge:Single;
  4.   end;
  5.  
  6.   TDimensionsf=record
  7.     XMin,XMax,YMin,YMax,ZMin,ZMax:Single;
  8.   end;
  9.  
  10.   TContour=record
  11.     Points:array[0..2500] of TPolyPoint3D;
  12.     Dimensions:TDimensionsf;
  13.     Count:Smallint;
  14.   end;
  15.  
  16.   TColor3B=array [0..2] of Shortint;
  17.  
  18.   TEntity=record
  19.     Contour:TContour;
  20.     Border:Boolean;
  21.     BorderColor:TColor3B;
  22.     FillColor:TColor3B;
  23.     Handle:integer;
  24.   end;
  25.  


Die Renderprocedure wird von Application.OnIdle aufgerufen und sieht folgendermaßen aus:
Code:
  1.  
  2.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  3.  
  4.   glMatrixMode(GL_MODELVIEW);
  5.   glLoadIdentity;
  6.  
  7.   glTranslatef(XPos,YPos,0);
  8.   glScalef(Scale,Scale,Scale);
  9.  
  10.   glInitNames;
  11.   glPushName(0);
  12.  
  13.   for i:=0 to High(Items) do
  14.   begin
  15.     glColor3b(
  16.       Items[i].FillColor[0],
  17.       Items[i].FillColor[1],
  18.       Items[i].FillColor[2]
  19.     );
  20.     GLMode:=GL_POLYGON;
  21.     glLoadName(Items[i].Handle);
  22.     glBegin(GLMode);
  23.         for a:=0 to Items[i].Contour.Count-1 do
  24.         begin
  25.           glVertex3f(
  26.             Items[i].Contour.Points[a].X,
  27.             Items[i].Contour.Points[a].Y,
  28.             Items[i].Contour.Points[a].Z
  29.           );
  30.         end;
  31.      glEnd;
  32.     end;
  33.   end;
  34.  
  35.   SwapBuffers(DC);
  36.  


Beim Init rufe ich folgendes auf:
Code:
  1.  
  2.   glMatrixMode(GL_PROJECTION);
  3.   glLoadIdentity;
  4.   glViewport(0,0,WinControl.ClientWidth,WinControl.ClientHeight);
  5.   glOrtho(0,WinControl.ClientWidth,0,WinControl.ClientHeight,0,128);
  6.  


Die Objektverschiebung habe ich mit folgendem OnMouseMove Event auf einem Panel angedacht:
Code:
  1.  
  2.   Viewport.CalculateCursorByViewport(X,Y);
  3.  
  4.     vector.TranslateContour(
  5.       Viewport.Items[0].Contour,
  6.       Viewport.Cursor.Drawing.X-PntMouseDown.X,
  7.       Viewport.Cursor.Drawing.Y-PntMouseDown.Y,
  8.       0
  9.  
  10.     );
  11.  
  12.     PntMouseDown:=PolyPoint3D(
  13.       Viewport.Cursor.Drawing.X,
  14.       Viewport.Cursor.Drawing.Y,
  15.       0,0
  16.     );
  17.  

PntMouseDown wird OnMouseDown gesetzt und die Funktion CalculateCursorByViewport sieht so aus:
Code:
  1.  
  2.   Cursor.Viewport.X:=X;
  3.   Cursor.Viewport.Y:=Y;
  4.   Cursor.Drawing.X:=(X*(1/Scale)-(XPos*(1/Scale)));
  5.   Cursor.Drawing.Y:=(WinControl.ClientHeight-Y-1)*(1/Scale)-(YPos*(1/Scale));
  6.  


Die Funktion TranslateContour habe ich folgendermaßen implementiert:
Code:
  1.  
  2. procedure TranslateContour(var Contour:TContour;DX,DY,DZ:Single);
  3. var
  4.   i:integer;
  5. begin
  6.   for i:=0 to Contour.Count-1 do
  7.   begin
  8.     with Contour.Points[i] do
  9.     begin
  10.       X:=X+DX;
  11.       Y:=Y+DY;
  12.       Z:=Z+DZ;
  13.     end;
  14.   end;
  15.   with Contour.Dimensions do
  16.   begin
  17.     XMin:=XMin+DX;
  18.     XMax:=XMax+DX;
  19.     YMin:=YMin+DY;
  20.     YMax:=YMax+DY;
  21.     ZMin:=ZMin+DZ;
  22.     ZMax:=ZMax+DZ;
  23.   end;
  24. end;
  25.  


Das Projekt habe ich jetzt mal nicht angehängt, weil es die msxml2_tlb (msxml6) braucht und ich nicht sicher bin, ob ihr die habt...
Hat jemand ne Idee, wie ich das ganze etwas tunen könnte?

VIELEN, VIELEN DANK!!
Flo


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 24, 2006 17:55 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 23, 2006 17:48
Beiträge: 24
:roll:
Hab mittlerweile rausgefunden, dass ich mir die TranslateContour wohl sparen kann und einfach dem TEntity X,Y,Z hinzufügen kann, welches ich mit glTranslatef anwende :lol:
Trotzdem bin ich offen für weitere Tweaks ;)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 24, 2006 18:54 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
Gibt noch die übliche Möglichkeiten à la Displaylisten. Dann solltest du versuchen glBegin() und glEnd zusparen indem du die entsprechenden Objekte mit dem gleichen GLMode zusammenfasst.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 24, 2006 18:59 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 23, 2006 17:48
Beiträge: 24
Hab gelesen, dass Displaylisten wohl nicht so schnell erzeugt werden sollen. Wenn ich dann eine Echtzeitansicht während der Drehung eines Objektes haben möchte, sollte ich es dann außerhalb der Liste zeichnen, oder?

Wg. Zusammenfassen: Kann ich glLoadName und glTranslatef innerhalb eines glBegin/End Blocks verwenden?

Edit:
Nochwas:
Eigentlich isses ja Verschwendung, wenn ich Render bei Application.OnIdle aufrufe. Würde ja reichen, wenn ich es OnMouseMove und OnFormShow/Resize aufrufe.
Allerdings hab ich noch nicht ganz geblickt, wo ich das ganze das erste Mal aufrufen soll, damit ich überhaupt was sehe, wenn ich die Anwendung starte.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 24, 2006 19:16 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
Ok, das mit glBegin-glEnd geht nicht, da glLoadname dadrinnen nicht aufgerufen werden darf.

Wegen der Displaylisten:
Die erzeugst du nur einmal und rufst dann einfach die Displaylisten ab, daher werden sie nur einmal erstellt.
Das mit dem Translate und Rotate ist kein Problem solange deine Strukturen entsprechend aufgeteilt sind.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 25, 2006 07:52 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
So. Als erstes einmal. Habe ich das Richtig gelesen? TNT1? Erwarte bitte keine Wunder von dieser Karte. Selbst bei 400 Flächen dürftest du damit schon hart am Limit sein. Bei einer 2400+ Maschiene hätte ich aber keine TNT 1 erwartet. ;-)

DL: Auf dieser Karte sind DLs genau so schnell wie VertexArrays (Clientseitig) oder das Rendern in einer Schleife. DLs entfalten sich erst richtig, wenn die Karte in der Lage ist die Vertexdaten im Speicher abzulegen. Und die TNT ist es nicht. Allerdings sollte dein Programm auf neueren Karten laufen bietet sich es schon an. Dann aber bitte darauf achten, dass du nur dein Polygon in die DL Packst. Das Skalieren, Rotieren, Farbe etc sollte alles außerhalb passieren.

Wobei wir auch schon beim Nächsten wären. Weißt du, dass GL_POLYGON recht langsam ist und nur konvexe Polygone kann? Solltet du also auch Polygone haben die Konkav sind so musst du diese Tessletieren. Also vorab in einzelne Dreiecke zerlegen. Dabei könnte gluTessBeginPolygon für dich ganz interessant werden.

Sonst kann i0n0s nur zustimmen. Lass so viel wie möglich weg. Allerdings ist der Code schon sehr schmal und ich denke, dass man daran kaum noch etwas verändern kann. Bis auf die Sache mit den Polygon evtl bringt das schon ein bisschen. Aber sonst denke ich es wäre besser du findest dich damit ab, dass die Karte einfach nicht zu mehr im Stande sein wird. Für mich sieht der Code nämlich schon reichlich schmal aus.

Zeichnen auf verlangen. Du kannst nicht nur dann zeichnen, wenn du die Maus betätigst. Benutze dafür das OnPaint des Formulars. Sobald ein anderes Fenster über dein Fenster malt wird so automatisch neu gerendert. Wenn du jetzt die Maus bewegst oder sonst etwas machst genügt es, wenn du dann Form.Repaint aufrufst damit neu gerendert wird. Und OnIdle kannst du dann komplett weglassen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 25, 2006 13:05 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Für die Frage was ein Befehl kann ("Darf man xyz in glBegin aufrufen") gibts das DGL-Wiki. Einfach bei den Befehlen mal die Fehlermeldungen angucken, oder aber glBegin selbst. Da steht auch noch was dazu.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 15 Queries | GZIP : On ]