0025282: Visualization, OpenGl_PrimitiveArray - provide built-in GLSL programs as...
authorkgv <kgv@opencascade.com>
Thu, 2 Oct 2014 09:46:27 +0000 (13:46 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 2 Oct 2014 10:29:19 +0000 (14:29 +0400)
Enumerations Visual3d_TypeOfModel, V3d_TypeOfShadingModel.
- Remove unused values V3d_MULTICOLOR, V3d_HIDDEN, Visual3d_TOM_INTERP_COLOR.
- Add per-pixel shading mode - V3d_PHONG, Visual3d_TOM_FRAGMENT.

Draw Harness command vrenderparams.
Add option -shadingModel to setup Shading Model.

OpenGl_Caps::ffpEnable - new option to switch FFP/built-in GLSL programs.
OpenGl_ShaderManager - add built-in GLSL programs.

Draw Harness command vcaps.
- Fix command syntax to meet coding rules.
- Add option -ffp to activate/disable built-in GLSL programs.

GLSL API changes.
- Rename vertex attribute occColor -> occVertColor.
- Introduce vec4 occColor uniform variable for light-less shaders.
- Introduce float occPointSize uniform variable for marker programs.

OpenGl_VertexBuffer::bindAttribute() - activate normalization for non-GL_FLOAT types,
since color attribute is defined as 32-bit vector of 4 unsigned byte values.

OpenGl_Context - add methods SetColor4fv() and SetPointSize()
for parameters redirection to active GLSL program
(as alternative to glColor4fv() and glPointSize()).

OpenGl_ShaderProgram - define default precision for float types
in Fragment Shader within OpenGL ES 2.0+ context.

OpenGl_AspectMarker, initialize Aspect_TOM_O_POINT display list
in the same way as sprite texture.

OpenGl_Texture, do not use sized internal formats on OpenGL ES.

40 files changed:
samples/mfc/standard/04_Viewer3d/src/ShadingModelDlg.cpp
samples/mfc/standard/04_Viewer3d/src/ShadingModelDlg.h
samples/mfc/standard/04_Viewer3d/src/Viewer3d.rc
samples/mfc/standard/04_Viewer3d/src/resource.h
src/InterfaceGraphic/InterfaceGraphic_telem.hxx
src/OpenGl/OpenGl_AspectFace.cxx
src/OpenGl/OpenGl_AspectFace.hxx
src/OpenGl/OpenGl_AspectLine.cxx
src/OpenGl/OpenGl_AspectLine.hxx
src/OpenGl/OpenGl_AspectMarker.cxx
src/OpenGl/OpenGl_AspectMarker.hxx
src/OpenGl/OpenGl_AspectText.cxx
src/OpenGl/OpenGl_AspectText.hxx
src/OpenGl/OpenGl_Caps.cxx
src/OpenGl/OpenGl_Caps.hxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_PrimitiveArray.hxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_ShaderProgram.cxx
src/OpenGl/OpenGl_ShaderProgram.hxx
src/OpenGl/OpenGl_Text.cxx
src/OpenGl/OpenGl_Texture.cxx
src/OpenGl/OpenGl_Texture.hxx
src/OpenGl/OpenGl_VertexBuffer.lxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_2.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/OpenGl/OpenGl_Workspace_5.cxx
src/Shaders/Declarations.glsl
src/V3d/V3d.cdl
src/ViewerTest/ViewerTest_ViewerCommands.cxx
src/Visual3d/Visual3d.cdl
src/Visual3d/Visual3d_ContextView.cdl
tests/bugs/vis/bug23654_MarkersRecompute
tests/bugs/vis/bug24131_markers
tests/bugs/vis/bug24728

index dcd165b..c053f45 100755 (executable)
@@ -35,9 +35,10 @@ void CShadingModelDlg::DoDataExchange(CDataExchange* pDX)
 
 BEGIN_MESSAGE_MAP(CShadingModelDlg, CDialog)
        //{{AFX_MSG_MAP(CShadingModelDlg)
-       ON_BN_CLICKED(IDC_SHADINGMODEL_COLOR, OnShadingmodelColor)
-       ON_BN_CLICKED(IDC_SHADINGMODEL_FLAT, OnShadingmodelFlat)
+       ON_BN_CLICKED(IDC_SHADINGMODEL_COLOR,   OnShadingmodelColor)
+       ON_BN_CLICKED(IDC_SHADINGMODEL_FLAT,    OnShadingmodelFlat)
        ON_BN_CLICKED(IDC_SHADINGMODEL_GOURAUD, OnShadingmodelGouraud)
+       ON_BN_CLICKED(IDC_SHADINGMODEL_PHONG,   OnShadingmodelPhong)
        //}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
@@ -62,3 +63,8 @@ void CShadingModelDlg::OnShadingmodelGouraud()
        myCurrent_V3d_View->Update();   
 }
 
+void CShadingModelDlg::OnShadingmodelPhong()
+{
+       myCurrent_V3d_View->SetShadingModel(V3d_PHONG);
+       myCurrent_V3d_View->Update();
+}
index dc88f1e..6ddad56 100755 (executable)
@@ -40,6 +40,7 @@ protected:
        afx_msg void OnShadingmodelColor();
        afx_msg void OnShadingmodelFlat();
        afx_msg void OnShadingmodelGouraud();
+       afx_msg void OnShadingmodelPhong();
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
 
index 66bb00d..01e4c83 100755 (executable)
@@ -136,7 +136,7 @@ BEGIN
     CONTROL         "Cueing ON/OFF",IDC_CHECK_CUEINGONOFF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,49,67,10
 END
 
-IDD_SHADINGMODEL DIALOG  0, 0, 60, 66
+IDD_SHADINGMODEL DIALOG 0, 0, 60, 86
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "ShadingModel"
 FONT 8, "MS Sans Serif"
@@ -144,6 +144,7 @@ BEGIN
     PUSHBUTTON      "COLOR",IDC_SHADINGMODEL_COLOR,7,7,46,16
     PUSHBUTTON      "FLAT",IDC_SHADINGMODEL_FLAT,7,25,46,15
     PUSHBUTTON      "GOURAUD",IDC_SHADINGMODEL_GOURAUD,7,43,46,16
+    PUSHBUTTON      "PHONG",IDC_SHADINGMODEL_PHONG,7,62,46,16
 END
 
 IDD_MODELCLIPPING DIALOG  0, 0, 180, 74
index 9a75ffa..fac2093 100755 (executable)
@@ -63,6 +63,7 @@
 #define IDC_ISOV                        1005
 #define IDC_SHADINGMODEL_GOURAUD        1006
 #define IDC_EDIT_ISOV                   1006
+#define IDC_SHADINGMODEL_PHONG          1007
 #define IDC_CHECK_MODELCLIPPINGONOFF    1008
 #define IDC_SLIDER_OFFSETFACTOR         1010
 #define IDC_SLIDER_OFFSETUNITS          1011
index 3492cfe..db4acbf 100644 (file)
@@ -69,9 +69,6 @@ typedef enum
 
 #define TEL_HS_USER_DEF_START      15
 
-#define TEL_SM_FLAT    1
-#define TEL_SM_GOURAUD 2
-
 /* Standard Lighting Models */
 #define  TEL_FRONT_BACK_LM  1
 
index e669f96..ab4a4b3 100644 (file)
@@ -422,23 +422,21 @@ void OpenGl_AspectFace::Release (OpenGl_Context* theContext)
 // function : BuildTexture
 // purpose  :
 // =======================================================================
