LWJGL IllegalArgument Exception bei glTexImage2D

Runtime

Top Contributor
Hallo zusammen,

ich bekomme wie im Titel beschrieben von LWJGL eine IllegalArgumentException geworfen mit der Message
Code:
Number of remaining buffer elements is 1512756, must be at least 3145728. Because at most 3145728 elements can be returned, a buffer with at least 3145728 elements is required, regardless of actual returned element count
, wobei ich diese ungerechtfertigt finde weil:
GPUs, die ARB_texture_non_power_of_two nicht unterstützen müssen zwingend eine Texturgrösse haben, bei der Breite und Höhe eine Potenz von 2 ist. Um aber trotzdem ein Bild hochzuladen, dessen Breite und Höhe keine Potenz von 2 sind, hab ich mit
Code:
glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, width)
die Breite eingegrenzt. LWJGL will aber trotzdem die volle Anzahl bytes, auch wenn es diese nicht bräuchte, da ich ja nur ein Ausschnitt laden will.Gibts irgend einen (LWJGL) Weg, dieser Exception aus dem Weg zu gehen?

LG Runtime
 

Kr0e

Gesperrter Benutzer
Ich bräuchte für eine qualifizierte Aussage schon etwas Code. So aus dem Stehgreif könnte es viele Ursachen geben.

Aber mal aus Neugier: Unterstützen diese Fähigkeit (Laden von Texturen ohne zwingend als 2er-Potenz) nicht so ziemlich alle Grafikkarten mittlerweile ? Ich meine ,wenn du gezwungen bist, ok dann seh ichs ein. Aber jenachdem machst du dir vlt zuviel Stress...
 

Evil-Devil

Top Contributor
Runtime, du musst das entsprechende Checking deaktivieren.

Siehe dazu im Wiki den NoCheck Parameter.
LWJGL Hidden Switches - LWJGL

Allerdings solltest du darauf achten das dein Programm nicht nur bei dir sondern auch anderen läuft. Das kann bei deaktivierten Checks durchaus auf die Schnauze fallen bzw. ein fehlerhaftes Verhalten provozieren.
 

Runtime

Top Contributor
Ich bräuchte für eine qualifizierte Aussage schon etwas Code. So aus dem Stehgreif könnte es viele Ursachen geben.

Stimmt! Da hab ich was vergessen :S Ich denke folgende Erklärung sollte reichen:
Die Exception wird geworfen, weil der DataBuffer, der übergeben wird kleiner als width * height * numChannels ist, weil ja nicht das gesamte Bild gefüllt werden soll. Deshalb meckert LWJGL, es habe zu wenig Daten, obwohl es eigentlich reichen würde.

Unterstützen diese Fähigkeit (Laden von Texturen ohne zwingend als 2er-Potenz) nicht so ziemlich alle Grafikkarten mittlerweile ? Ich meine ,wenn du gezwungen bist, ok dann seh ichs ein. Aber jenachdem machst du dir vlt zuviel Stress...
Der Sinn dieses Codes ist, auf möglichst vielen Computer zu funktionieren zu können, auch wenn diese relativ alt sind, deshalb möchte ich möglichst viele Ausnahmen behandeln und Extensions nutzen.
 

Runtime

Top Contributor
Ich hab mal an den Anfang der init-Methode
Code:
System.setProperty("org.lwjgl.util.NoChecks", "true")
reingeschrieben, aber die Exception tritt noch immer auf.
 

Evil-Devil

Top Contributor
Entsprechen deine width* height*bitdepth Werte der Textur Größe oder sind das 2er Potenzen?

Poste am besten das Programm oder den Bereich damit man es nachstellen kann.
 
G

Guest2

Gast
Moin,

mir ist zugegebenermaßen nicht klar, was Du erreichen möchtest, aber kann es sein das Du eigentlich glTexSubImage2D suchst?

Viele Grüße,
Fancy
 
S

Spacerat

Gast
Der Sinn dieses Codes ist, auf möglichst vielen Computer zu funktionieren zu können, auch wenn diese relativ alt sind, deshalb möchte ich möglichst viele Ausnahmen behandeln und Extensions nutzen.
Wäre es dann nicht Klüger, die Bildbreiten und -höhen direkt anzupassen bevor man einen Puffer draus macht?
Java:
public static BufferedImage reSize(BufferedImage img)
{
	int w = nearestPowerOfTwo(img.getWidth());
	int h = nearestPowerOfTwo(img.getFeight());
	Image rc = new BufferedImage(w, h, img.getType());
	rc.getGraphics().drawImage(img, 0, 0, w, h, null);
	return rc;
}

public static int nearestPowerOfTwo(int value)
{
	int next = nextPowerOfTwo(value);
	int last = lastPowerOfTwo(value);
	return (value - last < next - value)? last : next;
}

public static int lastPowerOfTwo(int value)
{
	return (int) Math.pow(2.0, Math.floor(log10(value) / log10(2)));
}

public static int nextPowerOfTwo(int value)
{
	return (int) Math.pow(2.0, Math.ceil(log10(value) / log10(2)));
}
Hier mal ein paar Utility-Methoden dafür.
 
Zuletzt bearbeitet von einem Moderator:

Runtime

