Benutzung von ARB_texture_non_power_of_two
-
Also generell gibt dir glGetString(GL_EXTENSIONS) einen String zurueck, der die Namen aller unterstuetzten Extensions als Teilstrings enthaelt.
-
There is no additional procedural or enumerant api introduced by this
extension except that an implementation which exports the extension
string will allow an application to pass in texture dimensions for
the 1D, 2D, cube map, and 3D targets that may or may not be a power
of two.
-
otze schrieb:
hmm, vielleicht, weil es Grafikkarten gibt, die nur Quadratische Texturen deren seiten 2x pixel lang sind annehmen?
findet man die auch außerhalb von museen? ich kann mir spontan KEINE karte vorstellen, die keine einschränkung der kantenlänge auf 2er potenzen hat aber an nicht-quadratischen texturen scheitert.
aus geschwindigkeitsgründen würde ich trotzdem potenzen nehmen oder zumindest testen, ob es einen spürbaren unterschied macht. leerräume lassen sich fast immer mit irgendwas füllen.
-
Trienco schrieb:
weniger als 0 zeilen werdens nicht.
Eigentlich doch. Man muss nur testen ob der Extensionstring das besagte Token enthält und dann kann man schon NPOTD Texturen verwenden, wie man lustig ist. Was besonderes glEnablen braucht man nicht, Texturetargets bleiben auch gleich.
cya
liquid
-

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.

Problem ist nämlich, dass es bei mir nicht geht. Power_of_2 Texturen sind kein Problem, aber sobald das nicht mehr gewährleistet ist, bleibt der Quad halt weiß. Hier die Laderoutine, ist mehr oder weniger Copy-Paste gewesen, abe ich weiß ja was passiert. Ist halt mit SDL gemacht:
SDL_Surface *tex; tex = IMG_Load(filename); { //glGenTextures(1, &TEXTURE); //Ist diese Zeile aktiv, läd die Routine die Texture nicht //Hat einer Ahnung warum? glBindTexture(GL_TEXTURE_2D, TEXTURE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex->w, tex->h,0, GL_RGB, GL_UNSIGNED_BYTE, tex->pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); SDL_FreeSurface(tex); }Hab wie gesagt ne GF4 TI, okay, die ist jetzt auch schon mehr als 2 Jahre alt, kA ob die das Unterstützt, aber das kann man ja rauskriegen. Wäre es ansonsten möglich, dass neue Treiber von Nvidia sowas emulieren? Hab momentan den 61.76.
Wenn die Unterstützung seitens älterer Grakas allerdings so schwach ist, kann ich meine Idee allerdings so ziemlich vergessen, denn die meisten, die die CD bekommen werden, haben bestimmt nicht gerade das neuste Model im AGP (oder noch PCI, ISA will ich mal nicht hoffen
) stecken. 
Seht ihr sonst noch ne Möglichkeit? Es soll dabei aber jedenfalls nicht den Krampf ausarten alle Bilder (werden so mehrere Hundert wohl sein) jetzt so zu strecken, dass es geht und die nachher im Programm wieder auf das entsprechende Format zu bringen, denn die Bilder müssen ja für alle Anderen, die entsprechende Hardware icht haben auch zu benutzen sein, wahrscheinlich in HTML oder so, oder nur so in den Ordner direkt.
Ich hoffe es gibt noch ne Möglichkeit
-
wenn du dich traust, nen eigenen loadder zu bauen, kannst du die zu kurzen seiten ja oben und unten mit schwarz auffüllen.und das ganze somit dann quadratisch machen
--------------------------- schwarz --------------------------- Bild --------------------------- schwarz ---------------------------
-
Du solltest erst einmal glGenTextures wieder "einkommentieren" und dann glBindTexture aber vor dem Zeichnen aufrufen.
So kannst du dir mehrere texture objects erstellen und hin- und herswitchen.Zu deinem Problem: Du könntest versuchen, deine Bilder auf z.B. 1280 * 1024 oder sowas zu bringen, und dann links und rechts einfach die überstehenden Pixel abzuschneiden.
SDL_Surface *tex; tex = IMG_Load(filename); GLuint texture; glGenTextures(1, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); GLint leeres_array[1024][1024]; glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024,0, GL_RGB, GL_UNSIGNED_BYTE, leeres_array); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 1024, GL_RGB, GL_UNSIGNED_BYTE, tex->pixels); SDL_FreeSurface(tex); glBindTexture(GL_TEXTURE_2D, texture);Sollte ungefähr so gehen. Der rechte Rand ist dann halt weg, geht leider nicht anders. Einen Offset kann man leider nur in dem Zielbild angeben, da wir das ganz bemalt haben wollen, ist er (0, 0), nicht in dem, aus dem wir lesen, wo wir (1280-1024/2) als x-offset gewählt hätten, damit links und rechts was abgeschnitten wird, aber eben nur die Hälfte. Ich vermute außerdem, dass glTexImage2D in diesem Fall überflüssig ist.
Wenn non-power-of-2 nicht geht, sind entweder dies hier, das was Otze gesagt hat, oder ein Stauchen des Bildes per gluScaleImage nicht zu vermeiden.
-
*seufz* ich glaub irgendwie war ich nicht ausführlich genug.
ja, man KANN einfach sinnlos mit schwarz auffüllen und den speicher verschwenden. man könnte ihn aber dann aber auch sinnvoll für andere kleine texturen benutzen. WENN man den speicher schon verbraten will, dann streckt man bitte das bild auf die nächstbeste größe und muß sich dann auch nicht an den texturkoordinaten einen abbrechen. wenn man DAS haben will, kann man auch gleich glubuildmipmaps benutzen, weil das bei "unpassenden" dateien eben genau das heimlich automatisch macht.
das ist auch kein großer verlust, weil unpassende größen, selbst wenn sie unterstützt werden nicht unbedingt gut für die performance sind.
-
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 tcoordscya
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 seinRichtig, 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 mappenHattest 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 1024SDL_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
liquidEDIT: Ausserdem müssten wenn deine Min/Mag Filter vertauscht sein. Beim Vergrößern bringt es irgendwie nichts Mipmaps zu verwenden...