Merge pull request #4831 from jherico/plugins_pt2

Display plugins part 2
This commit is contained in:
Brad Hefta-Gaub 2015-05-13 20:40:33 -07:00
commit 77019eafa7
20 changed files with 278 additions and 135 deletions

38
cmake/externals/openvr/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,38 @@
include(ExternalProject)
include(SelectLibraryConfigurations)
set(EXTERNAL_NAME OpenVR)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://github.com/ValveSoftware/openvr/archive/0.9.0.zip
URL_MD5 4fbde7759f604aaa68b9c40d628cc34a
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
LOG_DOWNLOAD 1
)
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/headers CACHE TYPE INTERNAL)
if (WIN32)
# FIXME need to account for different architectures
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/win32/openvr_api.lib CACHE TYPE INTERNAL)
elseif(APPLE)
# FIXME need to account for different architectures
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/osx32/libopenvr_api.dylib CACHE TYPE INTERNAL)
elseif(NOT ANDROID)
# FIXME need to account for different architectures
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/linux32/libopenvr_api.so CACHE TYPE INTERNAL)
endif()

View file

@ -0,0 +1,21 @@
#
# FindLibOVR.cmake
#
# Try to find the LibOVR library to use the Oculus
# Once done this will define
#
# OPENVR_FOUND - system found LibOVR
# OPENVR_INCLUDE_DIRS - the LibOVR include directory
# OPENVR_LIBRARIES - Link this to use LibOVR
#
# Distributed under the Apache License, Version 2.0.
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#
if (NOT ANDROID)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OPENVR DEFAULT_MSG OPENVR_INCLUDE_DIRS OPENVR_LIBRARIES)
endif()
mark_as_advanced(OPENVR_INCLUDE_DIRS OPENVR_LIBRARIES OPENVR_SEARCH_DIRS)

View file

