Bug #589 uykusuz's improvements

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@4990 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: 1312882a481d7b6f83629e2a54651200be044823
Former-commit-id: 2da1347370384904b0db1312c21af9194179a2da
This commit is contained in:
mungewell 2012-10-09 20:40:49 +00:00
parent 1b1bb1a9a2
commit 512c1dd5b6
2 changed files with 42 additions and 31 deletions

View file

@ -48,6 +48,11 @@ cGrCamera::getDist2 (tCarElt *car)
return dx * dx + dy * dy;
}
float
cGrCamera::getAspectRatio()
{
return screen->getViewRatio();
}
static void
grMakeLookAtMat4 ( sgMat4 dst, const sgVec3 eye, const sgVec3 center, const sgVec3 up )
@ -116,7 +121,7 @@ void cGrPerspCamera::setProjection(void)
// tan and atan functions operate on angles in radians. Also,
// we're only interested in half the viewing angle.
float fovx = atan(screen->getViewRatio() / spanaspect * tan(fovy * M_PI / 360.0)) * 360.0 / M_PI;
float fovx = atan(getAspectRatio() / spanaspect * tan(fovy * M_PI / 360.0)) * 360.0 / M_PI;
grContext.setFOV(fovx, fovy);
grContext.setNearFar(fnear, ffar);
}
@ -493,6 +498,7 @@ cGrCarCamMirror::cGrCarCamMirror(cGrScreen *myscreen, int id, int drawCurr, int
: cGrPerspCamera(myscreen, id, drawCurr, 1, drawBG, 1,
myfovy, myfovymin, myfovymax,
myfnear, myffar, myfogstart, myfogend)
, origFovY(myfovy)
{
}
@ -550,7 +556,6 @@ void cGrCarCamMirror::adaptScreenSize()
vpy = screen->getScrY();
vpw = screen->getScrW();
vph = screen->getScrH();
vp_aspectratio = double(vph)/vpw;
// mirror width adjusted to fit board size
int boardW = screen->getBoardWidth();
@ -559,35 +564,23 @@ void cGrCarCamMirror::adaptScreenSize()
my = vpy + 5 * vph / 6 - vph / 10;
mw = vpw * boardW /200;
mh = vph / 6;
m_centery = my + mh/2;
aspectRatio = float(mw) / mh;
limitFov();
}
void cGrCarCamMirror::beforeDraw (void)
{
glFrontFace( GL_CW );
/* The aspect ratio of the mirror is probably not the same
* as the real aspect ratio. Thus we do the following:
* 1) set up the mirror viewport with the same aspect ratio
* as the real scene
* 2) scissor the area of the actual mirror
*
* The viewport in 1) will be the same as the actual mirror,
* but with the height adjusted to fit the real aspect ratio.
* For that the mirror's height is calculated by multiplying
* the mirror's width with the real aspect ratio.
* To get the lower-left corner of the mirror's viewport half
* of that new height is subtracted from the mirror center's
* y-coordinate.
*/
double mvph = mw * vp_aspectratio;
int mvpy = m_centery - (mvph/2);
glViewport(mx, mvpy, mw, mvph);
// Scissor needed with Nouveau driver
glEnable(GL_SCISSOR_TEST);
glScissor(mx, my, mw, mh);
glViewport(mx, my, mw, mh);
// make mirror in front of everything by forcing overdrawing of everything
glClear(GL_DEPTH_BUFFER_BIT);
}
void cGrCarCamMirror::afterDraw (void)
@ -599,6 +592,11 @@ void cGrCarCamMirror::afterDraw (void)
glFrontFace( GL_CCW );
}
void cGrCarCamMirror::limitFov(void)
{
fovy = origFovY / getAspectRatio();
}
// cGrCarCamInsideFixedCar ================================================================
class cGrCarCamInsideFixedCar : public cGrPerspCamera

View file

@ -77,6 +77,14 @@ class cGrCamera
virtual float getLODFactor(float x, float y, float z) = 0; /* Get the LOD factor for an object located at x,y,z */
/** Retrieve the aspect ratio of this camera. This is used in
* cGrPerspCamera::setProjection() to calculate the fov.
* Usually this is simply the screen's aspect ratio. But for example the mirror's cam
* has another aspect ratio, which needs to be taken into account when setting up the
* view.
*/
virtual float getAspectRatio();
/* Set the camera view */
void action(void) {
setProjection();
@ -167,11 +175,11 @@ class cGrPerspCamera : public cGrCamera
float myfnear, float myffar = 1500.0, float myfogstart = 1400.0, float myfogend = 1500.0);
virtual void update(tCarElt *car, tSituation *s) = 0; /* Change the camera if necessary */
void setProjection(void);
void setModelView(void);
void loadDefaults(char *attr);
virtual void setProjection(void);
virtual void setModelView(void);
virtual void loadDefaults(char *attr);
void setViewOffset(float newOffset);
void setZoom(int cmd);
virtual void setZoom(int cmd);
float getLODFactor(float x, float y, float z);
float getFogStart(void) { return fogstart; }
float getFogEnd(void) { return fogend; }
@ -187,7 +195,7 @@ class cGrPerspCamera : public cGrCamera
return (cGrPerspCamera *)cGrCamera::next();
}
void limitFov(void) {}
virtual void limitFov(void) {}
void onSelect(tCarElt *car, tSituation *s) {}
virtual float getFovY(void) {
@ -221,7 +229,7 @@ class cGrOrthoCamera : public cGrCamera
void update(tCarElt *car, tSituation *s) { }
float getLODFactor(float x, float y, float z) { return 1; }
void loadDefaults(char *attr) { }
void setZoom(int cmd) { }
virtual void setZoom(int cmd) { }
void onSelect(tCarElt *car, tSituation *s) {}
};
@ -247,9 +255,9 @@ class cGrCarCamMirror : public cGrPerspCamera
{
protected:
int vpx, vpy, vpw, vph; /* viewport size */
double vp_aspectratio; /* viewport aspect ratio: vph/vpw */
int mx, my, mw, mh; /* drawing area */
int m_centery; /* y-coordinate of the mirror's center point */
float aspectRatio; /* the aspect ratio of the mirror: mw / mh */
float origFovY; /* fovy set using constructor */
public:
cGrCarCamMirror(cGrScreen *myscreen, int id, int drawCurr, int drawBG,
@ -259,6 +267,8 @@ class cGrCarCamMirror : public cGrPerspCamera
void update (tCarElt *car, tSituation *s);
virtual float getAspectRatio() { return aspectRatio; }
void setViewport (int x, int y, int w, int h);
void setScreenPos (int x, int y, int w, int h);
@ -267,9 +277,12 @@ class cGrCarCamMirror : public cGrPerspCamera
virtual void beforeDraw(void);
virtual void afterDraw(void);
/** Called by cGrScreen::activate() after the screen updated it's screen size.
* Cameras should use the cGrCamera::screen property to get the updated information. */
void adaptScreenSize();
virtual void limitFov(void);
};