CustomWindow::CustomWindow( QWindow *parent ) : QQuickWindow( parent ) { connect( this, &CustomWindow::vsyncChanged, this, &CustomWindow::vsyncChangedHandler ); // Reinitalize the scene graph when the OpenGL context gets destroyed // Needed because only when the context gets recreated is the format read setPersistentOpenGLContext( false ); setPersistentSceneGraph( false ); // Grab window surface format as the OpenGL context will not be created yet QSurfaceFormat fmt = format(); #if defined( Q_OS_WIN ) // Set buffering mode // Testing shows that on Windows, vsync stays on (swapBuffers() blocks) while single buffered // even when the swap interval is 0 and even while fullscreen! So, we have to turn on double buffering if we // want vsync to actually be off, but turn on single buffering while vsynced to avoid unnecessary additional latency fmt.setSwapBehavior( vsync ? QSurfaceFormat::SingleBuffer : QSurfaceFormat::DoubleBuffer ); emit doubleBufferedChanged( fmt.swapBehavior() == QSurfaceFormat::DoubleBuffer ); #elif defined( Q_OS_MACX ) fmt.setSwapBehavior( QSurfaceFormat::SingleBuffer ); emit doubleBufferedChanged( fmt.swapBehavior() == QSurfaceFormat::DoubleBuffer ); // For proper OS X fullscreen setFlags( flags() | Qt::WindowFullscreenButtonHint ); #endif // Enforce the default value for vsync fmt.setSwapInterval( vsync ? 1 : 0 ); setFormat( fmt ); }
void KisOpenGL::initialize() { #ifdef HAVE_OPENGL dbgUI << "OpenGL: initializing"; KisConfig cfg; QSurfaceFormat format; format.setProfile(QSurfaceFormat::CompatibilityProfile); format.setOptions(QSurfaceFormat::DeprecatedFunctions); format.setDepthBufferSize(24); format.setStencilBufferSize(8); format.setVersion(3, 2); // if (cfg.disableDoubleBuffering()) { if (false) { format.setSwapBehavior(QSurfaceFormat::SingleBuffer); } else { format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); } format.setSwapInterval(0); // Disable vertical refresh syncing QSurfaceFormat::setDefaultFormat(format); #endif }
void ccApplication::init() { //See http://doc.qt.io/qt-5/qopenglwidget.html#opengl-function-calls-headers-and-qopenglfunctions /** Calling QSurfaceFormat::setDefaultFormat() before constructing the QApplication instance is mandatory on some platforms (for example, OS X) when an OpenGL core profile context is requested. This is to ensure that resource sharing between contexts stays functional as all internal contexts are created using the correct version and profile. **/ { QSurfaceFormat format = QSurfaceFormat::defaultFormat(); format.setSwapBehavior( QSurfaceFormat::DoubleBuffer ); format.setStencilBufferSize( 0 ); #ifdef CC_GL_WINDOW_USE_QWINDOW format.setStereo( true ); #endif #ifdef Q_OS_MAC format.setVersion( 2, 1 ); // must be 2.1 - see ccGLWindow::functions() format.setProfile( QSurfaceFormat::CoreProfile ); #endif #ifdef QT_DEBUG format.setOption( QSurfaceFormat::DebugContext, true ); #endif QSurfaceFormat::setDefaultFormat( format ); } // The 'AA_ShareOpenGLContexts' attribute must be defined BEFORE the creation of the Q(Gui)Application // DGM: this is mandatory to enable exclusive full screen for ccGLWidget (at least on Windows) QCoreApplication::setAttribute( Qt::AA_ShareOpenGLContexts ); }
OpenGLWidget::OpenGLWidget(MainWindow* mainWindow) : QOpenGLWidget{mainWindow} , m_axisLegendScene{mainWindow->app()} , m_width{0} , m_height{0} , m_currentLocation{} , m_previousLocation{} { this->setFocusPolicy(Qt::StrongFocus); m_contextMenu = new QMenu(this); QMenu* createMenu = m_contextMenu->addMenu("Create"); createMenu->addAction(tr("Box"), this, SLOT(createBox())); createMenu->addAction(tr("Cylinder"), this, SLOT(createCylinder())); createMenu->addAction(tr("Cone"), this, SLOT(createCone())); createMenu->addAction(tr("Sphere"), this, SLOT(createSphere())); m_contextMenu->addAction(tr("Import Mesh"), this, SLOT(importMesh())); QSurfaceFormat format = this->format(); format.setVersion(kOpenGLMajorVersion, kOpenGLMinorVersion); format.setProfile(QSurfaceFormat::CoreProfile); format.setDepthBufferSize(32); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); LOG(INFO) << fmt::format("Setting format with OpenGL version {}.{}", kOpenGLMajorVersion, kOpenGLMinorVersion); this->setFormat(format); }
void CustomWindow::vsyncChangedHandler( bool vsync ) { QSurfaceFormat fmt = format(); // Grab OpenGL context surface format if it's ready to go, it's more filled out than the window one // It can be unitialized on startup before so check that it exists before using it if( openglContext() ) { fmt = openglContext()->format(); } #if defined( Q_OS_WIN ) fmt.setSwapBehavior( vsync ? QSurfaceFormat::SingleBuffer : QSurfaceFormat::DoubleBuffer ); #elif defined( Q_OS_MACX ) // Leave it alone, OS X happily accepts single buffering #endif fmt.setSwapInterval( vsync ? 1 : 0 ); // Window must be reset to apply the changes resetPlatformWindow( fmt ); emit doubleBufferedChanged( fmt.swapBehavior() == QSurfaceFormat::DoubleBuffer ); }
static QSurfaceFormat qSurfaceFormatFromPixelFormat(const PIXELFORMATDESCRIPTOR &pfd, QWindowsOpenGLAdditionalFormat *additionalIn = 0) { QSurfaceFormat format; if (pfd.dwFlags & PFD_DOUBLEBUFFER) format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); format.setDepthBufferSize(pfd.cDepthBits); if (pfd.iPixelType == PFD_TYPE_RGBA) format.setAlphaBufferSize(pfd.cAlphaBits); format.setRedBufferSize(pfd.cRedBits); format.setGreenBufferSize(pfd.cGreenBits); format.setBlueBufferSize(pfd.cBlueBits); format.setStencilBufferSize(pfd.cStencilBits); format.setStereo(pfd.dwFlags & PFD_STEREO); if (additionalIn) { QWindowsOpenGLAdditionalFormat additional; if (isDirectRendering(pfd)) additional.formatFlags |= QWindowsGLDirectRendering; if (hasGLOverlay(pfd)) additional.formatFlags |= QWindowsGLOverlay; if (pfd.cAccumRedBits) additional.formatFlags |= QWindowsGLAccumBuffer; if (testFlag(pfd.dwFlags, PFD_DRAW_TO_BITMAP)) { additional.formatFlags |= QWindowsGLRenderToPixmap; additional.pixmapDepth = pfd.cColorBits; } *additionalIn = additional; } return format; }
QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced) { QSurfaceFormat retFormat = format; *reduced = true; if (retFormat.redBufferSize() > 1) { retFormat.setRedBufferSize(1); } else if (retFormat.greenBufferSize() > 1) { retFormat.setGreenBufferSize(1); } else if (retFormat.blueBufferSize() > 1) { retFormat.setBlueBufferSize(1); } else if (retFormat.samples() > 1) { retFormat.setSamples(qMin(retFormat.samples() / 2, 16)); } else if (retFormat.stereo()) { retFormat.setStereo(false); }else if (retFormat.stencilBufferSize() > 0) { retFormat.setStencilBufferSize(0); }else if (retFormat.hasAlpha()) { retFormat.setAlphaBufferSize(0); }else if (retFormat.depthBufferSize() > 0) { retFormat.setDepthBufferSize(0); }else if (retFormat.swapBehavior() != QSurfaceFormat::SingleBuffer) { retFormat.setSwapBehavior(QSurfaceFormat::SingleBuffer); }else{ *reduced = false; } return retFormat; }
ContextPoolContext::ContextPoolContext(QOpenGLContext* share_context, bool reserved) : reserved(reserved), count(0), surface(NULL), context(NULL) { QSurfaceFormat format; format.setMajorVersion(3); format.setMinorVersion(2); format.setSwapInterval(0); format.setSwapBehavior(QSurfaceFormat::SingleBuffer); format.setRenderableType(QSurfaceFormat::OpenGL); format.setProfile(QSurfaceFormat::CoreProfile); format.setOption(QSurfaceFormat::DebugContext); surface = new QOffscreenSurface(); surface->setFormat(format); surface->create(); if (!surface->isValid()) { throw; } context = new QOpenGLContext(); context->setShareContext(share_context); context->setFormat(surface->requestedFormat()); if (!context->create()) { throw; } context->makeCurrent(surface); gl = context->versionFunctions<QOpenGLFunctions_3_2_Core>(); if (gl == nullptr || !gl->initializeOpenGLFunctions()) { throw; } indirect = new QOpenGLExtension_ARB_multi_draw_indirect(); if (!indirect->initializeOpenGLFunctions()) { throw; } vab = new QOpenGLExtension_ARB_vertex_attrib_binding(); if (!vab->initializeOpenGLFunctions()) { throw; } sso = new QOpenGLExtension_ARB_separate_shader_objects(); if (!sso->initializeOpenGLFunctions()) { throw; } tex = new QOpenGLExtension_ARB_texture_buffer_object(); if (!tex->initializeOpenGLFunctions()) { throw; } buffer = (QOpenGLExtension_ARB_buffer_storage)context->getProcAddress("glBufferStorage"); debug = new QOpenGLExtension_ARB_debug_output(); if (!debug->initializeOpenGLFunctions()) { throw; } debug->glDebugMessageCallbackARB(debug_callback, nullptr); debug->glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_FALSE); debug->glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, 0, GL_TRUE); context->doneCurrent(); context->moveToThread(nullptr); }
QSurfaceFormat QSGContext::defaultSurfaceFormat() const { QSurfaceFormat format; format.setDepthBufferSize(24); format.setStencilBufferSize(8); if (QQuickWindow::hasDefaultAlphaBuffer()) format.setAlphaBufferSize(8); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); return format; }
GLView::GLView(int textureWidth, int textureHeight, std::function<void(GLView *)> initCallback) : QOpenGLWidget(), _textureWidth(textureWidth), _textureHeight(textureHeight) { #if __APPLE__ QSurfaceFormat glFormat; glFormat.setVersion( 3, 3 ); glFormat.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile); glFormat.setSwapBehavior(QSurfaceFormat::SwapBehavior::SingleBuffer); glFormat.setSwapInterval(0); setFormat(glFormat); #endif _initCallback = initCallback; }
void RunTestInOpenGLOffscreenEnvironment(char const * testName, bool apiOpenGLES3, TestFunction const & fn) { std::vector<char> buf(strlen(testName) + 1); strcpy(buf.data(), testName); char * raw = buf.data(); int argc = 1; QApplication app(argc, &raw); QSurfaceFormat fmt; fmt.setAlphaBufferSize(8); fmt.setBlueBufferSize(8); fmt.setGreenBufferSize(8); fmt.setRedBufferSize(8); fmt.setStencilBufferSize(0); fmt.setSamples(0); fmt.setSwapBehavior(QSurfaceFormat::DoubleBuffer); fmt.setSwapInterval(1); fmt.setDepthBufferSize(16); if (apiOpenGLES3) { fmt.setProfile(QSurfaceFormat::CoreProfile); fmt.setVersion(3, 2); } else { fmt.setProfile(QSurfaceFormat::CompatibilityProfile); fmt.setVersion(2, 1); } auto surface = std::make_unique<QOffscreenSurface>(); surface->setFormat(fmt); surface->create(); auto context = std::make_unique<QOpenGLContext>(); context->setFormat(fmt); context->create(); context->makeCurrent(surface.get()); if (fn) fn(apiOpenGLES3); context->doneCurrent(); surface->destroy(); QTimer::singleShot(0, &app, SLOT(quit())); app.exec(); }
OpenGLWindow::OpenGLWindow( QWindow *parent ) : QWindow( parent ), d( new Private(this) ) { setSurfaceType( QWindow::OpenGLSurface ); QSurfaceFormat format; //format.setDepthBufferSize( 24 ); //format.setSamples( 4 ); //format.setMajorVersion( 3 ); //format.setMinorVersion( 3 ); format.setSwapBehavior( QSurfaceFormat::DoubleBuffer ); format.setRenderableType( QSurfaceFormat::OpenGL ); format.setProfile( QSurfaceFormat::CompatibilityProfile ); setFormat( format ); create(); d->thread = OpenGLRenderThread::instance(); d->renderId = d->thread->registerSurface( this ); d->thread->update( d->renderId ); }
void KisOpenGL::setDefaultFormat() { QSurfaceFormat format; #ifdef Q_OS_MAC // format.setProfile(QSurfaceFormat::CoreProfile); // format.setOptions(QSurfaceFormat::DeprecatedFunctions); format.setVersion(2, 1); #else format.setProfile(QSurfaceFormat::CompatibilityProfile); format.setOptions(QSurfaceFormat::DeprecatedFunctions); format.setVersion(3, 0); #endif format.setDepthBufferSize(24); format.setStencilBufferSize(8); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); KisConfig cfg; if (cfg.disableVSync()) { format.setSwapInterval(0); // Disable vertical refresh syncing } QSurfaceFormat::setDefaultFormat(format); }
/*! Returns a window format for the OpenGL format specified by \a format. */ QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format) { QSurfaceFormat retFormat; if (format.alpha()) retFormat.setAlphaBufferSize(format.alphaBufferSize() == -1 ? 1 : format.alphaBufferSize()); if (format.blueBufferSize() >= 0) retFormat.setBlueBufferSize(format.blueBufferSize()); if (format.greenBufferSize() >= 0) retFormat.setGreenBufferSize(format.greenBufferSize()); if (format.redBufferSize() >= 0) retFormat.setRedBufferSize(format.redBufferSize()); if (format.depth()) retFormat.setDepthBufferSize(format.depthBufferSize() == -1 ? 1 : format.depthBufferSize()); retFormat.setSwapBehavior(format.doubleBuffer() ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::DefaultSwapBehavior); if (format.sampleBuffers()) retFormat.setSamples(format.samples() == -1 ? 4 : format.samples()); if (format.stencil()) retFormat.setStencilBufferSize(format.stencilBufferSize() == -1 ? 1 : format.stencilBufferSize()); retFormat.setStereo(format.stereo()); return retFormat; }
window::window(init_fn_type const& init_fn, step_fn_type const& step_fn, draw_fn_type const& draw_fn, fini_fn_type const& fini_fn) : m_context(nullptr) , m_gl_logger(nullptr) , m_initialised(false) , m_finished(false) , m_init_fn(init_fn) , m_step_fn(step_fn) , m_draw_fn(draw_fn) , m_fini_fn(fini_fn) { QSurfaceFormat format; // format.setDepthBufferSize(16); format.setDepthBufferSize( 24 ); format.setMajorVersion(4U); format.setMinorVersion(2U); format.setProfile(QSurfaceFormat::CoreProfile); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); format.setOption(QSurfaceFormat::DebugContext); format.setSwapInterval(0); format.setSamples(0); m_context = new QOpenGLContext(this); m_context->setFormat(format); m_context->create(); setSurfaceType(QWindow::OpenGLSurface); setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); //setGeometry(QRect(10, 10, 640, 480)); setFormat(format); create(); }
int main(int argc, char *argv[]) { QApplication a(argc, argv); QSurfaceFormat format; format.setMajorVersion(4); format.setMinorVersion(1); format.setProfile(QSurfaceFormat::CoreProfile); format.setRenderableType(QSurfaceFormat::OpenGL); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); format.setSamples(2); format.setDepthBufferSize(24); format.setRedBufferSize(8); format.setGreenBufferSize(8); format.setBlueBufferSize(8); format.setAlphaBufferSize(0); format.setStencilBufferSize(8); QSurfaceFormat::setDefaultFormat(format); DemoGLWindow window; window.show(); return a.exec(); }
void NcQuickView::ensureOpenGLFormat() { //QGLFormat glFormat; //glFormat.setVersion(3,2); //glFormat.setProfile(QGLFormat::CoreProfile); //QGLFormat::setDefaultFormat(glFormat); QSurfaceFormat glf = QSurfaceFormat::defaultFormat(); glf.setVersion(4,1); glf.setProfile(QSurfaceFormat::CoreProfile); // glf.setOption(QSurfaceFormat::DebugContext); glf.setSamples(4); glf.setSwapBehavior(QSurfaceFormat::SingleBuffer); glf.setRedBufferSize(8); glf.setGreenBufferSize(8); glf.setBlueBufferSize(8); glf.setDepthBufferSize(8); // qDebug() <<"glversion = "<< glf.version(); QSurfaceFormat::setDefaultFormat(glf); // QGLFormat::setDefaultFormat(glFormat); }
/*! Returns a window format for the OpenGL format specified by \a format. */ QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format) { QSurfaceFormat retFormat; if (format.alpha()) retFormat.setAlphaBufferSize(format.alphaBufferSize() == -1 ? 1 : format.alphaBufferSize()); if (format.blueBufferSize() >= 0) retFormat.setBlueBufferSize(format.blueBufferSize()); if (format.greenBufferSize() >= 0) retFormat.setGreenBufferSize(format.greenBufferSize()); if (format.redBufferSize() >= 0) retFormat.setRedBufferSize(format.redBufferSize()); if (format.depth()) retFormat.setDepthBufferSize(format.depthBufferSize() == -1 ? 1 : format.depthBufferSize()); retFormat.setSwapBehavior(format.doubleBuffer() ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::DefaultSwapBehavior); if (format.sampleBuffers()) retFormat.setSamples(format.samples() == -1 ? 4 : format.samples()); if (format.stencil()) retFormat.setStencilBufferSize(format.stencilBufferSize() == -1 ? 1 : format.stencilBufferSize()); retFormat.setStereo(format.stereo()); retFormat.setMajorVersion(format.majorVersion()); retFormat.setMinorVersion(format.minorVersion()); retFormat.setProfile(static_cast<QSurfaceFormat::OpenGLContextProfile>(format.profile())); return retFormat; }
int main(int argc, char **argv) { //See http://doc.qt.io/qt-5/qopenglwidget.html#opengl-function-calls-headers-and-qopenglfunctions /** Calling QSurfaceFormat::setDefaultFormat() before constructing the QApplication instance is mandatory on some platforms (for example, OS X) when an OpenGL core profile context is requested. This is to ensure that resource sharing between contexts stays functional as all internal contexts are created using the correct version and profile. **/ { QSurfaceFormat format = QSurfaceFormat::defaultFormat(); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); format.setOption(QSurfaceFormat::StereoBuffers, true); format.setStencilBufferSize(0); #ifdef CC_GL_WINDOW_USE_QWINDOW format.setStereo(true); #endif #ifdef Q_OS_MAC format.setStereo(false); format.setVersion( 2, 1 ); format.setProfile( QSurfaceFormat::CoreProfile ); #endif #ifdef QT_DEBUG format.setOption(QSurfaceFormat::DebugContext, true); #endif QSurfaceFormat::setDefaultFormat(format); } //The 'AA_ShareOpenGLContexts' attribute must be defined BEFORE the creation of the Q(Gui)Application //DGM: this is mandatory to enable exclusive full screen for ccGLWidget (at least on Windows) QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); //QT initialiation qccApplication app(argc, argv); //Locale management { //Force 'english' locale so as to get a consistent behavior everywhere QLocale locale = QLocale(QLocale::English); locale.setNumberOptions(QLocale::c().numberOptions()); QLocale::setDefault(locale); #ifdef Q_OS_UNIX //We reset the numeric locale for POSIX functions //See http://qt-project.org/doc/qt-5/qcoreapplication.html#locale-settings setlocale(LC_NUMERIC, "C"); #endif } #ifdef USE_VLD VLDEnable(); #endif #ifdef Q_OS_MAC // This makes sure that our "working directory" is not within the application bundle QDir appDir = QCoreApplication::applicationDirPath(); if ( appDir.dirName() == "MacOS" ) { appDir.cdUp(); appDir.cdUp(); appDir.cdUp(); QDir::setCurrent( appDir.absolutePath() ); } #endif //splash screen QSplashScreen* splash = 0; QTime splashStartTime; //restore some global parameters { QSettings settings; settings.beginGroup(ccPS::GlobalShift()); double maxAbsCoord = settings.value(ccPS::MaxAbsCoord(), ccGlobalShiftManager::MaxCoordinateAbsValue()).toDouble(); double maxAbsDiag = settings.value(ccPS::MaxAbsDiag(), ccGlobalShiftManager::MaxBoundgBoxDiagonal()).toDouble(); settings.endGroup(); ccLog::Print(QString("[Global Shift] Max abs. coord = %1 / max abs. diag = %2").arg(maxAbsCoord, 0, 'e', 0).arg(maxAbsDiag, 0, 'e', 0)); ccGlobalShiftManager::SetMaxCoordinateAbsValue(maxAbsCoord); ccGlobalShiftManager::SetMaxBoundgBoxDiagonal(maxAbsDiag); } //Command line mode? bool commandLine = (argc > 1 && argv[1][0] == '-'); //specific case: translation file selection int lastArgumentIndex = 1; QTranslator translator; if (commandLine && QString(argv[1]).toUpper() == "-LANG") { QString langFilename = QString(argv[2]); //Load translation file if (translator.load(langFilename, QCoreApplication::applicationDirPath())) { qApp->installTranslator(&translator); } else { QMessageBox::warning(0, QObject::tr("Translation"), QObject::tr("Failed to load language file '%1'").arg(langFilename)); } commandLine = false; lastArgumentIndex = 3; } //command line mode if (!commandLine) { if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_1) == 0) { QMessageBox::critical(0, "Error", "This application needs OpenGL 2.1 at least to run!"); return EXIT_FAILURE; } //splash screen splashStartTime.start(); QPixmap pixmap(QString::fromUtf8(":/CC/images/imLogoV2Qt.png")); splash = new QSplashScreen(pixmap, Qt::WindowStaysOnTopHint); splash->show(); QApplication::processEvents(); } //global structures initialization ccTimer::Init(); FileIOFilter::InitInternalFilters(); //load all known I/O filters (plugins will come later!) ccNormalVectors::GetUniqueInstance(); //force pre-computed normals array initialization ccColorScalesManager::GetUniqueInstance(); //force pre-computed color tables initialization int result = 0; if (commandLine) { //command line processing (no GUI) result = ccCommandLineParser::Parse(argc, argv); } else { //main window init. MainWindow* mainWindow = MainWindow::TheInstance(); if (!mainWindow) { QMessageBox::critical(0, "Error", "Failed to initialize the main application window?!"); return EXIT_FAILURE; } mainWindow->show(); QApplication::processEvents(); //show current Global Shift parameters in Console { ccLog::Print(QString("[Global Shift] Max abs. coord = %1 / max abs. diag = %2") .arg(ccGlobalShiftManager::MaxCoordinateAbsValue(), 0, 'e', 0) .arg(ccGlobalShiftManager::MaxBoundgBoxDiagonal(), 0, 'e', 0)); } if (argc > lastArgumentIndex) { if (splash) splash->close(); //any additional argument is assumed to be a filename --> we try to load it/them QStringList filenames; for (int i = lastArgumentIndex; i<argc; ++i) filenames << QString(argv[i]); mainWindow->addToDB(filenames); } if (splash) { //we want the splash screen to be visible a minimum amount of time (1000 ms.) while (splashStartTime.elapsed() < 1000) { splash->raise(); QApplication::processEvents(); //to let the system breath! } splash->close(); QApplication::processEvents(); delete splash; splash = 0; } //let's rock! try { result = app.exec(); } catch(...) { QMessageBox::warning(0, "CC crashed!","Hum, it seems that CC has crashed... Sorry about that :)"); } } //release global structures MainWindow::DestroyInstance(); FileIOFilter::UnregisterAll(); #ifdef CC_TRACK_ALIVE_SHARED_OBJECTS //for debug purposes unsigned alive = CCShareable::GetAliveCount(); if (alive > 1) { printf("Error: some shared objects (%u) have not been released on program end!",alive); system("PAUSE"); } #endif return result; }
void Engine::init() { if (mIsInitialized) { return; } // Create renderer. mRenderer.reset(new Renderer()); mRenderList.reset(new RenderList()); // Create window. mViewer.reset(new QQuickView()); mViewer->setSource(Util::getUrlPathToAsset("Engine/qml/main.qml")); mViewer->setResizeMode(QQuickView::SizeRootObjectToView); // Initially set the window to call glClear for us. This is to prevent an uninitialized frame // buffer from being displayed to the user. We prevent the window from calling glClear later // so that we can render under it. mViewer->setColor(QColor::fromRgba(0x00000000)); mViewer->setClearBeforeRendering(true); // Attempt to select RGB565 with a 16-bit depth buffer. // TODO: According to comments in q_createConfigAttributesFromFormat (qeglconvenience.cpp) this // doesn't work. QSurfaceFormat surfaceFormat; surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer); surfaceFormat.setRedBufferSize(5); surfaceFormat.setGreenBufferSize(6); surfaceFormat.setBlueBufferSize(5); surfaceFormat.setDepthBufferSize(16); surfaceFormat.setStencilBufferSize(8); surfaceFormat.setAlphaBufferSize(0); surfaceFormat.setSamples(0); mViewer->setFormat(surfaceFormat); showViewer(); // Load materials. mTextureManager.reset(new TextureManager()); mTerrainMaterials.reset(new TerrainMaterials(Util::getPathToData("materials.json"))); mSoundManager.reset(new SoundManager(this)); // Create UI components. mInputArea = getRoot()->findChild<InputArea*>("inputArea"); Q_ASSERT(mInputArea); mCamera = mViewer->rootObject()->findChild<Camera*>("camera"); mLevelLoader = mCamera->findChild<QQuickItem*>("levelLoader"); // Other connections. connect(mViewer.get(), &QQuickView::beforeSynchronizing, this, &Engine::onBeforeSynchronizing, Qt::DirectConnection); connect(mViewer.get(), &QQuickView::beforeRendering, this, &Engine::onBeforeRendering, Qt::DirectConnection); connect(mViewer.get(), &QQuickView::afterRendering, this, &Engine::onAfterRendering, Qt::DirectConnection); connect(mViewer.get(), &QQuickView::afterAnimating, this, &Engine::update, Qt::DirectConnection); connect(mLevelLoader, SIGNAL(loadCompleted(bool)), this, SLOT(onLoadCompleted(bool))); mContactListener.reset(new ContactListener()); mDestructionListener.reset(new DestructionListener()); mDebugDraw.reset(new LiquidFunDebugDraw()); mIsInitialized = true; }
static QSurfaceFormat qSurfaceFormatFromHDC(const QOpenGLStaticContext &staticContext, HDC hdc, int pixelFormat, QWindowsOpenGLAdditionalFormat *additionalIn = 0) { enum { attribSize =40 }; QSurfaceFormat result; if (!staticContext.hasExtensions()) return result; int iAttributes[attribSize]; int iValues[attribSize]; qFill(iAttributes, iAttributes + attribSize, int(0)); qFill(iValues, iValues + attribSize, int(0)); int i = 0; const bool hasSampleBuffers = testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers); iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0 iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1 iAttributes[i++] = WGL_PIXEL_TYPE_ARB; // 2 iAttributes[i++] = WGL_RED_BITS_ARB; // 3 iAttributes[i++] = WGL_GREEN_BITS_ARB; // 4 iAttributes[i++] = WGL_BLUE_BITS_ARB; // 5 iAttributes[i++] = WGL_ALPHA_BITS_ARB; // 6 iAttributes[i++] = WGL_ACCUM_BITS_ARB; // 7 iAttributes[i++] = WGL_STENCIL_BITS_ARB; // 8 iAttributes[i++] = WGL_STEREO_ARB; // 9 iAttributes[i++] = WGL_ACCELERATION_ARB; // 10 iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; // 11 if (hasSampleBuffers) { iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 12 iAttributes[i++] = WGL_SAMPLES_ARB; // 13 } if (!staticContext.wglGetPixelFormatAttribIVARB(hdc, pixelFormat, 0, i, iAttributes, iValues)) { qErrnoWarning("%s: wglGetPixelFormatAttribIVARB() failed for basic parameters.", __FUNCTION__); return result; } result.setSwapBehavior(iValues[0] ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::SingleBuffer); result.setDepthBufferSize(iValues[1]); result.setRedBufferSize(iValues[3]); result.setGreenBufferSize(iValues[4]); result.setBlueBufferSize(iValues[5]); result.setAlphaBufferSize(iValues[6]); result.setStencilBufferSize(iValues[8]); if (iValues[9]) result.setOption(QSurfaceFormat::StereoBuffers); if (hasSampleBuffers) result.setSamples(iValues[13]); if (additionalIn) { if (iValues[7]) additionalIn->formatFlags |= QWindowsGLAccumBuffer; if (iValues[10] == WGL_FULL_ACCELERATION_ARB) additionalIn->formatFlags |= QWindowsGLDirectRendering; if (iValues[11]) additionalIn->formatFlags |= QWindowsGLOverlay; } return result; }
int main(int argc, char **argv) { //See http://doc.qt.io/qt-5/qopenglwidget.html#opengl-function-calls-headers-and-qopenglfunctions /** Calling QSurfaceFormat::setDefaultFormat() before constructing the QApplication instance is mandatory on some platforms (for example, OS X) when an OpenGL core profile context is requested. This is to ensure that resource sharing between contexts stays functional as all internal contexts are created using the correct version and profile. **/ { QSurfaceFormat format = QSurfaceFormat::defaultFormat(); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); format.setOption(QSurfaceFormat::StereoBuffers, true); format.setStencilBufferSize(0); #ifdef CC_GL_WINDOW_USE_QWINDOW format.setStereo(true); #endif #ifdef Q_OS_MAC format.setStereo(false); format.setVersion( 2, 1 ); format.setProfile( QSurfaceFormat::CoreProfile ); #endif #ifdef QT_DEBUG format.setOption(QSurfaceFormat::DebugContext, true); #endif QSurfaceFormat::setDefaultFormat(format); } //The 'AA_ShareOpenGLContexts' attribute must be defined BEFORE the creation of the Q(Gui)Application //DGM: this is mandatory to enable exclusive full screen for ccGLWidget (at least on Windows) QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); //QT initialiation qccApplication app(argc, argv); //Locale management { //Force 'english' locale so as to get a consistent behavior everywhere QLocale locale = QLocale(QLocale::English); locale.setNumberOptions(QLocale::c().numberOptions()); QLocale::setDefault(locale); #ifdef Q_OS_UNIX //We reset the numeric locale for POSIX functions //See http://qt-project.org/doc/qt-5/qcoreapplication.html#locale-settings setlocale(LC_NUMERIC, "C"); #endif } #ifdef USE_VLD VLDEnable(); #endif #ifdef Q_OS_MAC // This makes sure that our "working directory" is not within the application bundle QDir appDir = QCoreApplication::applicationDirPath(); if ( appDir.dirName() == "MacOS" ) { appDir.cdUp(); appDir.cdUp(); appDir.cdUp(); QDir::setCurrent( appDir.absolutePath() ); } #endif //store the log message until a valid logging instance is registered ccLog::EnableMessageBackup(true); //restore some global parameters { QSettings settings; settings.beginGroup(ccPS::GlobalShift()); double maxAbsCoord = settings.value(ccPS::MaxAbsCoord(), ccGlobalShiftManager::MaxCoordinateAbsValue()).toDouble(); double maxAbsDiag = settings.value(ccPS::MaxAbsDiag(), ccGlobalShiftManager::MaxBoundgBoxDiagonal()).toDouble(); settings.endGroup(); ccLog::Print(QString("[Global Shift] Max abs. coord = %1 / max abs. diag = %2").arg(maxAbsCoord, 0, 'e', 0).arg(maxAbsDiag, 0, 'e', 0)); ccGlobalShiftManager::SetMaxCoordinateAbsValue(maxAbsCoord); ccGlobalShiftManager::SetMaxBoundgBoxDiagonal(maxAbsDiag); } //Command line mode? bool commandLine = (argc > 1 && argv[1][0] == '-'); //specific commands int lastArgumentIndex = 1; QTranslator translator; if (commandLine) { //translation file selection if (QString(argv[lastArgumentIndex]).toUpper() == "-LANG") { QString langFilename = QString(argv[2]); //Load translation file if (translator.load(langFilename, QCoreApplication::applicationDirPath())) { qApp->installTranslator(&translator); } else { QMessageBox::warning(0, QObject::tr("Translation"), QObject::tr("Failed to load language file '%1'").arg(langFilename)); } commandLine = false; lastArgumentIndex += 2; } } //splash screen QSplashScreen* splash = 0; QTime splashStartTime; //standard mode if (!commandLine) { if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_1) == 0) { QMessageBox::critical(0, "Error", "This application needs OpenGL 2.1 at least to run!"); return EXIT_FAILURE; } //splash screen splashStartTime.start(); QPixmap pixmap(QString::fromUtf8(":/CC/images/imLogoV2Qt.png")); splash = new QSplashScreen(pixmap, Qt::WindowStaysOnTopHint); splash->show(); QApplication::processEvents(); } //global structures initialization FileIOFilter::InitInternalFilters(); //load all known I/O filters (plugins will come later!) ccNormalVectors::GetUniqueInstance(); //force pre-computed normals array initialization ccColorScalesManager::GetUniqueInstance(); //force pre-computed color tables initialization //load the plugins tPluginInfoList plugins; QStringList dirFilters; QStringList pluginPaths; { QString appPath = QCoreApplication::applicationDirPath(); #if defined(Q_OS_MAC) dirFilters << "*.dylib"; // plugins are in the bundle appPath.remove("MacOS"); pluginPaths += (appPath + "Plugins/ccPlugins"); #if defined(CC_MAC_DEV_PATHS) // used for development only - this is the path where the plugins are built // this avoids having to install into the application bundle when developing pluginPaths += (appPath + "../../../ccPlugins"); #endif #elif defined(Q_OS_WIN) dirFilters << "*.dll"; //plugins are in bin/plugins pluginPaths << (appPath + "/plugins"); #elif defined(Q_OS_LINUX) dirFilters << "*.so"; // Plugins are relative to the bin directory where the executable is found QDir binDir(appPath); if (binDir.dirName() == "bin") { binDir.cdUp(); pluginPaths << (binDir.absolutePath() + "/lib/cloudcompare/plugins"); } else { // Choose a reasonable default to look in pluginPaths << "/usr/lib/cloudcompare/plugins"; } #else #warning Need to specify the plugin path for this OS. #endif #ifdef Q_OS_MAC // Add any app data paths // Plugins in these directories take precendence over the included ones QStringList appDataPaths = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); for (const QString &appDataPath : appDataPaths) { pluginPaths << (appDataPath + "/plugins"); } #endif } ccPlugins::LoadPlugins(plugins, pluginPaths, dirFilters); int result = 0; //command line mode if (commandLine) { //command line processing (no GUI) result = ccCommandLineParser::Parse(argc, argv); } else { //main window init. MainWindow* mainWindow = MainWindow::TheInstance(); if (!mainWindow) { QMessageBox::critical(0, "Error", "Failed to initialize the main application window?!"); return EXIT_FAILURE; } mainWindow->dispatchPlugins(plugins, pluginPaths); mainWindow->show(); QApplication::processEvents(); //show current Global Shift parameters in Console { ccLog::Print(QString("[Global Shift] Max abs. coord = %1 / max abs. diag = %2") .arg(ccGlobalShiftManager::MaxCoordinateAbsValue(), 0, 'e', 0) .arg(ccGlobalShiftManager::MaxBoundgBoxDiagonal(), 0, 'e', 0)); } if (argc > lastArgumentIndex) { if (splash) splash->close(); //any additional argument is assumed to be a filename --> we try to load it/them QStringList filenames; for (int i = lastArgumentIndex; i < argc; ++i) { QString arg(argv[i]); //special command: auto start a plugin if (arg.startsWith(":start-plugin:")) { QString pluginName = arg.mid(14); QString pluginNameUpper = pluginName.toUpper(); //look for this plugin bool found = false; for (const tPluginInfo &plugin : plugins) { if (plugin.object->getName().replace(' ', '_').toUpper() == pluginNameUpper) { found = true; bool success = plugin.object->start(); if (!success) { ccLog::Error(QString("Failed to start the plugin '%1'").arg(plugin.object->getName())); } break; } } if (!found) { ccLog::Error(QString("Couldn't find the plugin '%1'").arg(pluginName.replace('_', ' '))); } } else { filenames << arg; } } mainWindow->addToDB(filenames); } if (splash) { //we want the splash screen to be visible a minimum amount of time (1000 ms.) while (splashStartTime.elapsed() < 1000) { splash->raise(); QApplication::processEvents(); //to let the system breath! } splash->close(); QApplication::processEvents(); delete splash; splash = 0; } //let's rock! try { result = app.exec(); } catch (...) { QMessageBox::warning(0, "CC crashed!", "Hum, it seems that CC has crashed... Sorry about that :)"); } //release the plugins for (tPluginInfo &plugin : plugins) { plugin.object->stop(); //just in case if (!plugin.qObject->parent()) { delete plugin.object; plugin.object = 0; plugin.qObject = 0; } } } //release global structures MainWindow::DestroyInstance(); FileIOFilter::UnregisterAll(); #ifdef CC_TRACK_ALIVE_SHARED_OBJECTS //for debug purposes unsigned alive = CCShareable::GetAliveCount(); if (alive > 1) { printf("Error: some shared objects (%u) have not been released on program end!",alive); system("PAUSE"); } #endif return result; }
int main(int argc, char *argv[]) { //See http://doc.qt.io/qt-5/qopenglwidget.html#opengl-function-calls-headers-and-qopenglfunctions /** Calling QSurfaceFormat::setDefaultFormat() before constructing the QApplication instance is mandatory on some platforms (for example, OS X) when an OpenGL core profile context is requested. This is to ensure that resource sharing between contexts stays functional as all internal contexts are created using the correct version and profile. **/ { QSurfaceFormat format = QSurfaceFormat::defaultFormat(); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); format.setStencilBufferSize(0); #ifdef CC_GL_WINDOW_USE_QWINDOW format.setStereo(true); #endif #ifdef Q_OS_MAC format.setStereo(false); format.setVersion( 2, 1 ); format.setProfile( QSurfaceFormat::CoreProfile ); #endif #ifdef QT_DEBUG format.setOption(QSurfaceFormat::DebugContext); #endif QSurfaceFormat::setDefaultFormat(format); } ccApplication a(argc, argv); //Locale management { //Force 'english' locale so as to get a consistent behavior everywhere QLocale locale = QLocale(QLocale::English); locale.setNumberOptions(QLocale::c().numberOptions()); QLocale::setDefault(locale); #ifdef Q_OS_UNIX //We reset the numeric locale for POSIX functions //See http://qt-project.org/doc/qt-5/qcoreapplication.html#locale-settings setlocale(LC_NUMERIC, "C"); #endif } #ifdef USE_VLD VLDEnable(); #endif #ifdef Q_OS_MAC // This makes sure that our "working directory" is not within the application bundle QDir appDir = QCoreApplication::applicationDirPath(); if ( appDir.dirName() == "MacOS" ) { appDir.cdUp(); appDir.cdUp(); appDir.cdUp(); QDir::setCurrent( appDir.absolutePath() ); } #endif if (!QGLFormat::hasOpenGL()) { QMessageBox::critical(0, "Error", "This application needs OpenGL to run!"); return EXIT_FAILURE; } if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_1) == 0) { QMessageBox::critical(0, "Error", "This application needs OpenGL 2.1 at least to run!"); return EXIT_FAILURE; } //common data initialization FileIOFilter::InitInternalFilters(); //load all known I/O filters (plugins will come later!) ccNormalVectors::GetUniqueInstance(); //force pre-computed normals array initialization ccColorScalesManager::GetUniqueInstance(); //force pre-computed color tables initialization ccViewer w/*(0,Qt::Window|Qt::CustomizeWindowHint)*/; #ifdef Q_OS_MAC a.setViewer( &w ); #endif //register minimal logger to display errors ccViewerLog logger(&w); ccLog::RegisterInstance(&logger); w.show(); //files to open are passed as argument if (argc > 1) { //parse arguments QStringList filenames; int i = 1; while ( i < argc) { QString argument = QString(argv[i++]).toUpper(); //Argument '-WIN X Y W H' (to set window size and position) if (argument.toUpper() == "-WIN") { bool ok = true; if (i+3 < argc) { bool converionOk; int x = QString(argv[i ]).toInt(&converionOk); ok &= converionOk; int y = QString(argv[i+1]).toInt(&converionOk); ok &= converionOk; int width = QString(argv[i+2]).toInt(&converionOk); ok &= converionOk; int height = QString(argv[i+3]).toInt(&converionOk); ok &= converionOk; i += 4; if (ok) { //change window position and size w.move(x,y); w.resize(width,height); } } if (!ok) { ccLog::Warning("Invalid arguments! 4 integer values are expected after '-win' (X Y W H)"); break; } } else if (argument == "-TOP") { w.setWindowFlags(w.windowFlags() | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint); w.show(); } else //any other argument is assumed to be a filename (that will we try to load) { filenames << argument; } } if (!filenames.empty()) w.addToDB(filenames); } #ifdef Q_OS_MAC // process events to load any files on the command line QCoreApplication::processEvents(); #endif w.checkForLoadedEntities(); int result = a.exec(); //release global structures FileIOFilter::UnregisterAll(); return result; }
int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QSurfaceFormat format; format.setMajorVersion(4); format.setMinorVersion(1); format.setProfile(QSurfaceFormat::CoreProfile); format.setRenderableType(QSurfaceFormat::OpenGL); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); format.setSamples(2); // Today I learned: the surface itself doesn't need an alpha channel. // When we blend colours in OpenGL, the alpha value passed in with the colour // is only used internally by OpenGL in order to calculate the physical RGB // to write back into the colour buffer. We don't need to set any alpha on the // surface itself, since the RGB values will already have been blended by the // time they're written back to the colour buffer. If we do set the alpha, that // means we'll actually be able to see through the surface and whatever is behind // will be visible. This isn't what we want for the application main window! // If we want to create a frame buffer later on where the actual colour buffer // output should be translucent, override the default alpha buffer size to 8 bits. format.setDepthBufferSize(24); format.setRedBufferSize(8); format.setGreenBufferSize(8); format.setBlueBufferSize(8); format.setAlphaBufferSize(0); format.setStencilBufferSize(8); QSurfaceFormat::setDefaultFormat(format); qDebug() << "Set default OpenGL format:" << format; QApplication a(argc, argv); a.setApplicationName("Calliper"); a.setApplicationDisplayName("Calliper"); a.setOrganizationName("Infra"); a.setOrganizationName("Infra"); // Initialise the resource manager. ResourceManager::initialise(); // Initialise the renderer. OpenGLRenderer::initialise(); // Initialise the over-arching application. Application::initialise(new MainWindow()); // Set up resources. resourceManager()->makeCurrent(); resourceManager()->setUpOpenGLResources(); renderer()->setUpOpenGLResources(); resourceManager()->doneCurrent(); application()->mainWindow()->show(); int ret = a.exec(); // Shut down the application. Application::shutdown(); // Shut down the renderer. OpenGLRenderer::shutdown(); // Shut down the resource manager. ResourceManager::shutdown(); return ret; return a.exec(); }