Kann mir jemand sagen, wie ich Texturen beliebiger Größe zeichnen kann? (non Power of 2, größer als MaxTextureSize)
Bedingung: es muß mit jeder Grafikkarte (die Opengl kann) also z.B. OpenGL 1.2 funktionieren.
Ich kann mir bisher folgendes vortellen(oder habs auch schon realisiert), alles aber mit mehr oder weniger Problemen:
1) glDrawPixels(fWidth, fHeight, GL_RGB, GL_UNSIGNED_BYTE, FRGBArray);
Funktioniert, das wird aber für größere Grafiken (und evtl ohne Hardwarebeschleunigung) recht schnell sehr langsam.
2) gluBuild2DMipmaps(GL_TEXTURE_2D, 4, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, pData)
+ glBindTexture(GL_TEXTURE_2D, TmpTex); glTexCoord2f(0, 0);...
Das gibt leider ein recht verwaschenens Bild (Die Texture ist nicht so scharf, wie im Original) und es scheint wohl für Non Power of two auch nicht auf jeder Grafikkarte zu funktionieren.
3) NonPowerOfTwo-Extension - ist leider nicht auf jeder Grafikkarte verwendbar und hilft mir somit nicht.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
glDrawPixels: Würde ich nicht empfehlen, das die Daten jedes mal zur Karte kopiert werden müssen und ob das Hardwarebeschleunigt ist weiß ich auch nich.
gluBuild2DMipmaps: Das würde ich auch nicht empfehlen, da diese Funktion die Bilder an POT anpasst. Und das sorgt unweigerlich dafür, dass die Textur matschig wird. Hast du ja selber schon gemerkt.
Also ich würde die Bilder eher zerschneiden. Also so in 512x512 Texturen. Bzw so das kaum Platz verschenkt wird. Und diese dann darstellen und damit wieder das ganze Bild zusammen bauen.
Also ich würde die Bilder eher zerschneiden. Also so in 512x512 Texturen. Bzw so das kaum Platz verschenkt wird. Und diese dann darstellen und damit wieder das ganze Bild zusammen bauen.
Jep, das ist denke ich die beste lösung.. allerdings, wenn du das ganze zoom-bar machen willst, also so das man das bild auch vergrößern können soll, bekommst du da sehr unschöne effekte an den kanten von den einzelnen tiles (bedingt dadurch das jedes tile für sich gefiltert wird - immer nur bis zum jeweiligen rand)..
Die alternative wären TextureRectangles, allerdings sind die limitiert in ihrer größe und setzen auch irgendeine OpenGL version/extension vorraus..
Mit dem Zerschneiden kann ich dann maxTextureSize Limitierungen umgehen. In einem meiner Fäll geht das wohl wie ich euren Ausführungen entnehme ganz gut, da ich dort nicht zoomen muß, in einem anderen muß ich Zoomen und hab somit Probleme in der Darstellung.
Aber was mache ich mit PowerOfTwo: Wenn ich z.B. Grafiken mit 150x150 Punkten habe?
Die kann ich doch nicht aus x einzelnen Stücken (PowerofTwo) zusammensetzen (oder ist das wirklich der einzige Weg?). Wie sollte man damit umgehen, wenn man das auf jeder Grafikarte darstellen will?
Registriert: Mo Sep 02, 2002 15:41 Beiträge: 867 Wohnort: nahe Stuttgart
user69 hat geschrieben:
Aber was mache ich mit PowerOfTwo: Wenn ich z.B. Grafiken mit 150x150 Punkten habe? Die kann ich doch nicht aus x einzelnen Stücken (PowerofTwo) zusammensetzen (oder ist das wirklich der einzige Weg?). Wie sollte man damit umgehen, wenn man das auf jeder Grafikarte darstellen will?
Der einfachste Weg wäre ja, die Grafik mit nem Bearbeitungsprogramm auf die nächstgrößere (zb. 256) oder nächstkleinere (zb. 128) PoT zu skalieren oder in eine Datei mit der nächsthöheren PoT einfügen. Sprich, die Datei ist 256x256, enthält aber nur eine 150x150 Grafik, der Rest ist schwarz. Die Texturkoordinaten sind dann halt (0, 150/256) und nicht (0, 1).
Dabei dürften meiner Meinung nach wie beim Hochskalieren eigentlich keine Details verloren gehen, es funktioniert überall und man benötigt beim Zeichnen auch nur 1 Quad.
Oder hab ich hier was übersehen?
Registriert: Sa Okt 22, 2005 20:24 Beiträge: 291 Wohnort: Frauenfeld/CH
Vielfach ist es auch leicht, sofern das ganze nicht von anderen Leuten bearbeitet werden können soll, einfach seine Texturen in GIMP Photoshop oder einem anderen Bildbearbeitungsprogramm auf die geeigeneten Grössen zu skalieren.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Hochskalieren. Auch wenn das Bild größer skaliert wird werden die Daten verändert bzw in dem Falle auch weichgerechnet. Je nach Inhalt kann man schon einen Unterschied sehen. Aber bei Fotos oder spieleüblichen Texturen kann man einen Unterschied wohl eher nur messen.
Ohne die Texturdaten zu verändern gibt es einen simplen Trick um eine NPOT Textur in eine POT zu packen und auch noch so zu gestallten, dass man zoomen kann. Das geht aber nur, wenn die Textur nicht wiederholt wird. Also GL_REPEAT und dieses auch mit den Texturkoordinaten benutzt wird. Als Beispiel mal deine 150x150. Packen wird diese in eine 256x256 große Textur mit rechts und unten entsprechend Luft, dann passiert beim Zoomen folgendes. An der Rechten bzw linken Seite sieht man eine Verfärbung. Und zwar in Richtung des Randes den wir gesetzt haben. Diese Verfärbung resultiert aus dem OpenGL internen Texturfilter der zwischen den Texeln interpoliert. Der Trick besteht jetzt darin, dass man die letzte und untere Zeile (Echpixel nicht vergessen) der Textur noch mal in die resultierende Textur packt. Die Texturkoordinaten gehen aber weiterhin nur bis 150/256. Und wenn der Texturfilter die Textur jetzt glätten möchte dann blendet er die Textur mit sich selber. Und schon gibt es am Rand keine Verfärbung mehr und die Textur bleibt trotzdem 1:1 Pixelgetreu erhalten.
Tiles und Zoomen. Das müsste aber eigentlich auch gehen. Man müsste dann aber in den Tiles jeweils eine Überschneidung von einem Pixel erzeugen und die Texturkoordinaten an den Überschneidungen dürften nicht bis zum Rand der Pixel (also 0 oder 1) gehen sondern nur bis zur Mitte der Pixel. Und die Fläche darf natürlich auch nur bis zur Mitte gehen bzw muss dort wieder anfangen.
@user69: Ich weiß ja nicht genau was du vor hast. Deswegen kann es sein, dass das was ich vorschlage evtl unter Umständen etwas übertrieben ist.
Tiles und Zoomen. Das müsste aber eigentlich auch gehen. Man müsste dann aber in den Tiles jeweils eine Überschneidung von einem Pixel erzeugen und die Texturkoordinaten an den Überschneidungen dürften nicht bis zum Rand der Pixel (also 0 oder 1) gehen sondern nur bis zur Mitte der Pixel. Und die Fläche darf natürlich auch nur bis zur Mitte gehen bzw muss dort wieder anfangen.
Stimmt, wenn man sie sich leicht überschneiden lässt sollte es problemlosg ehen
@Lossy eX
Ja das ist woh genau das, was ich brauch. Nun muß ich es "nur" noch umsetzen (sowohl das Aufteilen als auch das Problem mit dem glätten).
Was habe ich vor:
Mein Anwendung ist kein Spiel sondern 3D-CAD nahe.
verschiedene Probleme:
1. Ich will Bemaßungen erzeugen. Je nach User sind da Anzahlen von 0-ca30 (oder max. 50) möglich. Da Text recht schwierig ist und per OpenGl auch bei meinen Versuchen auch nicht so toll aussah habe ich mich dazu entschlossen Bemaßungen als Bitmap (mit hellgelben Hintergrund) zu machen diese darzustellen. Derzeit per Drawpixels. Diese werden nicht gezoomt müssen aber scharf dargestellt werden. Zur Beschleunigung will ich diese nun per Textur zeichnen.
2. Hintergrundbilder einbinden (z.B. Logos von usern definiert). Die muß ich per Textur Zeichenen und tus derzeit per MipMap was zu unschärfe führt.
3. Bitmaps in 2D-Zeichungen darstellen - hab ich bisher noch nicht. (was scharf sein muß und evtl auch per verschiedenen Tiles je nach größe gemacht werden muß).
Die müssen auch Zoombar sein, also das volle Programm, wie von dir beschrieben ;-(
Nun noch meine weiteren Fragen:
- Kann ich die Texture für sihe 1. jedes mal neu erzeugen oder muß ich Sie aus Geschwindigkeitsgründen der Grafikkarte hochladen und mit Bindtexture zuweisen. Wie gesagt, die Gafik dafür ist recht klein (allgemein bis zu 128 Pkt.) und es könne bis zu 50 solche Grafiken sein. Ich habe Angst daß beim Hochladen an die Grafikkarte diese bei alten Modellen zum Problem werden kann. Können da einfach Grafikkarten Probleme machen?
- Zu: Der Trick besteht jetzt darin, dass man die letzte und untere Zeile (Eckpixel nicht vergessen) der Textur noch mal in die resultierende Textur packt. Die Texturkoordinaten gehen aber weiterhin nur bis 150/256. Und wenn der Texturfilter die Textur jetzt glätten möchte dann blendet er die Textur mit sich selber.
=> muß ich nicht auch die linke und erste Zeile doppeln (also ingesamt die Grafik 2 Pixel größer machen?)
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Ah. Da kommen wir der Sache doch näher.
Zu Erstens würde ich dir mal ganz spontan und uneigennützigfolgendes Thema näher ans Herz legen. Die Linien kannst mit OpenGL Linien erzeugen. Text passend dran zeichnen sollte dann eigentlich ein einfaches sein. Und fertig ist die Skalierung.
"Der Trick". Die Linke und obere Spalte/Reihe musst du nicht anpassen, denn wenn du als Filtermodus GL_CLAMP bzw GL_CLAMP_TO_EDGE benutzt dann wird die Mitte des Pixels schon automatisch bis zum Rand der Textur erweitert. Das funktioniert aber auf der anderen Seite nicht, weil die Textur ja einen Rand hat. GL_CLAMP ist seit OpenGL 1.1 enthaltenund GL_CLAMP_TO_EDGE seit OpenGL 1.2. Wobei ich selber gerade nicht weiß wo da eigentlich der Unterschied ist.
Zu 2. und 3. Solltest du damit Probleme habe schieß los. Ich habe das zwar selber noch nicht pratisch praktiziert aber sollte mich wundern wenn ich falsch liege.
Danke, ich denk so werde ich es demnächst mal angehen.
Es wird aber ein paar Tage daueren, da ich noch einen Task zu Ende bringen muß und dann erst mal für 2 Wochen in urlaub gehe...
@Lossy eX: Echt gute tipps von Dir, perfekt.
Ich werde mir demnächst dann mal deine Units anschauen, ob ich da Teile von verwenden kann. Du hast ja echt mal tolle Lizenzbedingungen, nicht die einschränkende GPL. Ganz kann ichs es so wohl nicht nutzen, da ich nicht auf DLLs zurückgreifen kann. Meine App sollte per wie z.B. eine mit Winzip erstellte exe Funktionieren, also als Single File mit angehängten Daten.
Nochmal zu der Frage wie ichs angehe:
- Kann ich die keinen Texturen jedes mal neu erzeugen oder muß ich Sie aus Geschwindigkeitsgründen der Grafikkarte hochladen und mit Bindtexture zuweisen? Wie gesagt, die Gafik dafür ist recht klein (allgemein bis zu 128 Pkt.) und es könne bis zu 50 solche Grafiken sein. Ich habe Angst daß beim Hochladen an die Grafikkarte diese bei alten Modellen zum Problem werden kann. Können da einfach Grafikkarten Probleme machen?
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Sofern du Pascal benutzt kannst du die Units von mir auch direkt benutzen. Also ohne DLL. Allerdings ist es nicht auf Größe optimiert. War auch nie ein Ziel davon. Wobei ein größerer Teil die enthaltenen Codepages sind.
Und Texturen solltest du in jedem Falle hochladen. Wenn sich diese stark verändern kann man zwar pro Frame den Texturspeicher aktualisieren aber um sie richtig nutzen zu können solltest du sie hochladen. Denn da liegt ja genau der Geschwindigkeitsvorteil. So etwas wie glDrawPixels dürfte wohl schon eher Ärger machen. Und zwar was die Geschwindigkeit angeht.
Ältere Karten dürften da kein Problem darstellen. Mal ein kleines Beispiel. 128x128x4 Kanäle ergeben 64KB und das mal 50 ergeben knapp über 3 MB benötigten Speicher. Selbst eine mittlerweile wirklich alte Karte wie eine TNT2 hat mindestens 32 MB Speicher. Und das passt da auf jeden Fall locker noch mit rein.
Was Qualität angeht brauchst du dir auch keine Sorge mache, da RGB(A) mit 8 BPP absolut mittelalterlicher Standard ist. Und das können alle Karten die Texturen können.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Meine Mailadresse findest du auf der Teamseite. Aber falls es nichts wirklich spezielles ist dann immer hier im Forum. Denn so können auch alle Anderen davon profitieren. Und bei Fragen zu den Units sind alle nicht viel weiter als du. Aber Hilfe ist in arbeit.
Wegen GL_CLAMP und GL_CLAMP_TO_EDGE: mbMn dehnt GL_CLAMP den letzten Pixel der Textur bis zum ende des Polys und GL_CLAMP_TO_EDGE lässt die Textur an ihrem Ende enden (also ab hier wird das Quad nicht mehr texturiert). Natürlich jeweils bei Texturkoordinaten >1 oder <0.
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Mitglieder in diesem Forum: 0 Mitglieder und 14 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.