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

Aktuelle Zeit: Do Mär 28, 2024 18:23

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 15 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Fr Apr 28, 2017 17:52 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Bei diesem Tutorial-Code, werden veränderte Vertex-Daten zur Laufzeit neu geladen.

Ist dies der sauberste Weg, oder habe ich einen Schönheits-Fehler eingebaut.
Ich will ja nichts falsches weiter geben.


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Mai 06, 2017 22:59 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Mein OpenGL ist inzwischen zwar ganz schön eingerostet (seit Vulkan zieht mich nix mehr in Richtung GL), aber bei regelmäßigen Buffer-Updates (die da wohl gemacht werden) sollte man afair eher mit sowas wie glMapBuffer arbeiten. glBufferData sollte man wenn überhaupt nur für einmalig (oder selten) statisch zu füllende Daten verwenden, das ist in einem Beispiel wohl nicht der Fall.

P.S. : Die Kommentare beinhalten noch viele Rechtschreibfehler.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Mai 07, 2017 17:15 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
aber bei regelmäßigen Buffer-Updates (die da wohl gemacht werden) sollte man afair eher mit sowas wie glMapBuffer arbeiten.

Ich habe mir das näher angeguckt, nur mit glMapBuffer kann ich nichts gescheites finden.

Zitat:
P.S. : Die Kommentare beinhalten noch viele Rechtschreibfehler.

Ich habe selbst viele Fehler gefunden und behoben.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Mai 08, 2017 16:29 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Es stimmt dass man glBufferData vermeiden sollte (da das einen vollständig neuen Buffer allokiert und damit die gleichen Probleme hat wie glMapBuffer), aber glBufferSubData kann bei weitem besser sein als glMapBuffer.

glBufferSubData hat (aus Treibersicht) den Vorteil, dass das schreiben auf die Hardware asynchron passieren kann. Bei glMapBuffer muss die Verwendung des Buffers auf der GPU angehalten sein (zumindest wenn glMapBuffer als tatsächliches memory mapping implementiert wird etc.etc.). Wenn man nur glBufferSubData verwendet kann die GPU sogar für jeden Frame intern einen neuen Buffer anlegen und den alten wegschmeißen, sozusagen vollständig immutable buffer haben.

viele Grüße,
Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Mai 08, 2017 19:14 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Ich habe mal glBufferData durch glBufferSubData ersetzt, ab dann bleibt die Mesh schwarz.
Wen ich es bei Vector auch noch mache, dann kommt gar keine Mesh mehr.
Was verstehe ich da falsch ?
Code:
  1.  with CircleMesh[MeshNr] do begin
  2.     glBindVertexArray(VBuffer.VAO);
  3.  
  4.     // Vektor
  5.     glBindBuffer(GL_ARRAY_BUFFER, VBuffer.VBOvert);
  6. //    glBufferSubData(GL_ARRAY_BUFFER,0, sizeof(TFace) * size, Pointer(Vector));
  7.     glBufferData(GL_ARRAY_BUFFER, sizeof(TFace) * size, Pointer(Vector), GL_STATIC_DRAW); // neu mit Pointer
  8.     glEnableVertexAttribArray(10);
  9.     glVertexAttribPointer(10, 3, GL_FLOAT, False, 0, nil);
  10.     SetLength(Vector, 0);         // Daten im VRAM entfernen.
  11.  
  12.     // Farbe
  13.     glBindBuffer(GL_ARRAY_BUFFER, VBuffer.VBOcol);
  14.     glBufferSubData(GL_ARRAY_BUFFER,0, sizeof(TFace) * size, Pointer(Color));
  15. //    glBufferData(GL_ARRAY_BUFFER, sizeof(TFace) * size, Pointer(Color), GL_STATIC_DRAW);
  16.     glEnableVertexAttribArray(11);
  17.     glVertexAttribPointer(11, 3, GL_FLOAT, False, 0, nil);
  18.     SetLength(Color, 0);
  19.   end;  

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Mai 08, 2017 21:48 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
So scheint es zu funktionieren.

Ist es richtig, das ich GL_DYNAMIC_DRAW verwende oder wäre GL_STATIC_DRAW besser ?
Code:
  1. procedure TForm1.CreateScene;
  2. var
  3.   i: integer;
  4. begin
  5.   Shader := TShader.Create([FileToStr('Vertexshader.glsl'), FileToStr('Fragmentshader.glsl')]);
  6.   Shader.UseProgram;
  7.  
  8.   for i := 0 to Length(CircleMesh) - 1 do begin
  9.     with CircleMesh[i] do begin
  10.       glGenVertexArrays(1, @VBuffer.VAO);
  11.       glGenBuffers(1, @VBuffer.VBOvert);
  12.       glGenBuffers(1, @VBuffer.VBOcol);
  13.  
  14.       glBindVertexArray(VBuffer.VAO);
  15.  
  16.       // Vektor
  17.       glBindBuffer(GL_ARRAY_BUFFER, VBuffer.VBOvert); 
  18.       glBufferData(GL_ARRAY_BUFFER, sizeof(TFace) * maxSektor , nil, GL_DYNAMIC_DRAW); // neu mit Pointer
  19.       glEnableVertexAttribArray(10);
  20.       glVertexAttribPointer(10, 3, GL_FLOAT, False, 0, nil);
  21.  
  22.       // Farbe
  23.       glBindBuffer(GL_ARRAY_BUFFER, VBuffer.VBOcol);
  24.       glBufferData(GL_ARRAY_BUFFER, sizeof(TFace) * maxSektor, nil, GL_DYNAMIC_DRAW);
  25.       glEnableVertexAttribArray(11);
  26.       glVertexAttribPointer(11, 3, GL_FLOAT, False, 0, nil); 
  27.     end;
  28.   end;
  29. end;


