Autor Beitrag
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Do 08.05.08 14:44 
Folgendes Problem:
Ich habe ca. 1 Mio Koordinaten die ich mit glBegin(GL_LINE_STRIP) zeichne. Um das zu beschleunigen hab ich das in eine Liste (glNewList) ausgelagert.
Das funktioniert super und ist schnell genug.

Wenn ich nun aber die Linienbreite erhöhe, dann ist das total langsam.
ausblenden Delphi-Quelltext
1:
2:
3:
   glNewList(FList, GL_COMPILE);
   glLineWidth(2);
   ...


Das Problem dabei ist nicht etwa, dass glCallList(FList) ewig dauert (das geht gleich schnell), sondern SwapBuffers braucht auf einmal ewig lang!. Irgendwie kommts mir so vor, dass opengl wenn glLineWidth > 1 ist per GDI zeichnet.
Kennt jemand das Problem und weiß eventl. eine Lösung?

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Do 08.05.08 14:59 
Breite Linien zu rastern ist einfach wesentlich komplizierter... Bekannt ist mir das Problem also durchaus.

Wobei, 1 Million? Müssen die wirklich immer alle gerendert werden? Hier würde ich ansetzen, wenn ich das optimieren sollte.
Was renderst du denn schönes?

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
uall@ogc Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Do 08.05.08 15:16 
ja ggf müssen alle gerendert werden.

Wenn ich aber statt ner Linie, nen QUAD zeichne (was dann bisl dicker ist) gehts wieder schnell.

Zwischen 20msek und 780msek im Durchschnitt ist es aber für die doppelte Breite schon bisl krass. Das sind 50FPS vs 1FPS...

Warum SwapBuffers so lange dauert is nu klar, denn erst da werden die Daten an die Graka geschickt (gdi32.ExtEscape)

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Do 08.05.08 15:28 
OpenGL arbeitet asynchron. Du darfst also nicht immer davon ausgehen, dass der Aufruf abgearbeitet ist sobald er zurück kommt. Besonders bei Displaylisten/VBOs. Die Wartezeit kommt immer dann zum Tragen, wenn eine Operation aufgerufen wird die vorraussetzt, dass alle Operationen abgeschlossen sind. So zum Beispiel beim Swapen. Dann muss die Grafikkarte komplett fertig gezeichnet haben. Oder es wird eben gewartet.

Die Breite der Linien hat mitunter einen starken Einfluss auf die Geschwindigkeit. Alleine schon, weil eine breitere Linie bedeutet, dass die Grafikkarte doppelt so viele Pixel in den Buffern befüllen muss. Je nach Karte kannst du da auch sagen. Größe * 2 = Geschwindigkeit / 2.

OpenGL unterscheidet 2 Linientypen. SMOOTH und normalen Linien. Setzen kannst du dies mit glHint(GL_LINE_SMOOTH_HINT, GL_NICEST oder GL_FASTEST);. Ich denke was da was ist sollte selbsterklärend sein.

Außerdem haben die Linien einen Größenbereich den die Karte unterstützen. Die Je nach Linientyp kannst du die Größen mit glGetIntegerfv(GL_LINE_WIDTH_RANGE; (array [0..1of single;)) und glGetIntegerfv(GL_SMOOTH_LINE_WIDTH_RANGE, ...) erfragen. Dabei werden 2 Werte zurückgeliefert. Erste Stelle min und zweite max.

So eine wirklichen Lösungsvorschlag dazu kann ich dir leider nicht geben. Das Einzige was evtl etwas bringt ist das Smoothing zu entfernen (fastest). Falls das bereits der Fall ist, dann kann es auch an der Grafikkarte liegen. Aktuell werden die Karten primär nur auf Polygone optimiert und so etwas wie Linien etc sind nur noch rudimentär vorhanden. Es kann auch gut sein, dass der Treiber bei dir in den Softwaremodus umschaltet. Wenn es Faktor ~ 50+ langsamer ist, dann wird es auf der CPU berechnet. Das ist leider ein Trend den die Großen der Branche vermehrt einschlagen.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
uall@ogc Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Do 08.05.08 15:50 
Danke erstmal, ich hab nen kleines TestProg geschrieben, was das Problem verdeutlicht (glLineWidth = 2) dann dauerts bei mir 10 mal so lang.

Vielleicht kann das mal jemand testen. Ich habe hier eine Matrox Karte drin... eben aus meinem Projekt extrahiert :)


