! This module provides facilities to modify the view in an OpenGL window.
! The mouse buttons and keyboard arrow keys can be used to zoom, pan,
! rotate and change the scale. A menu or submenu can be used toselect which
! buttons perform which function and to reset the view to the initial settings.
! This is limited to one window.
! William F. Mitchell
! william.mitchell@nist.gov
! Mathematical and Computational Sciences Division
! National Institute of Standards and Technology
! April, 1998
! Touse this module:
!
! 1) put a USE view_modifier statement in any programunit that calls a
! procedurein this module
!
! 2) set the initial operation assignments, view and scale below the
! "Initial configuration" comment below
!
! 3) call view_modifier_init after glutCreateWindow
! This is a function that returns integer(kind=glcint) menuid. The menuid
! is the ID returned by glutCreateMenu. You can either use the view_modifier
! menu as your menu by calling glutAttachMenu immediately after
! view_modifier_init, as in
! menuid = view_modifier_init()
! call glutAttachMenu(GLUT_RIGHT_BUTTON)
! or by using the menuid to attach a submenu to your own menu, as in
! call glutAddSubMenu("View Modifier",menuid)
!
! 4) in any callback functions that update the display, put
! call reset_view
! as the first executable statement
!
! Note that view_modifier_init sets the callback functions for glutMouseFunc,
! glutMotionFunc and glutSpecialFunc, so don't call these yourself
!
! The menu allows you toselect what operation is attached to the left and
! middle mouse buttons and arrow keys, reset to the initial view, and quit.
! The right mouse button should be used for the menu.
type(cart2D), save :: angle type(cart3D), save :: shift real(kind=gldouble), save :: xscale_factor, yscale_factor, zscale_factor logical, save :: moving_left, moving_middle type(cart2D), save :: begin_left, begin_middle
if (button == GLUT_LEFT_BUTTON .and. state == GLUT_DOWN) then
moving_left = .true.
begin_left = cart2D(x,y) endif if (button == GLUT_LEFT_BUTTON .and. state == GLUT_UP) then
moving_left = .false. endif if (button == GLUT_MIDDLE_BUTTON .and. state == GLUT_DOWN) then
moving_middle = .true.
begin_middle = cart2D(x,y) endif if (button == GLUT_MIDDLE_BUTTON .and. state == GLUT_UP) then
moving_middle = .false. endif endsubroutine mouse
integer :: button_function type(cart2D) :: begin real(kind=gldouble) :: factor
! Determine and apply the button function
if (moving_left) then
button_function = left_button_func
begin = begin_left elseif(moving_middle) then
button_function = middle_button_func
begin = begin_middle endif
selectcase(button_function) case (ZOOM) if (y < begin%y) then
factor = 1.0_gldouble/(1.0_gldouble + .002_gldouble*(begin%y-y)) elseif (y > begin%y) then
factor = 1.0_gldouble + .002_gldouble*(y-begin%y) else
factor = 1.0_gldouble endif
shift%z = factor*shift%z case (PAN)
shift%x = shift%x + .01*(x - begin%x)
shift%y = shift%y - .01*(y - begin%y) case (ROTATE)
angle%x = angle%x + (x - begin%x)
angle%y = angle%y + (y - begin%y) case (SCALEX) if (y < begin%y) then
factor = 1.0_gldouble + .002_gldouble*(begin%y-y) elseif (y > begin%y) then
factor = 1.0_gldouble/(1.0_gldouble + .002_gldouble*(y-begin%y)) else
factor = 1.0_gldouble endif
xscale_factor = xscale_factor * factor case (SCALEY) if (y < begin%y) then
factor = 1.0_gldouble + .002_gldouble*(begin%y-y) elseif (y > begin%y) then
factor = 1.0_gldouble/(1.0_gldouble + .002_gldouble*(y-begin%y)) else
factor = 1.0_gldouble endif
yscale_factor = yscale_factor * factor case (SCALEZ) if (y < begin%y) then
factor = 1.0_gldouble + .002_gldouble*(begin%y-y) elseif (y > begin%y) then
factor = 1.0_gldouble/(1.0_gldouble + .002_gldouble*(y-begin%y)) else
factor = 1.0_gldouble endif
zscale_factor = zscale_factor * factor endselect
! update private variables and redisplay
if (moving_left) then
begin_left = cart2D(x,y) elseif(moving_middle) then
begin_middle = cart2D(x,y) endif
if (moving_left .or. moving_middle) then call glutPostRedisplay endif
! rotate so the z-axis comes out the top, x-axis out the spout call glRotated(90.0_gldouble,1.0_gldouble,0.0_gldouble,0.0_gldouble) call glMaterialfv(GL_FRONT, GL_AMBIENT, ambient) call glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse) call glMaterialfv(GL_FRONT, GL_SPECULAR, specular) call glMaterialf(GL_FRONT, GL_SHININESS, 25.6_glfloat) call glutSolidTeapot(1.0_gldouble)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.