Top Contributor
@Spacerat
Tut mir leid, ich hab mich verschrieben. Ich übergebe einen nio Buffer, nicht einen DataBuffer :S

@Fancy
Funktioniert glSumImage2D denn auch mit Zahlen, die keine Zweierpotenzen sind? Woher kennt OpenGL dann die tatsächliche Grösse der Textur?

@Evil-Devil
Width & height sind im Beispiel Zweierpotenzen.

Ich kann leider erst am Abend Code posten, da ich Schule hab.
 

Evil-Devil

Top Contributor
Öhm, du übergibst OpenGL (LWJGL) die größen einer Zweierpotenzen Tex und willst dann eine NonPowerOfTwo hochladen? Das kann so doch gar nicht gehen. Du müsstet ja den verbleibenden Speicher leer lassen bzw. mit Weiß oder Schwarz füllen. Besser wäre es den Buffer entsprechend anzupassen, keine NPoT Texturen zu verwenden oder die NPot Textur auf eine PoT zu kopieren.
 
S

Spacerat

Gast
@Spacerat
Tut mir leid, ich hab mich verschrieben. Ich übergebe einen nio Buffer, nicht einen DataBuffer :S
Das leuchtet mir ein. Genaugenommen sogar einen DirectBuffer. Auch hier ist wieder so eine Stelle, wo ich auf ein Machwerk von mir hinweisen könnte - http://www.java-forum.org/spiele-multimedia-programmierung/130336-lwjgl-opengl-text.html#post852545. Des Jar-Archiv ist nicht blos für Text, sondern beinhaltet auch einen TexturMaker aus beliebigen Image-Instanzen statt einen auf Dateinamen beruhenden.
 
Zuletzt bearbeitet von einem Moderator:
G

Guest2

Gast
glTexImage2D setzt eine ganze Textur (der Buffer muss also gleich oder größer als die Textur sein). glTexSubImage2D setzt nur einen Teil einer Textur (der Buffer kann also auch kleiner sein).

Mit NPOT können beide umgehen. Ab OpenGL 2.0 muss jeder Grafikkartentreiber NPOT Texturen unterstützen. NPOT Texture hilft vielleicht bei der Frage, ob man diese nutzen möchte oder nicht.

(glTexSubImage2D wird (/wurde) gerne genutzt um größere Texturen langsam und stückweise auf die Grafikkarte zu schieben, hat dann ein wenig was von einem "stream". Heute gibt es aber GL_ARB_sync (ab GL 3.2 im "core"), mit dem auch verschiedene GL Threads synchronisiert werden können - ein streamen mit glTexSubImage2D wird dadurch unnötig)

Viele Grüße,
Fancy
 

Runtime

Top Contributor
@Fancy
Wenn ich also glTexSubImage2D aufrufe, woher weiss denn OpenGL wie gross diese Textur ist? Es wird ja nur ein Ausschnitt gezeigt, die Breite und die Höhe der Textur sind damit ja noch nicht definiert.

@Spacerat
Ich könnte für alles, was ich bisher in OpenGL schrieb und schreibe, fremden Code nehmen. Mein Ziel ist nicht die Produktivität, sondern der Lerneffekt und der Spass den ich beim Programmieren habe.

Wie ich es bisher versucht habe:
Java:
    public static Texture createTexture(int width, int height, TextureDataFormat format, int bitDepth, byte[] data) {
        TextureData texData = new TextureData(width, height, format);
        
        int wPower2;
        int hPower2;
        
        if(GLContext.getCapabilities().GL_ARB_texture_non_power_of_two) {
            wPower2 = width;
            hPower2 = height;
        } else {
            wPower2 = (int) Math.pow(2, Math.ceil(Math.log(width) / Math.log(2)));
            hPower2 = (int) Math.pow(2, Math.ceil(Math.log(height) / Math.log(2)));
            GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, width);
        }
        
        texData.bind();
        
        switch(bitDepth) {
            case 1:
                FloatBuffer palette = InkWaveUtils.wrap(new float[] {0, 1});
                GL11.glPixelMap(GL11.GL_PIXEL_MAP_I_TO_R, palette);
                GL11.glPixelMap(GL11.GL_PIXEL_MAP_I_TO_G, palette);
                GL11.glPixelMap(GL11.GL_PIXEL_MAP_I_TO_B, palette);
                GL11.glPixelMap(GL11.GL_PIXEL_MAP_I_TO_A, palette);

                GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, DATA_TYPES_4BIT[format.numChannels() - 1], wPower2, hPower2,
                        0, GL11.GL_COLOR_INDEX, GL11.GL_BITMAP, InkWaveUtils.wrap(data));
                break;

            case 2:
                GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, DATA_TYPES_8BIT[format.numChannels() - 1], wPower2, 
                        hPower2, 0, DATA_FORMAT[format.numChannels() - 1], GL11.GL_UNSIGNED_BYTE, InkWaveUtils.wrap(convert2to8(data)));
                break;

            case 4:
                GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, DATA_TYPES_4BIT[format.numChannels() - 1], wPower2,
                        hPower2, 0, DATA_FORMAT[format.numChannels() - 1], GL12.GL_UNSIGNED_SHORT_4_4_4_4, InkWaveUtils.wrap(data));
                break;

            case 8:
                GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, DATA_TYPES_8BIT[format.numChannels() - 1], wPower2, 
                        hPower2, 0, DATA_FORMAT[format.numChannels() - 1], GL11.GL_UNSIGNED_BYTE, InkWaveUtils.wrap(data));
                break;

            case 16:
                GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, DATA_TYPES_16BIT[format.numChannels() - 1], wPower2, 
                        hPower2, 0, DATA_FORMAT[format.numChannels() - 1], GL11.GL_UNSIGNED_SHORT, InkWaveUtils.wrap(data));
                break;

            default:
                throw new IllegalArgumentException(bitDepth + " is an unsupported bit depth.");
        }
        return new Texture(texData, width, height);
    }
 
