! In addition to modifications for the F and ELF90 subsets, rgb_colors was
! changed from glubyte to glfloat
module olympic_mod
use opengl_gl
use opengl_glu
use opengl_glut
implicit none
private
public :: fReshape, Key, visible, DrawScene, Init
private :: FillTorus, Clamp, MyRand, ReInit, Idle
integer , parameter , private :: &
XSIZE = 100 , &
YSIZE = 75 , &
RINGS = 5 , &
BLUERING = 0 , &
BLACKRING = 1 , &
REDRING = 2 , &
YELLOWRING = 3 , &
GREENRING = 4 , &
BLACK = 0 , &
RED = 1 , &
GREEN = 2 , &
YELLOW = 3 , &
BLUE = 4 , &
MAGENTA = 5 , &
CYAN = 6 , &
WHITE = 7
real (kind =glfloat), parameter , private :: BACKGROUND = 8 .0
integer , parameter , private :: double = kind (0 .0 _gldouble)
real , parameter , private :: M_PI = 3 .141592654
integer (kind =glenum), public :: rgb, doubleBuffer
!integer (kind =glubyte), private , dimension (0 :RINGS-1 ,0 :2 ) :: rgb_colors
real (kind =glfloat), private , dimension (0 :RINGS-1 ,0 :2 ) :: rgb_colors
integer (kind =glint), private , dimension (0 :RINGS-1 ) :: mapped_colors
real (kind =glfloat), private , dimension (0 :RINGS-1 ,0 :2 ) :: dests
real (kind =glfloat), private , dimension (0 :RINGS-1 ,0 :2 ) :: offsets
real (kind =glfloat), private , dimension (0 :RINGS-1 ) :: angs
real (kind =glfloat), private , dimension (0 :RINGS-1 ,0 :2 ) :: rotAxis
integer , private , dimension (0 :RINGS-1 ) :: iters
integer (kind =gluint), private :: theTorus
contains
subroutine FillTorus(rc, numc, rt, numt)
real , intent (in ) :: rc, rt
integer , intent (in ) :: numc, numt
integer :: i, j, k
real :: s, t
real (kind =glfloat) :: x, y, z
real :: pi, twopi
pi = M_PI
twopi = 2 * pi
do i = 0 , numc-1
call glbegin(GL_QUAD_STRIP)
do j = 0 , numt
do k = 1 , 0 , -1
s = modulo((i + k), numc) + 0 .5
t = modulo(j, numt)
x = cos(t * twopi / numt) * cos(s * twopi / numc)
y = sin(t * twopi / numt) * cos(s * twopi / numc)
z = sin(s * twopi / numc)
call glnormal3f(x, y, z)
x = (rt + rc * cos(s * twopi / numc)) * cos(t * twopi / numt)
y = (rt + rc * cos(s * twopi / numc)) * sin(t * twopi / numt)
z = rc * sin(s * twopi / numc)
call glvertex3f(x, y, z)
end do
end do
call glend()
end do
return
end subroutine FillTorus
function Clamp(iters_left,t) result(resClamp)
integer , intent (in ) :: iters_left
real , intent (in ) :: t
real :: resClamp
if (iters_left < 3 ) then
resClamp = 0 .0
else
resClamp = (iters_left - 2 ) * t / iters_left
end if
return
end function Clamp
subroutine MyRand(resMyRand)
real , intent (out ) :: resMyRand
real :: rval
call random_number(rval)
resMyRand = 10 .0 * (rval - 0 .5 )
return
end subroutine MyRand
subroutine ReInit()
integer :: i
real :: deviation, temp
call MyRand(deviation)
deviation = deviation / 2
deviation = deviation * deviation
do i = 0 , RINGS-1
call MyRand(offsets(i,0 ))
call MyRand(offsets(i,1 ))
call MyRand(offsets(i,2 ))
call MyRand(angs(i))
angs(i) = 260 .0 * angs(i)
call MyRand(rotAxis(i,0 ))
call MyRand(rotAxis(i,1 ))
call MyRand(rotAxis(i,2 ))
call MyRand(temp)
iters(i) = (deviation * temp + 60 .0 )
end do
return
end subroutine ReInit
subroutine Init()
real (kind =glfloat), save :: top_y = 1 .0
real (kind =glfloat), save :: bottom_y = 0 .0
real (kind =glfloat), save :: top_z = 0 .15
real (kind =glfloat), save :: bottom_z = 0 .69
real (kind =glfloat), save :: fspacing = 2 .5
real (kind =glfloat), save , dimension (4 ) :: lmodel_ambient = (/0 .0 , 0 .0 , 0 .0 , 0 .0 /)
real (kind =glfloat), save , dimension (1 ) :: lmodel_twoside = (/GL_FALSE/)
real (kind =glfloat), save , dimension (1 ) :: lmodel_local = (/GL_FALSE/)
real (kind =glfloat), save , dimension (4 ) :: light0_ambient = (/0 .1 , 0 .1 , 0 .1 , 1 .0 /)
real (kind =glfloat), save , dimension (4 ) :: light0_diffuse = (/1 .0 , 1 .0 , 1 .0 , 0 .0 /)
real (kind =glfloat), save , dimension (4 ) :: light0_position = (/0 .8660254 , 0 .5 , 1 .0 , 0 .0 /)
real (kind =glfloat), save , dimension (4 ) :: light0_specular = (/1 .0 , 1 .0 , 1 .0 , 0 .0 /)
real (kind =glfloat), save , dimension (4 ) :: bevel_mat_ambient = (/0 .0 , 0 .0 , 0 .0 , 1 .0 /)
real (kind =glfloat), save , dimension (1 ) :: bevel_mat_shininess = (/40 .0 /)
real (kind =glfloat), save , dimension (4 ) :: bevel_mat_specular = (/1 .0 , 1 .0 , 1 .0 , 0 .0 /)
real (kind =glfloat), save , dimension (4 ) :: bevel_mat_diffuse = (/1 .0 , 0 .0 , 0 .0 , 0 .0 /)
call random_seed()
call ReInit()
! changed for glfloat rgb_colors
rgb_colors = 0 .0 _glfloat
rgb_colors(BLUERING,2 ) = 1 .0 _glfloat
rgb_colors(REDRING,0 ) = 1 .0 _glfloat
rgb_colors(GREENRING,1 ) = 1 .0 _glfloat
rgb_colors(YELLOWRING,0 ) = 1 .0 _glfloat
rgb_colors(YELLOWRING,1 ) = 1 .0 _glfloat
mapped_colors(BLUERING) = BLUE
mapped_colors(REDRING) = RED
mapped_colors(GREENRING) = GREEN
mapped_colors(YELLOWRING) = YELLOW
mapped_colors(BLACKRING) = BLACK
dests(BLUERING,:) = (/-fspacing, top_y, top_z/)
dests(BLACKRING,:) = (/0 .0 , top_y, top_z/)
dests(REDRING,:) = (/fspacing, top_y, top_z/)
dests(YELLOWRING,:) = (/-fspacing / 2 .0 , bottom_y, bottom_z/)
dests(GREENRING,:) = (/fspacing / 2 .0 , bottom_y, bottom_z/)
theTorus = glgenlists(1 )
call glnewlist(theTorus, GL_COMPILE)
call FillTorus(0 .1 , 8 , 1 .0 , 25 )
call glendlist()
call glenable(GL_CULL_FACE)
call glcullface(GL_BACK)
call glenable(GL_DEPTH_TEST)
call glcleardepth(1 .0 _glclampd)
if (rgb == GL_TRUE) then
call glclearcolor(0 .5 _glclampf, 0 .5 _glclampf, 0 .5 _glclampf, 0 .0 _glclampf)
call gllightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient)
call gllightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse)
call gllightfv(GL_LIGHT0, GL_SPECULAR, light0_specular)
call gllightfv(GL_LIGHT0, GL_POSITION, light0_position)
call glenable(GL_LIGHT0)
call gllightmodelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_local)
call gllightmodelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside)
call gllightmodelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient)
call glenable(GL_LIGHTING)
call glmaterialfv(GL_FRONT, GL_AMBIENT, bevel_mat_ambient)
call glmaterialfv(GL_FRONT, GL_SHININESS, bevel_mat_shininess)
call glmaterialfv(GL_FRONT, GL_SPECULAR, bevel_mat_specular)
call glmaterialfv(GL_FRONT, GL_DIFFUSE, bevel_mat_diffuse)
call glcolormaterial(GL_FRONT_AND_BACK, GL_DIFFUSE)
call glenable(GL_COLOR_MATERIAL)
call glshademodel(GL_SMOOTH)
else
call glclearindex(BACKGROUND)
call glshademodel(GL_FLAT)
end if
call glmatrixmode(GL_PROJECTION)
call gluperspective(45 .0 _gldouble, 1 .33 _gldouble, 0 .1 _gldouble, 100 .0 _gldouble)
call glmatrixmode(GL_MODELVIEW)
return
end subroutine Init
subroutine Idle()
integer :: i, j
integer (kind =glenum), save :: more = GL_FALSE
do i = 0 , RINGS-1
if (iters(i) /= 0 ) then
do j = 0 , 2
offsets(i,j) = Clamp(iters(i), offsets(i,j))
end do
angs(i) = Clamp(iters(i), angs(i))
iters(i) = iters(i) - 1
more = GL_TRUE
end if
end do
if (more == GL_TRUE) then
call glutpostredisplay()
else
call glutidlefunc()
end if
return
end subroutine Idle
subroutine fReshape(width,height)
integer (kind =glcint), intent (in out ) :: width, height
! if glcint is not the same as glsizei, width and height will
! need to be copied to variables of the later kind
call glviewport(0 _glint, 0 _glint, width, height)
return
end subroutine fReshape
subroutine Key(ikey, x, y)
integer (kind =glcint), intent (in out ) :: ikey, x, y
select case (ikey)
case (27 ) ! esc
stop
case (ichar(" " ))
call ReInit()
call glutidlefunc(Idle)
end select
return
end subroutine Key
! fortran handling of command line arguments is nonstandard, so
! this feature is omitted. Here is the original C code.
!GLenum
!Args(int argc, char **argv)
!{
! GLint i;
!
! rgb = GL_TRUE;
! doubleBuffer = GL_TRUE;
!
! for (i = 1 ; i < argc; i++) {
! if (strcmp(argv[i], "-ci" ) == 0 ) {
! rgb = GL_FALSE;
! } else if (strcmp(argv[i], "-rgb" ) == 0 ) {
! rgb = GL_TRUE;
! } else if (strcmp(argv[i], "-sb" ) == 0 ) {
! doubleBuffer = GL_FALSE;
! } else if (strcmp(argv[i], "-db" ) == 0 ) {
! doubleBuffer = GL_TRUE;
! } else {
! printf("%s (Bad option).\n" , argv[i]);
! return GL_FALSE;
! }
! }
! return GL_TRUE;
!}
subroutine visible(vis)
integer (kind =glcint), intent (in out ) :: vis
if (vis == GLUT_VISIBLE) then
call glutidlefunc(Idle)
else
call glutidlefunc()
end if
return
end subroutine visible
subroutine DrawScene()
integer :: i
call glpushmatrix()
call glclear(ior(GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT))
call glulookat(0 .0 _gldouble, 0 .0 _gldouble, 10 .0 _gldouble, &
0 .0 _gldouble, 0 .0 _gldouble, 0 .0 _gldouble, &
0 .0 _gldouble, 1 .0 _gldouble, 0 .0 _gldouble)
do i = 0 , RINGS-1
if (rgb == GL_TRUE) then
! call glcolor3ubv(rgb_colors(i,:))
call glcolor3fv(rgb_colors(i,:))
else
call glindexi(mapped_colors(i))
end if
call glpushmatrix()
call gltranslatef(dests(i,0 ) + offsets(i,0 ), dests(i,1 ) + offsets(i,1 ), &
dests(i,2 ) + offsets(i,2 ))
call glrotatef(angs(i), rotAxis(i,0 ), rotAxis(i,1 ), rotAxis(i,2 ))
call glcalllist(theTorus)
call glpopmatrix()
end do
call glpopmatrix()
if (doubleBuffer == GL_TRUE) then
call glutswapbuffers()
else
call glflush()
end if
return
end subroutine DrawScene
end module olympic_mod
program main
use opengl_gl
use opengl_glu
use opengl_glut
use olympic_mod
implicit none
integer (kind =glenum) :: ftype
integer :: i
call glutinitwindowsize(400 _glcint, 300 _glcint)
! not checking command line arguments
! glutInit(&argc, argv);
! if (Args(argc, argv) == GL_FALSE) {
! exit (1 );
! }
call glutinit()
rgb = GL_TRUE ! default values which could have been
doubleBuffer = GL_TRUE ! overwritten by command line arguments
if (rgb == GL_TRUE) then
ftype = GLUT_RGB
else
ftype = GLUT_INDEX
end if
if (doubleBuffer == GL_TRUE) then
ftype = ior(ftype,GLUT_DOUBLE)
else
ftype = ior(ftype,GLUT_SINGLE)
end if
call glutinitdisplaymode(ftype)
i = glutcreatewindow("Olympic" )
call Init()
call glutreshapefunc(fReshape)
call glutkeyboardfunc(Key)
call glutdisplayfunc(DrawScene)
call glutvisibilityfunc(visible)
call glutmainloop()
stop
end program main
Messung V0.5 in Prozent C=100 H=93 G=96
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-13)
¤
*© Formatika GbR, Deutschland