无法从字节数组创建纹理 (JOGL)
Can't create texture from byte array (JOGL)
我正在尝试将 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;
好的,我已经通过取消索引所有内容并制作 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));
我正在尝试将 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;
好的,我已经通过取消索引所有内容并制作 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));