mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Working on display plugins
This commit is contained in:
parent
e651c722c3
commit
b5e6b737c4
21 changed files with 220 additions and 873 deletions
|
@ -316,7 +316,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
_previousScriptLocation("LastScriptLocation"),
|
||||
_scriptsLocationHandle("scriptsLocation"),
|
||||
_fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES),
|
||||
_viewTransform(),
|
||||
_scaleMirror(1.0f),
|
||||
_rotateMirror(0.0f),
|
||||
_raiseMirror(0.0f),
|
||||
|
@ -878,7 +877,7 @@ void Application::paintGL() {
|
|||
|
||||
// Sync up the View Furstum with the camera
|
||||
// FIXME: it's happening again in the updateSHadow and it shouldn't, this should be the place
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
_myCamera.loadViewFrustum(_viewFrustum);
|
||||
|
||||
if (getShadowsEnabled()) {
|
||||
updateShadowMap();
|
||||
|
@ -891,43 +890,40 @@ void Application::paintGL() {
|
|||
auto finalFbo = primaryFbo;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFbo));
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glPushMatrix();
|
||||
{
|
||||
// Viewport is assigned to the size of the framebuffer
|
||||
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
|
||||
if (displayPlugin->isStereo()) {
|
||||
QRect r(QPoint(0, 0), QSize(size.width() / 2, size.height()));
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for_each_eye([&](Eye eye){
|
||||
// FIXME we need to let the display plugin decide how the geometry works for stereo rendering
|
||||
// for instance, an interleaved display should have half the vertical resolution, while a side
|
||||
// by side display for a temporal interleave should have full resolution
|
||||
glViewport(r.x(), r.y(), r.width(), r.height());
|
||||
glScissor(r.x(), r.y(), r.width(), r.height());
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
// FIXME Fetch the projection matrix from the plugin
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
// Load the view frustum, used by meshes
|
||||
Camera eyeCamera;
|
||||
eyeCamera.setRotation(_myCamera.getRotation());
|
||||
eyeCamera.setPosition(_myCamera.getPosition());
|
||||
eyeCamera.setTransform(displayPlugin->getModelview(eye, _myCamera.getTransform()));
|
||||
eyeCamera.setProjection(displayPlugin->getProjection(eye, _myCamera.getProjection()));
|
||||
|
||||
displaySide(eyeCamera);
|
||||
glPopMatrix();
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||
glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition();
|
||||
_rearMirrorTools->render(true, QPoint(mpos.x, mpos.y));
|
||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||
renderRearViewMirror(_mirrorViewRect);
|
||||
}
|
||||
}, [&] {
|
||||
r.moveLeft(r.width());
|
||||
}
|
||||
});
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
} else {
|
||||
glViewport(0, 0, size.width(), size.height());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
displaySide(_myCamera);
|
||||
glPopMatrix();
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||
glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition();
|
||||
_rearMirrorTools->render(true, QPoint(mpos.x, mpos.y));
|
||||
|
@ -938,6 +934,8 @@ void Application::paintGL() {
|
|||
finalFbo = DependencyManager::get<GlowEffect>()->render();
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
// This might not be needed *right now*. We want to ensure that the FBO rendering
|
||||
// has completed before we start trying to read from it in another context. However
|
||||
// once we have multi-threaded rendering, this will almost certainly be critical,
|
||||
|
@ -984,19 +982,6 @@ void Application::showEditEntitiesHelp() {
|
|||
InfoView::show(INFO_EDIT_ENTITIES_PATH);
|
||||
}
|
||||
|
||||
void Application::resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size) {
|
||||
#if 0
|
||||
if (OculusManager::isConnected()) {
|
||||
OculusManager::configureCamera(camera);
|
||||
} else if (TV3DManager::isConnected()) {
|
||||
TV3DManager::configureCamera(camera, size.x, size.y);
|
||||
} else {
|
||||
#endif
|
||||
camera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), (float)size.x / size.y, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Application::resizeEvent(QResizeEvent * event) {
|
||||
resizeGL();
|
||||
|
@ -1014,12 +999,9 @@ void Application::resizeGL() {
|
|||
|
||||
_renderResolution = toGlm(renderSize);
|
||||
DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
|
||||
resetCamerasOnResizeGL(_myCamera, _renderResolution);
|
||||
|
||||
glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu???
|
||||
|
||||
updateProjectionMatrix();
|
||||
glLoadIdentity();
|
||||
_myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()),
|
||||
aspect(getCanvasSize()), DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
offscreenUi->resize(fromGlm(getCanvasSize()));
|
||||
|
@ -1031,24 +1013,6 @@ void Application::resizeGL() {
|
|||
Stats::getInstance()->resetWidth(_renderResolution.x, horizontalOffset);
|
||||
}
|
||||
|
||||
void Application::updateProjectionMatrix() {
|
||||
updateProjectionMatrix(_myCamera);
|
||||
}
|
||||
|
||||
void Application::updateProjectionMatrix(Camera& camera, bool updateViewFrustum) {
|
||||
_projectionMatrix = camera.getProjection();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(glm::value_ptr(_projectionMatrix));
|
||||
|
||||
// Tell our viewFrustum about this change, using the application camera
|
||||
if (updateViewFrustum) {
|
||||
loadViewFrustum(camera, _viewFrustum);
|
||||
}
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
void Application::controlledBroadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) {
|
||||
foreach(NodeType_t type, destinationNodeTypes) {
|
||||
// Perform the broadcast for one type
|
||||
|
@ -2205,7 +2169,7 @@ void Application::updateMouseRay() {
|
|||
PerformanceWarning warn(showWarnings, "Application::updateMouseRay()");
|
||||
|
||||
// make sure the frustum is up-to-date
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
_myCamera.loadViewFrustum(_viewFrustum);
|
||||
|
||||
PickRay pickRay = computePickRay(getTrueMouseX(), getTrueMouseY());
|
||||
_mouseRayOrigin = pickRay.origin;
|
||||
|
@ -2491,7 +2455,7 @@ void Application::update(float deltaTime) {
|
|||
// to the server.
|
||||
{
|
||||
PerformanceTimer perfTimer("loadViewFrustum");
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
_myCamera.loadViewFrustum(_viewFrustum);
|
||||
}
|
||||
|
||||
quint64 now = usecTimestampNow();
|
||||
|
@ -2826,24 +2790,6 @@ QRect Application::getDesirableApplicationGeometry() {
|
|||
return applicationGeometry;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// loadViewFrustum()
|
||||
//
|
||||
// Description: this will load the view frustum bounds for EITHER the head
|
||||
// or the "myCamera".
|
||||
//
|
||||
void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
||||
// We will use these below, from either the camera or head vectors calculated above
|
||||
viewFrustum.setProjection(camera.getProjection());
|
||||
|
||||
// Set the viewFrustum up with the correct position and orientation of the camera
|
||||
viewFrustum.setPosition(camera.getPosition());
|
||||
viewFrustum.setOrientation(camera.getRotation());
|
||||
|
||||
// Ask the ViewFrustum class to calculate our corners
|
||||
viewFrustum.calculate();
|
||||
}
|
||||
|
||||
glm::vec3 Application::getSunDirection() {
|
||||
// Sun direction is in fact just the location of the sun relative to the origin
|
||||
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
||||
|
@ -2872,7 +2818,7 @@ void Application::updateShadowMap() {
|
|||
glm::vec2(0.0f, 0.5f), glm::vec2(0.5f, 0.5f) };
|
||||
|
||||
float frustumScale = 1.0f / (_viewFrustum.getFarClip() - _viewFrustum.getNearClip());
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
_myCamera.loadViewFrustum(_viewFrustum);
|
||||
|
||||
int matrixCount = 1;
|
||||
//int targetSize = fbo->width();
|
||||
|
@ -2944,28 +2890,18 @@ void Application::updateShadowMap() {
|
|||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z);
|
||||
|
||||
glm::mat4 projAgain;
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat*)&projAgain);
|
||||
|
||||
glm::mat4 proj = glm::ortho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z);
|
||||
glLoadMatrixf(glm::value_ptr(proj));
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glm::vec3 axis = glm::axis(inverseRotation);
|
||||
glRotatef(glm::degrees(glm::angle(inverseRotation)), axis.x, axis.y, axis.z);
|
||||
glLoadMatrixf(glm::value_ptr(glm::mat4_cast(inverseRotation)));
|
||||
|
||||
// store view matrix without translation, which we'll use for precision-sensitive objects
|
||||
updateUntranslatedViewMatrix();
|
||||
|
||||
// Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation
|
||||
// the viewTransofmr object is updatded with the correct values and saved,
|
||||
// this is what is used for rendering the Entities and avatars
|
||||
Transform viewTransform;
|
||||
viewTransform.setRotation(rotation);
|
||||
// viewTransform.postTranslate(shadowFrustumCenter);
|
||||
setViewTransform(viewTransform);
|
||||
|
||||
|
||||
|
@ -3003,7 +2939,6 @@ void Application::updateShadowMap() {
|
|||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
// glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
|
||||
activeRenderingThread = nullptr;
|
||||
}
|
||||
|
||||
|
@ -3118,16 +3053,23 @@ const ViewFrustum* Application::getDisplayViewFrustum() const {
|
|||
return &_displayViewFrustum;
|
||||
}
|
||||
|
||||
void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) {
|
||||
void Application::displaySide(const Camera& theCamera, bool selfAvatarOnly) {
|
||||
activeRenderingThread = QThread::currentThread();
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
PerformanceTimer perfTimer("display");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
||||
// transform by eye offset
|
||||
|
||||
// load the view frustum
|
||||
loadViewFrustum(theCamera, _displayViewFrustum);
|
||||
theCamera.loadViewFrustum(_displayViewFrustum);
|
||||
|
||||
// Load the legacy GL stacks, used by entities (for now)
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(glm::value_ptr(theCamera.getProjection()));
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(glm::value_ptr(glm::inverse(theCamera.getTransform())));
|
||||
|
||||
// FIXME just flip the texture coordinates
|
||||
// flip x if in mirror mode (also requires reversing winding order for backface culling)
|
||||
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||
glScalef(-1.0f, 1.0f, 1.0f);
|
||||
|
@ -3137,17 +3079,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
||||
// transform view according to theCamera
|
||||
// could be myCamera (if in normal mode)
|
||||
// or could be viewFrustumOffsetCamera if in offset mode
|
||||
|
||||
glm::quat rotation = theCamera.getRotation();
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(-glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
|
||||
// store view matrix without translation, which we'll use for precision-sensitive objects
|
||||
updateUntranslatedViewMatrix(-theCamera.getPosition());
|
||||
|
||||
// Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation
|
||||
// the viewTransofmr object is updatded with the correct values and saved,
|
||||
// this is what is used for rendering the Entities and avatars
|
||||
|
@ -3157,17 +3089,8 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||
viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
if (renderSide != RenderArgs::MONO) {
|
||||
glm::mat4 invView = glm::inverse(_untranslatedViewMatrix);
|
||||
|
||||
viewTransform.evalFromRawMatrix(invView);
|
||||
viewTransform.preTranslate(_viewMatrixTranslation);
|
||||
}
|
||||
|
||||
setViewTransform(viewTransform);
|
||||
|
||||
glTranslatef(_viewMatrixTranslation.x, _viewMatrixTranslation.y, _viewMatrixTranslation.z);
|
||||
|
||||
// Setup 3D lights (after the camera transform, so that they are positioned in world space)
|
||||
{
|
||||
PerformanceTimer perfTimer("lights");
|
||||
|
@ -3208,7 +3131,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||
// TODO: handle this correctly for zones
|
||||
const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition());
|
||||
const EnvironmentData& closestData = _environment.getClosestData(_displayViewFrustum.getPosition());
|
||||
|
||||
if (closestData.getHasStars()) {
|
||||
const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
|
||||
|
@ -3216,7 +3139,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
|
||||
glm::vec3 sunDirection = (getAvatarPosition() - closestData.getSunLocation())
|
||||
/ closestData.getAtmosphereOuterRadius();
|
||||
float height = glm::distance(theCamera.getPosition(), closestData.getAtmosphereCenter());
|
||||
float height = glm::distance(_displayViewFrustum.getPosition(), closestData.getAtmosphereCenter());
|
||||
if (height < closestData.getAtmosphereInnerRadius()) {
|
||||
// If we're inside the atmosphere, then determine if our keyLight is below the horizon
|
||||
alpha = 0.0f;
|
||||
|
@ -3255,7 +3178,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
PerformanceTimer perfTimer("atmosphere");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... atmosphere...");
|
||||
_environment.renderAtmospheres(theCamera);
|
||||
_environment.renderAtmospheres(_displayViewFrustum.getPosition());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3303,7 +3226,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||
renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||
}
|
||||
_entities.render(renderMode, renderSide, renderDebugFlags);
|
||||
_entities.render(renderMode, RenderArgs::MONO, renderDebugFlags);
|
||||
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
||||
// Restaure polygon mode
|
||||
|
@ -3327,7 +3250,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
}
|
||||
|
||||
bool mirrorMode = (theCamera.getMode() == CAMERA_MODE_MIRROR);
|
||||
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("avatars");
|
||||
DependencyManager::get<AvatarManager>()->renderAvatars(mirrorMode ? RenderArgs::MIRROR_RENDER_MODE : RenderArgs::NORMAL_RENDER_MODE,
|
||||
|
@ -3362,7 +3285,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
_nodeBoundsDisplay.draw();
|
||||
|
||||
// Render the world box
|
||||
if (theCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
||||
if (!mirrorMode && Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
||||
PerformanceTimer perfTimer("worldBox");
|
||||
renderWorldBox();
|
||||
}
|
||||
|
@ -3405,33 +3328,32 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
activeRenderingThread = nullptr;
|
||||
}
|
||||
|
||||
void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation) {
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix);
|
||||
_viewMatrixTranslation = viewMatrixTranslation;
|
||||
}
|
||||
|
||||
void Application::setViewTransform(const Transform& view) {
|
||||
_viewTransform = view;
|
||||
}
|
||||
|
||||
void Application::loadTranslatedViewMatrix(const glm::vec3& translation) {
|
||||
glLoadMatrixf((const GLfloat*)&_untranslatedViewMatrix);
|
||||
glTranslatef(translation.x + _viewMatrixTranslation.x, translation.y + _viewMatrixTranslation.y,
|
||||
translation.z + _viewMatrixTranslation.z);
|
||||
}
|
||||
//void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation) {
|
||||
// glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix);
|
||||
// _viewMatrixTranslation = viewMatrixTranslation;
|
||||
//}
|
||||
//
|
||||
//void Application::loadTranslatedViewMatrix(const glm::vec3& translation) {
|
||||
// glLoadMatrixf((const GLfloat*)&_untranslatedViewMatrix);
|
||||
// glTranslatef(translation.x + _viewMatrixTranslation.x, translation.y + _viewMatrixTranslation.y,
|
||||
// translation.z + _viewMatrixTranslation.z);
|
||||
//}
|
||||
//
|
||||
//void Application::getModelViewMatrix(glm::dmat4* modelViewMatrix) {
|
||||
// (*modelViewMatrix) =_untranslatedViewMatrix;
|
||||
// (*modelViewMatrix)[3] = _untranslatedViewMatrix * glm::vec4(_viewMatrixTranslation, 1);
|
||||
//}
|
||||
|
||||
void Application::getModelViewMatrix(glm::dmat4* modelViewMatrix) {
|
||||
(*modelViewMatrix) =_untranslatedViewMatrix;
|
||||
(*modelViewMatrix)[3] = _untranslatedViewMatrix * glm::vec4(_viewMatrixTranslation, 1);
|
||||
(*modelViewMatrix) = glm::inverse(_displayViewFrustum.getView());
|
||||
}
|
||||
|
||||
void Application::getProjectionMatrix(glm::dmat4* projectionMatrix) {
|
||||
*projectionMatrix = _projectionMatrix;
|
||||
}
|
||||
|
||||
void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
||||
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const {
|
||||
_displayViewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
*projectionMatrix = _displayViewFrustum.getProjection();
|
||||
}
|
||||
|
||||
bool Application::getShadowsEnabled() {
|
||||
|
@ -3497,8 +3419,6 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
|
|||
glViewport(x, size.height() - y - height, width, height);
|
||||
glScissor(x, size.height() - y - height, width, height);
|
||||
}
|
||||
bool updateViewFrustum = false;
|
||||
updateProjectionMatrix(_mirrorCamera, updateViewFrustum);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
@ -3511,11 +3431,9 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
|
|||
glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition();
|
||||
_rearMirrorTools->render(false, QPoint(mpos.x, mpos.y));
|
||||
}
|
||||
|
||||
// reset Viewport and projection matrix
|
||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
updateProjectionMatrix(_myCamera, updateViewFrustum);
|
||||
}
|
||||
|
||||
void Application::resetSensors() {
|
||||
|
@ -4598,11 +4516,11 @@ void Application::shutdownPlugins() {
|
|||
}
|
||||
|
||||
glm::vec3 Application::getHeadPosition() const {
|
||||
return getActiveDisplayPlugin()->headTranslation();
|
||||
return glm::vec3(getActiveDisplayPlugin()->getHeadPose()[3]);
|
||||
}
|
||||
|
||||
glm::quat Application::getHeadOrientation() const {
|
||||
return getActiveDisplayPlugin()->headOrientation();
|
||||
return glm::quat_cast(getActiveDisplayPlugin()->getHeadPose());
|
||||
}
|
||||
|
||||
glm::uvec2 Application::getCanvasSize() const {
|
||||
|
|
|
@ -249,10 +249,11 @@ public:
|
|||
Overlays& getOverlays() { return _overlays; }
|
||||
|
||||
float getFps() const { return _fps; }
|
||||
const glm::vec3& getViewMatrixTranslation() const { return _viewMatrixTranslation; }
|
||||
void setViewMatrixTranslation(const glm::vec3& translation) { _viewMatrixTranslation = translation; }
|
||||
//const glm::vec3& getViewMatrixTranslation() const { return _viewMatrixTranslation; }
|
||||
//void setViewMatrixTranslation(const glm::vec3& translation) { _viewMatrixTranslation = translation; }
|
||||
|
||||
virtual const Transform& getViewTransform() const { return _viewTransform; }
|
||||
virtual Transform& getViewTransform() { return _viewTransform; }
|
||||
void setViewTransform(const Transform& view);
|
||||
|
||||
float getFieldOfView() { return _fieldOfView.get(); }
|
||||
|
@ -278,8 +279,9 @@ public:
|
|||
|
||||
QImage renderAvatarBillboard();
|
||||
|
||||
void displaySide(Camera& whichCamera, bool selfAvatarOnly = false, RenderArgs::RenderSide renderSide = RenderArgs::MONO);
|
||||
void displaySide(const Camera& camera, bool selfAvatarOnly = false);
|
||||
|
||||
/*
|
||||
/// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as
|
||||
/// the view matrix translation.
|
||||
void updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation = glm::vec3());
|
||||
|
@ -289,16 +291,11 @@ public:
|
|||
/// Loads a view matrix that incorporates the specified model translation without the precision issues that can
|
||||
/// result from matrix multiplication at high translation magnitudes.
|
||||
void loadTranslatedViewMatrix(const glm::vec3& translation);
|
||||
|
||||
*/
|
||||
void getModelViewMatrix(glm::dmat4* modelViewMatrix);
|
||||
void getProjectionMatrix(glm::dmat4* projectionMatrix);
|
||||
|
||||
virtual const glm::vec3& getShadowDistances() const { return _shadowDistances; }
|
||||
|
||||
/// Computes the off-axis frustum parameters for the view frustum, taking mirroring into account.
|
||||
virtual void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
||||
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const;
|
||||
|
||||
virtual ViewFrustum* getCurrentViewFrustum() { return getDisplayViewFrustum(); }
|
||||
virtual bool getShadowsEnabled();
|
||||
virtual bool getCascadeShadowsEnabled();
|
||||
|
@ -476,10 +473,6 @@ private slots:
|
|||
void setCursorVisible(bool visible);
|
||||
|
||||
private:
|
||||
void resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size);
|
||||
void updateProjectionMatrix();
|
||||
void updateProjectionMatrix(Camera& camera, bool updateViewFrustum = true);
|
||||
|
||||
void updateCursorVisibility();
|
||||
|
||||
void sendPingPackets();
|
||||
|
@ -505,7 +498,6 @@ private:
|
|||
void renderLookatIndicator(glm::vec3 pointOfInterest);
|
||||
|
||||
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
|
||||
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
|
||||
|
||||
glm::vec3 getSunDirection();
|
||||
|
||||
|
@ -579,9 +571,11 @@ private:
|
|||
Setting::Handle<float> _fieldOfView;
|
||||
|
||||
Transform _viewTransform;
|
||||
glm::mat4 _projectionMatrix;
|
||||
/*
|
||||
glm::mat4 _untranslatedViewMatrix;
|
||||
glm::vec3 _viewMatrixTranslation;
|
||||
glm::mat4 _projectionMatrix;
|
||||
*/
|
||||
|
||||
float _scaleMirror;
|
||||
float _rotateMirror;
|
||||
|
|
|
@ -46,13 +46,7 @@ QString modeToString(CameraMode mode) {
|
|||
}
|
||||
|
||||
Camera::Camera() :
|
||||
_mode(CAMERA_MODE_THIRD_PERSON),
|
||||
_position(0.0f, 0.0f, 0.0f),
|
||||
_projection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), 16.0f/9.0f, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)),
|
||||
_hmdPosition(),
|
||||
_hmdRotation(),
|
||||
_isKeepLookingAt(false),
|
||||
_lookingAt(0.0f, 0.0f, 0.0f)
|
||||
_projection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), 16.0f/9.0f, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -63,26 +57,33 @@ void Camera::update(float deltaTime) {
|
|||
return;
|
||||
}
|
||||
|
||||
void Camera::recompose() {
|
||||
mat4 orientation = glm::mat4_cast(_rotation);
|
||||
mat4 translation = glm::translate(mat4(), _position);
|
||||
_transform = translation * orientation;
|
||||
}
|
||||
|
||||
void Camera::decompose() {
|
||||
_position = vec3(_transform[3]);
|
||||
_rotation = glm::quat_cast(_transform);
|
||||
}
|
||||
|
||||
void Camera::setTransform(const glm::mat4& transform) {
|
||||
_transform = transform;
|
||||
decompose();
|
||||
}
|
||||
|
||||
void Camera::setPosition(const glm::vec3& position) {
|
||||
_position = position;
|
||||
_position = position;
|
||||
recompose();
|
||||
if (_isKeepLookingAt) {
|
||||
lookAt(_lookingAt);
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::setRotation(const glm::quat& rotation) {
|
||||
_rotation = rotation;
|
||||
if (_isKeepLookingAt) {
|
||||
lookAt(_lookingAt);
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::setHmdPosition(const glm::vec3& hmdPosition) {
|
||||
_hmdPosition = hmdPosition;
|
||||
if (_isKeepLookingAt) {
|
||||
lookAt(_lookingAt);
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::setHmdRotation(const glm::quat& hmdRotation) {
|
||||
_hmdRotation = hmdRotation;
|
||||
recompose();
|
||||
if (_isKeepLookingAt) {
|
||||
lookAt(_lookingAt);
|
||||
}
|
||||
|
@ -143,3 +144,21 @@ void Camera::keepLookingAt(const glm::vec3& point) {
|
|||
_isKeepLookingAt = true;
|
||||
_lookingAt = point;
|
||||
}
|
||||
|
||||
void Camera::loadViewFrustum(ViewFrustum& frustum) const {
|
||||
// We will use these below, from either the camera or head vectors calculated above
|
||||
frustum.setProjection(getProjection());
|
||||
|
||||
// Set the viewFrustum up with the correct position and orientation of the camera
|
||||
frustum.setPosition(getPosition());
|
||||
frustum.setOrientation(getRotation());
|
||||
|
||||
// Ask the ViewFrustum class to calculate our corners
|
||||
frustum.calculate();
|
||||
}
|
||||
|
||||
ViewFrustum Camera::toViewFrustum() const {
|
||||
ViewFrustum result;
|
||||
loadViewFrustum(result);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -43,28 +43,31 @@ public:
|
|||
|
||||
void update( float deltaTime );
|
||||
|
||||
void setRotation(const glm::quat& rotation);
|
||||
void setProjection(const glm::mat4 & projection);
|
||||
void setHmdPosition(const glm::vec3& hmdPosition);
|
||||
void setHmdRotation(const glm::quat& hmdRotation);
|
||||
CameraMode getMode() const { return _mode; }
|
||||
void setMode(CameraMode m);
|
||||
|
||||
glm::quat getRotation() const { return _rotation * _hmdRotation; }
|
||||
const glm::mat4& getProjection() const { return _projection; }
|
||||
const glm::vec3& getHmdPosition() const { return _hmdPosition; }
|
||||
const glm::quat& getHmdRotation() const { return _hmdRotation; }
|
||||
CameraMode getMode() const { return _mode; }
|
||||
void setProjection(const glm::mat4& projection);
|
||||
|
||||
void loadViewFrustum(ViewFrustum& frustum) const;
|
||||
ViewFrustum toViewFrustum() const;
|
||||
|
||||
public slots:
|
||||
QString getModeString() const;
|
||||
void setModeString(const QString& mode);
|
||||
|
||||
glm::vec3 getPosition() const { return _position + _hmdPosition; }
|
||||
const glm::quat getRotation() const { return _rotation; }
|
||||
void setRotation(const glm::quat& rotation);
|
||||
|
||||
const glm::vec3 getPosition() const { return _position; }
|
||||
void setPosition(const glm::vec3& position);
|
||||
|
||||
const glm::quat getOrientation() const { return getRotation(); }
|
||||
void setOrientation(const glm::quat& orientation) { setRotation(orientation); }
|
||||
glm::quat getOrientation() const { return getRotation(); }
|
||||
|
||||
|
||||
const glm::mat4 getTransform() const { return _transform; }
|
||||
void setTransform(const glm::mat4& transform);
|
||||
|
||||
PickRay computePickRay(float x, float y);
|
||||
|
||||
// These only work on independent cameras
|
||||
|
@ -82,13 +85,17 @@ signals:
|
|||
void modeUpdated(const QString& newMode);
|
||||
|
||||
private:
|
||||
CameraMode _mode;
|
||||
void recompose();
|
||||
void decompose();
|
||||
|
||||
CameraMode _mode{ CAMERA_MODE_THIRD_PERSON };
|
||||
glm::mat4 _transform;
|
||||
glm::mat4 _projection;
|
||||
|
||||
// derived
|
||||
glm::vec3 _position;
|
||||
glm::quat _rotation;
|
||||
glm::mat4 _projection;
|
||||
glm::vec3 _hmdPosition;
|
||||
glm::quat _hmdRotation;
|
||||
bool _isKeepLookingAt;
|
||||
bool _isKeepLookingAt{ false };
|
||||
glm::vec3 _lookingAt;
|
||||
};
|
||||
|
||||
|
|
|
@ -68,17 +68,17 @@ void Environment::resetToDefault() {
|
|||
_data[HifiSockAddr()][0];
|
||||
}
|
||||
|
||||
void Environment::renderAtmospheres(Camera& camera) {
|
||||
void Environment::renderAtmospheres(const glm::vec3& position) {
|
||||
// get the lock for the duration of the call
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
if (_environmentIsOverridden) {
|
||||
renderAtmosphere(camera, _overrideData);
|
||||
renderAtmosphere(position, _overrideData);
|
||||
} else {
|
||||
foreach (const ServerData& serverData, _data) {
|
||||
// TODO: do something about EnvironmentData
|
||||
foreach (const EnvironmentData& environmentData, serverData) {
|
||||
renderAtmosphere(camera, environmentData);
|
||||
renderAtmosphere(position, environmentData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,13 +228,13 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) {
|
|||
return program;
|
||||
}
|
||||
|
||||
void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) {
|
||||
void Environment::renderAtmosphere(const glm::vec3& position, const EnvironmentData& data) {
|
||||
glm::vec3 center = data.getAtmosphereCenter();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(center.x, center.y, center.z);
|
||||
|
||||
glm::vec3 relativeCameraPos = camera.getPosition() - center;
|
||||
glm::vec3 relativeCameraPos = position - center;
|
||||
float height = glm::length(relativeCameraPos);
|
||||
|
||||
// use the appropriate shader depending on whether we're inside or outside
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
|
||||
void init();
|
||||
void resetToDefault();
|
||||
void renderAtmospheres(Camera& camera);
|
||||
void renderAtmospheres(const glm::vec3& camera);
|
||||
|
||||
void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; }
|
||||
void endOverride() { _environmentIsOverridden = false; }
|
||||
|
@ -46,7 +46,7 @@ private:
|
|||
|
||||
ProgramObject* createSkyProgram(const char* from, int* locations);
|
||||
|
||||
void renderAtmosphere(Camera& camera, const EnvironmentData& data);
|
||||
void renderAtmosphere(const glm::vec3& position, const EnvironmentData& data);
|
||||
|
||||
bool _initialized;
|
||||
ProgramObject* _skyFromAtmosphereProgram;
|
||||
|
|
|
@ -767,6 +767,7 @@ void SkeletonModel::resetShapePositionsToDefaultPose() {
|
|||
|
||||
void SkeletonModel::renderBoundingCollisionShapes(float alpha) {
|
||||
const int BALL_SUBDIVISIONS = 10;
|
||||
#if 0
|
||||
if (_shapes.isEmpty()) {
|
||||
// the bounding shape has not been propery computed
|
||||
// so no need to render it
|
||||
|
@ -797,6 +798,7 @@ void SkeletonModel::renderBoundingCollisionShapes(float alpha) {
|
|||
Avatar::renderJointConnectingCone( origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), glm::vec4(0.6f, 0.8f, 0.6f, alpha));
|
||||
|
||||
glPopMatrix();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SkeletonModel::hasSkeleton() {
|
||||
|
|
|
@ -120,7 +120,7 @@ void TV3DManager::display(Camera& whichCamera) {
|
|||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
qApp->displaySide(eyeCamera, false, RenderArgs::MONO);
|
||||
qApp->displaySide(eyeCamera, false);
|
||||
#if 0
|
||||
qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov);
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
class Plugin : public QObject {
|
||||
public:
|
||||
virtual const QString & getName() = 0;
|
||||
virtual bool isSupported() { return true; }
|
||||
virtual bool isSupported() const { return true; }
|
||||
|
||||
virtual void init() {}
|
||||
virtual void deinit() {}
|
||||
|
|
|
@ -21,14 +21,34 @@
|
|||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
||||
enum class Eye {
|
||||
Left,
|
||||
Right,
|
||||
Mono
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper method to iterate over each eye
|
||||
*/
|
||||
template <typename F>
|
||||
void for_each_eye(F f) {
|
||||
f(Left);
|
||||
f(Right);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper method to iterate over each eye, with an additional lambda to take action between the eyes
|
||||
*/
|
||||
template <typename F, typename FF>
|
||||
void for_each_eye(F f, FF ff) {
|
||||
f(Eye::Left);
|
||||
ff();
|
||||
f(Eye::Right);
|
||||
}
|
||||
|
||||
class DisplayPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum class Eye {
|
||||
Left,
|
||||
Right,
|
||||
Mono
|
||||
};
|
||||
virtual bool isHmd() const { return false; }
|
||||
virtual bool isStereo() const { return false; }
|
||||
virtual bool isThrottled() const { return false; }
|
||||
|
@ -76,23 +96,24 @@ public:
|
|||
};
|
||||
virtual bool isMouseOnScreen() const;
|
||||
|
||||
|
||||
// Stereo specific methods
|
||||
virtual glm::mat4 getProjection(Eye eye) const {
|
||||
return glm::mat4();
|
||||
virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const {
|
||||
return baseProjection;
|
||||
}
|
||||
|
||||
virtual glm::mat4 getModelview(Eye eye, const glm::mat4& baseModelview) const {
|
||||
return glm::inverse(getEyePose(eye)) * baseModelview;
|
||||
}
|
||||
|
||||
// HMD specific methods
|
||||
// TODO move these into another class
|
||||
virtual glm::mat4 headPose() const {
|
||||
virtual glm::mat4 getEyePose(Eye eye) const {
|
||||
static const glm::mat4 pose; return pose;
|
||||
}
|
||||
|
||||
virtual glm::quat headOrientation() const {
|
||||
static const glm::quat orientation; return orientation;
|
||||
}
|
||||
|
||||
virtual glm::vec3 headTranslation() const {
|
||||
static const glm::vec3 tranlsation; return tranlsation;
|
||||
virtual glm::mat4 getHeadPose() const {
|
||||
static const glm::mat4 pose; return pose;
|
||||
}
|
||||
|
||||
virtual void abandonCalibration() {}
|
||||
|
@ -108,3 +129,4 @@ protected:
|
|||
virtual void doneCurrent() {}
|
||||
virtual void swapBuffers() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ void LegacyDisplayPlugin::activate() {
|
|||
|
||||
_window->installEventFilter(qApp);
|
||||
_window->installEventFilter(DependencyManager::get<OffscreenUi>().data());
|
||||
|
||||
DependencyManager::get<OffscreenUi>()->setProxyWindow(_window->windowHandle());
|
||||
SimpleDisplayPlugin::activate();
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,11 @@ Tv3dDisplayPlugin::Tv3dDisplayPlugin() {
|
|||
});
|
||||
}
|
||||
|
||||
bool Tv3dDisplayPlugin::isSupported() const {
|
||||
// FIXME this should attempt to do a scan for supported 3D output
|
||||
return true;
|
||||
}
|
||||
|
||||
gpu::TexturePointer _crosshairTexture;
|
||||
|
||||
|
||||
|
@ -238,210 +243,3 @@ void Tv3dDisplayPlugin::deactivate() {
|
|||
_timer.stop();
|
||||
GlWindowDisplayPlugin::deactivate();
|
||||
}
|
||||
/*
|
||||
std::function<QPointF(const QPointF&)> Tv3dDisplayPlugin::getMouseTranslator() {
|
||||
return [=](const QPointF& point){
|
||||
QPointF result{ point };
|
||||
QSize size = getDeviceSize();
|
||||
result.rx() *= 2.0f;
|
||||
if (result.x() > size.width()) {
|
||||
result.rx() -= size.width();
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
glm::ivec2 Tv3dDisplayPlugin::trueMouseToUiMouse(const glm::ivec2 & position) const {
|
||||
ivec2 result{ position };
|
||||
uvec2 size = getCanvasSize();
|
||||
result.x *= 2;
|
||||
result.x %= size.x;
|
||||
return result;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
void Tv3dDisplayPlugin::activate() {
|
||||
GlWindowDisplayPlugin::activate();
|
||||
_window->setPosition(100, 100);
|
||||
_window->resize(512, 512);
|
||||
_window->setVisible(true);
|
||||
_window->show();
|
||||
}
|
||||
|
||||
void Tv3dDisplayPlugin::deactivate() {
|
||||
GlWindowDisplayPlugin::deactivate();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
glm::ivec2 LegacyDisplayPlugin::getCanvasSize() const {
|
||||
return toGlm(_window->size());
|
||||
}
|
||||
|
||||
bool LegacyDisplayPlugin::hasFocus() const {
|
||||
return _window->hasFocus();
|
||||
}
|
||||
|
||||
PickRay LegacyDisplayPlugin::computePickRay(const glm::vec2 & pos) const {
|
||||
return PickRay();
|
||||
}
|
||||
|
||||
bool isMouseOnScreen() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void LegacyDisplayPlugin::preDisplay() {
|
||||
SimpleDisplayPlugin::preDisplay();
|
||||
auto size = toGlm(_window->size());
|
||||
glViewport(0, 0, size.x, size.y);
|
||||
}
|
||||
|
||||
bool LegacyDisplayPlugin::isThrottled() const {
|
||||
return _window->isThrottleRendering();
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#if 0
|
||||
|
||||
int TV3DManager::_screenWidth = 1;
|
||||
int TV3DManager::_screenHeight = 1;
|
||||
double TV3DManager::_aspect = 1.0;
|
||||
eyeFrustum TV3DManager::_leftEye;
|
||||
eyeFrustum TV3DManager::_rightEye;
|
||||
eyeFrustum* TV3DManager::_activeEye = NULL;
|
||||
|
||||
|
||||
bool TV3DManager::isConnected() {
|
||||
return Menu::getInstance()->isOptionChecked(MenuOption::Enable3DTVMode);
|
||||
}
|
||||
|
||||
void TV3DManager::connect() {
|
||||
auto deviceSize = qApp->getDeviceSize();
|
||||
configureCamera(*(qApp->getCamera()), deviceSize.width(), deviceSize.height());
|
||||
}
|
||||
|
||||
|
||||
// The basic strategy of this stereoscopic rendering is explained here:
|
||||
// http://www.orthostereo.com/geometryopengl.html
|
||||
void TV3DManager::setFrustum(const Camera& whichCamera) {
|
||||
const double DTR = 0.0174532925; // degree to radians
|
||||
const double IOD = 0.05; //intraocular distance
|
||||
double fovy = DEFAULT_FIELD_OF_VIEW_DEGREES; // field of view in y-axis
|
||||
double nearZ = DEFAULT_NEAR_CLIP; // near clipping plane
|
||||
double screenZ = 0.25f; // screen projection plane
|
||||
|
||||
double top = nearZ * tan(DTR * fovy / 2.0); //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) {
|
||||
const Camera& whichCamera = whichCamera_;
|
||||
|
||||
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 = DEFAULT_NEAR_CLIP; // near clipping plane
|
||||
double farZ = DEFAULT_FAR_CLIP; // far clipping plane
|
||||
|
||||
// left eye portal
|
||||
int portalX = 0;
|
||||
int portalY = 0;
|
||||
QSize deviceSize = qApp->getDeviceSize() *
|
||||
qApp->getRenderResolutionScale();
|
||||
int portalW = deviceSize.width() / 2;
|
||||
int portalH = deviceSize.height();
|
||||
|
||||
|
||||
DependencyManager::get<GlowEffect>()->prepare();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
Camera eyeCamera;
|
||||
eyeCamera.setRotation(whichCamera.getRotation());
|
||||
eyeCamera.setPosition(whichCamera.getPosition());
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glPushMatrix();
|
||||
forEachEye([&](eyeFrustum& eye) {
|
||||
_activeEye = &eye;
|
||||
glViewport(portalX, portalY, portalW, portalH);
|
||||
glScissor(portalX, portalY, portalW, portalH);
|
||||
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
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
qApp->displaySide(eyeCamera, false, RenderArgs::MONO);
|
||||
#if 0
|
||||
qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov);
|
||||
#endif
|
||||
_activeEye = NULL;
|
||||
}, [&] {
|
||||
// render right side view
|
||||
portalX = deviceSize.width() / 2;
|
||||
});
|
||||
glPopMatrix();
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
auto finalFbo = DependencyManager::get<GlowEffect>()->render();
|
||||
auto fboSize = finalFbo->getSize();
|
||||
// Get the ACTUAL device size for the BLIT
|
||||
deviceSize = qApp->getDeviceSize();
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo));
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, 0, fboSize.x, fboSize.y,
|
||||
0, 0, deviceSize.width(), deviceSize.height(),
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
|
||||
// reset the viewport to how we started
|
||||
glViewport(0, 0, deviceSize.width(), deviceSize.height());
|
||||
}
|
||||
|
||||
void TV3DManager::overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
||||
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) {
|
||||
if (_activeEye) {
|
||||
left = _activeEye->left;
|
||||
right = _activeEye->right;
|
||||
bottom = _activeEye->bottom;
|
||||
top = _activeEye->top;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@ public:
|
|||
virtual const QString & getName();
|
||||
Tv3dDisplayPlugin();
|
||||
virtual bool isStereo() const final { return true; }
|
||||
virtual bool isSupported() const final;
|
||||
void display(GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||
GLuint overlayTexture, const glm::uvec2& overlaySize);
|
||||
virtual void activate();
|
||||
|
|
|
@ -9,16 +9,17 @@
|
|||
//
|
||||
#include "WindowDisplayPlugin.h"
|
||||
#include "RenderUtil.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include "Application.h"
|
||||
|
||||
WindowDisplayPlugin::WindowDisplayPlugin() {
|
||||
connect(&_timer, &QTimer::timeout, this, [&] {
|
||||
emit requestRender();
|
||||
// if (qApp->getActiveDisplayPlugin() == this) {
|
||||
emit requestRender();
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
const QString WindowDisplayPlugin::NAME("WindowDisplayPlugin");
|
||||
const QString WindowDisplayPlugin::NAME("QWindow 2D Renderer");
|
||||
|
||||
const QString & WindowDisplayPlugin::getName() {
|
||||
return NAME;
|
||||
|
@ -35,417 +36,3 @@ void WindowDisplayPlugin::deactivate() {
|
|||
GlWindowDisplayPlugin::deactivate();
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
//
|
||||
// MainWindow.h
|
||||
// interface
|
||||
//
|
||||
// Created by Mohammed Nafees on 04/06/2014.
|
||||
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef __hifi__MainWindow__
|
||||
#define __hifi__MainWindow__
|
||||
|
||||
#include <QWindow>
|
||||
#include <QTimer>
|
||||
|
||||
#include <SettingHandle.h>
|
||||
|
||||
#define MSECS_PER_FRAME_WHEN_THROTTLED 66
|
||||
|
||||
class MainWindow : public QWindow {
|
||||
public:
|
||||
explicit MainWindow(QWindow* parent = NULL);
|
||||
|
||||
// Some helpers for compatiblity with QMainWindow
|
||||
void activateWindow() {
|
||||
requestActivate();
|
||||
}
|
||||
|
||||
bool isMinimized() const {
|
||||
return windowState() == Qt::WindowMinimized;
|
||||
}
|
||||
|
||||
void stopFrameTimer();
|
||||
|
||||
bool isThrottleRendering() const;
|
||||
|
||||
int getDeviceWidth() const;
|
||||
int getDeviceHeight() const;
|
||||
QSize getDeviceSize() const { return QSize(getDeviceWidth(), getDeviceHeight()); }
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
private slots:
|
||||
void activeChanged(Qt::ApplicationState state);
|
||||
void throttleRender();
|
||||
bool eventFilter(QObject*, QEvent* event);
|
||||
*/
|
||||
public slots:
|
||||
void restoreGeometry();
|
||||
void saveGeometry();
|
||||
|
||||
signals:
|
||||
void windowGeometryChanged(QRect geometry);
|
||||
void windowShown(bool shown);
|
||||
|
||||
protected:
|
||||
virtual void moveEvent(QMoveEvent* event);
|
||||
virtual void resizeEvent(QResizeEvent* event);
|
||||
virtual void showEvent(QShowEvent* event);
|
||||
virtual void hideEvent(QHideEvent* event);
|
||||
virtual void changeEvent(QEvent* event);
|
||||
virtual void windowStateChanged(Qt::WindowState windowState);
|
||||
virtual void activeChanged();
|
||||
|
||||
virtual void initializeGL();
|
||||
virtual void paintGL();
|
||||
virtual void resizeGL(int width, int height);
|
||||
|
||||
private:
|
||||
Setting::Handle<QRect> _windowGeometry;
|
||||
Setting::Handle<int> _windowState;
|
||||
Qt::WindowState _lastState{ Qt::WindowNoState };
|
||||
QOpenGLContext * _context{ nullptr };
|
||||
QTimer _frameTimer;
|
||||
bool _throttleRendering{ false };
|
||||
int _idleRenderInterval{ MSECS_PER_FRAME_WHEN_THROTTLED };
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__MainWindow__) */
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// MainWindow.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Mohammed Nafees on 04/06/2014.
|
||||
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QEvent>
|
||||
#include <QMoveEvent>
|
||||
#include <QResizeEvent>
|
||||
#include <QShowEvent>
|
||||
#include <QHideEvent>
|
||||
#include <QWindowStateChangeEvent>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "Menu.h"
|
||||
#include "Util.h"
|
||||
|
||||
#include <QOpenGLContext>
|
||||
|
||||
|
||||
MainWindow::MainWindow(QWindow * parent) :
|
||||
QWindow(parent),
|
||||
_windowGeometry("WindowGeometry"),
|
||||
_windowState("WindowState", 0) {
|
||||
setSurfaceType(QSurface::OpenGLSurface);
|
||||
|
||||
QSurfaceFormat format;
|
||||
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
|
||||
format.setDepthBufferSize(16);
|
||||
format.setStencilBufferSize(8);
|
||||
format.setVersion(4, 1);
|
||||
// Ugh....
|
||||
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile);
|
||||
setFormat(format);
|
||||
|
||||
_context = new QOpenGLContext;
|
||||
_context->setFormat(format);
|
||||
_context->create();
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
void MainWindow::restoreGeometry() {
|
||||
QRect geometry = _windowGeometry.get(qApp->desktop()->availableGeometry());
|
||||
setGeometry(geometry);
|
||||
|
||||
// Restore to maximized or full screen after restoring to windowed so that going windowed goes to good position and sizes.
|
||||
int state = _windowState.get(Qt::WindowNoState) & ~Qt::WindowActive;
|
||||
if (state != Qt::WindowNoState) {
|
||||
setWindowState((Qt::WindowState)state);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::saveGeometry() {
|
||||
// Did not use geometry() on purpose,
|
||||
// see http://doc.qt.io/qt-5/qsettings.html#restoring-the-state-of-a-gui-application
|
||||
_windowState.set((int)windowState());
|
||||
|
||||
// Save position and size only if windowed so that have good values for windowed after starting maximized or full screen.
|
||||
if (windowState() == Qt::WindowNoState) {
|
||||
_windowGeometry.set(geometry());
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::moveEvent(QMoveEvent* event) {
|
||||
emit windowGeometryChanged(QRect(event->pos(), size()));
|
||||
QWindow::moveEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::resizeEvent(QResizeEvent* event) {
|
||||
emit windowGeometryChanged(QRect(QPoint(x(), y()), event->size()));
|
||||
QWindow::resizeEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::showEvent(QShowEvent* event) {
|
||||
if (event->spontaneous()) {
|
||||
emit windowShown(true);
|
||||
}
|
||||
QWindow::showEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::hideEvent(QHideEvent* event) {
|
||||
if (event->spontaneous()) {
|
||||
emit windowShown(false);
|
||||
}
|
||||
QWindow::hideEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::windowStateChanged(Qt::WindowState windowState) {
|
||||
// If we're changing from minimized to non-minimized or vice versas, emit
|
||||
// a windowShown signal (i.e. don't emit the signal if we're going from
|
||||
// fullscreen to nostate
|
||||
if ((_lastState == Qt::WindowMinimized) ^ (windowState == Qt::WindowMinimized)) {
|
||||
emit windowShown(windowState != Qt::WindowMinimized);
|
||||
}
|
||||
|
||||
bool fullscreen = windowState == Qt::WindowFullScreen;
|
||||
if (fullscreen != Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)) {
|
||||
Menu::getInstance()->setIsOptionChecked(MenuOption::Fullscreen, fullscreen);
|
||||
}
|
||||
|
||||
_lastState = windowState;
|
||||
QWindow::windowStateChanged(windowState);
|
||||
}
|
||||
|
||||
void MainWindow::activeChanged() {
|
||||
if (isActive()) {
|
||||
emit windowShown(true);
|
||||
} else {
|
||||
emit windowShown(false);
|
||||
}
|
||||
QWindow::activeChanged();
|
||||
}
|
||||
|
||||
void MainWindow::stopFrameTimer() {
|
||||
_frameTimer.stop();
|
||||
}
|
||||
|
||||
bool MainWindow::isThrottleRendering() const {
|
||||
return _throttleRendering || isMinimized();
|
||||
}
|
||||
|
||||
|
||||
int MainWindow::getDeviceWidth() const {
|
||||
return width() * devicePixelRatio();
|
||||
}
|
||||
|
||||
int MainWindow::getDeviceHeight() const {
|
||||
return height() * devicePixelRatio();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MainWindow::initializeGL() {
|
||||
Application::getInstance()->initializeGL();
|
||||
// setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
// setAcceptDrops(true);
|
||||
connect(Application::getInstance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(activeChanged(Qt::ApplicationState)));
|
||||
connect(&_frameTimer, SIGNAL(timeout()), this, SLOT(throttleRender()));
|
||||
}
|
||||
|
||||
void GLCanvas::resizeGL(int width, int height) {
|
||||
Application::getInstance()->resizeGL(width, height);
|
||||
}
|
||||
|
||||
void GLCanvas::paintGL() {
|
||||
if (!_throttleRendering && !Application::getInstance()->getWindow()->isMinimized()) {
|
||||
//Need accurate frame timing for the oculus rift
|
||||
if (OculusManager::isConnected()) {
|
||||
OculusManager::beginFrameTiming();
|
||||
}
|
||||
|
||||
Application::getInstance()->paintGL();
|
||||
|
||||
if (!OculusManager::isConnected()) {
|
||||
swapBuffers();
|
||||
} else {
|
||||
if (OculusManager::allowSwap()) {
|
||||
swapBuffers();
|
||||
}
|
||||
OculusManager::endFrameTiming();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
GLCanvas::GLCanvas() : QGLWidget(QGL::NoDepthBuffer | QGL::NoStencilBuffer),
|
||||
#ifdef Q_OS_LINUX
|
||||
// Cause GLCanvas::eventFilter to be called.
|
||||
// It wouldn't hurt to do this on Mac and PC too; but apparently it's only needed on linux.
|
||||
qApp->installEventFilter(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLCanvas::keyPressEvent(QKeyEvent* event) {
|
||||
Application::getInstance()->keyPressEvent(event);
|
||||
}
|
||||
|
||||
void GLCanvas::keyReleaseEvent(QKeyEvent* event) {
|
||||
Application::getInstance()->keyReleaseEvent(event);
|
||||
}
|
||||
|
||||
void GLCanvas::focusOutEvent(QFocusEvent* event) {
|
||||
Application::getInstance()->focusOutEvent(event);
|
||||
}
|
||||
|
||||
void GLCanvas::mouseMoveEvent(QMouseEvent* event) {
|
||||
Application::getInstance()->mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void GLCanvas::mousePressEvent(QMouseEvent* event) {
|
||||
Application::getInstance()->mousePressEvent(event);
|
||||
}
|
||||
|
||||
void GLCanvas::mouseReleaseEvent(QMouseEvent* event) {
|
||||
Application::getInstance()->mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void GLCanvas::activeChanged(Qt::ApplicationState state) {
|
||||
switch (state) {
|
||||
case Qt::ApplicationActive:
|
||||
// If we're active, stop the frame timer and the throttle.
|
||||
_frameTimer.stop();
|
||||
_throttleRendering = false;
|
||||
break;
|
||||
|
||||
case Qt::ApplicationSuspended:
|
||||
case Qt::ApplicationHidden:
|
||||
// If we're hidden or are about to suspend, don't render anything.
|
||||
_throttleRendering = false;
|
||||
_frameTimer.stop();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Otherwise, throttle.
|
||||
if (!_throttleRendering && !Application::getInstance()->isAboutToQuit()) {
|
||||
_frameTimer.start(_idleRenderInterval);
|
||||
_throttleRendering = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas::throttleRender() {
|
||||
_frameTimer.start(_idleRenderInterval);
|
||||
if (!Application::getInstance()->getWindow()->isMinimized()) {
|
||||
//Need accurate frame timing for the oculus rift
|
||||
if (OculusManager::isConnected()) {
|
||||
OculusManager::beginFrameTiming();
|
||||
}
|
||||
|
||||
Application::getInstance()->paintGL();
|
||||
swapBuffers();
|
||||
|
||||
if (OculusManager::isConnected()) {
|
||||
OculusManager::endFrameTiming();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int updateTime = 0;
|
||||
bool GLCanvas::event(QEvent* event) {
|
||||
switch (event->type()) {
|
||||
case QEvent::TouchBegin:
|
||||
Application::getInstance()->touchBeginEvent(static_cast<QTouchEvent*>(event));
|
||||
event->accept();
|
||||
return true;
|
||||
case QEvent::TouchEnd:
|
||||
Application::getInstance()->touchEndEvent(static_cast<QTouchEvent*>(event));
|
||||
return true;
|
||||
case QEvent::TouchUpdate:
|
||||
Application::getInstance()->touchUpdateEvent(static_cast<QTouchEvent*>(event));
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QGLWidget::event(event);
|
||||
}
|
||||
|
||||
void GLCanvas::wheelEvent(QWheelEvent* event) {
|
||||
Application::getInstance()->wheelEvent(event);
|
||||
}
|
||||
|
||||
void GLCanvas::dragEnterEvent(QDragEnterEvent* event) {
|
||||
const QMimeData* mimeData = event->mimeData();
|
||||
foreach(QUrl url, mimeData->urls()) {
|
||||
auto urlString = url.toString();
|
||||
if (Application::getInstance()->canAcceptURL(urlString)) {
|
||||
event->acceptProposedAction();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas::dropEvent(QDropEvent* event) {
|
||||
Application::getInstance()->dropEvent(event);
|
||||
}
|
||||
|
||||
// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the
|
||||
// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to
|
||||
// receive keyPress events for the Alt (and Meta) key in a reliable manner.
|
||||
//
|
||||
// This filter catches events before QMenuBar can steal the keyboard focus.
|
||||
// The idea was borrowed from
|
||||
// http://www.archivum.info/qt-interest@trolltech.com/2006-09/00053/Re-(Qt4)-Alt-key-focus-QMenuBar-(solved).html
|
||||
|
||||
bool GLCanvas::eventFilter(QObject*, QEvent* event) {
|
||||
switch (event->type()) {
|
||||
case QEvent::KeyPress:
|
||||
case QEvent::KeyRelease:
|
||||
case QEvent::ShortcutOverride:
|
||||
{
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->key() == Qt::Key_Alt || keyEvent->key() == Qt::Key_Meta) {
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
keyPressEvent(keyEvent);
|
||||
} else if (event->type() == QEvent::KeyRelease) {
|
||||
keyReleaseEvent(keyEvent);
|
||||
} else {
|
||||
QGLWidget::event(event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
*/
|
||||
#endif
|
||||
|
|
|
@ -394,7 +394,6 @@ void ApplicationOverlay::displayOverlayTextureHmd(Camera& whichCamera) {
|
|||
glEnable(GL_LIGHTING);
|
||||
} glPopMatrix();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Draws the FBO texture for 3DTV.
|
||||
void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov) {
|
||||
|
@ -489,6 +488,7 @@ void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float
|
|||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void ApplicationOverlay::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) const {
|
||||
|
@ -501,13 +501,13 @@ void ApplicationOverlay::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origi
|
|||
glm::vec3 overlaySpaceDirection = glm::normalize(orientation * IDENTITY_FRONT);
|
||||
|
||||
|
||||
const glm::vec3& hmdPosition = qApp->getCamera()->getHmdPosition();
|
||||
const glm::quat& hmdOrientation = qApp->getCamera()->getHmdRotation();
|
||||
glm::vec3 hmdPosition; // = qApp->getCamera()->getHmdPosition();
|
||||
glm::quat hmdOrientation; // = qApp->getCamera()->getHmdRotation();
|
||||
|
||||
// We need the RAW camera orientation and position, because this is what the overlay is
|
||||
// We need the camera orientation and position, because this is what the overlay is
|
||||
// rendered relative to
|
||||
const glm::vec3 overlayPosition = qApp->getCamera()->getPosition() - hmdPosition;
|
||||
const glm::quat overlayOrientation = qApp->getCamera()->getRotation() * glm::inverse(hmdOrientation);
|
||||
const glm::vec3 overlayPosition = qApp->getCamera()->getPosition();
|
||||
const glm::quat overlayOrientation = qApp->getCamera()->getRotation();
|
||||
|
||||
// Intersection UI overlay space
|
||||
glm::vec3 worldSpaceDirection = overlayOrientation * overlaySpaceDirection;
|
||||
|
|
|
@ -38,23 +38,18 @@ void LocalModelsOverlay::render(RenderArgs* args) {
|
|||
if (_visible) {
|
||||
|
||||
float glowLevel = getGlowLevel();
|
||||
Glower* glower = NULL;
|
||||
QSharedPointer<Glower> glower;
|
||||
if (glowLevel > 0.0f) {
|
||||
glower = new Glower(glowLevel);
|
||||
glower = QSharedPointer<Glower>(new Glower(glowLevel));
|
||||
}
|
||||
|
||||
glPushMatrix(); {
|
||||
Application* app = Application::getInstance();
|
||||
glm::vec3 oldTranslation = app->getViewMatrixTranslation();
|
||||
app->setViewMatrixTranslation(oldTranslation + _position);
|
||||
Transform originalTransform = qApp->getViewTransform();
|
||||
qApp->getViewTransform().postTranslate(_position);
|
||||
_entityTreeRenderer->render();
|
||||
Application::getInstance()->setViewMatrixTranslation(oldTranslation);
|
||||
qApp->setViewTransform(originalTransform);
|
||||
} glPopMatrix();
|
||||
|
||||
if (glower) {
|
||||
delete glower;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,14 +27,17 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
ViewFrustum::ViewFrustum() {
|
||||
}
|
||||
|
||||
void ViewFrustum::setOrientation(const glm::quat& orientationAsQuaternion) {
|
||||
_orientation = orientationAsQuaternion;
|
||||
_right = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_RIGHT, 0.0f));
|
||||
_up = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_UP, 0.0f));
|
||||
_direction = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_FRONT, 0.0f));
|
||||
_view = glm::translate(mat4(), _position) * glm::mat4_cast(_orientation);
|
||||
}
|
||||
|
||||
void ViewFrustum::setPosition(const glm::vec3& position) {
|
||||
_position = position;
|
||||
_view = glm::translate(mat4(), _position) * glm::mat4_cast(_orientation);
|
||||
}
|
||||
|
||||
// Order cooresponds to the order defined in the BoxVertex enum.
|
||||
|
|
|
@ -36,11 +36,9 @@ const float DEFAULT_FAR_CLIP = (float)TREE_SCALE;
|
|||
|
||||
class ViewFrustum {
|
||||
public:
|
||||
ViewFrustum();
|
||||
|
||||
// setters for camera attributes
|
||||
void setPosition(const glm::vec3& p) { _position = p; }
|
||||
void setOrientation(const glm::quat& orientationAsQuaternion);
|
||||
void setPosition(const glm::vec3& position);
|
||||
void setOrientation(const glm::quat& orientation);
|
||||
|
||||
// getters for camera attributes
|
||||
const glm::vec3& getPosition() const { return _position; }
|
||||
|
@ -54,7 +52,8 @@ public:
|
|||
void getFocalLength(float focalLength) { _focalLength = focalLength; }
|
||||
|
||||
// getters for lens attributes
|
||||
const glm::mat4 getProjection() const { return _projection; };
|
||||
const glm::mat4& getProjection() const { return _projection; };
|
||||
const glm::mat4& getView() const { return _view; };
|
||||
float getWidth() const { return _width; }
|
||||
float getHeight() const { return _height; }
|
||||
float getFieldOfView() const { return _fieldOfView; }
|
||||
|
@ -120,6 +119,7 @@ private:
|
|||
// camera location/orientation attributes
|
||||
glm::vec3 _position; // the position in world-frame
|
||||
glm::quat _orientation;
|
||||
glm::mat4 _view;
|
||||
|
||||
// Lens attributes
|
||||
glm::mat4 _projection;
|
||||
|
|
|
@ -30,10 +30,6 @@ public:
|
|||
/// Returns the shadow distances for the current view state
|
||||
virtual const glm::vec3& getShadowDistances() const = 0;
|
||||
|
||||
/// Computes the off-axis frustum parameters for the view frustum, taking mirroring into account.
|
||||
virtual void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
||||
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const = 0;
|
||||
|
||||
/// gets the current view frustum for rendering the view state
|
||||
virtual ViewFrustum* getCurrentViewFrustum() = 0;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <PathUtils.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "AbstractViewStateInterface.h"
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
|
@ -112,7 +113,8 @@ void AmbientOcclusionEffect::render() {
|
|||
|
||||
float left, right, bottom, top, nearVal, farVal;
|
||||
glm::vec4 nearClipPlane, farClipPlane;
|
||||
_viewState->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
auto viewFrustum = _viewState->getCurrentViewFrustum();
|
||||
viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
|
||||
int viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
|
|
|
@ -319,9 +319,10 @@ void DeferredLightingEffect::render() {
|
|||
glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat));
|
||||
}
|
||||
|
||||
auto viewFrustum = _viewState->getCurrentViewFrustum();
|
||||
float left, right, bottom, top, nearVal, farVal;
|
||||
glm::vec4 nearClipPlane, farClipPlane;
|
||||
_viewState->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
program->setUniformValue(locations->nearLocation, nearVal);
|
||||
float depthScale = (farVal - nearVal) / farVal;
|
||||
program->setUniformValue(locations->depthScale, depthScale);
|
||||
|
@ -363,8 +364,8 @@ void DeferredLightingEffect::render() {
|
|||
// enlarge the scales slightly to account for tesselation
|
||||
const float SCALE_EXPANSION = 0.05f;
|
||||
|
||||
const glm::vec3& eyePoint = _viewState->getCurrentViewFrustum()->getPosition();
|
||||
float nearRadius = glm::distance(eyePoint, _viewState->getCurrentViewFrustum()->getNearTopLeft());
|
||||
const glm::vec3& eyePoint = viewFrustum->getPosition();
|
||||
float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft());
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
|
||||
|
|
Loading…
Reference in a new issue