mirror of
https://github.com/overte-org/overte.git
synced 2025-04-26 06:56:32 +02:00
219 lines
6.7 KiB
C++
219 lines
6.7 KiB
C++
//
|
|
// GLCanvas.cpp
|
|
// interface/src
|
|
//
|
|
// Created by Stephen Birarda on 8/14/13.
|
|
// Copyright 2013 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include <QMimeData>
|
|
#include <QUrl>
|
|
#include <QWindow>
|
|
|
|
#include "Application.h"
|
|
#include "GLCanvas.h"
|
|
#include "MainWindow.h"
|
|
#include "devices/OculusManager.h"
|
|
|
|
const int MSECS_PER_FRAME_WHEN_THROTTLED = 66;
|
|
|
|
GLCanvas::GLCanvas() : QGLWidget(QGL::NoDepthBuffer | QGL::NoStencilBuffer),
|
|
_throttleRendering(false),
|
|
_idleRenderInterval(MSECS_PER_FRAME_WHEN_THROTTLED)
|
|
{
|
|
#ifdef Q_OS_LINUX
|
|
// Cause GLCanvas::eventFilter to be called.
|
|
// It wouldn't hurt to do this on Mac and PC too; but apparently it's only needed on linux.
|
|
qApp->installEventFilter(this);
|
|
#endif
|
|
}
|
|
|
|
void GLCanvas::stopFrameTimer() {
|
|
_frameTimer.stop();
|
|
}
|
|
|
|
bool GLCanvas::isThrottleRendering() const {
|
|
return _throttleRendering || Application::getInstance()->getWindow()->isMinimized();
|
|
}
|
|
|
|
int GLCanvas::getDeviceWidth() const {
|
|
return width() * (windowHandle() ? windowHandle()->devicePixelRatio() : 1.0f);
|
|
}
|
|
|
|
int GLCanvas::getDeviceHeight() const {
|
|
return height() * (windowHandle() ? windowHandle()->devicePixelRatio() : 1.0f);
|
|
}
|
|
|
|
void GLCanvas::initializeGL() {
|
|
Application::getInstance()->initializeGL();
|
|
setAttribute(Qt::WA_AcceptTouchEvents);
|
|
setAcceptDrops(true);
|
|
connect(Application::getInstance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(activeChanged(Qt::ApplicationState)));
|
|
connect(&_frameTimer, SIGNAL(timeout()), this, SLOT(throttleRender()));
|
|
|
|
// Note, we *DO NOT* want Qt to automatically swap buffers for us. This results in the "ringing" bug mentioned in WL#19514 when we're throttling the framerate.
|
|
setAutoBufferSwap(false);
|
|
}
|
|
|
|
void GLCanvas::paintGL() {
|
|
if (!_throttleRendering && !Application::getInstance()->getWindow()->isMinimized()) {
|
|
//Need accurate frame timing for the oculus rift
|
|
if (OculusManager::isConnected()) {
|
|
OculusManager::beginFrameTiming();
|
|
}
|
|
|
|
Application::getInstance()->paintGL();
|
|
|
|
if (!OculusManager::isConnected()) {
|
|
swapBuffers();
|
|
} else {
|
|
if (OculusManager::allowSwap()) {
|
|
swapBuffers();
|
|
}
|
|
OculusManager::endFrameTiming();
|
|
}
|
|
}
|
|
}
|
|
|
|
void GLCanvas::resizeGL(int width, int height) {
|
|
Application::getInstance()->resizeGL(width, height);
|
|
}
|
|
|
|
void GLCanvas::keyPressEvent(QKeyEvent* event) {
|
|
Application::getInstance()->keyPressEvent(event);
|
|
}
|
|
|
|
void GLCanvas::keyReleaseEvent(QKeyEvent* event) {
|
|
Application::getInstance()->keyReleaseEvent(event);
|
|
}
|
|
|
|
void GLCanvas::focusOutEvent(QFocusEvent* event) {
|
|
Application::getInstance()->focusOutEvent(event);
|
|
}
|
|
|
|
void GLCanvas::mouseMoveEvent(QMouseEvent* event) {
|
|
Application::getInstance()->mouseMoveEvent(event);
|
|
}
|
|
|
|
void GLCanvas::mousePressEvent(QMouseEvent* event) {
|
|
Application::getInstance()->mousePressEvent(event);
|
|
}
|
|
|
|
void GLCanvas::mouseReleaseEvent(QMouseEvent* event) {
|
|
Application::getInstance()->mouseReleaseEvent(event);
|
|
}
|
|
|
|
void GLCanvas::activeChanged(Qt::ApplicationState state) {
|
|
switch (state) {
|
|
case Qt::ApplicationActive:
|
|
// If we're active, stop the frame timer and the throttle.
|
|
_frameTimer.stop();
|
|
_throttleRendering = false;
|
|
break;
|
|
|
|
case Qt::ApplicationSuspended:
|
|
case Qt::ApplicationHidden:
|
|
// If we're hidden or are about to suspend, don't render anything.
|
|
_throttleRendering = false;
|
|
_frameTimer.stop();
|
|
break;
|
|
|
|
default:
|
|
// Otherwise, throttle.
|
|
if (!_throttleRendering) {
|
|
_frameTimer.start(_idleRenderInterval);
|
|
_throttleRendering = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void GLCanvas::throttleRender() {
|
|
_frameTimer.start(_idleRenderInterval);
|
|
if (!Application::getInstance()->getWindow()->isMinimized()) {
|
|
//Need accurate frame timing for the oculus rift
|
|
if (OculusManager::isConnected()) {
|
|
OculusManager::beginFrameTiming();
|
|
}
|
|
|
|
Application::getInstance()->paintGL();
|
|
swapBuffers();
|
|
|
|
if (OculusManager::isConnected()) {
|
|
OculusManager::endFrameTiming();
|
|
}
|
|
}
|
|
}
|
|
|
|
int updateTime = 0;
|
|
bool GLCanvas::event(QEvent* event) {
|
|
switch (event->type()) {
|
|
case QEvent::TouchBegin:
|
|
Application::getInstance()->touchBeginEvent(static_cast<QTouchEvent*>(event));
|
|
event->accept();
|
|
return true;
|
|
case QEvent::TouchEnd:
|
|
Application::getInstance()->touchEndEvent(static_cast<QTouchEvent*>(event));
|
|
return true;
|
|
case QEvent::TouchUpdate:
|
|
Application::getInstance()->touchUpdateEvent(static_cast<QTouchEvent*>(event));
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
return QGLWidget::event(event);
|
|
}
|
|
|
|
void GLCanvas::wheelEvent(QWheelEvent* event) {
|
|
Application::getInstance()->wheelEvent(event);
|
|
}
|
|
|
|
void GLCanvas::dragEnterEvent(QDragEnterEvent* event) {
|
|
const QMimeData* mimeData = event->mimeData();
|
|
foreach (QUrl url, mimeData->urls()) {
|
|
auto urlString = url.toString();
|
|
if (Application::getInstance()->canAcceptURL(urlString)) {
|
|
event->acceptProposedAction();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GLCanvas::dropEvent(QDropEvent* event) {
|
|
Application::getInstance()->dropEvent(event);
|
|
}
|
|
|
|
// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the
|
|
// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to
|
|
// receive keyPress events for the Alt (and Meta) key in a reliable manner.
|
|
//
|
|
// This filter catches events before QMenuBar can steal the keyboard focus.
|
|
// The idea was borrowed from
|
|
// http://www.archivum.info/qt-interest@trolltech.com/2006-09/00053/Re-(Qt4)-Alt-key-focus-QMenuBar-(solved).html
|
|
|
|
bool GLCanvas::eventFilter(QObject*, QEvent* event) {
|
|
switch (event->type()) {
|
|
case QEvent::KeyPress:
|
|
case QEvent::KeyRelease:
|
|
case QEvent::ShortcutOverride:
|
|
{
|
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
|
if (keyEvent->key() == Qt::Key_Alt || keyEvent->key() == Qt::Key_Meta) {
|
|
if (event->type() == QEvent::KeyPress) {
|
|
keyPressEvent(keyEvent);
|
|
} else if (event->type() == QEvent::KeyRelease) {
|
|
keyReleaseEvent(keyEvent);
|
|
} else {
|
|
QGLWidget::event(event);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|