1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00

0029337: Visualization, TKOpenGl - visual artifacts on Intel Broadwell GPU

Enable multiple draw buffers in shader program only if its required by specific application.

occSetFragColor() - a new GLSL function has been introduced
as an alternative to setting occFragColor/occFragCoverage variables.
This commit is contained in:
apl 2017-11-27 15:16:21 +03:00 committed by apn
parent 12d71ad6a5
commit b17e5bae1a
12 changed files with 201 additions and 75 deletions

View File

@ -78,7 +78,9 @@ const TCollection_AsciiString& Graphic3d_ShaderProgram::ShadersFolder()
// ======================================================================= // =======================================================================
Graphic3d_ShaderProgram::Graphic3d_ShaderProgram() Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
: myNbLightsMax (THE_MAX_LIGHTS_DEFAULT), : myNbLightsMax (THE_MAX_LIGHTS_DEFAULT),
myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT) myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT),
myNbFragOutputs (THE_NB_FRAG_OUTPUTS),
myHasWeightOitOutput (false)
{ {
myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_") myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_")
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER)); + TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER));

View File

@ -43,6 +43,9 @@ public:
//! Default value of THE_MAX_CLIP_PLANES macros within GLSL program (see Declarations.glsl). //! Default value of THE_MAX_CLIP_PLANES macros within GLSL program (see Declarations.glsl).
static const Standard_Integer THE_MAX_CLIP_PLANES_DEFAULT = 8; static const Standard_Integer THE_MAX_CLIP_PLANES_DEFAULT = 8;
//! Default value of THE_NB_FRAG_OUTPUTS macros within GLSL program (see Declarations.glsl).
static const Standard_Integer THE_NB_FRAG_OUTPUTS = 1;
public: public:
//! Creates new empty program object. //! Creates new empty program object.
@ -115,6 +118,21 @@ public:
//! Should be done before GLSL program initialization. //! Should be done before GLSL program initialization.
Standard_EXPORT void SetVertexAttributes (const Graphic3d_ShaderAttributeList& theAttributes); Standard_EXPORT void SetVertexAttributes (const Graphic3d_ShaderAttributeList& theAttributes);
//! Returns the number (1+) of Fragment Shader outputs to be written to
//! (more than 1 can be in case of multiple draw buffers); 1 by default.
Standard_Integer NbFragmentOutputs() const { return myNbFragOutputs; }
//! Sets the number of Fragment Shader outputs to be written to.
//! Should be done before GLSL program initialization.
void SetNbFragmentOutputs (const Standard_Integer theNbOutputs) { myNbFragOutputs = theNbOutputs; }
//! Return true if Fragment Shader color should output the weighted OIT coverage; FALSE by default.
Standard_Boolean HasWeightOitOutput() const { return myHasWeightOitOutput; }
//! Set if Fragment Shader color should output the weighted OIT coverage.
//! Note that weighted OIT also requires at least 2 Fragment Outputs (color + coverage).
void SetWeightOitOutput (Standard_Boolean theOutput) { myHasWeightOitOutput = theOutput; }
//! Pushes custom uniform variable to the program. //! Pushes custom uniform variable to the program.
//! The list of pushed variables is automatically cleared after applying to GLSL program. //! The list of pushed variables is automatically cleared after applying to GLSL program.
//! Thus after program recreation even unchanged uniforms should be pushed anew. //! Thus after program recreation even unchanged uniforms should be pushed anew.
@ -164,6 +182,8 @@ private:
TCollection_AsciiString myHeader; //!< GLSL header with version code and used extensions TCollection_AsciiString myHeader; //!< GLSL header with version code and used extensions
Standard_Integer myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS) Standard_Integer myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES) Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
Standard_Integer myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
Standard_Boolean myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
}; };

View File

