"Fossies" - the Fresh Open Source Software Archive

Member "Ygl-4.2/3d.c" (8 May 2012, 26128 Bytes) of package /linux/misc/Ygl-4.2g.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "3d.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.2f_vs_4.2g.

    1 /*
    2  *    Ygl: Run GL programs with standard X11 and/or OpenGL routines.
    3  *    (C) Fred Hucht 1996-2007
    4  *    EMail: fred<at>thp.Uni-Duisburg.de
    5  */
    6 
    7 static const char vcid[] = "$Id: 3d.c,v 4.9 2007-05-08 13:28:43+02 fred Exp fred $";
    8 
    9 #include "header.h"
   10 
   11 #ifdef OGL
   12 static int msingle = 1; /* IrisGL is in single matrix mode per default */
   13 #endif
   14 
   15 /*
   16  * Projection transformations (apply to projection matrix stack)
   17  */
   18 void ortho(Coord left, Coord right, Coord bottom,
   19        Coord top,  Coord near,  Coord far) {
   20   const char * MyName = "ortho";
   21   I(MyName, "%g,%g,%g,%g,%g,%g", left, right, bottom, top, near, far);
   22   IFOGL(
   23     GLint old;
   24     glGetIntegerv(GL_MATRIX_MODE, &old);    /* save old mmode */
   25     glMatrixMode(GL_PROJECTION);        /*switch to PROJECTION mode*/
   26     if (!Ygl.SelectMode) glLoadIdentity();  /* reset matrix */
   27     glOrtho(left, right, bottom, top, near, far);
   28     if (msingle || Ygl.SelectMode) {
   29       glMatrixMode(GL_MODELVIEW);
   30       glLoadIdentity();
   31     }  
   32     glMatrixMode(old),          /* restore mmode */
   33     /* In X11 2d mode we allow ortho() calls and ignore the z-component */
   34     ortho2(left, right, bottom, top)
   35     );  
   36 }
   37 
   38 #ifdef OGL
   39 /* the remaining stuff is only available in OpenGL mode */
   40 
   41 void perspective(Angle ang, Float32 aspect, Coord near, Coord far) {
   42   const char * MyName = "perspective";
   43   GLint old;
   44   I(MyName, "%d,%g,%g,%g", ang, aspect, near, far);
   45   if(!Ygl.UseOGL) NI(MyName);
   46   
   47   glGetIntegerv(GL_MATRIX_MODE, &old);
   48   glMatrixMode(GL_PROJECTION);
   49   if (!Ygl.SelectMode) glLoadIdentity();
   50   gluPerspective(0.1 * ang, aspect, near, far);
   51   if (msingle || Ygl.SelectMode) {
   52     glMatrixMode(GL_MODELVIEW);
   53     glLoadIdentity();
   54   }  
   55   glMatrixMode(old);
   56 }
   57 
   58 void window(Coord left, Coord right, Coord bottom,
   59         Coord top,  Coord near,  Coord far) {
   60   const char * MyName = "window";
   61   GLint old;
   62   I(MyName, "%g,%g,%g,%g,%g,%g", left, right, bottom, top, near, far);
   63   if(!Ygl.UseOGL) NI(MyName);
   64   
   65   glGetIntegerv(GL_MATRIX_MODE, &old);
   66   glMatrixMode(GL_PROJECTION);
   67   if (!Ygl.SelectMode) glLoadIdentity();
   68   glFrustum(left, right, bottom, top, near, far);
   69   if (msingle || Ygl.SelectMode) {
   70     glMatrixMode(GL_MODELVIEW);
   71     glLoadIdentity();
   72   }  
   73   glMatrixMode(old);
   74 }
   75 
   76 /*
   77  * Coordinate transformations 
   78  */
   79 void lookat(Coord eyex, Coord eyey, Coord eyez,
   80         Coord cenx, Coord ceny, Coord cenz,
   81         Angle twist) {
   82   const char * MyName = "lookat";
   83   GLdouble rx = cenx - eyex;
   84   GLdouble ry = ceny - eyey;
   85   GLdouble rz = cenz - eyez;
   86   GLdouble upx, upy, upz;
   87   I(MyName, "%g,%g,%g,%g,%g,%g,%d", eyex, eyey, eyez, cenx, ceny, cenz, twist);
   88   if(!Ygl.UseOGL) NI(MyName);
   89   if(rx != 0.0 || rz != 0.0) {
   90     /* OK, view line is not y-axis, so up direction is y-axis */
   91     upx = 0.0; upy = 1.0; upz = 0.0;
   92   } else {
   93     /* Special case: looking along y-axis, up = -z */
   94     upx = 0.0; upy = 0.0; upz = -1.0;
   95   }
   96   gluLookAt(eyex, eyey, eyez, cenx, ceny, cenz, upx, upy, upz);
   97   glRotatef(0.1 * twist, rx, ry, rz);
   98 }
   99 
  100 void polarview(Coord distance, Angle azim, Angle inc, Angle twist) {
  101   const char * MyName = "polarview";
  102   I(MyName, "%g,%d,%d,%d", distance, azim, inc, twist);
  103   if(!Ygl.UseOGL) NI(MyName);
  104   glTranslatef(0.0, 0.0, -distance);
  105   glRotatef(-0.1 * twist, 0.0, 0.0, 1.0);
  106   glRotatef(-0.1 * inc,   1.0, 0.0, 0.0);
  107   glRotatef(-0.1 * azim,  0.0, 0.0, 1.0);
  108 }
  109 
  110 void rotate(Angle angle, Char8 axis) {
  111   const char * MyName = "rotate";
  112   I(MyName, "%d,'%c'", angle, axis);
  113   if(!Ygl.UseOGL) NI(MyName);
  114   rot(0.1 * angle, axis);
  115 }
  116 
  117 void rot(Float32 angle, Char8 axis) {
  118   const char * MyName = "rot";
  119   GLfloat x = 0.0F, y = 0.0F, z = 0.0F;
  120   I(MyName, "%g,'%c'", angle, axis);
  121   if(!Ygl.UseOGL) NI(MyName);
  122   switch(axis) {
  123   case 'x': case 'X': x = 1.0F; break;
  124   case 'y': case 'Y': y = 1.0F; break;
  125   case 'z': case 'Z': z = 1.0F; break;
  126   default:
  127     Yprintf(MyName, "invalid axis '%c'.\n", axis);
  128     return;
  129   }
  130   glRotatef(angle, x, y, z);
  131 }
  132 
  133 void translate(Coord x, Coord y, Coord z) {
  134   const char * MyName = "translate";
  135   I(MyName, "%g,%g,%g", x, y, z);
  136   if(!Ygl.UseOGL) NI(MyName);
  137   glTranslatef(x, y, z);
  138 }
  139 
  140 void scale(Float32 x, Float32 y, Float32 z) {
  141   const char * MyName = "scale";
  142   I(MyName, "%g,%g,%g", x, y, z);
  143   if(!Ygl.UseOGL) NI(MyName);
  144   glScalef(x, y, z);
  145 #if 0
  146   /* done in setup_visuals */
  147   if(x != 1.0 || y != 1.0 || z != 1.0) {
  148     glEnable(GL_NORMALIZE); /* Could be better... */
  149   }
  150 #endif
  151 }
  152 
  153 /*
  154  * Matrix ops
  155  */
  156 void pushmatrix(void) {
  157   const char * MyName = "pushmatrix";
  158   I(MyName, "");
  159   if(!Ygl.UseOGL) NI(MyName);
  160   glPushMatrix();
  161 }
  162 
  163 void popmatrix(void) {
  164   const char * MyName = "popmatrix";
  165   I(MyName, "");
  166   if(!Ygl.UseOGL) NI(MyName);
  167   glPopMatrix();
  168 }
  169 
  170 void loadmatrix(Matrix m) {
  171   const char * MyName = "loadmatrix";
  172   GLfloat glm[16];
  173   short i, j;
  174   I(MyName, "Matrix");
  175   if(!Ygl.UseOGL) NI(MyName);
  176   /* Under OpenGL matrices are in column order, transpose... */
  177   for(i = 0; i < 4; i++) for(j = 0; j < 4; j++) glm[4*j + i] = m[i][j];
  178   glLoadMatrixf(glm);
  179 }
  180 
  181 /* getmatrix: see misc.c */
  182 
  183 void multmatrix(Matrix m) {
  184   const char * MyName = "multmatrix";
  185   GLfloat glm[16];
  186   short i, j;
  187   I(MyName, "Matrix");
  188   if(!Ygl.UseOGL) NI(MyName);
  189   /* Under OpenGL matrices are in column order, transpose... */
  190   for(i = 0; i < 4; i++) for(j = 0; j < 4; j++) glm[4*j + i] = m[i][j];
  191   glMultMatrixf(glm);
  192 }
  193 
  194 void mmode(Int16 mode) {
  195   const char * MyName = "mmode";
  196   I(MyName, "%d", mode);
  197   if(!Ygl.UseOGL) NI(MyName);
  198   switch(mode) {
  199   case MSINGLE:
  200     msingle = 1;
  201     glMatrixMode(GL_MODELVIEW);
  202     break;
  203   case MPROJECTION:
  204     msingle = 0;
  205     glMatrixMode(GL_PROJECTION);
  206     break;
  207   case MVIEWING:
  208     msingle = 0;
  209     glMatrixMode(GL_MODELVIEW);
  210     break;
  211   default:
  212     Yprintf(MyName, "invalid mode %d.\n", mode);
  213     break;
  214   }
  215 }
  216 
  217 Int32 getmmode(void) {
  218   const char * MyName = "getmmode";
  219   GLint mode;
  220   I(MyName, "");
  221   if(!Ygl.UseOGL) NIR(MyName, -1);
  222   
  223   glGetIntegerv(GL_MATRIX_MODE, &mode);
  224   
  225   switch(mode) {
  226   case GL_MODELVIEW:  return MVIEWING;
  227   case GL_PROJECTION: return MPROJECTION;
  228   default:
  229     Yprintf(MyName, "strange OpenGL matrix mode %d\n", mode);
  230     return -1;
  231   }
  232 }
  233 
  234 /*
  235  * z-buffer stuff
  236  */
  237 void depthcue(Int32 mode) {
  238   const char * MyName = "depthcue";
  239   I(MyName, "%d", mode);
  240   if(!Ygl.UseOGL) NI(MyName);
  241   if(!Ygl.PCM && !W->rgb) {
  242     Yprintf(MyName, "private colormap required.\n");
  243     return;
  244   }
  245   switch (mode) {
  246   case True:
  247     glEnable (GL_FOG);
  248     break;
  249   case False:
  250     glDisable(GL_FOG);
  251     break;
  252   default:
  253     Yprintf(MyName, "invalid mode %d.\n", mode);
  254     return;
  255   }
  256 }
  257 
  258 #define GL2OGL_Z(z) (((double)(z) + 0x800000)/0xFFFFFF)
  259 
  260 void lshaderange(Colorindex low, Colorindex high, Int32 near, Int32 far) {
  261   const char * MyName = "lshaderange";
  262   I(MyName, "%d,%d,%d,%d", low, high, near, far);
  263   if(!Ygl.UseOGL) NI(MyName);
  264   glFogi(GL_FOG_MODE, GL_LINEAR);
  265   glFogi(GL_FOG_START, near);
  266   glFogi(GL_FOG_END,   far);
  267   glFogi(GL_FOG_INDEX, YGL_COLORS(low));
  268 }
  269   
  270 void lRGBrange(Int16 rmin, Int16 gmin, Int16 bmin,
  271            Int16 rmax, Int16 gmax, Int16 bmax, 
  272            Int32 near, Int32 far) {
  273   const char * MyName = "lRGBrange";
  274   GLfloat color[3];
  275   I(MyName, "%d,%d,%d,%d,%d,%d,%d,%d", rmin, gmin, bmin, rmax, gmax, bmax, near, far);
  276   if(!Ygl.UseOGL) NI(MyName);
  277   color[0] = rmax;
  278   color[1] = gmax;
  279   color[2] = bmax;
  280   glFogi(GL_FOG_MODE, GL_LINEAR);
  281   glFogi(GL_FOG_START, near);
  282   glFogi(GL_FOG_END,   far);
  283   glFogfv(GL_FOG_COLOR, color);
  284 }
  285 
  286 void zbuffer(Int32 mode) {
  287   const char * MyName = "zbuffer";
  288   I(MyName, "%d", mode);
  289   if(!Ygl.UseOGL) NI(MyName);
  290   switch (mode) {
  291   case True:
  292     glEnable (GL_DEPTH_TEST);
  293     break;
  294   case False:
  295     glDisable(GL_DEPTH_TEST);
  296     break;
  297   default:
  298     Yprintf(MyName, "invalid mode %d.\n", mode);
  299     return;
  300   }
  301 }
  302 
  303 void lsetdepth(Int32 near, Int32 far) {
  304   const char * MyName = "lsetdepth";
  305   I(MyName, "%d,%d", near, far);
  306   if(!Ygl.UseOGL) NI(MyName);
  307   glDepthRange(GL2OGL_Z(near),
  308            GL2OGL_Z(far));
  309 }
  310 
  311 void zclear(void) {
  312   const char * MyName = "zclear";
  313   I(MyName, "");
  314   if(!Ygl.UseOGL) NI(MyName);
  315   /*glClearDepth(1.0);*/
  316   glClear(GL_DEPTH_BUFFER_BIT);
  317 }
  318 
  319 void zdraw(Int32 bool) {
  320   const char * MyName = "zdraw";
  321   I(MyName, "%d", bool);
  322   if(!Ygl.UseOGL) NI(MyName);
  323   glDepthMask(bool);
  324 }
  325 
  326 void czclear(Int32 cval, Int32 zval) {
  327   const char * MyName = "czclear";
  328   I(MyName, "%d,%d", cval, zval);
  329   if(!Ygl.UseOGL) NI(MyName);
  330   glClearDepth(GL2OGL_Z(zval));
  331   /*if(Ygl.RGB) glClearColor(glColor4ubv((GLubyte *)&cval);
  332     else */
  333   glClearIndex(cval);
  334   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  335 }
  336 
  337 void zfunction(Int32 func) {
  338   const char * MyName = "zfunction";
  339   GLenum glfunc;
  340   I(MyName, "%d", func);
  341   if(!Ygl.UseOGL) NI(MyName);
  342   switch(func) {
  343   case ZF_NEVER:    glfunc = GL_NEVER;    break;
  344   case ZF_LESS:     glfunc = GL_LESS;     break;
  345   case ZF_LEQUAL:   glfunc = GL_LEQUAL;   break;
  346   case ZF_GREATER:  glfunc = GL_GREATER;  break;
  347   case ZF_NOTEQUAL: glfunc = GL_NOTEQUAL; break;
  348   case ZF_GEQUAL:   glfunc = GL_GEQUAL;   break;
  349   case ZF_ALWAYS:   glfunc = GL_ALWAYS;   break;
  350   default:
  351     Yprintf(MyName, "invalid function %d.\n", func);
  352     return;
  353   }
  354   glDepthFunc(glfunc);
  355 }
  356 
  357 /* Display lists */
  358 Int32 genobj(void) {
  359   const char * MyName = "genobj";
  360   I(MyName, "");
  361   if(!Ygl.UseOGL) NIR(MyName, -1);
  362   return glGenLists(1);
  363 }
  364 
  365 Int32 isobj(Int32 object) {
  366   const char * MyName = "isobj";
  367   I(MyName, "%d", object);
  368   if(!Ygl.UseOGL) NIR(MyName, -1);
  369   return glIsList(object);
  370 }
  371 
  372 void makeobj(Int32 object) {
  373   const char * MyName = "makeobj";
  374   I(MyName, "%d", object);
  375   if(!Ygl.UseOGL) NI(MyName);
  376   glNewList(object, GL_COMPILE);
  377 }
  378 
  379 Int32 getopenobj(void) {
  380   const char * MyName = "getopenobj";
  381   GLint object;
  382   I(MyName, "");
  383   if(!Ygl.UseOGL) NIR(MyName, -1);
  384   glGetIntegerv(GL_LIST_INDEX, &object);
  385   return object;
  386 }
  387 
  388 void closeobj(void) {
  389   const char * MyName = "closeobj";
  390   I(MyName, "");
  391   if(!Ygl.UseOGL) NI(MyName);
  392   glEndList();
  393 }
  394 
  395 void callobj(Int32 object) {
  396   const char * MyName = "callobj";
  397   I(MyName, "%d", object);
  398   if(!Ygl.UseOGL) NI(MyName);
  399   glCallList(object);
  400 }
  401 
  402 void delobj(Int32 object) {
  403   const char * MyName = "delobj";
  404   I(MyName, "%d", object);
  405   if(!Ygl.UseOGL) NI(MyName);
  406   glDeleteLists(object, 1);
  407 }
  408 
  409 /* Lighting */
  410 
  411 /*
  412  * Material
  413  */
  414 static int MaterialNum = 0;
  415 static struct Material {
  416   Uint    index;        /* lmdef index */
  417   GLuint  list;         /* 1st of 2 OpenGL List IDs for MATERIAL */
  418   Float32 emission[4];      /* and BACKMATERIAL */
  419   Float32 ambient[4];
  420   Float32 diffuse[4];
  421   Float32 specular[4];
  422   Float32 shininess[1];
  423   Float32 alpha[1];
  424   Float32 colorindexes[4];
  425 } *Materials = NULL, Materialdefault = {
  426   0, 0,
  427   {0.0F, 0.0F, 0.0F, 1.0F}, /* emission */
  428   {0.2F, 0.2F, 0.2F, 1.0F}, /* ambient */
  429   {0.8F, 0.8F, 0.8F, 1.0F}, /* diffuse */
  430   {0.0F, 0.0F, 0.0F, 1.0F}, /* specular */
  431   {0.0F},           /* shininess */
  432   {1.0F},           /* alpha */
  433   {0.0F, 127.5F, 255.0F}};  /* colorindexes */
  434 
  435 static void defmaterial(const char *caller, 
  436             Int16 index, Int16 numpoints, Float32 prop[]) {
  437   int i;
  438   int newmaterial = False;
  439   struct Material *material;
  440   
  441   if(Materials == NULL) { /* initialize */
  442     i = MaterialNum++;
  443     Materials = (struct Material*)malloc(sizeof(struct Material));
  444     newmaterial = True;
  445   } else {
  446     for(i = MaterialNum - 1; i >= 0 && Materials[i].index != index; i--);
  447     if(i < 0) { /* not found, allocate new */
  448       i = MaterialNum++;
  449       Materials = (struct Material*)
  450     realloc(Materials, MaterialNum * sizeof(struct Material));
  451       newmaterial = True;
  452     }
  453   }
  454   
  455   if(Materials == NULL) {
  456     Yprintf(caller, "can't allocate memory.\n");
  457     exit(-1);
  458   }
  459   
  460   material = &Materials[i];
  461   
  462   if(newmaterial) { /* initialize with defaults */
  463     memcpy(material, &Materialdefault, sizeof(struct Material));
  464     material->index = index;
  465     material->list  = glGenLists(2);
  466   } else {
  467     glDeleteLists(material->list, 2);
  468   }
  469   
  470   for(i = 0; i < numpoints && prop[i];) switch((int)(prop[i++])) {
  471     int j;
  472   case EMISSION:
  473     for(j = 0; j < 3; j++) material->emission[j] = prop[i++];
  474     break;
  475   case AMBIENT:
  476     for(j = 0; j < 3; j++) material->ambient[j] = prop[i++];
  477     break;
  478   case DIFFUSE:
  479     for(j = 0; j < 3; j++) material->diffuse[j] = prop[i++];
  480     break;
  481   case SPECULAR:
  482     for(j = 0; j < 3; j++) material->specular[j] = prop[i++];
  483     break;
  484   case SHININESS:
  485     material->shininess[0] = prop[i++];
  486     break;
  487   case ALPHA:
  488     material->alpha[0] = prop[i++];
  489     break;
  490   case COLORINDEXES:
  491     for(j = 0; j < 3; j++) material->colorindexes[j] = prop[i++];
  492     break;
  493   default:
  494     Yprintf(caller, "invalid MATERIAL property %g.\n", prop[i-1]);
  495     return;
  496   }
  497   /* Set alpha components */
  498   material->emission[3] = material->alpha[0];
  499   material->ambient[3]  = material->alpha[0];
  500   material->diffuse[3]  = material->alpha[0];
  501   material->specular[3] = material->alpha[0];
  502   
  503   /* Put the complete definition into a display list */
  504   glNewList(material->list, GL_COMPILE);
  505   glMaterialfv(GL_FRONT, GL_EMISSION,  material->emission);
  506   glMaterialfv(GL_FRONT, GL_AMBIENT,   material->ambient);
  507   glMaterialfv(GL_FRONT, GL_DIFFUSE,   material->diffuse);
  508   glMaterialfv(GL_FRONT, GL_SPECULAR,  material->specular);
  509   glMaterialfv(GL_FRONT, GL_SHININESS, material->shininess);
  510   glMaterialfv(GL_FRONT, GL_COLOR_INDEXES, material->colorindexes);
  511   glEndList();
  512 
  513   /* and again for BACKMATERIAL */
  514   glNewList(material->list + 1, GL_COMPILE);
  515   glMaterialfv(GL_BACK, GL_EMISSION,  material->emission);
  516   glMaterialfv(GL_BACK, GL_AMBIENT,   material->ambient);
  517   glMaterialfv(GL_BACK, GL_DIFFUSE,   material->diffuse);
  518   glMaterialfv(GL_BACK, GL_SPECULAR,  material->specular);
  519   glMaterialfv(GL_BACK, GL_SHININESS, material->shininess);
  520   glMaterialfv(GL_BACK, GL_COLOR_INDEXES, material->colorindexes);
  521   glEndList();
  522 }
  523 
  524 /*
  525  * LightModel
  526  */
  527 static int LightModelNum = 0;
  528 static struct LightModel {
  529   Uint    index;        /* lmdef index */
  530   GLuint  list;         /* OpenGL List ID */
  531   Float32 ambient[4];
  532   Float32 localviewer[1];
  533   Float32 twoside[1];
  534 } *LightModels = NULL, LightModeldefault = {
  535   0, 0,
  536   {0.2F, 0.2F, 0.2F, 1.0F}, /* ambient */
  537   {0.0F},           /* localviewer */
  538   {0.0F}            /* twoside */
  539 };
  540 
  541 static struct Attenuation_ {
  542   Float32 constant;
  543   Float32 linear;
  544   Float32 quadratic;
  545 } Attenuation = {
  546   1.0F,
  547   0.0F,
  548   0.0F
  549 };
  550   
  551 static void deflightmodel(const char *caller, 
  552               Int16 index, Int16 numpoints, Float32 prop[]) {
  553   int i;
  554   int newlightmodel = False;
  555   struct LightModel *lightmodel;
  556   
  557   if(LightModels == NULL) { /* initialize */
  558     i = LightModelNum++;
  559     LightModels = (struct LightModel*)malloc(sizeof(struct LightModel));
  560     newlightmodel = True;
  561   } else {
  562     for(i = LightModelNum - 1; i >= 0 && LightModels[i].index != index; i--);
  563     if(i < 0) { /* not found, allocate new */
  564       i = LightModelNum++;
  565       LightModels = (struct LightModel*)
  566     realloc(LightModels, LightModelNum * sizeof(struct LightModel));
  567       newlightmodel = True;
  568     }
  569   }
  570   
  571   if(LightModels == NULL) {
  572     Yprintf(caller, "can't allocate memory.\n");
  573     exit(-1);
  574   }
  575   
  576   lightmodel = &LightModels[i];
  577   
  578   if(newlightmodel) { /* initialize with defaults */
  579     memcpy(lightmodel, &LightModeldefault, sizeof(struct LightModel));
  580     lightmodel->index = index;
  581     lightmodel->list  = glGenLists(1);
  582   } else {
  583     glDeleteLists(lightmodel->list, 1);
  584   }
  585   
  586   for(i = 0; i < numpoints && prop[i];) switch((int)(prop[i++])) {
  587     int j;
  588   case AMBIENT:
  589     for(j = 0; j < 3; j++) lightmodel->ambient[j] = prop[i++];
  590     break;
  591   case LOCALVIEWER:
  592     lightmodel->localviewer[0] = prop[i++];
  593     break;
  594   case ATTENUATION:
  595     /* used in lmbind */
  596     Attenuation.constant = prop[i++];
  597     Attenuation.linear   = prop[i++];
  598     /*Yprintf(caller, "LMODEL ATTENUATION experimental.\n");*/
  599     break;
  600   case ATTENUATION2:
  601     /* used in lmbind */
  602     Attenuation.quadratic = prop[i++];
  603     /*Yprintf(caller, "LMODEL ATTENUATION2 experimental.\n");*/
  604     break;
  605   case TWOSIDE:
  606     lightmodel->twoside[0] = prop[i++];
  607     break;
  608   default:
  609     Yprintf(caller, "invalid LMODEL property %g.\n", prop[i-1]);
  610     return;
  611   }
  612   
  613   /* Put the complete definition into a display list */
  614   glNewList(lightmodel->list, GL_COMPILE);
  615   glLightModelfv(GL_LIGHT_MODEL_AMBIENT,
  616          lightmodel->ambient);
  617   glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER,
  618          lightmodel->localviewer);
  619   glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE,
  620          lightmodel->twoside);
  621   glEndList();
  622 }
  623 
  624 /*
  625  * Light
  626  */
  627 static int LightNum = 0;
  628 static struct Light {
  629   Uint    index;
  630   Float32 ambient[4];
  631   Float32 lcolor[4];
  632   Float32 position[4];
  633   Float32 spotdir[3];
  634   Float32 spotexp[1];
  635   Float32 spotcut[1];
  636 } *Lights = NULL, Lightdefault = {
  637   0,
  638   {0.0F, 0.0F, 0.0F, 1.0F}, /* ambient */
  639   {1.0F, 1.0F, 1.0F, 1.0F}, /* lcolor */
  640   {0.0F, 0.0F, 1.0F, 0.0F}, /* position */
  641   {0.0F, 0.0F,-1.0F},       /* spotdir */
  642   {0.0F},           /* spotexp */
  643   {180.0F}};            /* spotcut */
  644 
  645 /* Which definition is already bound to light i? */
  646 static Int32 boundLightindex[8];
  647 
  648 static void deflight(const char *caller, 
  649              Int16 index, Int16 numpoints, Float32 prop[]) {
  650   int i;
  651   int newlight = False;
  652   struct Light *light;
  653   
  654   /* Reset entry in boundLightindex so lmbind reload definition */
  655   for(i = 0; i < 8; i++) if(boundLightindex[i] == index)
  656     boundLightindex[i] = 0;
  657   
  658   if(Lights == NULL) { /* initialize */
  659     i = LightNum++;
  660     Lights = (struct Light*)malloc(sizeof(struct Light));
  661     newlight = True;
  662     
  663   } else {
  664     for(i = LightNum - 1; i >= 0 && Lights[i].index != index; i--);
  665     if(i < 0) { /* not found, allocate new */
  666       i = LightNum++;
  667       Lights = (struct Light*)
  668     realloc(Lights, LightNum * sizeof(struct Light));
  669       newlight = True;
  670     }
  671   }
  672   
  673   if(Lights == NULL) {
  674     Yprintf(caller, "can't allocate memory.\n");
  675     exit(-1);
  676   }
  677   
  678   light = &Lights[i];
  679   
  680   if(newlight) { /* initialize with defaults */
  681     memcpy(light, &Lightdefault, sizeof(struct Light));
  682     light->index = index;
  683   }
  684   
  685   for(i = 0; i < numpoints && prop[i];) switch((int)(prop[i++])) {
  686     int j;
  687   case AMBIENT:
  688     for(j = 0; j < 3; j++) light->ambient[j] = prop[i++];
  689     break;
  690   case LCOLOR:
  691     for(j = 0; j < 3; j++) light->lcolor[j] = prop[i++];
  692     break;
  693   case POSITION:
  694     for(j = 0; j < 4; j++) light->position[j] = prop[i++];
  695     break;
  696   case SPOTDIRECTION:
  697     for(j = 0; j < 3; j++) light->spotdir[j] = prop[i++];
  698     break;
  699   case SPOTLIGHT:
  700     light->spotexp[0] = prop[i++];
  701     light->spotcut[0] = prop[i++];
  702     break;
  703   default:
  704     Yprintf(caller, "invalid LIGHT property %g.\n", prop[i-1]);
  705     return;
  706   }
  707 }
  708 
  709 void lmdef(Int16 deftype, Int16 index, Int16 numpoints, Float32 prop[]) {
  710   const char * MyName = "lmdef";
  711   I(MyName, "%d,%d,%d,*", deftype, index, numpoints);
  712   if(!Ygl.UseOGL) NI(MyName);
  713   
  714 #ifdef DEBUG
  715   {
  716     int i;
  717     Yprintf(MyName, "deftype=%d, index=%d, numpoints=%d: ",
  718         deftype, index, numpoints);
  719     for(i = 0; i < numpoints; i++) fprintf(stderr, "%g ", prop[i]);
  720     fprintf(stderr, "\n");
  721   }
  722 #endif
  723   
  724   if(index == 0) {
  725     Yprintf(MyName, "can't redefine index 0.\n");
  726     return;
  727   }
  728   
  729   switch(deftype) {
  730   case DEFMATERIAL:
  731     defmaterial(MyName, index, numpoints, prop);
  732     break;
  733   case DEFLIGHT:
  734     deflight(MyName, index, numpoints, prop);
  735     break;
  736   case DEFLMODEL:
  737     deflightmodel(MyName, index, numpoints, prop);
  738     break;
  739   default:
  740     Yprintf(MyName, "invalid type %d.\n", deftype);
  741     return;
  742   }
  743 }
  744 
  745 void lmbind(Int32 target, Int32 index) {
  746   const char * MyName = "lmbind";
  747   GLenum gllight;
  748   int i, boundi;
  749   I(MyName, "%d,%d", target, index);
  750   if(!Ygl.UseOGL) NI(MyName);
  751   
  752   if(target == MATERIAL || target == LMODEL) {
  753     if(index == 0) {
  754       glDisable(GL_LIGHTING);
  755       glDisable(GL_NORMALIZE);
  756       return;
  757     } else {
  758       glEnable(GL_LIGHTING);
  759       glEnable(GL_NORMALIZE); /* GL sets this */
  760     }
  761   }
  762   
  763   switch(target) {
  764   case MATERIAL:
  765     for(i = MaterialNum - 1; i >= 0 && Materials[i].index != index; i--);
  766     if(i < 0) {
  767       Yprintf(MyName, "MATERIAL %d not defined.\n", index);
  768       return;
  769     }
  770     glCallList(Materials[i].list);
  771     return;
  772   case BACKMATERIAL:
  773     for(i = MaterialNum - 1; i >= 0 && Materials[i].index != index; i--);
  774     if(i < 0) {
  775       Yprintf(MyName, "MATERIAL %d not defined.\n", index);
  776       return;
  777     }
  778     glCallList(Materials[i].list + 1);
  779     return;
  780   case LMODEL:
  781     for(i = LightModelNum - 1; i >= 0 && LightModels[i].index != index; i--);
  782     if(i < 0) {
  783       Yprintf(MyName, "MATERIAL %d not defined.\n", index);
  784       return;
  785     }
  786     glCallList(LightModels[i].list);
  787     return;
  788   case LIGHT0: boundi = 0; gllight = GL_LIGHT0; break;
  789   case LIGHT1: boundi = 1; gllight = GL_LIGHT1; break;
  790   case LIGHT2: boundi = 2; gllight = GL_LIGHT2; break;
  791   case LIGHT3: boundi = 3; gllight = GL_LIGHT3; break;
  792   case LIGHT4: boundi = 4; gllight = GL_LIGHT4; break;
  793   case LIGHT5: boundi = 5; gllight = GL_LIGHT5; break;
  794   case LIGHT6: boundi = 6; gllight = GL_LIGHT6; break;
  795   case LIGHT7: boundi = 7; gllight = GL_LIGHT7; break;
  796   default:
  797     Yprintf(MyName, "invalid target %d.\n", target);
  798     return;
  799   }
  800   
  801   if(index == 0) {
  802     glDisable(gllight);
  803   } else {
  804     glEnable(gllight);
  805     if(index != boundLightindex[boundi]) {
  806       /* load definition for light if changed or not already loaded */
  807       boundLightindex[boundi] = index;
  808       for(i = LightNum - 1; i >= 0 && Lights[i].index != index; i--);
  809       if(i < 0) {
  810     Yprintf(MyName, "LIGHT %d not defined.\n", index);
  811     return;
  812       }
  813       glLightfv(gllight, GL_AMBIENT,        Lights[i].ambient);
  814       glLightfv(gllight, GL_DIFFUSE,        Lights[i].lcolor);
  815       glLightfv(gllight, GL_SPECULAR,       Lights[i].lcolor);
  816       glLightfv(gllight, GL_POSITION,       Lights[i].position);
  817       glLightfv(gllight, GL_SPOT_DIRECTION, Lights[i].spotdir);
  818       glLightfv(gllight, GL_SPOT_EXPONENT,  Lights[i].spotexp);
  819       glLightfv(gllight, GL_SPOT_CUTOFF,    Lights[i].spotcut);
  820       glLightf(gllight, GL_CONSTANT_ATTENUATION,  Attenuation.constant);
  821       glLightf(gllight, GL_LINEAR_ATTENUATION,    Attenuation.linear);
  822       glLightf(gllight, GL_QUADRATIC_ATTENUATION, Attenuation.quadratic);
  823     }
  824   }
  825 }
  826 
  827 void lmcolor(Int32 mode) {
  828   const char * MyName = "lmcolor";
  829   GLenum glmode;
  830   I(MyName, "%d", mode);
  831   if(!Ygl.UseOGL) NI(MyName);
  832 
  833   switch(mode) {
  834   case LMC_COLOR:
  835     glDisable(GL_COLOR_MATERIAL);
  836     return;
  837   case LMC_NULL:
  838     Yprintf(MyName, "unimplemented mode %d.\n", mode);
  839     return;
  840   case LMC_EMISSION: glmode = GL_EMISSION; break;
  841   case LMC_AMBIENT:  glmode = GL_AMBIENT;  break;
  842   case LMC_DIFFUSE:  glmode = GL_DIFFUSE;  break;
  843   case LMC_SPECULAR: glmode = GL_SPECULAR; break;
  844   case LMC_AD:       glmode = GL_AMBIENT_AND_DIFFUSE; break;
  845   default:
  846     Yprintf(MyName, "invalid mode %d.\n", mode);
  847     return;
  848   }
  849   glEnable(GL_COLOR_MATERIAL);
  850   glColorMaterial(GL_FRONT_AND_BACK, glmode);
  851 }
  852 
  853 void shademodel(Int32 mode) {
  854   const char * MyName = "shademodel";
  855   GLenum glmode;
  856   I(MyName, "%d", mode);
  857   if(!Ygl.UseOGL) NI(MyName);
  858   
  859   switch(mode) {
  860   case FLAT:    glmode = GL_FLAT;   break;
  861   case GOURAUD: glmode = GL_SMOOTH; break;
  862   default:
  863     Yprintf(MyName, "invalid mode %d.\n", mode);
  864     return;
  865   }
  866   glShadeModel(glmode);
  867 }
  868 
  869 static int Face[] = {False, False};
  870 
  871 static void front_back(const char *caller, GLenum glcull, Int32 mode) {
  872   I(caller, "%d", mode);
  873   if(!Ygl.UseOGL) NI(caller);
  874   switch(mode) {
  875   case True:
  876     Face[0] = True;
  877     glCullFace(glcull);
  878     break;
  879   case False:
  880     Face[0] = False;
  881     break;
  882   default:
  883     Yprintf(caller, "invalid mode %d.\n", mode);
  884     return;
  885   }
  886   if(Face[0] || Face[1]) {
  887     glEnable(GL_CULL_FACE);
  888   } else {
  889     glDisable(GL_CULL_FACE);
  890   }
  891 }
  892 
  893 void frontface(Int32 mode) {
  894   const char * MyName = "frontface";
  895   front_back(MyName, GL_FRONT, mode);
  896 }
  897 
  898 void backface(Int32 mode) {
  899   const char * MyName = "backface";
  900   front_back(MyName, GL_BACK, mode);
  901 }
  902 
  903 void RGBwritemask(Int16 red, Int16 green, Int16 blue) {
  904   const char * MyName = "RGBwritemask";
  905   I(MyName, "%d,%d,%d", red, green, blue);
  906   if(!Ygl.UseOGL) NI(MyName);
  907   glColorMask(red != 0, green != 0, blue != 0, GL_FALSE);
  908 }
  909 
  910 /* for Pete Riley */
  911 void drawmode(Int32 mode) {
  912   const char * MyName = "drawmode";
  913   I(MyName, "%d", mode);
  914   if(!Ygl.UseOGL) NI(MyName);
  915   NI(MyName);
  916 }
  917 
  918 void iconsize(Int32 sx, Int32 sy) {
  919   const char * MyName = "iconsize";
  920   I(MyName, "%d,%d", sx, sy);
  921   if(!Ygl.UseOGL) NI(MyName);
  922   NI(MyName);
  923 }
  924 
  925 void overlay(Int32 arg) {
  926   const char * MyName = "overlay";
  927   I(MyName, "%d", arg);
  928   if(!Ygl.UseOGL) NI(MyName);
  929   NI(MyName);
  930 }
  931 
  932 void pushattributes(void) {
  933   const char * MyName = "pushattributes";
  934   I(MyName, "");
  935   if(!Ygl.UseOGL) NI(MyName);
  936   glPushAttrib(GL_ALL_ATTRIB_BITS);
  937 }
  938 
  939 void popattributes(void) {
  940   const char * MyName = "popattributes";
  941   I(MyName, "");
  942   if(!Ygl.UseOGL) NI(MyName);
  943   glPopAttrib();
  944 }
  945 
  946 void fullscrn(void) {
  947   const char * MyName = "fullscrn";
  948   I(MyName, "");
  949   if(!Ygl.UseOGL) NI(MyName);
  950   NI(MyName);
  951 }
  952 
  953 void endfullscrn(void) {
  954   const char * MyName = "endfullscrn";
  955   I(MyName, "");
  956   if(!Ygl.UseOGL) NI(MyName);
  957   NI(MyName);
  958 }
  959 
  960 void scrmask(Screencoord l, Screencoord r, Screencoord b, Screencoord t) {
  961   const char * MyName = "scrmask";
  962   I(MyName, "%d,%d,%d,%d", l, r, b, t);
  963   if(!Ygl.UseOGL) NI(MyName);
  964   glScissor(l, b, r - l, t - b);
  965   glEnable(GL_SCISSOR_TEST);
  966 }
  967 
  968 /* Added 2012 */
  969 
  970 void  blanktime     ( Int32 a ) {
  971   const char * MyName = "blanktime";
  972   //I(MyName, "");
  973   if(!Ygl.UseOGL) NI(MyName);
  974   NI(MyName);
  975 }
  976 void  defpattern    ( Int16 a, Int16 b, Int16 * c ) {
  977   const char * MyName = "defpattern";
  978   I(MyName, "");
  979   if(!Ygl.UseOGL) NI(MyName);
  980   NI(MyName);
  981 }
  982 Int32 getpattern    ( void ) {
  983   const char * MyName = "getpattern";
  984   I(MyName, "");
  985   if(!Ygl.UseOGL) NIR(MyName, 0);
  986   NIR(MyName, 0);
  987 }
  988 void  setpattern    ( Int16 a ) {
  989   const char * MyName = "setpattern";
  990   I(MyName, "");
  991   if(!Ygl.UseOGL) NI(MyName);
  992   NI(MyName);
  993 }
  994 void  writemask     ( Colorindex a ) {
  995   const char * MyName = "writemask";
  996   I(MyName, "");
  997   if(!Ygl.UseOGL) NI(MyName);
  998   NI(MyName);
  999 }
 1000 
 1001 #endif /* OGL */