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(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) {
|
||||
fovy = 90.0 / screen->getViewRatio();
|
||||
grMakeLookAtMat4(mat, eye, center, up);
|
||||
|
||||
#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 */)
|
||||
{
|
||||
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[2] = car->_bonnetPos_z;
|
||||
sgXformPnt3(P, car->_posMat);
|
||||
|
||||
|
||||
eye[0] = P[0];
|
||||
eye[1] = P[1];
|
||||
eye[2] = P[2];
|
||||
|
||||
p[0] = car->_bonnetPos_x - 30.0;
|
||||
p[1] = car->_bonnetPos_y;
|
||||
|
||||
float offset = 0;
|
||||
|
||||
// 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;
|
||||
sgXformPnt3(p, car->_posMat);
|
||||
|
||||
|
@ -523,6 +547,10 @@ void cGrCarCamMirror::update(tCarElt *car, tSituation * /* s */)
|
|||
up[0] = car->_posMat[2][0];
|
||||
up[1] = car->_posMat[2][1];
|
||||
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;
|
||||
vpw = w;
|
||||
vph = h;
|
||||
|
||||
if (viewCam) {
|
||||
delete viewCam;
|
||||
}
|
||||
viewCam = new cGrOrthoCamera(screen, x, x + w, y, y + h);
|
||||
limitFov();
|
||||
vp_aspectratio = double(vph)/vpw;
|
||||
}
|
||||
|
||||
|
||||
void cGrCarCamMirror::setPos (int x, int y, int w, int h)
|
||||
void cGrCarCamMirror::setScreenPos (int x, int y, int w, int h)
|
||||
{
|
||||
mx = x;
|
||||
my = y;
|
||||
mw = w;
|
||||
mh = h;
|
||||
|
||||
// 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;
|
||||
m_centery = my + mh/2;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
// Enable scissor test to conserve graphics memory bandwidth.
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(vpx + (vpw - mw)/2, vpy + (vph - mh)/2, mw, mh);
|
||||
glFrontFace( GL_CCW );
|
||||
}
|
||||
|
||||
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 ================================================================
|
||||
|
||||
class cGrCarCamInsideFixedCar : public cGrPerspCamera
|
||||
|
|
|
@ -247,34 +247,25 @@ class cGrCarCamMirror : public cGrPerspCamera
|
|||
{
|
||||
protected:
|
||||
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 */
|
||||
float tsu, tsv, teu, tev; /* texture coord */
|
||||
GLuint tex; /* texture */
|
||||
cGrOrthoCamera *viewCam;
|
||||
int m_centery; /* y-coordinate of the mirror's center point */
|
||||
|
||||
public:
|
||||
cGrCarCamMirror(cGrScreen *myscreen, int id, int drawCurr, int drawBG,
|
||||
float myfovy, float myfovymin, float myfovymax,
|
||||
float myfnear, float myffar = 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 ();
|
||||
float myfogstart = 1400.0, float myfogend = 1500.0);
|
||||
|
||||
void update (tCarElt *car, tSituation *s);
|
||||
void limitFov (void);
|
||||
|
||||
void setViewport (int x, int y, int w, int h);
|
||||
void setPos (int x, int y, int w, int h);
|
||||
void activateViewport (void);
|
||||
void store (void);
|
||||
void display (void);
|
||||
void setScreenPos (int x, int y, int w, int h);
|
||||
|
||||
virtual void setModelView(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) {
|
||||
// mirror width adjusted to fit board size
|
||||
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,
|
||||
(scrw * boardWidth /200), scrh / 6);
|
||||
}
|
||||
|
@ -349,15 +349,6 @@ void cGrScreen::update(tSituation *s, const cGrFrameInfo* frameInfo)
|
|||
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);
|
||||
glViewport(scrx, scry, scrw, scrh);
|
||||
glScissor(scrx, scry, scrw, scrh);
|
||||
|
@ -374,11 +365,11 @@ void cGrScreen::update(tSituation *s, const cGrFrameInfo* frameInfo)
|
|||
glDisable(GL_FOG);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
/* Mirror */
|
||||
if (mirrorFlag && curCam->isMirrorAllowed ()) {
|
||||
mirrorCam->display ();
|
||||
glViewport (scrx, scry, scrw, scrh);
|
||||
}
|
||||
/* Mirror */
|
||||
if (mirrorFlag && curCam->isMirrorAllowed ()) {
|
||||
dispCam = mirrorCam;
|
||||
camDraw (s);
|
||||
}
|
||||
|
||||
GfProfStartProfile("boardCam*");
|
||||
boardCam->action();
|
||||
|
|
Loading…
Reference in a new issue