@ -441,18 +441,13 @@ void OpenGl_Context::SetDrawBuffers (const Standard_Integer theNb, const Standar
Standard_Boolean useDefaultFbo = Standard_False; Standard_Boolean useDefaultFbo = Standard_False;
for (Standard_Integer anI = 0; anI < theNb; ++anI) for (Standard_Integer anI = 0; anI < theNb; ++anI)
{ {
#if !defined(GL_ES_VERSION_2_0) if (theDrawBuffers[anI] < GL_COLOR_ATTACHMENT0 && theDrawBuffers[anI] != GL_NONE)
const Standard_Integer aDrawBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theDrawBuffers[anI]) : theDrawBuffers[anI];
#else
const Standard_Integer aDrawBuffer = theDrawBuffers[anI];
#endif
if (aDrawBuffer < GL_COLOR_ATTACHMENT0 && aDrawBuffer != GL_NONE)
{ {
useDefaultFbo = Standard_True; useDefaultFbo = Standard_True;
} }
else if (aDrawBuffer != GL_NONE) else if (theDrawBuffers[anI] != GL_NONE)
{ {
myDrawBuffers.SetValue (anI, aDrawBuffer); myDrawBuffers.SetValue (anI, theDrawBuffers[anI]);
} }
} }
if (arbFBO != NULL && useDefaultFbo) if (arbFBO != NULL && useDefaultFbo)

View File

