From 94c414e4e86ed32a5ebc68f673d3d48c41b9d117 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 10 Jun 2015 08:12:58 -0700 Subject: [PATCH 1/8] Add unit quad, commonly used in compositing the overlays --- libraries/render-utils/src/GeometryCache.cpp | 15 +++++++++++++++ libraries/render-utils/src/GeometryCache.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 303d63bef8..3066fd4890 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -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) { diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index b438eb2d3b..76e03f8669 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -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) From 7374fb84e896a046361aee080f23459e25bd9921 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 10 Jun 2015 09:36:14 -0700 Subject: [PATCH 2/8] Working on fixing overlays with team-teaching merge --- interface/src/Application.cpp | 2 +- interface/src/devices/OculusManager.cpp | 29 ++- interface/src/devices/TV3DManager.cpp | 2 +- interface/src/ui/ApplicationOverlay.cpp | 313 ++++++++++++------------ interface/src/ui/ApplicationOverlay.h | 21 +- 5 files changed, 198 insertions(+), 169 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1763623fa6..9d5c43b7cf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -958,7 +958,7 @@ void Application::paintGL() { GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - _applicationOverlay.displayOverlayTexture(); + _applicationOverlay.displayOverlayTexture(&renderArgs); } if (!OculusManager::isConnected() || OculusManager::allowSwap()) { diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index a7383ae4bb..77263935f6 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -615,12 +615,9 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const renderArgs->_renderSide = RenderArgs::MONO; qApp->displaySide(renderArgs, *_camera, false); - qApp->getApplicationOverlay().displayOverlayTextureHmd(*_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)) { @@ -632,9 +629,35 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const glBindFramebuffer(GL_FRAMEBUFFER, 0); } + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); + //Render each eye into an fbo + for_each_eye(_ovrHmd, [&](ovrEyeType eye) { + _activeEye = eye; + // Update our camera to what the application camera is doing + _camera->setRotation(toGlm(eyeRenderPose[eye].Orientation)); + _camera->setPosition(toGlm(eyeRenderPose[eye].Position)); + configureCamera(*_camera); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(glm::value_ptr(_camera->getProjection())); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + ovrRecti & vp = _eyeTextures[eye].Header.RenderViewport; + vp.Size.h = _recommendedTexSize.h * _offscreenRenderScale; + vp.Size.w = _recommendedTexSize.w * _offscreenRenderScale; + + glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h); + qApp->getApplicationOverlay().displayOverlayTextureHmd(renderArgs, *_camera); + }); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); glPopMatrix(); + // restore our normal viewport glViewport(0, 0, deviceSize.width(), deviceSize.height()); diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 09edb03e5a..c14e589389 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -120,7 +120,7 @@ void TV3DManager::display(RenderArgs* renderArgs, Camera& whichCamera) { glLoadIdentity(); renderArgs->_renderSide = RenderArgs::MONO; qApp->displaySide(renderArgs, eyeCamera, false); - qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov); + qApp->getApplicationOverlay().displayOverlayTextureStereo(renderArgs, whichCamera, _aspect, fov); _activeEye = NULL; }, [&]{ // render right side view diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index bc8047fc98..79ec39b506 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -14,13 +14,16 @@ #include #include +#include + #include +#include #include -#include #include #include -#include #include +#include +#include #include "AudioClient.h" #include "audio/AudioIOStatsRenderer.h" @@ -149,7 +152,8 @@ ApplicationOverlay::ApplicationOverlay() : _previousMagnifierBottomLeft(), _previousMagnifierBottomRight(), _previousMagnifierTopLeft(), - _previousMagnifierTopRight() + _previousMagnifierTopRight(), + _framebufferObject(nullptr) { memset(_reticleActive, 0, sizeof(_reticleActive)); memset(_magActive, 0, sizeof(_reticleActive)); @@ -196,16 +200,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; @@ -227,6 +232,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()->renderUnitQuad(); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + } + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); } glPopMatrix(); @@ -236,166 +257,159 @@ 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 -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(); - } - if (secondPassTexture) { - glBindTexture(GL_TEXTURE_2D, secondPassTexture); - f(); - } - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); -} +//template +//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(); +// } +// //if (secondPassTexture) { +// // glBindTexture(GL_TEXTURE_2D, secondPassTexture); +// // f(); +// //} +// glBindTexture(GL_TEXTURE_2D, 0); +// glDisable(GL_TEXTURE_2D); +//} // Draws the FBO texture for the screen -void ApplicationOverlay::displayOverlayTexture() { +void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { + if (_alpha == 0.0f) { return; } + + if (!_crosshairTexture) { + _crosshairTexture = TextureCache::getImageTexture( + PathUtils::resourcesPath() + "images/sixense-reticle.png"); + } + + /* + FIXME - doesn't work + renderArgs->_context->syncCache(); + gpu::Batch batch; + DependencyManager::get()->bindSimpleProgram(batch, true); + batch.setModelTransform(Transform()); + batch.setProjectionTransform(mat4()); + batch.setViewTransform(Transform()); + batch.setUniformTexture(0, _crosshairTexture); + DependencyManager::get()->renderUnitQuad(batch, vec4(vec3(1), _alpha)); + renderArgs->_context->render(batch); + return; + */ + + + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_TEXTURE_2D); + glViewport(0, 0, qApp->getDeviceSize().width(), qApp->getDeviceSize().height()); + 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()); - - 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()->renderQuad( - topLeft, bottomRight, - texCoordTopLeft, texCoordBottomRight, - glm::vec4(1.0f, 1.0f, 1.0f, _alpha)); - }); - - if (!_crosshairTexture) { - _crosshairTexture = DependencyManager::get()-> - getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png"); - } - + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + { + glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture()); + DependencyManager::get()->renderUnitQuad(vec4(vec3(1), _alpha)); //draw the mouse pointer glm::vec2 canvasSize = qApp->getCanvasSize(); - glm::vec2 mouseSize = 32.0f / canvasSize; - auto mouseTopLeft = topLeft * mouseSize; - auto mouseBottomRight = bottomRight * mouseSize; + + // 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; + mat4 mouseMv = glm::translate(mat4(), vec3(mousePosition, 0)); - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // Scale the mouse based on the canvasSize (NOT the device size, + // we don't want a smaller mouse on retina displays) + glm::vec2 mouseSize = 32.0f / canvasSize; + mouseMv = glm::scale(mouseMv, vec3(mouseSize, 1.0f)); + + // Push the resulting matrix into modelview + glLoadMatrixf(glm::value_ptr(mouseMv)); glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture)); glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f }; - DependencyManager::get()->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(); + DependencyManager::get()->renderUnitQuad(reticleColor); + } + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); } // 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); + _overlays.buildVBO(_textureFov, _textureAspectRatio, 80, 80); + glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.01f); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + // The camera here contains only the head pose relative to the avatar position + vec3 pos = whichCamera.getPosition(); + quat rot = whichCamera.getOrientation(); + mat4 overlayXfm = glm::translate(glm::mat4(), pos) * glm::mat4_cast(rot); + glLoadMatrixf(glm::value_ptr(glm::inverse(overlayXfm))); + glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture()); + _overlays.render(); //Update and draw the magnifiers + /* + // FIXME Mangifiers need to be re-thought MyAvatar* myAvatar = DependencyManager::get()->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; - } + overlayXfm = glm::scale(overlayXfm, vec3(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; } - - 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); - }); + } else { + _magSizeMult[i] -= MAG_SPEED; + if (_magSizeMult[i] < 0.0f) { + _magSizeMult[i] = 0.0f; } } - - 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); + 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); + }); } + } + */ - with_each_texture(_overlays.getTexture(), _newUiTexture, [&] { - _overlays.render(); - }); - - if (!Application::getInstance()->isMouseHidden()) { - renderPointersOculus(); - } - 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(); + if (!Application::getInstance()->isMouseHidden()) { + renderPointersOculus(); + } } // Draws the FBO texture for 3DTV. -void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov) { +void ApplicationOverlay::displayOverlayTextureStereo(RenderArgs* renderArgs, Camera& whichCamera, float aspectRatio, float fov) { if (_alpha == 0.0f) { return; } @@ -440,15 +454,15 @@ void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float GLfloat y = -halfQuadHeight; glDisable(GL_DEPTH_TEST); - with_each_texture(_overlays.getTexture(), _newUiTexture, [&] { - DependencyManager::get()->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); - }); + //with_each_texture(_framebufferObject->texture(), _newUiTexture, [&] { + // DependencyManager::get()->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() + @@ -1071,29 +1085,24 @@ 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::TexturedHemisphere::bind() { - _framebufferObject->bind(); -} - -void ApplicationOverlay::TexturedHemisphere::release() { - _framebufferObject->release(); } void ApplicationOverlay::TexturedHemisphere::buildVBO(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; + } + textureFOV = fov; + textureAspectRatio = aspectRatio; + if (fov >= PI) { qDebug() << "TexturedHemisphere::buildVBO(): FOV greater or equal than Pi will create issues"; } @@ -1176,7 +1185,11 @@ void ApplicationOverlay::TexturedHemisphere::cleanupVBO() { } } -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()) { @@ -1189,7 +1202,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); @@ -1201,7 +1214,7 @@ void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() { //Renders a hemisphere with texture coordinates. void ApplicationOverlay::TexturedHemisphere::render() { - if (_framebufferObject == NULL || _vbo.first == 0 || _vbo.second == 0) { + if (_vbo.first == 0 || _vbo.second == 0) { qDebug() << "TexturedHemisphere::render(): Incorrect initialisation"; return; } @@ -1227,10 +1240,6 @@ void ApplicationOverlay::TexturedHemisphere::render() { 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 diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index ee82c9274a..36161dd29d 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -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); @@ -77,12 +78,6 @@ private: 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(); @@ -91,14 +86,14 @@ private: GLuint _vertices; GLuint _indices; - QOpenGLFramebufferObject* _framebufferObject; VerticesIndices _vbo; }; float _hmdUIAngularSize = DEFAULT_HMD_UI_ANGULAR_SIZE; - + QOpenGLFramebufferObject* _framebufferObject; + void renderReticle(glm::quat orientation, float alpha); - void renderPointers();; + void renderPointers(); void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder); void renderControllerPointers(); @@ -109,6 +104,8 @@ private: void renderStatsAndLogs(); void renderDomainConnectionStatusBorder(); + void buildFramebufferObject(); + TexturedHemisphere _overlays; float _textureFov; From 1f62fb4b6fbe33f090dc072dd3b0e15efc5b6d2d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 10 Jun 2015 15:24:29 -0700 Subject: [PATCH 3/8] Adding standard vertex and pixel shaders for drawing texture in applicationOverlay --- interface/src/ui/ApplicationOverlay.cpp | 30 ++++++++++++++--- interface/src/ui/ApplicationOverlay.h | 4 +++ .../render-utils/src/standardDrawTexture.slf | 24 ++++++++++++++ .../src/standardTransformPNTC.slv | 33 +++++++++++++++++++ 4 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 libraries/render-utils/src/standardDrawTexture.slf create mode 100644 libraries/render-utils/src/standardTransformPNTC.slv diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 79ec39b506..f57c10b64e 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -36,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; @@ -278,6 +281,24 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { // glDisable(GL_TEXTURE_2D); //} +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)); + } + + return _standardDrawPipeline; +} + // Draws the FBO texture for the screen void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { @@ -290,11 +311,12 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { PathUtils::resourcesPath() + "images/sixense-reticle.png"); } - /* - FIXME - doesn't work + + //FIXME - doesn't work renderArgs->_context->syncCache(); gpu::Batch batch; - DependencyManager::get()->bindSimpleProgram(batch, true); + //DependencyManager::get()->bindSimpleProgram(batch, true); + batch.setPipeline(getDrawPipeline()); batch.setModelTransform(Transform()); batch.setProjectionTransform(mat4()); batch.setViewTransform(Transform()); @@ -302,7 +324,7 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { DependencyManager::get()->renderUnitQuad(batch, vec4(vec3(1), _alpha)); renderArgs->_context->render(batch); return; - */ + glDisable(GL_DEPTH_TEST); diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index 36161dd29d..63ef48bd92 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -143,6 +143,10 @@ private: glm::vec3 _previousMagnifierTopLeft; glm::vec3 _previousMagnifierTopRight; + gpu::PipelinePointer _standardDrawPipeline; + + gpu::PipelinePointer getDrawPipeline(); + }; #endif // hifi_ApplicationOverlay_h diff --git a/libraries/render-utils/src/standardDrawTexture.slf b/libraries/render-utils/src/standardDrawTexture.slf new file mode 100644 index 0000000000..4fbeb6eb7f --- /dev/null +++ b/libraries/render-utils/src/standardDrawTexture.slf @@ -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; +} diff --git a/libraries/render-utils/src/standardTransformPNTC.slv b/libraries/render-utils/src/standardTransformPNTC.slv new file mode 100644 index 0000000000..fd2c28049f --- /dev/null +++ b/libraries/render-utils/src/standardTransformPNTC.slv @@ -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); +} \ No newline at end of file From ac0fc5d97405ec304bab0f15e18773dab2556d7c Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 11 Jun 2015 00:50:24 -0700 Subject: [PATCH 4/8] Working on oculus overlay code --- interface/src/ui/ApplicationOverlay.cpp | 235 ++++++++++++------------ interface/src/ui/ApplicationOverlay.h | 28 +-- 2 files changed, 117 insertions(+), 146 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index f57c10b64e..4be47e342a 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -301,7 +301,6 @@ gpu::PipelinePointer ApplicationOverlay::getDrawPipeline() { // Draws the FBO texture for the screen void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { - if (_alpha == 0.0f) { return; } @@ -312,80 +311,77 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { } - //FIXME - doesn't work renderArgs->_context->syncCache(); + glViewport(0, 0, qApp->getDeviceSize().width(), qApp->getDeviceSize().height()); + gpu::Batch batch; + Transform model; //DependencyManager::get()->bindSimpleProgram(batch, true); batch.setPipeline(getDrawPipeline()); batch.setModelTransform(Transform()); batch.setProjectionTransform(mat4()); - batch.setViewTransform(Transform()); - batch.setUniformTexture(0, _crosshairTexture); + 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()->renderUnitQuad(batch, vec4(vec3(1), _alpha)); + + //draw the mouse pointer + glm::vec2 canvasSize = qApp->getCanvasSize(); + + // 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 = 32.0f / canvasSize; + model.setScale(vec3(mouseSize, 1.0f)); + batch.setModelTransform(model); + batch.setUniformTexture(0, _crosshairTexture); + glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f }; + DependencyManager::get()->renderUnitQuad(batch, vec4(1)); renderArgs->_context->render(batch); - return; - - - - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_TEXTURE_2D); - glViewport(0, 0, qApp->getDeviceSize().width(), qApp->getDeviceSize().height()); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - { - glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture()); - DependencyManager::get()->renderUnitQuad(vec4(vec3(1), _alpha)); - //draw the mouse pointer - glm::vec2 canvasSize = qApp->getCanvasSize(); - - // 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; - mat4 mouseMv = glm::translate(mat4(), vec3(mousePosition, 0)); - - // Scale the mouse based on the canvasSize (NOT the device size, - // we don't want a smaller mouse on retina displays) - glm::vec2 mouseSize = 32.0f / canvasSize; - mouseMv = glm::scale(mouseMv, vec3(mouseSize, 1.0f)); - - // Push the resulting matrix into modelview - glLoadMatrixf(glm::value_ptr(mouseMv)); - glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture)); - glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f }; - DependencyManager::get()->renderUnitQuad(reticleColor); - } - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); } + +static gpu::BufferPointer _hemiVertices; +static gpu::BufferPointer _hemiIndices; +static int _hemiIndexCount{ 0 }; + // Draws the FBO texture for Oculus rift. void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera& whichCamera) { if (_alpha == 0.0f) { return; } - _overlays.buildVBO(_textureFov, _textureAspectRatio, 80, 80); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + auto geometryCache = DependencyManager::get(); + gpu::Batch batch; + //DependencyManager::get()->bindSimpleProgram(batch, true); + batch.setPipeline(getDrawPipeline()); + batch._glDisable(GL_DEPTH_TEST); + 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()); + + Transform model; + model.setTranslation(vec3(0.0f, 0.0f, -2.0f)); + batch.setModelTransform(model); + + // FIXME doesn't work + drawSphereSection(batch); + + // works... + geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha)); + + renderArgs->_context->render(batch); + // batch.setUniformTexture(0, gpu::TexturePointer()); + // geometryCache->renderSolidCube(batch, 0.5f, vec4(1)); + + /* // The camera here contains only the head pose relative to the avatar position vec3 pos = whichCamera.getPosition(); quat rot = whichCamera.getOrientation(); @@ -394,6 +390,7 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera glLoadMatrixf(glm::value_ptr(glm::inverse(overlayXfm))); glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture()); _overlays.render(); + */ //Update and draw the magnifiers /* @@ -423,11 +420,11 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera }); } } - */ if (!Application::getInstance()->isMouseHidden()) { renderPointersOculus(); } + */ } // Draws the FBO texture for 3DTV. @@ -1104,109 +1101,102 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() { } } -ApplicationOverlay::TexturedHemisphere::TexturedHemisphere() : - _vertices(0), - _indices(0), - _vbo(0, 0) { -} -ApplicationOverlay::TexturedHemisphere::~TexturedHemisphere() { - cleanupVBO(); -} - -void ApplicationOverlay::TexturedHemisphere::buildVBO(const float fov, - const float aspectRatio, - const int slices, - const int stacks) { +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) { + if (_hemiVerticesID != GeometryCache::UNKNOWN_ID && textureFOV == fov && textureAspectRatio == aspectRatio) { return; } + textureFOV = fov; textureAspectRatio = aspectRatio; + auto geometryCache = DependencyManager::get(); + if (_hemiVerticesID == GeometryCache::UNKNOWN_ID) { + _hemiVerticesID = geometryCache->allocateID(); + } + + _hemiVertices = gpu::BufferPointer(new gpu::Buffer()); + _hemiIndices = gpu::BufferPointer(new gpu::Buffer()); + + 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; // Compute vertices positions and texture UV coordinate - TextureVertex* vertexData = new TextureVertex[_vertices]; - TextureVertex* vertexPtr = &vertexData[0]; + // Create and write to buffer + //_hemiVertices->(sizeof(vec3) + sizeof(vec2) + sizeof(vec4)) * stacks * slices); for (int i = 0; i < stacks; i++) { float stacksRatio = (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); - for (int j = 0; j < slices; j++) { float slicesRatio = (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++; + pos = getPoint(yaw, pitch); + _hemiVertices->append(sizeof(pos), (gpu::Byte*)&pos); + _hemiVertices->append(sizeof(vec2), (gpu::Byte*)&vec2(slicesRatio, stacksRatio)); + _hemiVertices->append(sizeof(vec4), (gpu::Byte*)&vec4(1)); } } - // 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 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), sizeof(vec3)); + streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_DATA_SLOT, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::RGBA), sizeof(vec3) + sizeof(vec2)); + 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); } + GLuint ApplicationOverlay::getOverlayTexture() { return _framebufferObject->texture(); } @@ -1234,6 +1224,7 @@ void ApplicationOverlay::buildFramebufferObject() { glBindTexture(GL_TEXTURE_2D, 0); } +/* //Renders a hemisphere with texture coordinates. void ApplicationOverlay::TexturedHemisphere::render() { if (_vbo.first == 0 || _vbo.second == 0) { @@ -1261,7 +1252,7 @@ void ApplicationOverlay::TexturedHemisphere::render() { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } - +*/ glm::vec2 ApplicationOverlay::directionToSpherical(const glm::vec3& direction) { glm::vec2 result; // Compute yaw diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index 63ef48bd92..d78ad4bc9f 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -67,28 +67,8 @@ public: static glm::vec2 sphericalToScreen(const glm::vec2 & sphericalPos); private: - // Interleaved vertex data - struct TextureVertex { - glm::vec3 position; - glm::vec2 uv; - }; - - typedef QPair VerticesIndices; - class TexturedHemisphere { - public: - TexturedHemisphere(); - ~TexturedHemisphere(); - void buildVBO(const float fov, const float aspectRatio, const int slices, const int stacks); - void render(); - - private: - void cleanupVBO(); - - GLuint _vertices; - GLuint _indices; - 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; QOpenGLFramebufferObject* _framebufferObject; @@ -105,11 +85,11 @@ private: void renderDomainConnectionStatusBorder(); void buildFramebufferObject(); - - TexturedHemisphere _overlays; float _textureFov; float _textureAspectRatio; + int _hemiVerticesID{ GeometryCache::UNKNOWN_ID }; + enum Reticles { MOUSE, LEFT_CONTROLLER, RIGHT_CONTROLLER, NUMBER_OF_RETICLES }; bool _reticleActive[NUMBER_OF_RETICLES]; From ef520353008fb10205bcd8034b8d14d745966934 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 11 Jun 2015 02:20:51 -0700 Subject: [PATCH 5/8] Working on functional overlays --- interface/src/Application.cpp | 3 +- interface/src/devices/OculusManager.cpp | 38 +++++++++++----------- interface/src/devices/TV3DManager.cpp | 18 +++++------ interface/src/ui/ApplicationOverlay.cpp | 42 ++++++++++++++----------- 4 files changed, 53 insertions(+), 48 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9d5c43b7cf..a93b0186aa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -941,6 +941,7 @@ void Application::paintGL() { glPushMatrix(); glLoadIdentity(); displaySide(&renderArgs, _myCamera); + _applicationOverlay.displayOverlayTexture(&renderArgs); glPopMatrix(); if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { @@ -957,8 +958,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(&renderArgs); } if (!OculusManager::isConnected() || OculusManager::allowSwap()) { diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 77263935f6..2ee62c85f3 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -615,6 +615,7 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const renderArgs->_renderSide = RenderArgs::MONO; qApp->displaySide(renderArgs, *_camera, false); + qApp->getApplicationOverlay().displayOverlayTextureHmd(renderArgs, *_camera); }); _activeEye = ovrEye_Count; @@ -629,28 +630,27 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const glBindFramebuffer(GL_FRAMEBUFFER, 0); } - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); - //Render each eye into an fbo - for_each_eye(_ovrHmd, [&](ovrEyeType eye) { - _activeEye = eye; - // Update our camera to what the application camera is doing - _camera->setRotation(toGlm(eyeRenderPose[eye].Orientation)); - _camera->setPosition(toGlm(eyeRenderPose[eye].Position)); - configureCamera(*_camera); - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(glm::value_ptr(_camera->getProjection())); + //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); + ////Render each eye into an fbo + //for_each_eye(_ovrHmd, [&](ovrEyeType eye) { + // _activeEye = eye; + // // Update our camera to what the application camera is doing + // _camera->setRotation(toGlm(eyeRenderPose[eye].Orientation)); + // _camera->setPosition(toGlm(eyeRenderPose[eye].Position)); + // configureCamera(*_camera); + // glMatrixMode(GL_PROJECTION); + // glLoadMatrixf(glm::value_ptr(_camera->getProjection())); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + // glMatrixMode(GL_MODELVIEW); + // glLoadIdentity(); - ovrRecti & vp = _eyeTextures[eye].Header.RenderViewport; - vp.Size.h = _recommendedTexSize.h * _offscreenRenderScale; - vp.Size.w = _recommendedTexSize.w * _offscreenRenderScale; + // ovrRecti & vp = _eyeTextures[eye].Header.RenderViewport; + // vp.Size.h = _recommendedTexSize.h * _offscreenRenderScale; + // vp.Size.w = _recommendedTexSize.w * _offscreenRenderScale; - glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h); - qApp->getApplicationOverlay().displayOverlayTextureHmd(renderArgs, *_camera); - }); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + // glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h); + //}); + //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glPopMatrix(); diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index c14e589389..b0a2ff7e3b 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -12,6 +12,7 @@ #include "InterfaceConfig.h" #include +#include #include #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(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(renderArgs, whichCamera, _aspect, fov); + qApp->getApplicationOverlay().displayOverlayTexture(renderArgs); _activeEye = NULL; }, [&]{ // render right side view diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 4be47e342a..b4824e96a3 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -312,7 +312,6 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { renderArgs->_context->syncCache(); - glViewport(0, 0, qApp->getDeviceSize().width(), qApp->getDeviceSize().height()); gpu::Batch batch; Transform model; @@ -356,9 +355,10 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera return; } + renderArgs->_context->syncCache(); + auto geometryCache = DependencyManager::get(); gpu::Batch batch; - //DependencyManager::get()->bindSimpleProgram(batch, true); batch.setPipeline(getDrawPipeline()); batch._glDisable(GL_DEPTH_TEST); batch._glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture()); @@ -367,19 +367,23 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera batch.setProjectionTransform(whichCamera.getProjection()); batch.setViewTransform(Transform()); - Transform model; - model.setTranslation(vec3(0.0f, 0.0f, -2.0f)); - batch.setModelTransform(model); + Transform mv; + mv.setTranslation(vec3(0.0f, 0.0f, -1.0f)); + mv.preRotate(glm::inverse(qApp->getCamera()->getHmdRotation())); + mv.setScale(vec3(1.0f, 1.0f / aspect(qApp->getCanvasSize()), 1.0f)); + batch.setModelTransform(mv); + // FIXME doesn't work - drawSphereSection(batch); + // drawSphereSection(batch); // works... geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha)); + // sort of works, renders a semi-transparent red quad + // geometryCache->renderSolidCube(batch, 1.0f, vec4(1)); + renderArgs->_context->render(batch); - // batch.setUniformTexture(0, gpu::TexturePointer()); - // geometryCache->renderSolidCube(batch, 0.5f, vec4(1)); /* // The camera here contains only the head pose relative to the avatar position @@ -427,8 +431,9 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera */ } +/* // Draws the FBO texture for 3DTV. -void ApplicationOverlay::displayOverlayTextureStereo(RenderArgs* renderArgs, Camera& whichCamera, float aspectRatio, float fov) { +void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov) { if (_alpha == 0.0f) { return; } @@ -473,15 +478,15 @@ void ApplicationOverlay::displayOverlayTextureStereo(RenderArgs* renderArgs, Cam GLfloat y = -halfQuadHeight; glDisable(GL_DEPTH_TEST); - //with_each_texture(_framebufferObject->texture(), _newUiTexture, [&] { - // DependencyManager::get()->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); - //}); + with_each_texture(_overlays.getTexture(), _newUiTexture, [&] { + DependencyManager::get()->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() + @@ -521,6 +526,7 @@ void ApplicationOverlay::displayOverlayTextureStereo(RenderArgs* renderArgs, Cam 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(); From bc206633f5b1916a009fad216ee56332065349d3 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 11 Jun 2015 14:56:21 -0700 Subject: [PATCH 6/8] Fixing overlay rendering in HMD --- interface/resources/images/arrow.png | Bin 0 -> 3562 bytes interface/src/ui/ApplicationOverlay.cpp | 342 ++++++------------------ interface/src/ui/ApplicationOverlay.h | 2 +- 3 files changed, 78 insertions(+), 266 deletions(-) create mode 100644 interface/resources/images/arrow.png diff --git a/interface/resources/images/arrow.png b/interface/resources/images/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..408881b5856eb47a30875e3e56d5864721161587 GIT binary patch literal 3562 zcmdUt`#;nD8^_v>&Q++7{9N_Zsz0M==* zod*CASSkfH0KhjS_b&hd`q(~4J0M#M?u(ox0DvNG?~zad?EY9Ph;*vvAOHXp=Hz0J z=|L}3w2K>L>R8^PZ{I7O2$vdaap<*#Uu|_gIy~UBicJicDlZ z#oT*?_=N1+o**hKQJS&OwQ2S|FMIjks+^{Z*q`l9A9H%nCjQ}c>;Esnf^cn5k*X9 zDtIJvM-E6hnmauB8V%s$m0YR(j6(AOYaQ=Zxaf|nXhd}U)5Il`{<|J=u`8-l2Sk+)w2fZTFpVq+^VNbOIHDWEzXw;!TEupOl!#6bSK1;*{YJ|c(d%UezwJosB zc=QMJ+fywpC=OIGT`wp7eo4?o-Kyti6+y{Jdkx&njTs4=L~;x?`X$w+4)SuSIXQJ7 z;%Z)Hey~5FtC%13ZoZkBJQ8*cCYk7&2G7(TD)XtyWAc3?k#+2 zSg#k#mdRYRgv~@}Xlfje8{_+BNfv2R`Fs}BbLcl>eN-Ll zMq8jYR7x=HKDvahQ;p)T@CmDn4b1Nh(-MoAGg{jUe@WM|HsDuQOMVVAOFPKspjE0i z^C8vZ%pJ%+uK%uMP2K<22L?4~Io;K?zlnUro6GjvZ49$6g1A#&a2?86$9#wCOcS%C zb7}sG62)C19qs#(J5bIzi7QG=>-u$yEsR=h>f(-34m0xR(${nu&{RhA&@Mg7`B#`P zhV5a20jVJ##O)R@7r(@&R%V1)k5!_PR;jZ%Nic^nQe9LZq&r0-(CXstay#9kZWT(y zdgH7OM)5F71^WF%`v@Z|XC$dE{=2L=mdYTn>$X5itWF7S%qGfL>f`G0z@vPRSW|2% zzLM%PjXHas*`f@r_~wQ}Gmu43 z5G-)iN^`2uk6mWYBtokb!0*#IwiWpKfC!6##XRQBC1`bV$0fxT!VRorXxhHGe*NoA zdt6ZxwAvV!ZiN`4;o>WhDAGg8(B`wek@fWhHJ(dW4MtCkbqC#y7JcedE@AK> zMB$xO&3k{;t&x;emmKUb zowqJ(lDd|Eb9|sC!Ygpx87ARjG#b5XFF{X9cXw1L?RMHVsRnMv$I0lQd^=+#V#@$MlpA5irYfng==?oLWQ=QK^D$Ky_U!*jQH#m zjVjH$7E1+|ase%BK+M|o{iTaQ(Ml4H1$pu8=4el6V&M__e7G&_O(9<;GE^Al=TpLf zxO&AC{>m}9nRav|v8Os%CgDtTL=_WpJt#}L4rmX;ZoUwBsJ>kVxxfDKL-u*4inEt~ zepM8kiQ750nR9cof?+F3&-L4?2*iEAb9@@Ud-g}wloO$m!0J7N70PeSEAq6p3OKcD zep<3P?;@P-BzLYtBN~F-LxAwG5KLr9GB*Xf%Wrfd?2tQ{5+_qIEe`S;h*BXPA9!7* z{O#kEZB7c7JjG)*ytp`?abYuf2GbW035JF@wq+^JD38vuuKEw%F$L!JOIq~=P8ymV zjt6yfX60aCNrHV1;cN&@dcdu!k|na6-H;<1X+!&G)r4i5?y*WzOxI>K;!yduCwQRw zp)oRGk=9n3Lq4Fc>bY<x^GMN*P>x zcT=W7G2!>9k+a{t5kw;+2YqAccKgH6tOWRO&IL`{vOX8<_+#gs2a?glJn|}=3`vz{ zHAviptXq=nB%o57Oo#&v(9S0q<1wQCaMM$X_~?zvlB$ z{BS{j>8BHv>(J^Cw&VWjNl%$l^~FK0xgm}RHN;P_yMCbJkgqy!`%3TxmFo>4xWOMOk)+EW^_O9C7dZ>}I8Kh? zj}RS#{?`Mw|KiNv1NTC!8{_L%x!B03r-qWd`3rX$w%2JIqbaP0;T@MIu#e4!O_jj9 z<#;=AYz=r`={Y4aD2T>=*o5mw?KfuiR+fF=OW1)P@;v$;gLp~OWmI`C8Lwoc_?A2G z8WZjK)fU#5&sGhWjChlZ8*bHMkESnnvKsURQ^7~i%5%;9utUpqF}fdSqfACu_qEX4 zp@vXlm3Du40m?O>|E>T2`lg zkA8{BTL{+P!L`w6k!iPQ#a#f=|m#Qf(WK|Ir2F`ayL>?xU&W1IW5W%|H^ z!@V6^Km}^O#=A4H!qZs`D;m4uMCc;TUi*(Pr73>oa{>8VKq2hz#bW*--8Nf%b$@+! zHoF^Jp|5>CN4DvW)pU)?%g3N~Y6FGpe0l}{L^6G`j-fi~Y@`DQ5BtMg5BbtdGn`80 zlhZ=aS9n=RRb*}nf8eMeJDEc8%&t(^e!P8ZC+e-xs;70|LZCeN?35MHzihjDJDea% z_nQ6_6TRHs&%{vEqnm%C6bpLLKSPBjQ&ibGJ*2EF0a>wL|BHog#{CKrZI>`=PhmuX z1|o8of6J{XA8}XluF6Ue3=0>|PEYY5F8#6~g%gS*=5Vs(@K@8a<4r38-e(uhuy6R~b&w4cQHxqLICs#~XeF!9xRs?fdLjDOKWTh7 R^nCyTaI$x`E7(oB_+R=!c8UN1 literal 0 HcmV?d00001 diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index b4824e96a3..e5f701e807 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -120,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()->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), @@ -307,7 +286,7 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { if (!_crosshairTexture) { _crosshairTexture = TextureCache::getImageTexture( - PathUtils::resourcesPath() + "images/sixense-reticle.png"); + PathUtils::resourcesPath() + "images/arrow.png"); } @@ -349,6 +328,40 @@ static gpu::BufferPointer _hemiVertices; static gpu::BufferPointer _hemiIndices; static int _hemiIndexCount{ 0 }; +glm::vec2 getPolarCoordinates(const PalmData& palm) { + MyAvatar* myAvatar = DependencyManager::get()->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; +} + +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()->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); +} + + // Draws the FBO texture for Oculus rift. void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera& whichCamera) { if (_alpha == 0.0f) { @@ -357,176 +370,60 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera renderArgs->_context->syncCache(); - auto geometryCache = DependencyManager::get(); 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()); - Transform mv; - mv.setTranslation(vec3(0.0f, 0.0f, -1.0f)); - mv.preRotate(glm::inverse(qApp->getCamera()->getHmdRotation())); - mv.setScale(vec3(1.0f, 1.0f / aspect(qApp->getCanvasSize()), 1.0f)); - batch.setModelTransform(mv); + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + 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); - // FIXME doesn't work - // drawSphereSection(batch); + if (!_crosshairTexture) { + _crosshairTexture = TextureCache::getImageTexture( + PathUtils::resourcesPath() + "images/arrow.png"); + } + batch.setUniformTexture(0, _crosshairTexture); + auto geometryCache = DependencyManager::get(); + //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, vec3(reticleSize, reticleSize, 1.0f)); + batch.setModelTransform(reticleXfm); + // Render reticle at location + geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); + } + } - // works... - geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha)); - - // sort of works, renders a semi-transparent red quad - // geometryCache->renderSolidCube(batch, 1.0f, vec4(1)); + //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, vec3(reticleSize, reticleSize, 1.0f)); + batch.setModelTransform(reticleXfm); + geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); + } renderArgs->_context->render(batch); - - /* - // The camera here contains only the head pose relative to the avatar position - vec3 pos = whichCamera.getPosition(); - quat rot = whichCamera.getOrientation(); - mat4 overlayXfm = glm::translate(glm::mat4(), pos) * glm::mat4_cast(rot); - - glLoadMatrixf(glm::value_ptr(glm::inverse(overlayXfm))); - glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture()); - _overlays.render(); - */ - - //Update and draw the magnifiers - /* - // FIXME Mangifiers need to be re-thought - MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - const float scale = myAvatar->getScale() * _oculusUIRadius; - overlayXfm = glm::scale(overlayXfm, vec3(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); - }); - } - } - - if (!Application::getInstance()->isMouseHidden()) { - renderPointersOculus(); - } - */ } -/* -// Draws the FBO texture for 3DTV. -void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov) { - if (_alpha == 0.0f) { - return; - } - - MyAvatar* myAvatar = DependencyManager::get()->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()->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()->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(); @@ -556,22 +453,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()->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; @@ -624,7 +505,7 @@ bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position, void ApplicationOverlay::renderPointers() { //lazily load crosshair texture if (_crosshairTexture == 0) { - _crosshairTexture = TextureCache::getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png"); + _crosshairTexture = TextureCache::getImageTexture(PathUtils::resourcesPath() + "images/arrow.png"); } glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); @@ -790,43 +671,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()->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) { @@ -1111,7 +955,7 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() { void ApplicationOverlay::buildHemiVertices( const float fov, const float aspectRatio, const int slices, const int stacks) { static float textureFOV = 0.0f, textureAspectRatio = 1.0f; - if (_hemiVerticesID != GeometryCache::UNKNOWN_ID && textureFOV == fov && textureAspectRatio == aspectRatio) { + if (textureFOV == fov && textureAspectRatio == aspectRatio) { return; } @@ -1119,9 +963,6 @@ void ApplicationOverlay::buildHemiVertices( textureAspectRatio = aspectRatio; auto geometryCache = DependencyManager::get(); - if (_hemiVerticesID == GeometryCache::UNKNOWN_ID) { - _hemiVerticesID = geometryCache->allocateID(); - } _hemiVertices = gpu::BufferPointer(new gpu::Buffer()); _hemiIndices = gpu::BufferPointer(new gpu::Buffer()); @@ -1187,8 +1028,8 @@ void ApplicationOverlay::drawSphereSection(gpu::Batch& batch) { 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), sizeof(vec3)); - streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_DATA_SLOT, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::RGBA), sizeof(vec3) + sizeof(vec2)); + 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); @@ -1230,35 +1071,6 @@ void ApplicationOverlay::buildFramebufferObject() { glBindTexture(GL_TEXTURE_2D, 0); } -/* -//Renders a hemisphere with texture coordinates. -void ApplicationOverlay::TexturedHemisphere::render() { - if (_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); -} -*/ glm::vec2 ApplicationOverlay::directionToSpherical(const glm::vec3& direction) { glm::vec2 result; // Compute yaw diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index d78ad4bc9f..609bef745d 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -72,7 +72,7 @@ private: float _hmdUIAngularSize = DEFAULT_HMD_UI_ANGULAR_SIZE; QOpenGLFramebufferObject* _framebufferObject; - void renderReticle(glm::quat orientation, float alpha); + void renderReticle(gpu::Batch& batch, glm::quat orientation, float alpha); void renderPointers(); void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder); From d3cdbc389a4c7d3fda287ebe4ac440b0ccb4e051 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 11 Jun 2015 15:05:08 -0700 Subject: [PATCH 7/8] Code cleanup --- interface/src/devices/OculusManager.cpp | 24 ------------------------ interface/src/ui/ApplicationOverlay.cpp | 21 +-------------------- 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 2ee62c85f3..414c7f6199 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -629,35 +629,11 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const finalFbo = DependencyManager::get()->getPrimaryFramebuffer(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } - - //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); - ////Render each eye into an fbo - //for_each_eye(_ovrHmd, [&](ovrEyeType eye) { - // _activeEye = eye; - // // Update our camera to what the application camera is doing - // _camera->setRotation(toGlm(eyeRenderPose[eye].Orientation)); - // _camera->setPosition(toGlm(eyeRenderPose[eye].Position)); - // configureCamera(*_camera); - // glMatrixMode(GL_PROJECTION); - // glLoadMatrixf(glm::value_ptr(_camera->getProjection())); - - // glMatrixMode(GL_MODELVIEW); - // glLoadIdentity(); - - // ovrRecti & vp = _eyeTextures[eye].Header.RenderViewport; - // vp.Size.h = _recommendedTexSize.h * _offscreenRenderScale; - // vp.Size.w = _recommendedTexSize.w * _offscreenRenderScale; - - // glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h); - //}); - //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); - // restore our normal viewport glViewport(0, 0, deviceSize.width(), deviceSize.height()); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index e5f701e807..887af89cd0 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -242,24 +242,6 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { _framebufferObject->release(); } -// A quick and dirty solution for compositing the old overlay -// texture with the new one -//template -//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(); -// } -// //if (secondPassTexture) { -// // glBindTexture(GL_TEXTURE_2D, secondPassTexture); -// // f(); -// //} -// glBindTexture(GL_TEXTURE_2D, 0); -// glDisable(GL_TEXTURE_2D); -//} - gpu::PipelinePointer ApplicationOverlay::getDrawPipeline() { if (!_standardDrawPipeline) { auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(standardTransformPNTC_vert))); @@ -977,7 +959,6 @@ void ApplicationOverlay::buildHemiVertices( vec3 pos; // Compute vertices positions and texture UV coordinate // Create and write to buffer - //_hemiVertices->(sizeof(vec3) + sizeof(vec2) + sizeof(vec4)) * stacks * slices); for (int i = 0; i < stacks; i++) { float stacksRatio = (float)i / (float)(stacks - 1); // First stack is 0.0f, last stack is 1.0f // abs(theta) <= fov / 2.0f @@ -1052,7 +1033,7 @@ 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; } From 92f22bc6d52bde359f7b6fc8baa0678e139ba311 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 11 Jun 2015 15:40:16 -0700 Subject: [PATCH 8/8] Magic number and build errors --- interface/src/ui/ApplicationOverlay.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 887af89cd0..f6dd4f5773 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -260,6 +260,8 @@ gpu::PipelinePointer ApplicationOverlay::getDrawPipeline() { return _standardDrawPipeline; } +#define CURSOR_PIXEL_SIZE 32.0f + // Draws the FBO texture for the screen void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { if (_alpha == 0.0f) { @@ -296,7 +298,7 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { mousePosition -= 1.0f; mousePosition.y *= -1.0f; model.setTranslation(vec3(mousePosition, 0)); - glm::vec2 mouseSize = 32.0f / canvasSize; + glm::vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize; model.setScale(vec3(mouseSize, 1.0f)); batch.setModelTransform(model); batch.setUniformTexture(0, _crosshairTexture); @@ -957,20 +959,22 @@ void ApplicationOverlay::buildHemiVertices( //UV mapping source: http://www.mvps.org/directx/articles/spheremap.htm vec3 pos; + vec2 uv; // Compute vertices positions and texture UV coordinate // 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); + 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*)&vec2(slicesRatio, stacksRatio)); - _hemiVertices->append(sizeof(vec4), (gpu::Byte*)&vec4(1)); + _hemiVertices->append(sizeof(vec2), (gpu::Byte*)&uv); + _hemiVertices->append(sizeof(vec4), (gpu::Byte*)&color); } }