gpt4 book ai didi

java - glReadPixels 返回比预期更多的数据

转载 作者:行者123 更新时间:2023-11-30 07:57:24 27 4
gpt4 key购买 nike

我想使用 JOGL 保存我正在用 openGL 显示的视频。为此,我按如下方式将我的帧写入图片,然后,一旦我保存了所有帧,我将使用 ffmpeg。我知道这不是最好的方法,但我仍然不太清楚如何使用 tex2dimage 和 PBO 进行加速。这方面的任何帮助都会非常有用。

无论如何,我的问题是,如果我运行 opengl 类,它会工作,但是,如果我从另一个类调用这个类,那么我会看到 glReadPixels 向我发送错误消息。它总是向缓冲区返回比分配给我的缓冲区“pixelsRGB”的内存更多的数据。有谁知道为什么吗?

举个例子:width = 1042;高度=998。分配=3.119.748 glPixels 返回=3.121.742

public void display(GLAutoDrawable drawable) {
//Draw things.....

//bla bla bla
t++; //This is a time variable for the animation (it says to me the frame).

//Save frame
int width = drawable.getSurfaceWidth();
int height = drawable.getSurfaceHeight();
ByteBuffer pixelsRGB = Buffers.newDirectByteBuffer(width * height * 3);
gl.glReadPixels(0, 0, width,height, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, pixelsRGB);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

int[] pixels = new int[width * height];

int firstByte = width * height * 3;
int sourceIndex;
int targetIndex = 0;
int rowBytesNumber = width * 3;

for (int row = 0; row < height; row++) {
firstByte -= rowBytesNumber;
sourceIndex = firstByte;
for (int col = 0; col < width; col++) {
int iR = pixelsRGB.get(sourceIndex++);
int iG = pixelsRGB.get(sourceIndex++);
int iB = pixelsRGB.get(sourceIndex++);

pixels[targetIndex++] = 0xFF000000
| ((iR & 0x000000FF) << 16)
| ((iG & 0x000000FF) << 8)
| (iB & 0x000000FF);
}

}

bufferedImage.setRGB(0, 0, width, height, pixels, 0, width);


File a = new File(t+".png");
ImageIO.write(bufferedImage, "PNG", a);
}

注意:有了 pleluron 的回答,现在它可以工作了。好的代码是:

public void display(GLAutoDrawable drawable) {
//Draw things.....

//bla bla bla
t++; //This is a time variable for the animation (it says to me the frame).

//Save frame
int width = drawable.getSurfaceWidth();
int height = drawable.getSurfaceHeight();
ByteBuffer pixelsRGB = Buffers.newDirectByteBuffer(width * height * 4);
gl.glReadPixels(0, 0, width,height, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, pixelsRGB);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

int[] pixels = new int[width * height];

int firstByte = width * height * 4;
int sourceIndex;
int targetIndex = 0;
int rowBytesNumber = width * 4;

for (int row = 0; row < height; row++) {
firstByte -= rowBytesNumber;
sourceIndex = firstByte;
for (int col = 0; col < width; col++) {
int iR = pixelsRGB.get(sourceIndex++);
int iG = pixelsRGB.get(sourceIndex++);
int iB = pixelsRGB.get(sourceIndex++);

sourceIndex++;

pixels[targetIndex++] = 0xFF000000
| ((iR & 0x000000FF) << 16)
| ((iG & 0x000000FF) << 8)
| (iB & 0x000000FF);
}

}

bufferedImage.setRGB(0, 0, width, height, pixels, 0, width);


File a = new File(t+".png");
ImageIO.write(bufferedImage, "PNG", a);
}

最佳答案

glPixelStore设置的GL_PACK_ALIGNMENT的默认值为4。这意味着pixelsRGB的每一行应该从一个地址开始4 的倍数,并且缓冲区的宽度 (1042) 乘以像素中的字节数 (3) 不是 4 的倍数。添加一点填充,以便下一行从 4 的倍数开始将使总数缓冲区的字节大小比您预期的要大。

要修复它,请将 GL_PACK_ALIGNMENT 设置为 1。您还可以使用 GL_RGBA 读取像素并使用更大的缓冲区,因为数据最有可能存储在在 GPU 和 BufferedImage 中的方式。

编辑:BufferedImage 没有方便的“setRGBA”,太糟糕了。

关于java - glReadPixels 返回比预期更多的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41404432/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com