OpenGl Texturen



  • Ohne jetzt gross getestet zu haben:

    IMHO müsste es
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8UI, 64, 64,0, GL_RED, GL_BYTE, &texture_data[0]);

    heissen.

    Und die Multiplikation der Texturkoordinaten mit 64 im FragmentShader ist so beabsichtigt?



  • schonmal Danke für die Antworten!

    this->that schrieb:

    + Was kriegst du als Ausgabe, wenn du eine konstante Farbe zurückgibst?
    Also gl_FragColor = vec4(1,0,0,1) oder wie auch immer das in GLSL aussieht.

    Ja, der Shader ist stark vereinfacht. original wird mit der Textur eine bereits berechnete Farbe modifiziert. Und es kommt immer die unmodifizierte raus.

    + Könnte es am Texture Wrap Mode liegen?

    hab verschiedene Modes ausprobiert. denk mal, es ist okay so.

    inter2k3 schrieb:

    Und die Multiplikation der Texturkoordinaten mit 64 im FragmentShader ist so beabsichtigt?

    Ja und Nein. Ich hatte das ausprobiert, weil ich mir nicht sicher war, ob die Texturkoordinaten von 0-1 oder von 0-breite gehen sollten. Ich habe das also schon mal mit und ohne ausprobiert.

    Deinen Tipp kann ich leider erst Montag ausprobieren, werds dann aber sofort sagen, obs funktioniert.

    Die Gl-Calls sind aber ansonsten in Ordnung?



  • Ja, ansonsten sollte es eigentlich korrekt sein.
    Was noch sein könnte ist, dass du noch nen minification- und magnification-Filter für die Textur angeben musst.

    glGenTextures(1,&mLineTexture);
    glBindTexture(GL_TEXTURE_2D,mLineTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8UI, 64, 64,0, GL_RED, GL_BYTE, &texture_data[0]);
    

    Gruss.



  • Jop, ohne die Filter anzugeben geht in OGL nichts.



  • Hi, schon einmal Danke fuer die Hilfe. Ich habe gerade die Tipps ausprobiert, aber es hat leider nichts geholfen:

    Wechsel GL_RED_INTEGER -> GL_RED fuehrt zu: GL_INVALID_OPERATION in glTexImage2D.

    Die Filter sind jetzt aktiviert, aber das Ergebnis ist trotzdem nur, dass die komplette Ausgabe von texture(...) im Shader 0 ist.

    muss ich vielleicht noch generell Texturen aktivieren oder sowas in der Art?

    Gruesse,
    Otze



  • Hi,

    bist du denn sicher dass du das Uniform für den Sampler2D richtig gesetzt hast? Du musst das Ding NICHT auf die Texturid setzen, sondern die Texture Unit, im Normalfall also auf 0.

    mfG
    KaPtainCugel



  • Hez,

    ich habs leider immer noch nicht zum Laufen gekriegt.

    Ich habe mal mein programm auf Pastebin gestellt, vielleicht sieht ja jemand einen Fehler.

    http://pastebin.com/qvNU2TxB

    Sollte ohne Fehler laufen (sofern man die Shader in eine eigene Datei packt). Benoetigt aber qt und opencv.

    Hier der (wie ich glaube) relevante Teil. Ich paste gar nicht gerne so viel code, aber ich haenge da schon seit einigen Tagen und mein Studienprojekt geraet dadurch in Verzug:
    Textur Koordinaten

    void createTextureCoordBuffer()
      {
        size_t num_points=mFieldWidth*mFieldHeight;
        std::vector<GLfloat> texture_data(num_points*2);
        //snip
        GLCheck(glGenBuffers(1,&mLineCoordsBuffer));
        GLCheck(glBindBuffer(GL_ARRAY_BUFFER,mLineCoordsBuffer));
        GLCheck(glBufferData(GL_ARRAY_BUFFER, num_points*sizeof(GLfloat)*2,&texture_data[0],GL_STATIC_DRAW));
        GLCheck(glVertexAttribPointer(textureCoordIndex,2,GL_FLOAT,false,0,0));
        glEnableVertexAttribArray(textureCoordIndex);
      }
    

    textur erstellen:

    void createTexture()
      {
        std::vector<GLbyte> texture_data(64*64);
        //snip
        GLCheck(glGenTextures(1,&mLineTexture));
        GLCheck(glBindTexture(GL_TEXTURE_2D,mLineTexture));
        GLCheck(glGenerateMipmap(GL_TEXTURE_2D));
        GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
        GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
        GLCheck(glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ));
        GLCheck(glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ));
        GLCheck(glTexImage2D( GL_TEXTURE_2D, 0, GL_R8UI, 64, 64,0, GL_RED_INTEGER, GL_BYTE, &texture_data[0]));
      }
    

    zeichnen:

    void paintGL()
      {
        glClearColor(0, 0, 0, 0);
        glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);
    
        GLCheck(glBindVertexArray(mVertexArray));
        GLCheck(glUseProgram(mShaderProgram));
    
        //set matrices
        GLCheck(glUniformMatrix4fv(mCameraPosition,1,false,mCamera.ptr<float>(0)));
        GLCheck(glUniformMatrix4fv(mTransformationPosition,1,false,mTransform.ptr<float>(0)));
    
        //set constants
        GLCheck(glUniform1f(mMinValuePosition,0.0));
        GLCheck(glUniform1f(mMaxValuePosition,1.0));
        GLCheck(glUniform1f(mMaxZPosition,10.0));
        GLCheck(glUniform1i(mLineTexturePosition,0));
    
        GLCheck(glActiveTexture(GL_TEXTURE0));
        GLCheck(glEnable(GL_TEXTURE_2D));
        GLCheck(glBindTexture(GL_TEXTURE_2D,mLineTexture));
    
        //now draw at THE SPEED OF LIGHT!
        GLCheck(glDrawElements(GL_TRIANGLE_STRIP,mNumIndices,GL_UNSIGNED_INT,0));
    
        //clean up
        GLCheck(glActiveTexture(GL_TEXTURE0));
        GLCheck(glBindTexture(GL_TEXTURE_2D, 0));
        GLCheck(glDisable(GL_TEXTURE_2D));
      }
    

    Ich hoffe, der Fehler ist irgendwie trivial. Jeduemmer, desto besser. (und weil ich keine Erfahrung mit OGL hab, geht davon aus, dass ich nen dummen Fehelr gemacht habe). Die textur brauche ich eigentlich sogar nur, um auf dem Plot ein paar Linien zu zeichnen. dass das so schwierig ist, haette ich nicht gedacht...



  • Hi,

    das Problem ist wohl das hochladen der Textur, folgender Code liefert bei mir das gewünschte Ergebnis:

    void createTexture()
      {
        std::vector<GLfloat> texture_data_float(64*64);
    
        for (size_t y=0;y != 64; ++y)
        {
          for (size_t x=0;x != 64; ++x)
          {
            if (y < 5 || y > 59 || x < 5 || x > 59)
            {
    	  texture_data_float[y*64+x] = 0.0;
            }
            else
            {
    	  texture_data_float[y*64+x] = 1.0;
            }
          }
    
        }
        GLCheck(glGenTextures(1,&mLineTexture));
        GLCheck(glBindTexture(GL_TEXTURE_2D,mLineTexture));
        GLCheck(glGenerateMipmap(GL_TEXTURE_2D));
        GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
        GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
        GLCheck(glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ));
        GLCheck(glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ));
        GLCheck(glTexImage2D( GL_TEXTURE_2D, 0, GL_R32F, 64, 64,0, GL_RED, GL_FLOAT, &texture_data_float[0]));
      }
    

    und beim Fragmentshader das *64 weg bei den Texturkoordinaten.
    Sollte es dann noch nicht klappen, dann sag nochmal Bescheid, dann kann ich dir den ganzen Code schicken, vielleicht habe ich noch was geändert und kann mich nicht mehr erinnern.

    mfG
    KaPtainCugel



  • Argh zu langsam - wollt gerade auch nochmal was dazu schreiben.

    Naja - mach ich trotzdem:

    Meiner Meinung nach liegt es an

    glTexImage2D( GL_TEXTURE_2D, 0, GL_R8UI, 64, 64,0, GL_RED_INTEGER, GL_BYTE, &texture_data[0])
    

    Ich hab mir mal dazu nochmal die ref.pages angeschaut (http://www.opengl.org/sdk/docs/man4/xhtml/glTexImage2D.xml).

    Demzufolge sollte für das externalFormat wie bereits vorher von mir gesagt GL_RED und niht GL_RED_INTEGER sein, und GL_R8UI für das internalFormat ist auch nicht spezifiziert (allerdings GL_R32F ebenfalls nicht - wobei das bei mir genauso wie bei KPC tortzdem funktioniert).



  • Ich hab von OpenGL keinen Plan, aber laut der verlinkten Doku...
    internalFormat = GL_RED
    type = GL_UNSIGNED_BYTE
    ... nicht?



  • Es ist abhängig davon, was man erreichen möchte und wie die daten, die man als letztes Argument liefert interpretiert haben möchte.

    simples Beispiel:
    Es soll eine Textur erstellt werden, die 64*64 Texel gross ist. Allerdings speichere ich pro Texel nur einen unsigned byte Wert für die Farbe.

    std::vector<GLubyte> texData(64*64,255);
    

    Erstellt man die Texture nun mit

    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,64,64,0,GL_RED,GL_UNSIGNED_BYTE,&texData[0]);
    

    erhält man eine rote colorierte Textur.

    Intern werden aber pro Texel 3 Werte gespeichert, da als internalFormat GL_RGB angegeben wurde --> Rotwert = 1.0, Blau-/Gruenwert = 0.0;

    Platzsparender wäre, wenn ich das richtig verstanden habe in dem Fall natürlich:

    glTexImage2D(GL_TEXTURE_2D,0,GL_RED,64,64,0,GL_RED,GL_UNSIGNED_BYTE,&texData[0]);
    

    Möchte ich allerdings, dass die Daten die ich liefer (pro Texel nur ein unsigned byte) für alle Farkomponenten berücksichtigt werden, könnte man mit:

    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,64,64,0,GL_RGB,GL_UNSIGNED_BYTE_3_3_2,&texData[0]);
    

    eine weisse Textur erzeugen. Dabei wird angegeben, wieviele und welche bits für den jeweiligen Farbkanal berücksichtigt werden soll.



  • danke für die Tipps, ich werde es sobald möglich ausprobieren(also irgendwie Mittwoch...).

    Das komische ist halt, dass in der OGL 4.1 Spec gesagt wird, dass GL_R8UI akzeptiert werden muss. Gut, das hat nichts zu bedeuten. Ich würde dann aber spontan davon ausgehen, dass mit die GL einen Fehler liefert, wenn sie den Enum nicht kennt/verarbeiten kann. Eben genau das, was passiert, wenn ich

    glTexImage2D(GL_TEXTURE_2D,0,GL_R8UI,64,64,0,GL_RED,GL_BYTE,&texData[0]);
    

    eingebe. Warum auch immer. Man, da packe ich schon um jeden einzelnen Call einen Check und dann hilft das nicht einmal :(.

    Aber nochmal danke für eure Mühen!



  • otze schrieb:

    ...
    Das komische ist halt, dass in der OGL 4.1 Spec gesagt wird, dass GL_R8UI akzeptiert werden muss.

    Hm - wo steht das - hab ich nicht gefunden. Würd mich allerdings interessieren.

    P.S.: Ah - gerade gefunden - werd ich mir mal morgen in Ruhe durchlesen.

    otze schrieb:

    Ich würde dann aber spontan davon ausgehen, dass mit die GL einen Fehler liefert, wenn sie den Enum nicht kennt/verarbeiten kann.

    Wenn ich GL_R8UI verwende, erhalte ich auch eine Fehlermeldung von GL.



  • So - Problem erkannt und gelöst - zumindest bei mir.

    Also dein glTexImage2D-Call war fast korrekt so. Sorry - falls ich da etwas verwirrung reingebracht hab - arbeite eher selten mit Integern.

    Der call lautet also (Voraussetzung OpenGL 3.0):

    glTexImage2D(GL_TEXTURE_2D,0,GL_R8UI,64,64,0,GL_RED_INTEGER,GL_UNSIGNED_BYTE,&texture_data[0]);
    

    Allerdings musst du dann im Fragmentshader auch einen isampler2D nutzen anstelle eines sampler2D.

    Dann sollte das funktionieren.



  • Juhu, es laeuft 🙂

    danke fuer eure Hilfe!


Anmelden zum Antworten