mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-15 12:38:46 +02:00
first cut at 3D TV support
This commit is contained in:
parent
ebdf80a4ed
commit
a43844447c
6 changed files with 208 additions and 12 deletions
|
@ -57,6 +57,7 @@
|
|||
#include "Util.h"
|
||||
#include "devices/LeapManager.h"
|
||||
#include "devices/OculusManager.h"
|
||||
#include "devices/TV3DManager.h"
|
||||
#include "renderer/ProgramObject.h"
|
||||
#include "ui/TextRenderer.h"
|
||||
#include "InfoView.h"
|
||||
|
@ -439,7 +440,10 @@ void Application::paintGL() {
|
|||
|
||||
if (OculusManager::isConnected()) {
|
||||
OculusManager::display(whichCamera);
|
||||
|
||||
} else if (TV3DManager::isConnected()) {
|
||||
_glowEffect.prepare();
|
||||
TV3DManager::display(whichCamera);
|
||||
_glowEffect.render();
|
||||
} else {
|
||||
_glowEffect.prepare();
|
||||
|
||||
|
@ -474,8 +478,13 @@ void Application::paintGL() {
|
|||
_mirrorCamera.update(1.0f/_fps);
|
||||
|
||||
// set the bounds of rear mirror view
|
||||
glViewport(_mirrorViewRect.x(), _glWidget->height() - _mirrorViewRect.y() - _mirrorViewRect.height(), _mirrorViewRect.width(), _mirrorViewRect.height());
|
||||
glScissor(_mirrorViewRect.x(), _glWidget->height() - _mirrorViewRect.y() - _mirrorViewRect.height(), _mirrorViewRect.width(), _mirrorViewRect.height());
|
||||
float mirrorX = _mirrorViewRect.x();
|
||||
float mirrorY = _glWidget->height() - _mirrorViewRect.y() - _mirrorViewRect.height();
|
||||
float mirrorW = _mirrorViewRect.width();
|
||||
float mirrorH = _mirrorViewRect.height();
|
||||
|
||||
glViewport(mirrorX, mirrorY, mirrorW, mirrorH);
|
||||
glScissor(mirrorX, mirrorY, mirrorW, mirrorH);
|
||||
bool updateViewFrustum = false;
|
||||
updateProjectionMatrix(_mirrorCamera, updateViewFrustum);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
@ -501,14 +510,18 @@ void Application::paintGL() {
|
|||
_myAvatar.getSkeletonModel().setTranslation(_myAvatar.getHead().getFaceModel().getTranslation() -
|
||||
neckPosition);
|
||||
|
||||
displaySide(_mirrorCamera, true);
|
||||
//displaySide(_mirrorCamera, true);
|
||||
displaySide(whichCamera);
|
||||
|
||||
|
||||
// restore absolute translations
|
||||
_myAvatar.getSkeletonModel().setTranslation(absoluteSkeletonTranslation);
|
||||
_myAvatar.getHead().getFaceModel().setTranslation(absoluteFaceTranslation);
|
||||
|
||||
} else {
|
||||
displaySide(_mirrorCamera, true);
|
||||
//displaySide(_mirrorCamera, true);
|
||||
displaySide(whichCamera);
|
||||
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
|
@ -531,7 +544,8 @@ void Application::paintGL() {
|
|||
void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height) {
|
||||
if (OculusManager::isConnected()) {
|
||||
OculusManager::configureCamera(camera, width, height);
|
||||
|
||||
} else if (TV3DManager::isConnected()) {
|
||||
TV3DManager::configureCamera(camera, width, height);
|
||||
} else {
|
||||
camera.setAspectRatio((float)width / height);
|
||||
camera.setFieldOfView(Menu::getInstance()->getFieldOfView());
|
||||
|
@ -910,7 +924,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
case Qt::Key_J:
|
||||
if (isShifted) {
|
||||
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() - 0.1f);
|
||||
|
||||
if (TV3DManager::isConnected()) {
|
||||
TV3DManager::configureCamera(_myCamera, _glWidget->width(),_glWidget->height());
|
||||
}
|
||||
} else {
|
||||
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(-0.001, 0, 0));
|
||||
}
|
||||
|
@ -920,6 +936,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
case Qt::Key_M:
|
||||
if (isShifted) {
|
||||
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() + 0.1f);
|
||||
if (TV3DManager::isConnected()) {
|
||||
TV3DManager::configureCamera(_myCamera, _glWidget->width(),_glWidget->height());
|
||||
}
|
||||
|
||||
} else {
|
||||
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0.001, 0, 0));
|
||||
|
@ -1828,6 +1847,13 @@ void Application::init() {
|
|||
"trigger",
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
TV3DManager::connect();
|
||||
if (TV3DManager::isConnected()) {
|
||||
QMetaObject::invokeMethod(Menu::getInstance()->getActionForOption(MenuOption::Fullscreen),
|
||||
"trigger",
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
LeapManager::initialize();
|
||||
|
||||
|
@ -2415,7 +2441,7 @@ void Application::updateCamera(float deltaTime) {
|
|||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateCamera()");
|
||||
|
||||
if (!OculusManager::isConnected()) {
|
||||
if (!OculusManager::isConnected() && !TV3DManager::isConnected()) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
|
||||
_myCamera.setMode(CAMERA_MODE_MIRROR);
|
||||
|
@ -3800,7 +3826,7 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
|||
return;
|
||||
}
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... Avatars...");
|
||||
"Application::renderAvatars()");
|
||||
|
||||
if (!selfAvatarOnly) {
|
||||
// Render avatars of other nodes
|
||||
|
@ -4089,7 +4115,7 @@ void Application::resetSensors() {
|
|||
if (OculusManager::isConnected()) {
|
||||
OculusManager::reset();
|
||||
}
|
||||
|
||||
|
||||
QCursor::setPos(_headMouseX, _headMouseY);
|
||||
_myAvatar.reset();
|
||||
_myTransmitter.resetLevels();
|
||||
|
|
|
@ -255,11 +255,13 @@ private slots:
|
|||
void resetSensors();
|
||||
|
||||
|
||||
private:
|
||||
void resetCamerasOnResizeGL(Camera& camera, int width, int height);
|
||||
public:
|
||||
void updateProjectionMatrix();
|
||||
void updateProjectionMatrix(Camera& camera, bool updateViewFrustum = true);
|
||||
|
||||
private:
|
||||
void resetCamerasOnResizeGL(Camera& camera, int width, int height);
|
||||
|
||||
static bool sendVoxelsOperation(OctreeElement* node, void* extraData);
|
||||
static void processAvatarURLsMessage(unsigned char* packetData, size_t dataBytes);
|
||||
static void processAvatarFaceVideoMessage(unsigned char* packetData, size_t dataBytes);
|
||||
|
|
|
@ -232,6 +232,8 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, false);
|
||||
|
||||
|
||||
QMenu* avatarSizeMenu = viewMenu->addMenu("Avatar Size");
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ namespace MenuOption {
|
|||
const QString FilterSixense = "Smooth Sixense Movement";
|
||||
const QString DontRenderVoxels = "Don't call _voxels.render()";
|
||||
const QString DontCallOpenGLForVoxels = "Don't call glDrawRangeElementsEXT() for Voxels";
|
||||
const QString Enable3DTVMode = "Enable 3DTV Mode";
|
||||
const QString EnableOcclusionCulling = "Enable Occlusion Culling";
|
||||
const QString EnableVoxelPacketCompression = "Enable Voxel Packet Compression";
|
||||
const QString EchoServerAudio = "Echo Server Audio";
|
||||
|
|
124
interface/src/devices/TV3DManager.cpp
Normal file
124
interface/src/devices/TV3DManager.cpp
Normal file
|
@ -0,0 +1,124 @@
|
|||
//
|
||||
// TV3DManager.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 5/9/13.
|
||||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <QOpenGLFramebufferObject>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "Application.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "TV3DManager.h"
|
||||
#include "Menu.h"
|
||||
|
||||
int TV3DManager::_screenWidth = 1;
|
||||
int TV3DManager::_screenHeight = 1;
|
||||
double TV3DManager::_aspect = 1.0;
|
||||
eyeFrustum TV3DManager::_leftEye;
|
||||
eyeFrustum TV3DManager::_rightEye;
|
||||
|
||||
|
||||
bool TV3DManager::isConnected() {
|
||||
return Menu::getInstance()->isOptionChecked(MenuOption::Enable3DTVMode);
|
||||
}
|
||||
|
||||
void TV3DManager::connect() {
|
||||
}
|
||||
|
||||
|
||||
void TV3DManager::setFrustum(Camera& whichCamera) {
|
||||
const double DTR = 0.0174532925; // degree to radians
|
||||
const double IOD = 0.05; //intraocular distance
|
||||
double fovy = whichCamera.getFieldOfView(); // field of view in y-axis
|
||||
double nearZ = whichCamera.getNearClip(); // near clipping plane
|
||||
double screenZ = Application::getInstance()->getViewFrustum()->getFocalLength(); // screen projection plane
|
||||
|
||||
double top = nearZ * tan(DTR * fovy / 2); //sets top of frustum based on fovy and near clipping plane
|
||||
double right = _aspect * top; // sets right of frustum based on aspect ratio
|
||||
double frustumshift = (IOD / 2) * nearZ / screenZ;
|
||||
|
||||
_leftEye.top = top;
|
||||
_leftEye.bottom = -top;
|
||||
_leftEye.left = -right + frustumshift;
|
||||
_leftEye.right = right + frustumshift;
|
||||
_leftEye.modelTranslation = IOD / 2;
|
||||
|
||||
_rightEye.top = top;
|
||||
_rightEye.bottom = -top;
|
||||
_rightEye.left = -right - frustumshift;
|
||||
_rightEye.right = right - frustumshift;
|
||||
_rightEye.modelTranslation = -IOD / 2;
|
||||
}
|
||||
|
||||
void TV3DManager::configureCamera(Camera& whichCamera, int screenWidth, int screenHeight) {
|
||||
if (screenHeight == 0) {
|
||||
screenHeight = 1; // prevent divide by 0
|
||||
}
|
||||
_screenWidth = screenWidth;
|
||||
_screenHeight = screenHeight;
|
||||
_aspect= (double)_screenWidth / (double)_screenHeight;
|
||||
setFrustum(whichCamera);
|
||||
|
||||
glViewport (0, 0, _screenWidth, _screenHeight); // sets drawing viewport
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void TV3DManager::display(Camera& whichCamera) {
|
||||
double nearZ = whichCamera.getNearClip(); // near clipping plane
|
||||
double farZ = whichCamera.getFarClip(); // far clipping plane
|
||||
|
||||
// left eye portal
|
||||
int portalX = 0;
|
||||
int portalY = 0;
|
||||
int portalW = Application::getInstance()->getGLWidget()->width() / 2;
|
||||
int portalH = Application::getInstance()->getGLWidget()->height();
|
||||
|
||||
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);
|
||||
|
||||
glPushMatrix();
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity(); // reset projection matrix
|
||||
glFrustum(_leftEye.left, _leftEye.right, _leftEye.bottom, _leftEye.top, nearZ, farZ); // set left view frustum
|
||||
glTranslatef(_leftEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
Application::getInstance()->displaySide(whichCamera);
|
||||
}
|
||||
glPopMatrix();
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
// render right side view
|
||||
portalX = Application::getInstance()->getGLWidget()->width() / 2;
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
// render left side view
|
||||
glViewport(portalX, portalY, portalW, portalH);
|
||||
glScissor(portalX, portalY, portalW, portalH);
|
||||
glPushMatrix();
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity(); // reset projection matrix
|
||||
glFrustum(_rightEye.left, _rightEye.right, _rightEye.bottom, _rightEye.top, nearZ, farZ); // set left view frustum
|
||||
glTranslatef(_rightEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
Application::getInstance()->displaySide(whichCamera);
|
||||
}
|
||||
glPopMatrix();
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
// reset the viewport to how we started
|
||||
glViewport(0, 0, Application::getInstance()->getGLWidget()->width(), Application::getInstance()->getGLWidget()->height());
|
||||
}
|
41
interface/src/devices/TV3DManager.h
Normal file
41
interface/src/devices/TV3DManager.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// TV3DManager.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/24/2013
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__TV3DManager__
|
||||
#define __hifi__TV3DManager__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class Camera;
|
||||
|
||||
struct eyeFrustum {
|
||||
double left;
|
||||
double right;
|
||||
double bottom;
|
||||
double top;
|
||||
float modelTranslation;
|
||||
};
|
||||
|
||||
|
||||
/// Handles interaction with 3D TVs
|
||||
class TV3DManager {
|
||||
public:
|
||||
static void connect();
|
||||
static bool isConnected();
|
||||
static void configureCamera(Camera& camera, int screenWidth, int screenHeight);
|
||||
static void display(Camera& whichCamera);
|
||||
private:
|
||||
static void setFrustum(Camera& whichCamera);
|
||||
static int _screenWidth;
|
||||
static int _screenHeight;
|
||||
static double _aspect;
|
||||
static eyeFrustum _leftEye;
|
||||
static eyeFrustum _rightEye;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__TV3DManager__) */
|
Loading…
Reference in a new issue