簡體   English   中英

glReadPixels返回的數據超出預期

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM