OpenGl_ShaderObject::LoadAndCompile() - added method combining Load() and Compile() with optional error logging.
OpenGl_ShaderProgram::Link() now logs failures by default.
// commercial license or contractual agreement.
#include <Graphic3d_ShaderObject.hxx>
+
#include <OpenGl_Context.hxx>
#include <OpenGl_ShaderObject.hxx>
#include <OSD_Path.hxx>
#include <Standard_Assert.hxx>
#include <TCollection_AsciiString.hxx>
+#include <TCollection_ExtendedString.hxx>
#ifdef _WIN32
#include <malloc.h> // for alloca()
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderObject,OpenGl_Resource)
+//! Puts line numbers to the output of GLSL program source code.
+static TCollection_AsciiString putLineNumbers (const TCollection_AsciiString& theSource)
+{
+ std::stringstream aStream;
+ theSource.Print (aStream);
+ std::string aLine;
+ Standard_Integer aLineNumber = 1;
+ TCollection_AsciiString aResultSource;
+ while (std::getline (aStream, aLine))
+ {
+ TCollection_AsciiString anAsciiString = TCollection_AsciiString (aLine.c_str());
+ anAsciiString.Prepend (TCollection_AsciiString ("\n") + TCollection_AsciiString (aLineNumber) + ": ");
+ aResultSource += anAsciiString;
+ aLineNumber++;
+ }
+ return aResultSource;
+}
+
// =======================================================================
// function : CreateFromSource
// purpose :
Release (NULL);
}
+// =======================================================================
+// function : LoadAndCompile
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderObject::LoadAndCompile (const Handle(OpenGl_Context)& theCtx,
+ const TCollection_AsciiString& theSource,
+ bool theIsVerbose,
+ bool theToPrintSource)
+{
+ if (!theIsVerbose)
+ {
+ return LoadSource (theCtx, theSource)
+ && Compile (theCtx);
+ }
+
+ if (!LoadSource (theCtx, theSource))
+ {
+ if (theToPrintSource)
+ {
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, theSource);
+ }
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Error! Failed to set shader source");
+ Release (theCtx.operator->());
+ return false;
+ }
+
+ if (!Compile (theCtx))
+ {
+ if (theToPrintSource)
+ {
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, putLineNumbers (theSource));
+ }
+ TCollection_AsciiString aLog;
+ FetchInfoLog (theCtx, aLog);
+ if (aLog.IsEmpty())
+ {
+ aLog = "Compilation log is empty.";
+ }
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString ("Failed to compile shader object. Compilation log:\n") + aLog);
+ Release (theCtx.operator->());
+ return false;
+ }
+ else if (theCtx->caps->glslWarnings)
+ {
+ TCollection_AsciiString aLog;
+ FetchInfoLog (theCtx, aLog);
+ if (!aLog.IsEmpty()
+ && !aLog.IsEqual ("No errors.\n"))
+ {
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
+ TCollection_AsciiString ("Shader compilation log:\n") + aLog);
+ }
+ }
+ return true;
+}
+
// =======================================================================
// function : LoadSource
// purpose : Loads shader source code
//! Compiles the shader object.
Standard_EXPORT Standard_Boolean Compile (const Handle(OpenGl_Context)& theCtx);
+ //! Wrapper for compiling shader object with verbose printing on error.
+ //! @param theCtx bound OpenGL context
+ //! @param theSource source code to load
+ //! @param theIsVerbose flag to print log on error
+ //! @param theToPrintSource flag to print source code on error
+ Standard_EXPORT Standard_Boolean LoadAndCompile (const Handle(OpenGl_Context)& theCtx,
+ const TCollection_AsciiString& theSource,
+ bool theIsVerbose = true,
+ bool theToPrintSource = true);
+
//! Fetches information log of the last compile operation.
Standard_EXPORT Standard_Boolean FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
TCollection_AsciiString& theLog);
}
}
-//! Puts line numbers to the output of GLSL program source code.
-static TCollection_AsciiString putLineNumbers (const TCollection_AsciiString& theSource)
-{
- std::stringstream aStream;
- theSource.Print (aStream);
- std::string aLine;
- Standard_Integer aLineNumber = 1;
- TCollection_AsciiString aResultSource;
- while (std::getline (aStream, aLine))
- {
- TCollection_AsciiString anAsciiString = TCollection_AsciiString (aLine.c_str());
- anAsciiString.Prepend (TCollection_AsciiString ("\n") + TCollection_AsciiString (aLineNumber) + ": ");
- aResultSource += anAsciiString;
- aLineNumber++;
- }
- return aResultSource;
-}
-
// =======================================================================
// function : Initialize
// purpose : Initializes program object with the list of shader objects
+ Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs)
+ Shaders_DeclarationsImpl_glsl
+ anIter.Value()->Source(); // the source code itself (defining main() function)
- if (!aShader->LoadSource (theCtx, aSource))
- {
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource);
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Error! Failed to set shader source");
- aShader->Release (theCtx.operator->());
- return Standard_False;
- }
-
- if (!aShader->Compile (theCtx))
+ if (!aShader->LoadAndCompile (theCtx, aSource))
{
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, putLineNumbers (aSource));
- TCollection_AsciiString aLog;
- aShader->FetchInfoLog (theCtx, aLog);
- if (aLog.IsEmpty())
- {
- aLog = "Compilation log is empty.";
- }
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
- TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
- aShader->Release (theCtx.operator->());
return Standard_False;
}
- else if (theCtx->caps->glslWarnings)
- {
- TCollection_AsciiString aLog;
- aShader->FetchInfoLog (theCtx, aLog);
- if (!aLog.IsEmpty()
- && !aLog.IsEqual ("No errors.\n"))
- {
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
- TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
- }
- }
if (theCtx->caps->glslDumpLevel)
{
if (!Link (theCtx))
{
- TCollection_AsciiString aLog;
- FetchInfoLog (theCtx, aLog);
- if (aLog.IsEmpty())
- {
- aLog = "Linker log is empty.";
- }
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
- TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
return Standard_False;
}
- else if (theCtx->caps->glslWarnings)
- {
- TCollection_AsciiString aLog;
- FetchInfoLog (theCtx, aLog);
- if (!aLog.IsEmpty()
- && !aLog.IsEqual ("No errors.\n"))
- {
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
- TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
- }
- }
// set uniform defaults
const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
// function : Link
// purpose : Links the program object
// =======================================================================
-Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
+Standard_Boolean OpenGl_ShaderProgram::link (const Handle(OpenGl_Context)& theCtx)
{
if (myProgramID == NO_PROGRAM)
{
return Standard_True;
}
+// =======================================================================
+// function : Link
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx,
+ bool theIsVerbose)
+{
+ if (!theIsVerbose)
+ {
+ return link (theCtx);
+ }
+
+ if (!link (theCtx))
+ {
+ TCollection_AsciiString aLog;
+ FetchInfoLog (theCtx, aLog);
+ if (aLog.IsEmpty())
+ {
+ aLog = "Linker log is empty.";
+ }
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString ("Failed to link program object! Linker log:\n") + aLog);
+ return false;
+ }
+ else if (theCtx->caps->glslWarnings)
+ {
+ TCollection_AsciiString aLog;
+ FetchInfoLog (theCtx, aLog);
+ if (!aLog.IsEmpty()
+ && !aLog.IsEqual ("No errors.\n"))
+ {
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
+ TCollection_AsciiString ("GLSL linker log:\n") + aLog);
+ }
+ }
+ return true;
+}
+
// =======================================================================
// function : FetchInfoLog
// purpose : Fetches information log of the last link operation
//! List of pre-defined OCCT state uniform variables.
static Standard_CString PredefinedKeywords[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES];
+ //! Wrapper for compiling shader object with verbose printing on error.
+ Standard_EXPORT static bool compileShaderVerbose (const Handle(OpenGl_Context)& theCtx,
+ const Handle(OpenGl_ShaderObject)& theShader,
+ const TCollection_AsciiString& theSource,
+ bool theToPrintSource = true);
+
//! Creates uninitialized shader program.
//!
//! WARNING! This constructor is not intended to be called anywhere but from OpenGl_ShaderManager::Create().
const Graphic3d_ShaderObjectList& theShaders);
//! Links the program object.
- Standard_EXPORT Standard_Boolean Link (const Handle(OpenGl_Context)& theCtx);
+ //! @param theCtx bound OpenGL context
+ //! @param theIsVerbose flag to print log on error
+ Standard_EXPORT Standard_Boolean Link (const Handle(OpenGl_Context)& theCtx,
+ bool theIsVerbose = true);
//! Fetches information log of the last link operation.
Standard_EXPORT Standard_Boolean FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
return --myShareCount == 0;
}
+ //! Links the program object.
+ Standard_EXPORT Standard_Boolean link (const Handle(OpenGl_Context)& theCtx);
+
protected:
GLuint myProgramID; //!< Handle of OpenGL shader program
myPostFSAAShaderSource.SetPrefix (aPrefixString);
myOutImageShaderSource.SetPrefix (aPrefixString);
- if (!myRaytraceShader->LoadSource (theGlContext, myRaytraceShaderSource.Source())
- || !myPostFSAAShader->LoadSource (theGlContext, myPostFSAAShaderSource.Source())
- || !myOutImageShader->LoadSource (theGlContext, myOutImageShaderSource.Source()))
+ if (!myRaytraceShader->LoadAndCompile (theGlContext, myRaytraceShaderSource.Source())
+ || !myPostFSAAShader->LoadAndCompile (theGlContext, myPostFSAAShaderSource.Source())
+ || !myOutImageShader->LoadAndCompile (theGlContext, myOutImageShaderSource.Source()))
{
- return safeFailBack ("Failed to load source into ray-tracing fragment shaders", theGlContext);
- }
-
- TCollection_AsciiString aLog;
-
- if (!myRaytraceShader->Compile (theGlContext)
- || !myPostFSAAShader->Compile (theGlContext)
- || !myOutImageShader->Compile (theGlContext))
- {
-#ifdef RAY_TRACE_PRINT_INFO
- myRaytraceShader->FetchInfoLog (theGlContext, aLog);
-
- if (!aLog.IsEmpty())
- {
- std::cout << "Failed to compile ray-tracing shader: " << aLog << "\n";
- }
-#endif
return safeFailBack ("Failed to compile ray-tracing fragment shaders", theGlContext);
}
|| !myPostFSAAProgram->Link (theGlContext)
|| !myOutImageProgram->Link (theGlContext))
{
-#ifdef RAY_TRACE_PRINT_INFO
- myRaytraceProgram->FetchInfoLog (theGlContext, aLog);
-
- if (!aLog.IsEmpty())
- {
- std::cout << "Failed to compile ray-tracing shader: " << aLog << "\n";
- }
-#endif
return safeFailBack ("Failed to initialize vertex attributes for ray-tracing program", theGlContext);
}
}