@ -265,12 +265,6 @@ const char THE_FRAG_CLIP_PLANES_2[] =
EOL" discard;" EOL" discard;"
EOL" }"; EOL" }";
//! Output color and coverage for accumulation by OIT algorithm.
const char THE_FRAG_write_oit_buffers[] =
EOL" float aWeight = occFragColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2);"
EOL" occFragCoverage.r = occFragColor.a * aWeight;"
EOL" occFragColor = vec4 (occFragColor.rgb * occFragColor.a * aWeight, occFragColor.a);";
#if !defined(GL_ES_VERSION_2_0) #if !defined(GL_ES_VERSION_2_0)
static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
@ -1194,7 +1188,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
EOL" vec4 aColor = occColor;" EOL" vec4 aColor = occColor;"
EOL" aColor.a *= getAlpha();" EOL" aColor.a *= getAlpha();"
EOL" if (aColor.a <= 0.285) discard;" EOL" if (aColor.a <= 0.285) discard;"
EOL" occFragColor = aColor;" EOL" occSetFragColor (aColor);"
EOL"}"; EOL"}";
#if !defined(GL_ES_VERSION_2_0) #if !defined(GL_ES_VERSION_2_0)
@ -1245,7 +1239,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
EOL"void main()" EOL"void main()"
EOL"{" EOL"{"
EOL" gl_FragDepth = occTexture2D (uDepthSampler, TexCoord).r;" EOL" gl_FragDepth = occTexture2D (uDepthSampler, TexCoord).r;"
EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);" EOL" occSetFragColor (occTexture2D (uColorSampler, TexCoord));"
EOL"}"; EOL"}";
#if defined(GL_ES_VERSION_2_0) #if defined(GL_ES_VERSION_2_0)
@ -1268,7 +1262,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
EOL EOL
EOL"void main()" EOL"void main()"
EOL"{" EOL"{"
EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);" EOL" occSetFragColor (occTexture2D (uColorSampler, TexCoord));"
EOL"}"; EOL"}";
} }
#else #else
@ -1325,7 +1319,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramOitCompositing (const St
EOL"{" EOL"{"
EOL" vec4 aAccum = occTexture2D (uAccumTexture, TexCoord);" EOL" vec4 aAccum = occTexture2D (uAccumTexture, TexCoord);"
EOL" float aWeight = occTexture2D (uWeightTexture, TexCoord).r;" EOL" float aWeight = occTexture2D (uWeightTexture, TexCoord).r;"
EOL" occFragColor = vec4 (aAccum.rgb / max (aWeight, 0.00001), aAccum.a);" EOL" occSetFragColor (vec4 (aAccum.rgb / max (aWeight, 0.00001), aAccum.a));"
EOL"}"; EOL"}";
#if !defined(GL_ES_VERSION_2_0) #if !defined(GL_ES_VERSION_2_0)
if (myContext->IsGlGreaterEqual (3, 2)) if (myContext->IsGlGreaterEqual (3, 2))
@ -1352,7 +1346,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramOitCompositing (const St
EOL" ivec2 aTexel = ivec2 (textureSize (uAccumTexture) * TexCoord);" EOL" ivec2 aTexel = ivec2 (textureSize (uAccumTexture) * TexCoord);"
EOL" vec4 aAccum = texelFetch (uAccumTexture, aTexel, gl_SampleID);" EOL" vec4 aAccum = texelFetch (uAccumTexture, aTexel, gl_SampleID);"
EOL" float aWeight = texelFetch (uWeightTexture, aTexel, gl_SampleID).r;" EOL" float aWeight = texelFetch (uWeightTexture, aTexel, gl_SampleID).r;"
EOL" occFragColor = vec4 (aAccum.rgb / max (aWeight, 0.00001), aAccum.a);" EOL" occSetFragColor (vec4 (aAccum.rgb / max (aWeight, 0.00001), aAccum.a));"
EOL"}"; EOL"}";
#if !defined(GL_ES_VERSION_2_0) #if !defined(GL_ES_VERSION_2_0)
if (myContext->IsGlGreaterEqual (4, 0)) if (myContext->IsGlGreaterEqual (4, 0))
@ -1429,7 +1423,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcGetAlpha; TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcGetAlpha;
TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain, aSrcFragWriteOit; TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain, aSrcFragWriteOit;
TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return occColor; }"; TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return occColor; }";
TCollection_AsciiString aSrcFragMainGetColor = EOL" occFragColor = getColor();"; TCollection_AsciiString aSrcFragMainGetColor = EOL" occSetFragColor (getColor());";
if ((theBits & OpenGl_PO_Point) != 0) if ((theBits & OpenGl_PO_Point) != 0)
{ {
#if defined(GL_ES_VERSION_2_0) #if defined(GL_ES_VERSION_2_0)
@ -1458,14 +1452,14 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
EOL" vec4 aColor = getColor();" EOL" vec4 aColor = getColor();"
EOL" aColor.a = getAlpha();" EOL" aColor.a = getAlpha();"
EOL" if (aColor.a <= 0.1) discard;" EOL" if (aColor.a <= 0.1) discard;"
EOL" occFragColor = aColor;"; EOL" occSetFragColor (aColor);";
} }
else else
{ {
aSrcFragMainGetColor = aSrcFragMainGetColor =
EOL" vec4 aColor = getColor();" EOL" vec4 aColor = getColor();"
EOL" if (aColor.a <= 0.1) discard;" EOL" if (aColor.a <= 0.1) discard;"
EOL" occFragColor = aColor;"; EOL" occSetFragColor (aColor);";
} }
} }
else else
@ -1536,7 +1530,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
} }
if ((theBits & OpenGl_PO_WriteOit) != 0) if ((theBits & OpenGl_PO_WriteOit) != 0)
{ {
aSrcFragWriteOit += THE_FRAG_write_oit_buffers; aProgramSrc->SetNbFragmentOutputs (2);
aProgramSrc->SetWeightOitOutput (true);
} }
TCollection_AsciiString aSrcVertEndMain; TCollection_AsciiString aSrcVertEndMain;
@ -1578,7 +1573,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
EOL" if ((uint (uPattern) & (1U << aBit)) == 0U) discard;" EOL" if ((uint (uPattern) & (1U << aBit)) == 0U) discard;"
EOL" vec4 aColor = getColor();" EOL" vec4 aColor = getColor();"
EOL" if (aColor.a <= 0.1) discard;" EOL" if (aColor.a <= 0.1) discard;"
EOL" occFragColor = aColor;"; EOL" occSetFragColor (aColor);";
} }
else else
{ {
@ -1888,7 +1883,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
} }
if ((theBits & OpenGl_PO_WriteOit) != 0) if ((theBits & OpenGl_PO_WriteOit) != 0)
{ {
aSrcFragWriteOit += THE_FRAG_write_oit_buffers; aProgramSrc->SetNbFragmentOutputs (2);
aProgramSrc->SetWeightOitOutput (true);
} }
Standard_Integer aNbLights = 0; Standard_Integer aNbLights = 0;
@ -1923,7 +1919,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
+ EOL"void main()" + EOL"void main()"
EOL"{" EOL"{"
+ aSrcFragExtraMain + aSrcFragExtraMain
+ EOL" occFragColor = getColor();" + EOL" occSetFragColor (getColor());"
+ aSrcFragWriteOit + aSrcFragWriteOit
+ EOL"}"; + EOL"}";
@ -2037,7 +2033,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
} }
if ((theBits & OpenGl_PO_WriteOit) != 0) if ((theBits & OpenGl_PO_WriteOit) != 0)
{ {
aSrcFragWriteOit += THE_FRAG_write_oit_buffers; aProgramSrc->SetNbFragmentOutputs (2);
aProgramSrc->SetWeightOitOutput (true);
} }
aSrcVert = TCollection_AsciiString() aSrcVert = TCollection_AsciiString()
@ -2082,7 +2079,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
+ (isFlatNormal + (isFlatNormal
? EOL" Normal = normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));" ? EOL" Normal = normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));"
: "") : "")
+ EOL" occFragColor = getColor();" + EOL" occSetFragColor (getColor());"
+ aSrcFragWriteOit + aSrcFragWriteOit
+ EOL"}"; + EOL"}";
@ -2163,7 +2160,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
EOL" aColorL = pow (aColorL, THE_POW_UP);" // normalize EOL" aColorL = pow (aColorL, THE_POW_UP);" // normalize
EOL" aColorR = pow (aColorR, THE_POW_UP);" EOL" aColorR = pow (aColorR, THE_POW_UP);"
EOL" vec4 aColor = uMultR * aColorR + uMultL * aColorL;" EOL" vec4 aColor = uMultR * aColorR + uMultL * aColorL;"
EOL" occFragColor = pow (aColor, THE_POW_DOWN);" EOL" occSetFragColor (pow (aColor, THE_POW_DOWN));"
EOL"}"; EOL"}";
break; break;
} }
@ -2181,11 +2178,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);" EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
EOL" if (int (mod (gl_FragCoord.y - 1023.5, 2.0)) != 1)" EOL" if (int (mod (gl_FragCoord.y - 1023.5, 2.0)) != 1)"
EOL" {" EOL" {"
EOL" occFragColor = aColorL;" EOL" occSetFragColor (aColorL);"
EOL" }" EOL" }"
EOL" else" EOL" else"
EOL" {" EOL" {"
EOL" occFragColor = aColorR;" EOL" occSetFragColor (aColorR);"
EOL" }" EOL" }"
EOL"}"; EOL"}";
break; break;
@ -2204,11 +2201,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);" EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
EOL" if (int (mod (gl_FragCoord.x - 1023.5, 2.0)) == 1)" EOL" if (int (mod (gl_FragCoord.x - 1023.5, 2.0)) == 1)"
EOL" {" EOL" {"
EOL" occFragColor = aColorL;" EOL" occSetFragColor (aColorL);"
EOL" }" EOL" }"
EOL" else" EOL" else"
EOL" {" EOL" {"
EOL" occFragColor = aColorR;" EOL" occSetFragColor (aColorR);"
EOL" }" EOL" }"
EOL"}"; EOL"}";
break; break;
@ -2229,11 +2226,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
EOL" bool isEvenY = int(mod(floor(gl_FragCoord.y - 1023.5), 2.0)) == 1;" EOL" bool isEvenY = int(mod(floor(gl_FragCoord.y - 1023.5), 2.0)) == 1;"
EOL" if ((isEvenX && isEvenY) || (!isEvenX && !isEvenY))" EOL" if ((isEvenX && isEvenY) || (!isEvenX && !isEvenY))"
EOL" {" EOL" {"
EOL" occFragColor = aColorL;" EOL" occSetFragColor (aColorL);"
EOL" }" EOL" }"
EOL" else" EOL" else"
EOL" {" EOL" {"
EOL" occFragColor = aColorR;" EOL" occSetFragColor (aColorR);"
EOL" }" EOL" }"
EOL"}"; EOL"}";
break; break;
@ -2257,11 +2254,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);" EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
EOL" if (TexCoord.x <= 0.5)" EOL" if (TexCoord.x <= 0.5)"
EOL" {" EOL" {"
EOL" occFragColor = aColorL;" EOL" occSetFragColor (aColorL);"
EOL" }" EOL" }"
EOL" else" EOL" else"
EOL" {" EOL" {"
EOL" occFragColor = aColorR;" EOL" occSetFragColor (aColorR);"
EOL" }" EOL" }"
EOL"}"; EOL"}";
break; break;
@ -2285,11 +2282,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);" EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
EOL" if (TexCoord.y <= 0.5)" EOL" if (TexCoord.y <= 0.5)"
EOL" {" EOL" {"
EOL" occFragColor = aColorL;" EOL" occSetFragColor (aColorL);"
EOL" }" EOL" }"
EOL" else" EOL" else"
EOL" {" EOL" {"
EOL" occFragColor = aColorR;" EOL" occSetFragColor (aColorR);"
EOL" }" EOL" }"
EOL"}"; EOL"}";
break; break;
@ -2316,7 +2313,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
EOL" aColorL.b = 0.0;" EOL" aColorL.b = 0.0;"
EOL" aColorL.g = 0.0;" EOL" aColorL.g = 0.0;"
EOL" aColorR.r = 0.0;" EOL" aColorR.r = 0.0;"
EOL" occFragColor = aColorL + aColorR;" EOL" occSetFragColor (aColorL + aColorR);"
EOL"}"; EOL"}";
break; break;
} }

View File

@ -151,6 +151,8 @@ OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram
myShareCount(1), myShareCount(1),
myNbLightsMax (0), myNbLightsMax (0),
myNbClipPlanesMax (0), myNbClipPlanesMax (0),
myNbFragOutputs (1),
myHasWeightOitOutput (false),
myHasTessShader (false) myHasTessShader (false)
{ {
memset (myCurrentState, 0, sizeof (myCurrentState)); memset (myCurrentState, 0, sizeof (myCurrentState));
@ -180,6 +182,8 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
aShaderMask |= anIter.Value()->Type(); aShaderMask |= anIter.Value()->Type();
} }
myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0; myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
// detect the minimum GLSL version required for defined Shader Objects // detect the minimum GLSL version required for defined Shader Objects
#if defined(GL_ES_VERSION_2_0) #if defined(GL_ES_VERSION_2_0)
@ -275,19 +279,33 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
} }
TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n"; TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
if (theCtx->hasDrawBuffers) if (myNbFragOutputs > 1)
{ {
anExtensions += "#define OCC_ENABLE_draw_buffers\n"; if (theCtx->hasDrawBuffers)
}
if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
{
if (theCtx->arbDrawBuffers)
{ {
anExtensions += "#extension GL_ARB_draw_buffers : enable\n"; anExtensions += "#define OCC_ENABLE_draw_buffers\n";
if (myHasWeightOitOutput)
{
anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n";
}
} }
else if (theCtx->extDrawBuffers) else
{ {
anExtensions += "#extension GL_EXT_draw_buffers : enable\n"; theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
"Error! Multiple draw buffers required by the program, but aren't supported by OpenGL");
return Standard_False;
}
if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
{
if (theCtx->arbDrawBuffers)
{
anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
}
else if (theCtx->extDrawBuffers)
{
anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
}
} }
} }
@ -334,6 +352,7 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0; myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n"; aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n"; aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
+ (!aHeaderVer.IsEmpty() ? "\n" : "") + (!aHeaderVer.IsEmpty() ? "\n" : "")

