OpenGL Problem mit 'glBindTexture'



  • OpenGL ist eine State-Machine bzw arbeitet mit einer. Das heisst, wenn du einen Zustand auslöst, muss du ihn auch wieder resetten, um die Ausgangssituation zu haben. In deinem Fall:

    // Textur binden
    glBindTexture(GL_TEXTURE_2D, textureID);
    // Objekt zeichnen
    glBegin(GL_QUADS)
    (...)
    glEnd();
    // Textur wieder abschalten
    glBinTexture(GL_TEXTURE_2D, 0);
    

    Ganz einfach 🙂
    rya.



  • Ist es nicht besser mit glEnable(GL_TEXTURE_2D); und glDisable(GL_TEXTURE_2D);
    zu arbeiten?


  • Mod

    Andreas XXL schrieb:

    Ist es nicht besser mit glEnable(GL_TEXTURE_2D); und glDisable(GL_TEXTURE_2D);
    zu arbeiten?

    da hat doch jemand heimlich die doku gelesen, sowas macht man doch nicht 🤡



  • Jein.
    Du kannst natürlich auch folgendes machen:

    glEnable(GL_TEXTURE_2D);
    // Textur binden
    glBindTexture(GL_TEXTURE_2D, textureID);
    // Objekt zeichnen
    glBegin(GL_QUADS)
    (...)
     glEnd();
    // Textur wieder abschalten
    glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_TEXTURE_2D);
    

    So gehts natürlich auch. Aber auf ein glBindTexture mit der ID muss( bin mir gerade nicht 100% sicher, ob der Standard das verlangt, aber es ist der bessere Stil) immer ein glBindTexture mit einer 0 folgen. Um OpenGL eben mitzuteilen, dass die Texture jetzt nicht mehr verwendet wird.
    Falls es das einzigste Objekt ist, das texturiert wird, kann man natürlich GL_TEXTURE_2D nur für dieses aktivieren und danach deaktivieren.
    Arbeitest du mit C oder mit C++? Falls du mit C++ arbeitest, könntest du dir eine Klasse dafür schreiben. Entweder mit Texture-Loader oder ohne.
    Ne einfache Lösung wäre:

    class CGLTexture
    {
    public:
       CGLTexture(const GLuint ID)
       { 
           if(glIsTexture(ID)
           {
              m_id = ID;
           }
           else
           {
              throw std::runtime_error("ID is no valid Texture.");
           }
       }
    
       ~CGLTexture()
       {
         glDeleteTextures(1, &m_id);
       }
    
       void bind()
       {
           glBindTexture(GL_TEXTURE_2D, m_id);
       }
    
       void unbind()
       {
           glBindTexture(GL_TEXTURE_2D, 0);
       }
    private: 
       GLuint m_id;
    }
    

    Ist natürlich ausbaufähig und man kann noch nen Loader hinzufügen etc etc.
    So ist es weniger zu tippen :).
    rya.



  • Danke Leute,

    ich hab das jetzt mit glEnable(GL_TEXTURE_2D) und glDisable(GL_TEXTURE_2D) gemacht.
    Als Standard ist die Textureierung deaktiviert und wenn ich mit Texturen arbeiten möchte schalte ich sie wieder an.

    Gruß 🙂



  • Optimalerweise sortiert man die Objekte die man zeichnet nach verwendeten Texturen und/oder Materialeigenschaften. Das spart States und glBindTexture Aufrufe und bringt einen gewissen Performance Vorteil. Irgendwo davor oder danach könnte man dann einfach die untexturierten Objekte unterbringen.



  • Keine schlechte Idee, der 'sort' algorithmus in C++ ist ja sehr schnell aber was ist mit Objekten die als alpha-blending gerendert werden sollen. Damit meine ich z.B. die Linsen Effeckte. die sollten ja auch noch mal sortiert werden damit das gut aussieht.
    Denn ➡ in OpenGL sollte man alles was transparent ist von der Raumtiefe nacheinander zeichnen. (Weit weg zu erst zeichnen/ Nah dran als letztes zeichnen)

    Wo wir schon gerade dabei sind: wie kann man denn in OpenGL die Tiefe eines Objektes, abhängig von der aktuellen Kamerasicht, abfragen? Je nachdem wie sich die Kamera dreht ist das Objekt optisch tiefer im Raum oder weniger tief? 😕



  • Hm, Objektposition minus Kameraposition. Alle Komponenten des resultierenden Vektors addieren (abs()!), dann hast du ne Entfernung. Wenn du alle Objekte nach Tiefe sortierst hast du den Vorteil, das du auf den Depth Test verzichten kannst. Du renderst dann einfach alles von hinten nach vorne und kannst nochmal Geschwindigkeit rausholen (Das erschlägt auch das Problem mit den Blending-Effekten). Ob das korrekt funktioniert hängt allerdings von der Form der Geometrie ab die du da renderst. Wenn zwei Objekte so nah beisammen sind das sie sich irgendwie überlappen, gibts wieder Probleme.



  • Alle Komponenten des resultierenden Vektors addieren (abs()!), dann hast du ne Entfernung

    das ist in diesem zusammenhang falsch!

    Du renderst dann einfach alles von hinten nach vorne und kannst nochmal Geschwindigkeit rausholen

    eigentlich rendert man von vorne nach hinten um durch den zbuffer overdraw zu verhindern.

    Wenn du alle Objekte nach Tiefe sortierst hast du den Vorteil, das du auf den Depth Test verzichten kannst.

    nur wenn alle objekte konvex und gleich gross waeren.
    sind sie aber meistens nicht.



  • Ich will außerdem nur wissen wie weit ein Objetk von der Z-Achse aus von der Kamera entfernt ist, jedoch unabhängig von der X und Y Koordinate.

    Z
    |
    |  Objekt
    |    *
    |    |   \   ^   /
    |    |    \  |  / <- Sichtfeld
    |    |     \ | /
    |    |       *
    |          Kamera
    Y--------------------X
    


  • Ich will außerdem nur wissen wie weit ein Objetk von der Z-Achse aus von der Kamera entfernt ist, jedoch unabhängig von der X und Y Koordinate.

    Z
    |
    |  Objekt
    |    *
    |    |   \   ^   /
    |    |    \  |  / <- Sichtfeld
    |    |     \ | /
    |    |       *
    |          Kamera
    Y--------------------X
    


  • Einfach die Länge des Vektors berechnen:
    http://de.wikipedia.org/wiki/Vektor#Betrag_eines_Vektors
    rya.



  • hellihjb schrieb:

    Alle Komponenten des resultierenden Vektors addieren (abs()!), dann hast du ne Entfernung

    das ist in diesem zusammenhang falsch!

    Erklärung?

    Du renderst dann einfach alles von hinten nach vorne und kannst nochmal Geschwindigkeit rausholen

    eigentlich rendert man von vorne nach hinten um durch den zbuffer overdraw zu verhindern.

    Ähm ja, je nachdem wo bei dir "vorne" ist und ob deine Motivation darin liegt, den Depth Test zu umgehen oder nicht 🙄



  • Alle Komponenten des resultierenden Vektors addieren (abs()!), dann hast du ne Entfernung

    das ist in diesem zusammenhang falsch!

    Erklärung?

    du schlaegst vermutlich deshalb die sog. manhattan metrik vor um quadrat und wurzel des euklidischen abstands zu sparen.

    man braucht aber den abstand vom bildschirm (ebene) und nicht den abstand vom projektionszentrum (punkt).

    beispiel:
    zwei punkte im kamera-raum:
    [-4,-4,-2] -> distanz= 10
    [+1,+1,-5] -> distanz= 7
    obwohl der zweite punkt weiter hinten ist, hat er nach deiner rechnung eine kleinere entfernung.



  • scheiss server 😉



  • Stimmt, leuchtet ein. Danke.



  • @Scorcher24: wie man die länge eines Vektors berechnet weiß ich ja, aber ich hab ja versucht mit meinem, zugegeben etwaas abstraktem, Bild zu zeigen welche länge ich haben will.
    Nicht die Entfernung von einem Objetk bis zur Kamera, sondern die Tiefe eines Objektes der aktuellen Sichtperspektieve. Wenn ich die Kamera drehe würden sich die Tiefen also laufend verändern.



  • transformiere den punkt zunaechst mit der modelviewmatrix, dann mit der projektionsmatrix und nimm dir die z-koordinate.
    da du vermutlich den objektmittelpunkt (0,0,0) betrachtest bleibt auch nicht mehr viel von der berechnung uebrig.
    die matrizen bekommst du mit:

    float matrix1[16], matrix2[16];
    glGet(GL_MODELVIEW_MATRIX, matrix1);
    glGet(GL_PROJECTION_MATRIX, matrix2);
    

    alternative:
    transformiere die projektionsebene der kamera mit der inversen modelviewmatrix in den (untransformierten) objektraum und entnimm den abstand ursprung/ebene der ebenengleichung.


Anmelden zum Antworten