EDIT: Hab gerade damit nen PC gecrasht oO. Also vorher mal alles speichern :)
Einloggen, um Attachments anzusehen!
_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Do 08.05.08 16:04 
Ähm, wieso geht das bei dir?

Eigentlich kann man auf das Desktop-Window kein Handle holen, weil man das Pixelformat nicht ändern kann...

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Do 08.05.08 16:04 
Hallo,

ich würde dein Programm ja gerne testen, aber da kommt immer ein "unbekannter Softwarefehler". Was mich an dem Code wundert: Du erstellst nirgends ein Fenster - und genau an der Stelle, als du den Rendering Context zum nicht vorhandenen Fenster erstellen willst, kommt bei mir der Fehler. Wie wohin willst du eigentlich zeichnen? Klappt das bei dir wirklich?

Vielleicht kannst du deine Frage auch nochmal im DelphiGL posten - das ist ein Forum, das sich ausschließlich um OpenGL dreht.

Grüße,
Yogu

Mist, zu spät :(
uall@ogc Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Do 08.05.08 16:06 
ähm ja war eben zusammengeschustert, habs uach aufn nem anderen Rechner getestet, da kam auch nen Fehler.
Ich glaub ich muss ma ne kleine Testapp schreiben bei der man auch was sieht.

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 08.05.08 16:10 
Bei mir schmiert's Programm auch weg (GeForce 7600 GTX - Notebook ;-)).

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Do 08.05.08 16:15 
Alternativ kannst du auch mal glView bei dir ausprobieren. Der zeigt alle möglichen Extension und Min/Max Werte von OpenGL an. Aber frag mich nicht wo. Ich habe gerade nur gesehen, dass die die Oberfläche komplett geändert haben.

Zeichnen auf Desktop. Man kann ein Pixelformat nur einmal pro DC auswählen. Aber ich meine es geht auch, wenn man keines auswählt. Aber dann hat man unter Umständen keinen Doublebuffering was wiederum keinen Sinn machen würde. Aber Fenster solltest du wirklich machen. Wer weiß was der Treiber alles optimiert, wenn kein Fenster da ist. Hier gings im übrigen. Aber die Karte ist sehr beschränkt, weswegen die Ergebnisse (2x 1) rein gar nichts aussagen!


PS: Du hast dir ne Matrix aus deinem Projekt extrahiert? ;)

[edit]PPS: Es gibt seit geraumer Zeit eine neue dglOpenGL.pas (die ohne .NET). Dort wurde einiges an Balast entfernt.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
uall@ogc Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Do 08.05.08 16:37 
hier ein neues Beispiel:

Matrox Graka: Linie(1) = 200msek (1.mal) danach 30msek
Matrox Graka: Linie(2) = 900msek (immer)

Nvidia Graka: Linie(1) = 0msek
Nvidia Graka: Linie(2) = 0msek
Einloggen, um Attachments anzusehen!
_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
alias5000
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: Do 08.05.08 17:04 
ATI (Radeon 9600 XT): beides mal 0

_________________
Programmers never die, they just GOSUB without RETURN
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Do 08.05.08 17:11 
NVIDIA GeForce4 MX 4000:

Breite 1: ca. 550 ms
Breite 2: ca. 800 ms

Ich möchte noch anmerken, dass ich einfache OpenGL-Anwendungen durchaus mit 60 FPS rendern kann...
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Do 08.05.08 19:29 
Also beim ersten Mal immer 16ms und anschließend ziemlich genau 0ms. Ist beim ersten Mal evtl die Displaylistengenearion dort mint enthalten oder zu knapp davor? Mit deaktivierter OpenGL Beschleunigung liegt das immer bei ca 94 und 359ms. Also nicht nur das Doppelte sondern fast das Vierfache.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Do 08.05.08 19:48 
user profile iconLossy eX hat folgendes geschrieben:
Also beim ersten Mal immer 16ms und anschließend ziemlich genau 0ms.

Falls hier GetTickCount verwendet wird, heißt dass nichts. Wenn die Zeit unter einer Grenze liegt, kommt immer so etwas um den Dreh raus. Wenn du das nicht schon tust, user profile iconuall@ogc, solltest du lieber Suche in: Delphi-Forum, Delphi-Library QUERYPERFORMANCECOUNTER verwenden. Das geht bis auf Mikrosekunden genau.

