fortran66のブログ

fortran について書きます。

Fortranへの移植。


MODULE m_callback
USE opengl_gl
USE opengl_glu
USE opengl_glut
IMPLICIT NONE
INTEGER(GLint), PARAMETER :: KEY_ESC = 27
INTEGER(GLint) :: ixBegin = 0, iyBegin = 0
INTEGER(GLint) :: mButton
REAL(GLfloat) :: distance, twist, elevation, azimuth
REAL(GLdouble) :: xnear = 1.0_gldouble, farw = 30.0_gldouble, fovy = 60.0_gldouble
REAL(glfloat) :: greenDiffuse(4)  = (/ 0.0_glfloat, 1.0_glfloat, 0.5_glfloat, 1.0_glfloat /)
REAL(glfloat) :: whiteSpecular(4) = (/ 1.0_glfloat, 1.0_glfloat, 1.0_glfloat, 1.0_glfloat /)
REAL(glfloat) :: whiteAmbient(4)  = (/ 0.1_glfloat, 0.1_glfloat, 0.1_glfloat, 1.0_glfloat /)
REAL(GLfloat) :: cpoint(4, 4, 4) = & 
[ [ [ 1.0_glfloat, -1.0_glfloat,  0.0_glfloat, 1.0_glfloat], &
    [ 0.5_glfloat, -1.0_glfloat,  0.0_glfloat, 1.0_glfloat], &
    [-0.5_glfloat, -1.0_glfloat,  0.0_glfloat, 1.0_glfloat], &
    [-1.0_glfloat, -1.0_glfloat,  0.0_glfloat, 1.0_glfloat]  &
  ],  &
  [ [ 1.0_glfloat, -0.5_glfloat,  1.0_glfloat, 1.0_glfloat], &
    [ 0.5_glfloat, -0.5_glfloat,  1.0_glfloat, 1.0_glfloat], &
    [-0.5_glfloat, -0.5_glfloat,  1.0_glfloat, 1.0_glfloat], &
    [-1.0_glfloat, -0.5_glfloat,  1.0_glfloat, 1.0_glfloat]  &
  ],  &
  [ [ 1.0_glfloat,  0.5_glfloat, -1.0_glfloat, 1.0_glfloat], &
    [ 0.5_glfloat,  0.5_glfloat, -1.0_glfloat, 1.0_glfloat], &
    [-0.5_glfloat,  0.5_glfloat, -1.0_glfloat, 1.0_glfloat], &
    [-1.0_glfloat,  0.5_glfloat, -1.0_glfloat, 1.0_glfloat]  &
  ],  &
  [ [ 1.0_glfloat,  1.0_glfloat,  0.0_glfloat, 1.0_glfloat], &
    [ 0.5_glfloat,  1.0_glfloat,  0.0_glfloat, 1.0_glfloat], &
    [-0.5_glfloat,  1.0_glfloat,  0.0_glfloat, 1.0_glfloat], &
    [-1.0_glfloat,  1.0_glfloat,  0.0_glfloat, 1.0_glfloat]  &
  ] ]  
!
REAL(GLfloat) :: knotvec_u(8) = [ 0.0_glfloat, 0.0_glfloat, 0.0_glfloat, 0.0_glfloat, & 
                                  1.0_glfloat, 1.0_glfloat, 1.0_glfloat, 1.0_glfloat  ]
REAL(GLfloat) :: knotvec_v(8) = [ 0.0_glfloat, 0.0_glfloat, 0.0_glfloat, 0.0_glfloat, & 
                                  1.0_glfloat, 1.0_glfloat, 1.0_glfloat, 1.0_glfloat  ]
TYPE (GLUnurbsObj), POINTER :: nrb_obj
INTEGER (GLint) :: icp = 1, jcp = 1, icpNo = 0
CONTAINS
!---------------------------------------------------------
SUBROUTINE create_nurbs()
IMPLICIT NONE
nrb_obj => gluNewNurbsRenderer()
CALL gluNurbsProperty( nrb_obj, GLU_SAMPLING_TOLERANCE, 25.0_glfloat )
CALL gluNurbsProperty( nrb_obj, GLU_DISPLAY_MODE      , REAL(GLU_FILL, GLfloat) )
!CALL gluNurbsProperty( nrb_obj, GLU_DISPLAY_MODE      , REAL(GLU_OUTLINE_POLYGON,  GLfloat) )
RETURN
END SUBROUTINE create_nurbs
!---------------------------------------------------------
SUBROUTINE drawCP()
IMPLICIT NONE
INTEGER :: i, j
REAL(glfloat) :: x, y, z
CALL glColor3f( 1.0_glfloat, 1.0_glfloat, 0.0_glfloat )
CALL glPointSize( 5.0_glfloat )
CALL glBegin( GL_POINTS )
DO i = 1, 4
 DO j = 1, 4
  x = cpoint(1, j, i) / cpoint(4, j, i)
  y = cpoint(2, j, i) / cpoint(4, j, i)
  z = cpoint(3, j, i) / cpoint(4, j, i)
  CALL glVertex3f( x, y, z )
 END DO