View File

@ -226,6 +226,13 @@ public:
//! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS). //! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS).
Standard_Integer NbClipPlanesMax() const { return myNbClipPlanesMax; } Standard_Integer NbClipPlanesMax() const { return myNbClipPlanesMax; }
//! Return the length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS),
//! to be used for initialization occFragColorArray/occFragColorN.
Standard_Integer NbFragmentOutputs() const { return myNbFragOutputs; }
//! Return true if Fragment Shader color should output the weighted OIT coverage; FALSE by default.
Standard_Boolean HasWeightOitOutput() const { return myHasWeightOitOutput; }
private: private:
//! Returns index of last modification of variables of specified state type. //! Returns index of last modification of variables of specified state type.
@ -569,6 +576,8 @@ protected:
Standard_Integer myShareCount; //!< program users count, initialized with 1 (already shared by one user) Standard_Integer myShareCount; //!< program users count, initialized with 1 (already shared by one user)
Standard_Integer myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS) Standard_Integer myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES) Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
Standard_Integer myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
Standard_Boolean myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
Standard_Boolean myHasTessShader; //!< flag indicating that program defines tessellation stage Standard_Boolean myHasTessShader; //!< flag indicating that program defines tessellation stage
protected: protected:

View File

@ -24,6 +24,10 @@
//! Specifies the length of array of clipping planes, which is 8 by default. Defined by Shader Manager. //! Specifies the length of array of clipping planes, which is 8 by default. Defined by Shader Manager.
// #define THE_MAX_CLIP_PLANES 8 // #define THE_MAX_CLIP_PLANES 8
//! @def THE_NB_FRAG_OUTPUTS
//! Specifies the length of array of Fragment Shader outputs, which is 1 by default. Defined by Shader Manager.
// #define THE_NB_FRAG_OUTPUTS 1
// compatibility macros // compatibility macros
#if (__VERSION__ >= 130) #if (__VERSION__ >= 130)
#define THE_ATTRIBUTE in #define THE_ATTRIBUTE in
@ -58,20 +62,43 @@
#elif defined(FRAGMENT_SHADER) #elif defined(FRAGMENT_SHADER)
#if (__VERSION__ >= 130) #if (__VERSION__ >= 130)
#ifdef OCC_ENABLE_draw_buffers #ifdef OCC_ENABLE_draw_buffers
out vec4 occFragColorArray[2]; out vec4 occFragColorArray[THE_NB_FRAG_OUTPUTS];
#define occFragColor occFragColorArray[0] #define occFragColorArrayAlias occFragColorArray
#define occFragCoverage occFragColorArray[1] #define occFragColor0 occFragColorArray[0]
#else #else
out vec4 occFragColor; out vec4 occFragColor0;
#endif #endif
#else #else
#ifdef OCC_ENABLE_draw_buffers #ifdef OCC_ENABLE_draw_buffers
#define occFragColor gl_FragData[0] #define occFragColorArrayAlias gl_FragData
#define occFragCoverage gl_FragData[1] #define occFragColor0 gl_FragData[0]
#else #else
#define occFragColor gl_FragColor #define occFragColor0 gl_FragColor
#endif #endif
#endif #endif
#if (THE_NB_FRAG_OUTPUTS >= 2)
#define occFragColor1 occFragColorArrayAlias[1]
#else
vec4 occFragColor1;
#endif
#if (THE_NB_FRAG_OUTPUTS >= 3)
#define occFragColor2 occFragColorArrayAlias[2]
#else
vec4 occFragColor2;
#endif
#if (THE_NB_FRAG_OUTPUTS >= 4)
#define occFragColor3 occFragColorArrayAlias[3]
#else
vec4 occFragColor3;
#endif
// Built-in outputs notation
#define occFragColor occFragColor0
#define occFragCoverage occFragColor1
//! Define the main Fragment Shader output - color value.
void occSetFragColor (in vec4 theColor);
#endif #endif
// Matrix state // Matrix state