S

Spacerat

Gast
Lerneffekt ist gut und schön, der ist ja eigentlich immer da, sogar auch dann, wenn man Fremdcode analysiert bzw analysieren muss, weil nicht dokumentiert. Ich hatte z.B. irgend wann mal gelernt, dass jeder gerne auf Vorhandenes zurückgreift, in Sachen GL ganz speziell, wenn es darum geht Objekte und Bilder der verschiedensten Formate zu lesen und oder zu schreiben. So ist man dann recht schnell dabei und sucht sich einen Wolf nach z.B. Texturladern, die einem letztendlich nie genügen und man es deswegen doch selber macht. Dein Code sieht da nicht anders aus, deine Textur-Klassen lassen jedenfalls darauf schliessen.
[OT]BTW.: Ich weis zwar nicht, was [c]InkWaveUtils.wrap()[/c] bei dir macht, zumindest kann in DirectBuffers nicht "gewrapped" werden. Musste mich dahingehend auch durch dieses Forum "belehren" lassen. LMR.: Du weisst es auch nicht, weil der Texturlader nicht von dir stammt?[/OT]
Aber wie sonst käme man auf die Idee, Texturen anhand einiger ints, einem Datenformat und eines Bytearrays erstellen zu wollen, wo es doch eigentlich auf der Hand liegt (berichtigt mich bitte, wenn ich da falsch liege), sie anhand eines ladbaren Images zu erstellen.
Um z.B. an eines dieser Bytearrays zu gelangen, welches Daten eines bisher nicht unterstützten mit unter auch recht exotischen Datenformates (z.B. TIFF oder gar ACBM/ILBM) liefern soll, lernt man nun mitunter auch noch, fern ab vom eigentlichen Ziel, den Aufbau diverser Grafik- oder gar Objektformate kennen. Schon ist man erneut auf der Suche oder meisselt mal wieder selbst, wie gesagt, fern ab vom Ziel GL (oder Java3D oder JOGL oder ähnliches) lernen zu wollen.
[OT]Ich kenne im übrigen vier verschiedene Lader für WaveFront-Objekte die alle zueinander inkompatibel sind, aber nur einen, der die vier anderen durchaus ersetzen könnte (faktisch tut er dies sogar, bei mir jedenfalls). Ähnliches gilt für Grafik- und Soundformate. Der jeweils zu allen anderen APIs kompatible Dateilader ist Teil einer sauber von jeglichen anderen APIs getrennten und inzwischen exessiv von mir genutzten Datentyperkennung aus eigener Feder (mein erstes und bisher grösstes Projekt). Das mal zum Thema Lerneffekt.[/OT]
 
Zuletzt bearbeitet von einem Moderator:

Runtime

Top Contributor
Lerneffekt ist gut und schön, der ist ja eigentlich immer da, sogar auch dann, wenn man Fremdcode analysiert bzw analysieren muss, weil nicht dokumentiert.
Diese Aussage hat schon etwas Wahres, aber wenn man es selbst macht, kann man es sich besser merken und auch besser anwenden.

BTW.: Ich weis zwar nicht, was [c]InkWaveUtils.wrap()[/c] bei dir macht, zumindest kann in DirectBuffers nicht "gewrapped" werden. Musste mich dahingehend auch durch dieses Forum "belehren" lassen. LMR.: Du weisst es auch nicht, weil der Texturlader nicht von dir stammt?
InkWaveUtils ist eine von mir geschriebene Utility Klasse. Wrap ist schon nicht wirklich ein Wrap-Vorgang, sondern es alloziiert einen direkten Buffer mit der entsprechenden Grösse, kopiert das byte-Array rein und setzt die Endianness aus ByteOrder.LITTLE_ENDIAN.

Um z.B. an eines dieser Bytearrays zu gelangen, welches Daten eines bisher nicht unterstützten mit unter auch recht exotischen Datenformates (z.B. TIFF oder gar ACBM/ILBM) liefern soll, lernt man nun mitunter auch noch, fern ab vom eigentlichen Ziel, den Aufbau diverser Grafik- oder gar Objektformate kennen. Schon ist man erneut auf der Suche oder meisselt mal wieder selbst, wie gesagt, fern ab vom Ziel GL (oder Java3D oder JOGL oder ähnliches) lernen zu wollen.
Ich hab gar nie gesagt, dass ich mich nur auf OpenGL konzentrieren möchte, ich denke Datenformate zu kennen ist schon nützlich.

