【发布时间】:2021-07-21 16:27:00
【问题描述】:
以下数据格式:
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
);
}
着色器的行为正确,因为它们已使用帧缓冲区对象进行测试,并且它们显示帧缓冲区的正确内容。
但是当生成的纹理被渲染时,它似乎偏离了原始的颜色/值。
在大多数情况下,FloatBuffers 提供的值会导致黑色纹理,有时会出现意想不到的颜色(例如,石灰绿色而不是米色)。
不幸的是,我无法使用glPixelStorei,因为该界面缺少大部分参数。但无论如何glGetError 总是返回0,所以我怀疑数据以某种方式错误地编译到dataBuf 字节流中。
这可能是什么问题?
编辑:一些调试细节:
-
glGetError()始终为零 - 各个组件似乎对数据有一个粗略的了解,但大多数值都会产生黑色纹理:
- r: 1.0f, g: 1.0f, b: 1.0f, a: 1.0f --> 黑屏
- r: 0.9f, g: 0.9f, b: 0.9f, a: 0.9f --> 白屏
- r: 0.9f, g: 0.0f, b: 0.0f, a: 0.9f --> 红屏
- r: 0.0f, g: 0.9f, b: 0.0f, a: 0.9f --> 绿屏
- r: 0.0f, g: 0.0f, b: 0.9f, a: 0.9f --> 蓝屏
- r: 0.5f, g: 0.5f, b: 0.5f, a: 0.5f --> 黑屏
- r: 0.4f, g: 0.32f, b: 0.2f, a: 0.9f --> 绿屏
- 以上我怀疑是因为上传纹理时
dataBuf和openGL-s GL_FLOAT中的浮点值之间存在转换错误 - 否则,着色器和设置工作正常,因为它已使用帧缓冲区的颜色附件进行测试,并且在所有上述值下都可以正常工作。不同的是颜色纹理不是手动生成的,而是通过
glClear(GL_COLOR_BUFFER_BIT);渲染到帧缓冲区中的 - 使用整数缓冲区也可以按预期工作(整数数组,值 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
);
- LWJGL3 后端存在相同的行为
【问题讨论】:
-
“使用整数缓冲区也按预期工作(整数数组,值 0-255)”嗯,没有。当您使用带有
GL_UNSIGNED_INT格式数据的GL_RGBA内部vormat 时,访问它时,范围应为0到4294967295映射到标准化浮点范围[0,1]。当您使用[0,255]输入范围时,所有内容都应该与黑色没有区别。 -
好吧,不管它应该是什么,它在 0 - 255 的值下都能正常工作;我也有你的期望,但在我的机器上它不起作用,如果你认为这会有所帮助,我可以将完整的示例上传到 github。
标签: opengl libgdx buffer textures lwjgl