如何将 bufferedImage 加载为 opengl 纹理?
How can I load bufferedImage as opengl texture?
我正在尝试从加载的缓冲图像创建纹理,如下所示:
public static long loadTexture(String img) throws IOException{
File imgPath = new File(img);
BufferedImage bufferedImage = ImageIO.read(imgPath);
byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
int id = glGenTextures();
glBindTexture(GL_TEXTURE_2D, id);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferedImage.getWidth(), bufferedImage.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, ByteBuffer.wrap(pixels));
glGenerateMipmap(GL_TEXTURE_2D);
return id;
}
但是这段代码给我一个 java sigsegv 错误。我正在使用 Java.nio.Bytebuffer,因为 java 11 不支持 sun。
那我做错了什么?图片加载正确,4bpp:
//last 2 digits are lenght
FF-AD-6F-CB-FF-FF-FF-00-FF-FF-FF-00-FF-FF-FF-00-FF-FF-FF-00-FF-00-00-FF-FF-00-00-FF-FF-FF-FF-00-FF-FF-FF-00-FF-00-00-FF-FF-00-00-FF-FF-FF-FF-00-FF-FF-FF-00-FF-FF-FF-00-FF-FF-FF-00-FF-FF-FF-00-64
图片如下:
它当然很小,但数据是正确的。
那么为什么我会收到 sigsegv?日志很无用而且很长所以我不能 post 它。
以及如何从 4bpp 字节数组创建 opengl 纹理?
按照 Java Code Examples for org.lwjgl.opengl.GL11.glTexImage2D()
(示例 5)中的建议,您必须在循环中将数据复制到 ByteBuffer
:
public static long loadTexture(String img) throws IOException{
File imgPath = new File(img);
BufferedImage image = ImageIO.read(imgPath);
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = ByteBuffer.allocateDirect(image.getWidth() * image.getHeight() * 4);
for(int h = 0; h < image.getHeight(); h++) {
for(int w = 0; w < image.getWidth(); w++) {
int pixel = pixels[h * image.getWidth() + w];
buffer.put((byte) ((pixel >> 16) & 0xFF));
buffer.put((byte) ((pixel >> 8) & 0xFF));
buffer.put((byte) (pixel & 0xFF));
buffer.put((byte) ((pixel >> 24) & 0xFF));
}
}
buffer.flip();
int id = glGenTextures();
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(),
0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glGenerateMipmap(GL_TEXTURE_2D);
return id;
}
注意,glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
在这种情况下是不必要的,因为RGBA像素的大小是4个字节,所以每行对齐到4个字节,GL_UNPACK_ALIGNMENT
默认为4。
此外,如果你想使用Mipmaps (glGenerateMipmap
), then the minifying function (GL_TEXTURE_MIN_FILTER
) has to be GL_NEAREST_MIPMAP_NEAREST
, GL_LINEAR_MIPMAP_NEAREST
, GL_NEAREST_MIPMAP_LINEAR
or GL_LINEAR_MIPMAP_LINEAR
. (See glTexParameter
)
我正在尝试从加载的缓冲图像创建纹理,如下所示:
public static long loadTexture(String img) throws IOException{
File imgPath = new File(img);
BufferedImage bufferedImage = ImageIO.read(imgPath);
byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
int id = glGenTextures();
glBindTexture(GL_TEXTURE_2D, id);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferedImage.getWidth(), bufferedImage.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, ByteBuffer.wrap(pixels));
glGenerateMipmap(GL_TEXTURE_2D);
return id;
}
但是这段代码给我一个 java sigsegv 错误。我正在使用 Java.nio.Bytebuffer,因为 java 11 不支持 sun。 那我做错了什么?图片加载正确,4bpp:
//last 2 digits are lenght
FF-AD-6F-CB-FF-FF-FF-00-FF-FF-FF-00-FF-FF-FF-00-FF-FF-FF-00-FF-00-00-FF-FF-00-00-FF-FF-FF-FF-00-FF-FF-FF-00-FF-00-00-FF-FF-00-00-FF-FF-FF-FF-00-FF-FF-FF-00-FF-FF-FF-00-FF-FF-FF-00-FF-FF-FF-00-64
图片如下:
那么为什么我会收到 sigsegv?日志很无用而且很长所以我不能 post 它。
以及如何从 4bpp 字节数组创建 opengl 纹理?
按照 Java Code Examples for org.lwjgl.opengl.GL11.glTexImage2D()
(示例 5)中的建议,您必须在循环中将数据复制到 ByteBuffer
:
public static long loadTexture(String img) throws IOException{
File imgPath = new File(img);
BufferedImage image = ImageIO.read(imgPath);
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = ByteBuffer.allocateDirect(image.getWidth() * image.getHeight() * 4);
for(int h = 0; h < image.getHeight(); h++) {
for(int w = 0; w < image.getWidth(); w++) {
int pixel = pixels[h * image.getWidth() + w];
buffer.put((byte) ((pixel >> 16) & 0xFF));
buffer.put((byte) ((pixel >> 8) & 0xFF));
buffer.put((byte) (pixel & 0xFF));
buffer.put((byte) ((pixel >> 24) & 0xFF));
}
}
buffer.flip();
int id = glGenTextures();
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(),
0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glGenerateMipmap(GL_TEXTURE_2D);
return id;
}
注意,glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
在这种情况下是不必要的,因为RGBA像素的大小是4个字节,所以每行对齐到4个字节,GL_UNPACK_ALIGNMENT
默认为4。
此外,如果你想使用Mipmaps (glGenerateMipmap
), then the minifying function (GL_TEXTURE_MIN_FILTER
) has to be GL_NEAREST_MIPMAP_NEAREST
, GL_LINEAR_MIPMAP_NEAREST
, GL_NEAREST_MIPMAP_LINEAR
or GL_LINEAR_MIPMAP_LINEAR
. (See glTexParameter
)