mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-07 19:23:04 +02:00
Revert "Revert "Merge pull request #5106 from jherico/render_cursor""
This reverts commit 0cdc2b53fe
.
This commit is contained in:
parent
214f07d5f4
commit
737e418878
10 changed files with 327 additions and 469 deletions
BIN
interface/resources/images/arrow.png
Normal file
BIN
interface/resources/images/arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
|
@ -955,6 +955,7 @@ void Application::paintGL() {
|
|||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
displaySide(&renderArgs, _myCamera);
|
||||
_applicationOverlay.displayOverlayTexture(&renderArgs);
|
||||
glPopMatrix();
|
||||
|
||||
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||
|
@ -974,8 +975,6 @@ void Application::paintGL() {
|
|||
0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height(),
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
|
||||
_applicationOverlay.displayOverlayTexture();
|
||||
}
|
||||
|
||||
if (!OculusManager::isConnected() || OculusManager::allowSwap()) {
|
||||
|
|
|
@ -615,12 +615,10 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const
|
|||
|
||||
renderArgs->_renderSide = RenderArgs::MONO;
|
||||
qApp->displaySide(renderArgs, *_camera, false);
|
||||
qApp->getApplicationOverlay().displayOverlayTextureHmd(*_camera);
|
||||
qApp->getApplicationOverlay().displayOverlayTextureHmd(renderArgs, *_camera);
|
||||
});
|
||||
_activeEye = ovrEye_Count;
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
gpu::FramebufferPointer finalFbo;
|
||||
//Bind the output texture from the glow shader. If glow effect is disabled, we just grab the texture
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
|
||||
|
@ -631,6 +629,7 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const
|
|||
finalFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "InterfaceConfig.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <GlowEffect.h>
|
||||
#include "gpu/GLBackend.h"
|
||||
|
@ -106,21 +107,20 @@ void TV3DManager::display(RenderArgs* renderArgs, Camera& whichCamera) {
|
|||
_activeEye = &eye;
|
||||
glViewport(portalX, portalY, portalW, portalH);
|
||||
glScissor(portalX, portalY, portalW, portalH);
|
||||
|
||||
glm::mat4 projection = glm::frustum<float>(eye.left, eye.right, eye.bottom, eye.top, nearZ, farZ);
|
||||
float fov = atan(1.0f / projection[1][1]);
|
||||
projection = glm::translate(projection, vec3(eye.modelTranslation, 0, 0));
|
||||
eyeCamera.setProjection(projection);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity(); // reset projection matrix
|
||||
glFrustum(eye.left, eye.right, eye.bottom, eye.top, nearZ, farZ); // set left view frustum
|
||||
GLfloat p[4][4];
|
||||
// Really?
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0]));
|
||||
float cotangent = p[1][1];
|
||||
GLfloat fov = atan(1.0f / cotangent);
|
||||
glTranslatef(eye.modelTranslation, 0.0, 0.0); // translate to cancel parallax
|
||||
|
||||
glLoadMatrixf(glm::value_ptr(projection));
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
renderArgs->_renderSide = RenderArgs::MONO;
|
||||
qApp->displaySide(renderArgs, eyeCamera, false);
|
||||
qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov);
|
||||
qApp->getApplicationOverlay().displayOverlayTexture(renderArgs);
|
||||
_activeEye = NULL;
|
||||
}, [&]{
|
||||
// render right side view
|
||||
|
|
|
@ -14,13 +14,16 @@
|
|||
#include <QOpenGLFramebufferObject>
|
||||
#include <QOpenGLTexture>
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <DeferredLightingEffect.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <PathUtils.h>
|
||||
#include <gpu/GLBackend.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <PerfStat.h>
|
||||
#include <OffscreenUi.h>
|
||||
#include <CursorManager.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "AudioClient.h"
|
||||
#include "audio/AudioIOStatsRenderer.h"
|
||||
|
@ -33,6 +36,9 @@
|
|||
#include "Util.h"
|
||||
#include "ui/Stats.h"
|
||||
|
||||
#include "../../libraries/render-utils/standardTransformPNTC_vert.h"
|
||||
#include "../../libraries/render-utils/standardDrawTexture_frag.h"
|
||||
|
||||
// Used to animate the magnification windows
|
||||
const float MAG_SPEED = 0.08f;
|
||||
|
||||
|
@ -114,27 +120,6 @@ bool raySphereIntersect(const glm::vec3 &dir, const glm::vec3 &origin, float r,
|
|||
}
|
||||
}
|
||||
|
||||
void ApplicationOverlay::renderReticle(glm::quat orientation, float alpha) {
|
||||
glPushMatrix(); {
|
||||
glm::vec3 axis = glm::axis(orientation);
|
||||
glRotatef(glm::degrees(glm::angle(orientation)), axis.x, axis.y, axis.z);
|
||||
glm::vec3 topLeft = getPoint(reticleSize / 2.0f, -reticleSize / 2.0f);
|
||||
glm::vec3 topRight = getPoint(-reticleSize / 2.0f, -reticleSize / 2.0f);
|
||||
glm::vec3 bottomLeft = getPoint(reticleSize / 2.0f, reticleSize / 2.0f);
|
||||
glm::vec3 bottomRight = getPoint(-reticleSize / 2.0f, reticleSize / 2.0f);
|
||||
|
||||
// TODO: this version of renderQuad() needs to take a color
|
||||
glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], alpha };
|
||||
|
||||
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomLeft, bottomRight, topRight,
|
||||
glm::vec2(0.0f, 0.0f), glm::vec2(1.0f, 0.0f),
|
||||
glm::vec2(1.0f, 1.0f), glm::vec2(0.0f, 1.0f),
|
||||
reticleColor, _reticleQuad);
|
||||
} glPopMatrix();
|
||||
}
|
||||
|
||||
ApplicationOverlay::ApplicationOverlay() :
|
||||
_textureFov(glm::radians(DEFAULT_HMD_UI_ANGULAR_SIZE)),
|
||||
_textureAspectRatio(1.0f),
|
||||
|
@ -148,7 +133,8 @@ ApplicationOverlay::ApplicationOverlay() :
|
|||
_previousMagnifierBottomLeft(),
|
||||
_previousMagnifierBottomRight(),
|
||||
_previousMagnifierTopLeft(),
|
||||
_previousMagnifierTopRight()
|
||||
_previousMagnifierTopRight(),
|
||||
_framebufferObject(nullptr)
|
||||
{
|
||||
memset(_reticleActive, 0, sizeof(_reticleActive));
|
||||
memset(_magActive, 0, sizeof(_reticleActive));
|
||||
|
@ -195,16 +181,17 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
|||
//Handle fading and deactivation/activation of UI
|
||||
|
||||
// Render 2D overlay
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
_overlays.buildFramebufferObject();
|
||||
_overlays.bind();
|
||||
buildFramebufferObject();
|
||||
|
||||
_framebufferObject->bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glViewport(0, 0, size.x, size.y);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix(); {
|
||||
const float NEAR_CLIP = -10000;
|
||||
const float FAR_CLIP = 10000;
|
||||
|
@ -226,6 +213,22 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
|||
renderPointers();
|
||||
|
||||
renderDomainConnectionStatusBorder();
|
||||
if (_newUiTexture) {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBindTexture(GL_TEXTURE_2D, _newUiTexture);
|
||||
DependencyManager::get<GeometryCache>()->renderUnitQuad();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
glLoadIdentity();
|
||||
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
} glPopMatrix();
|
||||
|
@ -235,258 +238,160 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
|||
glEnable(GL_LIGHTING);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
|
||||
_overlays.release();
|
||||
_framebufferObject->release();
|
||||
}
|
||||
|
||||
// A quick and dirty solution for compositing the old overlay
|
||||
// texture with the new one
|
||||
template <typename F>
|
||||
void with_each_texture(GLuint firstPassTexture, GLuint secondPassTexture, F f) {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
if (firstPassTexture) {
|
||||
glBindTexture(GL_TEXTURE_2D, firstPassTexture);
|
||||
f();
|
||||
gpu::PipelinePointer ApplicationOverlay::getDrawPipeline() {
|
||||
if (!_standardDrawPipeline) {
|
||||
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(standardTransformPNTC_vert)));
|
||||
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(standardDrawTexture_frag)));
|
||||
auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
|
||||
gpu::Shader::makeProgram((*program));
|
||||
|
||||
auto state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
// enable decal blend
|
||||
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
||||
|
||||
_standardDrawPipeline.reset(gpu::Pipeline::create(program, state));
|
||||
}
|
||||
if (secondPassTexture) {
|
||||
glBindTexture(GL_TEXTURE_2D, secondPassTexture);
|
||||
f();
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
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
|
||||
void ApplicationOverlay::displayOverlayTexture() {
|
||||
void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) {
|
||||
if (_alpha == 0.0f) {
|
||||
return;
|
||||
}
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix(); {
|
||||
glLoadIdentity();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glViewport(0, 0, qApp->getDeviceSize().width(), qApp->getDeviceSize().height());
|
||||
|
||||
renderArgs->_context->syncCache();
|
||||
|
||||
static const glm::vec2 topLeft(-1, 1);
|
||||
static const glm::vec2 bottomRight(1, -1);
|
||||
static const glm::vec2 texCoordTopLeft(0.0f, 1.0f);
|
||||
static const glm::vec2 texCoordBottomRight(1.0f, 0.0f);
|
||||
with_each_texture(_overlays.getTexture(), _newUiTexture, [&] {
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(
|
||||
topLeft, bottomRight,
|
||||
texCoordTopLeft, texCoordBottomRight,
|
||||
glm::vec4(1.0f, 1.0f, 1.0f, _alpha));
|
||||
});
|
||||
gpu::Batch batch;
|
||||
Transform model;
|
||||
//DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true);
|
||||
batch.setPipeline(getDrawPipeline());
|
||||
batch.setModelTransform(Transform());
|
||||
batch.setProjectionTransform(mat4());
|
||||
batch.setViewTransform(model);
|
||||
batch._glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture());
|
||||
batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
DependencyManager::get<GeometryCache>()->renderUnitQuad(batch, vec4(vec3(1), _alpha));
|
||||
|
||||
if (!_crosshairTexture) {
|
||||
_crosshairTexture = DependencyManager::get<TextureCache>()->
|
||||
getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png");
|
||||
}
|
||||
//draw the mouse pointer
|
||||
glm::vec2 canvasSize = qApp->getCanvasSize();
|
||||
|
||||
//draw the mouse pointer
|
||||
glm::vec2 canvasSize = qApp->getCanvasSize();
|
||||
glm::vec2 mouseSize = 32.0f / canvasSize;
|
||||
auto mouseTopLeft = topLeft * mouseSize;
|
||||
auto mouseBottomRight = bottomRight * mouseSize;
|
||||
vec2 mousePosition = vec2(qApp->getMouseX(), qApp->getMouseY());
|
||||
mousePosition /= canvasSize;
|
||||
mousePosition *= 2.0f;
|
||||
mousePosition -= 1.0f;
|
||||
mousePosition.y *= -1.0f;
|
||||
// Get the mouse coordinates and convert to NDC [-1, 1]
|
||||
vec2 mousePosition = vec2(qApp->getMouseX(), qApp->getMouseY());
|
||||
mousePosition /= canvasSize;
|
||||
mousePosition *= 2.0f;
|
||||
mousePosition -= 1.0f;
|
||||
mousePosition.y *= -1.0f;
|
||||
model.setTranslation(vec3(mousePosition, 0));
|
||||
glm::vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize;
|
||||
model.setScale(vec3(mouseSize, 1.0f));
|
||||
batch.setModelTransform(model);
|
||||
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);
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
||||
glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f };
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(
|
||||
mouseTopLeft + mousePosition, mouseBottomRight + mousePosition,
|
||||
texCoordTopLeft, texCoordBottomRight,
|
||||
reticleColor);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
} glPopMatrix();
|
||||
|
||||
static gpu::BufferPointer _hemiVertices;
|
||||
static gpu::BufferPointer _hemiIndices;
|
||||
static int _hemiIndexCount{ 0 };
|
||||
|
||||
glm::vec2 getPolarCoordinates(const PalmData& palm) {
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
auto avatarOrientation = myAvatar->getOrientation();
|
||||
auto eyePos = myAvatar->getDefaultEyePosition();
|
||||
glm::vec3 tip = myAvatar->getLaserPointerTipPosition(&palm);
|
||||
// Direction of the tip relative to the eye
|
||||
glm::vec3 tipDirection = tip - eyePos;
|
||||
// orient into avatar space
|
||||
tipDirection = glm::inverse(avatarOrientation) * tipDirection;
|
||||
// Normalize for trig functions
|
||||
tipDirection = glm::normalize(tipDirection);
|
||||
// Convert to polar coordinates
|
||||
glm::vec2 polar(glm::atan(tipDirection.x, -tipDirection.z), glm::asin(tipDirection.y));
|
||||
return polar;
|
||||
}
|
||||
|
||||
// Draws the FBO texture for Oculus rift.
|
||||
void ApplicationOverlay::displayOverlayTextureHmd(Camera& whichCamera) {
|
||||
void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera& whichCamera) {
|
||||
if (_alpha == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER, 0.01f);
|
||||
renderArgs->_context->syncCache();
|
||||
|
||||
gpu::Batch batch;
|
||||
batch.setPipeline(getDrawPipeline());
|
||||
batch._glDisable(GL_DEPTH_TEST);
|
||||
batch._glDisable(GL_CULL_FACE);
|
||||
batch._glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture());
|
||||
batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
batch.setProjectionTransform(whichCamera.getProjection());
|
||||
batch.setViewTransform(Transform());
|
||||
|
||||
//Update and draw the magnifiers
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
const glm::quat& orientation = myAvatar->getOrientation();
|
||||
// Always display the HMD overlay relative to the camera position but
|
||||
// remove the HMD pose offset. This results in an overlay that sticks with you
|
||||
// even in third person mode, but isn't drawn at a fixed distance.
|
||||
glm::vec3 position = whichCamera.getPosition();
|
||||
position -= qApp->getCamera()->getHmdPosition();
|
||||
const float scale = myAvatar->getScale() * _oculusUIRadius;
|
||||
|
||||
// glm::vec3 eyeOffset = setEyeOffsetPosition;
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); {
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glm::mat4 rotation = glm::toMat4(orientation);
|
||||
glMultMatrixf(&rotation[0][0]);
|
||||
glScalef(scale, scale, scale);
|
||||
for (int i = 0; i < NUMBER_OF_RETICLES; i++) {
|
||||
|
||||
if (_magActive[i]) {
|
||||
_magSizeMult[i] += MAG_SPEED;
|
||||
if (_magSizeMult[i] > 1.0f) {
|
||||
_magSizeMult[i] = 1.0f;
|
||||
}
|
||||
} else {
|
||||
_magSizeMult[i] -= MAG_SPEED;
|
||||
if (_magSizeMult[i] < 0.0f) {
|
||||
_magSizeMult[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (_magSizeMult[i] > 0.0f) {
|
||||
//Render magnifier, but dont show border for mouse magnifier
|
||||
glm::vec2 projection = screenToOverlay(glm::vec2(_reticlePosition[MOUSE].x(),
|
||||
_reticlePosition[MOUSE].y()));
|
||||
with_each_texture(_overlays.getTexture(), 0, [&] {
|
||||
renderMagnifier(projection, _magSizeMult[i], i != MOUSE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
static float textureFOV = 0.0f, textureAspectRatio = 1.0f;
|
||||
if (textureFOV != _textureFov ||
|
||||
textureAspectRatio != _textureAspectRatio) {
|
||||
textureFOV = _textureFov;
|
||||
textureAspectRatio = _textureAspectRatio;
|
||||
|
||||
_overlays.buildVBO(_textureFov, _textureAspectRatio, 80, 80);
|
||||
}
|
||||
const quat& avatarOrientation = myAvatar->getOrientation();
|
||||
quat hmdOrientation = qApp->getCamera()->getHmdRotation();
|
||||
vec3 hmdPosition = glm::inverse(avatarOrientation) * qApp->getCamera()->getHmdPosition();
|
||||
mat4 overlayXfm = glm::mat4_cast(glm::inverse(hmdOrientation)) * glm::translate(mat4(), -hmdPosition);
|
||||
batch.setModelTransform(Transform(overlayXfm));
|
||||
drawSphereSection(batch);
|
||||
|
||||
with_each_texture(_overlays.getTexture(), _newUiTexture, [&] {
|
||||
_overlays.render();
|
||||
});
|
||||
|
||||
if (!Application::getInstance()->isMouseHidden()) {
|
||||
renderPointersOculus();
|
||||
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];
|
||||
if (palm.isActive()) {
|
||||
glm::vec2 polar = getPolarCoordinates(palm);
|
||||
// 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, reticleScale);
|
||||
batch.setModelTransform(reticleXfm);
|
||||
// Render reticle at location
|
||||
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
|
||||
}
|
||||
glDepthMask(GL_TRUE);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
glEnable(GL_LIGHTING);
|
||||
} glPopMatrix();
|
||||
}
|
||||
|
||||
//Mouse Pointer
|
||||
if (_reticleActive[MOUSE]) {
|
||||
glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(),
|
||||
_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, reticleScale);
|
||||
batch.setModelTransform(reticleXfm);
|
||||
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
|
||||
}
|
||||
|
||||
renderArgs->_context->render(batch);
|
||||
}
|
||||
|
||||
// Draws the FBO texture for 3DTV.
|
||||
void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov) {
|
||||
if (_alpha == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
const glm::vec3& viewMatrixTranslation = qApp->getViewMatrixTranslation();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
// Transform to world space
|
||||
glm::quat rotation = whichCamera.getRotation();
|
||||
glm::vec3 axis2 = glm::axis(rotation);
|
||||
glRotatef(-glm::degrees(glm::angle(rotation)), axis2.x, axis2.y, axis2.z);
|
||||
glTranslatef(viewMatrixTranslation.x, viewMatrixTranslation.y, viewMatrixTranslation.z);
|
||||
|
||||
// Translate to the front of the camera
|
||||
glm::vec3 pos = whichCamera.getPosition();
|
||||
glm::quat rot = myAvatar->getOrientation();
|
||||
glm::vec3 axis = glm::axis(rot);
|
||||
|
||||
glTranslatef(pos.x, pos.y, pos.z);
|
||||
glRotatef(glm::degrees(glm::angle(rot)), axis.x, axis.y, axis.z);
|
||||
|
||||
glm::vec4 overlayColor = {1.0f, 1.0f, 1.0f, _alpha};
|
||||
|
||||
//Render
|
||||
const GLfloat distance = 1.0f;
|
||||
|
||||
const GLfloat halfQuadHeight = distance * tan(fov);
|
||||
const GLfloat halfQuadWidth = halfQuadHeight * aspectRatio;
|
||||
const GLfloat quadWidth = halfQuadWidth * 2.0f;
|
||||
const GLfloat quadHeight = halfQuadHeight * 2.0f;
|
||||
|
||||
GLfloat x = -halfQuadWidth;
|
||||
GLfloat y = -halfQuadHeight;
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
with_each_texture(_overlays.getTexture(), _newUiTexture, [&] {
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(glm::vec3(x, y + quadHeight, -distance),
|
||||
glm::vec3(x + quadWidth, y + quadHeight, -distance),
|
||||
glm::vec3(x + quadWidth, y, -distance),
|
||||
glm::vec3(x, y, -distance),
|
||||
glm::vec2(0.0f, 1.0f), glm::vec2(1.0f, 1.0f),
|
||||
glm::vec2(1.0f, 0.0f), glm::vec2(0.0f, 0.0f),
|
||||
overlayColor);
|
||||
});
|
||||
|
||||
if (!_crosshairTexture) {
|
||||
_crosshairTexture = TextureCache::getImageTexture(PathUtils::resourcesPath() +
|
||||
"images/sixense-reticle.png");
|
||||
}
|
||||
|
||||
//draw the mouse pointer
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
||||
glm::vec2 canvasSize = qApp->getCanvasSize();
|
||||
const float reticleSize = 40.0f / canvasSize.x * quadWidth;
|
||||
x -= reticleSize / 2.0f;
|
||||
y += reticleSize / 2.0f;
|
||||
const float mouseX = (qApp->getMouseX() / (float)canvasSize.x) * quadWidth;
|
||||
const float mouseY = (1.0 - (qApp->getMouseY() / (float)canvasSize.y)) * quadHeight;
|
||||
|
||||
glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f };
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(glm::vec3(x + mouseX, y + mouseY, -distance),
|
||||
glm::vec3(x + mouseX + reticleSize, y + mouseY, -distance),
|
||||
glm::vec3(x + mouseX + reticleSize, y + mouseY - reticleSize, -distance),
|
||||
glm::vec3(x + mouseX, y + mouseY - reticleSize, -distance),
|
||||
glm::vec2(0.0f, 0.0f), glm::vec2(1.0f, 0.0f),
|
||||
glm::vec2(1.0f, 1.0f), glm::vec2(0.0f, 1.0f),
|
||||
reticleColor, _reticleQuad);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
void ApplicationOverlay::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) const {
|
||||
cursorPos *= qApp->getCanvasSize();
|
||||
|
@ -516,22 +421,6 @@ void ApplicationOverlay::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origi
|
|||
direction = glm::normalize(intersectionWithUi - origin);
|
||||
}
|
||||
|
||||
glm::vec2 getPolarCoordinates(const PalmData& palm) {
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
auto avatarOrientation = myAvatar->getOrientation();
|
||||
auto eyePos = myAvatar->getDefaultEyePosition();
|
||||
glm::vec3 tip = myAvatar->getLaserPointerTipPosition(&palm);
|
||||
// Direction of the tip relative to the eye
|
||||
glm::vec3 tipDirection = tip - eyePos;
|
||||
// orient into avatar space
|
||||
tipDirection = glm::inverse(avatarOrientation) * tipDirection;
|
||||
// Normalize for trig functions
|
||||
tipDirection = glm::normalize(tipDirection);
|
||||
// Convert to polar coordinates
|
||||
glm::vec2 polar(glm::atan(tipDirection.x, -tipDirection.z), glm::asin(tipDirection.y));
|
||||
return polar;
|
||||
}
|
||||
|
||||
//Caculate the click location using one of the sixense controllers. Scale is not applied
|
||||
QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const {
|
||||
QPoint rv;
|
||||
|
@ -582,13 +471,9 @@ 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/sixense-reticle.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);
|
||||
//bindCursorTexture();
|
||||
|
@ -750,43 +635,6 @@ void ApplicationOverlay::renderControllerPointers() {
|
|||
}
|
||||
}
|
||||
|
||||
void ApplicationOverlay::renderPointersOculus() {
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
//Controller Pointers
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
|
||||
PalmData& palm = myAvatar->getHand()->getPalms()[i];
|
||||
if (palm.isActive()) {
|
||||
glm::vec2 polar = getPolarCoordinates(palm);
|
||||
// Convert to quaternion
|
||||
glm::quat orientation = glm::quat(glm::vec3(polar.y, -polar.x, 0.0f));
|
||||
// Render reticle at location
|
||||
renderReticle(orientation, _alpha);
|
||||
}
|
||||
}
|
||||
|
||||
//Mouse Pointer
|
||||
if (_reticleActive[MOUSE]) {
|
||||
glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(),
|
||||
_reticlePosition[MOUSE].y()));
|
||||
glm::quat orientation(glm::vec3(-projection.y, projection.x, 0.0f));
|
||||
renderReticle(orientation, _alpha);
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
//Renders a small magnification of the currently bound texture at the coordinates
|
||||
void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder) {
|
||||
if (!_magnifier) {
|
||||
|
@ -1067,119 +915,109 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() {
|
|||
}
|
||||
}
|
||||
|
||||
ApplicationOverlay::TexturedHemisphere::TexturedHemisphere() :
|
||||
_vertices(0),
|
||||
_indices(0),
|
||||
_framebufferObject(NULL),
|
||||
_vbo(0, 0) {
|
||||
}
|
||||
|
||||
ApplicationOverlay::TexturedHemisphere::~TexturedHemisphere() {
|
||||
cleanupVBO();
|
||||
if (_framebufferObject != NULL) {
|
||||
delete _framebufferObject;
|
||||
void ApplicationOverlay::buildHemiVertices(
|
||||
const float fov, const float aspectRatio, const int slices, const int stacks) {
|
||||
static float textureFOV = 0.0f, textureAspectRatio = 1.0f;
|
||||
if (textureFOV == fov && textureAspectRatio == aspectRatio) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationOverlay::TexturedHemisphere::bind() {
|
||||
_framebufferObject->bind();
|
||||
}
|
||||
textureFOV = fov;
|
||||
textureAspectRatio = aspectRatio;
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
|
||||
_hemiVertices = gpu::BufferPointer(new gpu::Buffer());
|
||||
_hemiIndices = gpu::BufferPointer(new gpu::Buffer());
|
||||
|
||||
void ApplicationOverlay::TexturedHemisphere::release() {
|
||||
_framebufferObject->release();
|
||||
}
|
||||
|
||||
void ApplicationOverlay::TexturedHemisphere::buildVBO(const float fov,
|
||||
const float aspectRatio,
|
||||
const int slices,
|
||||
const int stacks) {
|
||||
if (fov >= PI) {
|
||||
qDebug() << "TexturedHemisphere::buildVBO(): FOV greater or equal than Pi will create issues";
|
||||
}
|
||||
// Cleanup old VBO if necessary
|
||||
cleanupVBO();
|
||||
|
||||
|
||||
//UV mapping source: http://www.mvps.org/directx/articles/spheremap.htm
|
||||
|
||||
// Compute number of vertices needed
|
||||
_vertices = slices * stacks;
|
||||
|
||||
vec3 pos;
|
||||
vec2 uv;
|
||||
// Compute vertices positions and texture UV coordinate
|
||||
TextureVertex* vertexData = new TextureVertex[_vertices];
|
||||
TextureVertex* vertexPtr = &vertexData[0];
|
||||
// Create and write to buffer
|
||||
for (int i = 0; i < stacks; i++) {
|
||||
float stacksRatio = (float)i / (float)(stacks - 1); // First stack is 0.0f, last stack is 1.0f
|
||||
uv.y = (float)i / (float)(stacks - 1); // First stack is 0.0f, last stack is 1.0f
|
||||
// abs(theta) <= fov / 2.0f
|
||||
float pitch = -fov * (stacksRatio - 0.5f);
|
||||
|
||||
float pitch = -fov * (uv.y - 0.5f);
|
||||
for (int j = 0; j < slices; j++) {
|
||||
float slicesRatio = (float)j / (float)(slices - 1); // First slice is 0.0f, last slice is 1.0f
|
||||
uv.x = (float)j / (float)(slices - 1); // First slice is 0.0f, last slice is 1.0f
|
||||
// abs(phi) <= fov * aspectRatio / 2.0f
|
||||
float yaw = -fov * aspectRatio * (slicesRatio - 0.5f);
|
||||
|
||||
vertexPtr->position = getPoint(yaw, pitch);
|
||||
vertexPtr->uv.x = slicesRatio;
|
||||
vertexPtr->uv.y = stacksRatio;
|
||||
vertexPtr++;
|
||||
float yaw = -fov * aspectRatio * (uv.x - 0.5f);
|
||||
pos = getPoint(yaw, pitch);
|
||||
static const vec4 color(1);
|
||||
_hemiVertices->append(sizeof(pos), (gpu::Byte*)&pos);
|
||||
_hemiVertices->append(sizeof(vec2), (gpu::Byte*)&uv);
|
||||
_hemiVertices->append(sizeof(vec4), (gpu::Byte*)&color);
|
||||
}
|
||||
}
|
||||
// Create and write to buffer
|
||||
glGenBuffers(1, &_vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo.first);
|
||||
static const int BYTES_PER_VERTEX = sizeof(TextureVertex);
|
||||
glBufferData(GL_ARRAY_BUFFER, _vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
|
||||
// Compute number of indices needed
|
||||
static const int VERTEX_PER_TRANGLE = 3;
|
||||
static const int TRIANGLE_PER_RECTANGLE = 2;
|
||||
int numberOfRectangles = (slices - 1) * (stacks - 1);
|
||||
_indices = numberOfRectangles * TRIANGLE_PER_RECTANGLE * VERTEX_PER_TRANGLE;
|
||||
_hemiIndexCount = numberOfRectangles * TRIANGLE_PER_RECTANGLE * VERTEX_PER_TRANGLE;
|
||||
|
||||
// Compute indices order
|
||||
GLushort* indexData = new GLushort[_indices];
|
||||
GLushort* indexPtr = indexData;
|
||||
std::vector<GLushort> indices;
|
||||
for (int i = 0; i < stacks - 1; i++) {
|
||||
for (int j = 0; j < slices - 1; j++) {
|
||||
GLushort bottomLeftIndex = i * slices + j;
|
||||
GLushort bottomRightIndex = bottomLeftIndex + 1;
|
||||
GLushort topLeftIndex = bottomLeftIndex + slices;
|
||||
GLushort topRightIndex = topLeftIndex + 1;
|
||||
|
||||
*(indexPtr++) = topLeftIndex;
|
||||
*(indexPtr++) = bottomLeftIndex;
|
||||
*(indexPtr++) = topRightIndex;
|
||||
|
||||
*(indexPtr++) = topRightIndex;
|
||||
*(indexPtr++) = bottomLeftIndex;
|
||||
*(indexPtr++) = bottomRightIndex;
|
||||
// FIXME make a z-order curve for better vertex cache locality
|
||||
indices.push_back(topLeftIndex);
|
||||
indices.push_back(bottomLeftIndex);
|
||||
indices.push_back(topRightIndex);
|
||||
|
||||
indices.push_back(topRightIndex);
|
||||
indices.push_back(bottomLeftIndex);
|
||||
indices.push_back(bottomRightIndex);
|
||||
}
|
||||
}
|
||||
// Create and write to buffer
|
||||
glGenBuffers(1, &_vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vbo.second);
|
||||
static const int BYTES_PER_INDEX = sizeof(GLushort);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices * BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
_hemiIndices->append(sizeof(GLushort) * indices.size(), (gpu::Byte*)&indices[0]);
|
||||
}
|
||||
|
||||
void ApplicationOverlay::TexturedHemisphere::cleanupVBO() {
|
||||
if (_vbo.first != 0) {
|
||||
glDeleteBuffers(1, &_vbo.first);
|
||||
_vbo.first = 0;
|
||||
}
|
||||
if (_vbo.second != 0) {
|
||||
glDeleteBuffers(1, &_vbo.second);
|
||||
_vbo.second = 0;
|
||||
}
|
||||
|
||||
void ApplicationOverlay::drawSphereSection(gpu::Batch& batch) {
|
||||
buildHemiVertices(_textureFov, _textureAspectRatio, 80, 80);
|
||||
static const int VERTEX_DATA_SLOT = 0;
|
||||
static const int TEXTURE_DATA_SLOT = 1;
|
||||
static const int COLOR_DATA_SLOT = 2;
|
||||
gpu::Stream::FormatPointer streamFormat(new gpu::Stream::Format()); // 1 for everyone
|
||||
streamFormat->setAttribute(gpu::Stream::POSITION, VERTEX_DATA_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||
streamFormat->setAttribute(gpu::Stream::TEXCOORD, TEXTURE_DATA_SLOT, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
|
||||
streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_DATA_SLOT, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::RGBA));
|
||||
batch.setInputFormat(streamFormat);
|
||||
|
||||
static const int VERTEX_STRIDE = sizeof(vec3) + sizeof(vec2) + sizeof(vec4);
|
||||
gpu::BufferView posView(_hemiVertices, 0, _hemiVertices->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::POSITION)._element);
|
||||
gpu::BufferView uvView(_hemiVertices, sizeof(vec3), _hemiVertices->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::TEXCOORD)._element);
|
||||
gpu::BufferView colView(_hemiVertices, sizeof(vec3) + sizeof(vec2), _hemiVertices->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::COLOR)._element);
|
||||
batch.setInputBuffer(VERTEX_DATA_SLOT, posView);
|
||||
batch.setInputBuffer(TEXTURE_DATA_SLOT, uvView);
|
||||
batch.setInputBuffer(COLOR_DATA_SLOT, colView);
|
||||
batch.setIndexBuffer(gpu::UINT16, _hemiIndices, 0);
|
||||
batch.drawIndexed(gpu::TRIANGLES, _hemiIndexCount);
|
||||
}
|
||||
|
||||
void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() {
|
||||
|
||||
GLuint ApplicationOverlay::getOverlayTexture() {
|
||||
return _framebufferObject->texture();
|
||||
}
|
||||
|
||||
void ApplicationOverlay::buildFramebufferObject() {
|
||||
auto canvasSize = qApp->getCanvasSize();
|
||||
QSize fboSize = QSize(canvasSize.x, canvasSize.y);
|
||||
if (_framebufferObject != NULL && fboSize == _framebufferObject->size()) {
|
||||
// Already build
|
||||
// Already built
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1188,7 +1026,7 @@ void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() {
|
|||
}
|
||||
|
||||
_framebufferObject = new QOpenGLFramebufferObject(fboSize, QOpenGLFramebufferObject::Depth);
|
||||
glBindTexture(GL_TEXTURE_2D, getTexture());
|
||||
glBindTexture(GL_TEXTURE_2D, getOverlayTexture());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
|
@ -1198,38 +1036,6 @@ void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() {
|
|||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
//Renders a hemisphere with texture coordinates.
|
||||
void ApplicationOverlay::TexturedHemisphere::render() {
|
||||
if (_framebufferObject == NULL || _vbo.first == 0 || _vbo.second == 0) {
|
||||
qDebug() << "TexturedHemisphere::render(): Incorrect initialisation";
|
||||
return;
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo.first);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vbo.second);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
static const int STRIDE = sizeof(TextureVertex);
|
||||
static const void* VERTEX_POINTER = 0;
|
||||
static const void* TEX_COORD_POINTER = (void*)sizeof(glm::vec3);
|
||||
glVertexPointer(3, GL_FLOAT, STRIDE, VERTEX_POINTER);
|
||||
glTexCoordPointer(2, GL_FLOAT, STRIDE, TEX_COORD_POINTER);
|
||||
|
||||
glDrawRangeElements(GL_TRIANGLES, 0, _vertices - 1, _indices, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
GLuint ApplicationOverlay::TexturedHemisphere::getTexture() {
|
||||
return _framebufferObject->texture();
|
||||
}
|
||||
|
||||
glm::vec2 ApplicationOverlay::directionToSpherical(const glm::vec3& direction) {
|
||||
glm::vec2 result;
|
||||
// Compute yaw
|
||||
|
|
|
@ -33,9 +33,9 @@ public:
|
|||
~ApplicationOverlay();
|
||||
|
||||
void renderOverlay(RenderArgs* renderArgs);
|
||||
void displayOverlayTexture();
|
||||
void displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov);
|
||||
void displayOverlayTextureHmd(Camera& whichCamera);
|
||||
void displayOverlayTexture(RenderArgs* renderArgs);
|
||||
void displayOverlayTextureStereo(RenderArgs* renderArgs, Camera& whichCamera, float aspectRatio, float fov);
|
||||
void displayOverlayTextureHmd(RenderArgs* renderArgs, Camera& whichCamera);
|
||||
|
||||
QPoint getPalmClickLocation(const PalmData *palm) const;
|
||||
bool calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const;
|
||||
|
@ -59,6 +59,7 @@ public:
|
|||
glm::vec2 screenToOverlay(const glm::vec2 & screenPos) const;
|
||||
glm::vec2 overlayToScreen(const glm::vec2 & overlayPos) const;
|
||||
void computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) const;
|
||||
GLuint getOverlayTexture();
|
||||
|
||||
static glm::vec2 directionToSpherical(const glm::vec3 & direction);
|
||||
static glm::vec3 sphericalToDirection(const glm::vec2 & sphericalPos);
|
||||
|
@ -66,38 +67,12 @@ public:
|
|||
static glm::vec2 sphericalToScreen(const glm::vec2 & sphericalPos);
|
||||
|
||||
private:
|
||||
// Interleaved vertex data
|
||||
struct TextureVertex {
|
||||
glm::vec3 position;
|
||||
glm::vec2 uv;
|
||||
};
|
||||
|
||||
typedef QPair<GLuint, GLuint> VerticesIndices;
|
||||
class TexturedHemisphere {
|
||||
public:
|
||||
TexturedHemisphere();
|
||||
~TexturedHemisphere();
|
||||
|
||||
void bind();
|
||||
void release();
|
||||
GLuint getTexture();
|
||||
|
||||
void buildFramebufferObject();
|
||||
void buildVBO(const float fov, const float aspectRatio, const int slices, const int stacks);
|
||||
void render();
|
||||
|
||||
private:
|
||||
void cleanupVBO();
|
||||
|
||||
GLuint _vertices;
|
||||
GLuint _indices;
|
||||
QOpenGLFramebufferObject* _framebufferObject;
|
||||
VerticesIndices _vbo;
|
||||
};
|
||||
|
||||
void buildHemiVertices(const float fov, const float aspectRatio, const int slices, const int stacks);
|
||||
void drawSphereSection(gpu::Batch& batch);
|
||||
float _hmdUIAngularSize = DEFAULT_HMD_UI_ANGULAR_SIZE;
|
||||
void renderReticle(glm::quat orientation, float alpha);
|
||||
void renderPointers();;
|
||||
QOpenGLFramebufferObject* _framebufferObject;
|
||||
|
||||
void renderPointers();
|
||||
void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder);
|
||||
|
||||
void renderControllerPointers();
|
||||
|
@ -109,10 +84,12 @@ private:
|
|||
void renderDomainConnectionStatusBorder();
|
||||
void bindCursorTexture(gpu::Batch& batch, uint8_t cursorId = 0);
|
||||
|
||||
TexturedHemisphere _overlays;
|
||||
void buildFramebufferObject();
|
||||
|
||||
float _textureFov;
|
||||
float _textureAspectRatio;
|
||||
int _hemiVerticesID{ GeometryCache::UNKNOWN_ID };
|
||||
|
||||
|
||||
enum Reticles { MOUSE, LEFT_CONTROLLER, RIGHT_CONTROLLER, NUMBER_OF_RETICLES };
|
||||
bool _reticleActive[NUMBER_OF_RETICLES];
|
||||
|
@ -125,8 +102,6 @@ private:
|
|||
float _alpha = 1.0f;
|
||||
float _oculusUIRadius;
|
||||
float _trailingAudioLoudness;
|
||||
|
||||
gpu::TexturePointer _crosshairTexture;
|
||||
|
||||
|
||||
QMap<uint16_t, gpu::TexturePointer> _cursors;
|
||||
|
@ -149,6 +124,10 @@ private:
|
|||
glm::vec3 _previousMagnifierTopLeft;
|
||||
glm::vec3 _previousMagnifierTopRight;
|
||||
|
||||
gpu::PipelinePointer _standardDrawPipeline;
|
||||
|
||||
gpu::PipelinePointer getDrawPipeline();
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_ApplicationOverlay_h
|
||||
|
|
|
@ -1179,6 +1179,21 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
batch.draw(gpu::QUADS, 4, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderUnitQuad(const glm::vec4& color, int id) {
|
||||
gpu::Batch batch;
|
||||
renderUnitQuad(batch, color, id);
|
||||
gpu::GLBackend::renderBatch(batch);
|
||||
}
|
||||
|
||||
void GeometryCache::renderUnitQuad(gpu::Batch& batch, const glm::vec4& color, int id) {
|
||||
static const glm::vec2 topLeft(-1, 1);
|
||||
static const glm::vec2 bottomRight(1, -1);
|
||||
static const glm::vec2 texCoordTopLeft(0.0f, 1.0f);
|
||||
static const glm::vec2 texCoordBottomRight(1.0f, 0.0f);
|
||||
renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color, id);
|
||||
}
|
||||
|
||||
|
||||
void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner,
|
||||
const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner,
|
||||
const glm::vec4& color, int id) {
|
||||
|
|
|
@ -155,6 +155,9 @@ public:
|
|||
void renderBevelCornersRect(int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id = UNKNOWN_ID);
|
||||
void renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id = UNKNOWN_ID);
|
||||
|
||||
void renderUnitQuad(const glm::vec4& color = glm::vec4(1), int id = UNKNOWN_ID);
|
||||
void renderUnitQuad(gpu::Batch& batch, const glm::vec4& color = glm::vec4(1), int id = UNKNOWN_ID);
|
||||
|
||||
void renderQuad(int x, int y, int width, int height, const glm::vec4& color, int id = UNKNOWN_ID)
|
||||
{ renderQuad(glm::vec2(x,y), glm::vec2(x + width, y + height), color, id); }
|
||||
void renderQuad(gpu::Batch& batch, int x, int y, int width, int height, const glm::vec4& color, int id = UNKNOWN_ID)
|
||||
|
|
24
libraries/render-utils/src/standardDrawTexture.slf
Normal file
24
libraries/render-utils/src/standardDrawTexture.slf
Normal file
|
@ -0,0 +1,24 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// standardDrawTexture.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Sam Gateau on 6/10/15.
|
||||
// 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
|
||||
//
|
||||
|
||||
// the texture
|
||||
uniform sampler2D colorMap;
|
||||
|
||||
varying vec2 varTexcoord;
|
||||
varying vec4 varColor;
|
||||
|
||||
|
||||
void main(void) {
|
||||
vec4 color = texture2D(colorMap, varTexcoord);
|
||||
gl_FragColor = color * varColor;
|
||||
}
|
33
libraries/render-utils/src/standardTransformPNTC.slv
Normal file
33
libraries/render-utils/src/standardTransformPNTC.slv
Normal file
|
@ -0,0 +1,33 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// standardTransformPNTC.slv
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Sam Gateau on 6/10/2015.
|
||||
// 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 gpu/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
varying vec3 varNormal;
|
||||
varying vec2 varTexcoord;
|
||||
varying vec4 varColor;
|
||||
|
||||
void main(void) {
|
||||
varTexcoord = gl_MultiTexCoord0.xy;
|
||||
varColor = gl_Color;
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$>
|
||||
<$transformModelToEyeDir(cam, obj, gl_Normal, varNormal)$>
|
||||
varNormal = normalize(varNormal);
|
||||
}
|
Loading…
Reference in a new issue