Commit 4db0a184 authored by Frédéric Larue's avatar Frédéric Larue
Browse files

All view related matrices are computed only once per frame rendering, and only if needed.

parent cdbaacca
......@@ -125,25 +125,34 @@ GLViewer::~GLViewer()
void GLViewer::init( DisplayDoF dof )
{
m_MustUpdateFocal = false;
m_MustUpdateProjectionMatrix = false;
m_MustUpdateViewMatrix = false;
m_SpeedFactor = 1.0;
m_CtrlSpeedFactor = 4.0;
m_ShiftSpeedFactor = 0.25;
m_FocusPoint[0] = m_FocusPoint[1] = m_FocusPoint[2] = 0.0;
m_DistToFocusPoint = 400.0;
m_FocusPoint = QVector3D(-1.0f,-1.0f,-1.0f);
setFocusPoint( QVector3D(0.0f,0.0f,0.0f) );
m_DoF = dof;
QMatrix4x4 rot;
if( dof == DISPLAY_DOF_2D )
m_ViewRotationMatrix.setToIdentity();
rot.setToIdentity();
else
{
m_ViewRotationMatrix.rotate( 30.0f, 1,0,0 );
m_ViewRotationMatrix.rotate( -30.0f, 0,1,0 );
rot.rotate( 30.0f, 1,0,0 );
rot.rotate( -30.0f, 0,1,0 );
}
setViewRotationMatrix( rot );
m_FovY = 0.0f;
setFovY( 65.0f );
m_DistToFocusPoint = 0.0f;
setDistToFocusPoint( 400.0f );
m_FovY = 65.0;
m_ZNear = 0.01 * m_DistToFocusPoint;
m_ZFar = 5.0 * m_DistToFocusPoint;
m_PointSize = 2;
m_IsCullingEnabled = false;
......@@ -424,9 +433,8 @@ void GLViewer::frameBox( Box3f &box, const QMatrix4x4 *xf )
if( !box.IsNull() )
{
double boxHalfDiag = box.Dimensions().length() * 0.5;
double focal = 1.0 / std::tan( m_FovY*M_PI/360.0 );
double depth = ( 2.0*m_ZFar*m_ZNear - m_DistToFocusPoint*(m_ZFar+m_ZNear) ) / (m_ZNear-m_ZFar);
double projectedRadius = boxHalfDiag * focal / depth;
double depth = ( 2.0*zFar()*zNear() - distToFocusPoint()*(zFar()+zNear()) ) / (zNear()-zFar());
double projectedRadius = boxHalfDiag * focal() / depth;
if( xf )
setFocusPoint( xf->map(box.Center()) );
......@@ -434,7 +442,7 @@ void GLViewer::frameBox( Box3f &box, const QMatrix4x4 *xf )
setFocusPoint( box.Center() );
if( projectedRadius > 0.000001 )
setDistToFocusPoint( m_DistToFocusPoint * (width()<height()? projectedRadius*height()/width() : projectedRadius) );
setDistToFocusPoint( distToFocusPoint() * (width()<height()? projectedRadius*height()/width() : projectedRadius) );
}
}
......@@ -748,35 +756,6 @@ void GLViewer::mouseMotionNavigationEvent( float dx, float dy, QMouseEvent *evt
}
QMatrix4x4 GLViewer::projectionMatrix() const
{
const double f = 1.0 / std::tan( 0.5 * (m_FovY*M_PI/180.0) );
QMatrix4x4 proj;
proj.fill( 0.0f );
proj(0,0) = f * height() / width();
proj(1,1) = f;
proj(2,2) = (m_ZNear + m_ZFar) / (m_ZNear - m_ZFar);
proj(2,3) = 2.0*m_ZNear*m_ZFar / (m_ZNear - m_ZFar);
proj(3,2) = -1.0;
return proj;
}
QMatrix4x4 GLViewer::viewMatrix() const
{
QMatrix4x4 mv;
mv.translate( 0.0, 0.0, -m_DistToFocusPoint );
mv *= m_ViewRotationMatrix;
mv.translate( -m_FocusPoint );
return mv;
}
QMatrix4x4 GLViewer::viewportMatrix( bool flipY ) const
{
const float xOff = 0.5f*width(), yOff = 0.5f*height();
......@@ -792,10 +771,8 @@ QMatrix4x4 GLViewer::viewportMatrix( bool flipY ) const
QMatrix4x4 GLViewer::modelMatrix( const DisplayableInterface *d ) const
{
auto dispInfo = m_Displayables.find(d->getSource());
if( dispInfo != m_Displayables.end() )
return dispInfo->second.GetTransform();
else
return QMatrix4x4();
assert( dispInfo != m_Displayables.end() );
return dispInfo->second.GetTransform();
}
......@@ -883,10 +860,12 @@ void GLViewer::paintGL()
// Setting up the OpenGL viewport.
glViewport( 0, 0, width(), height() );
// Clear the frame buffer.
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
......@@ -912,8 +891,55 @@ void GLViewer::paintGL()
glClear( GL_DEPTH_BUFFER_BIT );
// Setting up the OpenGL transforms and viewport.
glMatrixMode( GL_PROJECTION );
// Update the projection and view matrices, if needed.
if( m_MustUpdateFocal )
{
m_Focal = 1.0 / std::tan( fovY()*M_PI/360.0 );
m_MustUpdateFocal = false;
m_MustUpdateProjectionMatrix = true;
}
bool mustUpdateViewProjectionMatrix = false;
if( m_MustUpdateProjectionMatrix )
{
m_ProjectionMatrix.fill( 0.0f );
m_ProjectionMatrix(0,0) = focal() * height() / width();
m_ProjectionMatrix(1,1) = focal();
m_ProjectionMatrix(2,2) = (zNear() + zFar()) / (zNear() - zFar());
m_ProjectionMatrix(2,3) = 2.0f*zNear()*zFar() / (zNear() - zFar());
m_ProjectionMatrix(3,2) = -1.0f;
m_ProjectionMatrixInverse = m_ProjectionMatrix.inverted();
m_MustUpdateProjectionMatrix = false;
mustUpdateViewProjectionMatrix = true;
}
if( m_MustUpdateViewMatrix )
{
m_ViewMatrix.setToIdentity();
m_ViewMatrix.translate( 0.0, 0.0, -distToFocusPoint() );
m_ViewMatrix *= viewRotationMatrix();
m_ViewMatrix.translate( -focusPoint() );
m_ViewMatrixInverse = m_ViewMatrix.inverted();
m_MustUpdateViewMatrix = false;
mustUpdateViewProjectionMatrix = true;
}
if( mustUpdateViewProjectionMatrix )
{
m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix;
m_ViewProjectionMatrixInverse = m_ViewMatrixInverse * m_ProjectionMatrixInverse;
}
// Setup the OpenGL transforms and viewport.
glMatrixMode( GL_PROJECTION );
glLoadMatrixf( projectionMatrix().data() );
glMatrixMode( GL_MODELVIEW );
......@@ -1047,7 +1073,7 @@ void GLViewer::displayLabel( DisplayableInterface *d )
// Display the name of the image on overlay in the bottom-left corner, by constraining it to the displayed image rectangle.
QMatrix4x4 toViewportCoord = viewportMatrix(true) * modelViewProjectionMatrix(d);
QMatrix4x4 toViewportCoord = viewportMatrix(true) * MVPMatrix(d);
QVector3D bottomLeft = toViewportCoord.map( QVector3D( box.Min().x(), box.Min().y(), 0.0f ) );
QVector3D topRight = toViewportCoord.map( QVector3D( box.Max().x(), box.Max().y(), 0.0f ) );
......@@ -1093,6 +1119,8 @@ void GLViewer::displayLabel( DisplayableInterface *d )
void GLViewer::resizeGL( int width, int height )
{
m_MustUpdateProjectionMatrix = true;
glViewport( 0, 0, width, height );
m_InfoBarManager->onReshape();
......@@ -1220,7 +1248,7 @@ void GLViewer::updateSelectionZBuffer()
for( PriorityMap::iterator dlist=m_DisplayablesByPriority.begin(); dlist!=m_DisplayablesByPriority.end(); ++dlist )
for( DisplayableList::iterator dinfo=dlist->second.begin(); dinfo!=dlist->second.end(); ++dinfo )
{
m_ZBufferShader.SetUniform( "fullTransformMatrix", (projectionMatrix() * viewMatrix() * (*dinfo)->GetTransform()).data() );
m_ZBufferShader.SetUniform( "fullTransformMatrix", (viewProjectionMatrix() * (*dinfo)->GetTransform()).data() );
glPushAttrib( GL_ALL_ATTRIB_BITS );
(*dinfo)->displayable->onPicking( *(*dinfo)->displayable->getSource()->GetDisplayOptions(), m_ZBufferShader, "vertexPosition" );
glPopAttrib();
......@@ -1558,15 +1586,15 @@ void GLViewer::wheelEvent( QWheelEvent* evt )
{
if( !isSelectionEnabled() )
{
double deltaD = -0.0005 * m_SpeedFactor * m_DistToFocusPoint * evt->delta();
double deltaD = -0.0005 * m_SpeedFactor * distToFocusPoint() * evt->delta();
if( evt->modifiers() & Qt::ShiftModifier )
deltaD *= m_ShiftSpeedFactor;
else if( evt->modifiers() & Qt::ControlModifier )
deltaD *= m_CtrlSpeedFactor;
if( m_DistToFocusPoint + deltaD > 0.0 )
setDistToFocusPoint( m_DistToFocusPoint + deltaD );
if( distToFocusPoint() + deltaD > 0.0 )
setDistToFocusPoint( distToFocusPoint() + deltaD );
}
else
{
......@@ -2003,10 +2031,10 @@ bool GLViewer::getPickedPoint( const float x,
// The projection matrix is retargeted so as to focus only on a small window around the mouse cursor.
QMatrix4x4 projMat = projectionMatrix();
double frustumL = m_ZNear * (projMat(0,2)-1.0f) / projMat(0,0);
double frustumR = m_ZNear * (projMat(0,2)+1.0f) / projMat(0,0);
double frustumB = m_ZNear * (projMat(1,2)-1.0f) / projMat(1,1);
double frustumT = m_ZNear * (projMat(1,2)+1.0f) / projMat(1,1);
double frustumL = zNear() * (projMat(0,2)-1.0f) / projMat(0,0);
double frustumR = zNear() * (projMat(0,2)+1.0f) / projMat(0,0);
double frustumB = zNear() * (projMat(1,2)-1.0f) / projMat(1,1);
double frustumT = zNear() * (projMat(1,2)+1.0f) / projMat(1,1);
double newFrustumL = frustumL + (frustumR-frustumL) * (x+0.5f-PICKING_WIN_RADIUS)/width();
double newFrustumR = frustumL + (frustumR-frustumL) * (x+0.5f+PICKING_WIN_RADIUS)/width();
......@@ -2014,12 +2042,12 @@ bool GLViewer::getPickedPoint( const float x,
double newFrustumT = frustumB + (frustumT-frustumB) * (y+0.5f+PICKING_WIN_RADIUS)/height();
projMat.fill( 0.0f );
projMat(0,0) = 2.0f * m_ZNear / (newFrustumR - newFrustumL);
projMat(0,0) = 2.0f * zNear() / (newFrustumR - newFrustumL);
projMat(0,2) = (newFrustumR + newFrustumL) / (newFrustumR - newFrustumL);
projMat(1,1) = 2.0f * m_ZNear / (newFrustumT - newFrustumB);
projMat(1,1) = 2.0f * zNear() / (newFrustumT - newFrustumB);
projMat(1,2) = (newFrustumT + newFrustumB) / (newFrustumT - newFrustumB);
projMat(2,2) = (m_ZNear + m_ZFar) / (m_ZNear - m_ZFar);
projMat(2,3) = 2.0f * m_ZNear * m_ZFar / (m_ZNear - m_ZFar);
projMat(2,2) = (zNear() + zFar()) / (zNear() - zFar());
projMat(2,3) = 2.0f * zNear() * zFar() / (zNear() - zFar());
projMat(3,2) = -1.0f;
......@@ -2172,6 +2200,9 @@ void GLViewer::setFocusPoint( const QVector3D& p )
p.z() != m_FocusPoint.z() )
{
m_FocusPoint = p;
m_MustUpdateViewMatrix = true;
emit focusPointChanged( m_FocusPoint );
update();
}
......@@ -2186,6 +2217,9 @@ void GLViewer::setDistToFocusPoint( const float d )
m_ZNear = 0.01 * m_DistToFocusPoint;
m_ZFar = 5.0 * m_DistToFocusPoint;
m_MustUpdateProjectionMatrix = true;
m_MustUpdateViewMatrix = true;
emit distToFocusPointChanged( m_DistToFocusPoint );
update();
}
......@@ -2195,6 +2229,9 @@ void GLViewer::setDistToFocusPoint( const float d )
void GLViewer::setViewRotationMatrix( const QMatrix4x4& m )
{
m_ViewRotationMatrix = m;
m_MustUpdateViewMatrix = true;
update();
}
......@@ -2204,6 +2241,10 @@ void GLViewer::setFovY( float fovY )
if( fovY != m_FovY )
{
m_FovY = fovY;
m_MustUpdateFocal = true;
m_MustUpdateProjectionMatrix = true;
emit fovYChanged( m_FovY );
update();
}
......
......@@ -137,6 +137,22 @@ protected:
GPU::Shader m_ZBufferShader;
GPU::Texture2D m_SelectionDepthBuffer;
// View related transformations.
bool m_MustUpdateFocal;
double m_Focal;
bool m_MustUpdateProjectionMatrix;
QMatrix4x4 m_ProjectionMatrix;
QMatrix4x4 m_ProjectionMatrixInverse;
bool m_MustUpdateViewMatrix;
QMatrix4x4 m_ViewMatrix;
QMatrix4x4 m_ViewMatrixInverse;
QMatrix4x4 m_ViewProjectionMatrix;
QMatrix4x4 m_ViewProjectionMatrixInverse;
/*****************************\
| Constructor(s) / destructor |
\*****************************/
......@@ -189,30 +205,42 @@ public:
void paintGL();
virtual void resizeGL( int width, int height );
inline float speedFactor() const { return m_SpeedFactor; }
inline float ctrlSpeedFactor() const { return m_CtrlSpeedFactor; }
inline float shiftSpeedFactor() const { return m_ShiftSpeedFactor; }
inline const QVector3D& focusPoint() const { return m_FocusPoint; }
inline float distToFocusPoint() const { return m_DistToFocusPoint; }
inline const QMatrix4x4& viewRotationMatrix() const { return m_ViewRotationMatrix; }
inline float fovY() const { return m_FovY; }
inline float zNear() const { return m_ZNear; }
inline float zFar() const { return m_ZFar; }
inline float pointSize() const { return m_PointSize; }
inline DisplayDoF dof() const { return m_DoF; }
QMatrix4x4 projectionMatrix() const;
QMatrix4x4 viewMatrix() const;
QMatrix4x4 viewportMatrix( bool flipY = false ) const;
inline float speedFactor() const { return m_SpeedFactor; }
inline float ctrlSpeedFactor() const { return m_CtrlSpeedFactor; }
inline float shiftSpeedFactor() const { return m_ShiftSpeedFactor; }
inline const QVector3D& focusPoint() const { return m_FocusPoint; }
inline float distToFocusPoint() const { return m_DistToFocusPoint; }
inline const QMatrix4x4& viewRotationMatrix() const { return m_ViewRotationMatrix; }
inline float fovY() const { return m_FovY; }
inline double focal() const { return m_Focal; }
inline float zNear() const { return m_ZNear; }
inline float zFar() const { return m_ZFar; }
inline float pointSize() const { return m_PointSize; }
inline DisplayDoF dof() const { return m_DoF; }
const QMatrix4x4& projectionMatrix() const { return m_ProjectionMatrix; }
const QMatrix4x4& projectionMatrixInverse() const { return m_ProjectionMatrixInverse; }
const QMatrix4x4& viewMatrix() const { return m_ViewMatrix; }
const QMatrix4x4& viewMatrixInverse() const { return m_ViewMatrixInverse; }
QMatrix4x4 modelMatrix( const DisplayableInterface *d ) const;
QMatrix4x4 modelMatrixInverse( const DisplayableInterface *d ) const;
const QMatrix4x4& viewProjectionMatrix() const { return m_ViewProjectionMatrix; }
const QMatrix4x4& viewProjectionMatrixInverse() const { return m_ViewProjectionMatrixInverse; }
inline QMatrix4x4 modelViewMatrix( const DisplayableInterface *d ) const { return viewMatrix() * modelMatrix(d); }
inline QMatrix4x4 modelViewMatrixInverse( const DisplayableInterface *d ) const { return modelViewMatrix(d).inverted(); }
inline QMatrix4x4 MVPMatrix( const DisplayableInterface *d ) const { return viewProjectionMatrix() * modelMatrix(d); }
inline QMatrix4x4 MVPMatrixInverse( const DisplayableInterface *d ) const { return MVPMatrix(d).inverted(); }
QMatrix4x4 viewportMatrix( bool flipY = false ) const;
inline QMatrix4x4 normalMatrix( const DisplayableInterface *d ) const { QMatrix4x4 m = modelViewMatrix(d); m(0,3) = m(1,3) = m(2,3) = 0.0f; return m; }
inline QMatrix4x4 modelViewProjectionMatrix( const DisplayableInterface *d ) const { return projectionMatrix() * modelViewMatrix(d); }
inline const QMatrix4x4& lightRotationMatrix() const { return m_LightRotationMatrix; }
inline QVector3D lightDirection() const { return m_LightRotationMatrix.column(2).toVector3D(); }
inline bool isLightingEnabled() const { return m_IsLightingEnabled; }
inline bool isWireframeEnabled() const { return m_IsWireframeEnabled; }
inline bool isCullingEnabled() const { return m_IsCullingEnabled; }
inline bool isLightTrackingEye() const { return m_IsLightTrackingEnabled; }
inline void clearAllFactories() { m_Factories.clear(); }
......@@ -224,7 +252,6 @@ public:
virtual void removeAllDisplayables();
inline bool isDisplayed( GenericUIData *m ) const { return m_Displayables.find(m) != m_Displayables.end(); }
inline bool isAbleToDisplay( GenericUIData *m ) const { return m_Factories.find(m->GetTypeString()) != m_Factories.end(); }
inline bool isCullingEnabled() const { return m_IsCullingEnabled; }
inline DisplayableFactoryInterface* getFactory( const QString &type ) { FactoryMap::iterator f=m_Factories.find(type); return f==m_Factories.end()? NULL : f->second; }
inline const DisplayableFactoryInterface* getFactory( const QString &type ) const { FactoryMap::const_iterator f=m_Factories.find(type); return f==m_Factories.end()? NULL : f->second; }
inline DisplayableInterface* getDisplayable( const GenericUIData* m ) { DisplayableMap::iterator d=m_Displayables.find(m); return d==m_Displayables.end()? NULL : d->second.displayable; }
......
......@@ -181,7 +181,7 @@ void SelectionManagerMeshTexels::onDisplay( GLViewer *viewer )
// Setup selection display shader uniforms.
m_DisplayShader.SetSamplerBinding( "u_Texture", &m_Texture );
m_DisplayShader.SetUniform( "camFullMatrix", (viewer->projectionMatrix() * viewer->viewMatrix()).data() );
m_DisplayShader.SetUniform( "camFullMatrix", viewer->viewProjectionMatrix().data() );
// Perform rendering passe.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment