OpenGL VBOs und Multitexturing



  • Alles klar, das beantwortet meine Frage wohl mit JA.
    Danke 🙂



  • Kann mir einer Sagen warum ich nichts sehe wenn ich diesen Code starte?

    /* OpenGL VOreinstellungen */
    
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    
    float pVertices[] = { -1.0f,  1.0f, -10.0f,
                           1.0f,  1.0f, -10.0f,
                           0.0f, -1.0f, -10.0f };
    float pColors[] = { 1.0f, 1.0f, 1.0f,
                        1.0f, 1.0f, 0.0f,
                        0.0f, 0.0f, 1.0f };
    
    glColorPointer(3, GL_FLOAT, 0, pColors);
    glVertexPointer(3, GL_FLOAT, 0, pVertices);
    
    glDrawArrays(GL_TRIANGLES, 0, sizeof(pVertices) / sizeof(float));
    
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    
    /* Rest code */
    

    Eigentlich müsste er hier doch ein Dreieck zeichnen oder? 😕



  • Ja wie hast du denn die Projektion gesetzt?

    Du könntest beispielsweise auch die Dreiecke erstmal ganz einfach mit glBegin(), glVertex3f() etc zeichen, dass da auch alles stimmt.



  • Das hat bis her alles funktioniert. Die Projektion sieht so aus:

    /* Öffnen eines Fensters etc. */
    
    glViewport(0, 0, 1024, 768);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    gluPerspective(45.0f, 1024.0f / 768.0f, 0.1f, 100.0f);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
    /* Rendern etc. */
    

    So weit ich weiß müsste man aber auch ohne die Funktionen glGenBuffersARB, glBindBufferARB, glBufferDataARB und glDeleteBuffersARB VBOs rendern nicht wahr?!



  • Hast du Backface-Culling an? Bei der Reihenfolge deiner Koordinaten zeigt die Rückseite des Dreiecks zu dir



  • Ich habs an, allerdings hab ich ne 'Kamera'-Rotation eingebaut um dahinter zu schauen. Aber ich probiers trotzdem noch mal aus.

    PS: Das muss aber doch möglich sein mit VBOs zu arbeiten auch ohne: 'glGenBuffersARB()', 'glBindBufferARB()' usw. oder?



  • Alles klar, jetzt funktioniert es! 🙂

    Aber noch kurz ne Frage: ist es besser, sprich schneller, wenn man die Funktionen glGenBuffersARB, glBindBufferARB, glBufferDataARB und glDeleteBuffersARB verwendet?



  • LukasBanana schrieb:

    Alles klar, jetzt funktioniert es! 🙂

    Fein fein 🙂

    LukasBanana schrieb:

    Aber noch kurz ne Frage: ist es besser, sprich schneller, wenn man die Funktionen glGenBuffersARB, glBindBufferARB, glBufferDataARB und glDeleteBuffersARB verwendet?

    Inwieweit schneller? Erstmal zu deiner Frage oben: ja ohne diese Funktionen kannst du VBO's nicht nutzen, weil das nunmal die Funktionen sind, mit denen man VBOs nutzt^^ Man braucht nicht immer alle, aber wie willst du ohne BindBuffer nen VBO aktivieren ... ?

    Wenn du mit schneller meinst im Bezug auf andere Techniken zum Rendern, dann kommt es drauf an. VBOs sind einfach gesprochen nichts weiter als Speicherbereiche, welche im VRAM liegen. Das lohnt sich z.B. bei statischer Geometrie. Anstatt jedesmal die Daten aus dem RAM in den VRAM kopieren zu müssen (wie bei normalen Vertexarrays), befüllt man einmal das VBO und hat seine Daten dann gleich im VRAM. Das spart natürlich das Kopieren und wäre somit schneller.
    (mal als ein einfaches Beispiel). Es kommt natürlich auch auf deine Szene drauf an. Wenn deine Sachverhalte eher einfach sind, tuns auch Displaylisten.



  • Genau, Displaylisten hatte ich erst in Verwendung allerdings ist da das Problem dass man, wenn man die Szene verändert, die Liste komplett anlegen muss.

    Verzeihung dass ich die ganze Zeit von VBOs rede, ich hab jetzt rausgekriegt wie man VertexArrays richtig verwendet. Da kann man nämlich einfach bestimmte Werte innerhalb des Pointers (z.B: VerticesList[VertexIndex*3+0] = x; VerticesList[VertexIndex*3+1] = y; VerticesList[VertexIndex*3+2] = z) verändern. Das ist jedenfalls schneller als Displaylisten nicht wahr?!


  • Mod

    ich glaube du verwechselst/vermischt VertexArrays mit VBOs. das sind zwei verschiedene dinge.

    Je nachdem wie gut man coded und wie gut der treiber ist, sind VBOs oder DLs schneller.
    Vertexarrays sollten langsammer sein.



  • Das ist jedenfalls schneller als Displaylisten nicht wahr?!

    wenn du eine neue displayliste anlegst werden alle dafuer benoetigten daten vom ram in den grafikspeicher kopiert plus einige optimierungen vom treiber durchgefuehrt weil er davon ausgeht, dass du die liste mehr als einmal benutzen willst.
    wenn du den vertexbuffer deines vbos (komplett) mit neuen daten ueberschreibst ist der aufwand dafuer ungefaehr der gleiche.
    grundlegend macht das nur dann sinn, wenn sich die aenderungen nicht sinnvoll durch einen vertex-shader erledigen lassen.
    wenn deine vertexdaten nicht interleaved sind hast du bei vbos jedoch den vorteil, dass du nur einen buffer ueberschreiben musst, wenn sich nur ein attribut deiner vertices aendert.



  • rapso schrieb:

    ich glaube du verwechselst/vermischt VertexArrays mit VBOs. das sind zwei verschiedene dinge.

    Ja, das hab ich auch erst vor kurzem gemerkt. 🤡

    Allerdings glaube ich dass man bei VBOs, wenn man auch nur ein Vertex verändern will, genau wie bei Displaylisten, alles neu erstellen muss oder?

    Und noch was: es sollte doch relativ leicht sein von VertexArrays auf VBOs umzustellen oder?



  • Allerdings glaube ich dass ...

    Und wie kommst Du zu dieser These?
    Guck doch mal in die Dokumentation, da steht sowas drin.
    Dann kennt man die Fakten und muss keine Vermutungen anstellen.
    Hier gibt's auch ein Paper dazu, kannste mal lesen - das macht schlau.



  • Nagut, ich bin gerade dabei auf VBOs umzustellen allerdings habe ich jetzt ein anderes Problem:

    class vector3d {
      public:
        /* jede menge funktionen (operator +, -, * / ... usw.) */
        float X, Y, Z;
    };
    class color {
      public:
        /* ebenfalls funktionen ähnlich wie in vector3d */
        unsigned char Red, Green, Blue, Alpha;
    };
    
    typedef struct {
      vector3d Coord;
      color Color;
    } vertex3DInfo;
    
    std::vector<vertex3DInfo> VerticesList;
    
    /* Vertices anlegen ... */
    
    // Geht das so?
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, VerticesList.size()*sizeof(vector3d), &(VerticesList)[0].Coord, GL_STATIC_DRAW_ARB);
    
    // Mit 'glVertexPointer' sah das so aus:
    //glVertexPointer(3, GL_FLOAT, sizeof(vertex3DInfo), &(VerticesList)[0].Coord);
    

    Man beachte hier bei dass bei 'glBufferDataARB' auf einen Pointer verwiesen wird in dem auch noch andere Informationen, nämlich 'Color', stehen. Mit 'glVertexPointer' hat das wunderbar funktioniert. Wie mache ich das am bessten mit VBOs?



  • wenn du deine vertex-struktur so beibehalten willst, hast du eben nur einen einzigen vertexbuffer (interleaved) und gibst dann bei gl...Pointer() einen offset an, wo das jeweilige vertexattribut in der struktur zu finden ist.



  • In Ordnung, aber soll dass heißen dass ich auf alle Fälle die Funktion 'glInterleavedArrays' verwenden muss?



  • Ich hab das jetzt in etwa so:

    // 4*(3 + 1) >> 4 = 4 bytes (3 float & 4 char), NULL + 0 >> 0 = steht als erstes in der vertex3DInfo struct!
    glVertexPointer(3, GL_FLOAT, 4*(3 + 1), (char*)NULL + 0);
    

    Aber irgendwas mache ich immer noch falsch. Ich kann kein Object sehen.
    Und wenn ich das schreibe stürzt das Programm ganz ab:

    glVertexPointer(3, GL_FLOAT, sizeof(vertex3DInfo), (char*)NULL + 0);
    

    Was mache ich denn falsch?



  • Wenn Du mal sizeof(vector3d) und mal sizeof(vertex3DInfo) nimmst, wird das wohl auch nicht gehen...
    Solche Fluechtigkeitsfehler koenntest Du auch alleine finden.



  • Funktioniert inzwischen. Ich glaube es lag sogar an deinem benannten Fehler. Kann ich nicht genau sagen, ich hab ein Testprogramm geschrieben um meinen Fehler zu finden und dann hat's auch geklappt.

    Noch ne kleine Frage:

    Was ist schneller, in einer for-Schleife eine Displaylist aktualisieren oder einen VBO-Buffer aktuallisieren?


Anmelden zum Antworten