Benutzung von ARB_texture_non_power_of_two



  • MS_Noob schrieb:

    😮
    Echt? Im Klartext: Wenn die GRaka und der Treiber es unterstützen, lad ich die TExture ganz normal und muss nix weiter machen? Das wär ja cool. 😋

    Kannst du English ? Was daran kann man denn nicht verstehen ?

    GLint leeres_array[1024][1024];

    Auf den ersten Blick würde ich sagen, dass das so nicht funktionieren wird.



  • Hmm, wieso sollten NPO2-Texturen wesentlich langsamer sein? Auch mit PO2-Texturen konnte man ja mit entsprechenden Texturkoordinaten "ungerade" Sachen machen.

    Und weil OpenGL 2.0 die Extension eingebaut hat, muessten doch ca. alle Grafikkarten die neuer als 1-2 Jahre sind NPO2-Texturen unterstuetzen, oder?



  • Bei Geforce4 ist nix mit ARB_non_power_of_two, nichtmal die FX kann das. Nur die 6800 hat nativen NPOTD Support. Das hättest du aber auch feststellen können, wenn du mal geguckt hättest ob der Token im Extensionstring auftaucht, das wird er nämlich höchstwahrscheinlich nicht.

    cya
    liquid



  • Evtl. ist diese Extension interessant, die z.B. von Geforce-Karten unterstuetzt wird: EXT_texture_rectangle
    Diese soll (mit Einschraenkungen) beliebige Texturgroessen zulassen.



  • Nachteile:
    - keine Mipmaps
    - Clamping/Repeating eingeschränkt
    - unnormalisierte tcoords

    cya
    liquid



  • LiquidAcid schrieb:

    Nachteile:
    - keine Mipmaps
    - Clamping/Repeating eingeschränkt
    - unnormalisierte tcoords

    + border size = 0
    + kein support für GL_COLOR_INDEX



  • Also erstmal bedanke ich mich, für die vielen Antworten.

    GLint leeres_array[1024][1024];

    Auf den ersten Blick würde ich sagen, dass das so nicht funktionieren wird.

    Stimmt auch, also das es nicht geht. Abgesehen davon stürtzt das Programm beim erstellen den 2D Arrays ab, zumindest solange es "solche" Dimensionen hat. bei kleineren gehts dann, also nicht die Texturirung, sonder das Array. Ist das zuviel Speicher auf einmal? Immerhin nur 1 MB. Egal, da muss ich mir wohl extra Speicher holen, man ich hab soviel vergessen, in den 2 Jahren. In Pascal und Delphi braucht man ja so Sachen wie Speicherverwaltung nie, jedenfalls nicht bei dem was wir so machen.

    Achso. Also ich hab prinzipiell kein Problem damit bei den Texturen irgendwo Speicher zu verschwenden. Bei 4:3 Format der Bilder hau ich zwar 1/4 des Speichers sinnlos in die Tonne, aber ist erstmal egal. Wird ja sicher kein Problem sein. Der Hintergrund soll eh erstmal schwarz bleiben, da sieht man es ja nicht.
    Ist ja auch ne bisschen doof, das NPOT nicht so sehr unterstütz wird, zumal ja so sicher häufiger viel sparsamer mit dem Speicher umgegangen werden kann, zumindest in gewissen Grenzen.

    EXT_texture_rectangle wäre die Alternative gewesen, aber das wird auch nicht unterstützt. Wäre aber auch nicht das wahre. Am liebsten wäre mir ne Lösung, die mit Sicherheit auch noch auf ner GF256 oder so und vor allem auf ATI Karten läuft.

    Tut mir Leid, das ich kaum Hilfen meinerseits geben kann. 😞



  • MS_Noob schrieb:

    Stimmt auch, also das es nicht geht. Abgesehen davon stürtzt das Programm beim erstellen den 2D Arrays ab

    GLint leeres_array**[1024][1024]**;
    glTexImage2D(GL_TEXTURE_2D, 0, **GL_RGB, 1024, 1024,**0, GL_RGB, GL_UNSIGNED_BYTE, leeres_array);

    Hat auch gleich mehrere Fehler.

    1. GLint -> GL_UNSIGNED_BYTE
    2. GL_RGB && Size = 1024² -> leeres_array aber nur 1024², müsste aber 1024² * 3 sein



  • Ahvolon[F-Bytes] schrieb:

    MS_Noob schrieb:

    Stimmt auch, also das es nicht geht. Abgesehen davon stürtzt das Programm beim erstellen den 2D Arrays ab

    GLint leeres_array**[1024][1024]**;
    glTexImage2D(GL_TEXTURE_2D, 0, **GL_RGB, 1024, 1024,**0, GL_RGB, GL_UNSIGNED_BYTE, leeres_array);

    Hat auch gleich mehrere Fehler.

    1. GLint -> GL_UNSIGNED_BYTE
    2. GL_RGB && Size = 1024² -> leeres_array aber nur 1024², müsste aber 1024² * 3 sein

    Richtig, ist mir auch klar, war nur eine Art Platzhalter, aber habs vergessen vorm abschicken noch zu ändern, sorry 🙄

    GLubyte * leeres_array = new GLubyte[1024 * 1024 * 3];
    //...
    delete[] leeres_array;
    

    Aber:
    Laut Trienco ist das ja sowieso der falsche Weg.

    Du könntest nämlich auch einfach deine Textur strecken / stauchen und sie dann wieder auf ein Objekt mit richtigen Proportionen mappen.
    D.h.
    -per SDL laden
    -Speicher für die neue Textur wie oben anfordern
    -gluScaleImage(GL_RGB, tex->w, tex->h, GL_UNSIGNED_BYTE, tex->pixels, 1024, 1024, GL_UNSIGNED_BYTE, leeres_array);
    -Texturobjekt erstellen (siehe mein letzter Post) und halt ganz normal mit glTexImage2D weiter arbeiten (natürlich mit leeres_array [der name ist Unsinn])
    -die Textur auf ein Quad mit 4/3 mappen

    Hattest du das gemeint, Trienco? Oder wolltest du sagen, dass beim Mipmapping das von selbst gemacht wird? Das wusste ich dann nicht.



  • spl@t schrieb:

    Hattest du das gemeint, Trienco? Oder wolltest du sagen, dass beim Mipmapping das von selbst gemacht wird? Das wusste ich dann nicht.

    fast. an sich hat das mit mipmapping nichts zu tun, aber glubuildxdmipmap prüft halt netterweise die größe und paßt sie bei bedarf heimlich und automatisch an.

    wenn man die ganzen mipmaps aber sowieso nicht will, dann ist dein weg speicherfreundlicher (und glublamaps wird sowieso mit extremer sicherheit intern die gleiche funktion benutzen).

    insgesamt wär ich natürlich trotzdem dafür, daß man den leeren raum einfach buttons oder anderen textur kleinkram benutzt ,-)



  • Ja ja, du und deine Buttons... 🙄 Ich brauch ja gar keine.

    #define MAX_SIZE 1024
    
    SDL_Surface *tex;
        tex = IMG_Load(filename);        
    
            glGenTextures(1, &TEXTURE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    
            GLubyte * feld = new GLubyte[MAX_SIZE*MAX_SIZE*3];  
    
            glBindTexture(GL_TEXTURE_2D, TEXTURE); 
    
            gluScaleImage(GL_RGB, tex->w, tex->h, GL_UNSIGNED_BYTE, tex->pixels, MAX_SIZE, MAX_SIZE, GL_UNSIGNED_BYTE, feld);
    
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, MAX_SIZE, MAX_SIZE,0, GL_RGB, GL_UNSIGNED_BYTE, feld);            
    
        SDL_FreeSurface(tex);  
        delete[] feld;
    

    So "müsste" es gehen, oder hab ich was vergessen? Jedenfalls stütz der Spaß nicht mehr ab, aber mein Quad bleibt immer noch weiß, auch wenn ich jetzt POT Texturen laden will. Aber die Routine müsste ja so wie sie jetzt eigentlich beides können. Ich lad halt die ImageDaten und erzeuge dann einen Texturspeicher der eine quadratische Texture mit den Abmessungen der längeren Seite des Bildes aufnehmen kann. Da hinein wird das bild auf die quadratischen Abmessungen skaliert und dann wieder an meine eigentliche texture übergeben. Eigentlich müsste ich jetzt ne vertikal oder horizontal skalierte texture haben und nur noch den Quad anpassen.



  • Du hast einen Mipmapfilter ausgewählt, aber erzeugst keine Mipmaps. Also entweder welche erzeugen (manuell oder automatisch egal) oder Minificationfilter auf GL_LINEAR stellen.

    cya
    liquid

    EDIT: Ausserdem müssten wenn deine Min/Mag Filter vertauscht sein. Beim Vergrößern bringt es irgendwie nichts Mipmaps zu verwenden...



  • nachdem du, wie LiquidAcid es bereits sagte, das "_MIPMAP_NEAREST" entfernt hast, solltest du, falls es dann noch nicht geht, mal ein erneutes glBindTexture nach glTexImage2D versuchen (bzw. vor dem Zeichnen)



  • spl@t schrieb:

    (bzw. vor dem Zeichnen)

    👍 🙄



  • Ich danke Euch für eure guten Hilfen! 🕶

    Jetzt geht es in der Tat. Allerdings hab ich ein echten Verständnis problem:

    SDL_Surface *tex;
        tex = IMG_Load(filename);                
        w=tex->w;
        h=tex->h;
    
            //glGenTextures(1, &TEXTURE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
            GLubyte * feld = new GLubyte[MAX_SIZE*MAX_SIZE*3];  
    
            glBindTexture(GL_TEXTURE_2D, TEXTURE); 
    
            gluScaleImage(GL_RGB, tex->w, tex->h, GL_UNSIGNED_BYTE, tex->pixels, MAX_SIZE, MAX_SIZE, GL_UNSIGNED_BYTE, feld);
            glBindTexture(GL_TEXTURE_2D, TEXTURE);     
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, MAX_SIZE, MAX_SIZE,0, GL_RGB, GL_UNSIGNED_BYTE, feld);            
    
        SDL_FreeSurface(tex);  
        delete[] feld;
    

    Wie ihr seht ist glGenTextures wieder deaktiviert. Nur so geht es, fragt mich nicht warum. Schalte ich es wieder hinzu komme ich an die Texture nicht mehr heran. Ein weiteres Problem ist: Es ist ja alles schon in eine kleine Klasse verpackt:

    class CTexQuad : public CQuad
    {
        private:
             GLuint  TEXTURE;    
        public:
    
        int w;
        int h;
        void Draw();
        bool LoadTexture(char * filename);               
    };
    

    Ich dachte so könnte ich leicht mehrere Texturen laden, einfach mit mehreren Objekten. Erstmal, später will ich sowieso ne Liste von solchen Objektenmachen (geht doch oder 😕 ) Leider geht das wohl nicht so billig wie ich dachte. Hab ich 2 objekte diesen Typs und lade 2 Images wird prinzipiell auf dem ersten Quad die zweite TExture abgebildet, der zweite bleibt weiß. Ich vermute mal, das hat auch was mit glGenTexture(...); zu tun. 😞
    Ein weiteres Prob sind nur noch die Memberv. w und h. Ich versteh nicht wieso ist da nicht die Imagedimensionen reinbekommen, eigentlich doch total rudimentär? 😮
    zum Ende nochmal die zeichenroutine, da ist ja eigentlich (herje,wie oft ich hier schon dachte, das etwas eigentlich "s"o funktionieren müsste) auch nix besonderes:

    glPushMatrix();
        if(w>h)
        {
            glScalef(1.333,1,1);
        }
        else(w<h)
        {
            glScalef(1,1.333,1);
        }
               glEnable(GL_TEXTURE_2D);   
               glBindTexture(GL_TEXTURE_2D,TEXTURE);
               glBegin(GL_QUADS);
                       glColor4f(V[1].red,V[1].green,V[1].blue,V[1].alpha);
                       glTexCoord2f(1,1);
                       glVertex3f(V[1].x,V[1].y,V[1].z);
                       glColor4f(V[2].red,V[2].green,V[2].blue,V[2].alpha);
                       glTexCoord2f(0,1);
                       glVertex3f(V[2].x,V[2].y,V[2].z);        
                       glColor4f(V[3].red,V[3].green,V[3].blue,V[3].alpha);
                       glTexCoord2f(0,0);
                       glVertex3f(V[3].x,V[3].y,V[3].z);      
                       glColor4f(V[4].red,V[4].green,V[4].blue,V[4].alpha);
                       glTexCoord2f(1,0);
                       glVertex3f(V[4].x,V[4].y,V[4].z);         
               glEnd();
               glDisable(GL_TEXTURE_2D);
               glLoadIdentity();
               glPopMatrix();
    

    Nicht sehr Elegant mit dem glScalef, aber das tuts erstmal.

    danke



  • Wo komt in deinem Source "TEXTURE" her, wenn das alles schon in einer Klasse ist ?



  • Na TEXTURE ist doch private Member von CTexQuad



  • Setze mal TEXTURE im Ctor auf Null. Dann versuch nochmal in der Lademethode gleich nach dem glGenTexture das Binden durchzuführen (also gleich nach dem Gen).

    cya
    liquid



  • spl@t schrieb:

    erneutes glBindTexture nach glTexImage2D versuchen (bzw. vor dem Zeichnen)



  • spl@t schrieb:

    spl@t schrieb:

    erneutes glBindTexture nach glTexImage2D versuchen (bzw. vor dem Zeichnen)

    👍 🙄

    Aber klar. Wiederholen wir doch nochmal was nix bringt und jeder weiß.


Anmelden zum Antworten