int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); QGuiApplication app(argc, argv); Q_UNUSED(app); QSurfaceFormat format; format.setMajorVersion(3); format.setMinorVersion(0); QOpenGLContext context; context.setFormat(format); context.create(); if (!context.isValid()) return 1; qDebug() << QString::fromLatin1("Context created."); QOffscreenSurface surface; surface.setFormat(format); surface.create(); if(!surface.isValid()) return 2; qDebug() << QString::fromLatin1("Surface created."); context.makeCurrent(&surface); return RUN_ALL_TESTS(); }
int getMaxTextureSize() { int maxSize = 0; // Create a temp context - required if this is called from another thread QOpenGLContext ctx; if ( !ctx.create() ) { // TODO handle the error qDebug() << "No OpenGL context could be created, this is clearly bad..."; exit(-1); } // rather than using a QWindow - which actually dosen't seem to work in this case either! QOffscreenSurface surface; surface.setFormat( ctx.format() ); surface.create(); ctx.makeCurrent(&surface); // Now the call works QOpenGLFunctions glFuncs(QOpenGLContext::currentContext()); glFuncs.glEnable(GL_TEXTURE_2D); glFuncs.glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); return maxSize; }
static QSurface *createSurface(int surfaceClass) { if (surfaceClass == int(QSurface::Window)) { QWindow *window = new QWindow; window->setSurfaceType(QWindow::OpenGLSurface); window->setGeometry(0, 0, 10, 10); window->create(); return window; } else if (surfaceClass == int(QSurface::Offscreen)) { // Create a window and get the format from that. For example, if an EGL // implementation provides 565 and 888 configs for PBUFFER_BIT but only // 888 for WINDOW_BIT, we may end up with a pbuffer surface that is // incompatible with the context since it could choose the 565 while the // window and the context uses a config with 888. static QSurfaceFormat format; if (format.redBufferSize() == -1) { QWindow *window = new QWindow; window->setSurfaceType(QWindow::OpenGLSurface); window->setGeometry(0, 0, 10, 10); window->create(); format = window->format(); delete window; } QOffscreenSurface *offscreenSurface = new QOffscreenSurface; offscreenSurface->setFormat(format); offscreenSurface->create(); return offscreenSurface; } return 0; }
void GLC_QuickView::sceneGraphInitializedDone() { disconnect(this, SIGNAL(sceneGraphInitialized()), this, SLOT(sceneGraphInitializedDone())); QOpenGLContext* pContext= openglContext(); Q_ASSERT(pContext); m_pQOpenGLContext= new QOpenGLContext(); m_pQOpenGLContext->setShareContext(pContext); m_pQOpenGLContext->setFormat(pContext->format()); m_pQOpenGLContext->create(); Q_ASSERT(m_pQOpenGLContext->isValid()); QOffscreenSurface* pFakeSurface = new QOffscreenSurface(); pFakeSurface->setFormat(pContext->format()); pFakeSurface->create(); m_pContext= GLC_ContextManager::instance()->createContext(m_pQOpenGLContext, pFakeSurface); m_pContext->makeCurrent(); qDebug() << m_pContext; initializeGL(); }
void ResultRecorder::startResults(const QString &id) { // sub process will get all this. // safer that way, as then we keep OpenGL (and QGuiApplication) out of the host if (!Options::instance.isSubProcess) return; m_results["id"] = id; QString prettyProductName = #if QT_VERSION >= 0x050400 QSysInfo::prettyProductName(); #else # if defined(Q_OS_IOS) QStringLiteral("iOS"); # elif defined(Q_OS_OSX) QString::fromLatin1("OSX %d").arg(QSysInfo::macVersion()); # elif defined(Q_OS_WIN) QString::fromLatin1("Windows %d").arg(QSysInfo::windowsVersion()); # elif defined(Q_OS_LINUX) QStringLiteral("Linux"); # elif defined(Q_OS_ANDROID) QStringLiteral("Android"); # else QStringLiteral("unknown"); # endif #endif QVariantMap osMap; osMap["prettyProductName"] = prettyProductName; osMap["platformPlugin"] = QGuiApplication::platformName(); m_results["os"] = osMap; m_results["qt"] = QT_VERSION_STR; m_results["command-line"] = qApp->arguments().join(' '); // The following code makes the assumption that an OpenGL context the GUI // thread will get the same capabilities as the render thread's OpenGL // context. Not 100% accurate, but it works... QOpenGLContext context; context.create(); QOffscreenSurface surface; // In very odd cases, we can get incompatible configs here unless we pass the // GL context's format on to the offscreen format. surface.setFormat(context.format()); surface.create(); if (!context.makeCurrent(&surface)) { qWarning() << "failed to acquire GL context to get version info."; return; } QOpenGLFunctions *func = context.functions(); #if QT_VERSION >= 0x050300 const char *vendor = (const char *) func->glGetString(GL_VENDOR); const char *renderer = (const char *) func->glGetString(GL_RENDERER); const char *version = (const char *) func->glGetString(GL_VERSION); #else Q_UNUSED(func); const char *vendor = (const char *) glGetString(GL_VENDOR); const char *renderer = (const char *) glGetString(GL_RENDERER); const char *version = (const char *) glGetString(GL_VERSION); #endif if (!Options::instance.printJsonToStdout) { std::cout << "ID: " << id.toStdString() << std::endl; std::cout << "OS: " << prettyProductName.toStdString() << std::endl; std::cout << "QPA: " << QGuiApplication::platformName().toStdString() << std::endl; std::cout << "GL_VENDOR: " << vendor << std::endl; std::cout << "GL_RENDERER: " << renderer << std::endl; std::cout << "GL_VERSION: " << version << std::endl; } QVariantMap glInfo; glInfo["vendor"] = vendor; glInfo["renderer"] = renderer; glInfo["version"] = version; m_results["opengl"] = glInfo; context.doneCurrent(); }
int main(int argc, char* argv[]) { // Parse command line arguments std::vector<string> input_paths, seg_paths; string output_path, landmarks_path; string model_3dmm_h5_path, model_3dmm_dat_path; string reg_model_path, reg_deploy_path, reg_mean_path; string seg_model_path, seg_deploy_path; string cfg_path; bool generic, with_expr, with_gpu; unsigned int gpu_device_id, verbose; try { options_description desc("Allowed options"); desc.add_options() ("help,h", "display the help message") ("verbose,v", value<unsigned int>(&verbose)->default_value(0), "output debug information [0, 4]") ("input,i", value<std::vector<string>>(&input_paths)->required(), "image paths [source target]") ("output,o", value<string>(&output_path)->required(), "output path") ("segmentations,s", value<std::vector<string>>(&seg_paths), "segmentation paths [source target]") ("landmarks,l", value<string>(&landmarks_path)->required(), "path to landmarks model file") ("model_3dmm_h5", value<string>(&model_3dmm_h5_path)->required(), "path to 3DMM file (.h5)") ("model_3dmm_dat", value<string>(&model_3dmm_dat_path)->required(), "path to 3DMM file (.dat)") ("reg_model,r", value<string>(®_model_path)->required(), "path to 3DMM regression CNN model file (.caffemodel)") ("reg_deploy,d", value<string>(®_deploy_path)->required(), "path to 3DMM regression CNN deploy file (.prototxt)") ("reg_mean,m", value<string>(®_mean_path)->required(), "path to 3DMM regression CNN mean file (.binaryproto)") ("seg_model", value<string>(&seg_model_path), "path to face segmentation CNN model file (.caffemodel)") ("seg_deploy", value<string>(&seg_deploy_path), "path to face segmentation CNN deploy file (.prototxt)") ("generic,g", value<bool>(&generic)->default_value(false), "use generic model without shape regression") ("expressions,e", value<bool>(&with_expr)->default_value(true), "with expressions") ("gpu", value<bool>(&with_gpu)->default_value(true), "toggle GPU / CPU") ("gpu_id", value<unsigned int>(&gpu_device_id)->default_value(0), "GPU's device id") ("cfg", value<string>(&cfg_path)->default_value("face_swap_image.cfg"), "configuration file (.cfg)") ; variables_map vm; store(command_line_parser(argc, argv).options(desc). positional(positional_options_description().add("input", -1)).run(), vm); if (vm.count("help")) { cout << "Usage: face_swap_image [options]" << endl; cout << desc << endl; exit(0); } // Read config file std::ifstream ifs(vm["cfg"].as<string>()); store(parse_config_file(ifs, desc), vm); notify(vm); if(input_paths.size() != 2) throw error("Both source and target must be specified in input!"); if (!is_regular_file(input_paths[0])) throw error("source input must be a path to an image!"); if (!is_regular_file(input_paths[1])) throw error("target input target must be a path to an image!"); if (seg_paths.size() > 0 && !is_regular_file(seg_paths[0])) throw error("source segmentation must be a path to an image!"); if (seg_paths.size() > 1 && !is_regular_file(seg_paths[1])) throw error("target segmentation must be a path to an image!"); if (!is_regular_file(landmarks_path)) throw error("landmarks must be a path to a file!"); if (!is_regular_file(model_3dmm_h5_path)) throw error("model_3dmm_h5 must be a path to a file!"); if (!is_regular_file(model_3dmm_dat_path)) throw error("model_3dmm_dat must be a path to a file!"); if (!is_regular_file(reg_model_path)) throw error("reg_model must be a path to a file!"); if (!is_regular_file(reg_deploy_path)) throw error("reg_deploy must be a path to a file!"); if (!is_regular_file(reg_mean_path)) throw error("reg_mean must be a path to a file!"); if (!seg_model_path.empty() && !is_regular_file(seg_model_path)) throw error("seg_model must be a path to a file!"); if (!seg_deploy_path.empty() && !is_regular_file(seg_deploy_path)) throw error("seg_deploy must be a path to a file!"); } catch (const error& e) { cerr << "Error while parsing command-line arguments: " << e.what() << endl; cerr << "Use --help to display a list of options." << endl; exit(1); } try { // Intialize OpenGL context QApplication a(argc, argv); QSurfaceFormat surfaceFormat; surfaceFormat.setMajorVersion(1); surfaceFormat.setMinorVersion(5); QOpenGLContext openGLContext; openGLContext.setFormat(surfaceFormat); openGLContext.create(); if (!openGLContext.isValid()) return -1; QOffscreenSurface surface; surface.setFormat(surfaceFormat); surface.create(); if (!surface.isValid()) return -2; openGLContext.makeCurrent(&surface); // Initialize GLEW GLenum err = glewInit(); if (GLEW_OK != err) { // Problem: glewInit failed, something is seriously wrong fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); throw std::runtime_error("Failed to initialize GLEW!"); } // Initialize face swap face_swap::FaceSwap fs(landmarks_path, model_3dmm_h5_path, model_3dmm_dat_path, reg_model_path, reg_deploy_path, reg_mean_path, generic, with_expr, with_gpu, (int)gpu_device_id); // Read source and target images cv::Mat source_img = cv::imread(input_paths[0]); cv::Mat target_img = cv::imread(input_paths[1]); // Read source and target segmentations or initialize segmentation model cv::Mat source_seg, target_seg; if (seg_model_path.empty() || seg_deploy_path.empty()) { if (seg_paths.size() > 0) source_seg = cv::imread(seg_paths[0], cv::IMREAD_GRAYSCALE); if (seg_paths.size() > 1) target_seg = cv::imread(seg_paths[1], cv::IMREAD_GRAYSCALE); } else fs.setSegmentationModel(seg_model_path, seg_deploy_path); // Set source and target if (!fs.setSource(source_img, source_seg)) throw std::runtime_error("Failed to find faces in source image!"); if (!fs.setTarget(target_img, target_seg)) throw std::runtime_error("Failed to find faces in target image!"); // Do face swap cv::Mat rendered_img = fs.swap(); if (rendered_img.empty()) throw std::runtime_error("Face swap failed!"); // Write output to file path out_file_path = output_path; path out_dir_path = output_path; if (is_directory(output_path)) { path outputName = (path(input_paths[0]).stem() += "_") += (path(input_paths[1]).stem() += ".jpg"); out_file_path = path(output_path) /= outputName; } else out_dir_path = path(output_path).parent_path(); cv::imwrite(out_file_path.string(), rendered_img); // Debug if (verbose > 0) { // Write rendered image path debug_render_path = out_dir_path / (out_file_path.stem() += "_render.jpg"); cv::Mat debug_render_img = fs.debugRender(); cv::imwrite(debug_render_path.string(), debug_render_img); } if (verbose > 1) { // Write projected meshes path debug_src_mesh_path = out_dir_path / (out_file_path.stem() += "_src_mesh.jpg"); cv::Mat debug_src_mesh_img = fs.debugSourceMesh(); cv::imwrite(debug_src_mesh_path.string(), debug_src_mesh_img); path debug_tgt_mesh_path = out_dir_path / (out_file_path.stem() += "_tgt_mesh.jpg"); cv::Mat debug_tgt_mesh_img = fs.debugTargetMesh(); cv::imwrite(debug_tgt_mesh_path.string(), debug_tgt_mesh_img); } if (verbose > 2) { // Write landmarks render path debug_src_lms_path = out_dir_path / (out_file_path.stem() += "_src_landmarks.jpg"); cv::Mat debug_src_lms_img = fs.debugSourceLandmarks(); cv::imwrite(debug_src_lms_path.string(), debug_src_lms_img); path debug_tgt_lms_path = out_dir_path / (out_file_path.stem() += "_tgt_landmarks.jpg"); cv::Mat debug_tgt_lms_img = fs.debugTargetLandmarks(); cv::imwrite(debug_tgt_lms_path.string(), debug_tgt_lms_img); } if (verbose > 3) { // Write meshes path debug_src_ply_path = out_dir_path / (out_file_path.stem() += "_src_mesh.ply"); path debug_tgt_ply_path = out_dir_path / (out_file_path.stem() += "_tgt_mesh.ply"); face_swap::Mesh::save_ply(fs.getSourceMesh(), debug_src_ply_path.string()); face_swap::Mesh::save_ply(fs.getTargetMesh(), debug_tgt_ply_path.string()); } } catch (std::exception& e) { cerr << e.what() << endl; return 1; } return 0; }