1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0032591: Visualization, V3d_View - improve corner gradient

- Added new shader for correct Aspect_GradientFillMethod_Corner mode shading.
This commit is contained in:
achesnok 2021-10-02 16:33:48 +03:00 committed by smoskvin
parent c2064b60e7
commit 956d91571c
7 changed files with 137 additions and 67 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -209,13 +209,22 @@ Standard_Boolean OpenGl_BackgroundArray::createGradientArray (const Handle(OpenG
{
return Standard_False;
}
if (!myIndices->Init<unsigned short>(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<OpenGl_Vec2*>(myAttribs->changeValue (anIt));
*aVertData = aVertices[anIt];
OpenGl_Vec2* anUvData = reinterpret_cast<OpenGl_Vec2*>(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<unsigned short>(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;
}

View File

@ -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 :

View File

@ -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

View File

@ -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

View File

@ -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;