END DO
CALL glEnd()
!
CALL glColor3f( 1.0_glfloat, 0.5_glfloat, 0.5_glfloat )
CALL glPointSize( 10.0_glfloat )
CALL glBegin( GL_POINTS )
 x = cpoint(1, jcp, icp) / cpoint(4, jcp, icp)
 y = cpoint(2, jcp, icp) / cpoint(4, jcp, icp)
 z = cpoint(3, jcp, icp) / cpoint(4, jcp, icp)
 CALL glVertex3f( x, y, z )
CALL glEnd()
!
CALL glDisable( GL_DEPTH_TEST )
CALL glColor3f( 1.0_glfloat, 1.0_glfloat, 1.0_glfloat )
CALL glPointSize( 3.0_glfloat )
CALL glBegin( GL_POINTS )
 x = cpoint(1, jcp, icp) / cpoint(4, jcp, icp)
 y = cpoint(2, jcp, icp) / cpoint(4, jcp, icp)
 z = cpoint(3, jcp, icp) / cpoint(4, jcp, icp)
 CALL glVertex3f( x, y, z )
CALL glEnd()
CALL glEnable( GL_DEPTH_TEST )
RETURN
END SUBROUTINE drawCP
!---------------------------------------------------------
SUBROUTINE display()
IMPLICIT NONE
CALL glClear( IOR(GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT) )
CALL glPushMatrix()
CALL polarview( )
CALL glEnable( GL_DEPTH_TEST )
CALL glEnable( GL_LIGHTING   )
!
CALL glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 1 ) ! 1 <- GL_TRUE
CALL glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE , greenDiffuse  )
CALL glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, whiteSpecular )
CALL glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT , whiteAmbient  )
CALL glMaterialf ( GL_FRONT_AND_BACK, GL_SHININESS, 128.0_glfloat )
!
CALL glEnable( GL_NORMALIZE )
CALL glEnable( GL_AUTO_NORMAL )
CALL glPushMatrix()
!
CALL gluBeginSurface( nrb_obj )
CALL gluNurbsSurface( nrb_obj, 8, knotvec_u, 8, knotvec_v, & 
                      4 * 4, 4, cpoint(:, 1, 1), 4, 4, GL_MAP2_VERTEX_4 )
CALL gluEndSurface( nrb_obj )
!
CALL glPopMatrix()
CALL glDisable( GL_LIGHTING )
CALL drawCP()
CALL glDisable( GL_DEPTH_TEST )
CALL glPopMatrix()
CALL glutSwapBuffers() 
RETURN
END SUBROUTINE display
!---------------------------------------------------------
SUBROUTINE mySkey(key, ix, iy)
IMPLICIT NONE
INTEGER(GLcint), INTENT(IN OUT) :: key, ix, iy
SELECT CASE(key)
 CASE (GLUT_KEY_RIGHT)
  distance = distance + 0.1_glfloat
 CASE (GLUT_KEY_LEFT)
  distance = distance - 0.1_glfloat
 CASE (GLUT_KEY_UP)
 CASE (GLUT_KEY_DOWN)
 CASE DEFAULT
END SELECT
CALL glutPostRedisplay()
RETURN
END SUBROUTINE mySkey
!---------------------------------------------------------
SUBROUTINE myKbd(key, ix, iy)
IMPLICIT NONE
INTEGER(GLcint), INTENT(IN OUT) :: key, ix, iy
SELECT CASE(key)
 CASE (KEY_ESC) 
  STOP
 CASE (ICHAR('x'))
  icpNo = icpNo + 1
  IF (icpNo >= 16) icpNo = 0
  icp = icpNo / 4 
  jcp = icpNo - 4 * icp
  icp = icp + 1
  jcp = jcp + 1
  CALL glutPostRedisplay()
 CASE (ICHAR('z'))
  icpNo = icpNo - 1
  IF (icpNo < 0 ) icpNo = 15
  icp = icpNo / 4
  jcp = icpNo - 4 * icp
  icp = icp + 1
  jcp = jcp + 1
  CALL glutPostRedisplay()
 CASE DEFAULT
END SELECT
RETURN
END SUBROUTINE myKbd
!---------------------------------------------------------
SUBROUTINE myMouse( ibutton, istate, ix, iy )
IMPLICIT NONE
INTEGER(GLcint), INTENT(IN OUT) :: ibutton, istate, ix, iy 
IF (istate == GLUT_DOWN) THEN
 ixBegin = ix
 iyBegin = iy
 mButton = ibutton
