Working on display plugins

This commit is contained in:
Brad Davis 2015-05-26 17:32:41 -07:00
parent e651c722c3
commit b5e6b737c4
21 changed files with 220 additions and 873 deletions

View file

@ -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 {

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
};

View file

@ -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

View file

@ -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;

View file

@ -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() {

View file

@ -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

View file

@ -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() {}

View file

@ -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() {}
};

View file

@ -45,6 +45,8 @@ void LegacyDisplayPlugin::activate() {
_window->installEventFilter(qApp);
_window->installEventFilter(DependencyManager::get<OffscreenUi>().data());
DependencyManager::get<OffscreenUi>()->setProxyWindow(_window->windowHandle());
SimpleDisplayPlugin::activate();
}

View file

@ -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

View file

@ -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();

View file

@ -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

View file

@ -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;

View file

@ -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;
}
}
}

View file

@ -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.

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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>();