b3f5f8 1999-08-10 Henrik Grubbström (Grubba) /* 9eaf1d 2008-06-28 Martin Nilsson * \$Id: GLU.pmod,v 1.16 2008/06/28 16:36:53 nilsson Exp \$ b3f5f8 1999-08-10 Henrik Grubbström (Grubba) * * GL Utilities module. */ a20af6 2000-09-26 Fredrik Hübinette (Hubbe) a580e1 2000-09-27 Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__ a20af6 2000-09-26 Fredrik Hübinette (Hubbe) 1f6fee 2002-06-28 Martin Nilsson //! The GL Utilities module is a partial implementation of the //! GLU library. This module only contains functions that someone //! at some point actually needed to get his work done. If you //! need a GLU function that isn't in here, copy the C code from //! the GLU library (Mesa was used last time), tweak it so that //! it compiles as Pike code and then check it in into the CVS. 633562 2004-04-16 Martin Nilsson #if constant(GL) && constant(GL.glOrtho) ea27a5 1999-07-24 Johan Schön import GL; #ifndef M_PI #define M_PI 3.1415926536 #endif 1f6fee 2002-06-28 Martin Nilsson //! @decl void gluLookAt(float eyex, float eyey, float eyez,@ //! float centerx, float centery, float centerz,@ //! float upx, float upy, float upz) //! @decl void gluLookAt(Math.Matrix eye, Math.Matrix center, Math.Matrix up) //! //! gluLookAt creates a viewing matrix derived from an @[eye] point, //! a reference point indicating the @[center] of the scene, and an //! @[up] vector. The matrix maps the reference point to the negative //! z axis and the eye point to the origin, so that, when a typical //! projection matrix is used, the center of the scene maps to the //! center of the viewport. Similarly, the direction described by the //! up vector projected onto the viewing plane is mapped to the positive //! y axis so that it points upward in the viewport. The up vector must //! not be parallel to the line of sight from the eye to the reference //! point. //! //! The matrix generated by gluLookAt postmultiplies the current matrix. //! //! The relation between the matrix objects and the float values are e5ef06 2003-04-01 Martin Nilsson //! @code //! Math.Matrix eye = Math.Matrix( ({ eyex, eyey, eyez }) ); //! @endcode 1f6fee 2002-06-28 Martin Nilsson //! //! @seealso //! @[GL.glFrustum], @[gluPerspective] 4b8ed3 1999-10-25 Mirar (Pontus Hagland) void gluLookAt(float|object eye,float|object center,float|object up, float ... old_api) ea27a5 1999-07-24 Johan Schön { 1f6fee 2002-06-28 Martin Nilsson Math.Matrix x,y,z; 4b8ed3 1999-10-25 Mirar (Pontus Hagland) if (!objectp(eye)) { 1f6fee 2002-06-28 Martin Nilsson eye=Math.Matrix( ({eye,center,up }) ); center=Math.Matrix( old_api[..2] ); up=Math.Matrix( old_api[3..5] ); ea27a5 1999-07-24 Johan Schön } 4b8ed3 1999-10-25 Mirar (Pontus Hagland) /* Make rotation matrix */ ea27a5 1999-07-24 Johan Schön 4b8ed3 1999-10-25 Mirar (Pontus Hagland) z=(eye-center)->normv(); /* Z vector */ y=up; /* Y vector */ x=y->cross(z); /* X vector = Y cross Z */ y=z->cross(x); /* Recompute Y = Z cross X */ ea27a5 1999-07-24 Johan Schön 4b8ed3 1999-10-25 Mirar (Pontus Hagland) /* mpichler, 19950515 */ ea27a5 1999-07-24 Johan Schön /* cross product gives area of parallelogram, which is < 1.0 for * non-perpendicular unit-length vectors; so normalize x, y here */ 4b8ed3 1999-10-25 Mirar (Pontus Hagland) x=x->normv(); // normalize y=y->normv(); // normalize array m=Array.transpose(({ @(x->vect()), 0.0, @(y->vect()), 0.0, @(z->vect()), 0.0, 0.0, 0.0, 0.0, 1.0 })/4)*({}); ea27a5 1999-07-24 Johan Schön 5c1826 1999-10-25 Mirar (Pontus Hagland) glMultMatrix( m ); ea27a5 1999-07-24 Johan Schön /* Translate Eye to Origin */ 5c1826 1999-10-25 Mirar (Pontus Hagland) glTranslate( ((array)(-1*eye))[0] ); ea27a5 1999-07-24 Johan Schön } 1f6fee 2002-06-28 Martin Nilsson //! gluOrtho2D sets up a two-dimensional orthographic viewing region. //! This is equivalent to calling e5ef06 2003-04-01 Martin Nilsson //! @code //! glOrtho(left, right, bottom, top, -1.0, 1.0); //! @endcode 043764 2001-11-19 Martin Nilsson //! @fixme e5ef06 2003-04-01 Martin Nilsson //! The GLU manual says @expr{glOrtho(a,b,c,d, 0, 1)@}. 1f6fee 2002-06-28 Martin Nilsson //! @seealso //! @[GL.glOrtho], @[gluPerspective] ea27a5 1999-07-24 Johan Schön void gluOrtho2D(float left, float right, float bottom, float top) { glOrtho( left, right, bottom, top, -1.0, 1.0 ); } 1f6fee 2002-06-28 Martin Nilsson //! gluPerspective specifies a viewing frustum into the world coordinate //! system. In general, the aspect ratio in gluPerspective should match //! the aspect ratio of the associated viewport. For example, aspect = //! 2.0 means the viewer's angle of view is twice as wide in x as it is //! in y. If the viewport is twice as wide as it is tall, it displays the //! image without distortion. //! //! The matrix generated by gluPerspective is multipled by the current //! matrix, just as if @[GL.glMultMatrix] were called with the generated //! matrix. To load the perspective matrix onto the current matrix stack //! instead, precede the call to gluPerspective with a call to //! @[GL.glLoadIdentity]. ea27a5 1999-07-24 Johan Schön void gluPerspective(float fovy, float aspect, float zNear, float zFar) { float xmin, xmax, ymin, ymax; ymax = zNear * tan( fovy * M_PI / 360.0 ); ymin = -ymax; xmin = ymin * aspect; xmax = ymax * aspect; glFrustum( xmin, xmax, ymin, ymax, zNear, zFar ); } 1f6fee 2002-06-28 Martin Nilsson //! gluPickMatrix creates a projection matrix that can be used to //! restrict drawing to a small region of the viewport. This is //! typically useful to determine what objects are being drawn //! near the cursor. Use gluPickMatrix to restrict drawing to a //! small region around the cursor. Then, enter selection mode //! (with @[GL.glRenderMode] and rerender the scene. All primitives //! that would have been drawn near the cursor are identified and //! stored in the selection buffer. //! //! The matrix created by gluPickMatrix is multiplied by the current //! matrix just as if @[GL.glMultMatrix] is called with the generated //! matrix. To effectively use the generated pick matrix for picking, //! first call @[GL.glLoadIdentity] to load an identity matrix onto //! the perspective matrix stack. Then call gluPickMatrix, and //! finally, call a command (such as @[gluPerspective]) to multiply //! the perspective matrix by the pick matrix. //! //! When using gluPickMatrix to pick NURBS, be careful to turn off the //! NURBS property GLU_AUTO_LOAD_MATRIX. If GLU_AUTO_LOAD_MATRIX is not //! turned off, then any NURBS surface rendered is subdivided //! differently with the pick matrix than the way it was subdivided //! without the pick matrix. //! //! @param viewport //! The viewport is an array with four integers. //! 043764 2001-11-19 Martin Nilsson //! @fixme 1f6fee 2002-06-28 Martin Nilsson //! Does the NURB remark apply? //! //! @seealso //! @[GL.glGet], @[gluLoadIdentity], @[gluMultMatrix], @[gluRenderMode], //! @[gluPerspective] ea27a5 1999-07-24 Johan Schön void gluPickMatrix(float x, float y, float width, float height, array(int) viewport) { array(float) m=allocate(16); float sx, sy; float tx, ty; sx = viewport[2] / width; sy = viewport[3] / height; tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width; ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height; #define M(row,col) m[col*4+row] M(0,0) = sx; M(0,1) = 0.0; M(0,2) = 0.0; M(0,3) = tx; M(1,0) = 0.0; M(1,1) = sy; M(1,2) = 0.0; M(1,3) = ty; 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 glMultMatrix( m ); } 9eaf1d 2008-06-28 Martin Nilsson protected void transform_point(array(float) out, array(float)m, ea27a5 1999-07-24 Johan Schön array(float) in) { #define M(row,col) m[col*4+row] out[0] = M(0,0) * in[0] + M(0,1) * in[1] + M(0,2) * in[2] + M(0,3) * in[3]; out[1] = M(1,0) * in[0] + M(1,1) * in[1] + M(1,2) * in[2] + M(1,3) * in[3]; out[2] = M(2,0) * in[0] + M(2,1) * in[1] + M(2,2) * in[2] + M(2,3) * in[3]; out[3] = M(3,0) * in[0] + M(3,1) * in[1] + M(3,2) * in[2] + M(3,3) * in[3]; #undef M } 1f6fee 2002-06-28 Martin Nilsson //! gluProject transforms the specified object coordinates into window //! coordinates using @[model], @[proj], and @[viewport]. The result is //! returned in a three valued array. ea27a5 1999-07-24 Johan Schön array(float) gluProject(float objx, float objy, float objz, array(float) model, array(float) proj, array(int) viewport) { array(float) in=allocate(4),out=allocate(4); in[0]=objx; in[1]=objy; in[2]=objz; in[3]=1.0; transform_point(out,model,in); transform_point(in,proj,out); if (in[3]==0.0) return 0; in[0]/=in[3]; in[1]/=in[3]; in[2]/=in[3]; return ({ viewport[0]+(1+in[0])*viewport[2]/2, viewport[1]+(1+in[1])*viewport[3]/2, (1+in[2])/2 }); } // array(float) gluUnProject(float winx,float winy,float winz, // array(float) model, array(float) proj, // array(int) viewport) // { // array(float) // m=allocate(16), // A=allocate(16), // in=allocate(4), // out=allocate(4); // in[0]=(winx-viewport[0])*2/viewport[2] - 1.0; // in[1]=(winy-viewport[1])*2/viewport[3] - 1.0; // in[2]=2*winz - 1.0; // in[3]=1.0; // matmul(A,proj,model); // invert_matrix(A,m); // transform_point(out,m,in); // if (out[3]==0.0) // return GL_FALSE; // return ({ out[0]/out[3], out[1]/out[3], out[2]/out[3] }); // } b3f5f8 1999-08-10 Henrik Grubbström (Grubba) 627c73 2004-04-14 Martin Nilsson #else /* constant(GL) */ constant this_program_does_not_exist=1; #endif 9eaf1d 2008-06-28 Martin Nilsson