[英]glReadPixels returns more data than expected
我想使用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);
}
的默認值GL_PACK_ALIGNMENT
設置glPixelStore
是4。這意味着,每行pixelsRGB
應是4的倍數,並且您的緩沖區的寬度的地址(1042)開始的時間在像素的字節數(3)不是4的倍數。添加一點填充,以便下一行以4的倍數開始,將使緩沖區的總字節大小大於預期的大小。
要修復此問題,請將GL_PACK_ALIGNMENT
設置為1。您還可以使用GL_RGBA
讀取像素並使用更大的緩沖區,因為數據很可能以這種方式存儲在GPU和BufferedImage
。
編輯: BufferedImage
沒有方便的' setRGBA
',太糟糕了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.