Könntest du noch den Link zu deinem Projekt posten? Ich werde vllt Nutzen daran finden. Wenn ich Code von dir verwende (wenn ich darf) werde ich deinen Namen hinzufügen, aber mir gehts mal darum herauszufinden, wie du das ganze aufgebaut hast.
Btw: Dein Post kann mir nur meine nicht im Forum gestellten Fragen beantworten.
 
S

Spacerat

Gast
Könntest du noch den Link zu deinem Projekt posten? Ich werde vllt Nutzen daran finden. Wenn ich Code von dir verwende (wenn ich darf) werde ich deinen Namen hinzufügen, aber mir gehts mal darum herauszufinden, wie du das ganze aufgebaut hast.
Btw: Dein Post kann mir nur meine nicht im Forum gestellten Fragen beantworten.
Meinst du dieses hier? Oder JGL? Egal... mit dem Link hätte ich in soweit ein Problem, weil es keinen gibt. Als privater Einzelkämpfer entzieht es sich meiner Kenntnis, wo ich meine Projekte sinnvoll veröffentlichen könnte (Okay, man kann googeln und stösst dann vllt. auf Hoster für Webspace und anderes unbekanntes Zeugs, aber man hat keinerlei Möglichkeit ein Projekt zu umwerben bzw. bekannt zu machen). Alles was ich bisher tun kann, ist hier da und dort ein immer aktuelleres Archiv hochladen und den jeweiligen Host (vorzugsweise wäre es eben dieses Forum hier) damit "füllen" aber genau das würde ich gern vermeiden. Im Moment lassen sich meine Projekte entweder nur verwenden oder analysieren, weil sie überwiegend undokumentiert sind. Bei der oben verlinkten Lib würde ein stetes posten schon allein deswegen wenig Sinn machen, weil ständig eine Installations- bzw. Konfigurationsanleitung und eine Anleitung, wie man eigene Codecs schreibt, dabei sein müsste.
Wäre ja mal interessant, welche Fragen du hier im Forum nicht gestellt hast... Ich jedenfalls bin der Ansicht, dass Dateilader, welche auf spezielle APIs zugeschnitten sind, definitiv der falsche Ansatz sind. So wie ich meine, dass es sein sollte manifestiert sich in meinen Porjekten (DataTypesLibrary und JGL). Vllt. beantwortet das ja schon einige von diesen Fragen.
 

Runtime

Top Contributor
Dass die beiden Libraries im Grunde unabhängig sein sollen, kann ich nachvollziehen, da IO und Grafik zu unterschiedlich sind. Danke für die Idee mit den DataTypes :), das ist die Art System, die ich gesucht hab, ich werde das so durchziehen. Die vorherigen Fragen müssen nur nonoch geklärt werden, dann bin ich vollends zufrieden :) und unheimlich dankbar, weil das Projekt schon seit Wochen aus diesem Grund still steht.
 
G

Guest2

Gast
Bei glTexSubImage definierst Du vorher die Textur ganz normal mit glTexImage2D, dort kannst Du als Buffer auch null übergeben. So wird z.B. nur die linke Hälfte der Textur gesetzt:

Java:
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width * 2, height, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, (ByteBuffer) null);
        GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, width, height, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, texture);

Das skaliert Dir Deine Textur aber nicht auf POT.

Unabhängig davon kannst Du imho davon ausgehen, dass jede Grafikkarte außerhalb eines Museums intern alles als 32Bit RGBA8 darstellt, egal was Du für Parameter setzt. Imho ist es deshalb auch sinnvoll die Java Image Methoden zu nutzen, um Dir das Bild als RGBA zurückgeben zu lassen. BufferedImage.getRGB() gibt genau 32Bit RGBA zurück und berücksichtigt dabei sowohl den Farbraum (sRGB) als auch das ColorModel (TYPE_INT_ARGB). Imho vollkommen stressfrei.

Wenn Du es für sinnvoll hältst, lässt sich das Bild damit auch leicht auf POT skalieren, bevor es dann auf die Grafikkarte geschoben wird.

Viele Grüße,
Fancy
 

Marco13

Top Contributor
Imho ist es deshalb auch sinnvoll die Java Image Methoden zu nutzen, um Dir das Bild als RGBA zurückgeben zu lassen. BufferedImage.getRGB() gibt genau 32Bit RGBA zurück und berücksichtigt dabei sowohl den Farbraum (sRGB) als auch das ColorModel (TYPE_INT_ARGB). Imho vollkommen stressfrei.

Für jeden Pixel getRGB dürfte ziemlich langsam sein, dann lieber getPixels oder direkt den DataBufferInt-Inhalt holen. Ich meine auch da wären noch ein paar Glitches wegen ARGB vs. RGBA... aber vielleicht täusche ich mich auch.
 
G

Guest2

Gast
Ich hatte das hier im Sinn:

Java:
		BufferedImage image = ImageIO.read(inputStream);

[..]

		final int[] pixels = image.getRGB(0, 0, width, height, null, 0, width);
        final IntBuffer texture = BufferUtils.createIntBuffer(pixels.length);
        texture.put(pixels);
        texture.rewind();

[..]

        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, texture);

Dann muss man eigentlich nur noch aufpassen das man entweder das image oder die pixels spiegelt um den Ursprung von oben/links auf unten/links zu bekommen.

