Merge pull request #5097 from jherico/cursor_manager

Cursor manager first pass
This commit is contained in:
Brad Hefta-Gaub 2015-06-11 18:05:43 -07:00
commit c0deff9fdc
7 changed files with 214 additions and 53 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

@ -57,6 +57,7 @@
#include <AccountManager.h>
#include <AddressManager.h>
#include <CursorManager.h>
#include <AmbientOcclusionEffect.h>
#include <AudioInjector.h>
#include <DeferredLightingEffect.h>
@ -1239,9 +1240,20 @@ void Application::keyPressEvent(QKeyEvent* event) {
}
break;
case Qt::Key_Apostrophe:
resetSensors();
case Qt::Key_Apostrophe: {
if (isMeta) {
auto cursor = Cursor::Manager::instance().getCursor();
auto curIcon = cursor->getIcon();
if (curIcon == Cursor::Icon::DEFAULT) {
cursor->setIcon(Cursor::Icon::LINK);
} else {
cursor->setIcon(Cursor::Icon::DEFAULT);
}
} else {
resetSensors();
}
break;
}
case Qt::Key_A:
if (isShifted) {
@ -1365,12 +1377,27 @@ void Application::keyPressEvent(QKeyEvent* event) {
case Qt::Key_Slash:
Menu::getInstance()->triggerOption(MenuOption::Stats);
break;
case Qt::Key_Plus:
_myAvatar->increaseSize();
case Qt::Key_Plus: {
if (isMeta && event->modifiers().testFlag(Qt::KeypadModifier)) {
auto& cursorManager = Cursor::Manager::instance();
cursorManager.setScale(cursorManager.getScale() * 1.1f);
} else {
_myAvatar->increaseSize();
}
break;
case Qt::Key_Minus:
_myAvatar->decreaseSize();
}
case Qt::Key_Minus: {
if (isMeta && event->modifiers().testFlag(Qt::KeypadModifier)) {
auto& cursorManager = Cursor::Manager::instance();
cursorManager.setScale(cursorManager.getScale() / 1.1f);
} else {
_myAvatar->decreaseSize();
}
break;
}
case Qt::Key_Equal:
_myAvatar->resetSize();
break;

View file

@ -22,7 +22,7 @@
#include <gpu/GLBackend.h>
#include <GLMHelpers.h>
#include <OffscreenUi.h>
#include <PathUtils.h>
#include <CursorManager.h>
#include <PerfStat.h>
#include "AudioClient.h"
@ -128,7 +128,6 @@ ApplicationOverlay::ApplicationOverlay() :
_alpha(1.0f),
_oculusUIRadius(1.0f),
_trailingAudioLoudness(0.0f),
_crosshairTexture(0),
_previousBorderWidth(-1),
_previousBorderHeight(-1),
_previousMagnifierBottomLeft(),
@ -260,6 +259,18 @@ gpu::PipelinePointer ApplicationOverlay::getDrawPipeline() {
return _standardDrawPipeline;
}
void ApplicationOverlay::bindCursorTexture(gpu::Batch& batch, uint8_t cursorIndex) {
auto& cursorManager = Cursor::Manager::instance();
auto cursor = cursorManager.getCursor(cursorIndex);
auto iconId = cursor->getIcon();
if (!_cursors.count(iconId)) {
auto iconPath = cursorManager.getIconImage(cursor->getIcon());
_cursors[iconId] = DependencyManager::get<TextureCache>()->
getImageTexture(iconPath);
}
batch.setUniformTexture(0, _cursors[iconId]);
}
#define CURSOR_PIXEL_SIZE 32.0f
// Draws the FBO texture for the screen
@ -267,12 +278,6 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) {
if (_alpha == 0.0f) {
return;
}
if (!_crosshairTexture) {
_crosshairTexture = TextureCache::getImageTexture(
PathUtils::resourcesPath() + "images/arrow.png");
}
renderArgs->_context->syncCache();
@ -301,7 +306,7 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) {
glm::vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize;
model.setScale(vec3(mouseSize, 1.0f));
batch.setModelTransform(model);
batch.setUniformTexture(0, _crosshairTexture);
bindCursorTexture(batch);
glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f };
DependencyManager::get<GeometryCache>()->renderUnitQuad(batch, vec4(1));
renderArgs->_context->render(batch);
@ -328,24 +333,6 @@ glm::vec2 getPolarCoordinates(const PalmData& palm) {
return polar;
}
void ApplicationOverlay::renderReticle(gpu::Batch& batch, glm::quat orientation, float alpha) {
if (!_crosshairTexture) {
_crosshairTexture = TextureCache::getImageTexture(
PathUtils::resourcesPath() + "images/arrow.png");
}
batch.setUniformTexture(0, _crosshairTexture);
glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], alpha };
vec3 dist = getPoint(0, 0);
mat4 reticleXfm = glm::translate(mat4(), vec3(0, 0, -1));
reticleXfm = glm::mat4_cast(orientation) * reticleXfm;
reticleXfm = glm::scale(reticleXfm, vec3(reticleSize, reticleSize, 1.0f));
batch.setModelTransform(Transform(reticleXfm));
DependencyManager::get<GeometryCache>()->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
}
// Draws the FBO texture for Oculus rift.
void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera& whichCamera) {
if (_alpha == 0.0f) {
@ -373,12 +360,9 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera
drawSphereSection(batch);
if (!_crosshairTexture) {
_crosshairTexture = TextureCache::getImageTexture(
PathUtils::resourcesPath() + "images/arrow.png");
}
batch.setUniformTexture(0, _crosshairTexture);
bindCursorTexture(batch);
auto geometryCache = DependencyManager::get<GeometryCache>();
vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize);
//Controller Pointers
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
PalmData& palm = myAvatar->getHand()->getPalms()[i];
@ -387,7 +371,7 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera
// Convert to quaternion
mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
mat4 reticleXfm = overlayXfm * pointerXfm;
reticleXfm = glm::scale(reticleXfm, vec3(reticleSize, reticleSize, 1.0f));
reticleXfm = glm::scale(reticleXfm, reticleScale);
batch.setModelTransform(reticleXfm);
// Render reticle at location
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
@ -400,7 +384,7 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera
_reticlePosition[MOUSE].y()));
mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
mat4 reticleXfm = overlayXfm * pointerXfm;
reticleXfm = glm::scale(reticleXfm, vec3(reticleSize, reticleSize, 1.0f));
reticleXfm = glm::scale(reticleXfm, reticleScale);
batch.setModelTransform(reticleXfm);
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
}
@ -487,16 +471,12 @@ bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position,
//Renders optional pointers
void ApplicationOverlay::renderPointers() {
//lazily load crosshair texture
if (_crosshairTexture == 0) {
_crosshairTexture = TextureCache::getImageTexture(PathUtils::resourcesPath() + "images/arrow.png");
}
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glEnable(GL_TEXTURE_2D);
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
//glActiveTexture(GL_TEXTURE0);
//bindCursorTexture();
if (qApp->isHMDMode() && !qApp->getLastMouseMoveWasSimulated() && !qApp->isMouseHidden()) {
//If we are in oculus, render reticle later
@ -541,8 +521,8 @@ void ApplicationOverlay::renderPointers() {
_magActive[MOUSE] = false;
renderControllerPointers();
}
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
//glBindTexture(GL_TEXTURE_2D, 0);
//glDisable(GL_TEXTURE_2D);
}
void ApplicationOverlay::renderControllerPointers() {

View file

@ -72,7 +72,6 @@ private:
float _hmdUIAngularSize = DEFAULT_HMD_UI_ANGULAR_SIZE;
QOpenGLFramebufferObject* _framebufferObject;
void renderReticle(gpu::Batch& batch, glm::quat orientation, float alpha);
void renderPointers();
void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder);
@ -83,6 +82,7 @@ private:
void renderCameraToggle();
void renderStatsAndLogs();
void renderDomainConnectionStatusBorder();
void bindCursorTexture(gpu::Batch& batch, uint8_t cursorId = 0);
void buildFramebufferObject();
@ -104,7 +104,8 @@ private:
float _trailingAudioLoudness;
gpu::TexturePointer _crosshairTexture;
QMap<uint16_t, gpu::TexturePointer> _cursors;
GLuint _newUiTexture{ 0 };
int _reticleQuad;

View file

@ -0,0 +1,92 @@
//
// Created by Bradley Austin Davis on 2015/06/08
// Copyright 2015 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 "CursorManager.h"
#include <QCursor>
#include <QWidget>
#include <QUrl>
#include <PathUtils.h>
namespace Cursor {
void Instance::setIcon(uint16_t icon) {
_icon = icon;
}
uint16_t Instance::getIcon() const {
return _icon;
}
class MouseInstance : public Instance {
Source getType() const {
return Source::MOUSE;
}
ivec2 getScreenPosition() const {
return toGlm(QCursor::pos());
}
ivec2 getWindowPosition(QWidget* widget) const {
return toGlm(widget->mapFromGlobal(QCursor::pos()));
}
vec2 getRelativePosition(QWidget* widget) const {
vec2 pos = getWindowPosition(widget);
pos /= vec2(toGlm(widget->size()));
return pos;
}
};
static QMap<uint16_t, QString> ICONS;
static uint16_t _customIconId = Icon::USER_BASE;
Manager::Manager() {
ICONS[Icon::DEFAULT] = PathUtils::resourcesPath() + "images/arrow.png";
ICONS[Icon::LINK] = PathUtils::resourcesPath() + "images/reticleLink.png";
}
Manager& Manager::instance() {
static Manager instance;
return instance;
}
uint8_t Manager::getCount() {
return 1;
}
Instance* Manager::getCursor(uint8_t index) {
Q_ASSERT(index < getCount());
static MouseInstance mouseInstance;
if (index == 0) {
return &mouseInstance;
}
return nullptr;
}
uint16_t Manager::registerIcon(const QString& path) {
ICONS[_customIconId] = path;
return _customIconId++;
}
const QString& Manager::getIconImage(uint16_t icon) {
Q_ASSERT(ICONS.count(icon));
return ICONS[icon];
}
float Manager::getScale() {
return _scale;
}
void Manager::setScale(float scale) {
_scale = scale;
}
}

View file

@ -0,0 +1,61 @@
//
// Created by Bradley Austin Davis on 2015/06/08
// Copyright 2015 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
//
#pragma once
#include <stdint.h>
#include <GLMHelpers.h>
namespace Cursor {
enum class Source {
MOUSE,
LEFT_HAND,
RIGHT_HAND,
UNKNOWN,
};
enum Icon {
DEFAULT,
LINK,
GRAB,
// Add new system cursors here
// User cursors will have ids over this value
USER_BASE = 0xFF,
};
class Instance {
public:
virtual Source getType() const = 0;
virtual ivec2 getWindowPosition(QWidget* widget) const = 0;
virtual vec2 getRelativePosition(QWidget* widget) const = 0;
virtual ivec2 getScreenPosition() const = 0;
virtual void setIcon(uint16_t icon);
virtual uint16_t getIcon() const;
private:
uint16_t _icon;
};
class Manager {
Manager();
Manager(const Manager& other) = delete;
public:
static Manager& instance();
uint8_t getCount();
float getScale();
void setScale(float scale);
Instance* getCursor(uint8_t index = 0);
uint16_t registerIcon(const QString& path);
const QString& getIconImage(uint16_t icon);
private:
float _scale{ 1.0f };
};
}