Skip to content
Snippets Groups Projects
Select Git revision
19 results Searching

getopt.c

Blame
  • Forked from Nettle / nettle
    Source project has a limited visibility.
    GLU.pmod 7.80 KiB
    /*
     * GL Utilities module.
     */
    
    #pike __REAL_VERSION__
    #require constant(GL.glOrtho)
    
    //! 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.
    
    import GL;
    
    #ifndef M_PI
    #define M_PI 3.1415926536
    #endif
    
    //! @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
    //! @code
    //! Math.Matrix eye = Math.Matrix( ({ eyex, eyey, eyez }) );
    //! @endcode
    //!
    //! @seealso
    //!   @[GL.glFrustum], @[gluPerspective]
    void gluLookAt(float|object eye,float|object center,float|object up,
    	       float ... old_api)
    {
      Math.Matrix x,y,z;
    
      if (!objectp(eye))
      {
         eye=Math.Matrix( ({eye,center,up }) );
         center=Math.Matrix( old_api[..2] );
         up=Math.Matrix( old_api[3..5] );
      }
      
      /* Make rotation matrix */
      
      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 */
      
      /* mpichler, 19950515 */
      /* cross product gives area of parallelogram, which is < 1.0 for
       * non-perpendicular unit-length vectors; so normalize x, y here
       */
      
      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)*({}); 
      
      glMultMatrix( m );
      
      /* Translate Eye to Origin */
      glTranslate( ((array)(-1*eye))[0] );
    }  
    
    //! gluOrtho2D sets up a two-dimensional orthographic viewing region.
    //! This is equivalent to calling
    //! @code
    //! glOrtho(left, right, bottom, top, -1.0, 1.0);
    //! @endcode
    //! @fixme
    //!   The GLU manual says @expr{glOrtho(a,b,c,d, 0, 1)@}.
    //! @seealso
    //!   @[GL.glOrtho], @[gluPerspective]
    void gluOrtho2D(float left, float right,
    		float bottom, float top)
    {
      glOrtho( left, right, bottom, top, -1.0, 1.0 );
    }
    
    //! 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].
    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 );
    }
    
    //! 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.
    //!
    //! @fixme
    //!   Does the NURB remark apply?
    //!
    //! @seealso
    //!   @[GL.glGet], @[gluLoadIdentity], @[gluMultMatrix], @[gluRenderMode],
    //!   @[gluPerspective]
    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 );
    }
    
    protected void transform_point(array(float) out, array(float)m,
    			    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
    }
    
    //! gluProject transforms the specified object coordinates into window
    //! coordinates using @[model], @[proj], and @[viewport]. The result is
    //! returned in a three valued array.
    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] });
    // }