Der Weg über das Raster geht natürlich auch (mach ich selber auch oft ;)), allerdings muss man da ihmo ein wenig vorsichtiger sein, falls der Farbraum des image nicht sRGB ist, sondern z.B. "irgendwas" anderes. Laut JavaDoc berücksichtigt getRGB sowohl ColorModel als auch Farbraum. (Ich hab z.B. keinen Schimmer, wie weit die Werte sonst abweichen, wenn z.B. ein JPG in Adobe Wide RGB eingelesen wird.)

Viele Grüße,
Fancy
 

Marco13

Top Contributor
Oh ja stympt, beim BufferedImage heißt's getRGB, das getPixels war beim Raster ... aber wo da was mit ColorModel oder nicht umgewandelt wird, müßte ich mir auch noch genauer ansehen. Meine Frage resultierte wohl eher aus einem mangelnden Verständnis meinerseits für die genaue Bedeutung der Parameter:

Code:
void glTexImage2D(GLenum  target,  GLint  level,  GLint  internalFormat,  GLsizei  width,  GLsizei  height,  GLint  border,  GLenum  format,  GLenum  type,  const GLvoid *  data);

// Bei dir:
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, texture);

Ich dachte immer, 'internalFormat' wäre das, wie es intern gespeichert wird, und 'format' das, wie es tatsächlich im Datenblock gegeben ist, aber das stimmt wohl so nicht (und die Dokus zu dieser Methode sind meistens total besch^C^C^C^C nur eine Auflistung der akzeptierten Konstanten :autsch: )

Ich dachte:
- Der type ist GL_UNSIGNED_BYTE, weil das der Typ der einzelnen Komponenten ist (und welche Komponenten es gibt, geht aus dem format/internalFormat hervor). Bei dir ist das jetzt GL_UNSIGNED_INT_8_8_8_8_REV, was ich vorher noch nie gesehen hatte...

- Das format und das internalFormat ist eher eine art "Vereinbarung", wie die übergebenen Daten zu interpretieren sind - und man darf lügen :D Man kann also irgendwelche Daten übergeben, und OpenGL interpretiert sie so, wie im 'format' angegeben, und wandelt sie ins 'internalFormat' - die beiden bestimmen also lediglich eine art "Permutation" der echt gegebenen Daten.

Aber das ist wohl grober Unfug :( Werd' wohl nochmal eine Weile websuchen müssen, um eine Definition des Unterschiedes zwischen GL_RGBA8 und GL_RGBA zu finden, und eine Definition von GL_UNSIGNED_INT_8_8_8_8_REV und was genau wo zu stehen hat. Erstaunlich finde ich jetzt nur, dass mit
type = GL_UNSIGNED_BYTE;
internalFormat = GL_RGBA;
format = GL_BGRA;
die ARGB (!)-Daten, die ich aus einem Image hole, richtig angezeigt werden :rolleyes:
 
G

Guest2

Gast
So sehr liegst Du gar nicht daneben! ;)

Vielleicht hilft:

Image precision
Textures Internal and External

Da stehen dann auch so Feinheiten wie:

http://www.opengl.org/wiki/Textures_-_more hat gesagt.:
GL_RGBA8 doesn't truly mean that the GPU will store it as GL_RGBA8. It might actually store it as GL_BGRA8.


Auch hinter dem GL_UNSIGNED_INT_8_8_8_8_REV steckt nicht sonderlich viel. Aus dem getRGB() kommt ARGB und wir wollen BGRA. Das ist genau dasselbe nur eben jeweils 4 Bytes gelesen und von hinten nach vorne interpretiert und genau das macht GL_UNSIGNED_INT_8_8_8_8_REV. ;)


Viele Grüße,
Fancy
 
G

Guest2

Gast
Nachtrag:

Erstaunlich finde ich jetzt nur, dass mit
type = GL_UNSIGNED_BYTE;
internalFormat = GL_RGBA;
format = GL_BGRA;
die ARGB (!)-Daten, die ich aus einem Image hole, richtig angezeigt werden :rolleyes:

texture ist ein IntBuffer mit little endian. Deshalb ist GL_UNSIGNED_BYTE und GL_UNSIGNED_INT_8_8_8_8_REV im Ergebnis gleich. Aber stimmt, GL_UNSIGNED_BYTE sollte hier die bessere Wahl sein. Bei einem ByteBuffer muss es allerdings GL_UNSIGNED_INT_8_8_8_8_REV sein.

Viele Grüße,
Fancy
 
S

Spacerat

Gast
@Guest2: Der TO will ja seine Software auf möglichst vielen Rechnern (auch ältere) lauffähig machen (Bemerkenswert, wie ich finde). Deswegen glaube ich kaum, das GL_UNSIGNED_INT_8_8_8_8_REV auch nur annähernd hilfreich ist, denn meines Wissens ist das in GL1.x nicht vorhanden. Ich arbeitete extrem lange (viel zu lange nehm ich an) mit OpenGL1.1, ganz einfach deswegen, weil JOGL dies tat - naja keine Zeit für die Geschichte, warum ich LWJGL nun vorziehe. Deswegen aber existieren in meiner JGL-Lib diese Komponentendreher ebenfalls (benötigen natürlich CPU-Zeit).

Mir drängt sich im übrigen angesichts dieser Massen an Varianten dringende Verständnisfragen auf...

