OpenGL- VBOs, DisplayLists und viele Fragen



  • Grüss euch...
    Hab da noch ne Frage zu OpenGL, die Nehe leider nicht beantwortet.

    Man kann in OpenGL ja auf versch. Art und Weisen rendern bzw die Daten dazu liefern:
    - Direkt per Koordinaten mit glVertex3f etc.
    - Array-Rendering über Vertex-Arrays
    - Display-Listen
    - Vertex Buffer Objects durch ARB-Extension

    Jetzt ist die Frage die ich mir stelle:
    Welche Art benutze ich für welche Art von Objekt?
    Ich dachte mir das so:
    Die direkte Methode für animierte Elemente, da sich die Daten häufig ändern -> schneller oder Denkfehler? Eigentlich werden beim Setzen von Arrays ja Zeiger übergeben - das heisst, wenn die Daten sich ändern, sollten sich auch die Daten in der OpenGl-Machine ändern und dargestellt werden. Oder kopiert OpenGL die Daten? Dann würden ja auch die restlichen Methoden für animierte Objekte wegfallen. Oder VBOs nehmen und bei jedem Frame die manipulierten Daten neu eingeben?
    Ich stells mir nur gerade nicht sehr effizient vor, bei jedem Frame ein komplettes Array mit ner for-Schleife durchzulaufen.. und das ist ja nicht nur eines, bei einer Scene können das ja durchaus einige werden.
    Statische Daten, ok, dafür sind VBOs sehr gut, wenn vorhanden auf dem System. Ansonsten kann man ja auf Vertex-Arrays ausweichen, wie im Nehe-Tut zu VBOs sehr gut erklärt und gezeigt.
    Bei VBOs stellt sich mir noch ne Frage - kann man den Speicher der Graka irgendwie überwachen? Was den restlichen Platz angeht? Wie handelt OpenGL das? Meine Graka hier hat jetzt 512MB Ram, da geht ne Menge an Daten rein, aber was bei einem User der nur 128MB hat als Bsp. Wie kann ich hier verhindern, dass ich Out of Memory gehe? Oder geht das überhaupt?
    Puh, das sind mal so die Fragen, die mir durch den Kopf jagen 🤡
    Danke euch im Voraus 🙂
    rya.



  • Vertex Arrays liegen immer in Client-Memory, kannst du also Problemlos verändern. Die eignen sich also genauso gut wie glVertex[234][bifd]() für Animationen.

    Array-Lists und VBOs sind unveränderlich / liegen in Serverspeicher -> Ersteres nur für unveränderliches, zweiteres eignet sich auch nur wenn du das nicht so oft änderst.

    Den Grafikspeicher sollte der OGL-Treiber verwalten und notfalls einfach auf den Hauptspeicher zurückgreifen, dadurch bekommst du dann keine Out-Of-Memory sondern "nur" schlchte Leistung.

    EDIT://
    Wozu der Fullquote -> raus



  • könnte man nicht bei animantionen VBOs verwenden, da man ja für jeden frame ein eigenes array speichern könnte? Das wäre auf jeden fall schneller als bei jedem render prozess als die vertexdaten der graka immer wieder neu zu schicken, das ist dann schnell der flaschenhals.
    heutige speicher müssten das eigendlich noch schaffen. den speicher kriegste nicht voll nur wenne einzelne modells(reine vertex und index daten angenommen) in den graka speicher lädst vorher haste denke ich andere performance einbußen. ich denke, dass sich die geschwindigkeit nur dann zu stark veringert, wenn du den animationen physikalische per vertex berechnungen unterziehst oder ähnliches,so dass du in jedem frame den speicher umschreibst. gehen wir davon aus, dass du nicht mehrere frames in den speicher laden willst. dann kannste trotzdem das mal durchrechnen: du willst menschen animieren, dann passt du bei redem frame die daten im speicher der graka an und kannst von nun an sehr performance sparend rendern, z.B. eine menschenmenge von 100 leuten, die gerade umhergehen. ich wäre allerdings noch für die obige variante, da man dort verschiedene zeitpunkte ansteuern könnte, sonst heben alle gleichzeitig das bein. ^^



  • Ich würde einfach für alles VBOs verwenden.

    Wenns keine VBOs gibt... pech. Wenn man unbedingt OGL Implementierungen ohne VBOs unterstützen will: für statische Geometrie Display Lists, für veränderliche Geometrie Vertex Arrays.

    Zum blossen Objekte rumbewegen/drehen/skalieren/... braucht man auch an der Geometrie nix ändern, das macht man über die Transformations-Matrix. Solche Geometrie ist also wieder "statisch".

    Animationen von Figuren o.ä. macht man wohl am Besten über Vertex Blending, bzw. ganz allgemein über Vertex Shader.



  • könnte man nicht bei animantionen VBOs verwenden, da man ja für jeden frame ein eigenes array speichern könnte

    Wenn die Animation wenig genug Frames hat, und man keine interpolierten Zustände braucht ist das natürlich eine Möglichkeit.



  • Hmm, für jeden Frame ein Array? Ich stelle mir das gerade sehr resourcen-fressend vor.
    Ausserdem kopiert OGL doch afaik die Daten, oder? Ich hab die VBOs noch nicht ganz fertig, deswegen kann ichs nicht auf die schnelle testen. Aber ich hätte dann ja per Zeiger keinen direkten Zugriff auf diese Daten. Oder ich hab das im Nehe-Artikel falsch verstanden, weil da löschen die die Daten nach dem setzen. Vor allem ist die Adresse im Hauptspeicher doch eine andere als im Grafikspeicher, oder nicht? Oder gibts ne Methode einen Zeiger dahin zu bekommen?

    // Generate And Bind The Texture Coordinate Buffer
    glGenBuffersARB( 1, &m_nVBOTexCoords ); // Get A Valid Name
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_nVBOTexCoords ); // Bind The Buffer
    // Load The Data
    glBufferDataARB( GL_ARRAY_BUFFER_ARB, m_nVertexCount*2*sizeof(float), m_pTexCoords, GL_STATIC_DRAW_ARB );
    
    // Our Copy Of The Data Is No Longer Necessary, It Is Safe In The Graphics Card
    delete [] m_pVertices; m_pVertices = NULL;
    delete [] m_pTexCoords; m_pTexCoords = NULL;
    

    Code-Quelle: nehe.gamedev.net
    rya.

    ps.: Aber um 100 Menschen darzustellen die nicht gleichzeitig das Bein heben, wäre da ein direktes Rendern nicht besser? Und damit die nicht alle gleichzeitig das Bein heben, könnte man der Klasse doch ein Offset für die Animation mitgeben. So würde ich das jedenfalls machen. Aber nur mit nem guten FrustumCuller oder ner anderen eff. Art von Culling 😛


Anmelden zum Antworten