/* NIGHTFALL OpenGL Interface */ /* Copyright (C) 2001 Rainer Wichmann & Markus Kuster */ /* */ /* This program is free software; you can redistribute it */ /* and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ANSI C forbids an empty source file, so put this outside */ /* do nothing here if we don't have OpenGL */ #include #include #include #include #include "Light.h" #ifdef _WITH_OPENGL #include "LightGLPrefs.h" double RtoL2,RtoL3; /****************************************************************** @package nightfall @author Markus Kuster (kuster@astro.uni-tuebingen.de) @version 1.2 @short Make a vertex list for the roche lobes using eclipse test information @param (int) comp the binary component (primary/secondary) @return (void) @heading Open GL Animation *******************************************************************/ void GLMakeVolumeEclipsed( int Comp ) { register int i,j; float com; /* center of mass */ #ifdef HAVE_DISK long n_rings,n_ringsi,n_ringso; #endif long n_phi; /* # of steps in phi */ long n_eta; /* # of steps in eta */ double RX,C2,C; GLdouble s, t, ds, dt; /* t corresponds to eta and s to phi */ SurfaceElement *FirstVertPtr=NULL, *FirstVertPtr2=NULL; SurfaceElement *SurfPtr,*NextRingPtr; /* pointer to surface */ BinaryComponent *BinPtr; /* pointer to binary */ /* pointer to first surface element */ SurfPtr = Surface[Comp]; /* the x coordinate of the center of mass */ com = (((float)(Binary[Primary].Mq))/( 1.0 + (float)(Binary[Primary].Mq))); /* pointer to first surface element in the next ring */ NextRingPtr = Surface[Comp]; /* pointer to the binary parameters */ BinPtr = &Binary[Comp]; n_eta = StepsPerPi; /* number of steps in eta */ if (Flags.asynchron2 == ON) { F = BinPtr->Fratio; } else { F = 1.0; } /* find root of (potential(x) - surfacePotential) */ /* if ( Comp == Primary ) {*/ /* lambda, nu global; potential on x-axis */ /* RochePot = Binary[Primary].RochePot; */ /* Mq = Binary[Primary].Mq; */ /* lambda = 1.0; nu = 0.0; */ /* RtoL3 = RootFind(RocheSurface, BinPtr->RLag3, 0.001, 1.0e-8, */ /* "GLMakeVolume", &error); */ /* printf("Radius to L3 %f\n",RtoL2); */ /* printf("Position L3 %f\n",BinPtr->RLag3); */ /* } else if ( Comp == Secondary ) { */ /* lambda, nu global; potential on x-axis */ /* lambda = 1.0; */ /* nu = 0.0; */ /* RtoL2 = RootFind(RocheSurface, 0.0001, BinPtr->RLag2, 1.0e-8, */ /* "GLMakeVolume", &error); */ /* printf("Radius to L2 %f\n",RtoL2); */ /* printf("Position L2 %f\n",BinPtr->RLag2); */ /* } */ /* if (error == 1) { */ /* printf("Root finding failed"); */ /* exit(0); */ /* } */ #ifdef HAVE_DISK if ( Comp != Disk ) { #endif /* use a fixed n_phi in animation mode (see DivideSurface) */ n_phi = BinPtr->N_PhiStep[0]; /* increment for texture coordinates */ ds = 1.0/(GLdouble) (n_phi); dt = 1.0/(GLdouble) (n_eta+1); /* star radius on x-axis towards L1 */ RX = BinPtr->Xp; /* mirror x -> -x for secondary */ /* mirror y -> -y for left handed coordinates of roche lobes */ if (Comp == Secondary) { C = -1; C2 = -1; } else { C = 1; C2 = -1; } /* make vertex list for the roche lobe */ if (Flags.points == TRUE) { glBegin(GL_POINTS); } else { glBegin(GL_POLYGON); } t=0.0; s=0.0; /* polygon opposite of L1 on the x-axis */ for (j=0; j < n_phi; j++) { if (Comp == Primary) { if ( (SurfPtr->EclipseFlag == FALSE) ) { if (j == 0) { glNormal3f(C*SurfPtr->l, C2*SurfPtr->m, SurfPtr->n); } /* glTexCoord2d(s, t);*/ glVertex3f(C*SurfPtr->lambda,C2*SurfPtr->mu,SurfPtr->nu); } } else { if ( (SurfPtr->EclipseFlag == FALSE) ) { /* mirror x -> -x for secondary */ if (j == 0) { glNormal3f(C*SurfPtr->l, C2*SurfPtr->m, SurfPtr->n); } /*glTexCoord2d(s, t);*/ glVertex3f(C*SurfPtr->lambda,C2*SurfPtr->mu,SurfPtr->nu); } } ++SurfPtr; s += ds; } glEnd(); t += dt; SurfPtr = Surface[Comp]; /* first point of the next ring */ NextRingPtr += n_phi; /* begin vertex list */ if (Flags.points == TRUE) { glBegin(GL_POINTS); glPointSize(1); } else { glBegin(GL_QUAD_STRIP); } for (i=0; i < n_eta-1; i++) { s=0.0; for (j = 0; j < n_phi; j++) { /* store first vertices of the actual and next ring */ if (j == 0) { FirstVertPtr=SurfPtr; FirstVertPtr2=NextRingPtr; } if ( (Flags.points == FALSE) || ((SurfPtr->EclipseFlag == FALSE) && (NextRingPtr->EclipseFlag == FALSE)) ) { /* we are not in the last ring */ /* and not in the last segment */ /* assign normal vectors */ glNormal3f(C*SurfPtr->l, C2*SurfPtr->m, SurfPtr->n); glTexCoord2d(s, t); glVertex3f(C*SurfPtr->lambda,C2*SurfPtr->mu,SurfPtr->nu); glTexCoord2d(s, t+dt); glVertex3f(C*NextRingPtr->lambda,C2*NextRingPtr->mu,NextRingPtr->nu); } /* go to next vertex */ ++SurfPtr; ++NextRingPtr; s += ds; /* we are in the last ring or segment */ if (j == n_phi-1) { /* last point of the ring */ /* close the loop with the first point */ if ( (Flags.points == FALSE) || ((FirstVertPtr->EclipseFlag == FALSE) && (FirstVertPtr2->EclipseFlag == FALSE)) ) { glNormal3f(C*FirstVertPtr->l, C2*FirstVertPtr->m, FirstVertPtr->n); glTexCoord2d(s, t); glVertex3f(C*FirstVertPtr->lambda,C2*FirstVertPtr->mu,FirstVertPtr->nu); glTexCoord2d(s, t+dt); glVertex3f(C*FirstVertPtr2->lambda,C2*FirstVertPtr2->mu,FirstVertPtr2->nu); } } } /* end of phi loop */ t += dt; } /* end of eta loop */ t -= dt; s=0.0; for (j = 0; j < n_phi; j++) { if (j == 0) { FirstVertPtr=SurfPtr; } if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) { /* this is the last ring in direction to L1 */ glNormal3f(C*SurfPtr->l, C2*SurfPtr->m, SurfPtr->n); glTexCoord2d(s, t); glVertex3f(C*SurfPtr->lambda,C2*SurfPtr->mu,SurfPtr->nu); glTexCoord2d(s, t+dt); glVertex3f((float) C*RX,0,0); } ++SurfPtr; ++NextRingPtr; s += ds; if (j == n_phi-1) { /* are at the last point of the ring */ /* close the loop with the first point */ if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) { glNormal3f(C*FirstVertPtr->l, C2*FirstVertPtr->m, FirstVertPtr->n); glTexCoord2d(s, t); glVertex3f(C*FirstVertPtr->lambda,C2*FirstVertPtr->mu,FirstVertPtr->nu); glTexCoord2d(s, t+dt); glVertex3f(C*RX, 0, 0); } } } glEnd(); /* add spots */ if ( Comp == Primary) { GLMakeSpots(Comp, com-1.0); } else if (Comp == Secondary) { /* translate to the position of the secondary */ GLMakeSpots(Comp, com-1.0); } #ifdef HAVE_DISK } else { /* mirror x -> -x for disk */ C = -1; C2 = -1; /* Disk stuff */ n_phi = 32; n_rings = 42; n_ringso = BinPtr->RingsOut; n_ringsi = BinPtr->RingsIn; /* increment for texture coordinates */ ds=1.0/(GLdouble) (n_phi); dt=1.0/(GLdouble) (n_rings); /* increase pointer to the first vertex of the next ring */ NextRingPtr += n_phi; /* begin vertex list */ if (Flags.points == TRUE) { glBegin(GL_POINTS); } else { glBegin(GL_QUAD_STRIP); } t=0.0; /* start with top layer of the disk */ for (j = 0; j < n_rings; j++) { s=0.0; for (i=0; i < n_phi; i++) { if (i == 0) { FirstVertPtr = SurfPtr; FirstVertPtr2 = NextRingPtr; } if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) { /* assign normal vectors */ glNormal3f(C*SurfPtr->l , C2*SurfPtr->m , SurfPtr->n); glTexCoord2d(s, t); glVertex3f(C*SurfPtr->lambda , C2*SurfPtr->mu , SurfPtr->nu); glTexCoord2d(s, t+dt); glVertex3f(C*NextRingPtr->lambda, C2*NextRingPtr->mu, NextRingPtr->nu); } /* go to next vertex */ ++SurfPtr; ++NextRingPtr; s += ds; if ( i == n_phi-1) { if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) { /* last point of the ring */ /* close the loop with the first point */ glNormal3f(C*FirstVertPtr->l , C2*FirstVertPtr->m , FirstVertPtr->n ); glTexCoord2d(s, t); glVertex3f(C*FirstVertPtr->lambda , C2*FirstVertPtr->mu , FirstVertPtr->nu ); glTexCoord2d(s, t+dt); glVertex3f(C*FirstVertPtr2->lambda, C2*FirstVertPtr2->mu, FirstVertPtr2->nu); } } } /* end of phi loop */ t+=dt; } /* end of rings loop */ /* increment for texture coordinates */ ds=1.0/(GLdouble) (n_ringso); t = 0.0; /* outer disk rim */ for (j = 0; j < n_ringso; j++) { s = 0.0; for (i=0; i < n_phi; i++) { if (i == 0) { FirstVertPtr = SurfPtr; FirstVertPtr2 = NextRingPtr; } if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) { /* assign normal vectors */ glNormal3f(C*SurfPtr->l , C2*SurfPtr->m , SurfPtr->n); glTexCoord2d(s, t); glVertex3f(C*SurfPtr->lambda , C2*SurfPtr->mu , SurfPtr->nu); glTexCoord2d(s, t+dt); glVertex3f(C*NextRingPtr->lambda, C2*NextRingPtr->mu, NextRingPtr->nu); } /* go to next vertex */ ++SurfPtr; ++NextRingPtr; s += ds; if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) { if ( i == n_phi-1) { /* last point of the ring */ /* close the loop with the first point */ glNormal3f(C*FirstVertPtr->l , C2*FirstVertPtr->m , FirstVertPtr->n); glTexCoord2d(s, t); glVertex3f(C*FirstVertPtr->lambda , C2*FirstVertPtr->mu , FirstVertPtr->nu); glTexCoord2d(s, t+dt); glVertex3f(C*FirstVertPtr2->lambda, C2*FirstVertPtr2->mu, FirstVertPtr2->nu); } } } t+=dt; } /* increment for texture coordinates */ ds=1.0/(GLdouble) (n_phi); t=1.0; /* bottom layer of the disk */ for (j = 0; j < n_rings; j++) { s=0.0; for (i=0; i < n_phi; i++) { if (i == 0) { FirstVertPtr = SurfPtr; FirstVertPtr2 = NextRingPtr; } if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) { /* assign normal vectors */ glNormal3f(C*SurfPtr->l , C2*SurfPtr->m , SurfPtr->n); glTexCoord2d(s, t); glVertex3f(C*SurfPtr->lambda , C2*SurfPtr->mu , SurfPtr->nu); glTexCoord2d(s, t-dt); glVertex3f(C*NextRingPtr->lambda, C2*NextRingPtr->mu, NextRingPtr->nu); } /* go to next vertex */ ++SurfPtr; ++NextRingPtr; s += ds; if ( i == n_phi-1) { if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) { /* last point of the ring */ /* close the loop with the first point */ glNormal3f(C*FirstVertPtr->l , C2*FirstVertPtr->m , FirstVertPtr->n); glTexCoord2d(s, t); glVertex3f(C*FirstVertPtr->lambda , C2*FirstVertPtr->mu , FirstVertPtr->nu); glTexCoord2d(s, t-dt); glVertex3f(C*FirstVertPtr2->lambda, C2*FirstVertPtr2->mu, FirstVertPtr2->nu); } } } /* end of phi loop */ t-=dt; } /* end of rings loop */ /* increment for texture coordinates */ ds=1.0/(GLdouble) (n_ringsi); t=0.0; /* inner disk rim */ for (j = 0; j < n_ringsi-1; j++) { s=0.0; for (i=0; i < n_phi; i++) { if (i == 0) { FirstVertPtr = SurfPtr; FirstVertPtr2 = NextRingPtr; } if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) { /* assign normal vectors */ glNormal3f(C*SurfPtr->l , C2*SurfPtr->m , SurfPtr->n); glTexCoord2d(s, t); glVertex3f(C*SurfPtr->lambda , C2*SurfPtr->mu , SurfPtr->nu); glTexCoord2d(s, t+dt); glVertex3f(C*NextRingPtr->lambda, C2*NextRingPtr->mu, NextRingPtr->nu); } /* go to next vertex */ ++SurfPtr; ++NextRingPtr; s += ds; if ( i == n_phi-1) { if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) { /* last point of the ring */ /* close the loop with the first point */ glNormal3f(C*FirstVertPtr->l , C2*FirstVertPtr->m , FirstVertPtr->n); glTexCoord2d(s, t); glVertex3f(C*FirstVertPtr->lambda , C2*FirstVertPtr->mu , FirstVertPtr->nu); glTexCoord2d(s, t+dt); glVertex3f(C*FirstVertPtr2->lambda, C2*FirstVertPtr2->mu, FirstVertPtr2->nu); } } } t+=dt; } NextRingPtr = Surface[Comp]; s = 0; /* close the pot to the first vertex */ for (i=0; i < n_phi; i++) { if (i == 0) { FirstVertPtr = SurfPtr; FirstVertPtr2 = NextRingPtr; } if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) { /* assign normal vectors */ glNormal3f(C*SurfPtr->l , C2*SurfPtr->m , SurfPtr->n); glTexCoord2d(s, t); glVertex3f(C*SurfPtr->lambda , C2*SurfPtr->mu , SurfPtr->nu); glTexCoord2d(s, t+dt); glVertex3f(C*NextRingPtr->lambda, C2*NextRingPtr->mu, NextRingPtr->nu); } /* go to next vertex */ ++SurfPtr; ++NextRingPtr; s += ds; if ( i == n_phi-1) { if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) { /* last point of the ring */ /* close the loop with the first point */ glNormal3f(C*FirstVertPtr->l , C2*FirstVertPtr->m , FirstVertPtr->n); glTexCoord2d(s, t); glVertex3f(C*FirstVertPtr->lambda , C2*FirstVertPtr->mu , FirstVertPtr->nu); glTexCoord2d(s, t+dt); glVertex3f(C*FirstVertPtr2->lambda, C2*FirstVertPtr2->mu, FirstVertPtr2->nu); } } } glEnd(); } #endif } #endif /* OpenGL end */