PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : OpenGL-ES 2.0 + GLSL texture fetch


instinct
2009-11-25, 23:49:35
Ich habe gerade ein kleines Problem, welches womöglich durch die Länge meines bisherigen Tages bedingt ist. :redface:
Ich hoffe ihr könnte mir helfen. Folgendes ist ein einfaches Testszenario:

Meine Applikation erzeugt eine 2D-Textur mit vier bytes. Diese wird per als uniform-Variable an den Shader übergeben:

unsigned char data[] = {255,255,255,0};

texIds = (GLuint *)malloc(sizeof(GLuint));
glGenTextures(numTextures, texIds);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texIds[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
...


In meinem Shader wil ich nun lediglich den letzten Wert (0) auslesen und als Farbwert für ein Objekt setzen.

gl_FragColor = texture2D(volume_data, vec2(1.0,1.0));

Ich greife in die Textur mit (1.0,1.0) und müsste doch einen vec4(0.0) bekommen. Stattdessen ist mein Objekt weiss (wegen dem GL_REPEAT). Benutz ich GL_CLAMP_TO_EDGE wirds dunkel grau (was wegen GL_NEAREST nicht sein dürfte).

Kann mir jemand sagen, was ich falsch mache?

instinct
2009-11-26, 00:04:58
Anscheinend liegt es an GL_REPEAT. Ich hab nochma GL_CLAMP_TO_EDGE probiert und nun gehts.
Kann mir jemand erklären, weshalb es mit GL_REPEAT nicht funktioniert? Ich greif ja nicht über die Grenzen der Textur. Also weshalb macht er dann einen wraparound?

Coda
2009-11-26, 00:15:38
1.0 ist nach Wraparound wieder 0.0

Probier mal 0.95 oder sowas.

instinct
2009-11-26, 00:26:41
Bei 0.95 geht er wegen dem Nearest-Filtering auf 1.0 und macht wieder wrap around. Da die Textur nur 2x2 groß ist, bekomm ich mit GL_REPEAT wohl immer nur den ersten Wert. Es sei denn ich würde linear filtern

Coda
2009-11-26, 00:29:39
Dann eben 0.6. Das müsste gehen.

instinct
2009-11-26, 00:31:25
Es ist immer weiss. Ich mein, entweder ist der Wert unerhalb 0.5 und er nimmt den Wert 0.0 oder der Wert ist überhalb 0.5, wodurch 1.0 nimmt, was ein wraparound bedeutet.

Coda
2009-11-26, 00:35:38
Nein, das kann nicht sein. Der Nearest-Wert bezieht sich immer auf das nächste Texelzentrum und das ist bei deinem schwarzen Pixel bei (0.75, 0.75).

Ich vermute irgendwas stimmt dann nicht mit deiner Texturinitialisierung. Frag mal glGetError ab nach jedem Call.

Xmas
2009-11-26, 01:14:24
Du musst GL_UNPACK_ALIGNMENT auf 1 (oder 2) setzen, ansonsten erwartet GL dass Pixelzeilen an einer Speicheradresse welche ein Vielfaches von 4 ist beginnen.

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

Coda
2009-11-26, 02:11:44
Bist du sicher, dass das Array auf dem Stack nicht 4-Byte aligned ist?

Edit: Brainfart. Hast recht.

Stellt sich die Frage: Was ist dann mit letzten beiden Mipmaps bei größeren Texturen? Gilt das dort auch? Ich bin verwirrt.

instinct
2009-11-26, 08:02:52
Ich denke auch das es an dem GL_UNPACK_ALIGNMENT liegt. Ich werds heute Abend mal ausprobieren. Danke für den Tipp

Xmas
2009-11-27, 12:33:00
Stellt sich die Frage: Was ist dann mit letzten beiden Mipmaps bei größeren Texturen? Gilt das dort auch? Ich bin verwirrt.
Natürlich. Aber nur wenn du mehr als eine Zeile, aber weniger als 4 Bytes pro Zeile hast. Bei 32+bpp oder bei quadratischen 16bpp-Texturen ist das z.B. nicht der Fall.