diff --git a/src/Graphic3d/Graphic3d_ShaderManager.cxx b/src/Graphic3d/Graphic3d_ShaderManager.cxx index b9ee57ee38..d6dfb378b5 100644 --- a/src/Graphic3d/Graphic3d_ShaderManager.cxx +++ b/src/Graphic3d/Graphic3d_ShaderManager.cxx @@ -2093,3 +2093,37 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getBgCubeMapProgram() c aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts)); return aProgSrc; } + +// ======================================================================= +// function : getColoredQuadProgram +// purpose : +// ======================================================================= +Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getColoredQuadProgram() const +{ + Handle(Graphic3d_ShaderProgram) aProgSrc = new Graphic3d_ShaderProgram(); + + Graphic3d_ShaderObject::ShaderVariableList aUniforms, aStageInOuts; + aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT)); + aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 uColor1", Graphic3d_TOS_FRAGMENT)); + aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 uColor2", Graphic3d_TOS_FRAGMENT)); + + TCollection_AsciiString aSrcVert = TCollection_AsciiString() + + EOL"void main()" + EOL"{" + EOL" TexCoord = occTexCoord.st;" + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;" + EOL"}"; + + TCollection_AsciiString aSrcFrag = TCollection_AsciiString() + + EOL"void main()" + EOL"{" + EOL" vec3 c1 = mix (uColor1, uColor2, TexCoord.x);" + EOL" occSetFragColor (vec4 (mix (uColor2, c1, TexCoord.y), 1.0));" + EOL"}"; + + defaultGlslVersion (aProgSrc, "colored_quad", 0); + aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts)); + aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts)); + + return aProgSrc; +} diff --git a/src/Graphic3d/Graphic3d_ShaderManager.hxx b/src/Graphic3d/Graphic3d_ShaderManager.hxx index 5a4731acda..0619ea11e7 100644 --- a/src/Graphic3d/Graphic3d_ShaderManager.hxx +++ b/src/Graphic3d/Graphic3d_ShaderManager.hxx @@ -142,6 +142,9 @@ protected: //! Generates shader program to render environment cubemap as background. Standard_EXPORT Handle(Graphic3d_ShaderProgram) getBgCubeMapProgram() const; + //! Generates shader program to render correctly colored quad. + Standard_EXPORT Handle(Graphic3d_ShaderProgram) getColoredQuadProgram() const; + //! Prepare GLSL source for IBL generation used in PBR pipeline. Standard_EXPORT Handle(Graphic3d_ShaderProgram) getPBREnvBakingProgram (Standard_Integer theIndex) const; diff --git a/src/OpenGl/OpenGl_BackgroundArray.cxx b/src/OpenGl/OpenGl_BackgroundArray.cxx index cceff8f511..90dac5020d 100644 --- a/src/OpenGl/OpenGl_BackgroundArray.cxx +++ b/src/OpenGl/OpenGl_BackgroundArray.cxx @@ -209,13 +209,22 @@ Standard_Boolean OpenGl_BackgroundArray::createGradientArray (const Handle(OpenG { return Standard_False; } + if (!myIndices->Init(6)) + { + return Standard_False; + } + const unsigned short THE_FS_QUAD_TRIS[6] = {0, 1, 3, 1, 2, 3}; + for (unsigned int aVertIter = 0; aVertIter < 6; ++aVertIter) + { + myIndices->SetIndex (aVertIter, THE_FS_QUAD_TRIS[aVertIter]); + } OpenGl_Vec2 aVertices[4] = { OpenGl_Vec2(float(myViewWidth), 0.0f), OpenGl_Vec2(float(myViewWidth), float(myViewHeight)), - OpenGl_Vec2(0.0f, 0.0f), - OpenGl_Vec2(0.0f, float(myViewHeight)) + OpenGl_Vec2(0.0f, float(myViewHeight)), + OpenGl_Vec2(0.0f, 0.0f) }; float* aCorners[4] = {}; @@ -236,73 +245,65 @@ Standard_Boolean OpenGl_BackgroundArray::createGradientArray (const Handle(OpenG { aCorners[0] = myGradientParams.color2.ChangeData(); aCorners[1] = myGradientParams.color1.ChangeData(); - aCorners[2] = myGradientParams.color2.ChangeData(); - aCorners[3] = myGradientParams.color1.ChangeData(); + aCorners[2] = myGradientParams.color1.ChangeData(); + aCorners[3] = myGradientParams.color2.ChangeData(); break; } case Aspect_GradientFillMethod_Diagonal1: { aCorners[0] = myGradientParams.color2.ChangeData(); - aCorners[3] = myGradientParams.color1.ChangeData(); - aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[0][0] + aCorners[3][0]); - aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[0][1] + aCorners[3][1]); - aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[0][2] + aCorners[3][2]); + aCorners[2] = myGradientParams.color1.ChangeData(); + aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[0][0] + aCorners[2][0]); + aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[0][1] + aCorners[2][1]); + aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[0][2] + aCorners[2][2]); aCorners[1] = aDiagCorner1; - aCorners[2] = aDiagCorner2; + aCorners[3] = aDiagCorner2; break; } case Aspect_GradientFillMethod_Diagonal2: { aCorners[1] = myGradientParams.color1.ChangeData(); - aCorners[2] = myGradientParams.color2.ChangeData(); - aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[1][0] + aCorners[2][0]); - aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[1][1] + aCorners[2][1]); - aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[1][2] + aCorners[2][2]); + aCorners[3] = myGradientParams.color2.ChangeData(); + aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[1][0] + aCorners[3][0]); + aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[1][1] + aCorners[3][1]); + aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[1][2] + aCorners[3][2]); aCorners[0] = aDiagCorner1; - aCorners[3] = aDiagCorner2; + aCorners[2] = aDiagCorner2; break; } case Aspect_GradientFillMethod_Corner1: - { - aVertices[0] = OpenGl_Vec2(float(myViewWidth), float(myViewHeight)); - aVertices[1] = OpenGl_Vec2(0.0f, float(myViewHeight)); - aVertices[2] = OpenGl_Vec2(float(myViewWidth), 0.0f); - aVertices[3] = OpenGl_Vec2(0.0f, 0.0f); - - aCorners[0] = myGradientParams.color2.ChangeData(); - aCorners[1] = myGradientParams.color1.ChangeData(); - aCorners[2] = myGradientParams.color2.ChangeData(); - aCorners[3] = myGradientParams.color2.ChangeData(); - break; - } case Aspect_GradientFillMethod_Corner2: - { - aCorners[0] = myGradientParams.color2.ChangeData(); - aCorners[1] = myGradientParams.color1.ChangeData(); - aCorners[2] = myGradientParams.color2.ChangeData(); - aCorners[3] = myGradientParams.color2.ChangeData(); - break; - } case Aspect_GradientFillMethod_Corner3: - { - aVertices[0] = OpenGl_Vec2(float(myViewWidth), float(myViewHeight)); - aVertices[1] = OpenGl_Vec2(0.0f, float(myViewHeight)); - aVertices[2] = OpenGl_Vec2(float(myViewWidth), 0.0f); - aVertices[3] = OpenGl_Vec2(0.0f, 0.0f); - - aCorners[0] = myGradientParams.color2.ChangeData(); - aCorners[1] = myGradientParams.color2.ChangeData(); - aCorners[2] = myGradientParams.color1.ChangeData(); - aCorners[3] = myGradientParams.color2.ChangeData(); - break; - } case Aspect_GradientFillMethod_Corner4: { - aCorners[0] = myGradientParams.color2.ChangeData(); - aCorners[1] = myGradientParams.color2.ChangeData(); - aCorners[2] = myGradientParams.color1.ChangeData(); - aCorners[3] = myGradientParams.color2.ChangeData(); - break; + Graphic3d_Attribute aCornerAttribInfo[] = + { + { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 }, + { Graphic3d_TOA_UV, Graphic3d_TOD_VEC2 } + }; + + OpenGl_Vec2 anUVs[4] = + { + OpenGl_Vec2 (1.0f, 0.0f), + OpenGl_Vec2 (1.0f, 1.0f), + OpenGl_Vec2 (0.0f, 1.0f), + OpenGl_Vec2 (0.0f, 0.0f) + }; + + if (!myAttribs->Init (4, aCornerAttribInfo, 2)) + { + return Standard_False; + } + for (Standard_Integer anIt = 0; anIt < 4; ++anIt) + { + OpenGl_Vec2* aVertData = reinterpret_cast(myAttribs->changeValue (anIt)); + *aVertData = aVertices[anIt]; + + OpenGl_Vec2* anUvData = reinterpret_cast(myAttribs->changeValue (anIt) + myAttribs->AttributeOffset (1)); + // cyclically move highlighted corner depending on myGradientParams.type + *anUvData = anUVs[(anIt + myGradientParams.type - Aspect_GradientFillMethod_Corner1) % 4]; + } + return Standard_True; } case Aspect_GradientFillMethod_Elliptical: { @@ -365,15 +366,6 @@ Standard_Boolean OpenGl_BackgroundArray::createGradientArray (const Handle(OpenG *aColorData = theCtx->Vec4FromQuantityColor (OpenGl_Vec4(aCorners[anIt][0], aCorners[anIt][1], aCorners[anIt][2], 1.0f)).rgb(); } - if (!myIndices->Init(6)) - { - return Standard_False; - } - const unsigned short THE_FS_QUAD_TRIS[6] = {0, 1, 2, 1, 3, 2}; - for (unsigned int aVertIter = 0; aVertIter < 6; ++aVertIter) - { - myIndices->SetIndex (aVertIter, THE_FS_QUAD_TRIS[aVertIter]); - } return Standard_True; } diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index 4abc046bfe..04efdf9a1e 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -1397,6 +1397,19 @@ const Handle(Graphic3d_ShaderProgram)& OpenGl_ShaderManager::GetBgCubeMapProgram return myBgCubeMapProgram; } +// ======================================================================= +// function : GetColoredQuadProgram +// purpose : +// ======================================================================= +const Handle(Graphic3d_ShaderProgram)& OpenGl_ShaderManager::GetColoredQuadProgram () +{ + if (myColoredQuadProgram.IsNull()) + { + myColoredQuadProgram = getColoredQuadProgram(); + } + return myColoredQuadProgram; +} + // ======================================================================= // function : bindProgramWithState // purpose : diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx index 464323e06e..44d07b4f2a 100644 --- a/src/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/OpenGl/OpenGl_ShaderManager.hxx @@ -228,7 +228,10 @@ public: } //! Generates shader program to render environment cubemap as background. - Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgCubeMapProgram (); + Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgCubeMapProgram(); + + //! Generates shader program to render correctly colored quad. + Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetColoredQuadProgram(); //! Resets PBR shading models to corresponding non-PBR ones if PBR is not allowed. static Graphic3d_TypeOfShadingModel PBRShadingModelFallback (Graphic3d_TypeOfShadingModel theShadingModel, @@ -769,7 +772,8 @@ protected: OpenGl_MapOfShaderPrograms myMapOfLightPrograms; //!< map of lighting programs depending on lights configuration Handle(OpenGl_ShaderProgram) myPBREnvBakingProgram[3]; //!< programs for IBL maps generation used in PBR pipeline (0 for Diffuse; 1 for Specular; 2 for fallback) - Handle(Graphic3d_ShaderProgram) myBgCubeMapProgram; //!< program for background cubemap rendering + Handle(Graphic3d_ShaderProgram) myBgCubeMapProgram; //!< program for background cubemap rendering + Handle(Graphic3d_ShaderProgram) myColoredQuadProgram; //!< program for correct quad rendering Handle(OpenGl_ShaderProgram) myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index 2bca09c991..a2d17ad6a5 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -127,10 +127,11 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr, myTransientDrawToFront (Standard_True), myBackBufferRestored (Standard_False), myIsImmediateDrawn (Standard_False), - myTextureParams (new OpenGl_Aspects()), - myCubeMapParams (new OpenGl_Aspects()), - myPBREnvState (OpenGl_PBREnvState_NONEXISTENT), - myPBREnvRequest (Standard_False), + myTextureParams (new OpenGl_Aspects()), + myCubeMapParams (new OpenGl_Aspects()), + myColoredQuadParams (new OpenGl_Aspects()), + myPBREnvState (OpenGl_PBREnvState_NONEXISTENT), + myPBREnvRequest (Standard_False), // ray-tracing fields initialization myRaytraceInitStatus (OpenGl_RT_NONE), myIsRaytraceDataValid (Standard_False), @@ -192,6 +193,7 @@ OpenGl_View::~OpenGl_View() OpenGl_Element::Destroy (NULL, myTextureParams); OpenGl_Element::Destroy (NULL, myCubeMapParams); + OpenGl_Element::Destroy (NULL, myColoredQuadParams); } // ======================================================================= @@ -541,7 +543,16 @@ void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBac Quantity_Color aColor1, aColor2; theBackground.Colors (aColor1, aColor2); myBackgrounds[Graphic3d_TOB_GRADIENT]->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod()); - + if (theBackground.BgGradientFillMethod() >= Aspect_GradientFillMethod_Corner1 + && theBackground.BgGradientFillMethod() <= Aspect_GradientFillMethod_Corner4) + { + if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext()) + { + myColoredQuadParams->Aspect()->SetShaderProgram(aCtx->ShaderManager()->GetColoredQuadProgram()); + myColoredQuadParams->Aspect()->ShaderProgram()->PushVariableVec3 ("uColor1", aColor1.Rgb()); + myColoredQuadParams->Aspect()->ShaderProgram()->PushVariableVec3 ("uColor2", aColor2.Rgb()); + } + } myBackgroundType = Graphic3d_TOB_GRADIENT; } @@ -1007,7 +1018,19 @@ void OpenGl_View::drawBackground (const Handle(OpenGl_Workspace)& theWorkspace, || myBackgrounds[Graphic3d_TOB_TEXTURE]->TextureFillMethod() == Aspect_FM_CENTERED || myBackgrounds[Graphic3d_TOB_TEXTURE]->TextureFillMethod() == Aspect_FM_NONE)) { - myBackgrounds[Graphic3d_TOB_GRADIENT]->Render(theWorkspace, theProjection); + if (myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientFillMethod() >= Aspect_GradientFillMethod_Corner1 + && myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientFillMethod() <= Aspect_GradientFillMethod_Corner4) + { + const OpenGl_Aspects* anOldAspectFace = theWorkspace->SetAspects (myColoredQuadParams); + + myBackgrounds[Graphic3d_TOB_GRADIENT]->Render (theWorkspace, theProjection); + + theWorkspace->SetAspects (anOldAspectFace); + } + else + { + myBackgrounds[Graphic3d_TOB_GRADIENT]->Render (theWorkspace, theProjection); + } } // Drawing background image if it is defined diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index eec11de2c2..e64fdc0587 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -507,6 +507,7 @@ protected: //! @name Background parameters OpenGl_Aspects* myTextureParams; //!< Stores texture and its parameters for textured background OpenGl_Aspects* myCubeMapParams; //!< Stores cubemap and its parameters for cubemap background + OpenGl_Aspects* myColoredQuadParams; //!< Stores parameters for gradient (corner mode) background OpenGl_BackgroundArray* myBackgrounds[Graphic3d_TypeOfBackground_NB]; //!< Array of primitive arrays of different background types Handle(OpenGl_TextureSet) myTextureEnv;