1. Neueren Grakas scheint das Pixelformat ja relativ egal zu sein, deswegen gibt es in OGL nun weitere Formatkonstanten. Sind es auschliesslich die Grakas die andere Formate unterstützen oder springt GL zur Not auch ein, das Format softwareteschnisch (CPU-Zeit) zu ändern, wenn die Graka es nicht unterstützt?
2. läuft ein neueres GL überhaupt auf älterer Hardware? Wenn ja, dann müsste man doch eigentlich nur die OGL-Version auf dem älteren System vorraussetzen und sich während der SW-Entwicklung um diverse Programmiertechniken keinen Kopf mehr machen. Wenn nicht, dürfte man maximal mit OGL1.1 arbeiten und den ganzen aktuelleren "Kram" softwaretechnich lösen - Umgebung erforschen und Methodenaufrufe ggf. umleiten oder selbst implementieren und CPU-Zeit nutzen. Das bringt mich zu...
3. Immer besser werdende Grakas laufen wohl kaum auf älteren Systemen (passt ja schon von der Schnittstelle nicht - PCI-E). Immer besser werdende Grakas benötigen aber auch immer weniger CPU-Zeit, weil sie halt alles selber machen, z.B. Pixelformate von Texturen umwandeln. Benötigen besser werdende Grakas überhaupt noch CPU-Zeit geschweige denn eine wahnsinnig schnelle CPU?
4. Das Bemerkenswerte am Vorhaben des TO ist doch, dass neuere Technologien auf älteren Systemen gar nicht lauffähig sind. Sie mögen zwar funktionieren, aber man hätte unheimlich niedrige Bildwechselfrequenzen vllt. 25fpd (Frames per Decade :lol:). @TO: Was genau hast du vor?
 
Zuletzt bearbeitet von einem Moderator:
G

Guest2

Gast
Viele Fragen und viele relative Antworten: ;)

1. GL_UNSIGNED_INT_8_8_8_8_REV ist in OpenGL 1.2 definiert. Dank dem anstupser von Marco oben, ist aber aufgefallen, dass dies hier gar nicht nötig ist, da getRGB() ARGB als int[] zurückgibt, welches in einen IntBuffer mit little endian abgelegt werden kann. Bei der Angabe von GL_UNSIGNED_BYTE wird das aber eben auch als BGRA interpretiert und ist damit im Ergebnis gleich zu GL_UNSIGNED_INT_8_8_8_8_REV.

JOGL unterstützt dieselben OpenGL Profile wie LWJGL (alle aktuellen).

Die gebräuchlichsten (auch älteren) dedizierten Grafikkarten unterstützen entweder OpenGL 3.1 (wenn kein Geometrieshader vorhanden ist), OpenGL 3.3 (wenn er vorhanden ist) oder OpenGL 4.2 (wenn ein Tessellationshader vorhanden ist). Die gebräuchlichsten onbord Grafikkarten unterstützen mindestens OpenGL 2.0.

Theoretisch könnte es noch uralt onbord Grafikkarten geben, welche lediglich OpenGL 1.4 unterstützen. Auf noch älteren Rechnern läuft dann aber vermutlich auch kein Java mehr.

Wenn ein OpenGL Feature in OpenGL spezifiziert ist und der Grafikkartentreiber diese OpenGL Version unterstützt, dann muss das Feature zur Laufzeit zur Verfügung stehen (entweder per Hartware oder per Software). Wenn das Feature als OpenGL Extension spezifiziert wurde, dann kann es zur Laufzeit zur Verfügung stehen, muss aber nicht.

2. Normalerweise wird der Treiber soweit aktualisiert (und stellt damit neuere OpenGL Versionen zur Verfügung) bis andere Anforderungen an die Hartware gestellt werden. Das war bei OpenGL 3.2 der Fall, als der Geometrieshader verpflichtend wurde oder bei OpenGL 4.0 als der Tessellationshader verpflichtend wurde.

3. Bei allem, was mit Grafik zu tun hat, wird die CPU in der Tat immer unwichtiger. Allerdings können heutige Grafikkarten ungeheure Datenmengen verarbeiten. Unter Umständen mehr als in den Speicher der Grafikkarte passt, dann muss die CPU schnell zuarbeiten können. Außerdem führen einige OpenGL Befehle zu einer Synchronisation zwischen CPU und GPU, dann kann die CPU die GPU durchaus ausbremsen.

4. Imho sollte man sich bei einem Projekt mit OpenGL eine realistische Version als Mindestanforderung setzen und dann seinen Renderpfad entsprechend umsetzen. Zu versuchen alles zu unterstützen wird in den meisten Fällen imho nur ein unbefriedigendes (umständliches) Ergebnis liefern.

Hier gibt es einen Überblick über die verschiedenen OpenGL Versionen und stichpunktartig die Grafikkarten, welche mindestens dazu notwendig sind. Vielleicht hilft das.

Viele Grüße,
Fancy
 

Runtime

