【问题标题】:Can't create texture from byte array (JOGL)无法从字节数组创建纹理 (JOGL)
【发布时间】:2015-08-29 14:52:03
【问题描述】:

我正在尝试将 C# 应用程序移植到 Java,并且目前正在翻译 OpenGL 代码。在 C# 应用程序中使用 OpenTK,在 Java 应用程序中我选择了 JOGL。当我尝试创建纹理时,程序会引发异常。这是导致麻烦的代码:

            BMD0.Model.ModelData.Material.MatDef mat = (BMD0.Model.ModelData.Material.MatDef) model.model.mdlData[0].material.material[i];
            ImageData tmp_tex = Nsbtx.getTexture(tex, mat.texID, mat.palID).getImageData();
            gl.glBindTexture(GL2.GL_TEXTURE_2D, texturesID.get(i));
            ByteBuffer tmp_tex_data = ByteBuffer.allocate(tmp_tex.data.length);
            tmp_tex_data.put(tmp_tex.data);
            tmp_tex_data.flip();
            gl.glTexImage2D(texturesID.get(i), 0, GL2.GL_RGB, tmp_tex.width, tmp_tex.height, 0, GL2.GL_RGB, GL2.GL_UNSIGNED_BYTE, tmp_tex_data);
            texturesGL.put(i, texturesID.get(i));

例外是这样的:

java.lang.IndexOutOfBoundsException: Required 192 remaining bytes in buffer, only had 32

我正在使用 SWT 的 ImageData 加载我在 RAM 中的图像(它不是外部文件),它只有 32 字节长!为什么 JOGL 需要这么多字节?!

这是我第一个使用 OpenGL 的程序之一,所以我不是专家...

编辑:这是相应的 C# 代码:

        int id = GL.GenTexture();
        GL.BindTexture(TextureTarget.Texture2D, id);

        Bitmap bmp = BTX0.GetTexture(pluginHost, tex, num_tex, num_pal);
        System.Drawing.Imaging.BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);

        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0,
            OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0);

        bmp.UnlockBits(bmp_data);

        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Nearest);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Nearest);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.Repeat);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.Repeat);
        return id;

【问题讨论】:

  • tex_widthtex_height 是什么?对于图像来说,32 字节的数据量并不多……对于像 2x4 像素这样的东西就足够了。
  • 它们分别是纹理宽度和纹理高度。是的,图像应该是 4x4 像素
  • 2x4 像素在这里无法正常工作,行宽为 2 会导致 8 位 RGB 图像数据出现对齐问题。 2 像素 * 3 字节每个意味着第二、第三和第四行将从 3 字节边界开始,而不是 4 字节。第 2 行和第 4 行将错位。 也就是说,每个 3 字节的 4x4 像素是 48 字节而不是 32。
  • 8*8*3 = 192,这就解释了为什么缓冲区的长度应该是 192 字节。您将不得不取消该图像的托盘化,因为glTexImage2D (...) 不能以这种方式工作,它需要 RGB 三元组(每个组件 1 个字节,3 个组件)。对于您正在讨论的工作,您似乎有 4 位调色板条目。所以某种 16 色图像。
  • Andon 非常接近解释,这样的测试是由 JOGL 在将数据传递给 OpenGL 之前在内部完成的,这比崩溃要好。顺便说一句,宁可使用 Buffers.newDirectByteBuffer() 而不是将间接 NIO 缓冲区传递给 JOGL。

标签: java opengl textures jogl


【解决方案1】:

好的,我已经通过取消索引所有内容并制作 RGBA(还有 alpha 值)值来解决。

            BMD0.Model.ModelData.Material.MatDef mat = (BMD0.Model.ModelData.Material.MatDef) model.model.mdlData[0].material.material[i];
            ImageData tmp_tex = Nsbtx.getTexture(tex, mat.texID, mat.palID).getImageData();
            gl.glBindTexture(GL2.GL_TEXTURE_2D, texturesID.get(i));
            ByteBuffer tmp_tex_data = ByteBuffer.allocate(tmp_tex.height * tmp_tex.width * 4);
            PaletteData pal = tmp_tex.palette;
            for (int h = 0; h < tmp_tex.height; h++) {
                for (int w = 0; w < tmp_tex.width; w++) {
                    tmp_tex_data.put((byte) pal.getRGB(tmp_tex.getPixel(w, h)).red);
                    tmp_tex_data.put((byte) pal.getRGB(tmp_tex.getPixel(w, h)).green);
                    tmp_tex_data.put((byte) pal.getRGB(tmp_tex.getPixel(w, h)).blue);
                    tmp_tex_data.put((byte) tmp_tex.getAlpha(w, h));
                }
            }
            tmp_tex_data.flip();
            gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGBA, tmp_tex.width, tmp_tex.height, 0, GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE, tmp_tex_data);
            texturesGL.put(i, texturesID.get(i));

【讨论】:

  • 无论如何,你应该按照 gouessej 的建议使用 GLBuffers
  • 好的,我试试看;)
  • 当您准备好并有信心时,您还可以“升级”到采样器,如果您需要有关如何操作的帮助,请访问 jogl 论坛/irc ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
相关资源
最近更新 更多