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

Aktuelle Zeit: Sa Jun 21, 2025 21:52

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



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: glMapBuffer vs glBufferData
BeitragVerfasst: Mi Jun 20, 2012 13:45 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Hallo,

ich habe doch diese Fluid Simulation Demo gebaut, bei der ich für jedes Frame die Partikel-Positionen in ein VBO schreiben muss. Damit kann ich dann diese wunderbar im Shader für meine Point Sprites nutzen, etc.
Das funktioniert auch erste sahne wie ihr ja schon gesehen habt, aber jetzt frage ich mich, ob ich das auch richtig gemacht habe (Performance-Technisch).

Ich erstelle das VBO einmalig nachdem init von OpenGL und erzeuge einen Speicherbereich für die Maximal möglichen Partikel (256000):
Code:
  1.  
  2. glGenBuffersARB(1, &iVBO);
  3. glBindBufferARB(GL_ARRAY_BUFFER_ARB, iVBO);
  4. glBufferDataARB(GL_ARRAY_BUFFER_ARB, total * sizeof(float) * 4, NULL, GL_STREAM_DRAW_ARB);
  5. glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
  6.  


Macht es einen großen Unterschied ob ich GL_STREAM_DRAW_ARB oder GL_DYNAMIC_DRAW_ARB (aktuell) nehme?

Danach ist es simpel für jedes Frame, nachdem PhysX die Scene Simuliert hat, pumpe ich die Partikel-Positionen in das VBO (allerdings mit glMapBuffer):
Code:
  1.    
  2. glBindBufferARB(GL_ARRAY_BUFFER_ARB, iVBO);
  3. float* buffer = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY);
  4. ... fill vec4 buffer with particle positions
  5. glUnmapBuffer(GL_ARRAY_BUFFER_ARB);
  6. glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
  7.  


Habe gelesen das es einen Performance-Unterschied macht ob man glBufferData() oder glMapBufferARB() nutzt, stimmt das?
Hier die quelle: http://www.stevestreeting.com/2007/03/17/glmapbuffer-vs-glbuffersubdata-the-return/

Aktuell ist es so das ich pro Frame mind. 30000 Partikel auf einem Rutsch aktuallisieren muss, also die Partikel die tatsächliche Anzahl an Partikel... das entspricht also 480kb an daten und bei 100k partikel wären das schon 1,6 mb. Ist es hier sinnvoll das VBO auf kleinere VBO´s aufzuspalten und mehrere Drawcalls zu machen? Wäre das arg viel schneller?

Gruß und Danke,
Final


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glMapBuffer vs glBufferData
BeitragVerfasst: Mi Jun 20, 2012 13:58 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

das Aufteilen macht denke ich nur Sinn, wenn du nicht alle Daten hoch schieben musst. Wenn du es aufteilst un dann trotzdem alle VBOs aktualisieren musst wird es denke ich sogar langsamer, weil du ja zwischendurch noch die Buffer umbinden musst.
Wie genau bekommst du die Daten von PhysX? Wenn es ein Array mit den Daten ist, das du nicht aufbereiten musst, dann ist glBufferData eig schneller, weil du alles in einem Ruck hoch schieben kannst. Evtl wäre es auch möglich, den Pointer von glMapBuffer so zu manipulieren, das du ihn gleich an PysX übergeben kannst. Dann musst du dich gar nich großartig um die Aktualisierung der Daten kümmern.

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glMapBuffer vs glBufferData
BeitragVerfasst: Mi Jun 20, 2012 14:38 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Bergmann89 hat geschrieben:
Hey,

das Aufteilen macht denke ich nur Sinn, wenn du nicht alle Daten hoch schieben musst. Wenn du es aufteilst un dann trotzdem alle VBOs aktualisieren musst wird es denke ich sogar langsamer, weil du ja zwischendurch noch die Buffer umbinden musst.
Wie genau bekommst du die Daten von PhysX? Wenn es ein Array mit den Daten ist, das du nicht aufbereiten musst, dann ist glBufferData eig schneller, weil du alles in einem Ruck hoch schieben kannst. Evtl wäre es auch möglich, den Pointer von glMapBuffer so zu manipulieren, das du ihn gleich an PysX übergeben kannst. Dann musst du dich gar nich großartig um die Aktualisierung der Daten kümmern.