View File

@ -15,6 +15,21 @@
// This file includes implementation of common functions and properties accessors // This file includes implementation of common functions and properties accessors
#if defined(FRAGMENT_SHADER)
#if defined(OCC_WRITE_WEIGHT_OIT_COVERAGE)
//! Output color and coverage for accumulation by OIT algorithm.
void occSetFragColor (in vec4 theColor)
{
float aWeight = theColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2);
occFragCoverage.r = theColor.a * aWeight;
occFragColor = vec4 (theColor.rgb * theColor.a * aWeight, theColor.a);
}
#else
//! Output color.
void occSetFragColor (in vec4 theColor) { occFragColor = theColor; }
#endif
#endif
#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0) #if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)
// arrays of light sources // arrays of light sources
uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types

View File

@ -186,14 +186,6 @@ void main()
} }
} }
occFragColor = computeLighting (normalize (Normal), vec4 aColor = computeLighting (normalize (Normal), normalize (View), Position);
normalize (View), occSetFragColor (aColor);
Position);
if (occOitOutput != 0)
{
float aWeight = occFragColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2);
occFragCoverage.r = occFragColor.a * aWeight;
occFragColor = vec4 (occFragColor.rgb * occFragColor.a * aWeight, occFragColor.a);
}
} }

View File

