java - 试图解压缩 BC1 纹理压缩的扰乱 block

标签 java compression directx textures rgba

我一直在尝试用Java实现BC1(DXT1)解压算法。一切似乎都工作得相当精确,但我遇到了透明 block 周围的一些 block 的问题。我已经尝试解决这个问题几个小时但没有成功。

简而言之,解压缩所有 block 后,除了透明 block 周围的 block 之外,一切看起来都很好。在开发过程中,我一直在使用用 C++ 编写的 DirectXTex (texconv) 的结果来检查结果。

这是我与 DirectXTex 相比的结果: enter image description here

这是我正在使用的代码:

BufferedImage decompress(byte[] buffer, int width, int height)

和实现:

  BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
  int[] scanline = new int[4 * width]; //stores 4 horizontal lines (width/4 blocks)

  RGBA[] blockPalette = new RGBA[4]; //stores RGBA values of current block

  int bufferOffset = 0;

  for (int row = 0; row < height / 4; row++) {
        for (int col = 0; col < width / 4; col++) {

            short rgb0 = Short.reverseBytes(Bytes.getShort(buffer, bufferOffset));
            short rgb1 = Short.reverseBytes(Bytes.getShort(buffer, bufferOffset + 2));
            int bitmap = Integer.reverseBytes(Bytes.getInt(buffer, bufferOffset + 4));
            bufferOffset += 8;

            blockPalette[0] = R5G6B5.decode(rgb0);
            blockPalette[1] = R5G6B5.decode(rgb1);

            if(rgb0 <= rgb1) {
                int c2r = (blockPalette[0].getRed() + blockPalette[1].getRed()) / 2;
                int c2g = (blockPalette[0].getGreen() + blockPalette[1].getGreen()) / 2;
                int c2b = (blockPalette[0].getBlue() + blockPalette[1].getBlue()) / 2;

                 blockPalette[2] = new RGBA(c2r, c2g, c2b, 255);
                 blockPalette[3] = new RGBA(0, 0, 0, 0);

            } else {
                int c2r = (2 * blockPalette[0].getRed() + blockPalette[1].getRed()) / 3;
                int c2g = (2 * blockPalette[0].getGreen() + blockPalette[1].getGreen()) / 3;
                int c2b = (2 * blockPalette[0].getBlue() + blockPalette[1].getBlue()) / 3;

                int c3r = (blockPalette[0].getRed() + 2 * blockPalette[1].getRed()) / 3;
                int c3g = (blockPalette[0].getGreen() + 2 * blockPalette[1].getGreen()) / 3;
                int c3b = (blockPalette[0].getBlue() + 2 * blockPalette[1].getBlue()) / 3;


                blockPalette[2] = new RGBA(c2r, c2g, c2b, 255);
                blockPalette[3] = new RGBA(c3r, c3g, c3b, 255);

            }

            for (int i = 0; i < 16; i++, bitmap >>= 2) {
                int pi = (i / 4) * width + (col * 4 + i % 4);
                int index = bitmap & 3;
                scanline[pi] = A8R8G8B8.encode(blockPalette[index]);
           }
        }
        //copy scanline to buffered image
        result.setRGB(0, row * 4, width, 4, scanline, 0, width);
  }
  return result;

有谁知道问题出在哪里吗?我一直在执行与规范完全相同的步骤:Block Compression (Direct3D 10)

最佳答案

是吗blockPalette[2].set(c2r, c2g, c2b);应该是blockPalette[2].set(c2r, c2g, c2b, 255); ? (两个地点)

关于java - 试图解压缩 BC1 纹理压缩的扰乱 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59567528/

相关文章:

java - JBehave-Maven-Plugin,类路径中错误的 cdi-api 依赖项

java - 模拟 InboundJaxrsResponse

java - 如何通过 java 代码将 java HashMap 转换为不可变的 Scala 映射?

c# - .Net 6 System.IO.Compression 问题是否有任何解决方法。 DeflateStream.Read 方法在 .Net 6 中工作不正确,但在旧版本中工作正常

压缩 HTTP

java - 使用 mockito 对构造函数进行单元测试

algorithm - 压缩图表示?

testing - 游戏开发 : Automatic Testing of OpenGL and DirectX

c++ - 找不到用于 DirectX 编程的 d3dcompiler_43.dll

c# - DirectX 或 OpenGL