MfG Bergmann.


Also ich bekomm von PhysX nen vec3 pointer zurück, allerdings benötige ich in für VBO die 4 komponente (W) die ich aus dem Partikeldruck berechne die als Float Pointer zurückkommt.

W ist sozusagen die Partikelgröße. Partikel die nah bei einander liegen, haben einen hohen druck und welche die gar keine nachbarn haben einen niedrigeren. Das ist wichtig, damit herumfliegende alleinstehende Partikel nicht so groß sind wie die anderen. Wirkt einfach besser. Übrigens: Diese änderung habe ich erst seit 2 Versionen drin. Vorher hätte ich tatsächlich wohl die Daten direkt rüberpumpen können :(


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glMapBuffer vs glBufferData
BeitragVerfasst: Mi Jun 20, 2012 15:12 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Hm, da würde ich dann zwei VBOs machen. Einen für den vec3, meinetwegen als glVertexPointer anmelden und einen für den float, als glTexCoordPointer. Dann kannst du die Daten bei beiden einfach direkt rüberkopieren. Beim Rendern beide VBOs binden und yay :).

grüße

_________________
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  
 Betreff des Beitrags: Re: glMapBuffer vs glBufferData
BeitragVerfasst: Mi Jun 20, 2012 16:46 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Lord Horazont hat geschrieben:
Hm, da würde ich dann zwei VBOs machen. Einen für den vec3, meinetwegen als glVertexPointer anmelden und einen für den float, als glTexCoordPointer. Dann kannst du die Daten bei beiden einfach direkt rüberkopieren. Beim Rendern beide VBOs binden und yay :).

grüße


Verdammt, das würde gehen... aber dummerweise muss ich alle Partikel auf gültigkeit prüfen und vor allem schauen ob dieser den "Drain" zustand hat, und dann zurück zum VBO schreiben. Daher kann ich nicht einfach das ohne Prüfung uploaden.

Das sieht genau so aus (data ist der mappte speicherbereich im VBO):
Code:
  1. void
  2. CFluidSystem::writeToVBO(float* data, unsigned int &count, const bool noDensity, const float minDensity)
  3. {
  4.     vector<PxU32> deletedPartices;
  5.     count = 0;
  6.     PxParticleFluidReadData* rd = this->particleFluid->lockParticleFluidReadData();
  7.     if (rd)
  8.     {
  9.         int idx = 0;
  10.         PxStrideIterator<const PxParticleFlags> flagsIt(rd->flagsBuffer);
  11.         PxStrideIterator<const PxVec3> positionIt(rd->positionBuffer);
  12.         PxStrideIterator<const PxF32> densityIt(rd->densityBuffer);
  13.         for (unsigned i = 0; i < rd->validParticleRange; ++i, ++flagsIt, ++positionIt, ++densityIt)
  14.         {
  15.             bool drain = *flagsIt & PxParticleFlag::eCOLLISION_WITH_DRAIN;
  16.             if (drain) {
  17.                 deletedPartices.push_back(i);
  18.             }
  19.             if (*flagsIt & PxParticleFlag::eVALID && !drain)
  20.             {
  21.                 data[idx+0] = positionIt->x;
  22.                 data[idx+1] = positionIt->y;
  23.                 data[idx+2] = positionIt->z;
  24.                 if (!noDensity) {
  25.                     data[idx+3] = *densityIt;
  26.                     if (data[idx+3] > 1.0f) data[idx+3] = 1.0f;
  27.                     else if (data[idx+3] < minDensity) data[idx+3] = minDensity;
  28.                 } else {
  29.                     data[idx+3] = 1.0f;
  30.                 }
  31.                 idx+=4;
  32.                 count++;
  33.             }
  34.         }
  35.         rd->unlock();
  36.     }
  37.     if (deletedPartices.size() > 0) {
  38.         releaseParticles(PxStrideIterator<PxU32>(&deletedPartices[0]), deletedPartices.size());
  39.     }
  40. }
  41.  


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glMapBuffer vs glBufferData
BeitragVerfasst: Mi Jun 20, 2012 17:26 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Macht es einen großen Unterschied ob ich GL_STREAM_DRAW_ARB oder GL_DYNAMIC_DRAW_ARB (aktuell) nehme?

