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
INTEGER(GLCINT), PARAMETER :: imageWidth = 64, imageHeight = 64
!
INTEGER(GLint) :: ixBegin = 0, iyBegin = 0
REAL(GLfloat) :: xOrigin = 0.0_GLfloat, yOrigin = 0.0_GLfloat
REAL(GLfloat) :: distance, twist, elevation, azimuth
REAL(GLdouble) :: dnearw = 1.0_gldouble, farw = 20.0_gldouble, fovy = 60.0_gldouble
INTEGER(GLint) :: mbutton
REAL(GLfloat) :: tval = 0.0_GLfloat
INTEGER(GLint) :: texname(1) = 1
INTEGER(GLbyte) :: image(4, imageWidth, imageHeight)
!
CONTAINS
!---------------------------------------------------------
SUBROUTINE makeImage()
IMPLICIT NONE
INTEGER(GLint) :: i, j, icolor
CALL glBindTexture(GL_TEXTURE_2D, texname(1))
DO i = 1, imageHeight
 DO j = 1, imageWidth
  icolor = IOR( IAND(i, Z'8'), IAND(j, Z'8') ) * 255
  image(1, j, i) = INT(icolor, GLbyte)
  image(2, j, i) = INT(icolor, GLbyte)
  image(3, j, i) =   0_GLbyte
  image(4, j, i) = 100_GLbyte
 END DO
END DO
CALL glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
CALL glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
CALL glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
CALL glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
CALL glTexImage2D(GL_TEXTURE_2D, 0, 4, imageWidth, imageHeight, 0,      &
                   GL_RGBA, GL_UNSIGNED_BYTE, image(:, 1, 1) ) ! pointer
CALL glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
RETURN
END SUBROUTINE makeImage
!---------------------------------------------------------
SUBROUTINE display()
IMPLICIT NONE
REAL(glfloat) :: diffuse(4)  = (/ 0.0_glfloat, 0.0_glfloat, 1.0_glfloat, 1.0_glfloat /)
REAL(glfloat) :: specular(4) = (/ 1.0_glfloat, 1.0_glfloat, 1.0_glfloat, 1.0_glfloat /)
REAL(glfloat) :: ambient(4)  = (/ 0.1_glfloat, 0.1_glfloat, 0.1_glfloat, 1.0_glfloat /)
CALL glClear( IOR(GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT) )
CALL glPushMatrix()
CALL polarview( )
CALL glEnable( GL_DEPTH_TEST )
!
CALL glMaterialfv( GL_FRONT, GL_DIFFUSE  , diffuse   ) 
CALL glMaterialfv( GL_FRONT, GL_SPECULAR , specular  )
CALL glMaterialfv( GL_FRONT, GL_AMBIENT  , ambient   )
CALL glMaterialf ( GL_FRONT, GL_SHININESS, 128.0_glfloat )
CALL glEnable( GL_LIGHTING )
!
CALL glTranslatef( 0.0_GLfloat, 0.6_GLfloat, 0.0_GLfloat )
CALL glutSolidTeapot(1.0_GLdouble)
CALL glPopMatrix()
!
CALL glDisable( GL_LIGHTING  )
CALL glDIsable( GL_DEPTH_TEST )
CALL glutSwapBuffers() 
RETURN
END SUBROUTINE display
!---------------------------------------------------------
SUBROUTINE SetupTextures()
IMPLICIT NONE
CALL glPixelStorei( GL_UNPACK_ALIGNMENT, 1 )
CALL makeImage()
!CALL glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR )
!CALL glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR )
!CALL glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR )
!CALL glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR )
CALL glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP )
CALL glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP )
CALL glEnable( GL_TEXTURE_GEN_S )
CALL glEnable( GL_TEXTURE_GEN_T )
CALL glEnable( GL_TEXTURE_2D    )
RETURN
END SUBROUTINE SetupTextures
!---------------------------------------------------------
SUBROUTINE DeleteTextures()
IMPLICIT NONE
CALL glDeleteTextures( 1, texname )
RETURN
END SUBROUTINE DeleteTextures
!---------------------------------------------------------
SUBROUTINE myKbd(key, ix, iy)
IMPLICIT NONE
INTEGER(GLint), INTENT(IN OUT) :: key, ix, iy
SELECT CASE(key)
 CASE (KEY_ESC)
  CALL DeleteTextures() 
  STOP
 CASE DEFAULT
  CONTINUE
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)
  twist = AMOD( twist + ixDisp, 360.0_GLfloat )
 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 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 glutMouseFunc( myMouse )
CALL glutMotionFunc( myMotion )
CALL resetview()
CALL SetupTextures()
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, dnearw, farw )
CALL glMatrixMode( 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  =   5.0_glfloat
twist     =   0.0_glfloat
elevation = -45.0_glfloat
azimuth   =  30.0_glfloat
RETURN
END SUBROUTINE resetview
!---------------------------------------------------------
SUBROUTINE idle()
IMPLICIT NONE
LOGICAL, SAVE :: tflag = .FALSE.
IF (tflag) THEN 
 tval = tval - 0.05_GLfloat
 IF (tval < 0.0_GLfloat) tflag = .FALSE.
ELSE
 tval = tval + 0.05_GLfloat
 IF (tval < 0.2_GLfloat) tflag = .TRUE.
END IF
CALL glutPostRedisplay()
RETURN
END SUBROUTINE idle
!---------------------------------------------------------
END MODULE m_callback
!=========================================================
PROGRAM GLUT8
USE m_callback
IMPLICIT NONE
CALL glutInit()
CALL myInit( 'GLUT8-3' )
CALL glutReshapeFunc( myReshape )
CALL glutDisplayFunc( display )
CALL glutIdleFunc( idle )
CALL glutMainLoop()
STOP
END PROGRAM GLUT8