The following data format:
final int width = 256;
final int height = 256;
final float[][][] data = new float[width][height][4];
FloatBuffer dataBuf;
int textureHandle;
FrameBuffer testFrame;
@Override
public void create () {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
data[i][j][0] = 0.4f; /* r */
data[i][j][1] = 0.38f; /* g */
data[i][j][2] = 0.2f; /* b */
data[i][j][3] = 0.9f; /* a */
}
}
dataBuf = ByteBuffer.allocateDirect( Float.BYTES * 4 * width * height ).asFloatBuffer();
for (float[][] dat : data) { /* Float Byte size * RGBA * width * height */
for (float[] floats : dat) {
dataBuf.put(floats, 0, 4);
}
}
dataBuf.position(0); /* reset the caret position to the beginning of the array */
textureHandle = Gdx.gl.glGenTexture();
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE1);
Gdx.gl.glBindTexture(GL30.GL_TEXTURE_2D, textureHandle);
Gdx.gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_NEAREST);
Gdx.gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MAG_FILTER, GL30.GL_LINEAR);
Gdx.gl.glTexImage2D(
GL30.GL_TEXTURE_2D, 0, GL30.GL_RGBA32F,
width, height, 0, GL30.GL_RGBA, GL30.GL_FLOAT, dataBuf
);
}
The Shaders are behaving correctly, as they were tested with Framebuffer objects, and they display the correct contents of the Framebuffers.
However when the generated texture is rendered, it seems to deviate from the original color/value.
In most cases the values provided by the FloatBuffers result in a black texture, sometimes there is an unexpected color(e.g. lime-green instead of beige).
Unfortunately I couldn't play with glPixelStorei much, because the interface is missing most of its parameters. But in any case glGetError is always returning with 0, so I suspect the data is somehow incorrectly compiled into the dataBuf byte-stream.
What could be the problem here?
Edit: Some debugging details:
glGetError()is always zero- the individual components seem to have a rough idea of the data, but most of the values produce a black texture:
- r: 1.0f, g: 1.0f, b: 1.0f, a: 1.0f --> black screen
- r: 0.9f, g: 0.9f, b: 0.9f, a: 0.9f --> white screen
- r: 0.9f, g: 0.0f, b: 0.0f, a: 0.9f --> red screen
- r: 0.0f, g: 0.9f, b: 0.0f, a: 0.9f --> green screen
- r: 0.0f, g: 0.0f, b: 0.9f, a: 0.9f --> blue screen
- r: 0.5f, g: 0.5f, b: 0.5f, a: 0.5f --> black screen
- r: 0.4f, g: 0.32f, b: 0.2f, a: 0.9f --> green screen
- The above I suspect is because there is a conversion error between the floating point values in
dataBufand openGL-s GL_FLOAT when uploading the texture - Otherwise the shaders and setup works correctly, as it was tested with a Framebuffer's color attachement and works as expected with all of the above values. The differente there was that the color texture was not generated by hand, but rendered into the framebuffer via
glClear(GL_COLOR_BUFFER_BIT); - Using Integer buffers are also working as expected(integer array, values 0-255) :
dataBuf.position(0);
Gdx.gl.glTexImage2D(
GL30.GL_TEXTURE_2D, 0, GL30.GL_RGBA,
width, height, 0, GL30.GL_RGBA, GL30.GL_UNSIGNED_INT, dataBuf
);
- Same behavior is present with LWJGL3 backend
GL_RGBAinternal vormat withGL_UNSIGNED_INTformat data, the range should be0to4294967295mapped to normalized float range[0,1]when accessing it. When you use[0,255]input range, everything should be indistinguishable from black. - derhass