Fix snapshot for othographic view

This commit is contained in:
Maxime Gimeno 2018-04-06 15:20:59 +02:00
parent 55c3048a69
commit 130e42569e
3 changed files with 88 additions and 32 deletions

View File

@ -398,7 +398,13 @@ public:
virtual void loadModelViewMatrix(bool reset = true) const;
void computeProjectionMatrix() const;
void computeModelViewMatrix() const;
void setFrustum(double l, double r, double t, double b, double n, double f);
//!Sets the frustum according to the current type of the camera
//! (PERSPECTIVE or ORTHOGRAPHIC) in this order :
//! left, right, top, bottom, near, far
void setFrustum(double frustum[6]);
//!Fills `frustum` from the current frustum of the camera according
//! to the current type (PERSPECTIVE or ORTHOGRAPHIC) in this order :
//! left, right, top, bottom, near, far
void getFrustum(double frustum[6]);
virtual void loadProjectionMatrixStereo(bool leftBuffer = true) const;

View File

@ -2490,19 +2490,36 @@ qreal Camera::physicalDistanceToScreen() const {
CGAL_INLINE_FUNCTION
void Camera::setFrustum(double l, double r, double t, double b, double n, double f)
void Camera::setFrustum(double frustum[6])
{
double A = 2*n/(r-l);
double B = (r+l)/(r-l);
double C = 2*n/(t-b);
double D = (t+b)/(t-b);
float E = -(f+n)/(f-n);
float F = -2*(f*n)/(f-n);
projectionMatrix_[0] = A; projectionMatrix_[4] = 0; projectionMatrix_[8] = B ; projectionMatrix_[12] = 0;
projectionMatrix_[1] = 0; projectionMatrix_[5] = C; projectionMatrix_[9] = D ; projectionMatrix_[13] = 0;
projectionMatrix_[2] = 0; projectionMatrix_[6] = 0; projectionMatrix_[10] = E ; projectionMatrix_[14] = F;
projectionMatrix_[3] =0; projectionMatrix_[7] =0; projectionMatrix_[11] =-1; projectionMatrix_[15] =0;
double l(frustum[0]),r(frustum[1]),t(frustum[2]),
b(frustum[3]),n(frustum[4]),f(frustum[5]);
if(type() == PERSPECTIVE)
{
double A = 2*n/(r-l);
double B = (r+l)/(r-l);
double C = 2*n/(t-b);
double D = (t+b)/(t-b);
float E = -(f+n)/(f-n);
float F = -2*(f*n)/(f-n);
projectionMatrix_[0] = A; projectionMatrix_[4] = 0; projectionMatrix_[8] = B ; projectionMatrix_[12] = 0;
projectionMatrix_[1] = 0; projectionMatrix_[5] = C; projectionMatrix_[9] = D ; projectionMatrix_[13] = 0;
projectionMatrix_[2] = 0; projectionMatrix_[6] = 0; projectionMatrix_[10] = E ; projectionMatrix_[14] = F;
projectionMatrix_[3] =0; projectionMatrix_[7] =0; projectionMatrix_[11] =-1; projectionMatrix_[15] =0;
}
else
{
double A = 2/(r-l);
double B = -(r+l)/(r-l);
double C = 2/(t-b);
double D = -(t+b)/(t-b);
float E = -(f+n)/(f-n);
float F = -2/(f-n);
projectionMatrix_[0] = A; projectionMatrix_[1] = 0; projectionMatrix_[2] = 0 ; projectionMatrix_[3] = 0;
projectionMatrix_[4] = 0; projectionMatrix_[5] = C; projectionMatrix_[6] = 0 ; projectionMatrix_[7] = 0;
projectionMatrix_[8] = 0; projectionMatrix_[9] = 0; projectionMatrix_[10] = F ; projectionMatrix_[11] = 0;
projectionMatrix_[12] = B; projectionMatrix_[13] = D; projectionMatrix_[14] = E; projectionMatrix_[15] = 1;
}
projectionMatrixIsUpToDate_ = true;
}
@ -2510,13 +2527,31 @@ CGAL_INLINE_FUNCTION
void Camera::getFrustum(double frustum[6])
{
double l,r,t,b,n,f;
if(type() == PERSPECTIVE)
{
n = projectionMatrix_[14]/2*((projectionMatrix_[10]+1)/(projectionMatrix_[10]-1)-1);
f = n*(projectionMatrix_[10]-1)/(projectionMatrix_[10]+1);
l = ((2*n/projectionMatrix_[0])*(projectionMatrix_[8]-1)/(projectionMatrix_[8]+1))/(1-(projectionMatrix_[8]-1)/(projectionMatrix_[8]+1));
r = 2*n/projectionMatrix_[0]+l;
b=(-2*n/projectionMatrix_[5]*(1-projectionMatrix_[9])/(1+projectionMatrix_[9]))/(1+(1-projectionMatrix_[9])/(1+projectionMatrix_[9]));
t = 2*n/projectionMatrix_[5]+b;
}
else
{
double A(projectionMatrix_[0]),B(projectionMatrix_[12]),
C(projectionMatrix_[5]),D(projectionMatrix_[13]),
E(projectionMatrix_[14]),F(projectionMatrix_[10]);
double B1 = (B+1)/(1-B), D1 = (1-D)/(D+1),
E1=(E+1)/(1-E);
l = -2*B1/(1+B1*A);
r = 2+A*l;
t = 2*D1/(C*(1+D1));
b =t -2/C;
n = -2/(F*(1+E1));
f=n-2/F;
}
frustum[0] = l;
frustum[1] = r;
frustum[2] = t;

View File

@ -4367,17 +4367,35 @@ QImage* QGLViewer::takeSnapshot( qglviewer::SnapShotBackground background_color
qreal xMin, yMin;
if ((expand && (newAspectRatio>aspectRatio)) || (!expand && (newAspectRatio<aspectRatio)))
if(camera()->type()==qglviewer::Camera::PERSPECTIVE)
{
yMin = zNear * tan(camera()->fieldOfView() / 2.0);
xMin = newAspectRatio * yMin;
if ((expand && (newAspectRatio>aspectRatio)) || (!expand && (newAspectRatio<aspectRatio)))
{
yMin = zNear * tan(camera()->fieldOfView() / 2.0);
xMin = newAspectRatio * yMin;
}
else
{
xMin = zNear * tan(camera()->fieldOfView() / 2.0) * aspectRatio;
yMin = xMin / newAspectRatio;
}
}
else
{
xMin = zNear * tan(camera()->fieldOfView() / 2.0) * aspectRatio;
yMin = xMin / newAspectRatio;
double xy[6];
camera()->getFrustum(xy);
if ((expand && (newAspectRatio>aspectRatio)) || (!expand && (newAspectRatio<aspectRatio)))
{
yMin = -xy[3];
xMin = newAspectRatio * yMin;
;
}
else
{
xMin = -xy[0] * aspectRatio;
yMin = xMin / newAspectRatio;
}
}
QImage *image = new QImage(finalSize.width(), finalSize.height(), QImage::Format_ARGB32);
if (image->isNull())
@ -4411,12 +4429,14 @@ QImage* QGLViewer::takeSnapshot( qglviewer::SnapShotBackground background_color
{
fbo.bind();
glClearColor(backgroundColor().redF(), backgroundColor().greenF(), backgroundColor().blueF(), alpha);
camera()->setFrustum(-xMin + i*deltaX,
-xMin + (i+1)*deltaX,
yMin - j*deltaY,
yMin - (j+1)*deltaY,
zNear,
zFar);
double frustum[6];
frustum[0]= -xMin + i*deltaX;
frustum[1]= -xMin + (i+1)*deltaX ;
frustum[2]= yMin - j*deltaY;
frustum[3]= yMin - (j+1)*deltaY;
frustum[4]= zNear;
frustum[5]= zFar;
camera()->setFrustum(frustum);
preDraw();
draw();
fbo.release();
@ -4440,12 +4460,7 @@ QImage* QGLViewer::takeSnapshot( qglviewer::SnapShotBackground background_color
}
if(background_color !=0)
setBackgroundColor(previousBGColor);
camera()->setFrustum(frustum[0],
frustum[1],
frustum[2],
frustum[3],
frustum[4],
frustum[5]);
camera()->setFrustum(frustum);
return image;
}