END IF
RETURN
END SUBROUTINE myMouse
!---------------------------------------------------------
SUBROUTINE myMotion( ix, iy )
IMPLICIT NONE
INTEGER(GLcint), INTENT(IN OUT) :: ix, iy
INTEGER(GLcint) :: ixDisp, iyDisp
ixDisp = ix - ixBegin
iyDisp = iy - iyBegin
SELECT CASE (mButton)
 CASE (GLUT_LEFT_BUTTON)
  azimuth   = azimuth   + ixDisp / 2.0_GLfloat
  elevation = elevation - iyDisp / 2.0_GLfloat
 CASE (GLUT_MIDDLE_BUTTON)
  cpoint(1, jcp, icp) = cpoint(1, jcp, icp) + ixDisp / 180.0_GLfloat
  cpoint(2, jcp, icp) = cpoint(2, jcp, icp) - iyDisp / 180.0_GLfloat
 CASE (GLUT_RIGHT_BUTTON)
  cpoint(3, jcp, icp) = cpoint(3, jcp, icp) + ixDisp / 180.0_GLfloat
!  distance = distance - iyDisp / 40.0_GLfloat
 CASE DEFAULT
END SELECT 
ixBegin = ix
iyBegin = iy
CALL glutPostRedisplay()
RETURN
END SUBROUTINE myMotion
!---------------------------------------------------------
SUBROUTINE myInit(progname)
IMPLICIT NONE
CHARACTER(LEN = *), INTENT(IN) :: progname
INTEGER(GLcint) :: iwidth = 400, iheight = 400
INTEGER(GLcint) :: iwin
CALL glutInitWindowPosition( 0_glfloat, 0_glfloat )
CALL glutInitWindowSize( iwidth, iheight )
CALL glutInitDisplayMode( IOR(IOR(GLUT_RGBA, GLUT_DEPTH), GLUT_DOUBLE) )
iwin = glutCreateWindow( progname )
CALL glClearColor( 0.0_glfloat, 0.0_glfloat, 0.0_glfloat, 1.0_glfloat )
CALL glutKeyboardFunc( myKbd )
CALL glutSpecialFunc( mySkey )
CALL glutMouseFunc( myMouse )
CALL glutMotionFunc( myMotion )
CALL resetview()
CALL glShadeModel( GL_SMOOTH )
CALL glEnable( GL_LIGHT0 )
RETURN
END SUBROUTINE myInit
!---------------------------------------------------------
SUBROUTINE myReshape(iwidth, iheight)
IMPLICIT NONE
INTEGER(glcint), INTENT(IN OUT) :: iwidth, iheight
REAL(GLDOUBLE) :: aspect 
aspect = REAL(iwidth, glfloat) / REAL(iheight, glfloat)
CALL glViewport( 0, 0, iwidth, iheight )
CALL glMatrixMode( GL_PROJECTION )
CALL glLoadIdentity()
CALL gluPerspective( fovy, aspect, xnear, farw )
CALL glMatrixMode( GL_MODELVIEW )
CALL glEnable( GL_MODELVIEW )
RETURN
END SUBROUTINE myReshape
!---------------------------------------------------------
SUBROUTINE polarview()
IMPLICIT NONE
CALL glTranslatef( 0.0_glfloat, 0.0_glfloat, -distance )
CALL glRotatef(-twist    , 0.0_glfloat, 0.0_glfloat, 1.0_glfloat )
CALL glRotatef(-elevation, 1.0_glfloat, 0.0_glfloat, 0.0_glfloat )
CALL glRotatef(-azimuth  , 0.0_glfloat, 1.0_glfloat, 0.0_glfloat )
RETURN
END SUBROUTINE polarview
!---------------------------------------------------------
SUBROUTINE resetview()
IMPLICIT NONE
distance  =   3.0_glfloat
twist     =   0.0_glfloat
elevation = -45.0_glfloat
azimuth   =  30.0_glfloat
RETURN
END SUBROUTINE resetview
!---------------------------------------------------------
SUBROUTINE printHelp()
IMPLICIT NONE
PRINT *
PRINT *, "*            z, x  key         ...   CP selection                 *"
PRINT *, "*     Middle Mouse Button Drag ... x, y position of CP change     *"
PRINT *, "*     Right Mouse Button Drag  ... z    position of CP change     *"
PRINT *, "*     <-  key   ...  zoom in                                      *"
PRINT *, "*     ->  key   ...  zoom out                                     *"
RETURN
END SUBROUTINE printHelp
!---------------------------------------------------------
END MODULE m_callback
!=========================================================
PROGRAM GLUT9
USE m_callback
IMPLICIT NONE
CALL glutInit()
CALL printHelp()
CALL myInit( 'GLUT9-2ex' )
CALL create_nurbs()
CALL glutReshapeFunc( myReshape )
CALL glutDisplayFunc( display )
CALL glutMainLoop()
STOP
END PROGRAM GLUT9