从OpenGL渲染帧创建视频
我想从OpenGL中的动画创建视频文件。 我一直在阅读关于如何做到这一点,我的理解有两种选择:从OpenGL渲染帧创建视频
- 保存每一个在OpenGL渲染帧图像文件,然后创建从这些
- 视频文件获取的帧数据使用
glReadPixels()
和动态写那些为视频文件
第二种方法是什么,我相信会的工作最适合我,但是,我无法找到如何实现第二部分信息(写入到视频文件)。
任何人都可以指出我对一些网站,我学习如何做到这一点?我可以使用什么类型的库来编码(?)我在OpenGL中渲染的帧中的视频?
编辑
搜索更加一下这个之后,我相信ffmpeg的是要走的路。我发现this blog有一个显然可以在Windows上工作的代码。
我已经从网站上下载了ffmpeg,这样我就可以执行命令,就像在这个例子中一样。不幸的是,我的应用程序崩溃,没有视频正在创建。我检查了文件指针是否有效,但不是,所以我认为错误来自函数popen
的执行。
我传递了与命令完全相同的参数,但仍然没有有效的文件指针,关于可能发生什么的任何想法?
事情是,我不想花很多时间编码视频编码,因为我有其他项目可以工作。
由于我无法直接从我的C++代码使用ffmpeg
,所以可能的解决方案如下。在Qt5中,您可以使用功能paintGL
更新要渲染的帧。这之后,得到的像素与glReadPixels
,然后只用QImage
void OpenGLViewer::paintGL()
{
// Clear screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Update array attached to OpenGL
glDrawArrays(GL_POINTS, 0, _points);
update();
glReadPixels(0, 0, this->width(), this->height(), GL_RGBA, GL_UNSIGNED_BYTE, _buffer);
std::stringstream name;
name << "Frame" << _frame++ << ".png";
QString filename(name.str().c_str());
QImage imagen(_buffer, this->width(), this->height(), QImage::Format_ARGB32);
imagen.save(filename, "PNG");
}
的图像保存为PNG图像这将使用从下面的命令留在你的工作目录中的一些图片,你可以在视频编码控制台
ffmpeg -framerate 30 -start_number 0 -i Frame%d.png -vcodec mpeg4 -vf vflip test.avi
我还是要查,为什么颜色反转,但现在由于动画是最重要的事情,而不是颜色能正常工作。
您可以在安装libpng后以这种方式完成: uint8_t pixels = new uint8_t [w h * 3]; glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE,(GLvoid *)pixels);
for (int j = 0; j * 2 < h; ++j) {
int x = j * w * 3;
int y = (h - 1 - j) * w * 3;
for (int i = w * 3; i > 0; --i) {
uint8_t tmp = pixels[x];
pixels[x] = pixels[y];
pixels[y] = tmp;
++x;
++y;
}
}
png_structp PNG = png_create_write_struct(PNG_LIBPNG_VER_STRING,nullptr,nullptr,nullptr); if(!png) return false;
png_infop info = png_create_info_struct(png);
if (!info) {
png_destroy_write_struct(&png, &info);
return false;
}
std::string s = "IMAGE/"+string(filename);
FILE *fp = fopen(s.c_str(), "wb");
if (!fp) {
png_destroy_write_struct(&png, &info);
return false;
}
png_init_io(png, fp);
png_set_IHDR(png, info, w, h, 8 , PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_colorp palette = (png_colorp)png_malloc(png, PNG_MAX_PALETTE_LENGTH * sizeof(png_color));
if (!palette) {
fclose(fp);
png_destroy_write_struct(&png, &info);
return false;
}
png_set_PLTE(png, info, palette, PNG_MAX_PALETTE_LENGTH);
png_write_info(png, info);
png_set_packing(png);
png_bytepp rows = (png_bytepp)png_malloc(png, h * sizeof(png_bytep));
for (int i = 0; i < h; ++i)
rows[i] = (png_bytep)(pixels + (h - i - 1) * w * 3);
png_write_image(png, rows);
png_write_end(png, info);
png_free(png, palette);
png_destroy_write_struct(&png, &info);
fclose(fp);
delete[] rows;
ffmpeg -framerate 30 -start_number 0 -i Frame%d.png -vcodec mpeg4 -vf vflip test.avi – user3059007 2015-04-23 00:50:04
我在编码/解码视频文件方面并不是很有经验,但我认为你最好的选择是寻找一个能为你做到这一点的图书馆,而且你只需将数据传递给它。如果它的任何部分与我想象的音频(哪个)相同,它不会变得微不足道。不幸的是,我不知道任何图书馆。 – Daniel 2014-09-27 17:22:51
问题是,你并没有要求特定的帮助。有很多库能够将一系列RGB图像编码成视频流(ffmpeg,gstreamer,我非常确定OSX有本地的东西)。除非您要求提供有关这些库的具体内容,否则此问题无意义。 – peppe 2014-09-28 20:18:07