!! Copyright (C) Stichting Deltares, 2005-2014. !! !! This file is part of iMOD. !! !! This program is free software: you can redistribute it and/or modify !! it under the terms of the GNU General Public License as published by !! the Free Software Foundation, either version 3 of the License, or !! (at your option) any later version. !! !! This program is distributed in the hope that it will be useful, !! but WITHOUT ANY WARRANTY; without even the implied warranty of !! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !! GNU General Public License for more details. !! !! You should have received a copy of the GNU General Public License !! along with this program. If not, see . !! !! Contact: imod.support@deltares.nl !! Stichting Deltares !! P.O. Box 177 !! 2600 MH Delft, The Netherlands. !! MODULE MOD_3D_DISPLAY USE IMODVAR, ONLY : IDIAGERROR USE MODPLOT, ONLY : MP USE MOD_UTL, ONLY : UTL_MESSAGEHANDLE3D,UTL_MESSAGEHANDLE,RTOS,UTL_WSELECTFILE USE MOD_IDF, ONLY : IDFDEALLOCATE USE MOD_3D_PAR USE MOD_3D_UTL, ONLY : IMOD3D_SETCOLOR,IMOD3D_RETURNCOLOR,IMOD3D_GETCOLOR USE MOD_IPF_PAR, ONLY : ASSF CONTAINS !###====================================================================== SUBROUTINE IMOD3D_DISPLAY(IMODE) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IMODE REAL(KIND=GLFLOAT) :: XR,XG,XB INTEGER :: I,IR,IG,IB,J REAL(KIND=GLDOUBLE) :: Z INTEGER(GLINT) :: IVIEWPORT(4) TYPE (SPHERE3D) :: SLOOKFROM LOGICAL(GLBOOLEAN) :: LRED,LGREEN,LBLUE,LALPHA CALL IMOD3D_ERROR('IMOD3D_DISPLAY_ENTRY') IF(IMODE.EQ.1)THEN CALL GLENABLE(GL_DITHER) !## antialiasing points CALL GLENABLE(GL_POINT_SMOOTH) !## antialiasing lines CALL GLENABLE(GL_LINE_SMOOTH) !## enable blending - aliasing werkt (nog) niet voor polygonen... komt door ontbreken alpha factor! CALL GLENABLE(GL_BLEND) !## fastest mode CALL GLHINT(GL_POINT_SMOOTH_HINT,GL_FASTEST) !## fastest mode CALL GLHINT(GL_LINE_SMOOTH_HINT,GL_FASTEST) !## select mode --- force plotting idf/iff/gen/axes with color zero! ELSEIF(IMODE.EQ.2)THEN CALL GLDISABLE(GL_POINT_SMOOTH) CALL GLDISABLE(GL_LINE_SMOOTH) CALL GLDISABLE(GL_POLYGON_SMOOTH) CALL GLDISABLE(GL_BLEND) CALL GLDISABLE(GL_DITHER) ENDIF !## set light at position "pos" --- stationary CALL GLMATRIXMODE(GL_MODELVIEW) CALL GLPOPMATRIX() !## pops off the top matrix second-from-the top becomes the top CALL GLPUSHMATRIX() !## pushes all matrices in the current stack down one level, topmost is copied CALL GLLIGHTFV(GL_LIGHT0,GL_POSITION,POS) DO J=1,IANAGLYPHS+1 !## set right image if anaglyphs are active IF(J.EQ.2)CALL IMOD3D_ANAGLYPHS() !## set modelview matrix CALL IMOD3D_RESET_VIEW() !## set background CALL WRGBSPLIT(BGCOLOR,IR,IG,IB) XR=REAL(IR)/255.0_GLFLOAT; XG=REAL(IG)/255.0_GLFLOAT; XB=REAL(IB)/255.0_GLFLOAT CALL GLCLEARCOLOR(XR,XG,XB,0.0_GLFLOAT) CALL GLCOLORMASK(.TRUE._GLBOOLEAN,.TRUE._GLBOOLEAN,.TRUE._GLBOOLEAN,.TRUE._GLBOOLEAN) CALL GLCLEAR(IOR(GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT)) !## clear color and depth buffer each time a drawing is drawn IF(IANAGLYPHS.EQ.1)THEN IF(J.EQ.1)THEN LRED= .FALSE._GLBOOLEAN !## do not write red buffer LGREEN= .TRUE._GLBOOLEAN !## do write green buffer ELSE LRED= .TRUE._GLBOOLEAN !## do write red buffer LGREEN= .FALSE._GLBOOLEAN !## do not write green buffer ENDIF ELSE LRED= .TRUE._GLBOOLEAN !## do write red buffer LGREEN= .TRUE._GLBOOLEAN !## do write green buffer ENDIF LBLUE =.TRUE._GLBOOLEAN LALPHA=.TRUE._GLBOOLEAN CALL GLCOLORMASK(LRED,LGREEN,LBLUE,LALPHA) DO I=1,NCLPLIST IF(CLPPLOT(I)%ISEL.EQ.1)THEN CALL GLENABLE(CLPPLANES(I)) CALL GLPUSHMATRIX() CALL GLTRANSLATED(CLPPLOT(I)%X,CLPPLOT(I)%Y,CLPPLOT(I)%Z) CALL GLCLIPPLANE(CLPPLANES(I),CLPPLOT(I)%EQN) CALL GLPOPMATRIX() ELSE CALL GLDISABLE(CLPPLANES(I)) ENDIF END DO !## draw idf's - last cause antialiasing and blending not for polygons IF(NIDFLIST.GT.0)CALL IMOD3D_DISPLAY_IDF(IMODE) !## draw ipf-drills/points IF(NIPFLIST.GT.0)CALL IMOD3D_DISPLAY_IPF(IMODE) !## draw iff's IF(NIFFLIST.GT.0)CALL IMOD3D_DISPLAY_IFF() !## draw sol's IF(NSOLLIST.GT.0)CALL IMOD3D_DISPLAY_SOL() !## draw gen's IF(NGENLIST.GT.0)CALL IMOD3D_DISPLAY_GEN() DO I=1,NCLPLIST; CALL GLDISABLE(CLPPLANES(I)); END DO !## draw axes,roundbox IF(IMODE.EQ.1.AND.IBNDBOX.EQ.1)THEN CALL GLBLENDFUNC(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) !## (1) source (2) destination !## draw filled background in gl_cull_face mode CALL IMOD3D_SETCOLOR(BCOLOR) CALL GLLINEWIDTH(1.0_GLFLOAT) !## draw box IF(AXESINDEX(1).GT.0)CALL GLCALLLIST(AXESINDEX(1)) !## draw axes IF(AXESINDEX(2).GT.0)CALL GLCALLLIST(AXESINDEX(2)) ENDIF !## draw axes text,roundbox IF(IMODE.EQ.1.AND.IAXES.EQ.1)THEN CALL GLBLENDFUNC(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) !## (1) source (2) destination !## draw labels CALL IMOD3D_SETCOLOR(ACOLOR) IF(AXESINDEX(3).GT.0)CALL GLCALLLIST(AXESINDEX(3)) ENDIF !## plot and update indentifier-position IF(IINDPOS.EQ.1)THEN CALL IMOD3D_PLOT_INDPOS() ENDIF !## draw bmp CALL IMOD3D_DISPLAY_BMP() ENDDO !## draw axes,roundbox IF(IORIENT.EQ.1)THEN CALL GLMATRIXMODE(GL_MODELVIEW) CALL GLPOPMATRIX() !## pops off the top matrix second-from-the top becomes the top CALL GLPUSHMATRIX() !## pushes all matrices in the current stack down one level, topmost is copied !## lookat is the coordinate 0,0,0 !## lookfrom is the coordinate 10,-20,5 !## scale factors 1,1,1 SLOOKFROM=CART2SPHERE(LOOKFROM-LOOKAT) Z =INIT_SHIFTZ-SLOOKFROM%RHO !## displacement in the left-corner CALL GLTRANSLATED(-2.0_GLDOUBLE,-2.0_GLDOUBLE,-2.0_GLDOUBLE) !## no moving and/or zooming CALL GLTRANSLATED(0.0_GLDOUBLE,0.0_GLDOUBLE,Z) !%z affected by zoom CALL GLROTATED(ANGLE%X, 0.0_GLDOUBLE, 0.0_GLDOUBLE, 1.0_GLDOUBLE) CALL GLROTATED(ANGLE%Y, COS(PI*ANGLE%X/180.0_GLDOUBLE), & -SIN(PI*ANGLE%X/180.0_GLDOUBLE), 0.0_GLDOUBLE) CALL GLTRANSLATED(-LOOKAT%X, -LOOKAT%Y, -LOOKAT%Z) CALL IMOD3D_SETCOLOR(OCOLOR) CALL GLLINEWIDTH(1.0_GLFLOAT) CALL GLCALLLIST(ORIENTINDEX) ENDIF CALL IMOD3D_DISPLAY_LEGEND() !## show buffer only in imode.eq.1, other mode will be used for selecting in false-colour mode IF(IMODE.EQ.1)CALL WGLSWAPBUFFERS() CALL GLMATRIXMODE(GL_PROJECTION) CALL GLLOADIDENTITY() IF(IORTHO.EQ.0)THEN CALL GLUPERSPECTIVE(FOVY,RAT,ZNEAR,ZFAR) !## angle(fovy), aspect (ratio:w/h), near () and far() ELSE CALL GLORTHO(ZLEFT,ZRIGHT,ZBOTTOM,ZTOP,ZNEAR,ZFAR) ENDIF CALL IMOD3D_ERROR('IMOD3D_DISPLAY') END SUBROUTINE IMOD3D_DISPLAY !###====================================================================== SUBROUTINE IMOD3D_PLOT_INDPOS() !###====================================================================== IMPLICIT NONE REAL(KIND=GLFLOAT) :: X1,X2,Y1,Y2,Z1,Z2 X1=-XYZAXES(1) X2= XYZAXES(1) Y1=-XYZAXES(2) Y2= XYZAXES(2) Z1= BOT%Z Z2= TOP%Z !## plot lookat-point, midpos CALL GLPOINTSIZE(5.0_GLFLOAT) CALL GLBEGIN(GL_POINTS) CALL IMOD3D_SETCOLOR(WRGB(0,255,0)) IF(INDPOS%X.EQ.0.0_GLFLOAT.AND.INDPOS%Y.EQ.0.0_GLFLOAT.AND.INDPOS%Z.EQ.0.0_GLFLOAT)THEN INDPOS%X=LOOKAT%X; INDPOS%Y=LOOKAT%Y; INDPOS%Z=LOOKAT%Z ENDIF CALL IMOD3D_SETTINGSPUT_INDPOS() CALL GLVERTEX3F(INDPOS%X,INDPOS%Y,INDPOS%Z) CALL GLEND() CALL IMOD3D_SETCOLOR(WRGB(0,200,0)) CALL GLLINEWIDTH(1.0_GLFLOAT) CALL GLBEGIN(GL_LINE_STRIP) CALL GLVERTEX3F(INDPOS%X, Y2, Z1) CALL GLVERTEX3F(INDPOS%X,INDPOS%Y, Z1) CALL GLVERTEX3F(INDPOS%X,INDPOS%Y,INDPOS%Z) CALL GLVERTEX3F(INDPOS%X, Y2,INDPOS%Z) CALL GLVERTEX3F(INDPOS%X, Y2, Z1) CALL GLEND() CALL GLBEGIN(GL_LINE_STRIP) CALL GLVERTEX3F(INDPOS%X,INDPOS%Y, Z1) CALL GLVERTEX3F(X2 ,INDPOS%Y, Z1) CALL GLVERTEX3F(X2 ,INDPOS%Y,INDPOS%Z) CALL GLVERTEX3F(INDPOS%X,INDPOS%Y,INDPOS%Z) CALL GLVERTEX3F(INDPOS%X,INDPOS%Y, Z1) CALL GLEND() END SUBROUTINE IMOD3D_PLOT_INDPOS !###====================================================================== SUBROUTINE IMOD3D_SETTINGSPUT_INDPOS() !###====================================================================== IMPLICIT NONE REAL :: X,DX DX=TOP%X-BOT%X X=BOT%X+DX*(INDPOS%X+XYZAXES(1))/(XYZAXES(1)*2.0_GLFLOAT) CALL WDIALOGPUTREAL(IDF_REAL7,X,'(F8.1)') DX=TOP%Y-BOT%Y X=BOT%Y+DX*(INDPOS%Y+XYZAXES(2))/(XYZAXES(2)*2.0_GLFLOAT) CALL WDIALOGPUTREAL(IDF_REAL8,X,'(F8.1)') X=INDPOS%Z; CALL WDIALOGPUTREAL(IDF_REAL9,X,'(F8.1)') END SUBROUTINE IMOD3D_SETTINGSPUT_INDPOS !###====================================================================== SUBROUTINE IMOD3D_LIGHT() !###====================================================================== IMPLICIT NONE INTEGER :: I CALL WDIALOGSELECT(ID_D3DSETTINGS_TAB5) CALL WDIALOGGETTRACKBAR(IDF_TRACKBAR2,I); F_L1_AMBIENT=REAL(I)/100.0 CALL WDIALOGGETTRACKBAR(IDF_TRACKBAR3,I); F_L1_DIFFUSE=REAL(I)/100.0 CALL WDIALOGGETTRACKBAR(IDF_TRACKBAR4,I); F_L1_SPECULAR=REAL(I)/100.0 L1_AMBIENT= (/F_L1_AMBIENT,F_L1_AMBIENT,F_L1_AMBIENT,1.0_GLFLOAT/) L1_DIFFUSE= (/F_L1_DIFFUSE,F_L1_DIFFUSE,F_L1_DIFFUSE,1.0_GLFLOAT/) L1_SPECULAR=(/F_L1_SPECULAR,F_L1_SPECULAR,F_L1_SPECULAR,1.0_GLFLOAT/) !The ambient component is the light from that source that's been scattered so much by the environment !that its direction is impossible to determine - it seems to come from all directions. Backlighting in a room !has a large ambient component, since most of the light that reaches your eye has bounced off many !surfaces first. A spotlight outdoors has a tiny ambient component; most of the light travels in the same !direction, and since you're outdoors, very little of the light reaches your eye after bouncing off other !objects. When ambient light strikes a surface, it's scattered equally in all directions. !--- flattens image ---- CALL GLLIGHTFV(GL_LIGHT0, GL_AMBIENT, L1_AMBIENT) !Diffuse light comes from one direction, so it's brighter if it comes squarely down on a surface than if it !barely glances off the surface. Once it hits a surface, however, it's scattered equally in all directions, so it !appears equally bright, no matter where the eye is located. Any light coming from a particular position or !direction probably has a diffuse component. CALL GLLIGHTFV(GL_LIGHT0, GL_DIFFUSE,L1_DIFFUSE) !Finally, specular light comes from a particular direction, and it tends to bounce off the surface in a !preferred direction. A well-collimated laser beam bouncing off a high-quality mirror produces almost 100 !percent specular reflection. Shiny metal or plastic has a high specular component, and chalk or carpet has !almost none. You can think of specularity as shininess. CALL GLLIGHTFV(GL_LIGHT0, GL_SPECULAR,L1_SPECULAR) END SUBROUTINE IMOD3D_LIGHT !###====================================================================== SUBROUTINE IMOD3D_RESET_TO_INIT() !###====================================================================== !## This resets the view to the initial configuration IMPLICIT NONE TYPE (SPHERE3D) :: SLOOKFROM !## lookat is the coordinate 0,0,0 !## lookfrom is the coordinate 10,-20,5 !## scale factors 1,1,1 SLOOKFROM = CART2SPHERE(LOOKFROM-LOOKAT) ANGLE%X =-180.0_GLDOUBLE*SLOOKFROM%THETA/PI - 90.0_GLDOUBLE ANGLE%Y =-180.0_GLDOUBLE*SLOOKFROM%PHI/PI SHIFT%X = INIT_SHIFTX SHIFT%Y = INIT_SHIFTY SHIFT%Z = INIT_SHIFTZ-SLOOKFROM%RHO XSCALE_FACTOR= INIT_XSCALE_FACTOR YSCALE_FACTOR= INIT_YSCALE_FACTOR ZSCALE_FACTOR= INIT_ZSCALE_FACTOR CALL IMOD3D_ERROR('IMOD3D_RESET_TO_INIT') END SUBROUTINE IMOD3D_RESET_TO_INIT !###====================================================================== SUBROUTINE IMOD3D_DISPLAY_IPF(IMODE) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IMODE INTEGER :: IASSF,IIPF REAL(KIND=GLFLOAT) :: LT !## linethickness !## associated file drawn DO IASSF=1,NIPFLIST !## active based upon selection IF(IPFDLIST(5,IASSF).EQ.0)CYCLE !## part of selected ipf IIPF=IPFDLIST(1,IASSF); IF(IIPF.EQ.0)CYCLE !## selected in menu-field IF(IPFPLOT(IIPF)%ISEL.NE.1.OR.IPFLISTINDEX(IASSF,IMODE).EQ.0)CYCLE IF(IMODE.EQ.1)then !## line width IF(ISELECTED.EQ.IASSF)THEN IF(IPFPLOT(IIPF)%IFANCY.EQ.0)THEN CALL GLLINEWIDTH(10.0_GLFLOAT) CALL GLPOINTSIZE(10.0_GLFLOAT) ELSEIF(IPFPLOT(IIPF)%IFANCY.EQ.1)THEN CALL GLPOLYGONMODE(GL_FRONT,GL_LINE); CALL GLPOLYGONMODE(GL_BACK, GL_LINE) CALL GLLINEWIDTH(1.0_GLFLOAT) ENDIF ELSE !## mark whenever drill has been selected/activated to be interpolated LT=2.0_GLFLOAT CALL GLLINEWIDTH(LT) CALL GLPOINTSIZE(4.0_GLFLOAT) ENDIF IF(IPFPLOT(IIPF)%IFANCY.EQ.1)THEN IF(IPFPLOT(IIPF)%ISHADE.EQ.1.AND.IMODE.EQ.1)THEN CALL GLSHADEMODEL(GL_FLAT); CALL GLENABLE(GL_LIGHTING); CALL GLDISABLE(GL_BLEND) ENDIF ENDIF ENDIF CALL GLCALLLIST(IPFLISTINDEX(IASSF,IMODE)) IF(IMODE.EQ.1)THEN IF(IPFPLOT(IIPF)%IFANCY.EQ.1)THEN IF(IPFPLOT(IIPF)%ISHADE.EQ.1.AND.IMODE.EQ.1)THEN CALL GLDISABLE(GL_LIGHTING); CALL GLENABLE(GL_BLEND) ENDIF ENDIF CALL GLPOLYGONMODE(GL_BACK, GL_FILL); CALL GLPOLYGONMODE(GL_FRONT,GL_FILL) ENDIF END DO !## draw ipf labels IF(IMODE.EQ.1.AND.IPLOTLABELS.EQ.1)THEN !## associated file drawn DO IASSF=1,NIPFLIST !## active based upon selection IF(IPFDLIST(5,IASSF).EQ.0)CYCLE !## part of selected ipf IIPF=IPFDLIST(1,IASSF) !ASSF(IASSF)%IIPF !## selected in menu-field IF(IPFPLOT(IIPF)%ISEL.EQ.0.OR.IPFLISTINDEX(IASSF,3).EQ.0)CYCLE IF(ISELECTED.EQ.IASSF)THEN CALL IMOD3D_SETCOLOR(WRGB(255,0,0)) ELSE CALL IMOD3D_SETCOLOR(LCOLOR) ENDIF CALL GLCALLLIST(IPFLISTINDEX(IASSF,3)) ENDDO ENDIF CALL IMOD3D_ERROR('IMOD3D_DISPLAY_IPF') END SUBROUTINE IMOD3D_DISPLAY_IPF !###====================================================================== SUBROUTINE IMOD3D_DISPLAY_IDF(IMODE) !###====================================================================== IMPLICIT NONE INTEGER :: I,J INTEGER,INTENT(IN) :: IMODE DO I=1,SIZE(IDFLISTINDEX) IF(IDFPLOT(I)%ISEL.NE.1.OR.IDFLISTINDEX(I).EQ.0)CYCLE IF(IDFPLOT(I)%IFILL.EQ.1.OR.IDFPLOT(I)%IFILL.EQ.3)THEN !## opaque mode CALL GLBLENDFUNC(GL_ONE,GL_ZERO) !## (1) source (2) destination CALL GLPOLYGONMODE(GL_BACK, GL_FILL); CALL GLPOLYGONMODE(GL_FRONT,GL_FILL) IF(IDFPLOT(I)%ILEG.EQ.1)THEN CALL IMOD3D_SETCOLOR(IDFPLOT(I)%ICOLOR) ELSEIF(IDFPLOT(I)%ILEG.EQ.2)THEN !## legend colour - reread as not yet filled with legend-colouring !## do not change colour since colour is inside display-list ENDIF !## turn on light if neccessary IF(IDFPLOT(I)%ISHADED.EQ.1)THEN !## set material ... !## one single colour used IF(IDFPLOT(I)%ILEG.EQ.1)THEN !## show shaded surface ! CALL IMOD3D_RETURNCOLOR(IDFPLOT(I)%ICOLOR,AMBIENT) ! CALL GLMATERIALFV(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,AMBIENT) ENDIF !## flat shading CALL GLSHADEMODEL(GL_FLAT) !## heeft te maken met invullen kleuren CALL GLENABLE(GL_LIGHTING) ENDIF CALL GLCALLLIST(IDFLISTINDEX(I)) !## turn of light IF(IDFPLOT(I)%ISHADED.EQ.1)THEN CALL GLDISABLE(GL_LIGHTING) ENDIF ENDIF !## draw mesh IF(IDFPLOT(I)%IFILL.EQ.2.OR.IDFPLOT(I)%IFILL.EQ.3)THEN !## blend mode CALL GLBLENDFUNC(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) !## (1) source (2) destination !## show lines to represent rectangles/triangles IF(IDFPLOT(I)%IFILL.EQ.2)CALL IMOD3D_SETCOLOR(IDFPLOT(I)%ICOLOR) IF(IDFPLOT(I)%IFILL.EQ.3)CALL IMOD3D_SETCOLOR(WRGB(0,0,0)) CALL GLLINEWIDTH(1.0_GLFLOAT) !## outline (showing rectangles) CALL GLPOLYGONMODE(GL_FRONT,GL_LINE); CALL GLPOLYGONMODE(GL_BACK, GL_LINE) CALL GLCALLLIST(IDFLISTINDEX(I)) ENDIF END DO !## default CALL GLPOLYGONMODE(GL_BACK, GL_FILL); CALL GLPOLYGONMODE(GL_FRONT,GL_FILL) END SUBROUTINE IMOD3D_DISPLAY_IDF !###====================================================================== SUBROUTINE IMOD3D_DISPLAY_IFF() !###====================================================================== IMPLICIT NONE INTEGER :: I REAL(KIND=GLFLOAT) :: XW !## opaque mode CALL GLBLENDFUNC(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) !## (1) source (2) destination DO I=1,NIFFLIST IF(IFFPLOT(I)%ISEL.NE.1.OR.IFFLISTINDEX(I).EQ.0)CYCLE IF(MP(IFFPLOT(I)%IPLOT)%ILEG.EQ.0)THEN CALL IMOD3D_SETCOLOR(MP(IFFPLOT(I)%IPLOT)%SCOLOR) ENDIF XW=REAL(IFFPLOT(I)%ITHICKNESS) CALL GLLINEWIDTH(XW) CALL GLCALLLIST(IFFLISTINDEX(I)) END DO END SUBROUTINE IMOD3D_DISPLAY_IFF !###====================================================================== SUBROUTINE IMOD3D_DISPLAY_SOL() !###====================================================================== IMPLICIT NONE INTEGER :: I !## opaque mode !CALL GLBLENDFUNC(GL_ONE,GL_ZERO) !## (1) source (2) destination !## no lightning ... difficult to draw in correct seqence/order CALL GLENABLE(GL_LIGHTING) CALL GLSHADEMODEL(GL_FLAT) !## heeft te maken met invullen kleuren DO I=1,NSOLLIST IF(SOLPLOT(I)%ISEL.EQ.0)CYCLE IF(SOLPLOT(I)%IBITMAP.EQ.1)CYCLE IF(SOLLISTINDEX(I,1).EQ.0)CYCLE CALL GLBLENDFUNC(GL_ONE,GL_ZERO) !## (1) source (2) destination IF(SOLPLOT(I)%IINTERFACE.EQ.0)THEN CALL GLENABLE(GL_LIGHTING) IF(SOLPLOT(I)%IBLEND.EQ.1)THEN CALL GLBLENDFUNC(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) !## (1) source (2) destination ENDIF ELSE CALL GLDISABLE(GL_LIGHTING) ENDIF CALL GLCALLLIST(SOLLISTINDEX(I,1)) END DO CALL GLDISABLE(GL_LIGHTING) ! IF(ITRANSPARANCYBITMAP.EQ.1)THEN ! CALL GLBLENDFUNC(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) ! ELSE CALL GLDISABLE(GL_BLEND) ! ENDIF CALL GLCOLOR4F(1.0_GLFLOAT,1.0_GLFLOAT,1.0_GLFLOAT,1.0_GLFLOAT) DO I=1,NSOLLIST IF(SOLPLOT(I)%ISEL.EQ.0)CYCLE IF(SOLPLOT(I)%IBITMAP.EQ.0)CYCLE IF(SOLLISTINDEX(I,2).EQ.0)CYCLE IF(SOLPLOT(I)%IINTERFACE.EQ.1)THEN CALL GLPOLYGONMODE(GL_FRONT,GL_LINE); CALL GLPOLYGONMODE(GL_BACK, GL_LINE) ELSE CALL GLPOLYGONMODE(GL_BACK, GL_FILL); CALL GLPOLYGONMODE(GL_FRONT,GL_FILL) ENDIF CALL GLCALLLIST(SOLLISTINDEX(I,2)) ENDDO CALL GLENABLE(GL_BLEND) END SUBROUTINE IMOD3D_DISPLAY_SOL !###====================================================================== SUBROUTINE IMOD3D_DISPLAY_CLP() !###====================================================================== IMPLICIT NONE INTEGER :: I DO I=1,NCLPLIST IF(CLPPLOT(I)%ISEL.EQ.1)THEN CALL GLCALLLIST(CLPLISTINDEX(I)) ENDIF END DO END SUBROUTINE IMOD3D_DISPLAY_CLP !###====================================================================== SUBROUTINE IMOD3D_DISPLAY_GEN() !###====================================================================== IMPLICIT NONE INTEGER :: I REAL(KIND=GLFLOAT) :: XW,XR,XG,XB INTEGER :: IR,IG,IB !## blend mode CALL GLBLENDFUNC(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) !## (1) source (2) destination DO I=1,NGENLIST IF(GENPLOT(I)%ISEL.NE.1.OR.GENLISTINDEX(I).EQ.0)CYCLE IF(GENPLOT(I)%L3D)THEN !## show shaded surface CALL IMOD3D_SETCOLOR(GENPLOT(I)%ICOLOR,GENPLOT(I)%ITRANSPARANCY) ELSE CALL IMOD3D_SETCOLOR(GENPLOT(I)%ICOLOR) XW=REAL(GENPLOT(I)%ITHICKNESS) CALL GLLINEWIDTH(XW) ENDIF CALL GLCALLLIST(GENLISTINDEX(I)) END DO END SUBROUTINE IMOD3D_DISPLAY_GEN !###====================================================================== SUBROUTINE IMOD3D_DISPLAY_BMP() !###====================================================================== IMPLICIT NONE INTEGER :: I !## not background bitmap plotting IF(IACTBITMAP.EQ.0)RETURN IF(ITRANSPARANCYBITMAP.EQ.1)THEN CALL GLBLENDFUNC(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) ELSE CALL GLDISABLE(GL_BLEND) ENDIF CALL GLCOLOR4F(1.0_GLFLOAT,1.0_GLFLOAT,1.0_GLFLOAT,1.0_GLFLOAT) I=1 CALL GLCALLLIST(BMPLISTINDEX(I)) CALL GLENABLE(GL_BLEND) END SUBROUTINE IMOD3D_DISPLAY_BMP !###====================================================================== SUBROUTINE IMOD3D_DISPLAY_LEGEND() !###====================================================================== IMPLICIT NONE INTEGER :: I,N,M IF(LEGENDINDEX.EQ.0)RETURN !## save projection transformation matrix CALL GLMATRIXMODE(GL_PROJECTION); CALL GLPUSHMATRIX() !## set new projection transformation matrix CALL GLLOADIDENTITY() CALL GLORTHO(0.0_GLDOUBLE,100.0_GLDOUBLE,0.0_GLDOUBLE,100.0_GLDOUBLE,-1.0_GLDOUBLE,1.0_GLDOUBLE) !## save modelview transformation matrix CALL GLMATRIXMODE(GL_MODELVIEW); CALL GLPUSHMATRIX() !## set new modelview transformation matrix CALL GLLOADIDENTITY() CALL GLDISABLE(GL_BLEND) CALL GLDISABLE(GL_LIGHT0) CALL GLPOLYGONMODE(GL_FRONT_AND_BACK,GL_FILL) CALL GLDISABLE(GL_DEPTH_TEST) CALL GLCALLLIST(LEGENDINDEX) CALL GLENABLE(GL_BLEND) CALL GLENABLE(GL_LIGHT0) CALL GLDEPTHFUNC(GL_LESS) CALL GLENABLE(GL_DEPTH_TEST) !## restore transformations matrices CALL GLMATRIXMODE(GL_MODELVIEW); CALL GLPOPMATRIX() CALL GLMATRIXMODE(GL_PROJECTION); CALL GLPOPMATRIX() END SUBROUTINE IMOD3D_DISPLAY_LEGEND !###====================================================================== SUBROUTINE IMOD3D_DISPLAY_SAVE(ID) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: ID INTEGER(KIND=GLSIZEI) :: NDX,NDY INTEGER(GLINT) :: IVIEWPORT(4) REAL(KIND=GLFLOAT),DIMENSION(:),ALLOCATABLE :: FRGB INTEGER,DIMENSION(:),ALLOCATABLE :: IRGB INTEGER :: IHANDLE,I CHARACTER(LEN=256) :: FNAME REAL(KIND=GLFLOAT),DIMENSION(3) :: GLCOLOR IF(ID.EQ.ID_SAVEAS)THEN IF(.NOT.UTL_WSELECTFILE('All Known Files (*.bmp;*.pcx;*.png;*.jpg)|*.bmp;*.pcx;*.png;*.jpg|BitMap (*.bmp)|*.bmp| & ZSoft PC Paintbrush (*.pcx)|*.pcx|Portable Network Graphic image (*.png)|*.png|JPEG Image (*.jpg)|*.jpg|',& SAVEDIALOG+PROMPTON+DIRCHANGE+APPENDEXT,FNAME,& 'Save Current Image to BitMap (*.bmp;*.pcx;*.png;*.jpg)'))RETURN ENDIF !## capture entire screen CALL GLGETINTEGERV(GL_VIEWPORT,IVIEWPORT) NDX=IVIEWPORT(3); NDY=IVIEWPORT(4) ALLOCATE(FRGB(NDX*NDY*3),IRGB(NDX*NDY)) CALL GLREADBUFFER(GL_FRONT) CALL GLREADPIXELS(0_GLINT,0_GLINT,NDX,NDY,GL_RGB,GL_FLOAT,FRGB) DO I=0,(NDX*NDY)-1 GLCOLOR(1)=FRGB(I*3+1); GLCOLOR(2)=FRGB(I*3+2); GLCOLOR(3)=FRGB(I*3+3) CALL IMOD3D_GETCOLOR(IRGB(I+1),GLCOLOR) ENDDO CALL WBITMAPCREATE(IHANDLE,NDX,NDY) CALL WBITMAPGETDATA(IHANDLE,IRGB) !## switch vertically CALL WBITMAPMIRROR(IHANDLE,1) IF(ID.EQ.ID_SAVEAS)THEN CALL WBITMAPSAVE(IHANDLE,FNAME) ELSE CALL WBITMAPCLIPBOARD(IHANDLE) ENDIF CALL WBITMAPDESTROY(IHANDLE) DEALLOCATE(FRGB,IRGB) CALL GLREADBUFFER(GL_BACK) IF(ID.EQ.ID_SAVEAS)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'Succesfully saved the current image to'//CHAR(13)//TRIM(FNAME),'Information') ELSE CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'Succesfully copied the current image to'//CHAR(13)//'the Windows Clipboard','Information') ENDIF END SUBROUTINE IMOD3D_DISPLAY_SAVE !###====================================================================== SUBROUTINE IMOD3D_ANAGLYPHS() !###====================================================================== IMPLICIT NONE ! STEP =MINSTEP ! HEADING =HEADING+PERP ! LOOKFROM%X=LOOKFROM%X-COS(HEADING)*STEP ! LOOKFROM%Y=LOOKFROM%Y-SIN(HEADING)*STEP ! LOOKAT%X =LOOKAT%X-COS(HEADING)*STEP ! LOOKAT%Y =LOOKAT%Y-SIN(HEADING)*STEP ! HEADING =HEADING-PERP ! LOOKAT%X=LOOKFROM%X+COS(HEADING)*DX ! LOOKAT%Y=LOOKFROM%Y+SIN(HEADING)*DX ! LOOKAT%Z=LOOKFROM%Z+SIN(TILT)*DZ !## set transformation parameters according to the lookfrom() and lookat() variables ! CALL IMOD3D_RESET_TO_INIT() ! CALL IMOD3D_DISPLAY(1) END SUBROUTINE IMOD3D_ANAGLYPHS !###====================================================================== SUBROUTINE IMOD3D_RESET_VIEW() !###====================================================================== IMPLICIT NONE CALL GLTRANSLATED(SHIFT%X, SHIFT%Y, SHIFT%Z) CALL GLROTATED(ANGLE%X, 0.0_GLDOUBLE, 0.0_GLDOUBLE, 1.0_GLDOUBLE) CALL GLROTATED(ANGLE%Y, COS(PI*ANGLE%X/180.0_GLDOUBLE), & -SIN(PI*ANGLE%X/180.0_GLDOUBLE), 0.0_GLDOUBLE) CALL GLTRANSLATED(-LOOKAT%X, -LOOKAT%Y, -LOOKAT%Z) CALL GLSCALED(XSCALE_FACTOR,YSCALE_FACTOR,ZSCALE_FACTOR) CALL IMOD3D_ERROR('IMOD3D_RESET_VIEW') END SUBROUTINE IMOD3D_RESET_VIEW END MODULE MOD_3D_DISPLAY