Grüße,
Yogu
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Do 08.05.08 21:37 
Mich würde mal interessieren wie viele Linien das jetzt waren und wie viele davon außerhalb des Bild waren. Meines Wissens nach clippen einige Treiber Geometrie die außerhalb liegt. Was dann erwartungsgemäß schneller gehen sollte. Beim Messen solltest du auch berücksichtigen, dass es komplett fertig arbeitet. Also inklusive SwapBuffer.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
uall@ogc Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Fr 09.05.08 08:36 
Ja SwapBuffer ist in der Messung drin, Anzahl der Linien waren 500k
Es wird auch GetTickCount genutzt, was aber in meinem Fall ausreicht.

Ob nun geclipt wird is mir auch egal. Es geht mir daraum, dass auf manchen Grakas, der 1. Aufruft mit glLineWidth(1) lange dauert, danach realtiv schnell. Aber bei glLinewidth(2) manchmal mehr um das 4 Fache dauert. ich hab Schwankungen von dem 4-30!! fachen im Gegensatz zu glLineWidth(1)

@Yogu:
NVIDIA GeForce4 MX 4000:
Breite 1: ca. 550 ms
Breite 2: ca. 800 ms

Das sind normale Werte. Das glLineWidth(2) bis doppelt so lange dauert bei einer alten Graka passt schon.

Wenns aber > 4mal so lange dauert, glaub ich immer es wird per GDI gezeichnet oO
Einloggen, um Attachments anzusehen!
_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Fr 09.05.08 09:40 
user profile iconuall@ogc hat folgendes geschrieben:
Wenns aber > 4mal so lange dauert, glaub ich immer es wird per GDI gezeichnet oO

Die Treiber sind leider in der Lage fehlende Funktionalität selber nachlegen zu dürfen. Von OpenGL wird nur die Schnittstelle definiert. Aber es hat niemand gesagt, dass es alles per Hardware gemacht werden muss. Leider gibt es auch keine Möglichkeit so etwas zu erfragen. Das merkt man dann meistens wenn es zu langsam ist.

Mein klassisches Beispiel in diesem Fall sind die Chipreihen der Radeon 9700 etc. Texturen die als Größe keine Potenz von 2 haben werden unterstützt aber sobald MipMaps aktiv sind verfällt der Treiber in einen Softwaremodus. Es werden aber auch nur die Texturen im Treiber berechnet und sollten diese klein genug sein so fällt das kaum auf. Genau genommen hätten also die 9700er kein OpenGL 2.0 unterstützen dürfen. Zu mindest wenn alles in Hardware hätte sein müssen. Aber NVidia macht so etwas auch. Ich meine nur da war es was mit Shadern.


Zu der Verzögerung bei der ersten Benutzung. Ich kann mir gut vorstellen, dass beim ersten Aufruf verschiedene Dinge auf der Krafikkarte initialisiert werden müssen. Das ist aber wieder vollkomme Sache des Treibers weswegen man das nicht genau sagen kann. Spontan würden mir da aber 2 Dinge einfallen.
1) Entweder erzeugt das erste Mal swappen so einen Effekt. Glaube ich aber eher nicht. Bin aber auch schon überrascht worden. Das kann man aber auch recht einfach testen. Einfach vorher mal nen SwapBuffer auf einen leeren Buffer machen und schauen ob sich was tut.
2) Oder aber die Displayliste wird erst bei der ersten Benutzung wirklich zur Grafikkarte übertragen. Das glaube ich schon eher. Denn auf modernen Grafikkarten werden innerhalb der Displaylisten Vertex Buffer Objects benutzt. Damit liegen die Vertexdaten auf der Grafikkarte. Das geht aber nur wenn man genau weiß wie groß die Daten sind. Was bei einer DL für den Treiber nicht möglich ist bzw. frühstens erst bei glEndList.

Um das zu umgehen kannst du direkt VBOs benutzen. Die Daten kann man dann auch nachträglich ändern und muss nicht alles neu erstellen lassen. Auf richtig alten Karten oder welche ohne Datenspeicher werden aber keine VBOs in Hardware unterstützt. Aber NVidia hat es da im Treiber nachgebaut und ich meine ATI auch. Aber diese Lösung ist dann nicht oder nur kaum schneller als wie wenn man mit VertexArrays oder iterativ rendert.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 09.05.08 09:44 
nVIDIA GeForce 7600 GTX
Beide Male 0ms; selbst bei 1440x1050 Fensterauflösung ;-)

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 09.05.08 15:26 
bei mir bricht dein programm ab. "windows hat ein problem festgestellt und muss beendet werden..."