Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi GLScene: Frage bezüglich dem erstellen von Primitives etc. (https://www.delphipraxis.net/171189-glscene-frage-bezueglich-dem-erstellen-von-primitives-etc.html)

Maiky 25. Okt 2012 09:10

GLScene: Frage bezüglich dem erstellen von Primitives etc.
 
Hallo.

Ich habe diverse Punkte als Ausgangsbasis und möchte sowohl Punktwolken, also auch diese mit Linien verbinden oder gar ein Object darstellen. Ich habe alles realisiert, aber es ist extrem langsam und bei einer Aufbauzeit von 15-20s nicht in der Form brauchbar. Vielleicht kann mir jemand sagen ob ich hier was falsch mache oder es einfach so langsam ist? Wenn ich das selbe unten beschriebene Prinzip mit GLLines und GLPoints mache, dann ist es nur 1-2s bis alles angezeigt wird.
Code:
procedure TForm1.UpdateSceneMesh();
var
    nodes: TVectorList;

procedure DrawPolygon(nodes: TVectorList; LineColor : TGLColor);
var
    i : Integer;
    GLPolygon : TGLPolygon;
begin
    GLPolygon := TGLPolygon(GLDummyCube1.AddNewChild(TGLPolygon));
    GLPolygon.BeginUpdate;
    GLPolygon.Material.FrontProperties.Emission.Color := LineColor.Color;

    for i := 0 to nodes.Count - 1 do
    begin
        GLPolygon.AddNode(nodes.Items[i]);
    end;

    GLPolygon.EndUpdate;
end;

begin
    GLDummyCube1.DeleteChildren;
    GLDummyCube1.BeginUpdate;

    nodes := TVectorList.Create;
{
Hier lese ich meine Punkte in ein Array ein und leere bei jedem Schleifendurchlauf die TVectorList, welche am Ende der Schleife aus den hinzugefügten Vectoren ein neues Polygon erstellt.
}
    for i:= 0 to count - 1 do
    begin
         nodes.Clear;

         nodes.AddPoint(Vector3f(x,y,z));
         nodes.AddPoint(Vector3f(x..,y..,z..));
         nodes.AddPoint(Vector3f(x..,y..,z..));
         nodes.AddPoint(Vector3f(x..,y..,z..));

         DrawPolygon(nodes,clrGreen);
    end;
end;
Das ist jetzt vereinfacht dargestellt, damit man den Code besser überschauen kann. Fehlt mir hier irgendwo ein BeginUpdate/EndUpdate oder erstelle ich gar das Polygon auf einer gänzlich falschen Art und Weise?

Maiky 25. Okt 2012 11:37

AW: GLScene: Frage bezüglich dem erstellen von Primitives etc.
 
Zitat:

Zitat von Maiky (Beitrag 1188259)
Ich habe alles realisiert, aber es ist extrem langsam und bei einer Aufbauzeit von 15-20s nicht in der Form brauchbar.

Ich habe ganz vergessen hier zu erwähnen das nur das Initialisieren so lang dauert. Wenn ich das Objekt dann im GLSceneViewer bewege, ist die Animation flüssig. Daher denke ich das ich irgendwas falsch machen muss beim erstellen der Polygone.

EDIT: Wenn ich den Inhalt der Prozedure von DrawPolygon auskommentiere, ist alles sofort berechnet. Es liegt also am Createn oder vielleicht irgendwo fehlende BeginUpdate? Oder dauert das einfach so lange? ^^

Maiky 4. Nov 2012 19:11

AW: GLScene: Frage bezüglich dem erstellen von Primitives etc.
 
Schade das scheinbar niemand zu obigen Erfahrungen gemacht hat.

Gibt es eventuell die Möglichkeit das Rendern am Schluss zu machen? Aktuell zeichnet er das Polygon sofort nach dem erstellen dieses. Eventuell gibt das ja etwas Geschwindigkeit?

Hat hier eventuell doch jemand ein kleines Beispiel, wie man hunderte Linien oder Polygone zur Laufzeit erstellt und das möglichst so das es keine halbe Minute dauert? Wäre echt super, denn irgendwas muss ich ja völlig falsch machen. :thumb:

Maiky 15. Nov 2012 14:16

AW: GLScene: Frage bezüglich dem erstellen von Primitives etc.
 
Hänge leider immer noch an dem Problem fest.:(
Es handelt sich hierbei um ca. 8200 TGLPolygon's mit jeweils 3 bis 4 Nodes. Kann man da nichts machen? Dauert das wirklich 15-20s um so etwas zu initialisieren? Bewegen lässt es sich dann in der laufenden Anwendung zwar etwas zäh, aber recht flüssig.

Uwe Raabe 15. Nov 2012 15:54

AW: GLScene: Frage bezüglich dem erstellen von Primitives etc.
 
Kannst du das Projekt oder zumindest eine abgespeckte Version (ohne daß ich dutzende Komponenten installieren muss) als ZIP anhängen oder sonstwie bereitstellen? Dann will ich mir das mal ansehen. Aber versprechen kann ich nichts.

Maiky 19. Nov 2012 13:44

AW: GLScene: Frage bezüglich dem erstellen von Primitives etc.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das ist wirklich sehr lieb gemeint. Ich habe die ZIP angehangen , aber auch hier die Unit mal reingestellt. Vielleicht sieht man so ja auch etwas?

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, GLWin32Viewer, GLCrossPlatform, BaseClasses, GLScene,
  GLObjects, GLCoordinates, GLNodes, GLColor, GLRenderContextInfo, GLMaterial, GLState, GLTexture, VectorLists, VectorTypes, ComCtrls,
  CheckLst, te_forms, te_extctrls, Math, GLGeomObjects, GLMultiPolygon;

type
  TForm1 = class(TForm)
    GLScene1: TGLScene;
    GLSceneViewer1: TGLSceneViewer;
    Button1: TButton;
    GLCamera1: TGLCamera;
    GLDummyCube1: TGLDummyCube;
    GLLightSource1: TGLLightSource;
    GLPolygon1: TGLPolygon;
    procedure Button1Click(Sender: TObject);
  private
    procedure UpdateScene();
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.UpdateScene();
var
    i,rx,rz : Integer;
    nodes : TGLNodes;

procedure DrawPolygon(nodes: TGLNodes);
var
    i : Integer;
    GLPolygon : TGLPolygon;
begin
    //application.processmessages();

    GLPolygon := TGLPolygon(GLDummyCube1.AddNewChild(TGLPolygon));
    GLPolygon.BeginUpdate;
    GLPolygon.Material.FrontProperties.Emission.Color := clrRed;
    GLPolygon.Material.PolygonMode := pmFill;
    //GLPolygon.Material.PolygonMode := pmLines;

    GLPolygon.Nodes := nodes;
{
    for i := 0 to nodes.Count - 1 do
    begin
        GLPolygon.AddNode(nodes.Items[i]);
    end;
}
    GLPolygon.EndUpdate;
end;

procedure DrawNodes(var nodes: TGLNodes);
var
    j : Integer;
    node: TGLNode;
begin
    DrawPolygon(nodes);

    // Darstellung spiegeln
    for j := 0 to nodes.Count - 1 do
    begin
        node := nodes.Items[j];
        node.Y := -node.Y;
        nodes.Items[j] := node;
    end;
    DrawPolygon(nodes);
end;

begin
    GLDummyCube1.BeginUpdate;
    GLDummyCube1.DeleteChildren;

    //nodes := TVectorList.Create;
    nodes := TGLNodes.Create(GLDummyCube1);

    for i := 0 to 5000 do
    begin
        rx := Random(200);
        rz := Random(100);
        nodes.Clear;
        nodes.AddNode(-100+rx,0,-55+rz);
        nodes.AddNode(-90+rx,0,-55+rz);
        nodes.AddNode(-95+rx,0,-50+rz);
        DrawNodes(nodes);
    end;

    GLDummyCube1.EndUpdate;
    nodes.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    UpdateScene();
end;

end.
Ich habe ca. 17.000 Polygone (ca. 8500 die ich dann noch spiegele, da die Polygone nur das halbe Object darstellen) und brauche dafür so 15-20s auf meinem Rechner. Geht das wirklich nicht schneller?

Uwe Raabe 19. Nov 2012 17:35

AW: GLScene: Frage bezüglich dem erstellen von Primitives etc.
 
Versuch mal diesen Code:

Delphi-Quellcode:
procedure DrawPolygon(nodes: TGLNodes);
var
    i : Integer;
    GLPolygon : TGLPolygon;
begin
    GLPolygon := TGLPolygon.Create(nil);
    GLPolygon.Material.FrontProperties.Emission.Color := clrRed;
    GLPolygon.Material.PolygonMode := pmFill;
    GLPolygon.Nodes := nodes;
    GLPolygon.MoveTo(GLDummyCube1);
end;
Man vermeidet hier die ganzen Notifications für das Parent Objekt.

Uwe Raabe 19. Nov 2012 17:37

AW: GLScene: Frage bezüglich dem erstellen von Primitives etc.
 
Das könnte vielleicht auch noch etwas bringen:

Delphi-Quellcode:
  procedure DrawNodes(var nodes: TGLNodes);
  var
    j: Integer;
  begin
    DrawPolygon(nodes, clRed);
    nodes.BeginUpdate;
    try
      // Darstellung spiegeln
      for j := 0 to nodes.Count - 1 do begin
        nodes[j].y := -nodes[j].y;
      end;
    finally
      nodes.EndUpdate;
    end;
    DrawPolygon(nodes, clBlue);
  end;

Maiky 19. Nov 2012 17:55

AW: GLScene: Frage bezüglich dem erstellen von Primitives etc.
 
Wow, ich bin fast sprachlos und beeindruckt. Die erste Änderung hat die Zeit von ca. 20s auf ca. 5s(!) gedrückt. Die zweite Änderung dann noch einmal um ca. 1s, so das es jetzt 3-4s dauert und das empfinde ich als Ladezeit für so viele Polygone als in Ordnung. (Für einen 10Jahre alten Rechner mit onBoard-Grafikkarte)

Vielen lieben Dank! Großartige und professionelle Hilfe.


Das es an "GLPolygon := TGLPolygon(GLDummyCube1.AddNewChild(TGLPolygon));" liegt hätte ich aber nicht angenommen. Ich vermutete eigentlich eher das der Renderer eher erstmal alle Polygone "sammeln" sollte und dann die fertige Szene einmalig rendern. Aktuell rendert er ja jedes einzelne Polygon sofort. Das habe ich bemerkt als ich mal Application.ProcessMessages(); in DrawPolygon legte und er anstatt 20s dadurch auch gleich mehrere Minuten gebraucht hatte um dann die Szene anzuzeigen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz