From 0cdc2b53fe7815bba21a98ecbdfd91bcbb2898f5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 12 Jun 2015 12:57:24 -0700 Subject: [PATCH] Revert "Merge pull request #5106 from jherico/render_cursor" This reverts commit 4d18bd7cec710b5188d1f6ad5c58010117d7a77d, reversing changes made to 24fda9a7336e4eff1d1310dd3359dd6cbbb6acb5. --- interface/resources/images/arrow.png | Bin 3562 -> 0 bytes interface/src/Application.cpp | 3 +- interface/src/devices/OculusManager.cpp | 5 +- interface/src/devices/TV3DManager.cpp | 18 +- interface/src/ui/ApplicationOverlay.cpp | 666 +++++++++++------- interface/src/ui/ApplicationOverlay.h | 53 +- libraries/render-utils/src/GeometryCache.cpp | 15 - libraries/render-utils/src/GeometryCache.h | 3 - .../render-utils/src/standardDrawTexture.slf | 24 - .../src/standardTransformPNTC.slv | 33 - 10 files changed, 481 insertions(+), 339 deletions(-) delete mode 100644 interface/resources/images/arrow.png delete mode 100644 libraries/render-utils/src/standardDrawTexture.slf delete mode 100644 libraries/render-utils/src/standardTransformPNTC.slv diff --git a/interface/resources/images/arrow.png b/interface/resources/images/arrow.png deleted file mode 100644 index 408881b5856eb47a30875e3e56d5864721161587..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3562 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 R^nCyTaI$x`E7(oB_+R=!c8UN1 diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 56fe4188e9..0f0abb3996 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -955,7 +955,6 @@ void Application::paintGL() { glPushMatrix(); glLoadIdentity(); displaySide(&renderArgs, _myCamera); - _applicationOverlay.displayOverlayTexture(&renderArgs); glPopMatrix(); if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { @@ -972,6 +971,8 @@ 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()) { diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 414c7f6199..a7383ae4bb 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -615,10 +615,12 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const renderArgs->_renderSide = RenderArgs::MONO; qApp->displaySide(renderArgs, *_camera, false); - qApp->getApplicationOverlay().displayOverlayTextureHmd(renderArgs, *_camera); + 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)) { @@ -629,7 +631,6 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const finalFbo = DependencyManager::get()->getPrimaryFramebuffer(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } - glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index b0a2ff7e3b..09edb03e5a 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -12,7 +12,6 @@ #include "InterfaceConfig.h" #include -#include #include #include "gpu/GLBackend.h" @@ -107,20 +106,21 @@ 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 - glLoadMatrixf(glm::value_ptr(projection)); + 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 + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); renderArgs->_renderSide = RenderArgs::MONO; qApp->displaySide(renderArgs, eyeCamera, false); - qApp->getApplicationOverlay().displayOverlayTexture(renderArgs); + qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov); _activeEye = NULL; }, [&]{ // render right side view diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index ba0d3a60a9..0c1783f8ac 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -14,16 +14,13 @@ #include #include -#include - #include -#include #include +#include #include #include -#include -#include #include +#include #include "AudioClient.h" #include "audio/AudioIOStatsRenderer.h" @@ -36,9 +33,6 @@ #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; @@ -120,6 +114,27 @@ 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), @@ -133,8 +148,7 @@ ApplicationOverlay::ApplicationOverlay() : _previousMagnifierBottomLeft(), _previousMagnifierBottomRight(), _previousMagnifierTopLeft(), - _previousMagnifierTopRight(), - _framebufferObject(nullptr) + _previousMagnifierTopRight() { memset(_reticleActive, 0, sizeof(_reticleActive)); memset(_magActive, 0, sizeof(_reticleActive)); @@ -181,17 +195,16 @@ 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); - buildFramebufferObject(); - - _framebufferObject->bind(); + _overlays.buildFramebufferObject(); + _overlays.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; @@ -213,22 +226,6 @@ 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(); @@ -238,161 +235,259 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { glEnable(GL_LIGHTING); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); - _framebufferObject->release(); + _overlays.release(); } -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)); +// 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(); } - - 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()-> - getImageTexture(iconPath); + if (secondPassTexture) { + glBindTexture(GL_TEXTURE_2D, secondPassTexture); + f(); } - batch.setUniformTexture(0, _cursors[iconId]); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); } -#define CURSOR_PIXEL_SIZE 32.0f - // Draws the FBO texture for the screen -void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { +void ApplicationOverlay::displayOverlayTexture() { + 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()); + + 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"); + } + + //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; + + 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()->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(); +} + +// Draws the FBO texture for Oculus rift. +void ApplicationOverlay::displayOverlayTextureHmd(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); + + + //Update and draw the magnifiers + 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; + } + } + + 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); + } + + 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(); +} + +// Draws the FBO texture for 3DTV. +void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov) { if (_alpha == 0.0f) { return; } - renderArgs->_context->syncCache(); - - gpu::Batch batch; - Transform model; - //DependencyManager::get()->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()->renderUnitQuad(batch, vec4(vec3(1), _alpha)); + 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(); - - // 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); + 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()->renderUnitQuad(batch, vec4(1)); - renderArgs->_context->render(batch); + + 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); } - -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; -} - -// Draws the FBO texture for Oculus rift. -void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera& whichCamera) { - if (_alpha == 0.0f) { - return; - } - - 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()); - - 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); - - - bindCursorTexture(batch); - auto geometryCache = DependencyManager::get(); - 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); - } - } - - //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); -} - - void ApplicationOverlay::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) const { cursorPos *= qApp->getCanvasSize(); const glm::vec2 projection = screenToSpherical(cursorPos); @@ -421,6 +516,22 @@ 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; @@ -471,9 +582,13 @@ bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position, //Renders optional pointers void ApplicationOverlay::renderPointers() { - //glEnable(GL_TEXTURE_2D); - //glEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //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); //glActiveTexture(GL_TEXTURE0); //bindCursorTexture(); @@ -635,6 +750,43 @@ 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) { @@ -915,109 +1067,119 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() { } } +ApplicationOverlay::TexturedHemisphere::TexturedHemisphere() : + _vertices(0), + _indices(0), + _framebufferObject(NULL), + _vbo(0, 0) { +} -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; +ApplicationOverlay::TexturedHemisphere::~TexturedHemisphere() { + cleanupVBO(); + if (_framebufferObject != NULL) { + delete _framebufferObject; } +} - textureFOV = fov; - textureAspectRatio = aspectRatio; - - auto geometryCache = DependencyManager::get(); - - _hemiVertices = gpu::BufferPointer(new gpu::Buffer()); - _hemiIndices = gpu::BufferPointer(new gpu::Buffer()); +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) { 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 - vec3 pos; - vec2 uv; + // Compute number of vertices needed + _vertices = slices * stacks; + // Compute vertices positions and texture UV coordinate - // Create and write to buffer + TextureVertex* vertexData = new TextureVertex[_vertices]; + TextureVertex* vertexPtr = &vertexData[0]; for (int i = 0; i < stacks; i++) { - uv.y = (float)i / (float)(stacks - 1); // First stack is 0.0f, last stack is 1.0f + 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 * (uv.y - 0.5f); + float pitch = -fov * (stacksRatio - 0.5f); + for (int j = 0; j < slices; j++) { - uv.x = (float)j / (float)(slices - 1); // First slice is 0.0f, last slice is 1.0f + 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 * (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); + float yaw = -fov * aspectRatio * (slicesRatio - 0.5f); + + vertexPtr->position = getPoint(yaw, pitch); + vertexPtr->uv.x = slicesRatio; + vertexPtr->uv.y = stacksRatio; + vertexPtr++; } } + // 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); - _hemiIndexCount = numberOfRectangles * TRIANGLE_PER_RECTANGLE * VERTEX_PER_TRANGLE; + _indices = numberOfRectangles * TRIANGLE_PER_RECTANGLE * VERTEX_PER_TRANGLE; // Compute indices order - std::vector indices; + GLushort* indexData = new GLushort[_indices]; + GLushort* indexPtr = indexData; 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; - // 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); + + *(indexPtr++) = topLeftIndex; + *(indexPtr++) = bottomLeftIndex; + *(indexPtr++) = topRightIndex; + + *(indexPtr++) = topRightIndex; + *(indexPtr++) = bottomLeftIndex; + *(indexPtr++) = bottomRightIndex; } } - _hemiIndices->append(sizeof(GLushort) * indices.size(), (gpu::Byte*)&indices[0]); + // 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; } - -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::cleanupVBO() { + if (_vbo.first != 0) { + glDeleteBuffers(1, &_vbo.first); + _vbo.first = 0; + } + if (_vbo.second != 0) { + glDeleteBuffers(1, &_vbo.second); + _vbo.second = 0; + } } - -GLuint ApplicationOverlay::getOverlayTexture() { - return _framebufferObject->texture(); -} - -void ApplicationOverlay::buildFramebufferObject() { +void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() { auto canvasSize = qApp->getCanvasSize(); QSize fboSize = QSize(canvasSize.x, canvasSize.y); if (_framebufferObject != NULL && fboSize == _framebufferObject->size()) { - // Already built + // Already build return; } @@ -1026,7 +1188,7 @@ void ApplicationOverlay::buildFramebufferObject() { } _framebufferObject = new QOpenGLFramebufferObject(fboSize, QOpenGLFramebufferObject::Depth); - glBindTexture(GL_TEXTURE_2D, getOverlayTexture()); + glBindTexture(GL_TEXTURE_2D, getTexture()); 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); @@ -1036,6 +1198,38 @@ void ApplicationOverlay::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 diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index e8b5a77b1f..eb397fe3c6 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(RenderArgs* renderArgs); - void displayOverlayTextureStereo(RenderArgs* renderArgs, Camera& whichCamera, float aspectRatio, float fov); - void displayOverlayTextureHmd(RenderArgs* renderArgs, Camera& whichCamera); + void displayOverlayTexture(); + void displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov); + void displayOverlayTextureHmd(Camera& whichCamera); QPoint getPalmClickLocation(const PalmData *palm) const; bool calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const; @@ -59,7 +59,6 @@ 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); @@ -67,12 +66,38 @@ public: static glm::vec2 sphericalToScreen(const glm::vec2 & sphericalPos); private: - 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; + // Interleaved vertex data + struct TextureVertex { + glm::vec3 position; + glm::vec2 uv; + }; - void renderPointers(); + typedef QPair 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; + }; + + float _hmdUIAngularSize = DEFAULT_HMD_UI_ANGULAR_SIZE; + void renderReticle(glm::quat orientation, float alpha); + void renderPointers();; void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder); void renderControllerPointers(); @@ -84,12 +109,10 @@ private: void renderDomainConnectionStatusBorder(); void bindCursorTexture(gpu::Batch& batch, uint8_t cursorId = 0); - 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]; @@ -102,6 +125,8 @@ private: float _alpha = 1.0f; float _oculusUIRadius; float _trailingAudioLoudness; + + gpu::TexturePointer _crosshairTexture; QMap _cursors; @@ -124,10 +149,6 @@ private: glm::vec3 _previousMagnifierTopLeft; glm::vec3 _previousMagnifierTopRight; - gpu::PipelinePointer _standardDrawPipeline; - - gpu::PipelinePointer getDrawPipeline(); - }; #endif // hifi_ApplicationOverlay_h diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 3066fd4890..303d63bef8 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1179,21 +1179,6 @@ 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 76e03f8669..b438eb2d3b 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -155,9 +155,6 @@ 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) diff --git a/libraries/render-utils/src/standardDrawTexture.slf b/libraries/render-utils/src/standardDrawTexture.slf deleted file mode 100644 index 4fbeb6eb7f..0000000000 --- a/libraries/render-utils/src/standardDrawTexture.slf +++ /dev/null @@ -1,24 +0,0 @@ -<@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 deleted file mode 100644 index fd2c28049f..0000000000 --- a/libraries/render-utils/src/standardTransformPNTC.slv +++ /dev/null @@ -1,33 +0,0 @@ -<@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