X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blobdiff_plain;f=src%2FOpenGl%2FOpenGl_View.cxx;h=c4d986fc9a36d39f6e6667938e5faf40817acbb2;hb=2166f0fad8d7bd32bed2ce4b8766e115d7be63a8;hpb=1d2b1ccb453fcdf3aac0bdb2d5baf34dfb1cc4f9 diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx new file mode 100644 index 0000000000..c4d986fc9a --- /dev/null +++ b/src/OpenGl/OpenGl_View.cxx @@ -0,0 +1,645 @@ +// File: OpenGl_View.cxx +// Created: 20 September 2011 +// Author: Sergey ZERCHANINOV +// Copyright: OPEN CASCADE 2011 + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared) + +/*----------------------------------------------------------------------*/ + +static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED }; +static const OPENGL_BG_GRADIENT myDefaultBgGradient = { {{ 0.F, 0.F, 0.F, 1.F }}, {{ 0.F, 0.F, 0.F, 1.F }}, Aspect_GFM_NONE }; +static const Tmatrix3 myDefaultMatrix = { { 1.F, 0.F, 0.F, 0.F }, { 0.F, 1.F, 0.F, 0.F }, { 0.F, 0.F, 1.F, 0.F }, { 0.F, 0.F, 0.F, 1.F } }; +static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } }; +static const OPENGL_EXTRA_REP myDefaultExtra = +{ + //vrp + { 0.F, 0.F, 0.F }, + //vpn + { 0.F, 0.F, 1.F }, + //vup + { 0.F, 1.F, 0.F }, + //map + { + //window + { 0.F, 0.F, 1.F, 1.F }, + //viewport + { 0.F, 0.F, 0.F, 1.F, 1.F, 1.F }, + //proj + TelParallel, + //prp + { 0.F, 0.F, 0.F }, + //vpd + 0.F, + //fpd + 0.F, + //bpd + -1.F + }, + //scaleFactors + { 1.F, 1.F, 1.F } +}; + +static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } }; +static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F }; + +/*----------------------------------------------------------------------*/ + +OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext) +: myTextureEnv(0), + mySurfaceDetail(Visual3d_TOD_NONE), + myBackfacing(0), + myBgTexture(myDefaultBgTexture), + myBgGradient(myDefaultBgGradient), + //myOrientationMatrix(myDefaultMatrix), + //myMappingMatrix(myDefaultMatrix), + //shield_indicator = TOn, + //shield_colour = { { 0.F, 0.F, 0.F, 1.F } }, + //border_indicator = TOff, + //border_colour = { { 0.F, 0.F, 0.F, 1.F } }, + //active_status = TOn, + myZClip(myDefaultZClip), + myExtra(myDefaultExtra), + myFog(myDefaultFog), + myVisualization(AContext.Visualization), + myIntShadingMethod(TEL_SM_GOURAUD), + myAntiAliasing(Standard_False), + myAnimationListIndex(0), + myAnimationListReady(Standard_False), + myTransPers(&myDefaultTransPers), + myIsTransPers(Standard_False), + myResetFLIST(Standard_False) +{ + // Initialize matrices + memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3)); + memcpy(myMappingMatrix,myDefaultMatrix,sizeof(Tmatrix3)); + + // Shading method + switch (AContext.Model) + { + case 1 : /* VISUAL3D_TOM_INTERP_COLOR */ + case 3 : /* VISUAL3D_TOM_VERTEX */ + myIntShadingMethod = TEL_SM_GOURAUD; + break; + default : + myIntShadingMethod = TEL_SM_FLAT; + break; + } +} + +/*----------------------------------------------------------------------*/ + +OpenGl_View::~OpenGl_View () +{ + if (myAnimationListIndex) + glDeleteLists((GLuint)myAnimationListIndex,1); + + if ( myBgTexture.TexId != 0 ) + glDeleteTextures( 1, (GLuint*)&(myBgTexture.TexId) ); +} + +/*----------------------------------------------------------------------*/ + +void OpenGl_View::SetBackfacing (const Standard_Integer AMode) +{ + myBackfacing = AMode; + myResetFLIST = Standard_True; +} + +/*----------------------------------------------------------------------*/ + +//call_togl_setlight +void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext) +{ + myLights.Clear(); + + const int nb_lights = AContext.NbActiveLight; + + int i = 0; + const CALL_DEF_LIGHT *alight = &(AContext.ActiveLight[0]); + for ( ; i < nb_lights; i++, alight++ ) + { + OpenGl_Light rep; + + switch( alight->LightType ) + { + case 0 : /* TOLS_AMBIENT */ + rep.type = TLightAmbient; + rep.col.rgb[0] = alight->Color.r; + rep.col.rgb[1] = alight->Color.g; + rep.col.rgb[2] = alight->Color.b; + break; + + case 1 : /* TOLS_DIRECTIONAL */ + rep.type = TLightDirectional; + rep.col.rgb[0] = alight->Color.r; + rep.col.rgb[1] = alight->Color.g; + rep.col.rgb[2] = alight->Color.b; + rep.dir[0] = alight->Direction.x; + rep.dir[1] = alight->Direction.y; + rep.dir[2] = alight->Direction.z; + break; + + case 2 : /* TOLS_POSITIONAL */ + rep.type = TLightPositional; + rep.col.rgb[0] = alight->Color.r; + rep.col.rgb[1] = alight->Color.g; + rep.col.rgb[2] = alight->Color.b; + rep.pos[0] = alight->Position.x; + rep.pos[1] = alight->Position.y; + rep.pos[2] = alight->Position.z; + rep.atten[0] = alight->Attenuation[0]; + rep.atten[1] = alight->Attenuation[1]; + break; + + case 3 : /* TOLS_SPOT */ + rep.type = TLightSpot; + rep.col.rgb[0] = alight->Color.r; + rep.col.rgb[1] = alight->Color.g; + rep.col.rgb[2] = alight->Color.b; + rep.pos[0] = alight->Position.x; + rep.pos[1] = alight->Position.y; + rep.pos[2] = alight->Position.z; + rep.dir[0] = alight->Direction.x; + rep.dir[1] = alight->Direction.y; + rep.dir[2] = alight->Direction.z; + rep.shine = alight->Concentration; + rep.atten[0] = alight->Attenuation[0]; + rep.atten[1] = alight->Attenuation[1]; + rep.angle = alight->Angle; + break; + } + + rep.HeadLight = alight->Headlight; + + myLights.Append(rep); + } +} + +/*----------------------------------------------------------------------*/ + +//call_togl_setplane +void OpenGl_View::SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext) +{ + // clear clipping planes information + myClippingPlanes.Clear(); + // update information + int i = 0; + for (; i < AContext.NbActivePlane; i++) + { + const CALL_DEF_PLANE &aCPlane = AContext.ActivePlane[i]; + if ( aCPlane.Active && aCPlane.PlaneId > 0 ) + { + OPENGL_CLIP_REP aPlane; + aPlane.equation[0] = aCPlane.CoefA; + aPlane.equation[1] = aCPlane.CoefB; + aPlane.equation[2] = aCPlane.CoefC; + aPlane.equation[3] = aCPlane.CoefD; + myClippingPlanes.Append( aPlane ); + } + } +} + +/*----------------------------------------------------------------------*/ + +//call_togl_setvisualisation +void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext) +{ + myVisualization = AContext.Visualization; + // Shading method + switch (AContext.Model) + { + case 1 : /* VISUAL3D_TOM_INTERP_COLOR */ + case 3 : /* VISUAL3D_TOM_VERTEX */ + myIntShadingMethod = TEL_SM_GOURAUD; + break; + default : + myIntShadingMethod = TEL_SM_FLAT; + break; + } +} + +/*----------------------------------------------------------------------*/ + +//call_togl_cliplimit +void OpenGl_View::SetClipLimit (const CALL_DEF_VIEW &ACView) +{ + myZClip.Back.Limit = + ( ACView.Context.ZClipBackPlane - ACView.Mapping.BackPlaneDistance ) / + ( ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance ); + myZClip.Front.Limit = + ( ACView.Context.ZClipFrontPlane - ACView.Mapping.BackPlaneDistance ) / + ( ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance ); + if ( myZClip.Back.Limit < 0.F ) + myZClip.Back.Limit = 0.F; + if ( myZClip.Front.Limit > 1.F ) + myZClip.Front.Limit = 1.F; + if ( myZClip.Back.Limit > myZClip.Front.Limit ) + { + myZClip.Back.Limit = 0.F; + myZClip.Front.Limit = 1.F; + } + + myZClip.Back.IsOn = (ACView.Context.BackZClipping != 0); + myZClip.Front.IsOn = (ACView.Context.FrontZClipping != 0); +} + +/*----------------------------------------------------------------------*/ + +//call_togl_viewmapping +void OpenGl_View::SetMapping (const CALL_DEF_VIEW &ACView) +{ + const float ratio = ACView.DefWindow.dy / ACView.DefWindow.dx; + const float r_ratio = ACView.DefWindow.dx / ACView.DefWindow.dy; + + TEL_VIEW_MAPPING Map; + + Map.window.xmin = ACView.Mapping.WindowLimit.um; + Map.window.ymin = ACView.Mapping.WindowLimit.vm; + Map.window.xmax = ACView.Mapping.WindowLimit.uM; + Map.window.ymax = ACView.Mapping.WindowLimit.vM; + + Map.viewport.xmin = 0.F; + Map.viewport.xmax = ( 1.F < r_ratio ? 1.F : r_ratio ); + Map.viewport.ymin = 0.F; + Map.viewport.ymax = ( 1.F < ratio ? 1.F : ratio ); + Map.viewport.zmin = 0.F; + Map.viewport.zmax = 1.F; + + /* projection type */ + switch( ACView.Mapping.Projection ) + { + case 0 : + Map.proj = TelPerspective; + break; + case 1 : + Map.proj = TelParallel; + break; + } + + /* projection reference point */ + Map.prp[0] = ACView.Mapping.ProjectionReferencePoint.x; + Map.prp[1] = ACView.Mapping.ProjectionReferencePoint.y; + Map.prp[2] = ACView.Mapping.ProjectionReferencePoint.z; + if (!openglDisplay.IsNull() && !openglDisplay->Walkthrough()) + Map.prp[2] += ACView.Mapping.FrontPlaneDistance; + + /* view plane distance */ + Map.vpd = ACView.Mapping.ViewPlaneDistance; + + /* back plane distance */ + Map.bpd = ACView.Mapping.BackPlaneDistance; + + /* front plane distance */ + Map.fpd = ACView.Mapping.FrontPlaneDistance; + + Tint err_ind = 0; + + /* use user-defined matrix */ + if ( ACView.Mapping.IsCustomMatrix ) + { + int i, j; + for( i = 0; i < 4; i++ ) + for( j = 0; j < 4; j++ ) + myMappingMatrix[i][j] = ACView.Mapping.ProjectionMatrix[i][j]; + } + else + TelEvalViewMappingMatrix( &Map, &err_ind, myMappingMatrix ); + + if ( !err_ind ) + myExtra.map = Map; +} + +/*----------------------------------------------------------------------*/ + +//call_togl_vieworientation +void OpenGl_View::SetOrientation (const CALL_DEF_VIEW &ACView) +{ + Tfloat Vrp[3]; + Tfloat Vpn[3]; + Tfloat Vup[3]; + Tfloat ScaleFactors[3]; + + Vrp[0] = ACView.Orientation.ViewReferencePoint.x; + Vrp[1] = ACView.Orientation.ViewReferencePoint.y; + Vrp[2] = ACView.Orientation.ViewReferencePoint.z; + + Vpn[0] = ACView.Orientation.ViewReferencePlane.x; + Vpn[1] = ACView.Orientation.ViewReferencePlane.y; + Vpn[2] = ACView.Orientation.ViewReferencePlane.z; + + Vup[0] = ACView.Orientation.ViewReferenceUp.x; + Vup[1] = ACView.Orientation.ViewReferenceUp.y; + Vup[2] = ACView.Orientation.ViewReferenceUp.z; + + ScaleFactors[0] = ACView.Orientation.ViewScaleX; + ScaleFactors[1] = ACView.Orientation.ViewScaleY; + ScaleFactors[2] = ACView.Orientation.ViewScaleZ; + + Tint err_ind = 0; + + // use user-defined matrix + if ( ACView.Orientation.IsCustomMatrix ) + { + int i, j; + for( i = 0; i < 4; i++ ) + for( j = 0; j < 4; j++ ) + myOrientationMatrix[i][j] = ACView.Orientation.ModelViewMatrix[i][j]; + } + else + TelEvalViewOrientationMatrix( Vrp, Vpn, Vup, ScaleFactors, &err_ind, myOrientationMatrix ); + + if ( !err_ind ) + { + myExtra.vrp[0] = Vrp[0]; + myExtra.vrp[1] = Vrp[1]; + myExtra.vrp[2] = Vrp[2]; + + myExtra.vpn[0] = Vpn[0]; + myExtra.vpn[1] = Vpn[1]; + myExtra.vpn[2] = Vpn[2]; + + myExtra.vup[0] = Vup[0]; + myExtra.vup[1] = Vup[1]; + myExtra.vup[2] = Vup[2]; + + myExtra.scaleFactors[0] = ScaleFactors[0], + myExtra.scaleFactors[1] = ScaleFactors[1], + myExtra.scaleFactors[2] = ScaleFactors[2]; + } +} + +/*----------------------------------------------------------------------*/ + +void OpenGl_View::SetFog (const CALL_DEF_VIEW &ACView, const Standard_Boolean AFlag) +{ + if( !AFlag ) + { + myFog.IsOn = Standard_False; + } + else + { + myFog.IsOn = Standard_True; + + myFog.Front = + (ACView.Context.DepthFrontPlane - ACView.Mapping.BackPlaneDistance) / + (ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance); + + myFog.Back = + (ACView.Context.DepthBackPlane - ACView.Mapping.BackPlaneDistance) / + (ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance); + + if (myFog.Front < 0.F) + myFog.Front = 0.F; + else if (myFog.Front > 1.F) + myFog.Front = 1.F; + + if (myFog.Back < 0.F) + myFog.Back = 0.F; + else if (myFog.Back > 1.F) + myFog.Back = 1.F; + + if (myFog.Back > myFog.Front) + { + myFog.Front = 1.F; + myFog.Back = 0.F; + } + + myFog.Color.rgb[0] = ACView.DefWindow.Background.r; + myFog.Color.rgb[1] = ACView.DefWindow.Background.g; + myFog.Color.rgb[2] = ACView.DefWindow.Background.b; + myFog.Color.rgb[3] = 1.F; + } +} + +/*----------------------------------------------------------------------*/ + +void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor, + const Standard_Real AScale, const Standard_Boolean AsWireframe) +{ + myTrihedron = new OpenGl_Trihedron (APosition, AColor, AScale, AsWireframe); +} + +/*----------------------------------------------------------------------*/ + +void OpenGl_View::TriedronErase () +{ + myTrihedron.Nullify(); +} + +/*----------------------------------------------------------------------*/ + +void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_CGraduatedTrihedron &data) +{ + myGraduatedTrihedron = new OpenGl_GraduatedTrihedron(data); +} + +/*----------------------------------------------------------------------*/ + +void OpenGl_View::GraduatedTrihedronErase () +{ + myGraduatedTrihedron.Nullify(); +} + +/*----------------------------------------------------------------------*/ + +//transform_persistence_end +void OpenGl_View::EndTransformPersistence () +{ + if ( myIsTransPers ) + { + /* restore matrix */ + glMatrixMode (GL_PROJECTION); + glPopMatrix (); + glMatrixMode (GL_MODELVIEW); + glPopMatrix (); + myIsTransPers = Standard_False; + } +} + +/*----------------------------------------------------------------------*/ + +//transform_persistence_begin +const TEL_TRANSFORM_PERSISTENCE * OpenGl_View::BeginTransformPersistence (const TEL_TRANSFORM_PERSISTENCE *ATransPers) +{ + const TEL_TRANSFORM_PERSISTENCE *TransPers_old = myTransPers; + + if ( ATransPers->mode == 0 ) + { + EndTransformPersistence(); + return TransPers_old; + } + + myTransPers = ATransPers; + + GLint viewport[4]; + glGetIntegerv (GL_VIEWPORT, viewport); + GLdouble modelMatrix[4][4]; + glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble *) modelMatrix ); + GLdouble projMatrix[4][4]; + glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix ); + + double W = viewport[2]; + double H = viewport[3]; + + if ( myIsTransPers ) + { + /* restore matrix */ + glMatrixMode (GL_PROJECTION); + glPopMatrix (); + glMatrixMode (GL_MODELVIEW); + glPopMatrix (); + } + else + myIsTransPers = Standard_True; + + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + + /*pre loading matrix*/ + if( ATransPers->mode & TPF_PAN ) + /* Annulate translate matrix */ + { + modelMatrix[3][0] = 0.; + modelMatrix[3][1] = 0.; + modelMatrix[3][2] = 0.; + projMatrix[3][0] = 0.; + projMatrix[3][1] = 0.; + projMatrix[3][2] = 0.; + } + + if( ATransPers->mode & TPF_ZOOM ) + /* Annulate zoom matrix */ + { + const double scaleX = myExtra.scaleFactors[0]; + const double scaleY = myExtra.scaleFactors[1]; + const double scaleZ = myExtra.scaleFactors[2]; + + for (int i = 0; i < 3; ++i) + { + modelMatrix[0][i] /= scaleX; + modelMatrix[1][i] /= scaleY; + modelMatrix[2][i] /= scaleZ; + } + + const double det2 = 0.002 / ( W > H ? projMatrix[1][1] : projMatrix[0][0]); + projMatrix[0][0] *= det2; + projMatrix[1][1] *= det2; + } + + if( ATransPers->mode & TPF_ROTATE ) + /* Annulate rotate matrix */ + { + modelMatrix[0][0] = 1.; + modelMatrix[1][1] = 1.; + modelMatrix[2][2] = 1.; + + modelMatrix[1][0] = 0.; + modelMatrix[2][0] = 0.; + modelMatrix[0][1] = 0.; + modelMatrix[2][1] = 0.; + modelMatrix[0][2] = 0.; + modelMatrix[1][2] = 0.; + } + else if( ATransPers->mode & TPF_RELATIVE_ROTATE ) + /* Initialize relative rotate matrix*/ + { + modelMatrix[3][0] = 0.; + modelMatrix[3][1] = 0.; + modelMatrix[3][2] = 0.; + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslated( ATransPers->pointX, ATransPers->pointY, ATransPers->pointZ ); + } + + if( ATransPers->mode == TPF_TRIEDRON ) + { + /* Annulate translation matrix */ + modelMatrix[3][0] = 0.; + modelMatrix[3][1] = 0.; + modelMatrix[3][2] = 0.; + + projMatrix[3][0] = 0.; + projMatrix[3][1] = 0.; + projMatrix[3][2] = 0.; + + const double det2 = 0.002 / ( W > H ? projMatrix[1][1] : projMatrix[0][0]); + projMatrix[0][0] *= det2; + projMatrix[1][1] *= det2; + } + + /* load matrix */ + glMatrixMode (GL_MODELVIEW); + glMultMatrixd ((GLdouble *) modelMatrix); + + glMatrixMode (GL_PROJECTION); + glMultMatrixd ((GLdouble *) projMatrix); + + /*post loading matrix*/ + if( ATransPers->mode == TPF_TRIEDRON ) + { + glMatrixMode( GL_PROJECTION ); + + double winx, winy, winz; + const GLdouble idenMatrix[4][4] = { {1.,0.,0.,0.}, {0.,1.,0.,0.}, {0.,0.,1.,0.}, {0.,0.,0.,1.} }; + + gluUnProject( W/2., H/2., 0., (GLdouble*)idenMatrix, (GLdouble*)projMatrix, (GLint*)viewport, &winx, &winy, &winz); + double W1, H1; + W1 = winx; + H1 = winy; + gluUnProject( -W/2., -H/2., 0., (GLdouble*)idenMatrix, (GLdouble*)projMatrix, (GLint*)viewport, &winx, &winy, &winz); + double W2, H2; + W2 = winx; + H2 = winy; + + if( ATransPers->pointX == 0. && ATransPers->pointY == 0. ) + { + /*center*/ + } + else if( ATransPers->pointX > 0. && ATransPers->pointY > 0. ) + { + /*right upper*/ + glTranslated( 0.5*(W1 - W2 - ATransPers->pointZ), 0.5*(H1 - H2 - ATransPers->pointZ), 0. ); + } + else if( ATransPers->pointX > 0. && ATransPers->pointY < 0. ) + { + /*right lower*/ + glTranslated( 0.5*(W1 - W2 - ATransPers->pointZ), 0.5*(H2 - H1 + ATransPers->pointZ), 0. ); + } + else if( ATransPers->pointX < 0. && ATransPers->pointY > 0. ) + { + /*left upper*/ + glTranslated( 0.5*(W2 - W1 + ATransPers->pointZ), 0.5*(H1 - H2 - ATransPers->pointZ), 0. ); + } + else if( ATransPers->pointX < 0 && ATransPers->pointY < 0 ) + { + /*left lower*/ + glTranslated( -(W1 - W2)/2. + ATransPers->pointZ/2., -(H1-H2)/2. + ATransPers->pointZ/2., 0. ); + } + } + + return TransPers_old; +} + +/*----------------------------------------------------------------------*/