void draw_s2warpstereo(CAMERA cam) { /* draw the left view directly; draw the right view to a texture * then onto the screen using a warp */ // 1. create the texture if required. if (!_s2w_textureready) { if (_s2w_warpstereo_txt >= 0) { ss2dt(_s2w_warpstereo_txt); } int tmp = mWINWIDTH - 1; _s2w_warpstereo_w = 1; while (tmp) { tmp >>= 1; _s2w_warpstereo_w <<= 1; } tmp = mWINHEIGHT - 1; _s2w_warpstereo_h = 1; while (tmp) { tmp >>= 1; _s2w_warpstereo_h <<= 1; } _s2w_warpstereo_txt = ss2ctt(_s2w_warpstereo_w, _s2w_warpstereo_h); } #define H_DIVISOR 2 // 2. draw the right and save a texture of it glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glViewport(0, 0, mWINWIDTH / H_DIVISOR, mWINHEIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); drawView("r", 0.5); DrawExtras(); glPushAttrib(GL_ENABLE_BIT); glEnable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glBindTexture(GL_TEXTURE_2D, _s2w_warpstereo_txt); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, mWINWIDTH / H_DIVISOR, mWINHEIGHT); glPopAttrib(); // 3. draw the left image glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glViewport(0, 0, mWINWIDTH / H_DIVISOR, mWINHEIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); drawView("l", -0.5); DrawExtras(); // Remember the graphics state and return it at the end glPushAttrib(GL_ALL_ATTRIB_BITS); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); // the key for when we are in wireframe mode! - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glColor3f(1.0,1.0,1.0); // interleave the rows in the back buffer! // Right glViewport(mWINWIDTH/H_DIVISOR, 0, mWINWIDTH/H_DIVISOR, mWINHEIGHT); glDrawBuffer(GL_BACK); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #if (1) // draw the texture we just captured... glColor4f(1., 1., 1., 1.); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, 1, 0, 1, 0, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glEnable(GL_TEXTURE_2D); //fprintf(stderr, "using texture id %d to draw...\n", _s2w_warpstereo_txt); glBindTexture(GL_TEXTURE_2D, _s2w_warpstereo_txt); if (!_s2w_warpingactive || !_s2w_meshfn) { // just one big quad filling the screen glBegin(GL_QUADS); glTexCoord2f(0., 0.); glVertex2f(0., 0.); glTexCoord2f(0., (float)mWINHEIGHT / (float)_s2w_warpstereo_h); glVertex2f(0., 1.); glTexCoord2f((float)mWINWIDTH / (float)_s2w_warpstereo_w / H_DIVISOR, (float)mWINHEIGHT / (float)_s2w_warpstereo_h); glVertex2f(1., 1.); glTexCoord2f((float)mWINWIDTH / (float)_s2w_warpstereo_w / H_DIVISOR, 0.); glVertex2f(1., 0.); glEnd(); } else { // (meshnx-1) * (meshny-1) quads across the screen glBegin(GL_QUADS); float max_tc_x = (float)mWINWIDTH / (float)H_DIVISOR / (float)_s2w_warpstereo_w; float max_tc_y = (float)mWINHEIGHT / (float)_s2w_warpstereo_h; float on2asp = 0.5; int ix, iy; for (ix = 0; ix < meshnx-1; ix++) { for (iy = 0; iy < meshny-1; iy++) { // four corners glTexCoord2f(mesh[ix][iy].x * max_tc_x, mesh[ix][iy].y * max_tc_y); glVertex2f(0.5 + on2asp * mesh[ix][iy].u, 0.5 + 0.5 * mesh[ix][iy].v); glTexCoord2f(mesh[ix][iy+1].x * max_tc_x, mesh[ix][iy+1].y * max_tc_y); glVertex2f(0.5 + on2asp * mesh[ix][iy+1].u, 0.5 + 0.5 * mesh[ix][iy+1].v); glTexCoord2f(mesh[ix+1][iy+1].x * max_tc_x, mesh[ix+1][iy+1].y * max_tc_y); glVertex2f(0.5 + on2asp * mesh[ix+1][iy+1].u, 0.5 + 0.5 * mesh[ix+1][iy+1].v); glTexCoord2f(mesh[ix+1][iy].x * max_tc_x, mesh[ix+1][iy].y * max_tc_y); glVertex2f(0.5 + on2asp * mesh[ix+1][iy].u, 0.5 + 0.5 * mesh[ix+1][iy].v); } } glEnd(); } glDisable(GL_TEXTURE_2D); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); #endif glPopAttrib(); // mark the texture as ready for use _s2w_textureready = 1; }
void draw_s2fishdome(CAMERA cam) { // draw a fisheye / warped projection of the geometry double r, near, far; XYZ vp, vd, vr, vl; XYZ vright, vleft, vup; // Calculate various view vectors vp = cam.vp; vd = cam.vd; vr = CrossProduct(vd,cam.vu); vl = CrossProduct(cam.vu,vd); vd = ArbitraryRotate(vd,cam.fishrotate,vr); vup = CrossProduct(vr,vd); vright = VectorAdd(vr,vd); vleft = VectorAdd(vl,vd); near = VectorLength(_s2priv_pmin(),_s2priv_pmax()) / 100; far = MAX(cam.focallength,VectorLength(_s2priv_pmin(), _s2priv_pmax())) * 20; // Left glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glViewport(0,0,TEXTURESIZE,TEXTURESIZE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); s2Perspective(90.0,1.0,near,far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); s2LookAt(vp.x,vp.y,vp.z,vp.x+vleft.x,vp.y+vleft.y,vp.z+vleft.z,vup.x,vup.y,vup.z); MakeLighting(); MakeMaterial(); MakeGeometry(FALSE, FALSE); glBindTexture(GL_TEXTURE_2D,walltextureid[2]); glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,TEXTURESIZE,TEXTURESIZE); // Right glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glViewport(0,0,TEXTURESIZE,TEXTURESIZE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); s2Perspective(90.0,1.0,near,far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); s2LookAt(vp.x,vp.y,vp.z,vp.x+vright.x,vp.y+vright.y,vp.z+vright.z,vup.x,vup.y,vup.z); MakeLighting(); MakeMaterial(); MakeGeometry(FALSE, FALSE); glBindTexture(GL_TEXTURE_2D,walltextureid[3]); glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,TEXTURESIZE,TEXTURESIZE); // Top glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glViewport(0,0,TEXTURESIZE,TEXTURESIZE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); s2Perspective(90.0,1.0,near,far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); s2LookAt(vp.x,vp.y,vp.z,vp.x+vup.x,vp.y+vup.y,vp.z+vup.z,-vright.x,-vright.y,-vright.z); MakeLighting(); MakeMaterial(); MakeGeometry(FALSE, FALSE); glBindTexture(GL_TEXTURE_2D,walltextureid[0]); glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,TEXTURESIZE,TEXTURESIZE); // Bottom glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glViewport(0,0,TEXTURESIZE,TEXTURESIZE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); s2Perspective(90.0,1.0,near,far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); s2LookAt(vp.x,vp.y,vp.z,vp.x-vup.x,vp.y-vup.y,vp.z-vup.z,-vleft.x,-vleft.y,-vleft.z); MakeLighting(); MakeMaterial(); MakeGeometry(FALSE, FALSE); glBindTexture(GL_TEXTURE_2D,walltextureid[1]); glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,TEXTURESIZE,TEXTURESIZE); // Remember the graphics state and return it at the end glPushAttrib(GL_ALL_ATTRIB_BITS); glDisable(GL_LIGHTING); glDisable(GL_ALPHA_TEST); glDisable(GL_COLOR_MATERIAL); glDisable(GL_DITHER); //glDisable(GL_FOG); glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_STIPPLE); glDisable(GL_SCISSOR_TEST); glDisable(GL_STENCIL_TEST); // Setup projections for the dome glDrawBuffer(GL_BACK); if (_s2fd_options->dometype == WARPMAP) glClearColor(0.0,0.0,0.0,0.0); else glClearColor(0.05,0.05,0.05,0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0,0,_s2fd_options->screenwidth,_s2fd_options->screenheight); r = _s2fd_options->screenwidth / (double)_s2fd_options->screenheight; switch (_s2fd_options->dometype) { case TRUNCTOP: case TRUNCBOTTOM: glOrtho(-r*0.75,r*0.75,-0.75,0.75,0.1,10.0); break; case HSPHERICAL: glOrtho(-r*0.75,r*0.75,-0.75,0.75,0.1,10.0); break; case VSPHERICAL: case WARPMAP: default: glOrtho(-r,r,-1.0,1.0,0.1,10.0); break; } // Create camera projection for dome glMatrixMode(GL_MODELVIEW); glLoadIdentity(); switch (_s2fd_options->dometype) { case TRUNCBOTTOM: s2LookAt(0.0,-1.0,0.25,0.0,0.0,0.25,0.0,0.0,1.0); break; case TRUNCTOP: s2LookAt(0.0,-1.0,-0.25,0.0,0.0,-0.25,0.0,0.0,1.0); break; case HSPHERICAL: case VSPHERICAL: case WARPMAP: default: s2LookAt(0.0,-1.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0); break; } // Finally draw the dome geometry glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glColor3f(1.0,1.0,1.0); DrawDome(TRUE,FALSE); _s2_fadeinout(); DrawExtras(); glPopAttrib(); }