mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 01:24:36 +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"),
|
_previousScriptLocation("LastScriptLocation"),
|
||||||
_scriptsLocationHandle("scriptsLocation"),
|
_scriptsLocationHandle("scriptsLocation"),
|
||||||
_fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES),
|
_fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES),
|
||||||
_viewTransform(),
|
|
||||||
_scaleMirror(1.0f),
|
_scaleMirror(1.0f),
|
||||||
_rotateMirror(0.0f),
|
_rotateMirror(0.0f),
|
||||||
_raiseMirror(0.0f),
|
_raiseMirror(0.0f),
|
||||||
|
@ -878,7 +877,7 @@ void Application::paintGL() {
|
||||||
|
|
||||||
// Sync up the View Furstum with the camera
|
// 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
|
// 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()) {
|
if (getShadowsEnabled()) {
|
||||||
updateShadowMap();
|
updateShadowMap();
|
||||||
|
@ -891,43 +890,40 @@ void Application::paintGL() {
|
||||||
auto finalFbo = primaryFbo;
|
auto finalFbo = primaryFbo;
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFbo));
|
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFbo));
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glPushMatrix();
|
||||||
{
|
{
|
||||||
// Viewport is assigned to the size of the framebuffer
|
// Viewport is assigned to the size of the framebuffer
|
||||||
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
|
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
|
||||||
if (displayPlugin->isStereo()) {
|
if (displayPlugin->isStereo()) {
|
||||||
QRect r(QPoint(0, 0), QSize(size.width() / 2, size.height()));
|
QRect r(QPoint(0, 0), QSize(size.width() / 2, size.height()));
|
||||||
glEnable(GL_SCISSOR_TEST);
|
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());
|
glViewport(r.x(), r.y(), r.width(), r.height());
|
||||||
glScissor(r.x(), r.y(), r.width(), r.height());
|
glScissor(r.x(), r.y(), r.width(), r.height());
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
// Load the view frustum, used by meshes
|
||||||
// FIXME Fetch the projection matrix from the plugin
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glPushMatrix();
|
|
||||||
glLoadIdentity();
|
|
||||||
Camera eyeCamera;
|
Camera eyeCamera;
|
||||||
eyeCamera.setRotation(_myCamera.getRotation());
|
eyeCamera.setTransform(displayPlugin->getModelview(eye, _myCamera.getTransform()));
|
||||||
eyeCamera.setPosition(_myCamera.getPosition());
|
eyeCamera.setProjection(displayPlugin->getProjection(eye, _myCamera.getProjection()));
|
||||||
|
|
||||||
displaySide(eyeCamera);
|
displaySide(eyeCamera);
|
||||||
glPopMatrix();
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||||
glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition();
|
glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition();
|
||||||
_rearMirrorTools->render(true, QPoint(mpos.x, mpos.y));
|
_rearMirrorTools->render(true, QPoint(mpos.x, mpos.y));
|
||||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
} else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||||
renderRearViewMirror(_mirrorViewRect);
|
renderRearViewMirror(_mirrorViewRect);
|
||||||
}
|
}
|
||||||
|
}, [&] {
|
||||||
r.moveLeft(r.width());
|
r.moveLeft(r.width());
|
||||||
}
|
});
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
} else {
|
} else {
|
||||||
glViewport(0, 0, size.width(), size.height());
|
glViewport(0, 0, size.width(), size.height());
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glPushMatrix();
|
|
||||||
glLoadIdentity();
|
|
||||||
displaySide(_myCamera);
|
displaySide(_myCamera);
|
||||||
glPopMatrix();
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||||
glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition();
|
glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition();
|
||||||
_rearMirrorTools->render(true, QPoint(mpos.x, mpos.y));
|
_rearMirrorTools->render(true, QPoint(mpos.x, mpos.y));
|
||||||
|
@ -938,6 +934,8 @@ void Application::paintGL() {
|
||||||
finalFbo = DependencyManager::get<GlowEffect>()->render();
|
finalFbo = DependencyManager::get<GlowEffect>()->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
// This might not be needed *right now*. We want to ensure that the FBO rendering
|
// 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
|
// 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,
|
// 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);
|
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) {
|
void Application::resizeEvent(QResizeEvent * event) {
|
||||||
resizeGL();
|
resizeGL();
|
||||||
|
@ -1014,12 +999,9 @@ void Application::resizeGL() {
|
||||||
|
|
||||||
_renderResolution = toGlm(renderSize);
|
_renderResolution = toGlm(renderSize);
|
||||||
DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
|
DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
|
||||||
resetCamerasOnResizeGL(_myCamera, _renderResolution);
|
|
||||||
|
|
||||||
glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu???
|
_myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()),
|
||||||
|
aspect(getCanvasSize()), DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||||
updateProjectionMatrix();
|
|
||||||
glLoadIdentity();
|
|
||||||
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
offscreenUi->resize(fromGlm(getCanvasSize()));
|
offscreenUi->resize(fromGlm(getCanvasSize()));
|
||||||
|
@ -1031,24 +1013,6 @@ void Application::resizeGL() {
|
||||||
Stats::getInstance()->resetWidth(_renderResolution.x, horizontalOffset);
|
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) {
|
void Application::controlledBroadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) {
|
||||||
foreach(NodeType_t type, destinationNodeTypes) {
|
foreach(NodeType_t type, destinationNodeTypes) {
|
||||||
// Perform the broadcast for one type
|
// Perform the broadcast for one type
|
||||||
|
@ -2205,7 +2169,7 @@ void Application::updateMouseRay() {
|
||||||
PerformanceWarning warn(showWarnings, "Application::updateMouseRay()");
|
PerformanceWarning warn(showWarnings, "Application::updateMouseRay()");
|
||||||
|
|
||||||
// make sure the frustum is up-to-date
|
// make sure the frustum is up-to-date
|
||||||
loadViewFrustum(_myCamera, _viewFrustum);
|
_myCamera.loadViewFrustum(_viewFrustum);
|
||||||
|
|
||||||
PickRay pickRay = computePickRay(getTrueMouseX(), getTrueMouseY());
|
PickRay pickRay = computePickRay(getTrueMouseX(), getTrueMouseY());
|
||||||
_mouseRayOrigin = pickRay.origin;
|
_mouseRayOrigin = pickRay.origin;
|
||||||
|
@ -2491,7 +2455,7 @@ void Application::update(float deltaTime) {
|
||||||
// to the server.
|
// to the server.
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("loadViewFrustum");
|
PerformanceTimer perfTimer("loadViewFrustum");
|
||||||
loadViewFrustum(_myCamera, _viewFrustum);
|
_myCamera.loadViewFrustum(_viewFrustum);
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
|
@ -2826,24 +2790,6 @@ QRect Application::getDesirableApplicationGeometry() {
|
||||||
return applicationGeometry;
|
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() {
|
glm::vec3 Application::getSunDirection() {
|
||||||
// Sun direction is in fact just the location of the sun relative to the origin
|
// Sun direction is in fact just the location of the sun relative to the origin
|
||||||
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
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) };
|
glm::vec2(0.0f, 0.5f), glm::vec2(0.5f, 0.5f) };
|
||||||
|
|
||||||
float frustumScale = 1.0f / (_viewFrustum.getFarClip() - _viewFrustum.getNearClip());
|
float frustumScale = 1.0f / (_viewFrustum.getFarClip() - _viewFrustum.getNearClip());
|
||||||
loadViewFrustum(_myCamera, _viewFrustum);
|
_myCamera.loadViewFrustum(_viewFrustum);
|
||||||
|
|
||||||
int matrixCount = 1;
|
int matrixCount = 1;
|
||||||
//int targetSize = fbo->width();
|
//int targetSize = fbo->width();
|
||||||
|
@ -2944,28 +2890,18 @@ void Application::updateShadowMap() {
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glm::mat4 proj = glm::ortho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z);
|
||||||
glOrtho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z);
|
glLoadMatrixf(glm::value_ptr(proj));
|
||||||
|
|
||||||
glm::mat4 projAgain;
|
|
||||||
glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat*)&projAgain);
|
|
||||||
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadMatrixf(glm::value_ptr(glm::mat4_cast(inverseRotation)));
|
||||||
glm::vec3 axis = glm::axis(inverseRotation);
|
|
||||||
glRotatef(glm::degrees(glm::angle(inverseRotation)), axis.x, axis.y, axis.z);
|
|
||||||
|
|
||||||
// store view matrix without translation, which we'll use for precision-sensitive objects
|
|
||||||
updateUntranslatedViewMatrix();
|
|
||||||
|
|
||||||
// Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation
|
// Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation
|
||||||
// the viewTransofmr object is updatded with the correct values and saved,
|
// the viewTransofmr object is updatded with the correct values and saved,
|
||||||
// this is what is used for rendering the Entities and avatars
|
// this is what is used for rendering the Entities and avatars
|
||||||
Transform viewTransform;
|
Transform viewTransform;
|
||||||
viewTransform.setRotation(rotation);
|
viewTransform.setRotation(rotation);
|
||||||
// viewTransform.postTranslate(shadowFrustumCenter);
|
|
||||||
setViewTransform(viewTransform);
|
setViewTransform(viewTransform);
|
||||||
|
|
||||||
|
|
||||||
|
@ -3003,7 +2939,6 @@ void Application::updateShadowMap() {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
// glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
|
|
||||||
activeRenderingThread = nullptr;
|
activeRenderingThread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3118,16 +3053,23 @@ const ViewFrustum* Application::getDisplayViewFrustum() const {
|
||||||
return &_displayViewFrustum;
|
return &_displayViewFrustum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) {
|
void Application::displaySide(const Camera& theCamera, bool selfAvatarOnly) {
|
||||||
activeRenderingThread = QThread::currentThread();
|
activeRenderingThread = QThread::currentThread();
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
PerformanceTimer perfTimer("display");
|
PerformanceTimer perfTimer("display");
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
||||||
// transform by eye offset
|
|
||||||
|
|
||||||
// load the view frustum
|
// 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)
|
// flip x if in mirror mode (also requires reversing winding order for backface culling)
|
||||||
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
glScalef(-1.0f, 1.0f, 1.0f);
|
glScalef(-1.0f, 1.0f, 1.0f);
|
||||||
|
@ -3137,17 +3079,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
glFrontFace(GL_CCW);
|
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::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
|
// Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation
|
||||||
// the viewTransofmr object is updatded with the correct values and saved,
|
// the viewTransofmr object is updatded with the correct values and saved,
|
||||||
// this is what is used for rendering the Entities and avatars
|
// 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) {
|
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f));
|
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);
|
setViewTransform(viewTransform);
|
||||||
|
|
||||||
glTranslatef(_viewMatrixTranslation.x, _viewMatrixTranslation.y, _viewMatrixTranslation.z);
|
|
||||||
|
|
||||||
// Setup 3D lights (after the camera transform, so that they are positioned in world space)
|
// Setup 3D lights (after the camera transform, so that they are positioned in world space)
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("lights");
|
PerformanceTimer perfTimer("lights");
|
||||||
|
@ -3208,7 +3131,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||||
// TODO: handle this correctly for zones
|
// TODO: handle this correctly for zones
|
||||||
const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition());
|
const EnvironmentData& closestData = _environment.getClosestData(_displayViewFrustum.getPosition());
|
||||||
|
|
||||||
if (closestData.getHasStars()) {
|
if (closestData.getHasStars()) {
|
||||||
const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
|
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())
|
glm::vec3 sunDirection = (getAvatarPosition() - closestData.getSunLocation())
|
||||||
/ closestData.getAtmosphereOuterRadius();
|
/ closestData.getAtmosphereOuterRadius();
|
||||||
float height = glm::distance(theCamera.getPosition(), closestData.getAtmosphereCenter());
|
float height = glm::distance(_displayViewFrustum.getPosition(), closestData.getAtmosphereCenter());
|
||||||
if (height < closestData.getAtmosphereInnerRadius()) {
|
if (height < closestData.getAtmosphereInnerRadius()) {
|
||||||
// If we're inside the atmosphere, then determine if our keyLight is below the horizon
|
// If we're inside the atmosphere, then determine if our keyLight is below the horizon
|
||||||
alpha = 0.0f;
|
alpha = 0.0f;
|
||||||
|
@ -3255,7 +3178,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
PerformanceTimer perfTimer("atmosphere");
|
PerformanceTimer perfTimer("atmosphere");
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
"Application::displaySide() ... atmosphere...");
|
"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) {
|
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||||
}
|
}
|
||||||
_entities.render(renderMode, renderSide, renderDebugFlags);
|
_entities.render(renderMode, RenderArgs::MONO, renderDebugFlags);
|
||||||
|
|
||||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
||||||
// Restaure polygon mode
|
// Restaure polygon mode
|
||||||
|
@ -3327,7 +3250,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mirrorMode = (theCamera.getMode() == CAMERA_MODE_MIRROR);
|
bool mirrorMode = (theCamera.getMode() == CAMERA_MODE_MIRROR);
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("avatars");
|
PerformanceTimer perfTimer("avatars");
|
||||||
DependencyManager::get<AvatarManager>()->renderAvatars(mirrorMode ? RenderArgs::MIRROR_RENDER_MODE : RenderArgs::NORMAL_RENDER_MODE,
|
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();
|
_nodeBoundsDisplay.draw();
|
||||||
|
|
||||||
// Render the world box
|
// 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");
|
PerformanceTimer perfTimer("worldBox");
|
||||||
renderWorldBox();
|
renderWorldBox();
|
||||||
}
|
}
|
||||||
|
@ -3405,33 +3328,32 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
activeRenderingThread = nullptr;
|
activeRenderingThread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation) {
|
|
||||||
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix);
|
|
||||||
_viewMatrixTranslation = viewMatrixTranslation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::setViewTransform(const Transform& view) {
|
void Application::setViewTransform(const Transform& view) {
|
||||||
_viewTransform = view;
|
_viewTransform = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::loadTranslatedViewMatrix(const glm::vec3& translation) {
|
//void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation) {
|
||||||
glLoadMatrixf((const GLfloat*)&_untranslatedViewMatrix);
|
// glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix);
|
||||||
glTranslatef(translation.x + _viewMatrixTranslation.x, translation.y + _viewMatrixTranslation.y,
|
// _viewMatrixTranslation = viewMatrixTranslation;
|
||||||
translation.z + _viewMatrixTranslation.z);
|
//}
|
||||||
}
|
//
|
||||||
|
//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) {
|
void Application::getModelViewMatrix(glm::dmat4* modelViewMatrix) {
|
||||||
(*modelViewMatrix) =_untranslatedViewMatrix;
|
(*modelViewMatrix) = glm::inverse(_displayViewFrustum.getView());
|
||||||
(*modelViewMatrix)[3] = _untranslatedViewMatrix * glm::vec4(_viewMatrixTranslation, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::getProjectionMatrix(glm::dmat4* projectionMatrix) {
|
void Application::getProjectionMatrix(glm::dmat4* projectionMatrix) {
|
||||||
*projectionMatrix = _projectionMatrix;
|
*projectionMatrix = _displayViewFrustum.getProjection();
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::getShadowsEnabled() {
|
bool Application::getShadowsEnabled() {
|
||||||
|
@ -3497,8 +3419,6 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
|
||||||
glViewport(x, size.height() - y - height, width, height);
|
glViewport(x, size.height() - y - height, width, height);
|
||||||
glScissor(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);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
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();
|
glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition();
|
||||||
_rearMirrorTools->render(false, QPoint(mpos.x, mpos.y));
|
_rearMirrorTools->render(false, QPoint(mpos.x, mpos.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset Viewport and projection matrix
|
// reset Viewport and projection matrix
|
||||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
updateProjectionMatrix(_myCamera, updateViewFrustum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::resetSensors() {
|
void Application::resetSensors() {
|
||||||
|
@ -4598,11 +4516,11 @@ void Application::shutdownPlugins() {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Application::getHeadPosition() const {
|
glm::vec3 Application::getHeadPosition() const {
|
||||||
return getActiveDisplayPlugin()->headTranslation();
|
return glm::vec3(getActiveDisplayPlugin()->getHeadPose()[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::quat Application::getHeadOrientation() const {
|
glm::quat Application::getHeadOrientation() const {
|
||||||
return getActiveDisplayPlugin()->headOrientation();
|
return glm::quat_cast(getActiveDisplayPlugin()->getHeadPose());
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::uvec2 Application::getCanvasSize() const {
|
glm::uvec2 Application::getCanvasSize() const {
|
||||||
|
|
|
@ -249,10 +249,11 @@ public:
|
||||||
Overlays& getOverlays() { return _overlays; }
|
Overlays& getOverlays() { return _overlays; }
|
||||||
|
|
||||||
float getFps() const { return _fps; }
|
float getFps() const { return _fps; }
|
||||||
const glm::vec3& getViewMatrixTranslation() const { return _viewMatrixTranslation; }
|
//const glm::vec3& getViewMatrixTranslation() const { return _viewMatrixTranslation; }
|
||||||
void setViewMatrixTranslation(const glm::vec3& translation) { _viewMatrixTranslation = translation; }
|
//void setViewMatrixTranslation(const glm::vec3& translation) { _viewMatrixTranslation = translation; }
|
||||||
|
|
||||||
virtual const Transform& getViewTransform() const { return _viewTransform; }
|
virtual const Transform& getViewTransform() const { return _viewTransform; }
|
||||||
|
virtual Transform& getViewTransform() { return _viewTransform; }
|
||||||
void setViewTransform(const Transform& view);
|
void setViewTransform(const Transform& view);
|
||||||
|
|
||||||
float getFieldOfView() { return _fieldOfView.get(); }
|
float getFieldOfView() { return _fieldOfView.get(); }
|
||||||
|
@ -278,8 +279,9 @@ public:
|
||||||
|
|
||||||
QImage renderAvatarBillboard();
|
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
|
/// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as
|
||||||
/// the view matrix translation.
|
/// the view matrix translation.
|
||||||
void updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation = glm::vec3());
|
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
|
/// Loads a view matrix that incorporates the specified model translation without the precision issues that can
|
||||||
/// result from matrix multiplication at high translation magnitudes.
|
/// result from matrix multiplication at high translation magnitudes.
|
||||||
void loadTranslatedViewMatrix(const glm::vec3& translation);
|
void loadTranslatedViewMatrix(const glm::vec3& translation);
|
||||||
|
*/
|
||||||
void getModelViewMatrix(glm::dmat4* modelViewMatrix);
|
void getModelViewMatrix(glm::dmat4* modelViewMatrix);
|
||||||
void getProjectionMatrix(glm::dmat4* projectionMatrix);
|
void getProjectionMatrix(glm::dmat4* projectionMatrix);
|
||||||
|
|
||||||
virtual const glm::vec3& getShadowDistances() const { return _shadowDistances; }
|
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 ViewFrustum* getCurrentViewFrustum() { return getDisplayViewFrustum(); }
|
||||||
virtual bool getShadowsEnabled();
|
virtual bool getShadowsEnabled();
|
||||||
virtual bool getCascadeShadowsEnabled();
|
virtual bool getCascadeShadowsEnabled();
|
||||||
|
@ -476,10 +473,6 @@ private slots:
|
||||||
void setCursorVisible(bool visible);
|
void setCursorVisible(bool visible);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size);
|
|
||||||
void updateProjectionMatrix();
|
|
||||||
void updateProjectionMatrix(Camera& camera, bool updateViewFrustum = true);
|
|
||||||
|
|
||||||
void updateCursorVisibility();
|
void updateCursorVisibility();
|
||||||
|
|
||||||
void sendPingPackets();
|
void sendPingPackets();
|
||||||
|
@ -505,7 +498,6 @@ private:
|
||||||
void renderLookatIndicator(glm::vec3 pointOfInterest);
|
void renderLookatIndicator(glm::vec3 pointOfInterest);
|
||||||
|
|
||||||
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
|
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
|
||||||
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
|
|
||||||
|
|
||||||
glm::vec3 getSunDirection();
|
glm::vec3 getSunDirection();
|
||||||
|
|
||||||
|
@ -579,9 +571,11 @@ private:
|
||||||
Setting::Handle<float> _fieldOfView;
|
Setting::Handle<float> _fieldOfView;
|
||||||
|
|
||||||
Transform _viewTransform;
|
Transform _viewTransform;
|
||||||
|
glm::mat4 _projectionMatrix;
|
||||||
|
/*
|
||||||
glm::mat4 _untranslatedViewMatrix;
|
glm::mat4 _untranslatedViewMatrix;
|
||||||
glm::vec3 _viewMatrixTranslation;
|
glm::vec3 _viewMatrixTranslation;
|
||||||
glm::mat4 _projectionMatrix;
|
*/
|
||||||
|
|
||||||
float _scaleMirror;
|
float _scaleMirror;
|
||||||
float _rotateMirror;
|
float _rotateMirror;
|
||||||
|
|
|
@ -46,13 +46,7 @@ QString modeToString(CameraMode mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera::Camera() :
|
Camera::Camera() :
|
||||||
_mode(CAMERA_MODE_THIRD_PERSON),
|
_projection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), 16.0f/9.0f, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP))
|
||||||
_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)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,26 +57,33 @@ void Camera::update(float deltaTime) {
|
||||||
return;
|
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) {
|
void Camera::setPosition(const glm::vec3& position) {
|
||||||
_position = position;
|
_position = position;
|
||||||
|
recompose();
|
||||||
|
if (_isKeepLookingAt) {
|
||||||
|
lookAt(_lookingAt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setRotation(const glm::quat& rotation) {
|
void Camera::setRotation(const glm::quat& rotation) {
|
||||||
_rotation = rotation;
|
_rotation = rotation;
|
||||||
if (_isKeepLookingAt) {
|
recompose();
|
||||||
lookAt(_lookingAt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::setHmdPosition(const glm::vec3& hmdPosition) {
|
|
||||||
_hmdPosition = hmdPosition;
|
|
||||||
if (_isKeepLookingAt) {
|
|
||||||
lookAt(_lookingAt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::setHmdRotation(const glm::quat& hmdRotation) {
|
|
||||||
_hmdRotation = hmdRotation;
|
|
||||||
if (_isKeepLookingAt) {
|
if (_isKeepLookingAt) {
|
||||||
lookAt(_lookingAt);
|
lookAt(_lookingAt);
|
||||||
}
|
}
|
||||||
|
@ -143,3 +144,21 @@ void Camera::keepLookingAt(const glm::vec3& point) {
|
||||||
_isKeepLookingAt = true;
|
_isKeepLookingAt = true;
|
||||||
_lookingAt = point;
|
_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 update( float deltaTime );
|
||||||
|
|
||||||
void setRotation(const glm::quat& rotation);
|
CameraMode getMode() const { return _mode; }
|
||||||
void setProjection(const glm::mat4 & projection);
|
|
||||||
void setHmdPosition(const glm::vec3& hmdPosition);
|
|
||||||
void setHmdRotation(const glm::quat& hmdRotation);
|
|
||||||
void setMode(CameraMode m);
|
void setMode(CameraMode m);
|
||||||
|
|
||||||
glm::quat getRotation() const { return _rotation * _hmdRotation; }
|
|
||||||
const glm::mat4& getProjection() const { return _projection; }
|
const glm::mat4& getProjection() const { return _projection; }
|
||||||
const glm::vec3& getHmdPosition() const { return _hmdPosition; }
|
void setProjection(const glm::mat4& projection);
|
||||||
const glm::quat& getHmdRotation() const { return _hmdRotation; }
|
|
||||||
CameraMode getMode() const { return _mode; }
|
void loadViewFrustum(ViewFrustum& frustum) const;
|
||||||
|
ViewFrustum toViewFrustum() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
QString getModeString() const;
|
QString getModeString() const;
|
||||||
void setModeString(const QString& mode);
|
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);
|
void setPosition(const glm::vec3& position);
|
||||||
|
|
||||||
|
const glm::quat getOrientation() const { return getRotation(); }
|
||||||
void setOrientation(const glm::quat& orientation) { setRotation(orientation); }
|
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);
|
PickRay computePickRay(float x, float y);
|
||||||
|
|
||||||
// These only work on independent cameras
|
// These only work on independent cameras
|
||||||
|
@ -82,13 +85,17 @@ signals:
|
||||||
void modeUpdated(const QString& newMode);
|
void modeUpdated(const QString& newMode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CameraMode _mode;
|
void recompose();
|
||||||
|
void decompose();
|
||||||
|
|
||||||
|
CameraMode _mode{ CAMERA_MODE_THIRD_PERSON };
|
||||||
|
glm::mat4 _transform;
|
||||||
|
glm::mat4 _projection;
|
||||||
|
|
||||||
|
// derived
|
||||||
glm::vec3 _position;
|
glm::vec3 _position;
|
||||||
glm::quat _rotation;
|
glm::quat _rotation;
|
||||||
glm::mat4 _projection;
|
bool _isKeepLookingAt{ false };
|
||||||
glm::vec3 _hmdPosition;
|
|
||||||
glm::quat _hmdRotation;
|
|
||||||
bool _isKeepLookingAt;
|
|
||||||
glm::vec3 _lookingAt;
|
glm::vec3 _lookingAt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -68,17 +68,17 @@ void Environment::resetToDefault() {
|
||||||
_data[HifiSockAddr()][0];
|
_data[HifiSockAddr()][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::renderAtmospheres(Camera& camera) {
|
void Environment::renderAtmospheres(const glm::vec3& position) {
|
||||||
// get the lock for the duration of the call
|
// get the lock for the duration of the call
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
|
|
||||||
if (_environmentIsOverridden) {
|
if (_environmentIsOverridden) {
|
||||||
renderAtmosphere(camera, _overrideData);
|
renderAtmosphere(position, _overrideData);
|
||||||
} else {
|
} else {
|
||||||
foreach (const ServerData& serverData, _data) {
|
foreach (const ServerData& serverData, _data) {
|
||||||
// TODO: do something about EnvironmentData
|
// TODO: do something about EnvironmentData
|
||||||
foreach (const EnvironmentData& environmentData, serverData) {
|
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;
|
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();
|
glm::vec3 center = data.getAtmosphereCenter();
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(center.x, center.y, center.z);
|
glTranslatef(center.x, center.y, center.z);
|
||||||
|
|
||||||
glm::vec3 relativeCameraPos = camera.getPosition() - center;
|
glm::vec3 relativeCameraPos = position - center;
|
||||||
float height = glm::length(relativeCameraPos);
|
float height = glm::length(relativeCameraPos);
|
||||||
|
|
||||||
// use the appropriate shader depending on whether we're inside or outside
|
// use the appropriate shader depending on whether we're inside or outside
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void resetToDefault();
|
void resetToDefault();
|
||||||
void renderAtmospheres(Camera& camera);
|
void renderAtmospheres(const glm::vec3& camera);
|
||||||
|
|
||||||
void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; }
|
void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; }
|
||||||
void endOverride() { _environmentIsOverridden = false; }
|
void endOverride() { _environmentIsOverridden = false; }
|
||||||
|
@ -46,7 +46,7 @@ private:
|
||||||
|
|
||||||
ProgramObject* createSkyProgram(const char* from, int* locations);
|
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;
|
bool _initialized;
|
||||||
ProgramObject* _skyFromAtmosphereProgram;
|
ProgramObject* _skyFromAtmosphereProgram;
|
||||||
|
|
|
@ -767,6 +767,7 @@ void SkeletonModel::resetShapePositionsToDefaultPose() {
|
||||||
|
|
||||||
void SkeletonModel::renderBoundingCollisionShapes(float alpha) {
|
void SkeletonModel::renderBoundingCollisionShapes(float alpha) {
|
||||||
const int BALL_SUBDIVISIONS = 10;
|
const int BALL_SUBDIVISIONS = 10;
|
||||||
|
#if 0
|
||||||
if (_shapes.isEmpty()) {
|
if (_shapes.isEmpty()) {
|
||||||
// the bounding shape has not been propery computed
|
// the bounding shape has not been propery computed
|
||||||
// so no need to render it
|
// 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));
|
Avatar::renderJointConnectingCone( origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), glm::vec4(0.6f, 0.8f, 0.6f, alpha));
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkeletonModel::hasSkeleton() {
|
bool SkeletonModel::hasSkeleton() {
|
||||||
|
|
|
@ -120,7 +120,7 @@ void TV3DManager::display(Camera& whichCamera) {
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
qApp->displaySide(eyeCamera, false, RenderArgs::MONO);
|
qApp->displaySide(eyeCamera, false);
|
||||||
#if 0
|
#if 0
|
||||||
qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov);
|
qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
class Plugin : public QObject {
|
class Plugin : public QObject {
|
||||||
public:
|
public:
|
||||||
virtual const QString & getName() = 0;
|
virtual const QString & getName() = 0;
|
||||||
virtual bool isSupported() { return true; }
|
virtual bool isSupported() const { return true; }
|
||||||
|
|
||||||
virtual void init() {}
|
virtual void init() {}
|
||||||
virtual void deinit() {}
|
virtual void deinit() {}
|
||||||
|
|
|
@ -21,14 +21,34 @@
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
#include <RegisteredMetaTypes.h>
|
#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 {
|
class DisplayPlugin : public Plugin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum class Eye {
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
Mono
|
|
||||||
};
|
|
||||||
virtual bool isHmd() const { return false; }
|
virtual bool isHmd() const { return false; }
|
||||||
virtual bool isStereo() const { return false; }
|
virtual bool isStereo() const { return false; }
|
||||||
virtual bool isThrottled() const { return false; }
|
virtual bool isThrottled() const { return false; }
|
||||||
|
@ -76,23 +96,24 @@ public:
|
||||||
};
|
};
|
||||||
virtual bool isMouseOnScreen() const;
|
virtual bool isMouseOnScreen() const;
|
||||||
|
|
||||||
|
|
||||||
// Stereo specific methods
|
// Stereo specific methods
|
||||||
virtual glm::mat4 getProjection(Eye eye) const {
|
virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const {
|
||||||
return glm::mat4();
|
return baseProjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual glm::mat4 getModelview(Eye eye, const glm::mat4& baseModelview) const {
|
||||||
|
return glm::inverse(getEyePose(eye)) * baseModelview;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HMD specific methods
|
// HMD specific methods
|
||||||
// TODO move these into another class
|
// 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;
|
static const glm::mat4 pose; return pose;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual glm::quat headOrientation() const {
|
virtual glm::mat4 getHeadPose() const {
|
||||||
static const glm::quat orientation; return orientation;
|
static const glm::mat4 pose; return pose;
|
||||||
}
|
|
||||||
|
|
||||||
virtual glm::vec3 headTranslation() const {
|
|
||||||
static const glm::vec3 tranlsation; return tranlsation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void abandonCalibration() {}
|
virtual void abandonCalibration() {}
|
||||||
|
@ -108,3 +129,4 @@ protected:
|
||||||
virtual void doneCurrent() {}
|
virtual void doneCurrent() {}
|
||||||
virtual void swapBuffers() {}
|
virtual void swapBuffers() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,8 @@ void LegacyDisplayPlugin::activate() {
|
||||||
|
|
||||||
_window->installEventFilter(qApp);
|
_window->installEventFilter(qApp);
|
||||||
_window->installEventFilter(DependencyManager::get<OffscreenUi>().data());
|
_window->installEventFilter(DependencyManager::get<OffscreenUi>().data());
|
||||||
|
|
||||||
|
DependencyManager::get<OffscreenUi>()->setProxyWindow(_window->windowHandle());
|
||||||
SimpleDisplayPlugin::activate();
|
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;
|
gpu::TexturePointer _crosshairTexture;
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,210 +243,3 @@ void Tv3dDisplayPlugin::deactivate() {
|
||||||
_timer.stop();
|
_timer.stop();
|
||||||
GlWindowDisplayPlugin::deactivate();
|
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();
|
virtual const QString & getName();
|
||||||
Tv3dDisplayPlugin();
|
Tv3dDisplayPlugin();
|
||||||
virtual bool isStereo() const final { return true; }
|
virtual bool isStereo() const final { return true; }
|
||||||
|
virtual bool isSupported() const final;
|
||||||
void display(GLuint sceneTexture, const glm::uvec2& sceneSize,
|
void display(GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize);
|
GLuint overlayTexture, const glm::uvec2& overlaySize);
|
||||||
virtual void activate();
|
virtual void activate();
|
||||||
|
|
|
@ -9,16 +9,17 @@
|
||||||
//
|
//
|
||||||
#include "WindowDisplayPlugin.h"
|
#include "WindowDisplayPlugin.h"
|
||||||
#include "RenderUtil.h"
|
#include "RenderUtil.h"
|
||||||
|
#include "Application.h"
|
||||||
#include <QCoreApplication>
|
|
||||||
|
|
||||||
WindowDisplayPlugin::WindowDisplayPlugin() {
|
WindowDisplayPlugin::WindowDisplayPlugin() {
|
||||||
connect(&_timer, &QTimer::timeout, this, [&] {
|
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() {
|
const QString & WindowDisplayPlugin::getName() {
|
||||||
return NAME;
|
return NAME;
|
||||||
|
@ -35,417 +36,3 @@ void WindowDisplayPlugin::deactivate() {
|
||||||
GlWindowDisplayPlugin::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);
|
glEnable(GL_LIGHTING);
|
||||||
} glPopMatrix();
|
} glPopMatrix();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Draws the FBO texture for 3DTV.
|
// Draws the FBO texture for 3DTV.
|
||||||
void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov) {
|
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);
|
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void ApplicationOverlay::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) const {
|
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);
|
glm::vec3 overlaySpaceDirection = glm::normalize(orientation * IDENTITY_FRONT);
|
||||||
|
|
||||||
|
|
||||||
const glm::vec3& hmdPosition = qApp->getCamera()->getHmdPosition();
|
glm::vec3 hmdPosition; // = qApp->getCamera()->getHmdPosition();
|
||||||
const glm::quat& hmdOrientation = qApp->getCamera()->getHmdRotation();
|
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
|
// rendered relative to
|
||||||
const glm::vec3 overlayPosition = qApp->getCamera()->getPosition() - hmdPosition;
|
const glm::vec3 overlayPosition = qApp->getCamera()->getPosition();
|
||||||
const glm::quat overlayOrientation = qApp->getCamera()->getRotation() * glm::inverse(hmdOrientation);
|
const glm::quat overlayOrientation = qApp->getCamera()->getRotation();
|
||||||
|
|
||||||
// Intersection UI overlay space
|
// Intersection UI overlay space
|
||||||
glm::vec3 worldSpaceDirection = overlayOrientation * overlaySpaceDirection;
|
glm::vec3 worldSpaceDirection = overlayOrientation * overlaySpaceDirection;
|
||||||
|
|
|
@ -38,23 +38,18 @@ void LocalModelsOverlay::render(RenderArgs* args) {
|
||||||
if (_visible) {
|
if (_visible) {
|
||||||
|
|
||||||
float glowLevel = getGlowLevel();
|
float glowLevel = getGlowLevel();
|
||||||
Glower* glower = NULL;
|
QSharedPointer<Glower> glower;
|
||||||
if (glowLevel > 0.0f) {
|
if (glowLevel > 0.0f) {
|
||||||
glower = new Glower(glowLevel);
|
glower = QSharedPointer<Glower>(new Glower(glowLevel));
|
||||||
}
|
}
|
||||||
|
|
||||||
glPushMatrix(); {
|
glPushMatrix(); {
|
||||||
Application* app = Application::getInstance();
|
Application* app = Application::getInstance();
|
||||||
glm::vec3 oldTranslation = app->getViewMatrixTranslation();
|
Transform originalTransform = qApp->getViewTransform();
|
||||||
app->setViewMatrixTranslation(oldTranslation + _position);
|
qApp->getViewTransform().postTranslate(_position);
|
||||||
_entityTreeRenderer->render();
|
_entityTreeRenderer->render();
|
||||||
Application::getInstance()->setViewMatrixTranslation(oldTranslation);
|
qApp->setViewTransform(originalTransform);
|
||||||
} glPopMatrix();
|
} glPopMatrix();
|
||||||
|
|
||||||
if (glower) {
|
|
||||||
delete glower;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,14 +27,17 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
ViewFrustum::ViewFrustum() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewFrustum::setOrientation(const glm::quat& orientationAsQuaternion) {
|
void ViewFrustum::setOrientation(const glm::quat& orientationAsQuaternion) {
|
||||||
_orientation = orientationAsQuaternion;
|
_orientation = orientationAsQuaternion;
|
||||||
_right = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_RIGHT, 0.0f));
|
_right = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_RIGHT, 0.0f));
|
||||||
_up = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_UP, 0.0f));
|
_up = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_UP, 0.0f));
|
||||||
_direction = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_FRONT, 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.
|
// Order cooresponds to the order defined in the BoxVertex enum.
|
||||||
|
|
|
@ -36,11 +36,9 @@ const float DEFAULT_FAR_CLIP = (float)TREE_SCALE;
|
||||||
|
|
||||||
class ViewFrustum {
|
class ViewFrustum {
|
||||||
public:
|
public:
|
||||||
ViewFrustum();
|
|
||||||
|
|
||||||
// setters for camera attributes
|
// setters for camera attributes
|
||||||
void setPosition(const glm::vec3& p) { _position = p; }
|
void setPosition(const glm::vec3& position);
|
||||||
void setOrientation(const glm::quat& orientationAsQuaternion);
|
void setOrientation(const glm::quat& orientation);
|
||||||
|
|
||||||
// getters for camera attributes
|
// getters for camera attributes
|
||||||
const glm::vec3& getPosition() const { return _position; }
|
const glm::vec3& getPosition() const { return _position; }
|
||||||
|
@ -54,7 +52,8 @@ public:
|
||||||
void getFocalLength(float focalLength) { _focalLength = focalLength; }
|
void getFocalLength(float focalLength) { _focalLength = focalLength; }
|
||||||
|
|
||||||
// getters for lens attributes
|
// 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 getWidth() const { return _width; }
|
||||||
float getHeight() const { return _height; }
|
float getHeight() const { return _height; }
|
||||||
float getFieldOfView() const { return _fieldOfView; }
|
float getFieldOfView() const { return _fieldOfView; }
|
||||||
|
@ -120,6 +119,7 @@ private:
|
||||||
// camera location/orientation attributes
|
// camera location/orientation attributes
|
||||||
glm::vec3 _position; // the position in world-frame
|
glm::vec3 _position; // the position in world-frame
|
||||||
glm::quat _orientation;
|
glm::quat _orientation;
|
||||||
|
glm::mat4 _view;
|
||||||
|
|
||||||
// Lens attributes
|
// Lens attributes
|
||||||
glm::mat4 _projection;
|
glm::mat4 _projection;
|
||||||
|
|
|
@ -30,10 +30,6 @@ public:
|
||||||
/// Returns the shadow distances for the current view state
|
/// Returns the shadow distances for the current view state
|
||||||
virtual const glm::vec3& getShadowDistances() const = 0;
|
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
|
/// gets the current view frustum for rendering the view state
|
||||||
virtual ViewFrustum* getCurrentViewFrustum() = 0;
|
virtual ViewFrustum* getCurrentViewFrustum() = 0;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
#include <ViewFrustum.h>
|
||||||
|
|
||||||
#include "AbstractViewStateInterface.h"
|
#include "AbstractViewStateInterface.h"
|
||||||
#include "AmbientOcclusionEffect.h"
|
#include "AmbientOcclusionEffect.h"
|
||||||
|
@ -112,7 +113,8 @@ void AmbientOcclusionEffect::render() {
|
||||||
|
|
||||||
float left, right, bottom, top, nearVal, farVal;
|
float left, right, bottom, top, nearVal, farVal;
|
||||||
glm::vec4 nearClipPlane, farClipPlane;
|
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];
|
int viewport[4];
|
||||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||||
|
|
|
@ -319,9 +319,10 @@ void DeferredLightingEffect::render() {
|
||||||
glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat));
|
glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto viewFrustum = _viewState->getCurrentViewFrustum();
|
||||||
float left, right, bottom, top, nearVal, farVal;
|
float left, right, bottom, top, nearVal, farVal;
|
||||||
glm::vec4 nearClipPlane, farClipPlane;
|
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);
|
program->setUniformValue(locations->nearLocation, nearVal);
|
||||||
float depthScale = (farVal - nearVal) / farVal;
|
float depthScale = (farVal - nearVal) / farVal;
|
||||||
program->setUniformValue(locations->depthScale, depthScale);
|
program->setUniformValue(locations->depthScale, depthScale);
|
||||||
|
@ -363,8 +364,8 @@ void DeferredLightingEffect::render() {
|
||||||
// enlarge the scales slightly to account for tesselation
|
// enlarge the scales slightly to account for tesselation
|
||||||
const float SCALE_EXPANSION = 0.05f;
|
const float SCALE_EXPANSION = 0.05f;
|
||||||
|
|
||||||
const glm::vec3& eyePoint = _viewState->getCurrentViewFrustum()->getPosition();
|
const glm::vec3& eyePoint = viewFrustum->getPosition();
|
||||||
float nearRadius = glm::distance(eyePoint, _viewState->getCurrentViewFrustum()->getNearTopLeft());
|
float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft());
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue