Downgraded the OpenGL context version to 2.1. Qt's QOpenGLPaintDevice is

not compatible with OpenGL versions >= 3.0. NVIDIA does not care, but
unfortunately AMD does.
Also tweaked some other qt & opengl settings for more pleasant visuals.
This commit is contained in:
2016-09-22 00:16:35 +02:00
parent 439a46ec82
commit 8e815b0ce4
+93 -81
View File
@@ -43,27 +43,34 @@ namespace advsettings {
} }
QSurfaceFormat format; QSurfaceFormat format;
format.setMajorVersion( 4 ); // Qt's QOpenGLPaintDevice is not compatible with OpenGL versions >= 3.0
format.setMinorVersion( 1 ); // NVIDIA does not care, but unfortunately AMD does
format.setProfile( QSurfaceFormat::CompatibilityProfile ); // Are subtle changes to the semantics of OpenGL functions actually covered by the compatibility profile,
// and this is an AMD bug?
format.setVersion(2, 1);
//format.setProfile( QSurfaceFormat::CompatibilityProfile );
format.setDepthBufferSize(16);
format.setStencilBufferSize(8);
format.setSamples(16);
m_pOpenGLContext.reset(new QOpenGLContext()); m_pOpenGLContext.reset(new QOpenGLContext());
m_pOpenGLContext->setFormat( format ); m_pOpenGLContext->setFormat(format);
if (!m_pOpenGLContext->create()) { if (!m_pOpenGLContext->create()) {
throw std::runtime_error("Could not create OpenGL context"); throw std::runtime_error("Could not create OpenGL context");
} }
// create an offscreen surface to attach the context and FBO to // create an offscreen surface to attach the context and FBO to
m_pOffscreenSurface.reset(new QOffscreenSurface()); m_pOffscreenSurface.reset(new QOffscreenSurface());
m_pOffscreenSurface->setFormat(m_pOpenGLContext->format());
m_pOffscreenSurface->create(); m_pOffscreenSurface->create();
m_pOpenGLContext->makeCurrent( m_pOffscreenSurface.get() ); m_pOpenGLContext->makeCurrent(m_pOffscreenSurface.get());
m_pScene.reset(new QGraphicsScene()); m_pScene.reset(new QGraphicsScene());
connect( m_pScene.get(), SIGNAL(changed(const QList<QRectF>&)), this, SLOT( OnSceneChanged(const QList<QRectF>&)) ); connect(m_pScene.get(), SIGNAL(changed(const QList<QRectF>&)), this, SLOT(OnSceneChanged(const QList<QRectF>&)));
} }
void OverlayController::SetWidget(OverlayWidget *pWidget, const std::string& name, const std::string& key) { void OverlayController::SetWidget(OverlayWidget *pWidget, const std::string& name, const std::string& key) {
// all of the mouse handling stuff requires that the widget be at 0,0 // all of the mouse handling stuff requires that the widget be at 0,0
pWidget->move(0, 0); pWidget->move(0, 0);
m_pScene->addWidget(pWidget); m_pScene->addWidget(pWidget);
@@ -95,7 +102,11 @@ void OverlayController::SetWidget(OverlayWidget *pWidget, const std::string& nam
m_pPumpEventsTimer->setInterval(20); m_pPumpEventsTimer->setInterval(20);
m_pPumpEventsTimer->start(); m_pPumpEventsTimer->start();
m_pFbo.reset(new QOpenGLFramebufferObject(pWidget->width(), pWidget->height(), GL_TEXTURE_2D)); QOpenGLFramebufferObjectFormat fboFormat;
fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
fboFormat.setTextureTarget(GL_TEXTURE_2D);
m_pFbo.reset(new QOpenGLFramebufferObject(pWidget->width(), pWidget->height(), fboFormat));
vr::HmdVector2_t vecWindowSize = { vr::HmdVector2_t vecWindowSize = {
(float)pWidget->width(), (float)pWidget->width(),
@@ -109,40 +120,41 @@ void OverlayController::SetWidget(OverlayWidget *pWidget, const std::string& nam
fixFloorTabController.init(this, pWidget); fixFloorTabController.init(this, pWidget);
statisticsTabController.init(this, pWidget); statisticsTabController.init(this, pWidget);
settingsTabController.init(this, pWidget); settingsTabController.init(this, pWidget);
} }
void OverlayController::OnSceneChanged( const QList<QRectF>& ) { void OverlayController::OnSceneChanged(const QList<QRectF>&) {
// skip rendering if the overlay isn't visible // skip rendering if the overlay isn't visible
if( !vr::VROverlay() || !vr::VROverlay()->IsOverlayVisible( m_ulOverlayHandle ) && !vr::VROverlay()->IsOverlayVisible( m_ulOverlayThumbnailHandle ) ) if (!vr::VROverlay() || !vr::VROverlay()->IsOverlayVisible(m_ulOverlayHandle) && !vr::VROverlay()->IsOverlayVisible(m_ulOverlayThumbnailHandle))
return; return;
m_pOpenGLContext->makeCurrent( m_pOffscreenSurface.get() ); m_pOpenGLContext->makeCurrent(m_pOffscreenSurface.get());
m_pFbo->bind(); m_pFbo->bind();
QOpenGLPaintDevice device( m_pFbo->size() ); QOpenGLPaintDevice device(m_pFbo->size());
QPainter painter( &device ); QPainter painter(&device);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
m_pScene->render( &painter ); m_pScene->render(&painter);
m_pFbo->release(); m_pFbo->release();
GLuint unTexture = m_pFbo->texture(); GLuint unTexture = m_pFbo->texture();
if( unTexture != 0 ) { if (unTexture != 0) {
#if defined _WIN64 || defined _LP64 #if defined _WIN64 || defined _LP64
// To avoid any compiler warning because of cast to a larger pointer type (warning C4312 on VC) // To avoid any compiler warning because of cast to a larger pointer type (warning C4312 on VC)
vr::Texture_t texture = { (void*)((uint64_t)unTexture), vr::API_OpenGL, vr::ColorSpace_Auto }; vr::Texture_t texture = { (void*)((uint64_t)unTexture), vr::API_OpenGL, vr::ColorSpace_Auto };
#else #else
vr::Texture_t texture = { (void*)unTexture, vr::API_OpenGL, vr::ColorSpace_Auto }; vr::Texture_t texture = { (void*)unTexture, vr::API_OpenGL, vr::ColorSpace_Auto };
#endif #endif
vr::VROverlay()->SetOverlayTexture( m_ulOverlayHandle, &texture ); vr::VROverlay()->SetOverlayTexture(m_ulOverlayHandle, &texture);
} }
m_pOpenGLContext->functions()->glFlush(); // We need to flush otherwise the texture may be empty. m_pOpenGLContext->functions()->glFlush(); // We need to flush otherwise the texture may be empty.
} }
void OverlayController::OnTimeoutPumpEvents() { void OverlayController::OnTimeoutPumpEvents() {
if( !vr::VRSystem() ) if (!vr::VRSystem())
return; return;
/* /*
@@ -161,28 +173,28 @@ void OverlayController::OnTimeoutPumpEvents() {
moveCenterTabController.eventLoopTick(vr::VRCompositor()->GetTrackingSpace()); moveCenterTabController.eventLoopTick(vr::VRCompositor()->GetTrackingSpace());
vr::VREvent_t vrEvent; vr::VREvent_t vrEvent;
while( vr::VROverlay()->PollNextOverlayEvent( m_ulOverlayHandle, &vrEvent, sizeof( vrEvent ) ) ) { while (vr::VROverlay()->PollNextOverlayEvent(m_ulOverlayHandle, &vrEvent, sizeof(vrEvent))) {
switch( vrEvent.eventType ) { switch (vrEvent.eventType) {
case vr::VREvent_MouseMove: { case vr::VREvent_MouseMove: {
QPointF ptNewMouse( vrEvent.data.mouse.x, vrEvent.data.mouse.y ); QPointF ptNewMouse(vrEvent.data.mouse.x, vrEvent.data.mouse.y);
QPoint ptGlobal = ptNewMouse.toPoint(); QPoint ptGlobal = ptNewMouse.toPoint();
QGraphicsSceneMouseEvent mouseEvent( QEvent::GraphicsSceneMouseMove ); QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
mouseEvent.setWidget( NULL ); mouseEvent.setWidget(NULL);
mouseEvent.setPos( ptNewMouse ); mouseEvent.setPos(ptNewMouse);
mouseEvent.setScenePos( ptGlobal ); mouseEvent.setScenePos(ptGlobal);
mouseEvent.setScreenPos( ptGlobal ); mouseEvent.setScreenPos(ptGlobal);
mouseEvent.setLastPos( m_ptLastMouse ); mouseEvent.setLastPos(m_ptLastMouse);
mouseEvent.setLastScenePos( m_pWidget->mapToGlobal( m_ptLastMouse.toPoint() ) ); mouseEvent.setLastScenePos(m_pWidget->mapToGlobal(m_ptLastMouse.toPoint()));
mouseEvent.setLastScreenPos( m_pWidget->mapToGlobal( m_ptLastMouse.toPoint() ) ); mouseEvent.setLastScreenPos(m_pWidget->mapToGlobal(m_ptLastMouse.toPoint()));
mouseEvent.setButtons( m_lastMouseButtons ); mouseEvent.setButtons(m_lastMouseButtons);
mouseEvent.setButton( Qt::NoButton ); mouseEvent.setButton(Qt::NoButton);
mouseEvent.setModifiers( 0 ); mouseEvent.setModifiers(0);
mouseEvent.setAccepted( false ); mouseEvent.setAccepted(false);
m_ptLastMouse = ptNewMouse; m_ptLastMouse = ptNewMouse;
QApplication::sendEvent( m_pScene.get(), &mouseEvent ); QApplication::sendEvent(m_pScene.get(), &mouseEvent);
OnSceneChanged( QList<QRectF>() ); OnSceneChanged(QList<QRectF>());
} }
break; break;
@@ -192,23 +204,23 @@ void OverlayController::OnTimeoutPumpEvents() {
m_lastMouseButtons |= button; m_lastMouseButtons |= button;
QPoint ptGlobal = m_ptLastMouse.toPoint(); QPoint ptGlobal = m_ptLastMouse.toPoint();
QGraphicsSceneMouseEvent mouseEvent( QEvent::GraphicsSceneMousePress ); QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
mouseEvent.setWidget( NULL ); mouseEvent.setWidget(NULL);
mouseEvent.setPos( m_ptLastMouse ); mouseEvent.setPos(m_ptLastMouse);
mouseEvent.setButtonDownPos( button, m_ptLastMouse ); mouseEvent.setButtonDownPos(button, m_ptLastMouse);
mouseEvent.setButtonDownScenePos( button, ptGlobal); mouseEvent.setButtonDownScenePos(button, ptGlobal);
mouseEvent.setButtonDownScreenPos( button, ptGlobal ); mouseEvent.setButtonDownScreenPos(button, ptGlobal);
mouseEvent.setScenePos( ptGlobal ); mouseEvent.setScenePos(ptGlobal);
mouseEvent.setScreenPos( ptGlobal ); mouseEvent.setScreenPos(ptGlobal);
mouseEvent.setLastPos( m_ptLastMouse ); mouseEvent.setLastPos(m_ptLastMouse);
mouseEvent.setLastScenePos( ptGlobal ); mouseEvent.setLastScenePos(ptGlobal);
mouseEvent.setLastScreenPos( ptGlobal ); mouseEvent.setLastScreenPos(ptGlobal);
mouseEvent.setButtons( m_lastMouseButtons ); mouseEvent.setButtons(m_lastMouseButtons);
mouseEvent.setButton( button ); mouseEvent.setButton(button);
mouseEvent.setModifiers( 0 ); mouseEvent.setModifiers(0);
mouseEvent.setAccepted( false ); mouseEvent.setAccepted(false);
QApplication::sendEvent( m_pScene.get(), &mouseEvent ); QApplication::sendEvent(m_pScene.get(), &mouseEvent);
} }
break; break;
@@ -217,20 +229,20 @@ void OverlayController::OnTimeoutPumpEvents() {
m_lastMouseButtons &= ~button; m_lastMouseButtons &= ~button;
QPoint ptGlobal = m_ptLastMouse.toPoint(); QPoint ptGlobal = m_ptLastMouse.toPoint();
QGraphicsSceneMouseEvent mouseEvent( QEvent::GraphicsSceneMouseRelease ); QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
mouseEvent.setWidget( NULL ); mouseEvent.setWidget(NULL);
mouseEvent.setPos( m_ptLastMouse ); mouseEvent.setPos(m_ptLastMouse);
mouseEvent.setScenePos( ptGlobal ); mouseEvent.setScenePos(ptGlobal);
mouseEvent.setScreenPos( ptGlobal ); mouseEvent.setScreenPos(ptGlobal);
mouseEvent.setLastPos( m_ptLastMouse ); mouseEvent.setLastPos(m_ptLastMouse);
mouseEvent.setLastScenePos( ptGlobal ); mouseEvent.setLastScenePos(ptGlobal);
mouseEvent.setLastScreenPos( ptGlobal ); mouseEvent.setLastScreenPos(ptGlobal);
mouseEvent.setButtons( m_lastMouseButtons ); mouseEvent.setButtons(m_lastMouseButtons);
mouseEvent.setButton( button ); mouseEvent.setButton(button);
mouseEvent.setModifiers( 0 ); mouseEvent.setModifiers(0);
mouseEvent.setAccepted( false ); mouseEvent.setAccepted(false);
QApplication::sendEvent( m_pScene.get(), &mouseEvent ); QApplication::sendEvent(m_pScene.get(), &mouseEvent);
} }
break; break;
@@ -262,9 +274,9 @@ void OverlayController::OnTimeoutPumpEvents() {
} }
} }
if( m_ulOverlayThumbnailHandle != vr::k_ulOverlayHandleInvalid ) { if (m_ulOverlayThumbnailHandle != vr::k_ulOverlayHandleInvalid) {
while( vr::VROverlay()->PollNextOverlayEvent( m_ulOverlayThumbnailHandle, &vrEvent, sizeof( vrEvent) ) ) { while (vr::VROverlay()->PollNextOverlayEvent(m_ulOverlayThumbnailHandle, &vrEvent, sizeof(vrEvent))) {
switch( vrEvent.eventType ) { switch (vrEvent.eventType) {
case vr::VREvent_OverlayShown: { case vr::VREvent_OverlayShown: {
m_pWidget->repaint(); m_pWidget->repaint();
UpdateWidget(); UpdateWidget();
@@ -273,18 +285,18 @@ void OverlayController::OnTimeoutPumpEvents() {
} }
} }
} }
} }
void OverlayController::UpdateWidget() { void OverlayController::UpdateWidget() {
steamVRTabController.UpdateTab(); steamVRTabController.UpdateTab();
chaperoneTabController.UpdateTab(); chaperoneTabController.UpdateTab();
moveCenterTabController.UpdateTab(); moveCenterTabController.UpdateTab();
fixFloorTabController.UpdateTab(); fixFloorTabController.UpdateTab();
statisticsTabController.UpdateTab(); statisticsTabController.UpdateTab();
settingsTabController.UpdateTab(); settingsTabController.UpdateTab();
} }
void OverlayController::AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin universe, unsigned axisId, float offset, bool adjustBounds, bool commit) { void OverlayController::AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin universe, unsigned axisId, float offset, bool adjustBounds, bool commit) {
if (offset != 0.0f) { if (offset != 0.0f) {
if (commit) { if (commit) {
vr::VRChaperoneSetup()->RevertWorkingCopy(); vr::VRChaperoneSetup()->RevertWorkingCopy();
@@ -310,9 +322,9 @@ void OverlayController::AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin un
vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live);
} }
} }
} }
void OverlayController::RotateUniverseCenter(vr::ETrackingUniverseOrigin universe, float yAngle, bool adjustBounds, bool commit) { void OverlayController::RotateUniverseCenter(vr::ETrackingUniverseOrigin universe, float yAngle, bool adjustBounds, bool commit) {
if (yAngle != 0.0f) { if (yAngle != 0.0f) {
if (commit) { if (commit) {
vr::VRChaperoneSetup()->RevertWorkingCopy(); vr::VRChaperoneSetup()->RevertWorkingCopy();
@@ -353,9 +365,9 @@ void OverlayController::RotateUniverseCenter(vr::ETrackingUniverseOrigin univers
vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live);
} }
} }
} }
void OverlayController::AddOffsetToCollisionBounds(unsigned axisId, float offset, bool commit) { void OverlayController::AddOffsetToCollisionBounds(unsigned axisId, float offset, bool commit) {
// Apparently Valve sanity-checks the y-coordinates of the collision bounds (and only the y-coordinates) // Apparently Valve sanity-checks the y-coordinates of the collision bounds (and only the y-coordinates)
// I can move the bounds on the xz-plane, I can make the "ceiling" of the chaperone cage lower/higher, but when I // I can move the bounds on the xz-plane, I can make the "ceiling" of the chaperone cage lower/higher, but when I
// dare to set one single lower corner to something non-zero, every corner gets its y-coordinates reset to the defaults. // dare to set one single lower corner to something non-zero, every corner gets its y-coordinates reset to the defaults.
@@ -379,9 +391,9 @@ void OverlayController::AddOffsetToCollisionBounds(unsigned axisId, float offset
if (commit && collisionBoundsCount > 0) { if (commit && collisionBoundsCount > 0) {
vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live);
} }
} }
void OverlayController::RotateCollisionBounds(float angle, bool commit) { void OverlayController::RotateCollisionBounds(float angle, bool commit) {
if (commit) { if (commit) {
vr::VRChaperoneSetup()->RevertWorkingCopy(); vr::VRChaperoneSetup()->RevertWorkingCopy();
} }
@@ -414,7 +426,7 @@ void OverlayController::RotateCollisionBounds(float angle, bool commit) {
if (commit && collisionBoundsCount > 0) { if (commit && collisionBoundsCount > 0) {
vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live);
} }
} }
} // namespace advconfig } // namespace advconfig