@ -36,8 +36,22 @@ endif ()
configure_file(InterfaceConfig.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceConfig.h") configure_file(InterfaceConfig.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceConfig.h")
configure_file(InterfaceVersion.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceVersion.h") configure_file(InterfaceVersion.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceVersion.h")
macro(GroupSources curdir)
file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*)
foreach(child ${children})
if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child})
GroupSources(${curdir}/${child})
else()
string(REPLACE "/" "\\" groupname ${curdir})
source_group(${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
endif()
endforeach()
endmacro()
# grab the implementation and header files from src dirs # grab the implementation and header files from src dirs
file(GLOB_RECURSE INTERFACE_SRCS "src/*.cpp" "src/*.h") file(GLOB_RECURSE INTERFACE_SRCS "src/*.cpp" "src/*.h")
GroupSources("src")
# Add SpeechRecognizer if on Windows or OS X, otherwise remove # Add SpeechRecognizer if on Windows or OS X, otherwise remove
if (WIN32) if (WIN32)
@ -58,6 +72,7 @@ find_package(Qt5 COMPONENTS Gui Multimedia Network OpenGL Qml Quick Script Svg W
# grab the ui files in resources/ui # grab the ui files in resources/ui
file (GLOB_RECURSE QT_UI_FILES ui/*.ui) file (GLOB_RECURSE QT_UI_FILES ui/*.ui)
source_group("UI Files" FILES ${QT_UI_FILES})
# have qt5 wrap them and generate the appropriate header files # have qt5 wrap them and generate the appropriate header files
qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}") qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}")

View file

@ -839,6 +839,11 @@ void Application::paintGL() {
PerformanceWarning warn(showWarnings, "Application::paintGL()"); PerformanceWarning warn(showWarnings, "Application::paintGL()");
resizeGL(); resizeGL();
{
PerformanceTimer perfTimer("renderOverlay");
_applicationOverlay.renderOverlay();
}
glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_SMOOTH);
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
@ -921,13 +926,9 @@ void Application::paintGL() {
glBlitFramebuffer(0, 0, _renderResolution.x, _renderResolution.y, glBlitFramebuffer(0, 0, _renderResolution.x, _renderResolution.y,
0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height(), 0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height(),
GL_COLOR_BUFFER_BIT, GL_NEAREST); GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
_applicationOverlay.displayOverlayTexture();
{
PerformanceTimer perfTimer("renderOverlay");
_applicationOverlay.renderOverlay();
_applicationOverlay.displayOverlayTexture();
}
} }
if (!OculusManager::isConnected() || OculusManager::allowSwap()) { if (!OculusManager::isConnected() || OculusManager::allowSwap()) {
@ -3078,7 +3079,11 @@ PickRay Application::computePickRay(float x, float y) const {
if (isHMDMode()) { if (isHMDMode()) {
ApplicationOverlay::computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction); ApplicationOverlay::computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction);
} else { } else {
getViewFrustum()->computePickRay(x, y, result.origin, result.direction); if (activeRenderingThread) {
getDisplayViewFrustum()->computePickRay(x, y, result.origin, result.direction);
} else {
getViewFrustum()->computePickRay(x, y, result.origin, result.direction);
}
} }
return result; return result;
} }
@ -3133,6 +3138,16 @@ ViewFrustum* Application::getDisplayViewFrustum() {
return &_displayViewFrustum; return &_displayViewFrustum;
} }
const ViewFrustum* Application::getDisplayViewFrustum() const {
#ifdef DEBUG
if (QThread::currentThread() != activeRenderingThread) {
// FIXME, should this be an assert?
qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?";
}
#endif
return &_displayViewFrustum;
}
void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) { void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) {
activeRenderingThread = QThread::currentThread(); activeRenderingThread = QThread::currentThread();
PROFILE_RANGE(__FUNCTION__); PROFILE_RANGE(__FUNCTION__);

View file

@ -205,6 +205,7 @@ public:
// which might be different from the viewFrustum, i.e. shadowmap // which might be different from the viewFrustum, i.e. shadowmap
// passes, mirror window passes, etc // passes, mirror window passes, etc
ViewFrustum* getDisplayViewFrustum(); ViewFrustum* getDisplayViewFrustum();
const ViewFrustum* getDisplayViewFrustum() const;
ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; } ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; }
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; } const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
EntityTreeRenderer* getEntities() { return &_entities; } EntityTreeRenderer* getEntities() { return &_entities; }

View file

@ -520,12 +520,6 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati
return; return;
} }
ApplicationOverlay& applicationOverlay = Application::getInstance()->getApplicationOverlay();
// We only need to render the overlays to a texture once, then we just render the texture on the hemisphere
// PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay()
applicationOverlay.renderOverlay();
//Bind our framebuffer object. If we are rendering the glow effect, we let the glow effect shader take care of it //Bind our framebuffer object. If we are rendering the glow effect, we let the glow effect shader take care of it
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) { if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
DependencyManager::get<GlowEffect>()->prepare(); DependencyManager::get<GlowEffect>()->prepare();
@ -614,9 +608,8 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati
//glTranslatef(_eyeRenderDesc[eye].ViewAdjust.x, _eyeRenderDesc[eye].ViewAdjust.y, _eyeRenderDesc[eye].ViewAdjust.z); //glTranslatef(_eyeRenderDesc[eye].ViewAdjust.x, _eyeRenderDesc[eye].ViewAdjust.y, _eyeRenderDesc[eye].ViewAdjust.z);
_camera->setEyeOffsetPosition(glm::vec3(-_eyeRenderDesc[eye].HmdToEyeViewOffset.x, -_eyeRenderDesc[eye].HmdToEyeViewOffset.y, -_eyeRenderDesc[eye].HmdToEyeViewOffset.z)); _camera->setEyeOffsetPosition(glm::vec3(-_eyeRenderDesc[eye].HmdToEyeViewOffset.x, -_eyeRenderDesc[eye].HmdToEyeViewOffset.y, -_eyeRenderDesc[eye].HmdToEyeViewOffset.z));
Application::getInstance()->displaySide(*_camera, false, RenderArgs::MONO); qApp->displaySide(*_camera, false, RenderArgs::MONO);
qApp->getApplicationOverlay().displayOverlayTextureHmd(*_camera);
applicationOverlay.displayOverlayTextureHmd(*_camera);
}); });
_activeEye = ovrEye_Count; _activeEye = ovrEye_Count;

View file

@ -92,74 +92,40 @@ void TV3DManager::display(Camera& whichCamera) {
int portalW = deviceSize.width() / 2; int portalW = deviceSize.width() / 2;
int portalH = deviceSize.height(); int portalH = deviceSize.height();
ApplicationOverlay& applicationOverlay = Application::getInstance()->getApplicationOverlay();
// We only need to render the overlays to a texture once, then we just render the texture as a quad
// PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay()
applicationOverlay.renderOverlay();
DependencyManager::get<GlowEffect>()->prepare(); DependencyManager::get<GlowEffect>()->prepare();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_SCISSOR_TEST);
// render left side view
glViewport(portalX, portalY, portalW, portalH);
glScissor(portalX, portalY, portalW, portalH);
Camera eyeCamera; Camera eyeCamera;
eyeCamera.setRotation(whichCamera.getRotation()); eyeCamera.setRotation(whichCamera.getRotation());
eyeCamera.setPosition(whichCamera.getPosition()); eyeCamera.setPosition(whichCamera.getPosition());
glEnable(GL_SCISSOR_TEST);
glPushMatrix(); glPushMatrix();
{ forEachEye([&](eyeFrustum& eye){
_activeEye = &_leftEye; _activeEye = &eye;
glViewport(portalX, portalY, portalW, portalH);
glScissor(portalX, portalY, portalW, portalH);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // reset projection matrix glLoadIdentity(); // reset projection matrix
glFrustum(_leftEye.left, _leftEye.right, _leftEye.bottom, _leftEye.top, nearZ, farZ); // set left view frustum glFrustum(eye.left, eye.right, eye.bottom, eye.top, nearZ, farZ); // set left view frustum
GLfloat p[4][4]; GLfloat p[4][4];
// Really? // Really?
glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0])); glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0]));
float cotangent = p[1][1]; float cotangent = p[1][1];
GLfloat fov = atan(1.0f / cotangent); GLfloat fov = atan(1.0f / cotangent);
glTranslatef(_leftEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax glTranslatef(eye.modelTranslation, 0.0, 0.0); // translate to cancel parallax
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
eyeCamera.setEyeOffsetPosition(glm::vec3(-_activeEye->modelTranslation,0,0)); eyeCamera.setEyeOffsetPosition(glm::vec3(-_activeEye->modelTranslation,0,0));
Application::getInstance()->displaySide(eyeCamera, false, RenderArgs::MONO); qApp->displaySide(eyeCamera, false, RenderArgs::MONO);
qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov);
applicationOverlay.displayOverlayTextureStereo(whichCamera, _aspect, fov);
_activeEye = NULL; _activeEye = NULL;
} }, [&]{
glPopMatrix(); // render right side view
glDisable(GL_SCISSOR_TEST); portalX = deviceSize.width() / 2;
});
// render right side view
portalX = deviceSize.width() / 2;
glEnable(GL_SCISSOR_TEST);
// render left side view
glViewport(portalX, portalY, portalW, portalH);
glScissor(portalX, portalY, portalW, portalH);
glPushMatrix();
{
_activeEye = &_rightEye;
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // reset projection matrix
glFrustum(_rightEye.left, _rightEye.right, _rightEye.bottom, _rightEye.top, nearZ, farZ); // set right view frustum
GLfloat p[4][4];
glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0]));
GLfloat cotangent = p[1][1];
GLfloat fov = atan(1.0f / cotangent);
glTranslatef(_rightEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
eyeCamera.setEyeOffsetPosition(glm::vec3(-_activeEye->modelTranslation,0,0));
Application::getInstance()->displaySide(eyeCamera, false, RenderArgs::MONO);
applicationOverlay.displayOverlayTextureStereo(whichCamera, _aspect, fov);
_activeEye = NULL;
}
glPopMatrix(); glPopMatrix();
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
@ -167,11 +133,13 @@ void TV3DManager::display(Camera& whichCamera) {
auto fboSize = finalFbo->getSize(); auto fboSize = finalFbo->getSize();
// Get the ACTUAL device size for the BLIT // Get the ACTUAL device size for the BLIT
deviceSize = qApp->getDeviceSize(); deviceSize = qApp->getDeviceSize();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo));
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, fboSize.x, fboSize.y, glBlitFramebuffer(0, 0, fboSize.x, fboSize.y,
0, 0, deviceSize.width(), deviceSize.height(), 0, 0, deviceSize.width(), deviceSize.height(),
GL_COLOR_BUFFER_BIT, GL_NEAREST); GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
// reset the viewport to how we started // reset the viewport to how we started
glViewport(0, 0, deviceSize.width(), deviceSize.height()); glViewport(0, 0, deviceSize.width(), deviceSize.height());

View file

@ -44,6 +44,20 @@ private:
static eyeFrustum _leftEye; static eyeFrustum _leftEye;
static eyeFrustum _rightEye; static eyeFrustum _rightEye;
static eyeFrustum* _activeEye; static eyeFrustum* _activeEye;
// The first function is the code executed for each eye
// while the second is code to be executed between the two eyes.
// The use case here is to modify the output viewport coordinates
// for the new eye.
// FIXME: we'd like to have a default empty lambda for the second parameter,
// but gcc 4.8.1 complains about it due to a bug. See
// http://stackoverflow.com/questions/25490662/lambda-as-default-parameter-to-a-member-function-template
template<typename F, typename FF>
static void forEachEye(F f, FF ff) {
f(_leftEye);
ff();
f(_rightEye);
}
}; };
#endif // hifi_TV3DManager_h #endif // hifi_TV3DManager_h

View file

@ -15,7 +15,6 @@
#include <Application.h> #include <Application.h>
#include <avatar/AvatarManager.h> #include <avatar/AvatarManager.h>
#include <devices/OculusManager.h>
#include <LODManager.h> #include <LODManager.h>
#include "BillboardOverlay.h" #include "BillboardOverlay.h"
@ -292,8 +291,8 @@ void Overlays::deleteOverlay(unsigned int id) {
unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
glm::vec2 pointCopy = point; glm::vec2 pointCopy = point;
if (OculusManager::isConnected()) { if (qApp->isHMDMode()) {
pointCopy = Application::getInstance()->getApplicationOverlay().screenToOverlay(point); pointCopy = qApp->getApplicationOverlay().screenToOverlay(point);
} }
QReadLocker lock(&_lock); QReadLocker lock(&_lock);

View file

@ -10,6 +10,7 @@
// //
#include "GPULogging.h" #include "GPULogging.h"
#include "GLBackendShared.h" #include "GLBackendShared.h"
#include <glm/gtc/type_ptr.hpp>
GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
{ {
@ -521,3 +522,29 @@ void GLBackend::do_glColor4f(Batch& batch, uint32 paramOffset) {
(void) CHECK_GL_ERROR(); (void) CHECK_GL_ERROR();
} }
void GLBackend::loadMatrix(GLenum target, const glm::mat4 & m) {
glMatrixMode(target);
glLoadMatrixf(glm::value_ptr(m));
}
void GLBackend::fetchMatrix(GLenum target, glm::mat4 & m) {
switch (target) {
case GL_MODELVIEW_MATRIX:
case GL_PROJECTION_MATRIX:
break;
// Lazy cheating
case GL_MODELVIEW:
target = GL_MODELVIEW_MATRIX;
break;
case GL_PROJECTION:
target = GL_PROJECTION_MATRIX;
break;
default:
Q_ASSERT_X(false, "GLBackend::fetchMatrix", "Bad matrix target");
}
glGetFloatv(target, glm::value_ptr(m));
}

View file

@ -79,6 +79,9 @@ public:
static GLShader* syncGPUObject(const Shader& shader); static GLShader* syncGPUObject(const Shader& shader);
static GLuint getShaderID(const ShaderPointer& shader); static GLuint getShaderID(const ShaderPointer& shader);
static void loadMatrix(GLenum target, const glm::mat4 & m);
static void fetchMatrix(GLenum target, glm::mat4 & m);
class GLState : public GPUObject { class GLState : public GPUObject {
public: public:
class Command { class Command {

View file

@ -142,22 +142,12 @@ gpu::FramebufferPointer GlowEffect::render() {
gpu::FramebufferPointer destFBO = textureCache->getSecondaryFramebuffer(); gpu::FramebufferPointer destFBO = textureCache->getSecondaryFramebuffer();
if (!_enabled || _isEmpty) { if (!_enabled || _isEmpty) {
// copy the primary to the screen // copy the primary to the screen
if (QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO));
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO)); glBindFramebuffer(GL_READ_FRAMEBUFFER, primaryFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER, primaryFBO); glBlitFramebuffer(
glBlitFramebuffer(0, 0, framebufferSize.width(), framebufferSize.height(), 0, 0, framebufferSize.width(), framebufferSize.height(),
0, 0, framebufferSize.width(), framebufferSize.height(), 0, 0, framebufferSize.width(), framebufferSize.height(),
GL_COLOR_BUFFER_BIT, GL_NEAREST); GL_COLOR_BUFFER_BIT, GL_NEAREST);
} else {
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO));
glViewport(0, 0, framebufferSize.width(), framebufferSize.height());
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
renderFullscreenQuad();
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
} else { } else {
// diffuse into the secondary/tertiary (alternating between frames) // diffuse into the secondary/tertiary (alternating between frames)
auto oldDiffusedFBO = auto oldDiffusedFBO =

View file

@ -1 +0,0 @@
#include "MatrixStack.h"

View file

@ -0,0 +1,43 @@
//
// OffscreenGlCanvas.cpp
// interface/src/renderer
//
// Created by Bradley Austin Davis on 2014/04/09.
// 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 "OffscreenGlContext.h"
OffscreenGlContext::OffscreenGlContext() {
}
void OffscreenGlContext::create(QOpenGLContext * sharedContext) {
QSurfaceFormat format;
format.setDepthBufferSize(16);
format.setStencilBufferSize(8);
format.setMajorVersion(4);
format.setMinorVersion(1);
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile);
_context.setFormat(format);
if (nullptr != sharedContext) {
_context.setShareContext(sharedContext);
}
_context.create();
_offscreenSurface.setFormat(_context.format());
_offscreenSurface.create();
}
bool OffscreenGlContext::makeCurrent() {
return _context.makeCurrent(&_offscreenSurface);
}
void OffscreenGlContext::doneCurrent() {
_context.doneCurrent();
}

View file

@ -0,0 +1,33 @@
//
// OffscreenGlCanvas.h
// interface/src/renderer
//
// Created by Bradley Austin Davis on 2014/04/09.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#pragma once
#ifndef hifi_OffscreenGlContext_h
#define hifi_OffscreenGlContext_h
#include <QOpenGLContext>
#include <QOffscreenSurface>
class OffscreenGlContext : public QObject {
public:
OffscreenGlContext();
void create(QOpenGLContext * sharedContext = nullptr);
bool makeCurrent();
void doneCurrent();
QOpenGLContext * getContext() {
return &_context;
}
protected:
QOpenGLContext _context;
QOffscreenSurface _offscreenSurface;
};
#endif // hifi_OffscreenGlCanvas_h

View file

@ -12,6 +12,8 @@
#ifndef hifi_RenderUtil_h #ifndef hifi_RenderUtil_h
#define hifi_RenderUtil_h #define hifi_RenderUtil_h
#include <MatrixStack.h>
/// Renders a quad from (-1, -1, 0) to (1, 1, 0) with texture coordinates from (sMin, tMin) to (sMax, tMax). /// Renders a quad from (-1, -1, 0) to (1, 1, 0) with texture coordinates from (sMin, tMin) to (sMax, tMax).
void renderFullscreenQuad(float sMin = 0.0f, float sMax = 1.0f, float tMin = 0.0f, float tMax = 1.0f); void renderFullscreenQuad(float sMin = 0.0f, float sMax = 1.0f, float tMin = 0.0f, float tMax = 1.0f);

View file

@ -548,18 +548,23 @@ float TextRenderer::draw(float x, float y, const QString & str,
float scale = (_pointSize / DEFAULT_POINT_SIZE) * 0.25f; float scale = (_pointSize / DEFAULT_POINT_SIZE) * 0.25f;
glm::vec2 result; glm::vec2 result;
MatrixStack::withGlMatrices([&] {
MatrixStack::withPushAll([&] {
MatrixStack & mv = MatrixStack::modelview(); MatrixStack & mv = MatrixStack::modelview();
// scale the modelview into font units MatrixStack & pr = MatrixStack::projection();
// FIXME migrate the constant scale factor into the geometry of the gpu::GLBackend::fetchMatrix(GL_MODELVIEW_MATRIX, mv.top());
// fonts so we don't have to flip the Y axis here and don't have to gpu::GLBackend::fetchMatrix(GL_PROJECTION_MATRIX, pr.top());
// scale at all.
mv.translate(glm::vec2(x, y)).scale(glm::vec3(scale, -scale, scale)); // scale the modelview into font units
// The font does all the OpenGL work // FIXME migrate the constant scale factor into the geometry of the
if (_font) { // fonts so we don't have to flip the Y axis here and don't have to
result = _font->drawString(x, y, str, actualColor, _effectType, bounds / scale); // scale at all.
} mv.translate(glm::vec2(x, y)).scale(glm::vec3(scale, -scale, scale));
}); // The font does all the OpenGL work
if (_font) {
result = _font->drawString(x, y, str, actualColor, _effectType, bounds / scale);
}
});
return result.x; return result.x;
} }

View file

@ -24,7 +24,7 @@ MenuItemProperties::MenuItemProperties() :
afterItem(""), afterItem(""),
isCheckable(false), isCheckable(false),
isChecked(false), isChecked(false),
isSeparator(false) isSeparator(false)
{ {
}; };

View file

@ -0,0 +1,9 @@
//
// Created by Bradley Austin Davis
// Copyright 2013 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 "MatrixStack.h"

View file

@ -1,21 +1,10 @@
/************************************************************************************ //
// Created by Bradley Austin Davis
Authors : Bradley Austin Davis <bdavis@saintandreas.org> // Copyright 2013 High Fidelity, Inc.
Copyright : Copyright Brad Davis. All Rights reserved. //
// Distributed under the Apache License, Version 2.0.
Licensed under the Apache License, Version 2.0 (the "License"); // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
you may not use this file except in compliance with the License. //
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
#pragma once #pragma once
#include <glm/glm.hpp> #include <glm/glm.hpp>
@ -26,10 +15,6 @@
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <stack> #include <stack>
#include <gpu/GPUConfig.h>
class MatrixStack : public std::stack<glm::mat4> { class MatrixStack : public std::stack<glm::mat4> {
public: public:
@ -183,22 +168,5 @@ public:
stack2.withPush(f); stack2.withPush(f);
}); });
} }
template <typename Function>
static void withGlMatrices(Function f) {
// Push the current stack, and then copy the values out of OpenGL
withPushAll([&] {
// Fetch the current matrices out of GL stack
// FIXME, eliminate the usage of deprecated GL
MatrixStack & mv = MatrixStack::modelview();
MatrixStack & pr = MatrixStack::projection();
glm::mat4 & mvm = mv.top();
glGetFloatv(GL_MODELVIEW_MATRIX, &(mvm[0][0]));
glm::mat4 & prm = pr.top();
glGetFloatv(GL_PROJECTION_MATRIX, &(prm[0][0]));
f();
});
}
}; };