我正在尝试使用OpenGL中的动画创建视频文件。 我一直在阅读如何做到这一点,据我所知,有两种选择:
glReadPixels()
获取帧数据,并将其写入视频文件第二种方法是我认为最适合我的方法,但是,我找不到有关如何实现第二部分的信息(写入视频文件)。
有人能指出我在某些网站上学习如何做到这一点吗?我可以使用哪种库来编码(?)来自我在OpenGL中渲染的帧的视频?
修改
在搜索了一下这个之后,我相信ffmpeg是可行的方法。我发现this blog的代码显然适用于Windows。
我已从网站下载了ffmpeg,以便我可以像在示例中一样执行命令。不幸的是,我的应用程序崩溃,没有创建视频。我检查文件指针是否有效,但事实并非如此,所以我认为错误来自函数popen
的执行。
我传递与命令完全相同的参数,但仍然没有有效的文件指针,对可能发生的事情有任何想法?
问题是,我不想花太多时间编写视频编码,因为我还有其他项目需要处理。
答案 0 :(得分:1)
由于我无法直接从我的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");
}
这将在您的工作目录中留下一堆图像,您可以使用控制台中的以下命令在视频中对其进行编码
ffmpeg -framerate 30 -start_number 0 -i Frame%d.png -vcodec mpeg4 -vf vflip test.avi
我仍然需要检查为什么颜色被反转但是现在这很好用,因为动画是重要的而不是颜色。
答案 1 :(得分:0)
安装libpng后你可以这样做: uint8_t pixels = new uint8_t [w h * 3]; glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE,(GLvoid *)像素);
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); 如果(!png) 返回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;