Working on consistent input response

This commit is contained in:
Brad Davis 2015-05-30 02:01:11 -07:00
parent 2758718c8d
commit fec214c552
12 changed files with 130 additions and 113 deletions

View file

@ -1102,9 +1102,9 @@ bool Application::event(QEvent* event) {
} }
bool Application::eventFilter(QObject* object, QEvent* event) { bool Application::eventFilter(QObject* object, QEvent* event) {
if (event->type() == QEvent::ShortcutOverride) { if (event->type() == QEvent::ShortcutOverride) {
if (DependencyManager::get<OffscreenUi>()->shouldSwallowShortcut(event)) { auto offscreenUi = DependencyManager::get<OffscreenUi>();
if (offscreenUi->shouldSwallowShortcut(event)) {
event->accept(); event->accept();
return true; return true;
} }
@ -1115,7 +1115,6 @@ bool Application::eventFilter(QObject* object, QEvent* event) {
return true; return true;
} }
} }
return false; return false;
} }
@ -1459,7 +1458,7 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
} }
if (activeWindow() == _window) { if (hasFocus()) {
_keyboardMouseDevice.mousePressEvent(event); _keyboardMouseDevice.mousePressEvent(event);
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
@ -1500,7 +1499,7 @@ void Application::mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceI
return; return;
} }
if (activeWindow() == _window) { if (hasFocus()) {
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
if (mouseOnScreen()) { if (mouseOnScreen()) {
if (DependencyManager::get<CameraToolBox>()->mouseDoublePressEvent(getMouseX(), getMouseY())) { if (DependencyManager::get<CameraToolBox>()->mouseDoublePressEvent(getMouseX(), getMouseY())) {
@ -1525,7 +1524,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
return; return;
} }
if (activeWindow() == _window) { if (hasFocus()) {
_keyboardMouseDevice.mouseReleaseEvent(event); _keyboardMouseDevice.mouseReleaseEvent(event);
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
@ -1563,7 +1562,7 @@ void Application::touchUpdateEvent(QTouchEvent* event) {
_keyboardMouseDevice.touchUpdateEvent(event); _keyboardMouseDevice.touchUpdateEvent(event);
bool validTouch = false; bool validTouch = false;
if (activeWindow() == _window) { if (hasFocus()) {
const QList<QTouchEvent::TouchPoint>& tPoints = event->touchPoints(); const QList<QTouchEvent::TouchPoint>& tPoints = event->touchPoints();
_touchAvg = glm::vec2(0); _touchAvg = glm::vec2(0);
int numTouches = tPoints.count(); int numTouches = tPoints.count();
@ -4675,14 +4674,15 @@ void Application::updateDisplayMode() {
} }
} }
if (_displayPlugin != newDisplayPlugin) { if (_displayPlugin != newDisplayPlugin) {
DependencyManager::get<OffscreenUi>()->setProxyWindow(nullptr);
if (newDisplayPlugin) { if (newDisplayPlugin) {
_offscreenContext->makeCurrent(); _offscreenContext->makeCurrent();
newDisplayPlugin->activate(this); newDisplayPlugin->activate(this);
newDisplayPlugin->installEventFilter(DependencyManager::get<OffscreenUi>().data());
newDisplayPlugin->installEventFilter(qApp);
QWindow* pluginWindow = newDisplayPlugin->getWindow(); QWindow* pluginWindow = newDisplayPlugin->getWindow();
if (pluginWindow) { if (pluginWindow) {
// Event filter queue is 'last in, first used'
pluginWindow->installEventFilter(DependencyManager::get<OffscreenUi>().data());
pluginWindow->installEventFilter(qApp);
DependencyManager::get<OffscreenUi>()->setProxyWindow(pluginWindow); DependencyManager::get<OffscreenUi>()->setProxyWindow(pluginWindow);
} }
_offscreenContext->makeCurrent(); _offscreenContext->makeCurrent();
@ -4690,6 +4690,7 @@ void Application::updateDisplayMode() {
std::swap(newDisplayPlugin, _displayPlugin); std::swap(newDisplayPlugin, _displayPlugin);
if (newDisplayPlugin) { if (newDisplayPlugin) {
newDisplayPlugin->removeEventFilter(DependencyManager::get<OffscreenUi>().data());
newDisplayPlugin->deactivate(); newDisplayPlugin->deactivate();
_offscreenContext->makeCurrent(); _offscreenContext->makeCurrent();
} }

View file

@ -9,13 +9,10 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // 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 "Application.h"
#include "GLCanvas.h" #include "GLCanvas.h"
#include "MainWindow.h"
const int MSECS_PER_FRAME_WHEN_THROTTLED = 66; const int MSECS_PER_FRAME_WHEN_THROTTLED = 66;
@ -35,7 +32,7 @@ void GLCanvas::stopFrameTimer() {
} }
bool GLCanvas::isThrottleRendering() const { bool GLCanvas::isThrottleRendering() const {
return _throttleRendering || Application::getInstance()->getWindow()->isMinimized(); return _throttleRendering || parentWidget()->isMinimized();
} }
int GLCanvas::getDeviceWidth() const { int GLCanvas::getDeviceWidth() const {
@ -57,7 +54,7 @@ void GLCanvas::initializeGL() {
} }
void GLCanvas::paintGL() { void GLCanvas::paintGL() {
if (!_throttleRendering && !Application::getInstance()->getWindow()->isMinimized()) { if (!isThrottleRendering()) {
Application::getInstance()->paintGL(); Application::getInstance()->paintGL();
} }
} }
@ -93,7 +90,7 @@ void GLCanvas::activeChanged(Qt::ApplicationState state) {
void GLCanvas::throttleRender() { void GLCanvas::throttleRender() {
_frameTimer.start(_idleRenderInterval); _frameTimer.start(_idleRenderInterval);
if (!Application::getInstance()->getWindow()->isMinimized()) { if (!parentWidget()->isMinimized()) {
Application::getInstance()->paintGL(); Application::getInstance()->paintGL();
} }
} }

View file

@ -29,12 +29,8 @@ static QWidget * oldWidget = nullptr;
void LegacyDisplayPlugin::activate(PluginContainer * container) { void LegacyDisplayPlugin::activate(PluginContainer * container) {
_window = new GLCanvas(); _window = new GLCanvas();
QOpenGLContext * sourceContext = QOpenGLContext::currentContext(); QOpenGLContext * sourceContext = QOpenGLContext::currentContext();
QOpenGLContext * newContext = new QOpenGLContext(); QOpenGLContext * newContext = new QOpenGLContext();
{ {
QSurfaceFormat format; QSurfaceFormat format;
format.setOption(QSurfaceFormat::DebugContext); format.setOption(QSurfaceFormat::DebugContext);
@ -56,11 +52,8 @@ void LegacyDisplayPlugin::activate(PluginContainer * container) {
_timer.start(8); _timer.start(8);
} }
void LegacyDisplayPlugin::deactivate() { void LegacyDisplayPlugin::deactivate() {
_timer.stop(); _timer.stop();
_window->removeEventFilter(DependencyManager::get<OffscreenUi>().data());
_window->removeEventFilter(qApp);
// FIXME, during shutdown, this causes an NPE. Need to deactivate the plugin before the main window is destroyed. // FIXME, during shutdown, this causes an NPE. Need to deactivate the plugin before the main window is destroyed.
// if (qApp->getWindow()) { // if (qApp->getWindow()) {
// qApp->getWindow()->setCentralWidget(oldWidget); // qApp->getWindow()->setCentralWidget(oldWidget);
@ -121,3 +114,11 @@ ivec2 LegacyDisplayPlugin::getTrueMousePosition() const {
QWindow* LegacyDisplayPlugin::getWindow() const { QWindow* LegacyDisplayPlugin::getWindow() const {
return _window->windowHandle(); return _window->windowHandle();
} }
void LegacyDisplayPlugin::installEventFilter(QObject* filter) {
_window->installEventFilter(filter);
}
void LegacyDisplayPlugin::removeEventFilter(QObject* filter) {
_window->removeEventFilter(filter);
}

View file

@ -31,7 +31,10 @@ public:
virtual void preDisplay(); virtual void preDisplay();
virtual void idle(); virtual void idle();
virtual ivec2 getTrueMousePosition() const; virtual ivec2 getTrueMousePosition() const;
virtual QWindow* getWindow() const; virtual QWindow* getWindow() const;
virtual void installEventFilter(QObject* filter);
virtual void removeEventFilter(QObject* filter);
protected: protected:
virtual void makeCurrent() final; virtual void makeCurrent() final;

View file

@ -5,7 +5,7 @@ setup_hifi_library(OpenGL)
setup_hifi_opengl() setup_hifi_opengl()
link_hifi_libraries(shared plugins ) link_hifi_libraries(shared plugins gpu render-utils)
add_dependency_external_projects(glm) add_dependency_external_projects(glm)
find_package(GLM REQUIRED) find_package(GLM REQUIRED)

View file

@ -92,6 +92,9 @@ public:
// The window for the surface, used for event interception. May be null. // The window for the surface, used for event interception. May be null.
virtual QWindow* getWindow() const = 0; virtual QWindow* getWindow() const = 0;
virtual void installEventFilter(QObject* filter) {}
virtual void removeEventFilter(QObject* filter) {}
// The mouse position relative to the window (or proxy window) surface // The mouse position relative to the window (or proxy window) surface
virtual glm::ivec2 getTrueMousePosition() const = 0; virtual glm::ivec2 getTrueMousePosition() const = 0;

View file

@ -47,51 +47,6 @@ QWindow* GlWindowDisplayPlugin::getWindow() const {
return _window; return _window;
} }
bool GlWindowDisplayPlugin::eventFilter(QObject* object, QEvent* event) {
if (qApp->eventFilter(object, event)) {
return true;
}
// FIXME
/*
auto offscreenUi = DependencyManager::get<OffscreenUi>();
if (offscreenUi->eventFilter(object, event)) {
return true;
}
*/
// distinct calls for easier debugging with breakpoints
switch (event->type()) {
case QEvent::KeyPress:
QCoreApplication::sendEvent(QCoreApplication::instance(), event);
break;
case QEvent::KeyRelease:
QCoreApplication::sendEvent(QCoreApplication::instance(), event);
break;
case QEvent::MouseButtonPress:
QCoreApplication::sendEvent(QCoreApplication::instance(), event);
break;
case QEvent::MouseButtonRelease:
QCoreApplication::sendEvent(QCoreApplication::instance(), event);
break;
case QEvent::FocusIn:
QCoreApplication::sendEvent(QCoreApplication::instance(), event);
break;
case QEvent::FocusOut:
QCoreApplication::sendEvent(QCoreApplication::instance(), event);
break;
case QEvent::Resize:
QCoreApplication::sendEvent(QCoreApplication::instance(), event);
break;
case QEvent::MouseMove:
QCoreApplication::sendEvent(QCoreApplication::instance(), event);
break;
default:
break;
}
return false;
}
void GlWindowDisplayPlugin::activate(PluginContainer * container) { void GlWindowDisplayPlugin::activate(PluginContainer * container) {
Q_ASSERT(nullptr == _window); Q_ASSERT(nullptr == _window);
_window = new GlWindow(QOpenGLContext::currentContext()); _window = new GlWindow(QOpenGLContext::currentContext());
@ -101,8 +56,6 @@ void GlWindowDisplayPlugin::activate(PluginContainer * container) {
_timer->start(8); _timer->start(8);
makeCurrent(); makeCurrent();
customizeContext(); customizeContext();
// FIXME
//DependencyManager::get<OffscreenUi>()->setProxyWindow(_window);
} }
void GlWindowDisplayPlugin::deactivate() { void GlWindowDisplayPlugin::deactivate() {
@ -125,3 +78,36 @@ glm::ivec2 GlWindowDisplayPlugin::getCanvasSize() const {
bool GlWindowDisplayPlugin::hasFocus() const { bool GlWindowDisplayPlugin::hasFocus() const {
return _window->isActive(); return _window->isActive();
} }
void GlWindowDisplayPlugin::installEventFilter(QObject* filter) {
_window->installEventFilter(filter);
}
void GlWindowDisplayPlugin::removeEventFilter(QObject* filter) {
_window->removeEventFilter(filter);
}
bool GlWindowDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) {
switch (event->type()) {
case QEvent::MouseMove:
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
case QEvent::KeyPress:
case QEvent::KeyRelease:
case QEvent::FocusIn:
case QEvent::FocusOut:
case QEvent::Resize:
case QEvent::TouchBegin:
case QEvent::TouchEnd:
case QEvent::TouchUpdate:
case QEvent::Wheel:
case QEvent::DragEnter:
case QEvent::Drop:
if (QCoreApplication::sendEvent(QCoreApplication::instance(), event)) {
return true;
}
break;
}
return false;
}

View file

@ -21,16 +21,23 @@ public:
virtual QSize getDeviceSize() const final; virtual QSize getDeviceSize() const final;
virtual glm::ivec2 getCanvasSize() const final; virtual glm::ivec2 getCanvasSize() const final;
virtual bool hasFocus() const; virtual bool hasFocus() const;
virtual bool eventFilter(QObject* object, QEvent* event);
virtual glm::ivec2 getTrueMousePosition() const; virtual glm::ivec2 getTrueMousePosition() const;
virtual QWindow* getWindow() const; virtual QWindow* getWindow() const;
virtual bool eventFilter(QObject* receiver, QEvent* event);
virtual void installEventFilter(QObject* filter);
virtual void removeEventFilter(QObject* filter);
protected: protected:
virtual void makeCurrent() final; virtual void makeCurrent() final;
virtual void doneCurrent() final; virtual void doneCurrent() final;
virtual void swapBuffers() final; virtual void swapBuffers() final;
// Called by the activate method to specify the initial window geometry
// flags, etc
virtual void customizeWindow() = 0; virtual void customizeWindow() = 0;
// Called by the activate method after the GL context has been created to
// initialize OpenGL context settings needed by the plugin
virtual void customizeContext() = 0; virtual void customizeContext() = 0;
private: private:

View file

@ -32,5 +32,4 @@ public:
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize, virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize,
GLuint overlayTexture, const glm::uvec2& overlaySize); GLuint overlayTexture, const glm::uvec2& overlaySize);
virtual void finishFrame(); virtual void finishFrame();
}; };

View file

@ -14,7 +14,6 @@
#include "../OglplusHelpers.h" #include "../OglplusHelpers.h"
#if 0
bool OculusWin32DisplayPlugin::isSupported() { bool OculusWin32DisplayPlugin::isSupported() {
ovr_Initialize(nullptr); ovr_Initialize(nullptr);
bool result = false; bool result = false;
@ -25,6 +24,7 @@ bool OculusWin32DisplayPlugin::isSupported() {
return result; return result;
} }
#if 0
// A basic wrapper for constructing a framebuffer with a renderbuffer // A basic wrapper for constructing a framebuffer with a renderbuffer
// for the depth attachment and an undefined type for the color attachement // for the depth attachment and an undefined type for the color attachement
// This allows us to reuse the basic framebuffer code for both the Mirror // This allows us to reuse the basic framebuffer code for both the Mirror

View file

@ -9,7 +9,11 @@
#include "OculusBaseDisplayPlugin.h" #include "OculusBaseDisplayPlugin.h"
class OffscreenGlCanvas;
class OculusWin32DisplayPlugin : public OculusBaseDisplayPlugin { class OculusWin32DisplayPlugin : public OculusBaseDisplayPlugin {
public: public:
virtual bool isSupported(); virtual bool isSupported();
private:
OffscreenGlCanvas* _canvas;
}; };

View file

@ -16,6 +16,8 @@
#include <MatrixStack.h> #include <MatrixStack.h>
#include <PathUtils.h> #include <PathUtils.h>
#include <TextureCache.h>
#include <gpu/GLBackend.h>
#include "../OglplusHelpers.h" #include "../OglplusHelpers.h"
@ -35,6 +37,7 @@ bool Tv3dDisplayPlugin::isSupported() const {
static ProgramPtr program; static ProgramPtr program;
static ShapeWrapperPtr plane; static ShapeWrapperPtr plane;
static gpu::TexturePointer crosshairTexture;
void Tv3dDisplayPlugin::customizeWindow() { void Tv3dDisplayPlugin::customizeWindow() {
_window->setFlags(Qt::FramelessWindowHint); _window->setFlags(Qt::FramelessWindowHint);
@ -64,15 +67,19 @@ void Tv3dDisplayPlugin::customizeContext() {
program = loadDefaultShader(); program = loadDefaultShader();
plane = loadPlane(program); plane = loadPlane(program);
Context::ClearColor(0, 0, 0, 1); Context::ClearColor(0, 0, 0, 1);
// _crosshairTexture = DependencyManager::get<TextureCache>()-> crosshairTexture = DependencyManager::get<TextureCache>()->
// getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png"); getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png");
} }
// FIXME make this into a setting that can be adjusted
const float DEFAULT_IPD = 0.064f; const float DEFAULT_IPD = 0.064f;
const float HALF_DEFAULT_IPD = DEFAULT_IPD / 2.0f; const float HALF_DEFAULT_IPD = DEFAULT_IPD / 2.0f;
glm::mat4 Tv3dDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProjection) const { glm::mat4 Tv3dDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProjection) const {
// Refer to http://www.nvidia.com/content/gtc-2010/pdfs/2010_gtc2010.pdf on creating
// stereo projection matrices. Do NOT use "toe-in", use translation.
float nearZ = DEFAULT_NEAR_CLIP; // near clipping plane float nearZ = DEFAULT_NEAR_CLIP; // near clipping plane
float screenZ = 0.25f; // screen projection plane float screenZ = 0.25f; // screen projection plane
// FIXME verify this is the right calculation // FIXME verify this is the right calculation
@ -91,15 +98,24 @@ glm::mat4 Tv3dDisplayPlugin::getModelview(Eye eye, const glm::mat4& baseModelvie
return baseModelview * glm::translate(mat4(), vec3(modelviewShift, 0, 0)); return baseModelview * glm::translate(mat4(), vec3(modelviewShift, 0, 0));
} }
template <typename F>
void sbs_for_each_eye(const uvec2& size, F f) {
QRect r(QPoint(0, 0), QSize(size.x / 2, size.y));
for_each_eye([&](Eye eye) {
oglplus::Context::Viewport(r.x(), r.y(), r.width(), r.height());
f(eye);
}, [&] {
r.moveLeft(r.width());
});
}
void Tv3dDisplayPlugin::display( void Tv3dDisplayPlugin::display(
GLuint sceneTexture, const glm::uvec2& sceneSize, GLuint sceneTexture, const glm::uvec2& sceneSize,
GLuint overlayTexture, const glm::uvec2& overlaySize) { GLuint overlayTexture, const glm::uvec2& overlaySize) {
QSize size = getDeviceSize(); uvec2 size = toGlm(getDeviceSize());
using namespace oglplus; using namespace oglplus;
Context::Viewport(size.width(), size.height()); Context::Viewport(size.x, size.y);
Context::Clear().ColorBuffer().DepthBuffer(); Context::Clear().ColorBuffer().DepthBuffer();
Mat4Uniform(*program, "ModelView").Set(mat4()); Mat4Uniform(*program, "ModelView").Set(mat4());
@ -109,10 +125,11 @@ void Tv3dDisplayPlugin::display(
plane->Draw(); plane->Draw();
const float overlayAspect = aspect(toGlm(size)); // FIXME the
const float screenAspect = aspect(size);
const GLfloat distance = 1.0f; const GLfloat distance = 1.0f;
const GLfloat halfQuadHeight = distance * tan(DEFAULT_FIELD_OF_VIEW_DEGREES); const GLfloat halfQuadHeight = distance * tan(DEFAULT_FIELD_OF_VIEW_DEGREES);
const GLfloat halfQuadWidth = halfQuadHeight * (float)size.width() / (float)size.height(); const GLfloat halfQuadWidth = halfQuadHeight * screenAspect;
const GLfloat quadWidth = halfQuadWidth * 2.0f; const GLfloat quadWidth = halfQuadWidth * 2.0f;
const GLfloat quadHeight = halfQuadHeight * 2.0f; const GLfloat quadHeight = halfQuadHeight * 2.0f;
@ -123,38 +140,39 @@ void Tv3dDisplayPlugin::display(
Context::Enable(Capability::Blend); Context::Enable(Capability::Blend);
glBindTexture(GL_TEXTURE_2D, overlayTexture); glBindTexture(GL_TEXTURE_2D, overlayTexture);
mat4 pr = glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), aspect(toGlm(size)), DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP); mat4 pr = glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), screenAspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP);
Mat4Uniform(*program, "Projection").Set(pr); Mat4Uniform(*program, "Projection").Set(pr);
// Position the camera relative to the overlay texture
MatrixStack mv; MatrixStack mv;
mv.translate(vec3(0, 0, -distance)).scale(vec3(0.7f, 0.7f / overlayAspect, 1.0f)); // .scale(vec3(quadWidth, quadHeight, 1.0)); mv.translate(vec3(0, 0, -distance)).scale(vec3(0.7f, 0.7f / screenAspect, 1.0f)); // .scale(vec3(quadWidth, quadHeight, 1.0));
sbs_for_each_eye(size, [&](Eye eye) {
QRect r(QPoint(0, 0), QSize(size.width() / 2, size.height())); mv.withPush([&] {
for (int i = 0; i < 2; ++i) { // translate
Context::Viewport(r.x(), r.y(), r.width(), r.height()); mv.top() = getModelview(eye, mv.top());
Mat4Uniform(*program, "ModelView").Set(mv.top()); Mat4Uniform(*program, "ModelView").Set(mv.top());
plane->Draw(); plane->Draw();
r.moveLeft(r.width()); });
} });
#if 0 glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(crosshairTexture));
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture)); glm::vec2 canvasSize = getCanvasSize();
glm::vec2 canvasSize = qApp->getCanvasSize(); glm::vec2 mouse = toGlm(_window->mapFromGlobal(QCursor::pos()));
glm::vec2 mouse = qApp->getMouse();
mouse /= canvasSize; mouse /= canvasSize;
mouse *= 2.0f; mouse *= 2.0f;
mouse -= 1.0f; mouse -= 1.0f;
mouse.y *= -1.0f; mouse.y *= -1.0f;
sbs_for_each_eye(size, [&](Eye eye) {
mv.withPush([&] {
// translate
mv.top() = getModelview(eye, mv.top());
mv.translate(mouse); mv.translate(mouse);
mv.scale(0.1f); //mv.scale(0.05f);
mv.scale(vec3(0.025f, 0.05f, 1.0f));
Mat4Uniform(*program, "ModelView").Set(mv.top()); Mat4Uniform(*program, "ModelView").Set(mv.top());
r = QRect(QPoint(0, 0), QSize(size.width() / 2, size.height()));
for (int i = 0; i < 2; ++i) {
Context::Viewport(r.x(), r.y(), r.width(), r.height());
plane->Draw(); plane->Draw();
r.moveLeft(r.width()); });
} });
#endif
Context::Disable(Capability::Blend); Context::Disable(Capability::Blend);
} }
@ -166,11 +184,9 @@ void Tv3dDisplayPlugin::activate(PluginContainer * container) {
void Tv3dDisplayPlugin::deactivate() { void Tv3dDisplayPlugin::deactivate() {
makeCurrent(); makeCurrent();
if (plane) {
plane.reset(); plane.reset();
program.reset(); program.reset();
// _crosshairTexture.reset(); crosshairTexture.reset();
}
doneCurrent(); doneCurrent();
GlWindowDisplayPlugin::deactivate(); GlWindowDisplayPlugin::deactivate();
} }