#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_ArbTexBindless.hxx>
-IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource)
+#include <OpenGl_GlCore32.hxx>
+
+#include "../Shaders/Shaders_DeclarationsImpl_glsl.pxx"
+#include "../Shaders/Shaders_Declarations_glsl.pxx"
+
+#ifdef _WIN32
+ #include <malloc.h> // for alloca()
+#endif
+
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram,OpenGl_Resource)
OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
"occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
"occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
- "occClipPlaneSpaces", // OpenGl_OCC_CLIP_PLANE_SPACES
"occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
"occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
"occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
"occColor", // OpenGl_OCCT_COLOR
- "occPointSize" // OpenGl_OCCT_POINT_SIZE
+ "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
+ "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
+ "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
+ "occPointSize" // OpenGl_OCCT_POINT_SIZE
};
// =======================================================================
return Standard_False;
}
- OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
- OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
- if (!aDeclFile.Exists()
- || !aDeclImplFile.Exists())
- {
- const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
- 0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
- aMsg);
- return Standard_False;
- }
+ TCollection_AsciiString aHeader = !myProxy.IsNull() && !myProxy->Header().IsEmpty()
+ ? (myProxy->Header() + "\n")
+ : TCollection_AsciiString();
- TCollection_AsciiString aDeclarations;
- aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
- aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
- aDeclFile.Close();
+ TCollection_AsciiString aDeclarations = Shaders_Declarations_glsl;
+ TCollection_AsciiString aDeclImpl = Shaders_DeclarationsImpl_glsl;
- TCollection_AsciiString aDeclImpl;
- aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
- aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
- aDeclImplFile.Close();
aDeclarations += aDeclImpl;
for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
if (!anIter.Value()->IsDone())
{
const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
+ GL_DEBUG_SEVERITY_HIGH,
aMsg);
return Standard_False;
}
if (aShader.IsNull())
{
TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
+ GL_DEBUG_SEVERITY_HIGH,
aMsg);
return Standard_False;
}
}
TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
+ TCollection_AsciiString anExtensions = "// This section enables extensions used in OCCT GLSL programs\n";
+ if (theCtx->hasDrawBuffers)
+ {
+ anExtensions += "#define OCC_ENABLE_draw_buffers\n";
+ }
+ 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";
+ }
+ }
+
+ if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions)
+ {
+#if defined(GL_ES_VERSION_2_0)
+ if (theCtx->oesSampleVariables)
+ {
+ anExtensions += "#extension GL_OES_sample_variables : enable\n";
+ }
+#else
+ if (theCtx->arbSampleShading)
+ {
+ anExtensions += "#extension GL_ARB_sample_shading : enable\n";
+ }
+#endif
+ }
+
switch (anIter.Value()->Type())
{
case Graphic3d_TOS_VERTEX:
{
- aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
+ aSource = aHeader + TCollection_AsciiString ("#define VERTEX_SHADER\n") + anExtensions + aSource;
break;
}
case Graphic3d_TOS_FRAGMENT:
#if defined(GL_ES_VERSION_2_0)
TCollection_AsciiString aPrefix (theCtx->hasHighp
? "precision highp float;\n"
- : "precision mediump float;\n");
- aSource = aPrefix + aSource;
+ "precision highp int;\n"
+ : "precision mediump float;\n"
+ "precision mediump int;\n");
+ aSource = aHeader + aPrefix + anExtensions + aSource;
+ #else
+ aSource = aHeader + anExtensions + aSource;
#endif
break;
}
if (!aShader->LoadSource (theCtx, aSource))
{
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource);
const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
+ GL_DEBUG_SEVERITY_HIGH,
aMsg);
aShader->Release (theCtx.operator->());
return Standard_False;
if (!aShader->Compile (theCtx))
{
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource);
TCollection_AsciiString aLog;
aShader->FetchInfoLog (theCtx, aLog);
if (aLog.IsEmpty())
{
aLog = "Compilation log is empty.";
}
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
+ GL_DEBUG_SEVERITY_HIGH,
TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
aShader->Release (theCtx.operator->());
return Standard_False;
if (!aLog.IsEmpty()
&& !aLog.IsEqual ("No errors.\n"))
{
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_PORTABILITY_ARB,
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_PORTABILITY,
0,
- GL_DEBUG_SEVERITY_LOW_ARB,
+ GL_DEBUG_SEVERITY_LOW,
TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
}
}
SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
+ // bind custom Vertex Attributes
+ if (!myProxy.IsNull())
+ {
+ for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
+ anAttribIter.More(); anAttribIter.Next())
+ {
+ SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
+ }
+ }
+
if (!Link (theCtx))
{
TCollection_AsciiString aLog;
{
aLog = "Linker log is empty.";
}
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
+ GL_DEBUG_SEVERITY_HIGH,
TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
return Standard_False;
}
if (!aLog.IsEmpty()
&& !aLog.IsEqual ("No errors.\n"))
{
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_PORTABILITY_ARB,
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_PORTABILITY,
0,
- GL_DEBUG_SEVERITY_LOW_ARB,
+ GL_DEBUG_SEVERITY_LOW,
TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
}
}
+ // set uniform defaults
+ const GLint aLocSampler = GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER);
+ const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
+ if (aLocSampler != INVALID_LOCATION
+ || aLocTexEnable != INVALID_LOCATION)
+ {
+ const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
+ theCtx->core20fwd->glUseProgram (myProgramID);
+ SetUniform (theCtx, aLocSampler, 0); // GL_TEXTURE0
+ SetUniform (theCtx, aLocTexEnable, 0); // Off
+ theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
+ }
+
return Standard_True;
}
}
myShaderObjects.Append (theShader);
- theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
+ theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
+ theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
return Standard_True;
}
}
GLint aStatus = GL_FALSE;
- theCtx->core20->glLinkProgram (myProgramID);
- theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
+ theCtx->core20fwd->glLinkProgram (myProgramID);
+ theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
if (aStatus == GL_FALSE)
{
return Standard_False;
}
GLint aLength = 0;
- theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
+ theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
if (aLength > 0)
{
GLchar* aLog = (GLchar*) alloca (aLength);
memset (aLog, 0, aLength);
- theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
+ theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
theOutput = aLog;
}
return Standard_True;
return Standard_True;
}
-// =======================================================================
-// function : ActiveState
-// purpose : Returns index of last modification for specified state type
-// =======================================================================
-Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
-{
- if (theType < MaxStateTypes)
- {
- return myCurrentState[theType];
- }
- return 0;
-}
-
-// =======================================================================
-// function : UpdateState
-// purpose : Updates index of last modification for specified state type
-// =======================================================================
-void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
- const Standard_Size theIndex)
-{
- if (theType < MaxStateTypes)
- {
- myCurrentState[theType] = theIndex;
- }
-}
-
// =======================================================================
// function : GetUniformLocation
// purpose : Returns location (index) of the specific uniform variable
const GLchar* theName) const
{
return myProgramID != NO_PROGRAM
- ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
+ ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
: INVALID_LOCATION;
}
const GLchar* theName) const
{
return myProgramID != NO_PROGRAM
- ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
+ ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
: INVALID_LOCATION;
}
return Standard_False;
}
- theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
+ theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
+ theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
+ theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
+ theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
return Standard_True;
}
theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
return Standard_True;
}
-
+
// =======================================================================
// function : SetAttribute
// purpose :
return Standard_False;
}
- theCtx->core20->glUniform1i (theLocation, theValue);
+ theCtx->core20fwd->glUniform1i (theLocation, theValue);
return Standard_True;
}
// =======================================================================
// function : SetUniform
-// purpose : Specifies the value of the 64-bit unsigned uniform variable
+// purpose :
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
const GLchar* theName,
- GLuint64 theValue)
+ const OpenGl_Vec2u& theValue)
{
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
}
// =======================================================================
// function : SetUniform
-// purpose : Specifies the value of the 64-bit unsigned uniform variable
+// purpose :
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
GLint theLocation,
- GLuint64 theValue)
+ const OpenGl_Vec2u& theValue)
{
- if (theCtx->arbTexBindless == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+ if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
{
return Standard_False;
}
#if !defined(GL_ES_VERSION_2_0)
- theCtx->arbTexBindless->glUniformHandleui64ARB (theLocation, theValue);
-#endif
-
+ theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
return Standard_True;
+#else
+ (void )theValue;
+ return Standard_False;
+#endif
}
// =======================================================================
// function : SetUniform
-// purpose : Specifies the value of the 64-bit unsigned uniform array
+// purpose :
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
const GLchar* theName,
const GLsizei theCount,
- const GLuint64* theValue)
+ const OpenGl_Vec2u* theValue)
{
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
}
// =======================================================================
// function : SetUniform
-// purpose : Specifies the value of the 64-bit unsigned uniform array
+// purpose :
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
GLint theLocation,
const GLsizei theCount,
- const GLuint64* theValue)
+ const OpenGl_Vec2u* theValue)
{
- if (theCtx->arbTexBindless == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+ if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
{
return Standard_False;
}
#if !defined(GL_ES_VERSION_2_0)
- theCtx->arbTexBindless->glUniformHandleui64vARB (theLocation, theCount, theValue);
-#endif
-
+ theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
return Standard_True;
+#else
+ (void )theCount;
+ (void )theValue;
+ return Standard_False;
+#endif
}
// =======================================================================
return Standard_False;
}
- theCtx->core20->glUniform1f (theLocation, theValue);
+ theCtx->core20fwd->glUniform1f (theLocation, theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform2iv (theLocation, 1, theValue);
+ theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform3iv (theLocation, 1, theValue);
+ theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform4iv (theLocation, 1, theValue);
+ theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform2fv (theLocation, 1, theValue);
+ theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform3fv (theLocation, 1, theValue);
+ theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform4fv (theLocation, 1, theValue);
+ theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
+ theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform1fv (theLocation, theCount, theData);
+ theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform2fv (theLocation, theCount, theData[0].GetData());
+ theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform3fv (theLocation, theCount, theData[0].GetData());
+ theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform4fv (theLocation, theCount, theData[0].GetData());
+ theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform1iv (theLocation, theCount, theData);
+ theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform2iv (theLocation, theCount, theData[0].GetData());
+ theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform3iv (theLocation, theCount, theData[0].GetData());
+ theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform4iv (theLocation, theCount, theData[0].GetData());
+ theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
return Standard_True;
}
return Standard_False;
}
- theCtx->core20->glUniform1i (theLocation, theTextureUnit);
+ theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
return Standard_True;
}
Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
{
if (myProgramID == NO_PROGRAM
- && theCtx->core20 != NULL)
+ && theCtx->core20fwd != NULL)
{
- myProgramID = theCtx->core20->glCreateProgram();
+ myProgramID = theCtx->core20fwd->glCreateProgram();
}
return myProgramID != NO_PROGRAM;
}
}
- if (theCtx->core20 != NULL
+ if (theCtx->core20fwd != NULL
&& theCtx->IsValid())
{
- theCtx->core20->glDeleteProgram (myProgramID);
+ theCtx->core20fwd->glDeleteProgram (myProgramID);
}
myProgramID = NO_PROGRAM;