问题描述
以下数据格式:
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
);
}
着色器的行为正确,因为它们已使用Framebuffer对象进行了测试,并且显示了Framebuffers的正确内容.
The Shaders are behaving correctly, as they were tested with Framebuffer objects, and they display the correct contents of the Framebuffers.
但是,当渲染生成的纹理时,它似乎偏离了原始颜色/值.在大多数情况下, FloatBuffers
提供的值会导致黑色纹理,有时会出现意想不到的颜色(例如,用石灰绿色代替米色).
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).
不幸的是,我无法使用 glPixelStorei
太多,因为该接口缺少其大部分参数.但是无论如何, glGetError
总是返回0,所以我怀疑数据以某种方式被错误地编译到了 dataBuf
字节流中.
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.
这里可能是什么问题?
一些调试详细信息:
-
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->白屏
[li] r:0.9f,g:0.0f,b:0.0f,a:0.9f->红屏[li] r:0.0f,g:0.9f,b:0.0f,a:0.9f->绿屏 - r:0.0f,g:0.0f,b:0.9f,a:0.9f -->蓝屏 [li] r:0.5f,g:0.5f,b:0.5f,a:0.5f->黑屏
- r:0.4f,g:0.32f,b:0.2f,a:0.9f -->绿屏
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
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后端存在相同的行为
推荐答案
我能够使用给定的代码复制问题,并且可以通过单行更改来解决.您的FloatBuffer缺省为big-endian字节顺序,看起来libGDX,LWJGL和/或OpenGL期望有little-endian.我在这里将您的示例制作为可执行的测试用例: https://github.com/yellowstonegames/SquidLib/blob/master/squidlib/src/test/java/squidpony/gdx/tests/issues/Issue6516.java#L37 (测试用例不依赖于整个库,在已经依赖libGDX并具有可用资源的项目中测试libGDX问题很方便).我的解决方法是更改:
I am able to replicate the issue with the given code, and it can be fixed with a one-line change. Your FloatBuffer defaults to big-endian byte order, and it looks like libGDX, LWJGL, and/or OpenGL expect little-endian. I made your example into an executable test case here: https://github.com/yellowstonegames/SquidLib/blob/master/squidlib/src/test/java/squidpony/gdx/tests/issues/Issue6516.java#L37 (the test case doesn't depend on the library as a whole, it just is handy to test libGDX issues in a project that already depends on libGDX and has assets available). My fix is to change:
dataBuf = ByteBuffer.allocateDirect(Float.BYTES * 4 * width * height).asFloatBuffer();
收件人:
dataBuf = ByteBuffer.allocateDirect(Float.BYTES * 4 * width * height).order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
您所拥有的其他一切似乎都是正确的;绘制纹理时,得到的是预期的浑浊棕色,而不是柠檬绿.
It looks like everything else you had is correct; I get the intended muddy brown color when I draw that texture, instead of lime green.
这篇关于在Libgdx/Lwjgl中,加载生成的纹理数据尚无定论的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!