! 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 subroutine 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
! call view_modifier_init(menuid)
! 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.
use opengl_gl use opengl_glu use opengl_glut implicitnone private public :: view_modifier_init, reset_view public :: display ! TEMP -- see comments immediately after this module private :: cart2sphere, sphere2cart, cart3D_plus_cart3D, cart3D_minus_cart3D, &
reset_to_init, mouse, motion, arrows, &
menu_handler, set_left_button, set_middle_button, set_arrow_keys, &
operator(+), operator(-)
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 + 0.002_gldouble*(begin%y-y)) elseif (y > begin%y) then
factor = 1.0_gldouble + 0.002_gldouble*(y-begin%y) else
factor = 1.0_gldouble endif
shift%z = factor*shift%z case (PAN)
shift%x = shift%x + 0.01*(x - begin%x)
shift%y = shift%y - 0.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 + 0.002_gldouble*(begin%y-y) elseif (y > begin%y) then
factor = 1.0_gldouble/(1.0_gldouble + 0.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 + 0.002_gldouble*(begin%y-y) elseif (y > begin%y) then
factor = 1.0_gldouble/(1.0_gldouble + 0.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 + 0.002_gldouble*(begin%y-y) elseif (y > begin%y) then
factor = 1.0_gldouble/(1.0_gldouble + 0.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
! This is a simple programto demonstrate the use of the view_modifier module
! It consists of a module with the callback functions and a main program.
! The F compiler on Linux complained about not finding this module. Because
! of lack of time I'm just going to move subroutine display to the
! view_modifier module instead of tracking down the problem.
!module view_demo_callbacks
!use opengl_gl
!use opengl_glut
!use view_modifier
!private
!public :: display
!
!contains
!
!subroutine display()
!
!! This gets called when the display needs to be redrawn
!
!call reset_view()
!
!call glclear(ior(GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT))
!call glcalllist(1)
!call glutswapbuffers()
!
!return
!endsubroutine display
!
!endmodule view_demo_callbacks
program view_demo
use opengl_gl use opengl_glut use view_modifier
!use view_demo_callbacks implicitnone
! 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.