JOGL을 사용하여 openGL에 표시되는 비디오를 저장하고 싶습니다. 이렇게하려면 다음과 같이 프레임을 그림에 쓰고 일단 모든 프레임을 저장하면 ffmpeg를 사용합니다. 이것이 최선의 방법은 아니지만 tex2dimage 및 PBO를 사용하여 가속화하는 방법은 아직 명확하지 않습니다. 그 방향으로의 도움은 매우 유용 할 것입니다.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);
}
com.jogamp.opengl.util.GLReadBufferUtil을 com.jogamp.opengl.util.texture.TextureIO와 함께 사용하십시오. 올바르게 사용하면 모든 이미지에 대해 동일한 버퍼 (TextureData 객체 내부)를 계속 사용하고 AWT를 없애고 PNGJ에 기반한 JOGL PNG 인코더가 빠르며 메모리 풋 프린트가 AWT/동등한 스윙. – gouessej
그런데 FFMPEG와 LibAV는 이미 미디어 플레이어 내부의 JOGL에서 사용됩니다. 어쩌면 소스 코드를보고 필요한 작성 방법을 폭로하는 방법을 알면 수많은 PNG 파일을 사용하지 않아도됩니다. – gouessej