Top Contributor
Ich möchte eine weitere Gamegrafiklibrary machen, aber im Style von JavaFX, weil JavaFX zum Programmieren sehr umständlich ist und nur sehr begrenzt unterstützt wird (Java 5). Die maximal verwendete OpenGL Version ist 2.0.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
coolian lwjgl glfw window zeigt nur grau an Spiele- und Multimedia-Programmierung 0
coolian slick lwjgl text darstellen mit UnicodeFont funktoniert nicht? Spiele- und Multimedia-Programmierung 11
F OpenGL (LWJGL) Shader Programmierung GLSL Spiele- und Multimedia-Programmierung 2
Meeresgott LWJGL 3 Problem mit einer Texture Spiele- und Multimedia-Programmierung 4
V LWJGL GUI Spiele- und Multimedia-Programmierung 1
V GUI in LWJGL 2 erstellen Spiele- und Multimedia-Programmierung 6
C GLSL Shaderprogrammierung in LWJGL 3 Spiele- und Multimedia-Programmierung 12
G Low Poly 3D LWJGL Shader Problem Spiele- und Multimedia-Programmierung 4
B LWJGL OpenGL SIGSEGV auf Linux (Verzweiflung :/) Spiele- und Multimedia-Programmierung 8
G LWJGL .obj .mtl loader Spiele- und Multimedia-Programmierung 3
G 2D animationen LWJGL Spiele- und Multimedia-Programmierung 0
pcfreak9000 "Allgemeine" Performance verbessern (LWJGL 2) Spiele- und Multimedia-Programmierung 2
G LWJGL Rendert nicht Spiele- und Multimedia-Programmierung 3
G lwjgl verwendung Spiele- und Multimedia-Programmierung 6
R [LWJGL] Skeletal Animation Spiele- und Multimedia-Programmierung 5
E LWJGL glGenVertexArrays() erzeugt doppelte IDs Spiele- und Multimedia-Programmierung 3
G Java 2D Spiel mit LWJGL verbinden Spiele- und Multimedia-Programmierung 1
Streeber Problem mit Transparenz/TextDrawing in LWJGL/Slick2d (OpenGL) Spiele- und Multimedia-Programmierung 1
K No Lwjgl Spiele- und Multimedia-Programmierung 2
T LWJGL 2.9.2: Seltsamer Effekt beim Rendern (VertexShader Problem?) Spiele- und Multimedia-Programmierung 3
T LWJGL: Terrain-Texturen / 2D-Array in Shader? Spiele- und Multimedia-Programmierung 2
S 2D-Render Probleme LWJGL 2 (Java) Spiele- und Multimedia-Programmierung 1
P java lwjgl Game Spiele- und Multimedia-Programmierung 0
T [LWJGL] Textur / File wieder freigeben Spiele- und Multimedia-Programmierung 4
F [LWJGL] Skeletal Animation 3D Spiele- und Multimedia-Programmierung 1
C Generelle Hilfe zur lwjgl Spiele- und Multimedia-Programmierung 0
D LWJGL gluLookAt "Umschauen" Problem Spiele- und Multimedia-Programmierung 0
D Problem mit Würfelanimierung in LWJGL Spiele- und Multimedia-Programmierung 7
RalleYTN LWJGL Vignette Spiele- und Multimedia-Programmierung 2
E LWJGL Switchen zwischen gluOrtho und gluPerspective Spiele- und Multimedia-Programmierung 0
RalleYTN LWJGL Rotation Spiele- und Multimedia-Programmierung 1
C LWJGL Color Picking Textures deaktivieren Spiele- und Multimedia-Programmierung 0
K FBO Framebuffer object [LWJGL] 2D tutorial gesucht Spiele- und Multimedia-Programmierung 2
K [LWJGL] 2D Tunneler Hintergrund Spiele- und Multimedia-Programmierung 7
S LWJGL 3d-spieleentwicklung Spiele- und Multimedia-Programmierung 3
H LWJGL-Renderfail Spiele- und Multimedia-Programmierung 1
Seikuassi LWJGL - Texturen flackern Spiele- und Multimedia-Programmierung 2
Androbin LWJGL - Kollisions-Bug (Fallen) Spiele- und Multimedia-Programmierung 14
K Schiessen in 2D (LWJGL) Spiele- und Multimedia-Programmierung 2
S LWJGL Kamera Problem - Alles verzerrt Spiele- und Multimedia-Programmierung 4
U Kann nur ein Objekt mit LWJGL rendern Spiele- und Multimedia-Programmierung 2
X LWJGL | Parent.isDisplayable() must be true | wie kann man das zu true machen? Spiele- und Multimedia-Programmierung 0
X [LWJGL] Binden von Texturen per PNG File und Texture Sheet Spiele- und Multimedia-Programmierung 1
X LWJGL - Anklick baren Button erstellen aber wie? Spiele- und Multimedia-Programmierung 6
U Quadrate anklicken LWJGL Spiele- und Multimedia-Programmierung 3
B LWJGL / OPENGL Kriege Depth-Test nicht hin :( Spiele- und Multimedia-Programmierung 0
B LWJGL Manche Seiten werden transparent angezeigt Spiele- und Multimedia-Programmierung 2
T LWJGL VBO's funktionieren nicht, geben aber auch keinen Fehler Spiele- und Multimedia-Programmierung 0
U Komische fragmente bei LWJGL Spiele- und Multimedia-Programmierung 6
B LWJGL StackOverFlow Problem nach 30sekunden. (Pong) Spiele- und Multimedia-Programmierung 2
Q LWJGL - Alpha-Probleme Spiele- und Multimedia-Programmierung 2
S [LWJGL] Zweimal selbe Textur trotz unterschiedlicher IDs Spiele- und Multimedia-Programmierung 3
O LWJGL AWTGLCanvas Tiefe auf 1 beschränkt Spiele- und Multimedia-Programmierung 5
Seikuassi LWJGL-Problem Spiele- und Multimedia-Programmierung 2
S [LWJGL] schwarzer Bildschrim beim rendern von .obj Model Spiele- und Multimedia-Programmierung 2
S [lwjgl] Renderbug bei mehreren Objekten Spiele- und Multimedia-Programmierung 2
R LWJGL: OpenGL Fehler - weitere Informationen auslesen möglich? Spiele- und Multimedia-Programmierung 2
S LWJGL Kamera Koordinaten invertiert. Spiele- und Multimedia-Programmierung 2
M LWJGL Text rendern Spiele- und Multimedia-Programmierung 3
B LWJGL Mauskoordinaten Spiele- und Multimedia-Programmierung 1
J LWJGL Update Schleife (Snake) Spiele- und Multimedia-Programmierung 6
B LWJGL Display.update() ist langsam Spiele- und Multimedia-Programmierung 5
R LWJGL: Performance glBegin, drawList, ... Spiele- und Multimedia-Programmierung 16
R LWJGL: Object Loader -> .obj, .c4d, ... laden Spiele- und Multimedia-Programmierung 3
R LWJGL: Textur -> unsichtbare Stellen, wie erzeugen? Spiele- und Multimedia-Programmierung 4
A LwJGL - Animation Stockt Spiele- und Multimedia-Programmierung 5
R [lwjgl] Cursor -> versetzt Zeichnen / Bild ist umgedreht Spiele- und Multimedia-Programmierung 2
R LWJGL: 3D Picking Spiele- und Multimedia-Programmierung 4
F LWJGL: Textur ändern mit GL11.readPixels Spiele- und Multimedia-Programmierung 5
F LWJGL: Licht und GL_LINES funktioniert nicht Spiele- und Multimedia-Programmierung 6
A [LWJGL] BMP Textur wird nicht richtig dargestellt Spiele- und Multimedia-Programmierung 8
S LWJGL Rechteck wird nicht gezeichnet Spiele- und Multimedia-Programmierung 6
F LWJGL: Is undefined? Spiele- und Multimedia-Programmierung 7
F LWJGL Kamerabug Spiele- und Multimedia-Programmierung 2
F LWJGL Problem mit Erstellen eines Objekts und der Kamera Spiele- und Multimedia-Programmierung 5
F LWJGL Dreidimensionaler Würfel Spiele- und Multimedia-Programmierung 15
P LWJGL oder OpenGL (C++) Spiele- und Multimedia-Programmierung 7
P "Tiefe" in Objekten - LWJGL Spiele- und Multimedia-Programmierung 12
T LWJGL 3D Objekt Collision: Wie? Spiele- und Multimedia-Programmierung 11
S LWJGL Kamera Frage Spiele- und Multimedia-Programmierung 2
V Komischer Fehler in LWJGL Spiele- und Multimedia-Programmierung 18
Z lwjgl oder jogl nutzen Spiele- und Multimedia-Programmierung 9
Y LWJGL Hintergrund Spiele- und Multimedia-Programmierung 7
Creylon [LWJGL] Textur wird falsch angezeigt Spiele- und Multimedia-Programmierung 12
Creylon [LWJGL] Spiel Exportieren Spiele- und Multimedia-Programmierung 2
Creylon [LWJGL] 2D Sprite Rotieren/Drehen Spiele- und Multimedia-Programmierung 6
CookieSoft LWJGL Ubuntu 12.04 Fehler Spiele- und Multimedia-Programmierung 7
E [LWJGL] Karusell, mehrere Objekte drehen sich um einen Mittelpunkt Spiele- und Multimedia-Programmierung 31
F lwjgl - Skysphere Spiele- und Multimedia-Programmierung 3
CookieSoft Slick und LWJGL Texture lag Spiele- und Multimedia-Programmierung 13
U OpenGl 1.1 (LWJGL GL11.*) und weiter? Spiele- und Multimedia-Programmierung 7
0 Grafikfehler LWJGL Spiele- und Multimedia-Programmierung 2
A LWJGL 3D Objekte Kollision Spiele- und Multimedia-Programmierung 3
Luk10 (LWJGL) Aufwendiges Animieren von Texturen Spiele- und Multimedia-Programmierung 16
S (LWJGL) VertexBufferObjects Spiele- und Multimedia-Programmierung 20
T LWJGL Grafik meines Projektes läuft nicht korrekt auf meinem iMac Spiele- und Multimedia-Programmierung 19
B LWJGL/OpenGL rendert manche Objekte nicht Spiele- und Multimedia-Programmierung 6
H LWJGL: Fragen zum Verständnis Spiele- und Multimedia-Programmierung 7
T LWJGL Gui erstellen Spiele- und Multimedia-Programmierung 7
Kenan89 lwjgl Exception Spiele- und Multimedia-Programmierung 3

Ähnliche Java Themen


Oben