-void OpenGl_AspectFace::Resources::BuildTexture (const Handle(OpenGl_Workspace)& theWS,
+void OpenGl_AspectFace::Resources::BuildTexture (const Handle(OpenGl_Context)&       theCtx,
                                                  const Handle(Graphic3d_TextureMap)& theTexture)
 {
-  const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
-
   // release old texture resource
   if (!Texture.IsNull())
   {
     if (TextureId.IsEmpty())
     {
-      aContext->DelayedRelease (Texture);
+      theCtx->DelayedRelease (Texture);
       Texture.Nullify();
     }
     else
     {
       Texture.Nullify(); // we need nullify all handles before ReleaseResource() call
-      aContext->ReleaseResource (TextureId, Standard_True);
+      theCtx->ReleaseResource (TextureId, Standard_True);
     }
   }
 
@@ -446,17 +444,17 @@ void OpenGl_AspectFace::Resources::BuildTexture (const Handle(OpenGl_Workspace)&
 
   if (!theTexture.IsNull())
   {
-    if (TextureId.IsEmpty() || !aContext->GetResource<Handle(OpenGl_Texture)> (TextureId, Texture))
+    if (TextureId.IsEmpty() || !theCtx->GetResource<Handle(OpenGl_Texture)> (TextureId, Texture))
     {
       Texture = new OpenGl_Texture (theTexture->GetParams());
       Handle(Image_PixMap) anImage = theTexture->GetImage();
       if (!anImage.IsNull())
       {
-        Texture->Init (aContext, *anImage.operator->(), theTexture->Type());
+        Texture->Init (theCtx, *anImage.operator->(), theTexture->Type());
       }
       if (!TextureId.IsEmpty())
       {
-        aContext->ShareResource (TextureId, Texture);
+        theCtx->ShareResource (TextureId, Texture);
       }
     }
   }
@@ -466,11 +464,10 @@ void OpenGl_AspectFace::Resources::BuildTexture (const Handle(OpenGl_Workspace)&
 // function : BuildShader
 // purpose  :
 // =======================================================================
-void OpenGl_AspectFace::Resources::BuildShader (const Handle(OpenGl_Workspace)&        theWS,
+void OpenGl_AspectFace::Resources::BuildShader (const Handle(OpenGl_Context)&          theCtx,
                                                 const Handle(Graphic3d_ShaderProgram)& theShader)
 {
-  const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
-  if (!aContext->IsGlGreaterEqual (2, 0))
+  if (!theCtx->IsGlGreaterEqual (2, 0))
   {
     return;
   }
@@ -478,7 +475,7 @@ void OpenGl_AspectFace::Resources::BuildShader (const Handle(OpenGl_Workspace)&
   // release old shader program resources
   if (!ShaderProgram.IsNull())
   {
-    aContext->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
+    theCtx->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
     ShaderProgramId.Clear();
     ShaderProgram.Nullify();
   }
@@ -487,5 +484,5 @@ void OpenGl_AspectFace::Resources::BuildShader (const Handle(OpenGl_Workspace)&
     return;
   }
 
-  aContext->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
+  theCtx->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
 }
index 7b8cd1e..35aa98e 100644 (file)
@@ -187,11 +187,11 @@ public:
   }
 
   //! @return texture map.
-  const Handle(OpenGl_Texture)& TextureRes (const Handle(OpenGl_Workspace)& theWorkspace) const
+  const Handle(OpenGl_Texture)& TextureRes (const Handle(OpenGl_Context)& theCtx) const
   {
     if (!myResources.IsTextureReady())
     {
-      myResources.BuildTexture (theWorkspace, myTexture);
+      myResources.BuildTexture (theCtx, myTexture);
       myResources.SetTextureReady();
     }
 
@@ -200,11 +200,11 @@ public:
 
   //! Init and return OpenGl shader program resource.
   //! @return shader program resource.
-  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Workspace)& theWorkspace) const 
+  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Context)& theCtx) const
   {
     if (!myResources.IsShaderReady())
     {
-      myResources.BuildShader (theWorkspace, myShaderProgram);
+      myResources.BuildShader (theCtx, myShaderProgram);
       myResources.SetShaderReady();
     }
 
@@ -250,9 +250,9 @@ protected:
     void ResetTextureReadiness() { myIsTextureReady = Standard_False; }
     void ResetShaderReadiness () { myIsShaderReady  = Standard_False; }
 
-    Standard_EXPORT void BuildTexture (const Handle(OpenGl_Workspace)&        theWS,
+    Standard_EXPORT void BuildTexture (const Handle(OpenGl_Context)&          theCtx,
                                        const Handle(Graphic3d_TextureMap)&    theTexture);
-    Standard_EXPORT void BuildShader  (const Handle(OpenGl_Workspace)&        theWS,
+    Standard_EXPORT void BuildShader  (const Handle(OpenGl_Context)&          theCtx,
                                        const Handle(Graphic3d_ShaderProgram)& theShader);
 
     Handle(OpenGl_Texture)       Texture;
index 48d23cf..c7ddf98 100644 (file)
@@ -99,11 +99,10 @@ void OpenGl_AspectLine::Release (OpenGl_Context* theContext)
 // function : BuildShader
 // purpose  :
 // =======================================================================
-void OpenGl_AspectLine::Resources::BuildShader (const Handle(OpenGl_Workspace)&        theWS,
+void OpenGl_AspectLine::Resources::BuildShader (const Handle(OpenGl_Context)&          theCtx,
                                                 const Handle(Graphic3d_ShaderProgram)& theShader)
 {
-  const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
-  if (!aContext->IsGlGreaterEqual (2, 0))
+  if (!theCtx->IsGlGreaterEqual (2, 0))
   {
     return;
   }
@@ -111,7 +110,7 @@ void OpenGl_AspectLine::Resources::BuildShader (const Handle(OpenGl_Workspace)&
   // release old shader program resources
   if (!ShaderProgram.IsNull())
   {
-    aContext->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
+    theCtx->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
     ShaderProgramId.Clear();
     ShaderProgram.Nullify();
   }
@@ -120,5 +119,5 @@ void OpenGl_AspectLine::Resources::BuildShader (const Handle(OpenGl_Workspace)&
     return;
   }
 
-  aContext->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
+  theCtx->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
 }
index dbb27aa..2e35092 100644 (file)
@@ -42,11 +42,11 @@ public:
 
   //! Init and return OpenGl shader program resource.
   //! @return shader program resource.
-  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Workspace)& theWorkspace) const
+  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Context)& theCtx) const
   {
     if (!myResources.IsShaderReady())
     {
-      myResources.BuildShader (theWorkspace, myShaderProgram);
+      myResources.BuildShader (theCtx, myShaderProgram);
       myResources.SetShaderReady();
     }
 
@@ -75,7 +75,8 @@ protected:
     void SetShaderReady()       { myIsShaderReady = Standard_True; }
     void ResetShaderReadiness() { myIsShaderReady = Standard_False; }
 
-    Standard_EXPORT void BuildShader (const Handle(OpenGl_Workspace)& theWS, const Handle(Graphic3d_ShaderProgram)& theShader);
+    Standard_EXPORT void BuildShader (const Handle(OpenGl_Context)&          theCtx,
+                                      const Handle(Graphic3d_ShaderProgram)& theShader);
 
     Handle(OpenGl_ShaderProgram) ShaderProgram;
     TCollection_AsciiString      ShaderProgramId;
index a29e430..c679aea 100644 (file)
@@ -31,7 +31,20 @@ namespace
 {
   static const TEL_COLOUR myDefaultColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }};
   static const TCollection_AsciiString THE_EMPTY_KEY;
-};
+
+  //! Draw inner point as filled rectangle
+  static Handle(TColStd_HArray1OfByte) fillPointBitmap (const Standard_Integer theSize)
+  {
+    // draw inner point as filled rectangle
+    const Standard_Integer        aNumOfBytes = (theSize / 8 + (theSize % 8 ? 1 : 0)) * theSize;
+    Handle(TColStd_HArray1OfByte) aBitMap     = new TColStd_HArray1OfByte (0, aNumOfBytes - 1);
+    for (Standard_Integer anIter = 0; anIter < aBitMap->Length(); ++anIter)
+    {
+      aBitMap->SetValue (anIter, 255);
+    }
+    return aBitMap;
+  }
+}
 
 // Following Section relates to default markers
 
@@ -1544,15 +1557,13 @@ void OpenGl_AspectMarker::Release (OpenGl_Context* theCtx)
 // function : BuildSprites
 // purpose  :
 // =======================================================================
-void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace)& theWorkspace,
+void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Context)&        theCtx,
                                                    const Handle(Graphic3d_MarkerImage)& theMarkerImage,
                                                    const Aspect_TypeOfMarker theType,
                                                    const Standard_ShortReal theScale,
                                                    const TEL_COLOUR& theColor,
                                                    Standard_ShortReal& theMarkerSize)
 {
-  const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
-
   // generate key for shared resource
   TCollection_AsciiString aNewKey  = THE_EMPTY_KEY;
   TCollection_AsciiString aNewKeyA = THE_EMPTY_KEY;
@@ -1566,13 +1577,13 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
     {
       if (SpriteKey.IsEmpty())
       {
-        aContext->DelayedRelease (Sprite);
+        theCtx->DelayedRelease (Sprite);
         Sprite.Nullify();
       }
       else
       {
         Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call
-        aContext->ReleaseResource (SpriteKey, Standard_True);
+        theCtx->ReleaseResource (SpriteKey, Standard_True);
       }
     }
     SpriteKey = aNewKey;
@@ -1583,13 +1594,13 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
     {
       if (SpriteAKey.IsEmpty())
       {
-        aContext->DelayedRelease (SpriteA);
+        theCtx->DelayedRelease (SpriteA);
         SpriteA.Nullify();
       }
       else
       {
         SpriteA.Nullify(); // we need nullify all handles before ReleaseResource() call
-        aContext->ReleaseResource (SpriteAKey, Standard_True);
+        theCtx->ReleaseResource (SpriteAKey, Standard_True);
       }
     }
     SpriteAKey = aNewKeyA;
@@ -1603,8 +1614,8 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
   }
 
   if (!aNewKey.IsEmpty()
-   && aContext->GetResource<Handle(OpenGl_PointSprite)> (aNewKeyA, SpriteA) // alpha sprite could be shared
-   && aContext->GetResource<Handle(OpenGl_PointSprite)> (aNewKey,  Sprite))
+   && theCtx->GetResource<Handle(OpenGl_PointSprite)> (aNewKeyA, SpriteA) // alpha sprite could be shared
+   && theCtx->GetResource<Handle(OpenGl_PointSprite)> (aNewKey,  Sprite))
   {
     // reuse shared resource
     if (!Sprite->IsDisplayList())
@@ -1622,16 +1633,16 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
   Sprite  = new OpenGl_PointSprite();
   if (!aNewKey.IsEmpty())
   {
-    aContext->ShareResource (aNewKey,  Sprite);
+    theCtx->ShareResource (aNewKey,  Sprite);
     if (!hadAlreadyAlpha)
     {
-      aContext->ShareResource (aNewKeyA, SpriteA);
+      theCtx->ShareResource (aNewKeyA, SpriteA);
     }
   }
 
-  if (!aContext.IsNull()
-   &&  aContext->IsGlGreaterEqual (2, 0)
-   && !aContext->caps->pntSpritesDisable)
+  if (!theCtx.IsNull()
+   &&  theCtx->IsGlGreaterEqual (2, 0)
+   && !theCtx->caps->pntSpritesDisable)
   {
     // Creating texture resource for using it with point sprites
     Handle(Graphic3d_MarkerImage) aNewMarkerImage;
@@ -1645,7 +1656,6 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
     else
     {
       // Creating image from default bitmap
-      Handle(TColStd_HArray1OfByte) aBitMap;
       Handle(Graphic3d_MarkerImage) aMarkerImage1, aMarkerImage2;
 
       const Standard_ShortReal aDelta = 0.1F;
@@ -1656,13 +1666,9 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
       {
         case Aspect_TOM_O_POINT:
         {
-          const Standard_Integer aSize = theScale > 7 ? 7 : (Standard_Integer )(theScale + 0.5F);
-          const Standard_Integer aNumOfBytes = (aSize / 8 + (aSize % 8 ? 1 : 0)) * aSize;
-          aBitMap = new TColStd_HArray1OfByte (0, aNumOfBytes - 1);
-          for (Standard_Integer anIter = 0; anIter < aBitMap->Length(); anIter++)
-          {
-            aBitMap->SetValue (anIter, 255);
-          }
+          // draw inner point as filled rectangle
+          const Standard_Integer        aSize   = theScale > 7 ? 7 : (Standard_Integer )(theScale + 0.5F);
+          Handle(TColStd_HArray1OfByte) aBitMap = fillPointBitmap (aSize);
           aMarkerImage2 = new Graphic3d_MarkerImage (aBitMap, aSize, aSize);
         }
         case Aspect_TOM_O_PLUS:
@@ -1756,18 +1762,18 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
 
     theMarkerSize = Max ((Standard_ShortReal )anImage->Width(),(Standard_ShortReal )anImage->Height());
 
-    Sprite->Init (aContext, *anImage.operator->(), Graphic3d_TOT_2D);
+    Sprite->Init (theCtx, *anImage.operator->(), Graphic3d_TOT_2D);
     if (!hadAlreadyAlpha)
     {
       if (anImageA.IsNull()
-       && Sprite->GetFormat() != GL_ALPHA8
+       && Sprite->GetFormat() != GL_ALPHA
        && !aNewMarkerImage.IsNull())
       {
         anImageA = aNewMarkerImage->GetImageAlpha();
       }
       if (!anImageA.IsNull())
       {
-        SpriteA->Init (aContext, *anImageA.operator->(), Graphic3d_TOT_2D);
+        SpriteA->Init (theCtx, *anImageA.operator->(), Graphic3d_TOT_2D);
       }
     }
   }
@@ -1776,7 +1782,7 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
   #if !defined(GL_ES_VERSION_2_0)
     // Creating list with bitmap for using it in compatibility mode
     GLuint aBitmapList = glGenLists (1);
-    Sprite->SetDisplayList (aContext, aBitmapList);
+    Sprite->SetDisplayList (theCtx, aBitmapList);
 
     Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes;
     if (theType == Aspect_TOM_USERDEFINED && !theMarkerImage.IsNull())
@@ -1817,6 +1823,14 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
       glNewList (aBitmapList, GL_COMPILE);
       switch (theType)
       {
+        case Aspect_TOM_O_POINT:
+        {
+          // draw inner point as filled rectangle
+          const Standard_Integer        aSize   = theScale > 7 ? 7 : (Standard_Integer )(theScale + 0.5F);
+          Handle(TColStd_HArray1OfByte) aBitMap = fillPointBitmap (aSize);
+          glBitmap (aSize, aSize, (GLfloat )(0.5f * aSize), (GLfloat )(0.5f * aSize),
+                    0.0f, 0.0f, &aBitMap->Array1().Value (aBitMap->Lower()));
+        }
         case Aspect_TOM_O_PLUS:
         case Aspect_TOM_O_STAR:
         case Aspect_TOM_O_X:
@@ -1826,9 +1840,12 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
           GetMarkerBitMapParam (Aspect_TOM_O, theScale, aWidth, aHeight, anOffset, aNumOfBytes);
           glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
                     0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
-          GetMarkerBitMapParam (Aspect_TypeOfMarker (theType - Aspect_TOM_O_POINT), theScale, aWidth, aHeight, anOffset, aNumOfBytes);
-          glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
-                    0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
+          if (theType != Aspect_TOM_O_POINT)
+          {
+            GetMarkerBitMapParam (Aspect_TypeOfMarker (theType - Aspect_TOM_O_POINT), theScale, aWidth, aHeight, anOffset, aNumOfBytes);
+            glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
+                      0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
+          }
           break;
         }
         case Aspect_TOM_BALL:
@@ -1890,11 +1907,10 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
 // function : BuildShader
 // purpose  :
 // =======================================================================
-void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Workspace)&        theWS,
+void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Context)&          theCtx,
                                                   const Handle(Graphic3d_ShaderProgram)& theShader)
 {
-  const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
-  if (!aContext->IsGlGreaterEqual (2, 0))
+  if (!theCtx->IsGlGreaterEqual (2, 0))
   {
     return;
   }
@@ -1902,7 +1918,7 @@ void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Workspace)
   // release old shader program resources
   if (!ShaderProgram.IsNull())
   {
-    aContext->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
+    theCtx->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
     ShaderProgramId.Clear();
     ShaderProgram.Nullify();
   }
@@ -1911,7 +1927,7 @@ void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Workspace)
     return;
   }
 
-  aContext->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
+  theCtx->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
 }
 
 // =======================================================================
index c71fa13..08292ba 100644 (file)
@@ -62,11 +62,11 @@ public:
 
   //! Init and return OpenGl point sprite resource.
   //! @return point sprite texture.
