本文介绍了在Libgdx/Lwjgl中,加载生成的纹理数据尚无定论的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下数据格式:

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中,加载生成的纹理数据尚无定论的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-18 14:51