Enable multiple draw buffers in shader program only if its required by specific application
// purpose : Creates new empty program object
// =======================================================================
Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
+: myIsMultiOutput (Standard_False)
{
myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_")
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER));
{
myAttributes = theAttributes;
}
+
+// =======================================================================
+// function : SetMultipleDrawBuffers
+// purpose :
+// =======================================================================
+void Graphic3d_ShaderProgram::SetUseMultipleDrawBuffers (const Standard_Boolean theIsMultiple)
+{
+ myIsMultiOutput = theIsMultiple;
+}
//! Should be done before GLSL program initialization.
Standard_EXPORT void SetVertexAttributes (const Graphic3d_ShaderAttributeList& theAttributes);
+ //! Returns true if shader program should write to multiple draw buffers.
+ Standard_Boolean UseMultipleDrawBuffers() const { return myIsMultiOutput; }
+
+ //! Sets a flag that shader program should write to multiple draw buffers (false by default, minimum 4 is supported).
+ //! Should be done before GLSL program initialization.
+ Standard_EXPORT void SetUseMultipleDrawBuffers (const Standard_Boolean theIsMultiple);
+
//! 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.
Graphic3d_ShaderVariableList myVariables; //!< the list of custom uniform variables
Graphic3d_ShaderAttributeList myAttributes; //!< the list of custom vertex attributes
TCollection_AsciiString myHeader; //!< GLSL header with version code and used extensions
-
+ Standard_Boolean myIsMultiOutput; //!< indicates whether program should use multiple draw buffers.
};
DEFINE_STANDARD_HANDLE (Graphic3d_ShaderProgram, Standard_Transient)
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)
}
if ((theBits & OpenGl_PO_WriteOit) != 0)
{
+ aProgramSrc->SetUseMultipleDrawBuffers (Standard_True);
+
aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
}
}
if ((theBits & OpenGl_PO_WriteOit) != 0)
{
+ aProgramSrc->SetUseMultipleDrawBuffers (Standard_True);
+
aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
}
}
if ((theBits & OpenGl_PO_WriteOit) != 0)
{
+ aProgramSrc->SetUseMultipleDrawBuffers (Standard_True);
+
aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
}
? (myProxy->Header() + "\n")
: TCollection_AsciiString();
+ Standard_Boolean toEnableDrawBuffers = !myProxy.IsNull()
+ ? myProxy->UseMultipleDrawBuffers()
+ : Standard_False;
+
TCollection_AsciiString aDeclarations = Shaders_Declarations_glsl;
TCollection_AsciiString aDeclImpl = Shaders_DeclarationsImpl_glsl;
TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
- if (theCtx->hasDrawBuffers)
- {
- anExtensions += "#define OCC_ENABLE_draw_buffers\n";
- }
- if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
+ if (toEnableDrawBuffers)
{
- if (theCtx->arbDrawBuffers)
+ if (theCtx->hasDrawBuffers)
+ {
+ anExtensions += "#define OCC_ENABLE_draw_buffers\n";
+ }
+ else
{
- anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
+ TCollection_ExtendedString aMsg = "Error! Multiple draw buffers required by the program, but aren't supported by GL";
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
+ 0,
+ GL_DEBUG_SEVERITY_HIGH,
+ aMsg);
+ return Standard_False;
}
- else if (theCtx->extDrawBuffers)
+
+ 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";
+ }
}
}
THE_ATTRIBUTE vec4 occVertColor;
#elif (__VERSION__ >= 130)
#ifdef OCC_ENABLE_draw_buffers
- out vec4 occFragColorArray[2];
- #define occFragColor occFragColorArray[0]
- #define occFragCoverage occFragColorArray[1]
+ out vec4 occFragColorArray[4];
+ // General purpose outputs notation
+ #define occFragColor0 occFragColorArray[0]
+ #define occFragColor1 occFragColorArray[1]
+ #define occFragColor2 occFragColorArray[2]
+ #define occFragColor3 occFragColorArray[3]
+ // Built-in outputs notation
+ #define occFragColor occFragColor0
+ #define occFragCoverage occFragColor1
#else
out vec4 occFragColor;
#endif
#else
#ifdef OCC_ENABLE_draw_buffers
- #define occFragColor gl_FragData[0]
- #define occFragCoverage gl_FragData[1]
+ // General purpose outputs notation
+ #define occFragColor0 gl_FragData[0]
+ #define occFragColor1 gl_FragData[1]
+ #define occFragColor2 gl_FragData[2]
+ #define occFragColor3 gl_FragData[3]
+ // Built-in outputs notation
+ #define occFragColor occFragColor0
+ #define occFragCoverage occFragColor1
#else
#define occFragColor gl_FragColor
#endif
" THE_ATTRIBUTE vec4 occVertColor;\n"
"#elif (__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[4];\n"
+ " // General purpose outputs notation\n"
+ " #define occFragColor0 occFragColorArray[0]\n"
+ " #define occFragColor1 occFragColorArray[1]\n"
+ " #define occFragColor2 occFragColorArray[2]\n"
+ " #define occFragColor3 occFragColorArray[3]\n"
+ " // Built-in outputs notation\n"
+ " #define occFragColor occFragColor0\n"
+ " #define occFragCoverage occFragColor1\n"
" #else\n"
" out vec4 occFragColor;\n"
" #endif\n"
"#else\n"
" #ifdef OCC_ENABLE_draw_buffers\n"
- " #define occFragColor gl_FragData[0]\n"
- " #define occFragCoverage gl_FragData[1]\n"
+ " // General purpose outputs notation\n"
+ " #define occFragColor0 gl_FragData[0]\n"
+ " #define occFragColor1 gl_FragData[1]\n"
+ " #define occFragColor2 gl_FragData[2]\n"
+ " #define occFragColor3 gl_FragData[3]\n"
+ " // Built-in outputs notation\n"
+ " #define occFragColor occFragColor0\n"
+ " #define occFragCoverage occFragColor1\n"
" #else\n"
" #define occFragColor gl_FragColor\n"
" #endif\n"