@ -18,6 +18,21 @@ static const char Shaders_DeclarationsImpl_glsl[] =
"\n" "\n"
"// This file includes implementation of common functions and properties accessors\n" "// This file includes implementation of common functions and properties accessors\n"
"\n" "\n"
"#if defined(FRAGMENT_SHADER)\n"
"#if defined(OCC_WRITE_WEIGHT_OIT_COVERAGE)\n"
"//! Output color and coverage for accumulation by OIT algorithm.\n"
"void occSetFragColor (in vec4 theColor)\n"
"{\n"
" float aWeight = theColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2);\n"
" occFragCoverage.r = theColor.a * aWeight;\n"
" occFragColor = vec4 (theColor.rgb * theColor.a * aWeight, theColor.a);\n"
"}\n"
"#else\n"
"//! Output color.\n"
"void occSetFragColor (in vec4 theColor) { occFragColor = theColor; }\n"
"#endif\n"
"#endif\n"
"\n"
"#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)\n" "#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)\n"
"// arrays of light sources\n" "// arrays of light sources\n"
"uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types\n" "uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types\n"

View File

@ -27,6 +27,10 @@ static const char Shaders_Declarations_glsl[] =
"//! Specifies the length of array of clipping planes, which is 8 by default. Defined by Shader Manager.\n" "//! Specifies the length of array of clipping planes, which is 8 by default. Defined by Shader Manager.\n"
"// #define THE_MAX_CLIP_PLANES 8\n" "// #define THE_MAX_CLIP_PLANES 8\n"
"\n" "\n"
"//! @def THE_NB_FRAG_OUTPUTS\n"
"//! Specifies the length of array of Fragment Shader outputs, which is 1 by default. Defined by Shader Manager.\n"
"// #define THE_NB_FRAG_OUTPUTS 1\n"
"\n"
"// compatibility macros\n" "// compatibility macros\n"
"#if (__VERSION__ >= 130)\n" "#if (__VERSION__ >= 130)\n"
" #define THE_ATTRIBUTE in\n" " #define THE_ATTRIBUTE in\n"
@ -61,20 +65,43 @@ static const char Shaders_Declarations_glsl[] =
"#elif defined(FRAGMENT_SHADER)\n" "#elif defined(FRAGMENT_SHADER)\n"
" #if (__VERSION__ >= 130)\n" " #if (__VERSION__ >= 130)\n"
" #ifdef OCC_ENABLE_draw_buffers\n" " #ifdef OCC_ENABLE_draw_buffers\n"
" out vec4 occFragColorArray[2];\n" " out vec4 occFragColorArray[THE_NB_FRAG_OUTPUTS];\n"
" #define occFragColor occFragColorArray[0]\n" " #define occFragColorArrayAlias occFragColorArray\n"
" #define occFragCoverage occFragColorArray[1]\n" " #define occFragColor0 occFragColorArray[0]\n"
" #else\n" " #else\n"
" out vec4 occFragColor;\n" " out vec4 occFragColor0;\n"
" #endif\n" " #endif\n"
" #else\n" " #else\n"
" #ifdef OCC_ENABLE_draw_buffers\n" " #ifdef OCC_ENABLE_draw_buffers\n"
" #define occFragColor gl_FragData[0]\n" " #define occFragColorArrayAlias gl_FragData\n"
" #define occFragCoverage gl_FragData[1]\n" " #define occFragColor0 gl_FragData[0]\n"
" #else\n" " #else\n"
" #define occFragColor gl_FragColor\n" " #define occFragColor0 gl_FragColor\n"
" #endif\n" " #endif\n"
" #endif\n" " #endif\n"
"\n"
" #if (THE_NB_FRAG_OUTPUTS >= 2)\n"
" #define occFragColor1 occFragColorArrayAlias[1]\n"
" #else\n"
" vec4 occFragColor1;\n"
" #endif\n"
" #if (THE_NB_FRAG_OUTPUTS >= 3)\n"
" #define occFragColor2 occFragColorArrayAlias[2]\n"
" #else\n"
" vec4 occFragColor2;\n"
" #endif\n"
" #if (THE_NB_FRAG_OUTPUTS >= 4)\n"
" #define occFragColor3 occFragColorArrayAlias[3]\n"
" #else\n"
" vec4 occFragColor3;\n"
" #endif\n"
"\n"
" // Built-in outputs notation\n"
" #define occFragColor occFragColor0\n"
" #define occFragCoverage occFragColor1\n"
"\n"
" //! Define the main Fragment Shader output - color value.\n"
" void occSetFragColor (in vec4 theColor);\n"
"#endif\n" "#endif\n"
"\n" "\n"
"// Matrix state\n" "// Matrix state\n"

