Benutzung von ARB_texture_non_power_of_two
-
Seid mir alle gegrüßt,
Ich hab vor 2 Jahren schonmal OpenGL programmiert, aber dann bin ich davon Abgekommen. Jetzt bin ich wieder dazu gekommen. Jpeg zu laden hab ich ja nun schon geschafft, das problem ist jetzt aber, dass Digiphots ja eigentlich nie power of 2 sind. Meist irgendwie 1280x960.... also immer 1:1,3 oder 1,3: 1. Selbst mit Umrechnungen ist das nicht zu machen. Die Jpeg sollen später auch nicht mehr verändert werden, da sie ebenfalls für entsprechende HTML Seiten auf ner CD bereitstehen sollen.
Nun bin ich ja schon dazu gekommen, dass NVidia schon vor einiger Zeit die ARB_texture_non_power_of_two entwickelt hat um beliebige Texturgrößen zu ermöglichen. Ist ja auch Core von OGL 2.0. Unterstützen wahrscheinlich nicht viel Grakas (ich hab ne GF4Ti, musste doch oder? ). Ach, ich quatsch schon wieder ohne ende.Klare Frage, wie Realisiere ich nun, dass ich die Extension nutzen kann. Ich geb zu, dass ich da nicht so richtig durchsehe. Ich vermute (und hoffe insgeheim) da es da nur um wenige Codezeilen handeln wird.
danke im Voraus,
-
MS_Noob schrieb:
dass Digiphots ja eigentlich nie power of 2 sind. Meist irgendwie 1280x960.... also immer 1:1,3 oder 1,3: 1.
was hat das seitenverhältnis (nebenbei: ich würds mit 4:3 versuchen) mit 2er-potenzen zu tun?
Klare Frage, wie Realisiere ich nun, dass ich die Extension nutzen kann. Ich geb zu, dass ich da nicht so richtig durchsehe. Ich vermute (und hoffe insgeheim) da es da nur um wenige Codezeilen handeln wird.
http://oss.sgi.com/projects/ogl-sample/registry/
speziell:
http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_non_power_of_two.txtweniger als 0 zeilen werdens nicht. für die performance aber trotzdem nicht gut. außerdem brauchts für hardware, die sowas nicht kann eine alternative, die, wenn man faul ist, einfach aus buildmipmaps besteht (das streckt die textur dann halt auf die passende größe).
-
was hat das seitenverhältnis (nebenbei: ich würds mit 4:3 versuchen) mit 2er-potenzen zu tun?
hmm, vielleicht, weil es Grafikkarten gibt, die nur Quadratische Texturen deren seiten 2x pixel lang sind annehmen?
-
Das mit dem Seitenverhältnis war so gemeint, dass es ja prinzipell bei 4:3 (oder halt 1,3:1) nie möglich wäre beide Seiten auf eine 2er Potenz zu bringen, aber das sollte nur der Erklärung meines Probs dienen. Früher durften die Texturen nur quatratisch und Power_of_two sein, heute reicht es aus, wenn beide seinen ne 2er Potenz sind.
@Trienco:
Ja, ich kenne diesen File auch, aber entweder bin ich zu dumm, oder ...(na ja gibt halt kein "oder")....ich seh die Lösung einfach nicht. O Codezeilen? Wie soll das gehen? Ich find keinen Ansatz Ich weiß ja prinzipiell, wie man Extensions nutzt, aber bei Multitexturing z.B. da hat man ja irgendwelche Funktionen und Werte die definiert wurden. Es gilt nur zu überprüfen, ob die Ext unterstützt wird und dann gehts schon los.
Aber zu ARB_texture_non_power_of_two ist ja laut dem File gar nichts definiert, keine Funktion, usw.Es ist sicher nur eine Verständnissache, ich stell mich einfach nur zu dumm an. Jetzt hab da diese von Intel erstellte GLsdk gefunden. Ist schon etwas spät heute, aber bin ich da wenigstens auf dem richtigen Tritt. Die scheint einige nette funktionen zum Überprüfen der Extensions zu haben.
Danke schonmal für die weitere Hilfe.
-
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