Re #589: refactored mirror (Boris)
The mirror is now rendered through an own viewport instead of to texture. o replaced with code from cGrCarCamBehindReverse o adapted new code to mirror viewport instead of fullscreen rendering o renamed cGrCarCamMirror::setPos() to setScreenPos() o put new functions before/afterDraw() to use to initialize mirror specialities o cGrScreen::update(): removed unnecessary code o cGrScreen::update(): moved mirror rendering after rendering of scene git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@4962 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: 00f6f93c0de7f74fdab77d37af2ea35b0cfc2e04 Former-commit-id: a0ff2de1efeb2cb061bb9bfc6dd0cd03805e399c
This commit is contained in:
parent
96f1fb2f69
commit
5360d04406
3 changed files with 89 additions and 113 deletions
|
@ -486,33 +486,57 @@ class cGrCarCamInsideDynDriverEye : public cGrCarCamInsideDriverEye
|
||||||
|
|
||||||
// cGrCarCamMirror ================================================================
|
// cGrCarCamMirror ================================================================
|
||||||
|
|
||||||
cGrCarCamMirror::~cGrCarCamMirror ()
|
cGrCarCamMirror::cGrCarCamMirror(cGrScreen *myscreen, int id, int drawCurr, int drawBG,
|
||||||
|
float myfovy, float myfovymin, float myfovymax,
|
||||||
|
float myfnear, float myffar,
|
||||||
|
float myfogstart, float myfogend)
|
||||||
|
: cGrPerspCamera(myscreen, id, drawCurr, 1, drawBG, 1,
|
||||||
|
myfovy, myfovymin, myfovymax,
|
||||||
|
myfnear, myffar, myfogstart, myfogend)
|
||||||
{
|
{
|
||||||
glDeleteTextures (1, &tex);
|
|
||||||
delete viewCam;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cGrCarCamMirror::setModelView(void)
|
||||||
|
{
|
||||||
|
sgMat4 mat, mat2, mirror;
|
||||||
|
|
||||||
void cGrCarCamMirror::limitFov(void) {
|
grMakeLookAtMat4(mat, eye, center, up);
|
||||||
fovy = 90.0 / screen->getViewRatio();
|
|
||||||
|
#define M(row,col) mirror[row][col]
|
||||||
|
M(0,0) = 1.0; M(0,1) = 0.0; M(0,2) = 0.0; M(0,3) = 0.0;
|
||||||
|
M(1,0) = 0.0; M(1,1) =-1.0; M(1,2) = 0.0; M(1,3) = 0.0;
|
||||||
|
M(2,0) = 0.0; M(2,1) = 0.0; M(2,2) = 1.0; M(2,3) = 0.0;
|
||||||
|
M(3,0) = 0.0; M(3,1) = 0.0; M(3,2) = 0.0; M(3,3) = 1.0;
|
||||||
|
#undef M
|
||||||
|
sgMultMat4(mat2, mat, mirror);
|
||||||
|
|
||||||
|
grContext.setCamera(mat2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cGrCarCamMirror::update(tCarElt *car, tSituation * /* s */)
|
void cGrCarCamMirror::update(tCarElt *car, tSituation * /* s */)
|
||||||
{
|
{
|
||||||
sgVec3 P, p;
|
sgVec3 P, p;
|
||||||
|
|
||||||
P[0] = car->_bonnetPos_x;
|
P[0] = car->_bonnetPos_x - (car->_dimension_x/2); // behind car
|
||||||
P[1] = car->_bonnetPos_y;
|
P[1] = car->_bonnetPos_y;
|
||||||
P[2] = car->_bonnetPos_z;
|
P[2] = car->_bonnetPos_z;
|
||||||
sgXformPnt3(P, car->_posMat);
|
sgXformPnt3(P, car->_posMat);
|
||||||
|
|
||||||
eye[0] = P[0];
|
eye[0] = P[0];
|
||||||
eye[1] = P[1];
|
eye[1] = P[1];
|
||||||
eye[2] = P[2];
|
eye[2] = P[2];
|
||||||
|
|
||||||
p[0] = car->_bonnetPos_x - 30.0;
|
float offset = 0;
|
||||||
p[1] = car->_bonnetPos_y;
|
|
||||||
|
// Compute offset angle and bezel compensation)
|
||||||
|
if (spansplit && viewOffset) {
|
||||||
|
offset += (viewOffset - 10 + (int((viewOffset - 10) * 2) * (bezelcomp - 100)/200)) *
|
||||||
|
atan(screen->getViewRatio() / spanaspect * tan(spanfovy * M_PI / 360.0)) * 2;
|
||||||
|
fovy = spanfovy;
|
||||||
|
}
|
||||||
|
|
||||||
|
p[0] = car->_bonnetPos_x + 30.0 * cos(offset);
|
||||||
|
p[1] = car->_bonnetPos_y + 30.0 * sin(offset);
|
||||||
p[2] = car->_bonnetPos_z;
|
p[2] = car->_bonnetPos_z;
|
||||||
sgXformPnt3(p, car->_posMat);
|
sgXformPnt3(p, car->_posMat);
|
||||||
|
|
||||||
|
@ -523,6 +547,10 @@ void cGrCarCamMirror::update(tCarElt *car, tSituation * /* s */)
|
||||||
up[0] = car->_posMat[2][0];
|
up[0] = car->_posMat[2][0];
|
||||||
up[1] = car->_posMat[2][1];
|
up[1] = car->_posMat[2][1];
|
||||||
up[2] = car->_posMat[2][2];
|
up[2] = car->_posMat[2][2];
|
||||||
|
|
||||||
|
speed[0] =car->pub.DynGCg.vel.x;
|
||||||
|
speed[1] =car->pub.DynGCg.vel.y;
|
||||||
|
speed[2] =car->pub.DynGCg.vel.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -532,91 +560,57 @@ void cGrCarCamMirror::setViewport(int x, int y, int w, int h)
|
||||||
vpy = y;
|
vpy = y;
|
||||||
vpw = w;
|
vpw = w;
|
||||||
vph = h;
|
vph = h;
|
||||||
|
vp_aspectratio = double(vph)/vpw;
|
||||||
if (viewCam) {
|
|
||||||
delete viewCam;
|
|
||||||
}
|
|
||||||
viewCam = new cGrOrthoCamera(screen, x, x + w, y, y + h);
|
|
||||||
limitFov();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cGrCarCamMirror::setPos (int x, int y, int w, int h)
|
void cGrCarCamMirror::setScreenPos (int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
mx = x;
|
mx = x;
|
||||||
my = y;
|
my = y;
|
||||||
mw = w;
|
mw = w;
|
||||||
mh = h;
|
mh = h;
|
||||||
|
m_centery = my + mh/2;
|
||||||
// round up texture size to next power of two
|
|
||||||
tw = GfNearestPow2(w);
|
|
||||||
th = GfNearestPow2(h);
|
|
||||||
if (tw < w) {
|
|
||||||
tw *= 2;
|
|
||||||
}
|
|
||||||
if (th < h) {
|
|
||||||
th *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create texture object.
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glReadBuffer(GL_BACK);
|
|
||||||
|
|
||||||
glCopyTexImage2D(GL_TEXTURE_2D,
|
|
||||||
0, // map level,
|
|
||||||
GL_RGB, // internal format,
|
|
||||||
0, 0, tw, th,
|
|
||||||
0 ); // border
|
|
||||||
|
|
||||||
tsu = (float) mw / tw;
|
|
||||||
teu = 0.0;
|
|
||||||
tsv = 0.0;
|
|
||||||
tev = (float) mh / th;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cGrCarCamMirror::activateViewport (void)
|
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);
|
||||||
|
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glScissor(mx, my, mw, mh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cGrCarCamMirror::afterDraw (void)
|
||||||
|
{
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
glViewport(vpx, vpy, vpw, vph);
|
glViewport(vpx, vpy, vpw, vph);
|
||||||
|
|
||||||
// Enable scissor test to conserve graphics memory bandwidth.
|
glFrontFace( GL_CCW );
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
glScissor(vpx + (vpw - mw)/2, vpy + (vph - mh)/2, mw, mh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cGrCarCamMirror::store (void)
|
|
||||||
{
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
|
||||||
glReadBuffer(GL_BACK);
|
|
||||||
|
|
||||||
// NVidia recommends to NOT use glCopyTexImage2D for performance reasons.
|
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
|
|
||||||
vpx + (vpw - mw)/2,
|
|
||||||
vpy + (vph - mh)/2, mw, mh);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void cGrCarCamMirror::display (void)
|
|
||||||
{
|
|
||||||
viewCam->action ();
|
|
||||||
|
|
||||||
glBindTexture (GL_TEXTURE_2D, tex);
|
|
||||||
glBegin(GL_TRIANGLE_STRIP);
|
|
||||||
{
|
|
||||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
|
||||||
glTexCoord2f(tsu, tsv); glVertex2f(mx, my);
|
|
||||||
glTexCoord2f(tsu, tev); glVertex2f(mx, my + mh);
|
|
||||||
glTexCoord2f(teu, tsv); glVertex2f(mx + mw, my);
|
|
||||||
glTexCoord2f(teu, tev); glVertex2f(mx + mw, my + mh);
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// cGrCarCamInsideFixedCar ================================================================
|
// cGrCarCamInsideFixedCar ================================================================
|
||||||
|
|
||||||
class cGrCarCamInsideFixedCar : public cGrPerspCamera
|
class cGrCarCamInsideFixedCar : public cGrPerspCamera
|
||||||
|
|
|
@ -247,34 +247,25 @@ class cGrCarCamMirror : public cGrPerspCamera
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
int vpx, vpy, vpw, vph; /* viewport size */
|
int vpx, vpy, vpw, vph; /* viewport size */
|
||||||
int tw, th; /* texture size */
|
double vp_aspectratio; /* viewport aspect ratio: vph/vpw */
|
||||||
int mx, my, mw, mh; /* drawing area */
|
int mx, my, mw, mh; /* drawing area */
|
||||||
float tsu, tsv, teu, tev; /* texture coord */
|
int m_centery; /* y-coordinate of the mirror's center point */
|
||||||
GLuint tex; /* texture */
|
|
||||||
cGrOrthoCamera *viewCam;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cGrCarCamMirror(cGrScreen *myscreen, int id, int drawCurr, int drawBG,
|
cGrCarCamMirror(cGrScreen *myscreen, int id, int drawCurr, int drawBG,
|
||||||
float myfovy, float myfovymin, float myfovymax,
|
float myfovy, float myfovymin, float myfovymax,
|
||||||
float myfnear, float myffar = 1500.0,
|
float myfnear, float myffar = 1500.0,
|
||||||
float myfogstart = 1400.0, float myfogend = 1500.0)
|
float myfogstart = 1400.0, float myfogend = 1500.0);
|
||||||
: cGrPerspCamera(myscreen, id, drawCurr, 1, drawBG, 1,
|
|
||||||
myfovy, myfovymin, myfovymax,
|
|
||||||
myfnear, myffar, myfogstart, myfogend) {
|
|
||||||
glGenTextures (1, &tex);
|
|
||||||
limitFov();
|
|
||||||
viewCam = NULL;
|
|
||||||
}
|
|
||||||
virtual ~cGrCarCamMirror ();
|
|
||||||
|
|
||||||
void update (tCarElt *car, tSituation *s);
|
void update (tCarElt *car, tSituation *s);
|
||||||
void limitFov (void);
|
|
||||||
|
|
||||||
void setViewport (int x, int y, int w, int h);
|
void setViewport (int x, int y, int w, int h);
|
||||||
void setPos (int x, int y, int w, int h);
|
void setScreenPos (int x, int y, int w, int h);
|
||||||
void activateViewport (void);
|
|
||||||
void store (void);
|
virtual void setModelView(void);
|
||||||
void display (void);
|
|
||||||
|
virtual void beforeDraw(void);
|
||||||
|
virtual void afterDraw(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ void cGrScreen::activate(int x, int y, int w, int h, float v)
|
||||||
if (mirrorCam) {
|
if (mirrorCam) {
|
||||||
// mirror width adjusted to fit board size
|
// mirror width adjusted to fit board size
|
||||||
mirrorCam->setViewport (scrx, scry, scrw, scrh);
|
mirrorCam->setViewport (scrx, scry, scrw, scrh);
|
||||||
mirrorCam->setPos (scrx + scrw / 2 - (scrw * boardWidth /400),
|
mirrorCam->setScreenPos (scrx + scrw / 2 - (scrw * boardWidth /400),
|
||||||
scry + 5 * scrh / 6 - scrh / 10,
|
scry + 5 * scrh / 6 - scrh / 10,
|
||||||
(scrw * boardWidth /200), scrh / 6);
|
(scrw * boardWidth /200), scrh / 6);
|
||||||
}
|
}
|
||||||
|
@ -349,15 +349,6 @@ void cGrScreen::update(tSituation *s, const cGrFrameInfo* frameInfo)
|
||||||
curCam->onSelect(curCar, s);
|
curCam->onSelect(curCar, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mirror */
|
|
||||||
if (mirrorFlag && curCam->isMirrorAllowed ()) {
|
|
||||||
mirrorCam->activateViewport ();
|
|
||||||
dispCam = mirrorCam;
|
|
||||||
glClear (GL_DEPTH_BUFFER_BIT);
|
|
||||||
camDraw (s);
|
|
||||||
mirrorCam->store ();
|
|
||||||
}
|
|
||||||
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glViewport(scrx, scry, scrw, scrh);
|
glViewport(scrx, scry, scrw, scrh);
|
||||||
glScissor(scrx, scry, scrw, scrh);
|
glScissor(scrx, scry, scrw, scrh);
|
||||||
|
@ -374,11 +365,11 @@ void cGrScreen::update(tSituation *s, const cGrFrameInfo* frameInfo)
|
||||||
glDisable(GL_FOG);
|
glDisable(GL_FOG);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
/* Mirror */
|
/* Mirror */
|
||||||
if (mirrorFlag && curCam->isMirrorAllowed ()) {
|
if (mirrorFlag && curCam->isMirrorAllowed ()) {
|
||||||
mirrorCam->display ();
|
dispCam = mirrorCam;
|
||||||
glViewport (scrx, scry, scrw, scrh);
|
camDraw (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
GfProfStartProfile("boardCam*");
|
GfProfStartProfile("boardCam*");
|
||||||
boardCam->action();
|
boardCam->action();
|
||||||
|
|
Loading…
Reference in a new issue