Code:
  1. procedure TForm1.UpdateScene(MeshNr: integer);
  2. var
  3.   i: integer;
  4. begin
  5.   glClearColor(0.6, 0.6, 0.4, 1.0);
  6.  
  7.   with CircleMesh[MeshNr] do begin
  8.     glBindVertexArray(VBuffer.VAO);
  9.  
  10.     // Vektor
  11.     glBindBuffer(GL_ARRAY_BUFFER, VBuffer.VBOvert);
  12.     glBufferSubData(GL_ARRAY_BUFFER,0, sizeof(TFace) * size, Pointer(Vector));
  13.     SetLength(Vector, 0);         // Daten im VRAM entfernen.
  14.  
  15.     // Farbe
  16.     glBindBuffer(GL_ARRAY_BUFFER, VBuffer.VBOcol);
  17.     glBufferSubData(GL_ARRAY_BUFFER,0, sizeof(TFace) * size, Pointer(Color));
  18.     SetLength(Color, 0);
  19.   end;
  20. end;
  21.  

Verstehe ich das richtig, das mit glBufferData VRAM reserviert wird, und mit glBufferSubData der Inhalt des VRAM aktualisiert wird ?
Ein Wermutstropfen hat glBufferSubData dennoch, man muss von Anfang an wissen, wie gross die Mesh maximal wird.

Aber ich denke ein 3D-Charakter, hat immer gleich viel Polygone, nur desen Form ändert sich.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Mai 09, 2017 08:53 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
mathias hat geschrieben:
Verstehe ich das richtig, das mit glBufferData VRAM reserviert wird, und mit glBufferSubData der Inhalt des VRAM aktualisiert wird?
Ja. Deswegen sollte glBufferData nur einmal aufgerufen werden und bei darauf folgenden Updates nur noch glBufferSubData.

Das Problem, das dabei bleibt, ist implizite Synchronisation von GPU und CPU. Es kann also vorkommen, dass die GPU auf die CPU wartet (oder umgekehrt) und dabei nutzlos Däumchen dreht. Um das zu verhindern, kann man Double- oder Triple-Buffering anwenden, oder man nutzt Persistent Mapped Buffers (oder macht beides zugleich). Für letzteres brauchst du die Extension GL_ARB_buffer_storage oder OpenGL 4.4. Ich denke darauf bezog sich Sascha's Post mit glMapBuffer. Ich habe das selbst noch nicht gemacht, sollte ich aber unbedingt mal ausprobieren. Hier gibt es einen Artikel über das Warum und Wie.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Mai 09, 2017 16:57 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Für letzteres brauchst du die Extension GL_ARB_buffer_storage oder OpenGL 4.4.

Da will ich eigentlich vermeiden, da es um OpenGL 3.3 geht.

Zitat:
Ist es richtig, das ich GL_DYNAMIC_DRAW verwende oder wäre GL_STATIC_DRAW besser ?

Wie sieht es damit aus, ist dies richtig ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Mai 09, 2017 19:33 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Wenn du den Buffer jeden (oder fast jeden) Frame updatest, dann ist DYNAMIC_DRAW richtig.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 10, 2017 16:28 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
glAwesome hat geschrieben:
Wenn du den Buffer jeden (oder fast jeden) Frame updatest, dann ist DYNAMIC_DRAW richtig.

Dann wäre dies nur bei einem animierten Charakter interessant. Bei meinem Beispiel würde somit STATIC_DRAW reichen.

Was hat DYNAMIC_DRAW für einen Nachteil gegenüber STATIC_DRAW ?
Sonst könnte man immer DYNAMIC_DRAW verwenden ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 10, 2017 17:03 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Wie genau der Treiber da optimiert ist unspezifiziert. Es handelt sich lediglich um einen Hint.

viele Grüße,
Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 10, 2017 17:56 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Wie genau der Treiber da optimiert ist unspezifiziert. Es handelt sich lediglich um einen Hint.

Verstehe ich das richtig, das es auch Treiber geben könnte, bei denen dieser Parameter gar keinen Einfluss hat ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 10, 2017 17:59 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Ja. Was genau (bzw. ob überhaupt) eine Implementation mit einem Hint macht bleibt ihr überlassen. Es wird also Treiber bei denen es keinen Unterschied zwischen STATIC_DRAW und DYNAMIC_DRAW gibt. Das ist einer der Nachteile der impliziten Natur von OpenGL.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Mai 18, 2017 19:15 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Mit Indicies, kann man das selbe machen, wie mit Vertex-Daten.
Man entdeckt immer wieder was neues. :wink:
Code:
  1.     glBindVertexArray(VBuffer.VAO);
  2.  
  3.     // Vektor
  4.     glBindBuffer(GL_ARRAY_BUFFER, VBuffer.VBOvert);
  5.     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(TVertex3f) * Vec_Count, Pointer(Vector)); // Daten ins VRAM schreiben.
  6.     SetLength(Vector, 0);                                                       // Daten im RAM entfernen.
  7.  
  8.     // Farbe
  9.     glBindBuffer(GL_ARRAY_BUFFER, VBuffer.VBOcol);
  10.     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(TVertex3f) * Vec_Count, Pointer(Color));
  11.     SetLength(Color, 0);
  12.  
  13.     // Indicien
  14.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBuffer.IBO);
  15.     glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(GLint) * Indicies_Count, Pointer(Indicies));
  16.     SetLength(Indicies, 0)

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Mai 19, 2017 17:03 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Habe ich das richtig verstanden, das glBufferSubData( sehr Ressourcen sparrend ist ?

_________________
OpenGL


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 39 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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.064s | 18 Queries | GZIP : On ]