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.
// =======================================================================
Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
: 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_")
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER));
//! Default value of THE_MAX_CLIP_PLANES macros within GLSL program (see Declarations.glsl).
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:
//! Creates new empty program object.
//! Should be done before GLSL program initialization.
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.
//! The list of pushed variables is automatically cleared after applying to GLSL program.
//! Thus after program recreation even unchanged uniforms should be pushed anew.
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 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 useDefaultFbo = Standard_False;
for (Standard_Integer anI = 0; anI < theNb; ++anI)
{
-#if !defined(GL_ES_VERSION_2_0)
- 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)
+ if (theDrawBuffers[anI] < GL_COLOR_ATTACHMENT0 && theDrawBuffers[anI] != GL_NONE)
{
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)
EOL" discard;"
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)
static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
EOL" vec4 aColor = occColor;"
EOL" aColor.a *= getAlpha();"
EOL" if (aColor.a <= 0.285) discard;"
- EOL" occFragColor = aColor;"
+ EOL" occSetFragColor (aColor);"
EOL"}";
#if !defined(GL_ES_VERSION_2_0)
EOL"void main()"
EOL"{"
EOL" gl_FragDepth = occTexture2D (uDepthSampler, TexCoord).r;"
- EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
+ EOL" occSetFragColor (occTexture2D (uColorSampler, TexCoord));"
EOL"}";
#if defined(GL_ES_VERSION_2_0)
EOL
EOL"void main()"
EOL"{"
- EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
+ EOL" occSetFragColor (occTexture2D (uColorSampler, TexCoord));"
EOL"}";
}
#else
EOL"{"
EOL" vec4 aAccum = occTexture2D (uAccumTexture, TexCoord);"
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"}";
#if !defined(GL_ES_VERSION_2_0)
if (myContext->IsGlGreaterEqual (3, 2))
EOL" ivec2 aTexel = ivec2 (textureSize (uAccumTexture) * TexCoord);"
EOL" vec4 aAccum = texelFetch (uAccumTexture, aTexel, gl_SampleID);"
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"}";
#if !defined(GL_ES_VERSION_2_0)
if (myContext->IsGlGreaterEqual (4, 0))
TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcGetAlpha;
TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain, aSrcFragWriteOit;
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 defined(GL_ES_VERSION_2_0)
EOL" vec4 aColor = getColor();"
EOL" aColor.a = getAlpha();"
EOL" if (aColor.a <= 0.1) discard;"
- EOL" occFragColor = aColor;";
+ EOL" occSetFragColor (aColor);";
}
else
{
aSrcFragMainGetColor =
EOL" vec4 aColor = getColor();"
EOL" if (aColor.a <= 0.1) discard;"
- EOL" occFragColor = aColor;";
+ EOL" occSetFragColor (aColor);";
}
}
else
}
if ((theBits & OpenGl_PO_WriteOit) != 0)
{
- aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
+ aProgramSrc->SetNbFragmentOutputs (2);
+ aProgramSrc->SetWeightOitOutput (true);
}
TCollection_AsciiString aSrcVertEndMain;
EOL" if ((uint (uPattern) & (1U << aBit)) == 0U) discard;"
EOL" vec4 aColor = getColor();"
EOL" if (aColor.a <= 0.1) discard;"
- EOL" occFragColor = aColor;";
+ EOL" occSetFragColor (aColor);";
}
else
{
}
if ((theBits & OpenGl_PO_WriteOit) != 0)
{
- aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
+ aProgramSrc->SetNbFragmentOutputs (2);
+ aProgramSrc->SetWeightOitOutput (true);
}
Standard_Integer aNbLights = 0;
+ EOL"void main()"
EOL"{"
+ aSrcFragExtraMain
- + EOL" occFragColor = getColor();"
+ + EOL" occSetFragColor (getColor());"
+ aSrcFragWriteOit
+ EOL"}";
}
if ((theBits & OpenGl_PO_WriteOit) != 0)
{
- aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
+ aProgramSrc->SetNbFragmentOutputs (2);
+ aProgramSrc->SetWeightOitOutput (true);
}
aSrcVert = TCollection_AsciiString()
+ (isFlatNormal
? EOL" Normal = normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));"
: "")
- + EOL" occFragColor = getColor();"
+ + EOL" occSetFragColor (getColor());"
+ aSrcFragWriteOit
+ EOL"}";
EOL" aColorL = pow (aColorL, THE_POW_UP);" // normalize
EOL" aColorR = pow (aColorR, THE_POW_UP);"
EOL" vec4 aColor = uMultR * aColorR + uMultL * aColorL;"
- EOL" occFragColor = pow (aColor, THE_POW_DOWN);"
+ EOL" occSetFragColor (pow (aColor, THE_POW_DOWN));"
EOL"}";
break;
}
EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
EOL" if (int (mod (gl_FragCoord.y - 1023.5, 2.0)) != 1)"
EOL" {"
- EOL" occFragColor = aColorL;"
+ EOL" occSetFragColor (aColorL);"
EOL" }"
EOL" else"
EOL" {"
- EOL" occFragColor = aColorR;"
+ EOL" occSetFragColor (aColorR);"
EOL" }"
EOL"}";
break;
EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
EOL" if (int (mod (gl_FragCoord.x - 1023.5, 2.0)) == 1)"
EOL" {"
- EOL" occFragColor = aColorL;"
+ EOL" occSetFragColor (aColorL);"
EOL" }"
EOL" else"
EOL" {"
- EOL" occFragColor = aColorR;"
+ EOL" occSetFragColor (aColorR);"
EOL" }"
EOL"}";
break;
EOL" bool isEvenY = int(mod(floor(gl_FragCoord.y - 1023.5), 2.0)) == 1;"
EOL" if ((isEvenX && isEvenY) || (!isEvenX && !isEvenY))"
EOL" {"
- EOL" occFragColor = aColorL;"
+ EOL" occSetFragColor (aColorL);"
EOL" }"
EOL" else"
EOL" {"
- EOL" occFragColor = aColorR;"
+ EOL" occSetFragColor (aColorR);"
EOL" }"
EOL"}";
break;
EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
EOL" if (TexCoord.x <= 0.5)"
EOL" {"
- EOL" occFragColor = aColorL;"
+ EOL" occSetFragColor (aColorL);"
EOL" }"
EOL" else"
EOL" {"
- EOL" occFragColor = aColorR;"
+ EOL" occSetFragColor (aColorR);"
EOL" }"
EOL"}";
break;
EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
EOL" if (TexCoord.y <= 0.5)"
EOL" {"
- EOL" occFragColor = aColorL;"
+ EOL" occSetFragColor (aColorL);"
EOL" }"
EOL" else"
EOL" {"
- EOL" occFragColor = aColorR;"
+ EOL" occSetFragColor (aColorR);"
EOL" }"
EOL"}";
break;
EOL" aColorL.b = 0.0;"
EOL" aColorL.g = 0.0;"
EOL" aColorR.r = 0.0;"
- EOL" occFragColor = aColorL + aColorR;"
+ EOL" occSetFragColor (aColorL + aColorR);"
EOL"}";
break;
}
myShareCount(1),
myNbLightsMax (0),
myNbClipPlanesMax (0),
+ myNbFragOutputs (1),
+ myHasWeightOitOutput (false),
myHasTessShader (false)
{
memset (myCurrentState, 0, sizeof (myCurrentState));
aShaderMask |= anIter.Value()->Type();
}
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
#if defined(GL_ES_VERSION_2_0)
}
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 == OpenGl_FeatureInExtensions)
- {
- if (theCtx->arbDrawBuffers)
+ if (theCtx->hasDrawBuffers)
{
- 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
+ {
+ 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)
{
- anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
+ if (theCtx->arbDrawBuffers)
+ {
+ anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
+ }
+ else if (theCtx->extDrawBuffers)
+ {
+ anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
+ }
}
}
myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\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
+ (!aHeaderVer.IsEmpty() ? "\n" : "")
//! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS).
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:
//! Returns index of last modification of variables of specified state type.
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 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
protected:
//! Specifies the length of array of clipping planes, which is 8 by default. Defined by Shader Manager.
// #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
#if (__VERSION__ >= 130)
#define THE_ATTRIBUTE in
#elif defined(FRAGMENT_SHADER)
#if (__VERSION__ >= 130)
#ifdef OCC_ENABLE_draw_buffers
- out vec4 occFragColorArray[2];
- #define occFragColor occFragColorArray[0]
- #define occFragCoverage occFragColorArray[1]
+ out vec4 occFragColorArray[THE_NB_FRAG_OUTPUTS];
+ #define occFragColorArrayAlias occFragColorArray
+ #define occFragColor0 occFragColorArray[0]
#else
- out vec4 occFragColor;
+ out vec4 occFragColor0;
#endif
#else
#ifdef OCC_ENABLE_draw_buffers
- #define occFragColor gl_FragData[0]
- #define occFragCoverage gl_FragData[1]
+ #define occFragColorArrayAlias gl_FragData
+ #define occFragColor0 gl_FragData[0]
#else
- #define occFragColor gl_FragColor
+ #define occFragColor0 gl_FragColor
#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
// Matrix state
// 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)
// arrays of light sources
uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types
}
}
- occFragColor = computeLighting (normalize (Normal),
- normalize (View),
- 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);
- }
+ vec4 aColor = computeLighting (normalize (Normal), normalize (View), Position);
+ occSetFragColor (aColor);
}
"\n"
"// This file includes implementation of common functions and properties accessors\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"
"// arrays of light sources\n"
"uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types\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"
"\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"
"#if (__VERSION__ >= 130)\n"
" #define THE_ATTRIBUTE in\n"
"#elif defined(FRAGMENT_SHADER)\n"
" #if (__VERSION__ >= 130)\n"
" #ifdef OCC_ENABLE_draw_buffers\n"
- " out vec4 occFragColorArray[2];\n"
- " #define occFragColor occFragColorArray[0]\n"
- " #define occFragCoverage occFragColorArray[1]\n"
+ " out vec4 occFragColorArray[THE_NB_FRAG_OUTPUTS];\n"
+ " #define occFragColorArrayAlias occFragColorArray\n"
+ " #define occFragColor0 occFragColorArray[0]\n"
" #else\n"
- " out vec4 occFragColor;\n"
+ " out vec4 occFragColor0;\n"
" #endif\n"
" #else\n"
" #ifdef OCC_ENABLE_draw_buffers\n"
- " #define occFragColor gl_FragData[0]\n"
- " #define occFragCoverage gl_FragData[1]\n"
+ " #define occFragColorArrayAlias gl_FragData\n"
+ " #define occFragColor0 gl_FragData[0]\n"
" #else\n"
- " #define occFragColor gl_FragColor\n"
+ " #define occFragColor0 gl_FragColor\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"
"\n"
"// Matrix state\n"
const TCollection_AsciiString& aShaderSrc = aShader->Source();
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_FragData") != -1;
Graphic3d_TypeOfShaderObject aShaderType = aShaderTypeArg;
}
}
+ if (!aProgram.IsNull()
+ && ViewerTest::CurrentView()->RenderingParams().TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
+ {
+ aProgram->SetNbFragmentOutputs (2);
+ aProgram->SetWeightOitOutput (true);
+ }
+
ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aGlobalPrsIter (GetMapOfAIS());
NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator aPrsIter (aPrsList);
const bool isGlobalList = aPrsList.IsEmpty();