ringrose@fibula.ai.mit.edu (Robert Ringrose) (03/13/91)
I am running into a problem with lighting on the Personal Iris 4D/25. (working with C and the gl libraries) It works fine until I put in a call to a routine with the following code, part of an attempt to get the current projection and modelview matrices: mmode(MPROJECTION); mmode(MVIEWING); I will grant that there is usually more code in between, but I have observed the problem with the code in between commented out AND the problem goes away when I comment out the mmode(MPROJECTION) call. Specifically, the problem is that the one infinite light I use, bound to LIGHT1, is rotated and the rotation is increased every time those two lines are executed. I have tried re-defining and re-binding the light, without change. Now, in an _old_ version of the manual it talks about keeping the inverse transpose of part of the modelview matrix and updating it as you go, for use with the lighting calculations. Is it possible that this matrix is getting messed up by the contents of the projection matrix when you go through mmode(MPROJECTION) with a non-unit projection matrix? Or am I on the wrong track - that section of the manual seems to be absent from version 4.0 (it was on 9-35 of the version 1.0 manual). Suggestions, reasons, solutions, workarounds, etc. would be _greatly_ appreciated. Please reply by E-mail to ringrose@ai.mit.edu - Robert Ringrose There's always one more bu6.
howardl@sgi.com (Howard Look) (03/13/91)
In article <13917@life.ai.mit.edu> ringrose@fibula.ai.mit.edu (Robert Ringrose) writes: > >I am running into a problem with lighting on the Personal Iris 4D/25. >(working with C and the gl libraries) > >It works fine until I put in a call to a routine with the >following code, part of an attempt to get the current >projection and modelview matrices: > > >mmode(MPROJECTION); >mmode(MVIEWING); > >... > >Specifically, the problem is that the one infinite light I use, >bound to LIGHT1, is rotated and the rotation is increased every >time those two lines are executed. I have tried re-defining and >re-binding the light, without change. Using mmode(MPROJECTION) is not a usual thing to do. As a matter of fact, for most applications, you really only need to go into mmode(MVIEWING) once in your initialize routine. Projection calls (perspective, window, ortho, ortho2) will replace the projection matrix anyway. Here is an example of a rotating infinite light source. The light is made to rotate by binding while a rotation is part of the current matrix. The light is only bound once. Hope this helps. -- howard. /* * light_motion.c * Compile with * cc light_motion.c -o light_motion -lsphere -lgl_s -lm */ #include <gl/gl.h> #include <gl/device.h> #include <gl/sphere.h> /* macro to count the number of properties in an array */ #define NP(array) ((sizeof(array)/(sizeof(array[0])))) void initialize(void); void drawscene(void); /* size of the window */ int xmax, ymax; /* different light positions */ #define EYE 1 #define WORLD 2 #define MOVING 3 int light_position = MOVING; int moving_eye = FALSE; float light_model[] = { AMBIENT, 0.1, 0.1, 0.1, ATTENUATION, 1.0, 0.0, LOCALVIEWER, 0.0, LMNULL }; float white_light[] = { AMBIENT, 0.2, 0.2, 0.2, POSITION, 0.0, 0.0, 10.0, 0.0, LCOLOR, 1.0, 1.0, 1.0, LMNULL }; float green_plastic[] = { DIFFUSE, 0.1, 1.0, 0.1, SPECULAR, 1.0, 1.0, 1.0, SHININESS, 10.0, LMNULL }; float yellow_plastic[] = { DIFFUSE, 1.0, 1.0, 0.1, SPECULAR, 1.0, 1.0, 1.0, SHININESS, 10.0, LMNULL }; void main () { Boolean exitflag = FALSE; short attached=0; /* attached to window */ short value; int dev; /* input device */ initialize(); while (exitflag == FALSE) { drawscene(); while ((exitflag == FALSE) && (qtest() || !attached)) { dev = qread (&value); if ((dev == ESCKEY) && (value == 0)) { exitflag = TRUE; } else if (dev == REDRAW) { reshapeviewport(); } else if (dev == INPUTCHANGE) { attached = value; } /* end while qtest or not attached */ } } /* end while (exitflag == FALSE) */ exit(0); } /* end main() */ void initialize(void) { int gid; xmax = getgdesc(GD_XPMAX); ymax = getgdesc(GD_YPMAX); prefposition( xmax/4, xmax*3/4, ymax/4, ymax*3/4 ); gid = winopen ("light1"); minsize (xmax/10, ymax/10); keepaspect (xmax, ymax); winconstraints(); RGBmode(); doublebuffer(); gconfig (); zbuffer(TRUE); qdevice(ESCKEY); qenter(REDRAW,gid); /* double matrix mode since using lighting */ mmode(MVIEWING); /* define the light model, light source, and material */ lmdef(DEFLMODEL, 1, NP(light_model), light_model); lmdef(DEFLIGHT, 1, NP(white_light), white_light); lmdef(DEFMATERIAL, 1, NP(green_plastic), green_plastic); lmdef(DEFMATERIAL, 2, NP(yellow_plastic), yellow_plastic); /* bind the light model */ lmbind(LMODEL, 1); } void drawscene(void) { static int angle = 0; static float unit[] = {0.0,0.0,0.0,1.0}; czclear(0x0, getgdesc(GD_ZMAX)); perspective(450, (float)xmax/(float)ymax, 1.0, 10.0); /* Bound here, the light is positioned relative to the eye */ if (light_position == EYE) lmbind(LIGHT0, 1); pushmatrix(); if (moving_eye) polarview(5.0, angle, angle, 0); else polarview(5.0, 0, 0, 0); /* Bound here, the light is positioned relative to the world */ if (light_position == WORLD) lmbind(LIGHT0, 1); if (light_position == MOVING) { pushmatrix(); rotate(angle,'x'); /* Bound here, the light rotates around the world x axis */ lmbind(LIGHT0, 1); popmatrix(); } pushmatrix(); translate(-1.0, 0.0, 0.0); lmbind(MATERIAL,1); sphdraw(unit); popmatrix(); pushmatrix(); translate(1.0, 0.0, 0.0); lmbind(MATERIAL,2); sphdraw(unit); /* turn off material so later objects will not be lit */ lmbind(MATERIAL,0); popmatrix(); popmatrix(); swapbuffers(); angle = angle + 20; } -- Howard Look Silicon Graphics howardl@sgi.com (415) 335-1780 .__ One of these :) after being run over by one of these O-O
ringrose@fibula.ai.mit.edu (Robert Ringrose) (03/14/91)
In article <1991Mar13.062945.5092@odin.corp.sgi.com> howardl@sgi.com (Howard Look) writes: > >Using mmode(MPROJECTION) is not a usual thing to do. No kidding, but is there another way to access the projection matrix so you can go from points on the screen to points in world coordinates? >Here is an example of a rotating infinite light source. The light is >made to rotate by binding while a rotation is part of the current matrix. >The light is only bound once. [Example program deleted] Howard: I have taken your example program and made a few changes so that it illustrates the bug I am running into. As it is here, the lights do not move. If, however, you uncomment the line mmode(MPROJECTION), marked with a "+++" comment, the light source begins to move, despite the fact that the very next line returns you to MVIEWING mode. Once again, I am running this on a Personal Iris 4D/25 and have no idea if other SGI workstations have the same problem. - Robert Ringrose "There's always one more bu6" --------------- Cut here ------------------- /* * lights.c * Compile with * cc lights.c -o lights -lsphere -lgl_s -lm */ #include <gl/gl.h> #include <gl/device.h> #include <gl/sphere.h> /* macro to count the number of properties in an array */ #define NP(array) ((sizeof(array)/(sizeof(array[0])))) void initialize(void); void drawscene(void); /* size of the window */ int xmax, ymax; /* different light positions */ #define EYE 1 #define WORLD 2 #define MOVING 3 int light_position = WORLD; int moving_eye = FALSE; float light_model[] = { AMBIENT, 0.1, 0.1, 0.1, ATTENUATION, 1.0, 0.0, LOCALVIEWER, 0.0, LMNULL }; float white_light[] = { AMBIENT, 0.2, 0.2, 0.2, POSITION, 2.0, 2.0, -2.0, 0.0, LCOLOR, 1.0, 1.0, 1.0, LMNULL }; float green_plastic[] = { DIFFUSE, 0.1, 1.0, 0.1, SPECULAR, 1.0, 1.0, 1.0, SHININESS, 10.0, LMNULL }; float yellow_plastic[] = { DIFFUSE, 1.0, 1.0, 0.1, SPECULAR, 1.0, 1.0, 1.0, SHININESS, 10.0, LMNULL }; void main () { Boolean exitflag = FALSE; short attached=0; /* attached to window */ short value; int dev; /* input device */ initialize(); while (exitflag == FALSE) { drawscene(); while ((exitflag == FALSE) && (qtest() || !attached)) { dev = qread (&value); if ((dev == ESCKEY) && (value == 0)) { exitflag = TRUE; } else if (dev == REDRAW) { reshapeviewport(); } else if (dev == INPUTCHANGE) { attached = value; } /* end while qtest or not attached */ } } exit(0); } /* end main() */ void initialize(void) { int gid; xmax = getgdesc(GD_XPMAX); ymax = getgdesc(GD_YPMAX); prefposition( xmax/4, xmax*3/4, ymax/4, ymax*3/4 ); gid = winopen ("light1"); minsize (xmax/10, ymax/10); keepaspect (xmax, ymax); winconstraints(); RGBmode(); doublebuffer(); gconfig (); zbuffer(TRUE); qdevice(ESCKEY); qenter(REDRAW,gid); /* double matrix mode since using lighting */ mmode(MVIEWING); /* define the light model, light source, and material */ lmdef(DEFLMODEL, 1, NP(light_model), light_model); lmdef(DEFLIGHT, 1, NP(white_light), white_light); lmdef(DEFMATERIAL, 1, NP(green_plastic), green_plastic); lmdef(DEFMATERIAL, 2, NP(yellow_plastic), yellow_plastic); /* bind the light model */ lmbind(LMODEL, 1); } void drawscene(void) { static int angle = 0; static float unit[] = {0.0,0.0,0.0,1.0}; czclear(0x0, getgdesc(GD_ZMAX)); lmbind(LIGHT0, 1); pushmatrix(); perspective(450, (float)xmax/(float)ymax, 1.0, 10.0); polarview(5.0, 0, 0, 0); rotate(-900, 'x'); /* +++ */ /* mmode(MPROJECTION); */ mmode(MVIEWING); pushmatrix(); translate(-1.0, 0.0, 0.0); lmbind(MATERIAL,1); sphdraw(unit); popmatrix(); pushmatrix(); translate(1.0, 0.0, 0.0); lmbind(MATERIAL,2); sphdraw(unit); /* turn off material so later objects will not be lit */ lmbind(MATERIAL,0); popmatrix(); popmatrix(); swapbuffers(); }
nieswand@LISBOA.KS.UIUC.EDU (Benno Nieswand) (03/15/91)
Robert Ringrose writes: > It works fine until I put in a call to a routine with the > following code, part of an attempt to get the current > projection and modelview matrices: > > > mmode(MPROJECTION); > mmode(MVIEWING); I had similar problems and I worked on it for a long time. It's a while ago and I don't remember all the details but I discussed the problem with several people and tried almost every possibility to figure out the systematics behind the problem. I wanted to bind a light to the world coord frame and change projection and viewing. So I did mmode( MPERSPECTIVE) and change perspective() AND polarview() without changing the light binding then I did mmode(MVIEWING) again. This worked fine, as long as I didn't switch the light off and tried to rebind it. The new source direction(infinite far away, as supposed) was dependend on the last projection matrix before the rebind, in contrary to a determined relativ position to the world coord frame. I'm sure there is a bug. Another time I had the same problem Robert, so the source rotated. If there is any solution, please let me know. Benno Nieswand