-  const Handle(OpenGl_PointSprite)& SpriteRes (const Handle(OpenGl_Workspace)& theWorkspace) const
+  const Handle(OpenGl_PointSprite)& SpriteRes (const Handle(OpenGl_Context)& theCtx) const
   {
     if (!myResources.IsSpriteReady())
     {
-      myResources.BuildSprites (theWorkspace, myMarkerImage, myType, myScale, myColor, myMarkerSize);
+      myResources.BuildSprites (theCtx, myMarkerImage, myType, myScale, myColor, myMarkerSize);
       myResources.SetSpriteReady();
     }
 
@@ -75,11 +75,11 @@ public:
 
   //! Init and return OpenGl highlight point sprite resource.
   //! @return point sprite texture for highlight.
-  const Handle(OpenGl_PointSprite)& SpriteHighlightRes (const Handle(OpenGl_Workspace)& theWorkspace) const
+  const Handle(OpenGl_PointSprite)& SpriteHighlightRes (const Handle(OpenGl_Context)& theCtx) const
   {
     if (!myResources.IsSpriteReady())
     {
-      myResources.BuildSprites (theWorkspace, myMarkerImage, myType, myScale, myColor, myMarkerSize);
+      myResources.BuildSprites (theCtx, myMarkerImage, myType, myScale, myColor, myMarkerSize);
       myResources.SetSpriteReady();
     }
 
@@ -88,11 +88,11 @@ public:
 
   //! Init and return OpenGl shader program resource.
   //! @return shader program resource.
-  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Workspace)& theWorkspace) const
+  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Context)& theCtx) const
   {
     if (!myResources.IsShaderReady())
     {
-      myResources.BuildShader (theWorkspace, myShaderProgram);
+      myResources.BuildShader (theCtx, myShaderProgram);
       myResources.SetShaderReady();
     }
 
@@ -131,14 +131,14 @@ protected: //! @name OpenGl resources
     void ResetSpriteReadiness() { myIsSpriteReady = Standard_False; }
     void ResetShaderReadiness() { myIsShaderReady = Standard_False; }
 
-    Standard_EXPORT void BuildSprites (const Handle(OpenGl_Workspace)&      theWS,
+    Standard_EXPORT void BuildSprites (const Handle(OpenGl_Context)&        theCtx,
                                        const Handle(Graphic3d_MarkerImage)& theMarkerImage,
                                        const Aspect_TypeOfMarker            theType,
                                        const Standard_ShortReal             theScale,
                                        const TEL_COLOUR&                    theColor,
                                        Standard_ShortReal&                  theMarkerSize);
 
-    Standard_EXPORT void BuildShader (const Handle(OpenGl_Workspace)&        theWS,
+    Standard_EXPORT void BuildShader (const Handle(OpenGl_Context)&          theCtx,
                                       const Handle(Graphic3d_ShaderProgram)& theShader);
 
     Standard_EXPORT void SpriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
index 772a183..98cc484 100755 (executable)
@@ -117,11 +117,10 @@ void OpenGl_AspectText::Release (OpenGl_Context* theContext)
 // function : BuildShader
 // purpose  :
 // =======================================================================
-void OpenGl_AspectText::Resources::BuildShader (const Handle(OpenGl_Workspace)&        theWS,
+void OpenGl_AspectText::Resources::BuildShader (const Handle(OpenGl_Context)&          theCtx,
                                                 const Handle(Graphic3d_ShaderProgram)& theShader)
 {
-  const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
-  if (!aContext->IsGlGreaterEqual (2, 0))
+  if (!theCtx->IsGlGreaterEqual (2, 0))
   {
     return;
   }
@@ -129,7 +128,7 @@ void OpenGl_AspectText::Resources::BuildShader (const Handle(OpenGl_Workspace)&
   // release old shader program resources
   if (!ShaderProgram.IsNull())
   {
-    aContext->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
+    theCtx->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
     ShaderProgramId.Clear();
     ShaderProgram.Nullify();
   }
@@ -138,5 +137,5 @@ void OpenGl_AspectText::Resources::BuildShader (const Handle(OpenGl_Workspace)&
     return;
   }
 
-  aContext->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
+  theCtx->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
 }
index 764cc55..79ccc8f 100755 (executable)
@@ -118,11 +118,11 @@ public:
 
   //! Init and return OpenGl shader program resource.
   //! @return shader program resource.
-  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Workspace)& theWorkspace) const
+  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Context)& theCtx) const
   {
     if (!myResources.IsShaderReady())
     {
-      myResources.BuildShader (theWorkspace, myShaderProgram);
+      myResources.BuildShader (theCtx, myShaderProgram);
       myResources.SetShaderReady();
     }
 
@@ -156,7 +156,7 @@ protected:
     void SetShaderReady()       { myIsShaderReady = Standard_True; }
     void ResetShaderReadiness() { myIsShaderReady = Standard_False; }
 
-    Standard_EXPORT void BuildShader (const Handle(OpenGl_Workspace)&        theWS,
+    Standard_EXPORT void BuildShader (const Handle(OpenGl_Context)&          theCtx,
                                       const Handle(Graphic3d_ShaderProgram)& theShader);
 
     Handle(OpenGl_ShaderProgram) ShaderProgram;
index baff8d1..a8bc4dd 100755 (executable)
@@ -15,6 +15,8 @@
 
 #include <OpenGl_Caps.hxx>
 
+#include <OpenGl_GlCore20.hxx>
+
 IMPLEMENT_STANDARD_HANDLE (OpenGl_Caps, Standard_Transient)
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Caps, Standard_Transient)
 
@@ -26,6 +28,11 @@ OpenGl_Caps::OpenGl_Caps()
 : vboDisable        (Standard_False),
   pntSpritesDisable (Standard_False),
   keepArrayData     (Standard_False),
+#if !defined(GL_ES_VERSION_2_0)
+  ffpEnable         (Standard_True),
+#else
+  ffpEnable         (Standard_False),
+#endif
   buffersNoSwap     (Standard_False),
   contextStereo     (Standard_False),
 #ifdef DEB
@@ -48,6 +55,7 @@ OpenGl_Caps& OpenGl_Caps::operator= (const OpenGl_Caps& theCopy)
   vboDisable        = theCopy.vboDisable;
   pntSpritesDisable = theCopy.pntSpritesDisable;
   keepArrayData     = theCopy.keepArrayData;
+  ffpEnable         = theCopy.ffpEnable;
   buffersNoSwap     = theCopy.buffersNoSwap;
   contextStereo     = theCopy.contextStereo;
   contextDebug      = theCopy.contextDebug;
index 3cd0ade..0b90e3e 100755 (executable)
@@ -20,7 +20,7 @@
 #include <Standard_Transient.hxx>
 #include <Handle_Standard_Transient.hxx>
 
-//! Class to define graphich driver capabilities.
+//! Class to define graphic driver capabilities.
 //! Notice that these options will be ignored if particular functionality does not provided by GL driver
 class OpenGl_Caps : public Standard_Transient
 {
@@ -30,6 +30,7 @@ public: //! @name flags to disable particular functionality, should be used only
   Standard_Boolean vboDisable;        //!< flag permits VBO usage, will significantly affect performance (OFF by default)
   Standard_Boolean pntSpritesDisable; //!< flag permits Point Sprites usage, will significantly affect performance (OFF by default)
   Standard_Boolean keepArrayData;     //!< Disables freeing CPU memory after building VBOs (OFF by default)
+  Standard_Boolean ffpEnable;         //!< Enables FFP (fixed-function pipeline), do not use built-in GLSL programs (ON by default on desktop OpenGL and OFF on OpenGL ES)
 
 public: //! @name context creation parameters
 
index 31c803b..a936cd1 100644 (file)
@@ -2061,8 +2061,13 @@ void OpenGl_Context::ReleaseDelayed()
 // function : BindProgram
 // purpose  :
 // =======================================================================
-void OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
+Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
 {
+  if (core20fwd == NULL)
+  {
+    return Standard_False;
+  }
+
   if (theProgram.IsNull()
   || !theProgram->IsValid())
   {
@@ -2071,9 +2076,53 @@ void OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram
       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
       myActiveProgram.Nullify();
     }
-    return;
+    return Standard_False;
   }
 
   myActiveProgram = theProgram;
   core20fwd->glUseProgram (theProgram->ProgramId());
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetColor4fv
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
+{
+  if (!myActiveProgram.IsNull())
+  {
+    myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
+  }
+#if !defined(GL_ES_VERSION_2_0)
+  else if (core11 != NULL)
+  {
+    core11->glColor4fv (theColor.GetData());
+  }
+#endif
+}
+
+// =======================================================================
+// function : SetPointSize
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
+{
+  if (!myActiveProgram.IsNull())
+  {
+    myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
+  #if !defined(GL_ES_VERSION_2_0)
+    //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
+  #endif
+  }
+#if !defined(GL_ES_VERSION_2_0)
+  //else
+  {
+    core11fwd->glPointSize (theSize);
+    if (core20fwd != NULL)
+    {
+      //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
+    }
+  }
+#endif
 }
index ae5d28e..916502b 100644 (file)
@@ -29,6 +29,7 @@
 #include <NCollection_List.hxx>
 #include <Message.hxx>
 #include <OpenGl_Caps.hxx>
+#include <OpenGl_Vec.hxx>
 #include <OpenGl_Resource.hxx>
 #include <Standard_Transient.hxx>
 #include <TCollection_AsciiString.hxx>
@@ -435,7 +436,14 @@ public: //! @name methods to alter or retrieve current state
 
   //! Bind specified program to current context,
   //! or unbind previous one when NULL specified.
-  Standard_EXPORT void BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram);
+  //! @return true if some program is bound to context
+  Standard_EXPORT Standard_Boolean BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram);
+
+  //! Setup current color.
+  Standard_EXPORT void SetColor4fv (const OpenGl_Vec4& theColor);
+
+  //! Setup point size.
+  Standard_EXPORT void SetPointSize (const Standard_ShortReal theSize);
 
 private:
 
index b976c14..50d101a 100755 (executable)
 
 namespace
 {
-  template<class T>
-  const Handle(OpenGl_ShaderProgram)& bindProgram (const Handle(OpenGl_Workspace)& theWS,
-                                                   const T*                        theAspect)
-  {
-    const Handle(OpenGl_Context)&       aCtx     = theWS->GetGlContext();
-    const Handle(OpenGl_ShaderProgram)& aProgram = theAspect->ShaderProgramRes (theWS);
-    aCtx->BindProgram (aProgram);
-    if (aProgram.IsNull())
-    {
-      return aCtx->ActiveProgram();
-    }
-
-    aProgram->ApplyVariables (aCtx);
-
-    const OpenGl_MaterialState* aMaterialState = aCtx->ShaderManager()->MaterialState (aProgram);
-    if (aMaterialState == NULL || aMaterialState->Aspect() != theAspect)
-    {
-      aCtx->ShaderManager()->UpdateMaterialStateTo (aProgram, theAspect);
-    }
-
-    aCtx->ShaderManager()->PushState (aProgram);
-    return aProgram;
-  }
-
-  inline const Handle(OpenGl_ShaderProgram)& bindProgram (const Handle(OpenGl_Workspace)& theWorkspace,
-                                                          const OpenGl_AspectFace*        theAspectFace,
-                                                          const OpenGl_AspectLine*        theAspectLine,
-                                                          const OpenGl_AspectMarker*      theAspectMarker,
-                                                          const GLint                     theDrawMode)
-  {
-    if (!theWorkspace->GetGlContext()->IsGlGreaterEqual (2, 0))
-    {
-      return theWorkspace->GetGlContext()->ActiveProgram();
-    }
-    switch (theDrawMode)
-    {
-      case GL_POINTS:
-        return bindProgram (theWorkspace, theAspectMarker);
-      case GL_LINES:
-      case GL_LINE_STRIP:
-        return bindProgram (theWorkspace, theAspectLine);
-    }
-    return bindProgram (theWorkspace, theAspectFace);
-  }
-
   //! Convert index data type from size
   inline GLenum toGlIndexType (const Standard_Integer theStride)
   {
@@ -407,11 +362,12 @@ Standard_Boolean OpenGl_PrimitiveArray::buildVBO (const Handle(OpenGl_Context)&
 // purpose  :
 // =======================================================================
 void OpenGl_PrimitiveArray::drawArray (const Handle(OpenGl_Workspace)& theWorkspace,
-                                       const Graphic3d_Vec4*           theFaceColors) const
+                                       const Graphic3d_Vec4*           theFaceColors,
+                                       const Standard_Boolean          theHasVertColor) const
 {
   const Handle(OpenGl_Context)& aGlContext  = theWorkspace->GetGlContext();
   const bool                    toHilight   = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) != 0;
-  bool                          hasVColors  = false;
+  bool                          hasVColors  = theHasVertColor && !toHilight;
   if (myVboAttribs.IsNull())
   {
   #if !defined(GL_ES_VERSION_2_0)
@@ -425,17 +381,10 @@ void OpenGl_PrimitiveArray::drawArray (const Handle(OpenGl_Workspace)& theWorksp
   }
 
   myVboAttribs->BindAllAttributes (aGlContext);
-  if (myVboAttribs->HasColorAttribute())
+  if (theHasVertColor && toHilight)
   {
-    if (toHilight)
-    {
-      // disable per-vertex colors
-      OpenGl_VertexBuffer::unbindAttribute (aGlContext, Graphic3d_TOA_COLOR);
-    }
-    else
-    {
-      hasVColors = true;
-    }
+    // disable per-vertex color
+    OpenGl_VertexBuffer::unbindAttribute (aGlContext, Graphic3d_TOA_COLOR);
   }
   if (!myVboIndices.IsNull())
   {
@@ -448,9 +397,7 @@ void OpenGl_PrimitiveArray::drawArray (const Handle(OpenGl_Workspace)& theWorksp
       for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
       {
         const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
-      #if !defined(GL_ES_VERSION_2_0)
-        if (theFaceColors != NULL) glColor3fv (theFaceColors[aGroupIter].GetData());
-      #endif
+        if (theFaceColors != NULL) aGlContext->SetColor4fv (theFaceColors[aGroupIter]);
         glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
         anOffset += aStride * aNbElemsInGroup;
       }
@@ -468,9 +415,7 @@ void OpenGl_PrimitiveArray::drawArray (const Handle(OpenGl_Workspace)& theWorksp
     for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
     {
       const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
-    #if !defined(GL_ES_VERSION_2_0)
-      if (theFaceColors != NULL) glColor3fv (theFaceColors[aGroupIter].GetData());
-    #endif
+      if (theFaceColors != NULL) aGlContext->SetColor4fv (theFaceColors[aGroupIter]);
       glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
       aFirstElem += aNbElemsInGroup;
     }
@@ -525,7 +470,7 @@ void OpenGl_PrimitiveArray::drawEdges (const TEL_COLOUR*               theEdgeCo
 
   if (aGlContext->IsGlGreaterEqual (2, 0))
   {
-    bindProgram (theWorkspace, anAspect);
+    aGlContext->ShaderManager()->BindProgram (anAspect, NULL, Standard_False, Standard_False, anAspect->ShaderProgramRes (aGlContext));
   }
 
   /// OCC22236 NOTE: draw edges for all situations:
@@ -533,9 +478,7 @@ void OpenGl_PrimitiveArray::drawEdges (const TEL_COLOUR*               theEdgeCo
   /// 2) draw elements from vertex array, when bounds defines count of primitive's vertices.
   /// 3) draw primitive's edges by vertexes if no edges and bounds array is specified
   myVboAttribs->BindPositionAttribute (aGlContext);
-#if !defined(GL_ES_VERSION_2_0)
-  glColor3fv (theEdgeColour->rgb);
-#endif
+  aGlContext->SetColor4fv (*(const OpenGl_Vec4* )theEdgeColour->rgb);
   if (!myVboIndices.IsNull())
   {
     myVboIndices->Bind (aGlContext);
@@ -577,14 +520,11 @@ void OpenGl_PrimitiveArray::drawEdges (const TEL_COLOUR*               theEdgeCo
   // unbind buffers
   myVboAttribs->UnbindAttribute (aGlContext, Graphic3d_TOA_POS);
 
-  if (myDrawMode > GL_LINE_STRIP)
-  {
-    // Restore line context
-    theWorkspace->SetAspectLine (anAspectLineOld);
-  #if !defined(GL_ES_VERSION_2_0)
-    glPopAttrib();
-  #endif
-  }
+  // restore line context
+#if !defined(GL_ES_VERSION_2_0)
+  glPopAttrib();
+#endif
+  theWorkspace->SetAspectLine (anAspectLineOld);
 }
 
 // =======================================================================
@@ -595,74 +535,39 @@ void OpenGl_PrimitiveArray::drawMarkers (const Handle(OpenGl_Workspace)& theWork
 {
   const OpenGl_AspectMarker* anAspectMarker     = theWorkspace->AspectMarker (Standard_True);
   const Handle(OpenGl_Context)&     aCtx        = theWorkspace->GetGlContext();
-  const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (theWorkspace);
-  const Standard_Boolean            isHilight   = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT);
-  if (aCtx->IsGlGreaterEqual (2, 0)
-   && !aSpriteNorm.IsNull() && !aSpriteNorm->IsDisplayList())
+  const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx);
+  if (!aSpriteNorm.IsNull()
+   && !aSpriteNorm->IsDisplayList())
   {
     // Textured markers will be drawn with the point sprites
+    aCtx->SetPointSize (anAspectMarker->MarkerSize());
   #if !defined(GL_ES_VERSION_2_0)
-    glPointSize (anAspectMarker->MarkerSize());
+    aCtx->core11fwd->glEnable (GL_ALPHA_TEST);
+    aCtx->core11fwd->glAlphaFunc (GL_GEQUAL, 0.1f);
   #endif
 
-    Handle(OpenGl_Texture) aTextureBack;
-    if (anAspectMarker->Type() != Aspect_TOM_POINT)
-    {
-      const Handle(OpenGl_PointSprite)& aSprite = (isHilight && anAspectMarker->SpriteHighlightRes (theWorkspace)->IsValid())
-                                                ? anAspectMarker->SpriteHighlightRes (theWorkspace)
-                                                : aSpriteNorm;
-      aTextureBack = theWorkspace->EnableTexture (aSprite);
-
-    #if !defined(GL_ES_VERSION_2_0)
-      glEnable (GL_ALPHA_TEST);
-      glAlphaFunc (GL_GEQUAL, 0.1f);
-    #endif
-
-      glEnable (GL_BLEND);
-      glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-    }
+    aCtx->core11fwd->glEnable (GL_BLEND);
+    aCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-    glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
+    aCtx->core11fwd->glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
 
-    glDisable (GL_BLEND);
+    aCtx->core11fwd->glDisable (GL_BLEND);
   #if !defined(GL_ES_VERSION_2_0)
-    glDisable (GL_ALPHA_TEST);
-  #endif
-    if (anAspectMarker->Type() != Aspect_TOM_POINT)
-    {
-      theWorkspace->EnableTexture (aTextureBack);
-    }
-  #if !defined(GL_ES_VERSION_2_0)
-    glPointSize (1.0f);
+    aCtx->core11fwd->glDisable (GL_ALPHA_TEST);
   #endif
+    aCtx->SetPointSize (1.0f);
     return;
   }
-
-  // Textured markers will be drawn with the glBitmap
-  if (anAspectMarker->Type() == Aspect_TOM_POINT
-   || anAspectMarker->Type() == Aspect_TOM_O_POINT)
+  else if (anAspectMarker->Type() == Aspect_TOM_POINT)
   {
-    const GLfloat aPntSize = anAspectMarker->Type() == Aspect_TOM_POINT
-                           ? anAspectMarker->MarkerSize()
-                           : 0.0f;
-  #if !defined(GL_ES_VERSION_2_0)
-    if (aPntSize > 0.0f)
-    {
-      glPointSize (aPntSize);
-    }
-  #endif
-    glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
-  #if !defined(GL_ES_VERSION_2_0)
-    if (aPntSize > 0.0f)
-    {
-      glPointSize (1.0f);
-    }
-  #endif
+    aCtx->SetPointSize (anAspectMarker->MarkerSize());
+    aCtx->core11fwd->glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
+    aCtx->SetPointSize (1.0f);
   }
-
 #if !defined(GL_ES_VERSION_2_0)
-  if (anAspectMarker->Type() != Aspect_TOM_POINT
-   && !aSpriteNorm.IsNull())
+  // Textured markers will be drawn with the glBitmap
+  else if (anAspectMarker->Type() != Aspect_TOM_POINT
+       && !aSpriteNorm.IsNull())
   {
     /**if (!isHilight && (myPArray->vcolours != NULL))
     {
@@ -677,7 +582,7 @@ void OpenGl_PrimitiveArray::drawMarkers (const Handle(OpenGl_Workspace)& theWork
     {
       for (Standard_Integer anIter = 0; anIter < myAttribs->NbElements; anIter++)
       {
-        glRasterPos3fv (myAttribs->Value<Graphic3d_Vec3> (anIter).GetData());
+        aCtx->core11->glRasterPos3fv (myAttribs->Value<Graphic3d_Vec3> (anIter).GetData());
         aSpriteNorm->DrawBitmap (theWorkspace->GetGlContext());
       }
     }
@@ -807,8 +712,8 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
   {
     // compatibility - keep data to draw markers using display lists
     const Standard_Boolean toKeepData = myDrawMode == GL_POINTS
-                                    && !anAspectMarker->SpriteRes (theWorkspace).IsNull()
-                                    &&  anAspectMarker->SpriteRes (theWorkspace)->IsDisplayList();
+                                    && !anAspectMarker->SpriteRes (aCtx).IsNull()
+                                    &&  anAspectMarker->SpriteRes (aCtx)->IsDisplayList();
     buildVBO (aCtx, toKeepData);
     myIsVboInit = Standard_True;
   }
@@ -825,18 +730,14 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
     aFrontLightingModel = 0;
   }
 
+  const Standard_Boolean hasColorAttrib = !myVboAttribs.IsNull()
+                                        && myVboAttribs->HasColorAttribute();
+  const Standard_Boolean isLightOn = aFrontLightingModel != 0
+                                 && !myVboAttribs.IsNull()
+                                 &&  myVboAttribs->HasNormalAttribute();
 #if !defined(GL_ES_VERSION_2_0)
-  // Temporarily disable environment mapping
-  if (myDrawMode <= GL_LINE_STRIP)
-  {
-    glPushAttrib (GL_ENABLE_BIT);
-    glDisable (GL_TEXTURE_1D);
-    glDisable (GL_TEXTURE_2D);
-  }
   // manage FFP lighting
-  if (aFrontLightingModel == 0
-  ||  myVboAttribs.IsNull()
-  || !myVboAttribs->HasNormalAttribute())
+  if (!isLightOn)
   {
     glDisable (GL_LIGHTING);
   }
@@ -845,10 +746,12 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
     glEnable (GL_LIGHTING);
   }
 #endif
-
-  bindProgram (theWorkspace,
-               anAspectFace, anAspectLine, anAspectMarker,
-               myDrawMode);
+  // Temporarily disable environment mapping
+  Handle(OpenGl_Texture) aTextureBack;
+  if (myDrawMode <= GL_LINE_STRIP)
+  {
+    aTextureBack = theWorkspace->DisableTexture();
+  }
 
   if ((myDrawMode >  GL_LINE_STRIP && anAspectFace->InteriorStyle() != Aspect_IS_EMPTY) ||
       (myDrawMode <= GL_LINE_STRIP))
@@ -857,14 +760,53 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
     const Graphic3d_Vec4* aFaceColors = !myBounds.IsNull() && !toHilight && anAspectFace->InteriorStyle() != Aspect_IS_HIDDENLINE
                                       ?  myBounds->Colors
                                       :  NULL;
-  #if !defined(GL_ES_VERSION_2_0)
-    glColor3fv (myDrawMode <= GL_LINE_STRIP ? aLineColor->rgb : anInteriorColor->rgb);
-  #endif
+    const Standard_Boolean hasVertColor = hasColorAttrib && !toHilight;
+    if (aCtx->IsGlGreaterEqual (2, 0))
+    {
+      switch (myDrawMode)
+      {
+        case GL_POINTS:
+        {
+          const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx);
+          if (!aSpriteNorm.IsNull()
+           && !aSpriteNorm->IsDisplayList())
+          {
+            const Handle(OpenGl_PointSprite)& aSprite = (toHilight && anAspectMarker->SpriteHighlightRes (aCtx)->IsValid())
+                                                      ? anAspectMarker->SpriteHighlightRes (aCtx)
+                                                      : aSpriteNorm;
+            theWorkspace->EnableTexture (aSprite);
+            aCtx->ShaderManager()->BindProgram (anAspectMarker, aSprite, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
+          }
+          else
+          {
+            aCtx->ShaderManager()->BindProgram (anAspectMarker, NULL, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
+          }
+          break;
+        }
+        case GL_LINES:
+        case GL_LINE_STRIP:
+        {
+          aCtx->ShaderManager()->BindProgram (anAspectLine, NULL, isLightOn, hasVertColor, anAspectLine->ShaderProgramRes (aCtx));
+          break;
+        }
+        default:
+        {
+          aCtx->ShaderManager()->BindProgram (anAspectFace, theWorkspace->ActiveTexture(), isLightOn, hasVertColor, anAspectFace->ShaderProgramRes (aCtx));
+          break;
+        }
+      }
+    }
+
+    aCtx->SetColor4fv (*(const OpenGl_Vec4* )(myDrawMode <= GL_LINE_STRIP ? aLineColor->rgb : anInteriorColor->rgb));
 
-    drawArray (theWorkspace, aFaceColors);
+    drawArray (theWorkspace, aFaceColors, hasColorAttrib);
   }
 
-  if (myDrawMode > GL_LINE_STRIP)
+  if (myDrawMode <= GL_LINE_STRIP)
+  {
+    theWorkspace->EnableTexture (aTextureBack);
+  }
+  else
   {
     if (anAspectFace->Edge()
      || anAspectFace->InteriorStyle() == Aspect_IS_HIDDENLINE)
@@ -873,11 +815,5 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
     }
   }
 
-#if !defined(GL_ES_VERSION_2_0)
-  if (myDrawMode <= GL_LINE_STRIP)
-  {
-    glPopAttrib();
-  }
-#endif
   aCtx->BindProgram (NULL);
 }
index c7d300e..c086204 100644 (file)
@@ -83,7 +83,8 @@ private:
 
   //! Main procedure to draw array
   void drawArray (const Handle(OpenGl_Workspace)& theWorkspace,
-                  const Graphic3d_Vec4*           theFaceColors) const;
+                  const Graphic3d_Vec4*           theFaceColors,
+                  const Standard_Boolean          theHasVertColor) const;
 
   //! Auxiliary procedures
   void drawEdges (const TEL_COLOUR*               theEdgeColour,
index 4f0e1de..db9e566 100755 (executable)
 IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderManager, Standard_Transient)
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
 
+namespace
+{
+
+#define EOL "\n"
+
+//! Auxiliary function to transform normal
+const char THE_FUNC_transformNormal[] =
+  EOL"vec3 transformNormal (in vec3 theNormal)"
+  EOL"{"
+  EOL"  vec4 aResult = occWorldViewMatrixInverseTranspose"
+  EOL"               * occModelWorldMatrixInverseTranspose"
+  EOL"               * vec4 (theNormal, 0.0);"
+  EOL"  return normalize (aResult.xyz);"
+  EOL"}";
+
+//! Global shader variable for color definition with lighting enabled.
+const char THE_FUNC_lightDef[] =
+  EOL"vec3 Ambient;"   //!< Ambient  contribution of light sources
+  EOL"vec3 Diffuse;"   //!< Diffuse  contribution of light sources
+  EOL"vec3 Specular;"; //!< Specular contribution of light sources
+
+//! Computes illumination from light sources
+const char THE_FUNC_computeLighting[] =
+  EOL"vec4 computeLighting (in vec3 theNormal,"
+  EOL"                      in vec3 theView,"
+  EOL"                      in vec4 thePoint,"
+  EOL"                      in bool theIsFront)"
+  EOL"{"
+  // clear the light intensity accumulators
+  EOL"  Ambient  = occLightAmbient.rgb;"
+  EOL"  Diffuse  = vec3 (0.0);"
+  EOL"  Specular = vec3 (0.0);"
+  EOL"  vec3 aPoint = thePoint.xyz / thePoint.w;"
+  EOL"  for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)"
+  EOL"  {"
+  EOL"    int aType = occLight_Type (anIndex);"
+  EOL"    if (aType == OccLightType_Direct)"
+  EOL"    {"
+  EOL"      directionalLight (anIndex, theNormal, theView, theIsFront);"
+  EOL"    }"
+  EOL"    else if (aType == OccLightType_Point)"
+  EOL"    {"
+  EOL"      pointLight (anIndex, theNormal, theView, aPoint, theIsFront);"
+  EOL"    }"
+  EOL"    else if (aType == OccLightType_Spot)"
+  EOL"    {"
+  EOL"      spotLight (anIndex, theNormal, theView, aPoint, theIsFront);"
+  EOL"    }"
+  EOL"  }"
+  EOL
+  EOL"  vec4 aMaterialAmbient  = theIsFront ? occFrontMaterial_Ambient()  : occBackMaterial_Ambient();"
+  EOL"  vec4 aMaterialDiffuse  = theIsFront ? occFrontMaterial_Diffuse()  : occBackMaterial_Diffuse();"
+  EOL"  vec4 aMaterialSpecular = theIsFront ? occFrontMaterial_Specular() : occBackMaterial_Specular();"
+  EOL"  vec4 aMaterialEmission = theIsFront ? occFrontMaterial_Emission() : occBackMaterial_Emission();"
+  EOL"  return vec4 (Ambient,  1.0) * aMaterialAmbient"
+  EOL"       + vec4 (Diffuse,  1.0) * aMaterialDiffuse"
+  EOL"       + vec4 (Specular, 1.0) * aMaterialSpecular"
+  EOL"                              + aMaterialEmission;"
+  EOL"}";
+
+//! Function computes contribution of isotropic point light source
+const char THE_FUNC_pointLight[] =
+  EOL"void pointLight (in int  theId,"
+  EOL"                 in vec3 theNormal,"
+  EOL"                 in vec3 theView,"
+  EOL"                 in vec3 thePoint,"
+  EOL"                 in bool theIsFront)"
+  EOL"{"
+  EOL"  vec3 aLight = occLight_Position (theId).xyz;"
+  EOL"  if (occLight_IsHeadlight (theId) == 0)"
+  EOL"  {"
+  EOL"    aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0));"
+  EOL"  }"
+  EOL"  aLight -= thePoint;"
+  EOL
+  EOL"  float aDist = length (aLight);"
+  EOL"  aLight = aLight * (1.0 / aDist);"
+  EOL
+  EOL"  float anAtten = 1.0 / (occLight_ConstAttenuation  (theId)"
+  EOL"                       + occLight_LinearAttenuation (theId) * aDist);"
+  EOL
+  EOL"  vec3 aHalf = normalize (aLight + theView);"
+  EOL
+  EOL"  vec3  aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
+  EOL"  float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
+  EOL"  float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
+  EOL
+  EOL"  float aSpecl = 0.0;"
+  EOL"  if (aNdotL > 0.0)"
+  EOL"  {"
+  EOL"    aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
+  EOL"  }"
+  EOL
+  EOL"Diffuse  += occLight_Diffuse  (theId).rgb * aNdotL * anAtten;"
+  EOL"Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
+  EOL"}";
+
+//! Function computes contribution of spotlight source
+const char THE_FUNC_spotLight[] =
+  EOL"void spotLight (in int  theId,"
+  EOL"                in vec3 theNormal,"
+  EOL"                in vec3 theView,"
+  EOL"                in vec3 thePoint,"
+  EOL"                in bool theIsFront)"
+  EOL"{"
+  EOL"  vec3 aLight   = occLight_Position      (theId).xyz;"
+  EOL"  vec3 aSpotDir = occLight_SpotDirection (theId).xyz;"
+  EOL"  if (occLight_IsHeadlight (theId) == 0)"
+  EOL"  {"
+  EOL"    aLight   = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight,   1.0));"
+  EOL"    aSpotDir = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aSpotDir, 0.0));"
+  EOL"  }"
+  EOL"  aLight -= thePoint;"
+  EOL
+  EOL"  float aDist = length (aLight);"
+  EOL"  aLight = aLight * (1.0 / aDist);"
+  EOL
+  EOL"  aSpotDir = normalize (aSpotDir);"
+  // light cone
+  EOL"  float aCosA = dot (aSpotDir, -aLight);"
+  EOL"  if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))"
+  EOL"  {"
+  EOL"    return;"
+  EOL"  }"
+  EOL
+  EOL"  float anExponent = occLight_SpotExponent (theId);"
+  EOL"  float anAtten    = 1.0 / (occLight_ConstAttenuation  (theId)"
+  EOL"                          + occLight_LinearAttenuation (theId) * aDist);"
+  EOL"  if (anExponent > 0.0)"
+  EOL"  {"
+  EOL"    anAtten *= pow (aCosA, anExponent * 128.0);"
+  EOL"  }"
+  EOL
+  EOL"  vec3 aHalf = normalize (aLight + theView);"
+  EOL
+  EOL"  vec3  aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
+  EOL"  float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
+  EOL"  float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
+  EOL
+  EOL"  float aSpecl = 0.0;"
+  EOL"  if (aNdotL > 0.0)"
+  EOL"  {"
+  EOL"    aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
+  EOL"  }"
+  EOL
+  EOL"  Diffuse  += occLight_Diffuse  (theId).rgb * aNdotL * anAtten;"
+  EOL"  Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
+  EOL"}";
+
+//! Function computes contribution of directional light source
+const char THE_FUNC_directionalLight[] =
+  EOL"void directionalLight (in int  theId,"
+  EOL"                       in vec3 theNormal,"
+  EOL"                       in vec3 theView,"
+  EOL"                       in bool theIsFront)"
+  EOL"{"
+  EOL"  vec3 aLight = normalize (occLight_Position (theId).xyz);"
+  EOL"  if (occLight_IsHeadlight (theId) == 0)"
+  EOL"  {"
+  EOL"    aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 0.0));"
+  EOL"  }"
+  EOL
+  EOL"  vec3 aHalf = normalize (aLight + theView);"
+  EOL
+  EOL"  vec3  aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
+  EOL"  float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
+  EOL"  float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
+  EOL
+  EOL"  float aSpecl = 0.0;"
+  EOL"  if (aNdotL > 0.0)"
+  EOL"  {"
+  EOL"    aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
+  EOL"  }"
+  EOL
+  EOL"  Diffuse  += occLight_Diffuse  (theId).rgb * aNdotL;"
+  EOL"  Specular += occLight_Specular (theId).rgb * aSpecl;"
+  EOL"}";
+
+//! Process clipping planes in Fragment Shader.
+//! Should be added at the beginning of the main() function.
+const char THE_FRAG_CLIP_PLANES[] =
+  EOL"  for (int aPlaneIter = 0; aPlaneIter < occClipPlaneCount; ++aPlaneIter)"
+  EOL"  {"
+  EOL"    vec4 aClipEquation = occClipPlaneEquations[aPlaneIter];"
+  EOL"    int  aClipSpace    = occClipPlaneSpaces[aPlaneIter];"
+  EOL"    if (aClipSpace == OccEquationCoords_World)"
+  EOL"    {"
+  EOL"      if (dot (aClipEquation.xyz, PositionWorld.xyz) + aClipEquation.w < 0.0)"
+  EOL"      {"
+  EOL"        discard;"
+  EOL"      }"
+  EOL"    }"
+  EOL"    else if (aClipSpace == OccEquationCoords_View)"
+  EOL"    {"
+  EOL"      if (dot (aClipEquation.xyz, Position.xyz) + aClipEquation.w < 0.0)"
+  EOL"      {"
+  EOL"        discard;"
+  EOL"      }"
+  EOL"    }"
+  EOL"  }";
+
+}
+
 // =======================================================================
 // function : OpenGl_ShaderManager
 // purpose  : Creates new empty shader manager
 // =======================================================================
 OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
-: myContext  (theContext),
+: myShadingModel (Visual3d_TOM_VERTEX),
+  myContext  (theContext),
   myLastView (NULL)
 {
-  //
+  myLightPrograms = myGouraudPrograms;
 }
 
 // =======================================================================
@@ -52,14 +256,14 @@ OpenGl_ShaderManager::~OpenGl_ShaderManager()
 // function : Create
 // purpose  : Creates new shader program
 // =======================================================================
-void OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
-                                   TCollection_AsciiString&               theShareKey,
-                                   Handle(OpenGl_ShaderProgram)&          theProgram)
+Standard_Boolean OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
+                                               TCollection_AsciiString&               theShareKey,
+                                               Handle(OpenGl_ShaderProgram)&          theProgram)
 {
   theProgram.Nullify();
   if (theProxy.IsNull())
   {
-    return;
+    return Standard_False;
   }
 
   theShareKey = theProxy->GetId();
@@ -69,7 +273,7 @@ void OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& thePro
     {
       myProgramList.Append (theProgram);
     }
-    return;
+    return Standard_True;
   }
 
   theProgram = new OpenGl_ShaderProgram (theProxy);
@@ -78,11 +282,12 @@ void OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& thePro
     theProgram->Release (myContext);
     theShareKey.Clear();
     theProgram.Nullify();
-    return;
+    return Standard_False;
   }
 
   myProgramList.Append (theProgram);
   myContext->ShareResource (theShareKey, theProgram);
+  return Standard_True;
 }
 
 // =======================================================================
@@ -783,3 +988,297 @@ void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& thePro
   PushProjectionState  (theProgram);  
   PushLightSourceState (theProgram);
 }
+
+// =======================================================================
+// function : prepareStdProgramFont
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
+{
+  Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
+  TCollection_AsciiString aSrcVert =
+      EOL"void main()"
+      EOL"{"
+      EOL"  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
+      EOL"}";
+
+  TCollection_AsciiString aSrcFrag =
+      EOL"float getAlpha(void) { return texture2D(occActiveSampler, gl_PointCoord).a; }"
+      EOL"void main()"
+      EOL"{"
+      EOL"  vec4 aColor = occColor;"
+      EOL"  aColor.a *= getAlpha();"
+      EOL"  if (aColor.a <= 0.285) discard;"
+      EOL"  gl_FragColor = aColor;"
+      EOL"}";
+
+  aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
+  aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
+  TCollection_AsciiString aKey;
+  if (!Create (aProgramSrc, aKey, myFontProgram))
+  {
+    myFontProgram = new OpenGl_ShaderProgram(); // just mark as invalid
+    return Standard_False;
+  }
+  return Standard_True;
+}
+
+// =======================================================================
+// function : prepareStdProgramFlat
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_ShaderProgram)& theProgram,
+                                                              const Standard_Integer        theBits)
+{
+  Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
+  TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
+  TCollection_AsciiString aSrcFragGetColor     = EOL"vec4 getColor(void) { return occColor; }";
+  TCollection_AsciiString aSrcFragMainGetColor = EOL"  gl_FragColor = getColor();";
+  if ((theBits & OpenGl_PO_Point) != 0)
+  {
+  #if defined(GL_ES_VERSION_2_0)
+    aSrcVertExtraMain += EOL"  gl_PointSize = occPointSize;";
+  #endif
+    if ((theBits & OpenGl_PO_TextureA) != 0)
+    {
+      aSrcFragGetColor =
+        EOL"float getAlpha(void) { return texture2D(occActiveSampler, gl_PointCoord).a; }"
+        EOL"vec4  getColor(void)"
+        EOL"{"
+        EOL"  vec4 aColor = occColor;"
+        EOL"  aColor.a *= getAlpha();"
+        EOL"  return aColor;"
+        EOL"}";
+
+      aSrcFragMainGetColor =
+        EOL"  vec4 aColor = getColor();"
+        EOL"  if (aColor.a <= 0.1) discard;"
+        EOL"  gl_FragColor = aColor;";
+    }
+    else if ((theBits & OpenGl_PO_TextureRGB) != 0)
+    {
+      aSrcFragGetColor =
+        EOL"vec4 getColor(void) { return texture2D(occActiveSampler, gl_PointCoord); }";
+      aSrcFragMainGetColor =
+        EOL"  vec4 aColor = getColor();"
+        EOL"  if (aColor.a <= 0.1) discard;"
+        EOL"  gl_FragColor = aColor;";
+    }
+  }
+  if ((theBits & OpenGl_PO_VertColor) != 0)
+  {
+    aSrcVertExtraOut  += EOL"varying vec4 VertColor;";
+    aSrcVertExtraMain += EOL"  VertColor = occVertColor;";
+    aSrcFragExtraOut  += EOL"varying vec4 VertColor;";
+    aSrcFragGetColor  =  EOL"vec4 getColor(void) { return VertColor; }";
+  }
+  if ((theBits & OpenGl_PO_ClipPlanes) != 0)
+  {
+    const char THE_POS_VARY[] =
+      EOL"varying vec4 PositionWorld;"
+      EOL"varying vec4 Position;";
+
+    aSrcVertExtraOut  += THE_POS_VARY;
+    aSrcFragExtraOut  += THE_POS_VARY;
+    aSrcVertExtraMain +=
+      EOL"  PositionWorld = occModelWorldMatrix * occVertex;"
+      EOL"  Position      = occWorldViewMatrix * PositionWorld;";
+    aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
+  }
+
+  aSrcVert =
+      aSrcVertExtraOut
+    + EOL"void main()"
+      EOL"{"
+    + aSrcVertExtraMain
+    + EOL"  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
+      EOL"}";
+
+  aSrcFrag =
+      aSrcFragExtraOut
+    + aSrcFragGetColor
+    + EOL"void main()"
+      EOL"{"
+    + aSrcFragExtraMain
+    + aSrcFragMainGetColor
+    + EOL"}";
+
+  aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
+  aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
+
+  TCollection_AsciiString aKey;
+  if (!Create (aProgramSrc, aKey, theProgram))
+  {
+    theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
+    return Standard_False;
+  }
+  return Standard_True;
+}
+
+// =======================================================================
+// function : prepareStdProgramGouraud
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram,
+                                                                 const Standard_Integer        theBits)
+{
+  Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
+  TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
+  if ((theBits & OpenGl_PO_Point) != 0)
+  {
+  #if defined(GL_ES_VERSION_2_0)
+    aSrcVertExtraMain += EOL"  gl_PointSize = occPointSize;";
+  #endif
+  }
+  if ((theBits & OpenGl_PO_ClipPlanes) != 0)
+  {
+    const char THE_POS_VARY[] =
+      EOL"varying vec4 PositionWorld;"
+      EOL"varying vec4 Position;";
+
+    aSrcVertExtraOut  += THE_POS_VARY;
+    aSrcFragExtraOut  += THE_POS_VARY;
+    aSrcVertExtraMain +=
+      EOL"  PositionWorld = aPositionWorld;"
+      EOL"  Position      = aPosition;";
+    aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
+  }
+
+  aSrcVert = TCollection_AsciiString()
+    + THE_FUNC_transformNormal
+    + EOL
+    + THE_FUNC_lightDef
+    + THE_FUNC_pointLight
+    + THE_FUNC_spotLight
+    + THE_FUNC_directionalLight
+    + EOL
+    + THE_FUNC_computeLighting
+    + EOL
+      EOL"varying vec4 FrontColor;"
+      EOL"varying vec4 BackColor;"
+      EOL
+    + aSrcVertExtraOut
+    + EOL"void main()"
+      EOL"{"
+      EOL"  vec4 aPositionWorld = occModelWorldMatrix * occVertex;"
+      EOL"  vec4 aPosition      = occWorldViewMatrix * aPositionWorld;"
+      EOL"  vec3 aNormal        = transformNormal (occNormal);"
+      EOL"  vec3 aView          = vec3 (0.0, 0.0, 1.0);"
+      EOL"  FrontColor  = computeLighting (normalize (aNormal), normalize (aView), aPosition, true);"
+      EOL"  BackColor   = computeLighting (normalize (aNormal), normalize (aView), aPosition, false);"
+    + aSrcVertExtraMain
+    + EOL"  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
+      EOL"}";
+
+  aSrcFrag = TCollection_AsciiString()
+    + EOL"varying vec4 FrontColor;"
+      EOL"varying vec4 BackColor;"
+    + aSrcFragExtraOut
+    + EOL"void main()"
+      EOL"{"
+    + aSrcFragExtraMain
+    + EOL"  gl_FragColor = gl_FrontFacing ? FrontColor : BackColor;"
+      EOL"}";
+
+  aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
+  aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
+  TCollection_AsciiString aKey;
+  if (!Create (aProgramSrc, aKey, theProgram))
+  {
+    theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
+    return Standard_False;
+  }
+  return Standard_True;
+}
+
+// =======================================================================
+// function : prepareStdProgramPhong
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
+                                                               const Standard_Integer        theBits)
+{
+  Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
+  TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraMain;
+  if ((theBits & OpenGl_PO_Point) != 0)
+  {
+  #if defined(GL_ES_VERSION_2_0)
+    aSrcVertExtraMain += EOL"  gl_PointSize = occPointSize;";
+  #endif
+  }
+  if ((theBits & OpenGl_PO_ClipPlanes) != 0)
+  {
+    aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
+  }
+
+  aSrcVert = TCollection_AsciiString()
+    + THE_FUNC_transformNormal
+    + EOL
+      EOL"varying vec4 PositionWorld;"
+      EOL"varying vec4 Position;"
+      EOL"varying vec3 Normal;"
+      EOL"varying vec3 View;"
+      EOL
+    + aSrcVertExtraOut
+    + EOL"void main()"
+      EOL"{"
+      EOL"  PositionWorld = occModelWorldMatrix * occVertex;"
+      EOL"  Position      = occWorldViewMatrix * PositionWorld;"
+      EOL"  Normal        = transformNormal (occNormal);"
+      EOL"  View          = vec3 (0.0, 0.0, 1.0);"
+    + aSrcVertExtraMain
+    + EOL"  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
+      EOL"}";
+
+  aSrcFrag = TCollection_AsciiString()
+    + EOL"varying vec4 PositionWorld;"
+      EOL"varying vec4 Position;"
+      EOL"varying vec3 Normal;"
+      EOL"varying vec3 View;"
+    + EOL
+    + THE_FUNC_lightDef
+    + THE_FUNC_pointLight
+    + THE_FUNC_spotLight
+    + THE_FUNC_directionalLight
+    + EOL
+    + THE_FUNC_computeLighting
+    + EOL
+      EOL"void main()"
+      EOL"{"
+    + aSrcFragExtraMain
+    + EOL"  gl_FragColor = computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing);"
+      EOL"}";
+
+  aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
+  aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
+  TCollection_AsciiString aKey;
+  if (!Create (aProgramSrc, aKey, theProgram))
+  {
+    theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
+    return Standard_False;
+  }
+  return Standard_True;
+}
+
+// =======================================================================
+// function : bindProgramWithState
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram,
+                                                             const OpenGl_Element*               theAspect)
+{
+  if (!myContext->BindProgram (theProgram))
+  {
+    return Standard_False;
+  }
+  theProgram->ApplyVariables (myContext);
+
+  const OpenGl_MaterialState* aMaterialState = MaterialState (theProgram);
+  if (aMaterialState == NULL || aMaterialState->Aspect() != theAspect)
+  {
+    UpdateMaterialStateTo (theProgram, theAspect);
+  }
+
+  PushState (theProgram);
+  return Standard_True;
+}
index 1da56c2..94b3e10 100755 (executable)
 #include <Handle_OpenGl_ShaderManager.hxx>
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_ShaderStates.hxx>
+#include <OpenGl_AspectFace.hxx>
+#include <OpenGl_AspectLine.hxx>
+#include <OpenGl_AspectText.hxx>
+#include <OpenGl_AspectMarker.hxx>
+#include <OpenGl_Texture.hxx>
+#include <Visual3d_TypeOfModel.hxx>
 
 class OpenGl_View;
 
@@ -33,6 +39,17 @@ typedef NCollection_Sequence<Handle(OpenGl_ShaderProgram)> OpenGl_ShaderProgramL
 //! Map to declare per-program states of OCCT materials.
 typedef NCollection_DataMap<Handle(OpenGl_ShaderProgram), OpenGl_MaterialState> OpenGl_MaterialStates;
 
+//! Standard GLSL program combination bits.
+enum OpenGl_ProgramOptions
+{
+  OpenGl_PO_ClipPlanes = 0x01, //!< handle clipping planes
+  OpenGl_PO_Point      = 0x02, //!< point marker
+  OpenGl_PO_VertColor  = 0x04, //!< per-vertex color
+  OpenGl_PO_TextureRGB = 0x08, //!< handle RGB   texturing
+  OpenGl_PO_TextureA   = 0x10, //!< handle Alpha texturing
+  OpenGl_PO_NB         = 0x20  //!< overall number of combinations
+};
+
 //! This class is responsible for managing shader programs.
 class OpenGl_ShaderManager : public Standard_Transient
 {
@@ -50,9 +67,10 @@ public:
   //! @param theProxy    [IN]  program definition
   //! @param theShareKey [OUT] sharing key
   //! @param theProgram  [OUT] OpenGL program
-  Standard_EXPORT void Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
-                               TCollection_AsciiString&               theShareKey,
-                               Handle(OpenGl_ShaderProgram)&          theProgram);
+  //! @return true on success
+  Standard_EXPORT Standard_Boolean Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
+                                           TCollection_AsciiString&               theShareKey,
+                                           Handle(OpenGl_ShaderProgram)&          theProgram);
 
   //! Unregisters specified shader program.
   Standard_EXPORT void Unregister (TCollection_AsciiString&      theShareKey,
@@ -64,16 +82,76 @@ public:
   //! Returns true if no program objects are registered in the manager.
   Standard_EXPORT Standard_Boolean IsEmpty() const;
 
-  DEFINE_STANDARD_RTTI (OpenGl_ShaderManager)
+  //! Bind program for filled primitives rendering
+  Standard_Boolean BindProgram (const OpenGl_AspectFace*            theAspect,
+                                const Handle(OpenGl_Texture)&       theTexture,
+                                const Standard_Boolean              theToLightOn,
+                                const Standard_Boolean              theHasVertColor,
+                                const Handle(OpenGl_ShaderProgram)& theCustomProgram)
+  {
+    if (!theCustomProgram.IsNull()
+     || myContext->caps->ffpEnable)
+    {
+      return bindProgramWithState (theCustomProgram, theAspect);
+    }
+
+    const Standard_Integer        aBits    = getProgramBits (theTexture, theHasVertColor);
+    Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theToLightOn, aBits);
+    return bindProgramWithState (aProgram, theAspect);
+  }
 
-protected:
+  //! Bind program for line rendering
+  Standard_Boolean BindProgram (const OpenGl_AspectLine*            theAspect,
+                                const Handle(OpenGl_Texture)&       theTexture,
+                                const Standard_Boolean              theToLightOn,
+                                const Standard_Boolean              theHasVertColor,
+                                const Handle(OpenGl_ShaderProgram)& theCustomProgram)
+  {
+    if (!theCustomProgram.IsNull()
+     || myContext->caps->ffpEnable)
+    {
+      return bindProgramWithState (theCustomProgram, theAspect);
+    }
+
+    const Standard_Integer        aBits    = getProgramBits (theTexture, theHasVertColor);
+    Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theToLightOn, aBits);
+    return bindProgramWithState (aProgram, theAspect);
+  }
 
-  OpenGl_MaterialStates   myMaterialStates;   //!< Per-program state of OCCT material
-  OpenGl_ProjectionState  myProjectionState;  //!< State of OCCT projection transformation
-  OpenGl_ModelWorldState  myModelWorldState;  //!< State of OCCT model-world transformation
-  OpenGl_WorldViewState   myWorldViewState;   //!< State of OCCT world-view transformation
-  OpenGl_LightSourceState myClippingState;    //!< State of OCCT clipping planes
-  OpenGl_LightSourceState myLightSourceState; //!< State of OCCT light sources
+  //! Bind program for point rendering
+  Standard_Boolean BindProgram (const OpenGl_AspectMarker*          theAspect,
+                                const Handle(OpenGl_Texture)&       theTexture,
+                                const Standard_Boolean              theToLightOn,
+                                const Standard_Boolean              theHasVertColor,
+                                const Handle(OpenGl_ShaderProgram)& theCustomProgram)
+  {
+    if (!theCustomProgram.IsNull()
+     || myContext->caps->ffpEnable)
+    {
+      return bindProgramWithState (theCustomProgram, theAspect);
+    }
+
+    const Standard_Integer        aBits    = getProgramBits (theTexture, theHasVertColor) | OpenGl_PO_Point;
+    Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theToLightOn, aBits);
+    return bindProgramWithState (aProgram, theAspect);
+  }
+
+  //! Bind program for rendering alpha-textured font.
+  Standard_Boolean BindProgram (const OpenGl_AspectText*            theAspect,
+                                const Handle(OpenGl_ShaderProgram)& theCustomProgram)
+  {
+    if (!theCustomProgram.IsNull()
+     || myContext->caps->ffpEnable)
+    {
+      return bindProgramWithState (theCustomProgram, theAspect);
+    }
+
+    if (myFontProgram.IsNull())
+    {
+      prepareStdProgramFont();
+    }
+    return bindProgramWithState (myFontProgram, theAspect);
+  }
 
 public:
 
@@ -167,6 +245,15 @@ public:
     myContext = theCtx;
   }
 
+  //! Sets shading model.
+  void SetShadingModel(const Visual3d_TypeOfModel theModel)
+  {
+    myLightPrograms = theModel == Visual3d_TOM_FRAGMENT
+                    ? myLightPrograms = myPhongPrograms
+                    : myLightPrograms = myGouraudPrograms;
+    myShadingModel = theModel;
+  }
+
   //! Sets last view manger used with.
   //! Helps to handle matrix states in multi-view configurations.
   void SetLastView (const OpenGl_View* theLastView)
@@ -182,12 +269,106 @@ public:
 
 protected:
 
-  OpenGl_ShaderProgramList myProgramList;  //!< The list of shader programs
-  OpenGl_Context*          myContext;      //!< The OpenGL context
+  //! Define program bits.
+  Standard_Integer getProgramBits (const Handle(OpenGl_Texture)& theTexture,
+                                   const Standard_Boolean        theHasVertColor)
+  {
+    Standard_Integer aBits = 0;
+    if (myContext->Clipping().IsClippingOrCappingOn())
+    {
+      aBits |= OpenGl_PO_ClipPlanes;
+    }
+    if (!theTexture.IsNull())
+    {
+      // GL_RED to be handled
+      aBits |= theTexture->GetFormat() == GL_ALPHA ? OpenGl_PO_TextureA : OpenGl_PO_TextureRGB;
+    }
+    if (theHasVertColor)
+    {
+      aBits |= OpenGl_PO_VertColor;
+    }
+    return aBits;
+  }
+
+  //! Prepare standard GLSL program.
+  Handle(OpenGl_ShaderProgram)& getStdProgram (const Standard_Boolean theToLightOn,
+                                               const Standard_Integer theBits)
+  {
+    if (theToLightOn)
+    {
+      Handle(OpenGl_ShaderProgram)& aProgram = myLightPrograms[theBits];
+      if (aProgram.IsNull())
+      {
+        prepareStdProgramLight (aProgram, theBits);
+      }
+      return aProgram;
+    }
+
+    Handle(OpenGl_ShaderProgram)& aProgram = myFlatPrograms[theBits];
+    if (aProgram.IsNull())
+    {
+      prepareStdProgramFlat (aProgram, theBits);
+    }
+    return aProgram;
+  }
+
+  //! Prepare standard GLSL program for textured font.
+  Standard_EXPORT Standard_Boolean prepareStdProgramFont();
+
+  //! Prepare standard GLSL program without lighting.
+  Standard_EXPORT Standard_Boolean prepareStdProgramFlat (Handle(OpenGl_ShaderProgram)& theProgram,
+                                                          const Standard_Integer        theBits);
+
+  //! Prepare standard GLSL program with lighting.
+  Standard_Boolean prepareStdProgramLight (Handle(OpenGl_ShaderProgram)& theProgram,
+                                           const Standard_Integer        theBits)
+  {
+    return myShadingModel == Visual3d_TOM_FRAGMENT
+         ? prepareStdProgramPhong   (theProgram, theBits)
+         : prepareStdProgramGouraud (theProgram, theBits);
+  }
+
+  //! Prepare standard GLSL program with per-vertex lighting.
+  Standard_EXPORT Standard_Boolean prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram,
+                                                             const Standard_Integer        theBits);
+
+  //! Prepare standard GLSL program with per-pixel lighting.
+  Standard_EXPORT Standard_Boolean prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
+                                                           const Standard_Integer        theBits);
+
+  //! Bind specified program to current context and apply state.
+  Standard_EXPORT Standard_Boolean bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram,
+                                                         const OpenGl_Element*               theAspect);
+
+protected:
+
+  Visual3d_TypeOfModel          myShadingModel;                  //!< lighting shading model
+  OpenGl_ShaderProgramList      myProgramList;                   //!< The list of shader programs
+  Handle(OpenGl_ShaderProgram)* myLightPrograms;                 //!< pointer to active lighting programs matrix, depending on shading model and lights configuration
+  Handle(OpenGl_ShaderProgram)  myGouraudPrograms[OpenGl_PO_NB]; //!< matrix with per-vertex   lighting programs
+  Handle(OpenGl_ShaderProgram)  myPhongPrograms  [OpenGl_PO_NB]; //!< matrix with per-fragment lighting programs
+  Handle(OpenGl_ShaderProgram)  myFlatPrograms   [OpenGl_PO_NB]; //!< programs matrix without  lighting
+  Handle(OpenGl_ShaderProgram)  myFontProgram;                   //!< standard program for textured text
+
+  OpenGl_Context*               myContext;                       //!< OpenGL context
+
+protected:
+
+  OpenGl_MaterialStates         myMaterialStates;                //!< Per-program state of OCCT material
+  OpenGl_ProjectionState        myProjectionState;               //!< State of OCCT projection  transformation
+  OpenGl_ModelWorldState        myModelWorldState;               //!< State of OCCT model-world transformation
+  OpenGl_WorldViewState         myWorldViewState;                //!< State of OCCT world-view  transformation
+  OpenGl_LightSourceState       myClippingState;                 //!< State of OCCT clipping planes
+  OpenGl_LightSourceState       myLightSourceState;              //!< State of OCCT light sources
 
 private:
 
-  const OpenGl_View*       myLastView;     //!< Pointer to the last view shader manager used with.
+  const OpenGl_View*            myLastView;                      //!< Pointer to the last view shader manager used with
+
+public:
+
+  DEFINE_STANDARD_RTTI (OpenGl_ShaderManager)
+
 };
 
 #endif // _OpenGl_ShaderManager_HeaderFile
index 4931090..a0e027e 100755 (executable)
@@ -59,7 +59,10 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
   "occTextureEnable",      // OpenGl_OCCT_TEXTURE_ENABLE
   "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
   "occFrontMaterial",      // OpenGl_OCCT_FRONT_MATERIAL
-  "occBackMaterial"        // OpenGl_OCCT_BACK_MATERIAL
+  "occBackMaterial",       // OpenGl_OCCT_BACK_MATERIAL
+  "occColor",              // OpenGl_OCCT_COLOR
+
+  "occPointSize"           // OpenGl_OCCT_POINT_SIZE
 
 };
 
@@ -208,9 +211,23 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     }
 
     TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
-    if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX)
+    switch (anIter.Value()->Type())
     {
-      aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
+      case Graphic3d_TOS_VERTEX:
+      {
+        aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
+        break;
+      }
+      case Graphic3d_TOS_FRAGMENT:
+      {
+      #if defined(GL_ES_VERSION_2_0)
+        TCollection_AsciiString aPrefix (theCtx->hasHighp
+                                       ? "precision highp float;\n"
+                                       : "precision mediump float;\n");
+        aSource = aPrefix + aSource;
+      #endif
+        break;
+      }
     }
 
     if (!aShader->LoadSource (theCtx, aSource))
@@ -267,7 +284,7 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
   SetAttributeName (theCtx, Graphic3d_TOA_POS,   "occVertex");
   SetAttributeName (theCtx, Graphic3d_TOA_NORM,  "occNormal");
   SetAttributeName (theCtx, Graphic3d_TOA_UV,    "occTexCoord");
-  SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occColor");
+  SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
 
   if (!Link (theCtx))
   {
index 9b5163f..c65124c 100755 (executable)
@@ -64,6 +64,9 @@ enum OpenGl_StateVariable
   OpenGl_OCCT_DISTINGUISH_MODE,
   OpenGl_OCCT_FRONT_MATERIAL,
   OpenGl_OCCT_BACK_MATERIAL,
+  OpenGl_OCCT_COLOR,
+
+  OpenGl_OCCT_POINT_SIZE,
 
   // DON'T MODIFY THIS ITEM (insert new items before it)
   OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES
@@ -502,8 +505,7 @@ protected:
 
 protected:
 
-  //! Defines last modification for variables of each state type.
-  Standard_Size myCurrentState[MaxStateTypes];
+  Standard_Size myCurrentState[MaxStateTypes];  //!< defines last modification for variables of each state type
 
   //! Stores locations of OCCT state uniform variables.
   GLint myStateLocations[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES];
index fcb775c..d991609 100755 (executable)
@@ -384,7 +384,7 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 
   if (aCtx->IsGlGreaterEqual (2, 0))
   {
-    const Handle(OpenGl_ShaderProgram)& aProgram = aTextAspect->ShaderProgramRes (theWorkspace);
+    const Handle(OpenGl_ShaderProgram)& aProgram = aTextAspect->ShaderProgramRes (aCtx);
     aCtx->BindProgram (aProgram);
     if (!aProgram.IsNull())
     {
index 4296d78..72aafc4 100644 (file)
@@ -54,7 +54,7 @@ OpenGl_Texture::OpenGl_Texture (const Handle(Graphic3d_TextureParams)& theParams
   myTarget (GL_TEXTURE_2D),
   mySizeX (0),
   mySizeY (0),
-  myTextFormat (GL_FLOAT),
+  myTextFormat (GL_RGBA),
   myHasMipmaps (Standard_False),
   myParams     (theParams)
 {
@@ -313,7 +313,13 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
     return false;
   }
   myHasMipmaps             = Standard_False;
-  myTextFormat             = theTextFormat;
+  myTextFormat             = thePixelFormat;
+#if !defined(GL_ES_VERSION_2_0)
+  const GLint anIntFormat  = theTextFormat;
+#else
+  // ES does not support sized formats and format conversions - them detected from data type
+  const GLint anIntFormat  = thePixelFormat;
+#endif
   const GLsizei aWidth     = theSizeX;
   const GLsizei aHeight    = theSizeY;
   const GLsizei aMaxSize   = theCtx->MaxTextureSize();
@@ -380,7 +386,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
       }
 
       // use proxy to check texture could be created or not
-      glTexImage1D (GL_PROXY_TEXTURE_1D, 0, myTextFormat,
+      glTexImage1D (GL_PROXY_TEXTURE_1D, 0, anIntFormat,
                     aWidthOut, 0,
                     thePixelFormat, theDataType, NULL);
       glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
@@ -392,7 +398,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
         return false;
       }
 
-      glTexImage1D (GL_TEXTURE_1D, 0, myTextFormat,
+      glTexImage1D (GL_TEXTURE_1D, 0, anIntFormat,
                     aWidthOut, 0,
                     thePixelFormat, theDataType, aDataPtr);
       if (glGetError() != GL_NO_ERROR)
@@ -449,7 +455,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
 
     #if !defined(GL_ES_VERSION_2_0)
       // use proxy to check texture could be created or not
-      glTexImage2D (GL_PROXY_TEXTURE_2D, 0, myTextFormat,
+      glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
                     aWidthOut, aHeightOut, 0,
                     thePixelFormat, theDataType, NULL);
       glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,  &aTestWidth);
@@ -463,7 +469,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
       }
     #endif
 
-      glTexImage2D (GL_TEXTURE_2D, 0, myTextFormat,
+      glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
                     aWidthOut, aHeightOut, 0,
                     thePixelFormat, theDataType, aDataPtr);
       if (glGetError() != GL_NO_ERROR)
@@ -492,7 +498,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
       {
       #if !defined(GL_ES_VERSION_2_0)
         // use proxy to check texture could be created or not
-        glTexImage2D (GL_PROXY_TEXTURE_2D, 0, myTextFormat,
+        glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
                       aWidthOut, aHeightOut, 0,
                       thePixelFormat, theDataType, NULL);
         glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,  &aTestWidth);
@@ -507,7 +513,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
       #endif
 
         // upload main picture
-        glTexImage2D (GL_TEXTURE_2D, 0, myTextFormat,
+        glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
                       aWidthOut, aHeightOut, 0,
                       thePixelFormat, theDataType, theImage->Data());
         if (glGetError() != GL_NO_ERROR)
@@ -530,7 +536,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
       else
       {
       #if !defined(GL_ES_VERSION_2_0)
-        bool isCreated = gluBuild2DMipmaps (GL_TEXTURE_2D, myTextFormat,
+        bool isCreated = gluBuild2DMipmaps (GL_TEXTURE_2D, anIntFormat,
                                             aWidth, aHeight,
                                             thePixelFormat, theDataType, theImage->Data()) == 0;
         if (isCreated)
@@ -618,11 +624,12 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
     glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   }
 
-  myTextFormat = theFormat.Internal();
+  const GLint anIntFormat = theFormat.Internal();
+  myTextFormat = theFormat.Format();
 
   glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE,
                 0,
-                myTextFormat,
+                anIntFormat,
                 aSizeX,
                 aSizeY,
                 0,
@@ -646,7 +653,7 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
 
   glTexImage2D (myTarget,
                 0,
-                myTextFormat,
+                anIntFormat,
                 aSizeX,
                 aSizeY,
                 0,
index 6240ab6..476c4b1 100644 (file)
@@ -195,8 +195,8 @@ public:
     return myTextureId;
   }
 
-  //! @return texture format
-  inline GLint GetFormat() const
+  //! @return texture format (not sized)
+  inline GLenum GetFormat() const
   {
     return myTextFormat;
   }
@@ -262,7 +262,7 @@ protected:
   GLenum           myTarget;     //!< GL_TEXTURE_1D/GL_TEXTURE_2D
   GLsizei          mySizeX;      //!< texture width
   GLsizei          mySizeY;      //!< texture height
-  GLint            myTextFormat; //!< texture format - GL_RGB, GL_RGBA,...
+  GLenum           myTextFormat; //!< texture format - GL_RGB, GL_RGBA,...
   Standard_Boolean myHasMipmaps; //!< flag indicates that texture was uploaded with mipmaps
 
   Handle(Graphic3d_TextureParams) myParams; //!< texture parameters
index fb11b48..9cec1ce 100644 (file)
@@ -32,7 +32,7 @@ inline void OpenGl_VertexBuffer::bindAttribute (const Handle(OpenGl_Context)&
   }
 
   theCtx->core20fwd->glEnableVertexAttribArray (theAttribute);
-  theCtx->core20fwd->glVertexAttribPointer (theAttribute, theNbComp, theDataType, GL_FALSE, theStride, theOffset);
+  theCtx->core20fwd->glVertexAttribPointer (theAttribute, theNbComp, theDataType, theDataType != GL_FLOAT, theStride, theOffset);
 }
 
 #if !defined(GL_ES_VERSION_2_0)
index c74a924..56725e9 100644 (file)
@@ -68,7 +68,7 @@ OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
   myTrihedron(NULL),
   myGraduatedTrihedron(NULL),
   myVisualization(AContext.Visualization),
-  myIntShadingMethod(TEL_SM_GOURAUD),
+  myShadingModel ((Visual3d_TypeOfModel )AContext.Model),
   myAntiAliasing(Standard_False),
   myTransPers(&myDefaultTransPers),
   myIsTransPers(Standard_False),
@@ -77,21 +77,7 @@ OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
   myStateCounter (theCounter),
   myLastLightSourceState (0, 0)
 {
-
-  // 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;
-  }
-
   myCurrLightSourceState = myStateCounter->Increment();
-
   myModificationState = 1; // initial state
 }
 
@@ -177,17 +163,7 @@ void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
 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;
-  }
+  myShadingModel  = (Visual3d_TypeOfModel )AContext.Model;
 }
 
 /*----------------------------------------------------------------------*/
index 527fa59..bbb90ca 100644 (file)
@@ -36,6 +36,7 @@
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
 #include <Graphic3d_ZLayerSettings.hxx>
 #include <Visual3d_TypeOfSurfaceDetail.hxx>
+#include <Visual3d_TypeOfModel.hxx>
 
 #include <OpenGl_BVHTreeSelector.hxx>
 #include <OpenGl_LayerList.hxx>
@@ -257,7 +258,7 @@ protected:
 
   //View_LABViewContext
   int myVisualization;
-  int myIntShadingMethod;
+  Visual3d_TypeOfModel       myShadingModel;  //!< lighting shading model
 
   //View_LABLight
   OpenGl_ListOfLight myLights;
index 7252e06..d8c5465 100644 (file)
@@ -366,25 +366,24 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
 
 #if !defined(GL_ES_VERSION_2_0)
-  // Store and disable current clipping planes
-  Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
-
-  OPENGL_CLIP_PLANE *aOldPlanes = new OPENGL_CLIP_PLANE[aMaxPlanes];
-  OPENGL_CLIP_PLANE *aPtrPlane = aOldPlanes;
-
-  GLenum aClipPlaneId = GL_CLIP_PLANE0;
-  const GLenum aClipLastId = GL_CLIP_PLANE0 + aMaxPlanes;
-  for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
+  // store and disable current clipping planes
+  const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
+  NCollection_Array1<OPENGL_CLIP_PLANE> aOldPlanes (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + aMaxPlanes - 1);
+  if (aContext->core11 != NULL)
   {
-    glGetClipPlane (aClipPlaneId, aPtrPlane->Equation);
-    if (aPtrPlane->isEnabled)
+    for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
     {
-      glDisable (aClipPlaneId);
-      aPtrPlane->isEnabled = GL_TRUE;
-    }
-    else
-    {
-      aPtrPlane->isEnabled = GL_FALSE;
+      OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
+      aContext->core11->glGetClipPlane (aClipPlaneId, aPlane.Equation);
+      if (aPlane.isEnabled)
+      {
+        aContext->core11fwd->glDisable (aClipPlaneId);
+        aPlane.isEnabled = GL_TRUE;
+      }
+      else
+      {
+        aPlane.isEnabled = GL_FALSE;
+      }
     }
   }
 #endif
@@ -403,7 +402,8 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   }
 
   // Set OCCT state uniform variables
-  const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
+  const Handle(OpenGl_ShaderManager) aManager   = aContext->ShaderManager();
+  const Standard_Boolean             isSameView = aManager->IsSameView (this); // force camera state update when needed
   if (!aManager->IsEmpty())
   {
     if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
@@ -412,13 +412,15 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
       myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
     }
 
-    if (myProjectionState != myCamera->ProjectionState())
+    if (myProjectionState != myCamera->ProjectionState()
+    || !isSameView)
     {
       myProjectionState = myCamera->ProjectionState();
       aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
     }
 
-    if (myModelViewState != myCamera->ModelViewState())
+    if (myModelViewState != myCamera->ModelViewState()
+    || !isSameView)
     {
       myModelViewState = myCamera->ModelViewState();
       aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
@@ -435,19 +437,6 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     }
   }
 
-  if (!aManager.IsNull())
-  {
-    if (!aManager->IsSameView (this))
-    {
-      // Force update camera states
-      myProjectionState = myCamera->ProjectionState();
-      aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
-
-      myModelViewState = myCamera->ModelViewState();
-      aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
-    }
-  }
-
   if (isProjectionMatUpdateNeeded
    || isOrientationMatUpdateNeeded)
   {
@@ -537,9 +526,12 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     glDisable(GL_FOG);
 
   // Apply InteriorShadingMethod
-  glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
+  aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET
+                               || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH);
 #endif
 
+  aManager->SetShadingModel (myShadingModel);
+
   // Apply AntiAliasing
   if (myAntiAliasing)
     theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
@@ -646,21 +638,20 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   //      Step 7: Finalize
   // ===============================
 
-  // Restore clipping planes
 #if !defined(GL_ES_VERSION_2_0)
-  aClipPlaneId = GL_CLIP_PLANE0;
-  aPtrPlane = aOldPlanes;
-
-  for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
+  // restore clipping planes
+  if (aContext->core11 != NULL)
   {
-    glClipPlane (aClipPlaneId, aPtrPlane->Equation);
-    if (aPtrPlane->isEnabled)
-      glEnable (aClipPlaneId);
-    else
-      glDisable (aClipPlaneId);
+    for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
+    {
+      const OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
+      aContext->core11->glClipPlane (aClipPlaneId, aPlane.Equation);
+      if (aPlane.isEnabled)
+        aContext->core11fwd->glEnable (aClipPlaneId);
+      else
+        aContext->core11fwd->glDisable (aClipPlaneId);
+    }
   }
-
-  delete[] aOldPlanes;
 #endif
 
   // ==============================================================
index 77041d8..c43f1de 100644 (file)
@@ -227,6 +227,7 @@ public:
   Standard_EXPORT Handle(OpenGl_Texture) DisableTexture();
   Standard_EXPORT Handle(OpenGl_Texture) EnableTexture (const Handle(OpenGl_Texture)&          theTexture,
                                                         const Handle(Graphic3d_TextureParams)& theParams = NULL);
+  const Handle(OpenGl_Texture)& ActiveTexture() const { return myTextureBound; }
 
   //! Set filter for restricting rendering of particular elements.
   //! Filter can be applied for rendering passes used by recursive
index f8f3703..2d4b07e 100644 (file)
@@ -455,7 +455,7 @@ const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean th
   {
     if (AspectFace_set->DoTextureMap())
     {
-      EnableTexture (AspectFace_set->TextureRes (this),
+      EnableTexture (AspectFace_set->TextureRes (myGlContext),
                      AspectFace_set->TextureParams());
     }
     else
index a23cf64..15f8837 100644 (file)
 #define THE_MAX_CLIP_PLANES 8
 
 // Vertex attributes
-// Note: At the moment, we just 'rename' the default OpenGL
-// vertex attributes from compatibility profile. In the next
-// release old functionality will be removed from shader API.
 #ifdef VERTEX_SHADER
   attribute vec4 occVertex;
   attribute vec3 occNormal;
   attribute vec4 occTexCoord;
-  attribute vec4 occColor;
+  attribute vec4 occVertColor;
 #endif
 
 // Matrix state
@@ -73,7 +70,7 @@ vec4  occFrontMaterial_Specular(void);     //!< Specular reflection
 float occFrontMaterial_Shininess(void);    //!< Specular exponent
 float occFrontMaterial_Transparency(void); //!< Transparency coefficient
 
-// Front material properties accessors
+// Back material properties accessors
 vec4  occBackMaterial_Emission(void);      //!< Emission color
 vec4  occBackMaterial_Ambient(void);       //!< Ambient  reflection
 vec4  occBackMaterial_Diffuse(void);       //!< Diffuse  reflection
@@ -81,9 +78,11 @@ vec4  occBackMaterial_Specular(void);      //!< Specular reflection
 float occBackMaterial_Shininess(void);     //!< Specular exponent
 float occBackMaterial_Transparency(void);  //!< Transparency coefficient
 
+uniform vec4      occColor;                //!< color value (in case of disabled lighting)
 uniform int       occDistinguishingMode;   //!< Are front and back faces distinguished?
 uniform int       occTextureEnable;        //!< Is texture enabled?
 uniform sampler2D occActiveSampler;        //!< Current active sampler
+uniform float     occPointSize;            //!< point size
 
 // clipping planes state
 const int OccEquationCoords_View  = 0; //!< view-space  clipping plane
index 9cb26f6..8016462 100644 (file)
@@ -72,15 +72,14 @@ is
         end TypeOfView ;
         ---Purpose: Defines the type of projection of the view.
 
-        enumeration TypeOfShadingModel is COLOR,MULTICOLOR,FLAT,GOURAUD,HIDDEN
+        enumeration TypeOfShadingModel is COLOR,FLAT,GOURAUD,PHONG
               end TypeOfShadingModel ;
         ---Purpose:
         -- Defines the type of shading for the graphic object:
-        -- -   V3d_COLOR: simple surface color,
-        -- -   V3d_MULTICOLOR: interpolated colors,
-        -- -   V3d_FLAT: flat shading,
-        -- -   V3d_GOURAUD: Gouraud shading,
-        -- -   V3d_HIDDEN: hidden line removal.
+        -- -   V3d_COLOR: simple surface color (Visual3d_TOM_NONE),
+        -- -   V3d_FLAT: flat shading (Visual3d_TOM_FACET),
+        -- -   V3d_GOURAUD: Gouraud shading (Visual3d_TOM_VERTEX),
+        -- -   V3d_PHONG: Phong shading (Visual3d_TOM_FRAGMENT).
 
         enumeration  TypeOfSurfaceDetail  is  TEX_NONE, TEX_ENVIRONMENT, TEX_ALL
                end TypeOfSurfaceDetail;
index 8ec91b4..8525d3e 100644 (file)
@@ -29,6 +29,7 @@
 #include <Graphic3d_TypeOfTextureFilter.hxx>
 #include <Graphic3d_AspectFillArea3d.hxx>
 #include <ViewerTest.hxx>
+#include <ViewerTest_AutoUpdater.hxx>
 #include <ViewerTest_EventManager.hxx>
 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
   #include <tk.h>
 #endif
 
+inline Standard_Boolean parseOnOff (Standard_CString  theArg,
+                                    Standard_Boolean& theIsOn)
+{
+  TCollection_AsciiString aFlag (theArg);
+  aFlag.LowerCase();
+  if (aFlag == "on"
+   || aFlag == "1")
+  {
+    theIsOn = Standard_True;
+    return Standard_True;
+  }
+  else if (aFlag == "off"
+        || aFlag == "0")
+  {
+    theIsOn = Standard_False;
+    return Standard_True;
+  }
+  return Standard_False;
+}
+
 // Auxiliary definitions
 static const char THE_KEY_DELETE = 127;
 
@@ -4121,10 +4142,10 @@ static int VCaps (Draw_Interpretor& theDI,
 {
   OpenGl_Caps* aCaps = &ViewerTest_myDefaultCaps;
   Handle(OpenGl_GraphicDriver)   aDriver;
-  Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
-  if (!aContextAIS.IsNull())
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+  if (!aContext.IsNull())
   {
-    aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
+    aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
     aCaps   = &aDriver->ChangeOptions();
   }
 
@@ -4133,27 +4154,76 @@ static int VCaps (Draw_Interpretor& theDI,
     theDI << "VBO:     " << (aCaps->vboDisable        ? "0" : "1") << "\n";
     theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
     theDI << "SoftMode:" << (aCaps->contextNoAccel    ? "1" : "0") << "\n";
+    theDI << "FFP:     " << (aCaps->ffpEnable         ? "1" : "0") << "\n";
     return 0;
   }
 
+  ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
   {
-    const TCollection_AsciiString anArg (theArgVec[anArgIter]);
-    if (anArg.Search ("vbo=") > -1)
+    Standard_CString        anArg     = theArgVec[anArgIter];
+    TCollection_AsciiString anArgCase (anArg);
+    anArgCase.LowerCase();
+    if (anUpdateTool.parseRedrawMode (anArg))
+    {
+      continue;
+    }
+    else if (anArgCase == "-ffp")
+    {
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aCaps->ffpEnable = toEnable;
+    }
+    else if (anArgCase == "-vbo")
     {
-      aCaps->vboDisable        = anArg.Token ("=", 2).IntegerValue() == 0;
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aCaps->vboDisable = !toEnable;
     }
-    else if (anArg.Search ("sprites=") > -1)
+    else if (anArgCase == "-sprite"
+          || anArgCase == "-sprites")
     {
-      aCaps->pntSpritesDisable = anArg.Token ("=", 2).IntegerValue() == 0;
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aCaps->pntSpritesDisable = !toEnable;
     }
-    else if (anArg.Search ("soft=") > -1)
+    else if (anArgCase == "-softmode")
     {
-      aCaps->contextNoAccel = anArg.Token ("=", 2).IntegerValue() != 0;
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aCaps->contextNoAccel = toEnable;
+    }
+    else if (anArgCase == "-accel"
+          || anArgCase == "-acceleration")
+    {
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aCaps->contextNoAccel = !toEnable;
     }
     else
     {
-      std::cerr << "Unknown argument: " << anArg << "\n";
+      std::cout << "Error: unknown argument '" << anArg << "'\n";
+      return 1;
     }
   }
   if (aCaps != &ViewerTest_myDefaultCaps)
@@ -6504,24 +6574,6 @@ static int VLight (Draw_Interpretor& theDi,
   return 0;
 }
 
-inline Standard_Boolean parseOnOff (Standard_CString  theArg,
-                                    Standard_Boolean& theIsOn)
-{
-  TCollection_AsciiString aFlag (theArg);
-  aFlag.LowerCase();
-  if (aFlag == "on")
-  {
-    theIsOn = Standard_True;
-    return Standard_True;
-  }
-  else if (aFlag == "off")
-  {
-    theIsOn = Standard_False;
-    return Standard_True;
-  }
-  return Standard_False;
-}
-
 //=======================================================================
 //function : VRenderParams
 //purpose  : Enables/disables rendering features
@@ -6588,24 +6640,39 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       case Graphic3d_RM_RAYTRACING:    theDI << "raytrace ";      break;
     }
     theDI << "\n";
-    theDI << "fsaa:        " << (aParams.IsAntialiasingEnabled      ? "on" : "off") << "\n";
-    theDI << "shadows:     " << (aParams.IsShadowEnabled            ? "on" : "off") << "\n";
-    theDI << "reflections: " << (aParams.IsReflectionEnabled        ? "on" : "off") << "\n";
-    theDI << "rayDepth:    " <<  aParams.RaytracingDepth                            << "\n";
-    theDI << "gleam:       " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
+    theDI << "fsaa:         " << (aParams.IsAntialiasingEnabled      ? "on" : "off") << "\n";
+    theDI << "shadows:      " << (aParams.IsShadowEnabled            ? "on" : "off") << "\n";
+    theDI << "reflections:  " << (aParams.IsReflectionEnabled        ? "on" : "off") << "\n";
+    theDI << "rayDepth:     " <<  aParams.RaytracingDepth                            << "\n";
+    theDI << "gleam:        " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
+    theDI << "shadingModel: ";
+    switch (aView->ShadingModel())
+    {
+      case V3d_COLOR:   theDI << "color";   break;
+      case V3d_FLAT:    theDI << "flat";    break;
+      case V3d_GOURAUD: theDI << "gouraud"; break;
+      case V3d_PHONG:   theDI << "phong";   break;
+    }
+    theDI << "\n";
     return 0;
   }
 
   Standard_Boolean toPrint = Standard_False;
+  ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
   {
     Standard_CString        anArg (theArgVec[anArgIter]);
     TCollection_AsciiString aFlag (anArg);
     aFlag.LowerCase();
-    if (aFlag == "-echo"
-     || aFlag == "-print")
+    if (anUpdateTool.parseRedrawMode (aFlag))
+    {
+      continue;
+    }
+    else if (aFlag == "-echo"
+          || aFlag == "-print")
     {
       toPrint = Standard_True;
+      anUpdateTool.Invalidate();
     }
     else if (aFlag == "-mode"
           || aFlag == "-rendermode"
@@ -6740,14 +6807,64 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       aParams.IsTransparentShadowEnabled = toEnable;
     }
+    else if (aFlag == "-shademodel"
+          || aFlag == "-shadingmodel"
+          || aFlag == "-shading")
+    {
+      if (toPrint)
+      {
+        switch (aView->ShadingModel())
+        {
+          case V3d_COLOR:   theDI << "color ";   break;
+          case V3d_FLAT:    theDI << "flat ";    break;
+          case V3d_GOURAUD: theDI << "gouraud "; break;
+          case V3d_PHONG:   theDI << "phong ";   break;
+        }
+        continue;
+      }
+
+      if (++anArgIter >= theArgNb)
+      {
+        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+      }
+
+      TCollection_AsciiString aMode (theArgVec[anArgIter]);
+      aMode.LowerCase();
+      if (aMode == "color"
+       || aMode == "none")
+      {
+        aView->SetShadingModel (V3d_COLOR);
+      }
+      else if (aMode == "flat"
+            || aMode == "facet")
+      {
+        aView->SetShadingModel (V3d_FLAT);
+      }
+      else if (aMode == "gouraud"
+            || aMode == "vertex"
+            || aMode == "vert")
+      {
+        aView->SetShadingModel (V3d_GOURAUD);
+      }
+      else if (aMode == "phong"
+            || aMode == "fragment"
+            || aMode == "frag"
+            || aMode == "pixel")
+      {
+        aView->SetShadingModel (V3d_PHONG);
+      }
+      else
+      {
+        std::cout << "Error: unknown shading model '" << aMode << "'\n";
+        return 1;
+      }
+    }
     else
     {
       std::cout << "Error: wrong syntax, unknown flag '" << anArg << "'\n";
       return 1;
     }
   }
-
-  aView->Redraw();
   return 0;
 }
 
@@ -7088,7 +7205,20 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\nvstereo [{0|1}] : turn stereo usage On/Off; affects only newly displayed objects",
     __FILE__, VStereo, group);
   theCommands.Add ("vcaps",
-    "vcaps [vbo={0|1}] [sprites={0|1}] [soft={0|1}] : modify particular graphic driver options",
+            "vcaps [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}]"
+    "\n\t\t:       [-softMode {0|1}] [-noupdate|-update]"
+    "\n\t\t: Modify particular graphic driver options:"
+    "\n\t\t:  FFP      - use fixed-function pipeline instead of"
+    "\n\t\t:             built-in GLSL programs"
+    "\n\t\t:  VBO      - use Vertex Buffer Object (copy vertex"
+    "\n\t\t:             arrays to GPU memory)"
+    "\n\t\t:  sprite   - use textured sprites instead of bitmaps"
+    "\n\t\t:  softMode - use software OpenGL implementation,"
+    "\n\t\t:             should be set BEFORE viewer creation"
+    "\n\t\t: Unlike vrenderparams, these parameters control alternative"
+    "\n\t\t: rendering paths producing the same visual result when"
+    "\n\t\t: possible."
+    "\n\t\t: Command is intended for testing old hardware compatibility.",
     __FILE__, VCaps, group);
   theCommands.Add ("vmemgpu",
     "vmemgpu [f]: print system-dependent GPU memory information if available;"
@@ -7278,13 +7408,18 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     __FILE__, VRenderParams, group);
   theCommands.Add("vrenderparams",
     "\n    Manages rendering parameters: "
-    "\n      '-rayTrace'            Enables  GPU ray-tracing"
-    "\n      '-raster'              Disables GPU ray-tracing"
-    "\n      '-rayDepth    0..10'   Defines maximum ray-tracing depth"
-    "\n      '-shadows     on|off'  Enables/disables shadows rendering"
-    "\n      '-reflections on|off'  Enables/disables specular reflections"
-    "\n      '-fsaa        on|off'  Enables/disables adaptive anti-aliasing"
-    "\n      '-gleam       on|off'  Enables/disables transparency shadow effects",
+    "\n      '-rayTrace'             Enables  GPU ray-tracing"
+    "\n      '-raster'               Disables GPU ray-tracing"
+    "\n      '-rayDepth     0..10'   Defines maximum ray-tracing depth"
+    "\n      '-shadows      on|off'  Enables/disables shadows rendering"
+    "\n      '-reflections  on|off'  Enables/disables specular reflections"
+    "\n      '-fsaa         on|off'  Enables/disables adaptive anti-aliasing"
+    "\n      '-gleam        on|off'  Enables/disables transparency shadow effects"
+    "\n      '-shadingModel model'   Controls shading model from enumeration"
+    "\n                              color, flat, gouraud, phong"
+    "\n    Unlike vcaps, these parameters dramatically change visual properties."
+    "\n    Command is intended to control presentation quality depending on"
+    "\n    hardware capabilities and performance.",
     __FILE__, VRenderParams, group);
   theCommands.Add("vfrustumculling",
     "vfrustumculling [toEnable]: enables/disables objects clipping",
index a3e673c..6c6758e 100644 (file)
@@ -126,21 +126,15 @@ is
     --      TOLS_SPOT       spot light
 
     enumeration TypeOfModel is  TOM_NONE,
-                    TOM_INTERP_COLOR,
                     TOM_FACET,
-                    TOM_VERTEX
+                    TOM_VERTEX,
+                    TOM_FRAGMENT
     end TypeOfModel;
     ---Purpose: Definition of the rendering (colour shading) model
-    --  TOM_NONE        No interpolation, constant shading
-    --              (FLAT Shading)
-    --  TOM_INTERP_COLOR    Linear interpolation of color
-    --              (Gouraud Shading)
-    --  TOM_FACET       Interpolation of color based on
-    --              dot products
-    --              (Quick Phong Shading)
-    --  TOM_VERTEX      Interpolation of color based on
-    --              normals
-    --              (Phong Shading)
+    --  Visual3d_TOM_NONE     No lighting, only white ambient light
+    --  Visual3d_TOM_FACET    No interpolation, constant shading      (Flat    Shading)
+    --  Visual3d_TOM_VERTEX   Interpolation of color based on normals (Gouraud Shading)
+    --  Visual3d_TOM_FRAGMENT Interpolation of color based on normals (Phong   Shading)
     ---Category: The enumerations
 
     enumeration TypeOfOrder is  TOO_TOPFIRST,
index 3fc1d0f..d7c145f 100644 (file)
@@ -180,14 +180,7 @@ is
                   AModel       : TypeOfModel from Visual3d )
                is static;
        ---Level: Public
-       ---Purpose: Modifies the shading model when the type of
-       --          visualization is TOV_SHADING
-       --
-       --          TypeOfModel : TOM_NONE
-       --                        TOM_INTERP_COLOR
-       --                        TOM_FACET
-       --                        TOM_VERTEX
-       --
+       ---Purpose: Modifies the shading model when the type of visualization is TOV_SHADING
        ---Category: Methods to modify the class definition
 
        SetVisualization ( me           : in out;
index 6c11e1c..e51a141 100644 (file)
@@ -28,7 +28,7 @@ set aCustom3 [locate_data_file images/marker_dot.png]
 # draw box in advance which should fit all our markers
 box b -8 -8 0 16 16 2
 
-vcaps sprites=1
+vcaps -sprites
 set aV "Driver1/Viewer1/View1"
 vinit name=$aV l=32 t=32 w=512 h=512
 vactivate $aV
index cc2993c..0bd9691 100644 (file)
@@ -32,7 +32,7 @@ puts "hI"
 for { set aMode 0 } { $aMode <= 1 } { incr aMode } {
   set aTitle "bitmaps"
   if { $aMode == 1 } { set aTitle "sprites" }
-  vcaps sprites=$aMode
+  vcaps -sprites $aMode
   set aV "Driver${aMode}/Viewer1/View1"
   vinit name=$aV l=32 t=32 w=512 h=512
   vactivate $aV
index 5a4c040..9675021 100644 (file)
@@ -7,7 +7,7 @@ puts ""
 #  Test image dumping with software accelerated GL context
 ############################################################
 
-vcaps soft=1
+vcaps -softMode
 vinit View1
 
 box b 1 2 3