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; return dx * dx + dy * dy;
} }
float
cGrCamera::getAspectRatio()
{
return screen->getViewRatio();
}
static void static void
grMakeLookAtMat4 ( sgMat4 dst, const sgVec3 eye, const sgVec3 center, const sgVec3 up ) 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, // tan and atan functions operate on angles in radians. Also,
// we're only interested in half the viewing angle. // 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.setFOV(fovx, fovy);
grContext.setNearFar(fnear, ffar); grContext.setNearFar(fnear, ffar);
} }
@ -493,6 +498,7 @@ cGrCarCamMirror::cGrCarCamMirror(cGrScreen *myscreen, int id, int drawCurr, int
: cGrPerspCamera(myscreen, id, drawCurr, 1, drawBG, 1, : cGrPerspCamera(myscreen, id, drawCurr, 1, drawBG, 1,
myfovy, myfovymin, myfovymax, myfovy, myfovymin, myfovymax,
myfnear, myffar, myfogstart, myfogend) myfnear, myffar, myfogstart, myfogend)
, origFovY(myfovy)
{ {
} }
@ -550,7 +556,6 @@ void cGrCarCamMirror::adaptScreenSize()
vpy = screen->getScrY(); vpy = screen->getScrY();
vpw = screen->getScrW(); vpw = screen->getScrW();
vph = screen->getScrH(); vph = screen->getScrH();
vp_aspectratio = double(vph)/vpw;
// mirror width adjusted to fit board size // mirror width adjusted to fit board size
int boardW = screen->getBoardWidth(); int boardW = screen->getBoardWidth();
@ -559,35 +564,23 @@ void cGrCarCamMirror::adaptScreenSize()
my = vpy + 5 * vph / 6 - vph / 10; my = vpy + 5 * vph / 6 - vph / 10;
mw = vpw * boardW /200; mw = vpw * boardW /200;
mh = vph / 6; mh = vph / 6;
m_centery = my + mh/2;
aspectRatio = float(mw) / mh;
limitFov();
} }
void cGrCarCamMirror::beforeDraw (void) void cGrCarCamMirror::beforeDraw (void)
{ {
glFrontFace( GL_CW ); glFrontFace( GL_CW );
/* The aspect ratio of the mirror is probably not the same // Scissor needed with Nouveau driver
* 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);
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glScissor(mx, my, mw, mh); 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) void cGrCarCamMirror::afterDraw (void)
@ -599,6 +592,11 @@ void cGrCarCamMirror::afterDraw (void)
glFrontFace( GL_CCW ); glFrontFace( GL_CCW );
} }
void cGrCarCamMirror::limitFov(void)
{
fovy = origFovY / getAspectRatio();
}
// cGrCarCamInsideFixedCar ================================================================ // cGrCarCamInsideFixedCar ================================================================
class cGrCarCamInsideFixedCar : public cGrPerspCamera 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 */ 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 */ /* Set the camera view */
void action(void) { void action(void) {
setProjection(); setProjection();
@ -167,11 +175,11 @@ class cGrPerspCamera : public cGrCamera
float myfnear, float myffar = 1500.0, float myfogstart = 1400.0, float myfogend = 1500.0); 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 */ virtual void update(tCarElt *car, tSituation *s) = 0; /* Change the camera if necessary */
void setProjection(void); virtual void setProjection(void);
void setModelView(void); virtual void setModelView(void);
void loadDefaults(char *attr); virtual void loadDefaults(char *attr);
void setViewOffset(float newOffset); void setViewOffset(float newOffset);
void setZoom(int cmd); virtual void setZoom(int cmd);
float getLODFactor(float x, float y, float z); float getLODFactor(float x, float y, float z);
float getFogStart(void) { return fogstart; } float getFogStart(void) { return fogstart; }
float getFogEnd(void) { return fogend; } float getFogEnd(void) { return fogend; }
@ -187,7 +195,7 @@ class cGrPerspCamera : public cGrCamera
return (cGrPerspCamera *)cGrCamera::next(); return (cGrPerspCamera *)cGrCamera::next();
} }
void limitFov(void) {} virtual void limitFov(void) {}
void onSelect(tCarElt *car, tSituation *s) {} void onSelect(tCarElt *car, tSituation *s) {}
virtual float getFovY(void) { virtual float getFovY(void) {
@ -221,7 +229,7 @@ class cGrOrthoCamera : public cGrCamera
void update(tCarElt *car, tSituation *s) { } void update(tCarElt *car, tSituation *s) { }
float getLODFactor(float x, float y, float z) { return 1; } float getLODFactor(float x, float y, float z) { return 1; }
void loadDefaults(char *attr) { } void loadDefaults(char *attr) { }
void setZoom(int cmd) { } virtual void setZoom(int cmd) { }
void onSelect(tCarElt *car, tSituation *s) {} void onSelect(tCarElt *car, tSituation *s) {}
}; };
@ -247,9 +255,9 @@ class cGrCarCamMirror : public cGrPerspCamera
{ {
protected: protected:
int vpx, vpy, vpw, vph; /* viewport size */ int vpx, vpy, vpw, vph; /* viewport size */
double vp_aspectratio; /* viewport aspect ratio: vph/vpw */
int mx, my, mw, mh; /* drawing area */ 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: public:
cGrCarCamMirror(cGrScreen *myscreen, int id, int drawCurr, int drawBG, cGrCarCamMirror(cGrScreen *myscreen, int id, int drawCurr, int drawBG,
@ -259,6 +267,8 @@ class cGrCarCamMirror : public cGrPerspCamera
void update (tCarElt *car, tSituation *s); void update (tCarElt *car, tSituation *s);
virtual float getAspectRatio() { return aspectRatio; }
void setViewport (int x, int y, int w, int h); void setViewport (int x, int y, int w, int h);
void setScreenPos (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 beforeDraw(void);
virtual void afterDraw(void); virtual void afterDraw(void);
/** Called by cGrScreen::activate() after the screen updated it's screen size. /** Called by cGrScreen::activate() after the screen updated it's screen size.
* Cameras should use the cGrCamera::screen property to get the updated information. */ * Cameras should use the cGrCamera::screen property to get the updated information. */
void adaptScreenSize(); void adaptScreenSize();
virtual void limitFov(void);
}; };