diff --git a/samples/mfc/standard/04_Viewer3d/src/ShadingModelDlg.cpp b/samples/mfc/standard/04_Viewer3d/src/ShadingModelDlg.cpp index dcd165b30e..c053f450d8 100755 --- a/samples/mfc/standard/04_Viewer3d/src/ShadingModelDlg.cpp +++ b/samples/mfc/standard/04_Viewer3d/src/ShadingModelDlg.cpp @@ -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(); +} diff --git a/samples/mfc/standard/04_Viewer3d/src/ShadingModelDlg.h b/samples/mfc/standard/04_Viewer3d/src/ShadingModelDlg.h index dc88f1e712..6ddad56b83 100755 --- a/samples/mfc/standard/04_Viewer3d/src/ShadingModelDlg.h +++ b/samples/mfc/standard/04_Viewer3d/src/ShadingModelDlg.h @@ -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() diff --git a/samples/mfc/standard/04_Viewer3d/src/Viewer3d.rc b/samples/mfc/standard/04_Viewer3d/src/Viewer3d.rc index 66bb00d783..01e4c83385 100755 --- a/samples/mfc/standard/04_Viewer3d/src/Viewer3d.rc +++ b/samples/mfc/standard/04_Viewer3d/src/Viewer3d.rc @@ -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 diff --git a/samples/mfc/standard/04_Viewer3d/src/resource.h b/samples/mfc/standard/04_Viewer3d/src/resource.h index 9a75ffae30..fac2093ddb 100755 --- a/samples/mfc/standard/04_Viewer3d/src/resource.h +++ b/samples/mfc/standard/04_Viewer3d/src/resource.h @@ -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 diff --git a/src/InterfaceGraphic/InterfaceGraphic_telem.hxx b/src/InterfaceGraphic/InterfaceGraphic_telem.hxx index 3492cfe9e6..db4acbf09f 100644 --- a/src/InterfaceGraphic/InterfaceGraphic_telem.hxx +++ b/src/InterfaceGraphic/InterfaceGraphic_telem.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_AspectFace.cxx b/src/OpenGl/OpenGl_AspectFace.cxx index e669f962c6..ab4a4b368e 100644 --- a/src/OpenGl/OpenGl_AspectFace.cxx +++ b/src/OpenGl/OpenGl_AspectFace.cxx @@ -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 (TextureId, Texture)) + if (TextureId.IsEmpty() || !theCtx->GetResource (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); } diff --git a/src/OpenGl/OpenGl_AspectFace.hxx b/src/OpenGl/OpenGl_AspectFace.hxx index 7b8cd1ee45..35aa98e097 100644 --- a/src/OpenGl/OpenGl_AspectFace.hxx +++ b/src/OpenGl/OpenGl_AspectFace.hxx @@ -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; diff --git a/src/OpenGl/OpenGl_AspectLine.cxx b/src/OpenGl/OpenGl_AspectLine.cxx index 48d23cfa22..c7ddf98fe2 100644 --- a/src/OpenGl/OpenGl_AspectLine.cxx +++ b/src/OpenGl/OpenGl_AspectLine.cxx @@ -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); } diff --git a/src/OpenGl/OpenGl_AspectLine.hxx b/src/OpenGl/OpenGl_AspectLine.hxx index dbb27aa3ef..2e35092c2e 100644 --- a/src/OpenGl/OpenGl_AspectLine.hxx +++ b/src/OpenGl/OpenGl_AspectLine.hxx @@ -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; diff --git a/src/OpenGl/OpenGl_AspectMarker.cxx b/src/OpenGl/OpenGl_AspectMarker.cxx index a29e430f9f..c679aea841 100644 --- a/src/OpenGl/OpenGl_AspectMarker.cxx +++ b/src/OpenGl/OpenGl_AspectMarker.cxx @@ -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 (aNewKeyA, SpriteA) // alpha sprite could be shared - && aContext->GetResource (aNewKey, Sprite)) + && theCtx->GetResource (aNewKeyA, SpriteA) // alpha sprite could be shared + && theCtx->GetResource (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); } // ======================================================================= diff --git a/src/OpenGl/OpenGl_AspectMarker.hxx b/src/OpenGl/OpenGl_AspectMarker.hxx index c71fa1374f..08292ba53e 100644 --- a/src/OpenGl/OpenGl_AspectMarker.hxx +++ b/src/OpenGl/OpenGl_AspectMarker.hxx @@ -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, diff --git a/src/OpenGl/OpenGl_AspectText.cxx b/src/OpenGl/OpenGl_AspectText.cxx index 772a183ea6..98cc48430a 100755 --- a/src/OpenGl/OpenGl_AspectText.cxx +++ b/src/OpenGl/OpenGl_AspectText.cxx @@ -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); } diff --git a/src/OpenGl/OpenGl_AspectText.hxx b/src/OpenGl/OpenGl_AspectText.hxx index 764cc55ed2..79ccc8f4d9 100755 --- a/src/OpenGl/OpenGl_AspectText.hxx +++ b/src/OpenGl/OpenGl_AspectText.hxx @@ -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; diff --git a/src/OpenGl/OpenGl_Caps.cxx b/src/OpenGl/OpenGl_Caps.cxx index baff8d117e..a8bc4ddeb0 100755 --- a/src/OpenGl/OpenGl_Caps.cxx +++ b/src/OpenGl/OpenGl_Caps.cxx @@ -15,6 +15,8 @@ #include +#include + 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; diff --git a/src/OpenGl/OpenGl_Caps.hxx b/src/OpenGl/OpenGl_Caps.hxx index 3cd0ade386..0b90e3e964 100755 --- a/src/OpenGl/OpenGl_Caps.hxx +++ b/src/OpenGl/OpenGl_Caps.hxx @@ -20,7 +20,7 @@ #include #include -//! 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 diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 31c803b79f..a936cd10f0 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -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 } diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index ae5d28eae8..916502b267 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -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: diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index b976c14bd7..50d101a8a4 100755 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -27,51 +27,6 @@ namespace { - template - 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); + aCtx->core11fwd->glEnable (GL_BLEND); + aCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - #if !defined(GL_ES_VERSION_2_0) - glEnable (GL_ALPHA_TEST); - glAlphaFunc (GL_GEQUAL, 0.1f); - #endif + aCtx->core11fwd->glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements); - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - - 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 (anIter).GetData()); + aCtx->core11->glRasterPos3fv (myAttribs->Value (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; + } + } + } - drawArray (theWorkspace, aFaceColors); + aCtx->SetColor4fv (*(const OpenGl_Vec4* )(myDrawMode <= GL_LINE_STRIP ? aLineColor->rgb : anInteriorColor->rgb)); + + 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); } diff --git a/src/OpenGl/OpenGl_PrimitiveArray.hxx b/src/OpenGl/OpenGl_PrimitiveArray.hxx index c7d300e5a6..c086204d3f 100644 --- a/src/OpenGl/OpenGl_PrimitiveArray.hxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.hxx @@ -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, diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index 4f0e1de974..db9e56688a 100755 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -28,15 +28,219 @@ 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; +} diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx index 1da56c278f..94b3e104d5 100755 --- a/src/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/OpenGl/OpenGl_ShaderManager.hxx @@ -24,6 +24,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include class OpenGl_View; @@ -33,6 +39,17 @@ typedef NCollection_Sequence OpenGl_ShaderProgramL //! Map to declare per-program states of OCCT materials. typedef NCollection_DataMap 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); + } -protected: + 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 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); + } + + //! 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 diff --git a/src/OpenGl/OpenGl_ShaderProgram.cxx b/src/OpenGl/OpenGl_ShaderProgram.cxx index 4931090734..a0e027eabf 100755 --- a/src/OpenGl/OpenGl_ShaderProgram.cxx +++ b/src/OpenGl/OpenGl_ShaderProgram.cxx @@ -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)) { diff --git a/src/OpenGl/OpenGl_ShaderProgram.hxx b/src/OpenGl/OpenGl_ShaderProgram.hxx index 9b5163f7cd..c65124c1ac 100755 --- a/src/OpenGl/OpenGl_ShaderProgram.hxx +++ b/src/OpenGl/OpenGl_ShaderProgram.hxx @@ -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]; diff --git a/src/OpenGl/OpenGl_Text.cxx b/src/OpenGl/OpenGl_Text.cxx index fcb775cf89..d991609fce 100755 --- a/src/OpenGl/OpenGl_Text.cxx +++ b/src/OpenGl/OpenGl_Text.cxx @@ -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()) { diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index 4296d7873e..72aafc4396 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -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, diff --git a/src/OpenGl/OpenGl_Texture.hxx b/src/OpenGl/OpenGl_Texture.hxx index 6240ab671e..476c4b1f37 100644 --- a/src/OpenGl/OpenGl_Texture.hxx +++ b/src/OpenGl/OpenGl_Texture.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_VertexBuffer.lxx b/src/OpenGl/OpenGl_VertexBuffer.lxx index fb11b4887d..9cec1ce4bc 100644 --- a/src/OpenGl/OpenGl_VertexBuffer.lxx +++ b/src/OpenGl/OpenGl_VertexBuffer.lxx @@ -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) diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index c74a924ab9..56725e93b6 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -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; } /*----------------------------------------------------------------------*/ diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 527fa593d5..bbb90ca43e 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -257,7 +258,7 @@ protected: //View_LABViewContext int myVisualization; - int myIntShadingMethod; + Visual3d_TypeOfModel myShadingModel; //!< lighting shading model //View_LABLight OpenGl_ListOfLight myLights; diff --git a/src/OpenGl/OpenGl_View_2.cxx b/src/OpenGl/OpenGl_View_2.cxx index 7252e06ff1..d8c54657f5 100644 --- a/src/OpenGl/OpenGl_View_2.cxx +++ b/src/OpenGl/OpenGl_View_2.cxx @@ -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 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 // ============================================================== diff --git a/src/OpenGl/OpenGl_Workspace.hxx b/src/OpenGl/OpenGl_Workspace.hxx index 77041d8bd0..c43f1deadf 100644 --- a/src/OpenGl/OpenGl_Workspace.hxx +++ b/src/OpenGl/OpenGl_Workspace.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_Workspace_5.cxx b/src/OpenGl/OpenGl_Workspace_5.cxx index f8f37034bf..2d4b07e902 100644 --- a/src/OpenGl/OpenGl_Workspace_5.cxx +++ b/src/OpenGl/OpenGl_Workspace_5.cxx @@ -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 diff --git a/src/Shaders/Declarations.glsl b/src/Shaders/Declarations.glsl index a23cf64681..15f88375f2 100644 --- a/src/Shaders/Declarations.glsl +++ b/src/Shaders/Declarations.glsl @@ -19,14 +19,11 @@ #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 diff --git a/src/V3d/V3d.cdl b/src/V3d/V3d.cdl index 9cb26f65bb..8016462440 100644 --- a/src/V3d/V3d.cdl +++ b/src/V3d/V3d.cdl @@ -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; diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 8ec91b41fa..8525d3e20b 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -96,6 +97,26 @@ #include #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)) { - aCaps->vboDisable = anArg.Token ("=", 2).IntegerValue() == 0; + continue; } - else if (anArg.Search ("sprites=") > -1) + else if (anArgCase == "-ffp") { - aCaps->pntSpritesDisable = anArg.Token ("=", 2).IntegerValue() == 0; + Standard_Boolean toEnable = Standard_True; + if (++anArgIter < theArgNb + && !parseOnOff (theArgVec[anArgIter], toEnable)) + { + --anArgIter; + } + aCaps->ffpEnable = toEnable; } - else if (anArg.Search ("soft=") > -1) + else if (anArgCase == "-vbo") { - aCaps->contextNoAccel = anArg.Token ("=", 2).IntegerValue() != 0; + Standard_Boolean toEnable = Standard_True; + if (++anArgIter < theArgNb + && !parseOnOff (theArgVec[anArgIter], toEnable)) + { + --anArgIter; + } + aCaps->vboDisable = !toEnable; + } + else if (anArgCase == "-sprite" + || anArgCase == "-sprites") + { + Standard_Boolean toEnable = Standard_True; + if (++anArgIter < theArgNb + && !parseOnOff (theArgVec[anArgIter], toEnable)) + { + --anArgIter; + } + aCaps->pntSpritesDisable = !toEnable; + } + else if (anArgCase == "-softmode") + { + 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", diff --git a/src/Visual3d/Visual3d.cdl b/src/Visual3d/Visual3d.cdl index a3e673ce74..6c6758e697 100644 --- a/src/Visual3d/Visual3d.cdl +++ b/src/Visual3d/Visual3d.cdl @@ -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, diff --git a/src/Visual3d/Visual3d_ContextView.cdl b/src/Visual3d/Visual3d_ContextView.cdl index 3fc1d0fc0e..d7c145fadc 100644 --- a/src/Visual3d/Visual3d_ContextView.cdl +++ b/src/Visual3d/Visual3d_ContextView.cdl @@ -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; diff --git a/tests/bugs/vis/bug23654_MarkersRecompute b/tests/bugs/vis/bug23654_MarkersRecompute index 6c11e1c4cc..e51a1419b0 100644 --- a/tests/bugs/vis/bug23654_MarkersRecompute +++ b/tests/bugs/vis/bug23654_MarkersRecompute @@ -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 diff --git a/tests/bugs/vis/bug24131_markers b/tests/bugs/vis/bug24131_markers index cc2993ca66..0bd9691995 100644 --- a/tests/bugs/vis/bug24131_markers +++ b/tests/bugs/vis/bug24131_markers @@ -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 diff --git a/tests/bugs/vis/bug24728 b/tests/bugs/vis/bug24728 index 5a4c0401fc..96750210f6 100644 --- a/tests/bugs/vis/bug24728 +++ b/tests/bugs/vis/bug24728 @@ -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