View File

@ -736,7 +736,8 @@ static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
const TCollection_AsciiString& aShaderSrc = aShader->Source(); const TCollection_AsciiString& aShaderSrc = aShader->Source();
const bool hasVertPos = aShaderSrc.Search ("gl_Position") != -1; const bool hasVertPos = aShaderSrc.Search ("gl_Position") != -1;
const bool hasFragColor = aShaderSrc.Search ("occFragColor") != -1 const bool hasFragColor = aShaderSrc.Search ("occSetFragColor") != -1
|| aShaderSrc.Search ("occFragColor") != -1
|| aShaderSrc.Search ("gl_FragColor") != -1 || aShaderSrc.Search ("gl_FragColor") != -1
|| aShaderSrc.Search ("gl_FragData") != -1; || aShaderSrc.Search ("gl_FragData") != -1;
Graphic3d_TypeOfShaderObject aShaderType = aShaderTypeArg; Graphic3d_TypeOfShaderObject aShaderType = aShaderTypeArg;
@ -768,6 +769,13 @@ static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
} }
} }
if (!aProgram.IsNull()
&& ViewerTest::CurrentView()->RenderingParams().TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
{
aProgram->SetNbFragmentOutputs (2);
aProgram->SetWeightOitOutput (true);
}
ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aGlobalPrsIter (GetMapOfAIS()); ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aGlobalPrsIter (GetMapOfAIS());
NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator aPrsIter (aPrsList); NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator aPrsIter (aPrsList);
const bool isGlobalList = aPrsList.IsEmpty(); const bool isGlobalList = aPrsList.IsEmpty();