Das kann je nach Treiber/Grafikkarte einen großen Unterschied machen. Auf meiner Grafikkarte (Geforce 9800 GT) ist z.B. aus mir nicht ersichtlichen Gründen GL_STATIC_DRAW auch für dynamische (!!) Daten am schnellsten.
=> Ausprobieren!

Zitat:
Habe gelesen das es einen Performance-Unterschied macht ob man glBufferData() oder glMapBufferARB() nutzt, stimmt das?

Die Performance von glBufferData entspricht der von glMapBuffer mit GL_WRITE_ONLY, wenn du einfach ein memcpy aufrufst und nur Daten kopierst. Intern wird da nicht viel mehr passieren. Der Vorteil von glMapBuffer ist das du mehr Kontrolle hast: Du kannst die Daten aufbereiten ohne sie zwischen durch speichern zu müssen. In so einem Fall ist glMapBuffer natürlich doppelt so schnell...weil du einen Kopiervorgang sparst.
Wenn du GL_READ_WRITE benutzt muss natürlich der Buffer auch noch zuerst von der Grafikkarte in den Systemspeicher kopiert werden.

Zitat:
Ist es hier sinnvoll das VBO auf kleinere VBO´s aufzuspalten und mehrere Drawcalls zu machen? Wäre das arg viel schneller?

Mehrere Drawcalls sind nie schneller als ein einziger, eher umgekehrt. Es sein den du hast zwischendurch Bereiche im Buffer die du gar nicht rendern willst (etwa deaktivierte Partikel), dann würde das natürlich Sinn machen. Aber selbst in diesem Fall kannst du einen VBO benutzen und diesen mit mehreren eingeschränkten Drawcalls verwenden.

Es macht mehr Sinn dafür zu sorgen das deine Partikel direkt hintereinander im Speicher liegen. Wenn du sowieso in jedem Frame den Buffer neu schreibst kannst du ihn bei der Gelegenheit auch gleich komprimieren (also beim schreiben deaktivierte Partikel überspringen).

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glMapBuffer vs glBufferData
BeitragVerfasst: Mi Jun 20, 2012 17:37 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Coolcat hat geschrieben:
Es macht mehr Sinn dafür zu sorgen das deine Partikel direkt hintereinander im Speicher liegen. Wenn du sowieso in jedem Frame den Buffer neu schreibst kannst du ihn bei der Gelegenheit auch gleich komprimieren (also beim schreiben deaktivierte Partikel überspringen).

Genau das passiert ja schon, ich schreibe nur die aktiven Partikel hintereinander in das VBO, zähle natürlich die Anzahl mit das beim rendern auch nur die korrekte aktive anzahl gerendert wird.

Aber ich sehe schon, viel kann ich nicht machen - übrigens GL_STREAM_DRAW ist gut 10 fps besser als DYNAMIC oder STATIC bei 100k partikel.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glMapBuffer vs glBufferData
BeitragVerfasst: Do Jun 21, 2012 12:25 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Du könntest die Selektion der aktiven Partikel durch einen Indexpuffer umsetzen. Dann schreibst du zwar evenutell zu viele Daten auf die Grafikkarte, wenn dir das aber Kopiervorgänge und Iterationen auf der CPU spart, kann das sinnvoll sein.

grüße

_________________
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  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 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.009s | 16 Queries | GZIP : On ]