glReadPixels返回比预期更多的数据

我想使用JOGL保存我用openGL显示的视频。要做到这一点,我写我的帧到图片如下,然后,一旦我保存所有帧,我会使用ffmpeg。我知道这不是最好的方法,但我仍然没有太清楚如何加速tex2dimage和PBOs。在这方面的任何帮助将是非常有用的。glReadPixels返回比预期更多的数据

无论如何,我的问题是,如果我运行opengl类的作品,但如果我从另一个类调用这个类,然后我看到glReadPixels是trhowing我的错误。它总是返回更多的数据到缓冲区,比内存已分配给我的缓冲区“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',太糟糕了。

以上是 glReadPixels返回比预期更多的数据 的全部内容, 来源链接: utcz.com/qa/267288.html

回到顶部