fortran66のブログ

fortran について書きます。

OpenGLによる3次元CGプログラミング
作者: 林武文, 加藤清敬
出版社/メーカー: コロナ社


MODULE m_callback
USE opengl_gl
USE opengl_glu
USE opengl_glut
IMPLICIT NONE
INTEGER(GLCINT), PARAMETER :: KEY_ESC = 27
LOGICAL :: wireFlag = GL_TRUE, revolveFlag = GL_FALSE
INTEGER(GLCINT) :: ixBegin, iyBegin, mButton
REAL(glfloat) :: distance, twist, elevation, azimuth
REAL(glfloat) :: theta = 15.0_glfloat
REAL(glfloat) :: rColor = 1.0_glfloat, gColor = 1.0_glfloat, bColor = 1.0_glfloat
CONTAINS
!---------------------------
SUBROUTINE display()
IMPLICIT NONE
CALL glClear( GL_COLOR_BUFFER_BIT )
CALL glPushMatrix()
CALL polarview()
CALL glRotatef( theta, 0.0_glfloat, 1.0_glfloat, 0.0_glfloat )
CALL glColor3f( rColor, gColor, bColor )
IF (wireFlag == GL_TRUE) THEN
 CALL glutWireCube( 1.0_gldouble )
ELSE
 CALL glutSolidCube( 1.0_gldouble )
END IF
CALL glPopMatrix()
CALL glutSwapBuffers()
RETURN
END SUBROUTINE display
!---------------------------
SUBROUTINE idle()
IMPLICIT NONE
theta = AMOD(theta + 0.05_glfloat, 360.0_glfloat)
CALL glutPostRedisplay()
RETURN
END SUBROUTINE idle
!---------------------------
SUBROUTINE myKbd(key, ix, iy)
IMPLICIT NONE
INTEGER(GLCINT), INTENT(IN OUT) :: key, ix, iy
SELECT CASE(key)
 CASE (ICHAR('w'))
 wireFlag = .NOT. wireFlag
 CASE (ICHAR('R'))
 CALL resetview()
 CASE (KEY_ESC)
 STOP
 CASE DEFAULT
 CONTINUE
END SELECT
CALL glutPostRedisplay()
RETURN
END SUBROUTINE myKbd
!---------------------------
SUBROUTINE myMouse(ibutton, istate, ix, iy)
IMPLICIT NONE
INTEGER, INTENT(IN OUT) :: ibutton, ix, iy
LOGICAL, INTENT(IN OUT) :: istate
IF (istate == GLUT_DOWN) THEN
 SELECT CASE(ibutton)
 CASE (GLUT_LEFT_BUTTON)
  mButton = ibutton
 CASE (GLUT_MIDDLE_BUTTON)
  revolveFlag = .NOT. revolveFlag
  IF (revolveFlag) THEN
   CALL glutIdleFunc( idle )
  ELSE
   CALL glutIdleFunc( 0 )
  END IF
 CASE (GLUT_RIGHT_BUTTON)

 CASE DEFAULT
  CONTINUE
 END SELECT
 ixBegin = ix
 iyBegin = iy
END IF
RETURN
END SUBROUTINE myMouse
!---------------------------
SUBROUTINE myMotion(ix, iy)
IMPLICIT NONE
INTEGER, INTENT(IN) :: ix, iy
INTEGER :: 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)
 CALL changeColor()
 CASE (GLUT_RIGHT_BUTTON)
 distance = distance + iyDisp / 40.0_glfloat
 CASE DEFAULT
 CONTINUE
END SELECT
ixBegin = ix
iyBegin = iy
CALL glutPostRedisplay()
RETURN
END SUBROUTINE myMotion
!---------------------------
SUBROUTINE changeColor()
IMPLICIT NONE
CALL RANDOM_NUMBER(rColor)
CALL RANDOM_NUMBER(gColor)
CALL RANDOM_NUMBER(bColor)
RETURN
END SUBROUTINE changeColor
!---------------------------
SUBROUTINE resetview()
IMPLICIT NONE
distance  = 5.0_glfloat
twist     = 0.0_glfloat
elevation = 0.0_glfloat
azimuth   = 0.0_glfloat
RETURN
END SUBROUTINE resetview
!---------------------------
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
!---------------------------
END MODULE m_callback
!=========================================================
MODULE m_subs
USE m_callback
IMPLICIT NONE
CONTAINS
!---------------------------
SUBROUTINE myInit(progname)
IMPLICIT NONE
CHARACTER(LEN = *), INTENT(IN) :: progname
INTEGER(GLCINT) :: iwidth = 600, iheight = 600
INTEGER(GLCINT) :: iwin
REAL(GLDOUBLE) :: aspect
aspect = REAL(iwidth, glfloat) / REAL(iheight, glfloat)
CALL glutInitWindowPosition( 0_glfloat, 0_glfloat )
CALL glutInitWindowSize( iwidth, iheight )
CALL glutInitDisplayMode( IOR(GLUT_RGBA, GLUT_DOUBLE) )
iwin = glutCreateWindow( progname )
CALL glClearColor( 0.0_glfloat, 0.0_glfloat, 0.0_glfloat, 1.0_glfloat )
!
CALL glutKeyboardFunc( myKbd )
CALL glutMouseFunc( myMouse )
CALL glutMotionFunc( myMotion )
!
CALL resetview()
!
CALL glMatrixMode( GL_PROJECTION )
CALL glLoadIdentity()
CALL gluPerspective( 45.0_gldouble, aspect, 1.0_gldouble, 20.0_gldouble )
CALL glMatrixMode( GL_MODELVIEW )
RETURN
END SUBROUTINE myInit
!---------------------------
END MODULE m_subs
!=========================================================
PROGRAM GLUT5
USE m_subs
IMPLICIT NONE
CALL glutInit()
CALL myInit( 'GLUT5-2' )
CALL glutDisplayFunc( display )
CALL glutMainLoop()
STOP
END PROGRAM GLUT5