JOGLを使用してOpenGLで表示しているもののビデオを保存します。これを行うには、次のようにフレームを写真に書き込んでから、すべてのフレームを保存したらffmpegを使用します。私はこれが最善の方法ではないことを知っていますが、tex2dimageとPBOでどのように加速するかについてはまだあまり明確ではありません。その方向への助けはとても役に立ちます。glReadPixelsが予想よりも多くのデータを返します
とにかく私の問題は、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);
}
com.jogamp.opengl.util.GLReadBufferUtilをcom.jogamp.opengl.util.texture.TextureIOで使用してください。正しく使用すると、すべての画像に対して同じバッファ(TextureDataオブジェクト内)を使用し続けることができ、AWTを取り除き、JNGL PNGエンコーダ(PNGJに基づいています)が高速で、AWT /スウィング相当物。 – gouessej
ところで、FFMPEGとLibAVはすでにJOGLのフードの中でメディアプレーヤーの中で使われています。たぶん、ソースコードを見て、書き込むために必要なメソッドを公開する方法を知ることができます。多数のPNGファイルを使用する必要はありません。 – gouessej