mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
New interior style Aspect_IS_OUTLINE is supported for Graphic3d_AspectFillArea3d. If this style is set, the triangles primitive array is drawn using the outline shader A new flag theMostAllowedEdgeClass is passed to the methods StdPrs_ShadedShape: Add, FillFaceBoundaries. It defines the most allowed continuity class of edges that will be included into the presentation. The edges with more continuity will be ignored. By default, the value is CN, i.e. all edges are included into the presentation. The new methods in AIS_Shape: SetMostContinuityClass, MostContinuityClass allows specifying the most allowed continuity class of edges at the level of shape's presentation
1470 lines
61 KiB
C++
Executable File
1470 lines
61 KiB
C++
Executable File
// Created on: 2013-09-19
|
|
// Created by: Denis BOGOLEPOV
|
|
// Copyright (c) 2013-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <OSD_File.hxx>
|
|
#include <OSD_Protection.hxx>
|
|
|
|
#include <Graphic3d_Buffer.hxx>
|
|
#include <Standard_Assert.hxx>
|
|
#include <Standard_Atomic.hxx>
|
|
#include <TCollection_ExtendedString.hxx>
|
|
|
|
#include <OpenGl_Context.hxx>
|
|
#include <OpenGl_ShaderProgram.hxx>
|
|
#include <OpenGl_ShaderManager.hxx>
|
|
#include <OpenGl_ArbTexBindless.hxx>
|
|
|
|
#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_NamedResource)
|
|
|
|
OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
|
|
|
|
// Declare OCCT-specific OpenGL/GLSL shader variables
|
|
Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
|
|
{
|
|
"occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
|
|
"occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
|
|
"occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
|
|
"occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
|
|
"occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
|
|
"occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
|
|
"occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
|
|
"occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
|
|
"occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
|
|
"occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
|
|
"occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
|
|
"occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
|
|
|
|
"occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
|
|
"occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
|
|
|
|
"occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
|
|
"occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
|
|
"occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
|
|
"occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
|
|
|
|
"occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
|
|
"occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
|
|
"occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
|
|
"occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
|
|
"occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF
|
|
"occColor", // OpenGl_OCCT_COLOR
|
|
|
|
"occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
|
|
"occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
|
|
|
|
"occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
|
|
"occPointSize", // OpenGl_OCCT_POINT_SIZE
|
|
|
|
"occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE
|
|
"occIsSilhouettePass", // OpenGl_OCCT_IS_SILHOUETTE_PASS
|
|
"occBackgroundColor", // OpenGl_OCCT_BACKGROUND_COLOR
|
|
"occSilhouetteColor", // OpenGl_OCCT_SILHOUETTE_COLOR
|
|
"occSilhouetteThickness" // OpenGl_OCCT_SILHOUETTE_THICKNESS
|
|
};
|
|
|
|
namespace
|
|
{
|
|
//! Convert Graphic3d_TypeOfShaderObject enumeration into OpenGL enumeration.
|
|
static GLenum shaderTypeToGl (Graphic3d_TypeOfShaderObject theType)
|
|
{
|
|
switch (theType)
|
|
{
|
|
case Graphic3d_TOS_VERTEX: return GL_VERTEX_SHADER;
|
|
case Graphic3d_TOS_FRAGMENT: return GL_FRAGMENT_SHADER;
|
|
case Graphic3d_TOS_GEOMETRY: return GL_GEOMETRY_SHADER;
|
|
case Graphic3d_TOS_TESS_CONTROL: return GL_TESS_CONTROL_SHADER;
|
|
case Graphic3d_TOS_TESS_EVALUATION: return GL_TESS_EVALUATION_SHADER;
|
|
case Graphic3d_TOS_COMPUTE: return GL_COMPUTE_SHADER;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : OpenGl_VariableSetterSelector
|
|
// purpose : Creates new variable setter selector
|
|
// =======================================================================
|
|
OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
|
|
{
|
|
// Note: Add new variable setters here
|
|
mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
|
|
(Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
|
|
(Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
|
|
(Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
|
|
(Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
|
|
(Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
|
|
(Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
|
|
(Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
|
|
(Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : ~OpenGl_VariableSetterSelector
|
|
// purpose : Releases memory resources of variable setter selector
|
|
// =======================================================================
|
|
OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
|
|
{
|
|
for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
|
|
{
|
|
delete anIt.Value();
|
|
}
|
|
|
|
mySetterList.Clear();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Set
|
|
// purpose : Sets generic variable to specified shader program
|
|
// =======================================================================
|
|
void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
|
|
const Handle(Graphic3d_ShaderVariable)& theVariable,
|
|
OpenGl_ShaderProgram* theProgram) const
|
|
{
|
|
Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
|
|
"The type of user-defined uniform variable is not supported...", );
|
|
|
|
mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : OpenGl_ShaderProgram
|
|
// purpose : Creates uninitialized shader program
|
|
// =======================================================================
|
|
OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
|
|
: OpenGl_NamedResource (!theProxy.IsNull() ? theProxy->GetId() : ""),
|
|
myProgramID (NO_PROGRAM),
|
|
myProxy (theProxy),
|
|
myShareCount(1),
|
|
myNbLightsMax (0),
|
|
myNbClipPlanesMax (0),
|
|
myNbFragOutputs (1),
|
|
myHasAlphaTest (false),
|
|
myHasWeightOitOutput (false),
|
|
myHasTessShader (false)
|
|
{
|
|
memset (myCurrentState, 0, sizeof (myCurrentState));
|
|
for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
|
|
{
|
|
myStateLocations[aVar] = INVALID_LOCATION;
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Initialize
|
|
// purpose : Initializes program object with the list of shader objects
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
|
|
const Graphic3d_ShaderObjectList& theShaders)
|
|
{
|
|
myHasTessShader = false;
|
|
if (theCtx.IsNull() || !Create (theCtx))
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString();
|
|
int aShaderMask = 0;
|
|
for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
|
|
{
|
|
aShaderMask |= anIter.Value()->Type();
|
|
}
|
|
myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
|
|
myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
|
|
myHasAlphaTest = !myProxy.IsNull() && myProxy->HasAlphaTest();
|
|
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)
|
|
if (myHasTessShader
|
|
|| (aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
|
|
{
|
|
if (!theCtx->IsGlGreaterEqual (3, 2))
|
|
{
|
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
|
"Error! Geometry and Tessellation shaders require OpenGL ES 3.2+");
|
|
return false;
|
|
}
|
|
else if (aHeaderVer.IsEmpty())
|
|
{
|
|
aHeaderVer = "#version 320 es";
|
|
}
|
|
}
|
|
else if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
|
|
{
|
|
if (!theCtx->IsGlGreaterEqual (3, 1))
|
|
{
|
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
|
"Error! Compute shaders require OpenGL ES 3.1+");
|
|
return false;
|
|
}
|
|
else if (aHeaderVer.IsEmpty())
|
|
{
|
|
aHeaderVer = "#version 310 es";
|
|
}
|
|
}
|
|
#else
|
|
if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
|
|
{
|
|
if (!theCtx->IsGlGreaterEqual (4, 3))
|
|
{
|
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
|
"Error! Compute shaders require OpenGL 4.3+");
|
|
return 0;
|
|
}
|
|
else if (aHeaderVer.IsEmpty())
|
|
{
|
|
aHeaderVer = "#version 430";
|
|
}
|
|
}
|
|
else if (myHasTessShader)
|
|
{
|
|
if (!theCtx->IsGlGreaterEqual (4, 0))
|
|
{
|
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
|
"Error! Tessellation shaders require OpenGL 4.0+");
|
|
return 0;
|
|
}
|
|
else if (aHeaderVer.IsEmpty())
|
|
{
|
|
aHeaderVer = "#version 400";
|
|
}
|
|
}
|
|
else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
|
|
{
|
|
if (!theCtx->IsGlGreaterEqual (3, 2))
|
|
{
|
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
|
"Error! Geometry shaders require OpenGL 3.2+");
|
|
return 0;
|
|
}
|
|
else if (aHeaderVer.IsEmpty())
|
|
{
|
|
aHeaderVer = "#version 150";
|
|
}
|
|
}
|
|
#endif
|
|
|
|
for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
|
|
{
|
|
if (!anIter.Value()->IsDone())
|
|
{
|
|
const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
|
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
|
|
return Standard_False;
|
|
}
|
|
|
|
const GLenum aShaderType = shaderTypeToGl (anIter.Value()->Type());
|
|
if (aShaderType == 0)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (aShaderType);
|
|
if (!aShader->Create (theCtx))
|
|
{
|
|
aShader->Release (theCtx.operator->());
|
|
return Standard_False;
|
|
}
|
|
|
|
TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
|
|
if (myNbFragOutputs > 1)
|
|
{
|
|
if (theCtx->hasDrawBuffers)
|
|
{
|
|
anExtensions += "#define OCC_ENABLE_draw_buffers\n";
|
|
if (myHasWeightOitOutput)
|
|
{
|
|
anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n";
|
|
}
|
|
}
|
|
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)
|
|
{
|
|
if (theCtx->arbDrawBuffers)
|
|
{
|
|
anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
|
|
}
|
|
else if (theCtx->extDrawBuffers)
|
|
{
|
|
anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
|
|
}
|
|
}
|
|
}
|
|
if (myHasAlphaTest)
|
|
{
|
|
anExtensions += "#define OCC_ALPHA_TEST\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
|
|
}
|
|
|
|
TCollection_AsciiString aPrecisionHeader;
|
|
if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT)
|
|
{
|
|
#if defined(GL_ES_VERSION_2_0)
|
|
aPrecisionHeader = theCtx->hasHighp
|
|
? "precision highp float;\n"
|
|
"precision highp int;\n"
|
|
: "precision mediump float;\n"
|
|
"precision mediump int;\n";
|
|
#endif
|
|
}
|
|
|
|
TCollection_AsciiString aHeaderType;
|
|
switch (anIter.Value()->Type())
|
|
{
|
|
case Graphic3d_TOS_COMPUTE: { aHeaderType = "#define COMPUTE_SHADER\n"; break; }
|
|
case Graphic3d_TOS_VERTEX: { aHeaderType = "#define VERTEX_SHADER\n"; break; }
|
|
case Graphic3d_TOS_TESS_CONTROL: { aHeaderType = "#define TESS_CONTROL_SHADER\n"; break; }
|
|
case Graphic3d_TOS_TESS_EVALUATION: { aHeaderType = "#define TESS_EVALUATION_SHADER\n"; break; }
|
|
case Graphic3d_TOS_GEOMETRY: { aHeaderType = "#define GEOMETRY_SHADER\n"; break; }
|
|
case Graphic3d_TOS_FRAGMENT: { aHeaderType = "#define FRAGMENT_SHADER\n"; break; }
|
|
}
|
|
|
|
TCollection_AsciiString aHeaderConstants;
|
|
myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
|
|
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" : "")
|
|
+ anExtensions // #extension - list of enabled extensions, should be second
|
|
+ aPrecisionHeader // precision - default precision qualifiers, should be before any code
|
|
+ aHeaderType // auxiliary macros defining a shader stage (type)
|
|
+ aHeaderConstants
|
|
+ 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))
|
|
{
|
|
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, 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 (!AttachShader (theCtx, aShader))
|
|
{
|
|
aShader->Release (theCtx.operator->());
|
|
return Standard_False;
|
|
}
|
|
}
|
|
|
|
// bind locations for pre-defined Vertex Attributes
|
|
SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
|
|
SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
|
|
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;
|
|
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();
|
|
theCtx->core20fwd->glUseProgram (myProgramID);
|
|
{
|
|
const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
|
|
if (aLocTexEnable != INVALID_LOCATION)
|
|
{
|
|
SetUniform (theCtx, aLocTexEnable, 0); // Off
|
|
}
|
|
}
|
|
{
|
|
const GLint aLocSampler = GetUniformLocation (theCtx, "occActiveSampler");
|
|
if (aLocSampler != INVALID_LOCATION)
|
|
{
|
|
SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0));
|
|
}
|
|
}
|
|
|
|
const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
|
|
const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
|
|
for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter)
|
|
{
|
|
const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter;
|
|
const GLint aLocSampler = GetUniformLocation (theCtx, aName.ToCString());
|
|
if (aLocSampler != INVALID_LOCATION)
|
|
{
|
|
SetUniform (theCtx, aLocSampler, aUnitIter);
|
|
}
|
|
}
|
|
|
|
theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : ~OpenGl_ShaderProgram
|
|
// purpose : Releases resources of shader program
|
|
// =======================================================================
|
|
OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
|
|
{
|
|
Release (NULL);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : AttachShader
|
|
// purpose : Attaches shader object to the program object
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
|
|
const Handle(OpenGl_ShaderObject)& theShader)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theShader.IsNull())
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
|
|
{
|
|
if (theShader == anIter.Value())
|
|
{
|
|
return Standard_False;
|
|
}
|
|
}
|
|
|
|
myShaderObjects.Append (theShader);
|
|
theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DetachShader
|
|
// purpose : Detaches shader object to the program object
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
|
|
const Handle(OpenGl_ShaderObject)& theShader)
|
|
{
|
|
if (myProgramID == NO_PROGRAM
|
|
|| theShader.IsNull())
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
OpenGl_ShaderList::Iterator anIter (myShaderObjects);
|
|
while (anIter.More())
|
|
{
|
|
if (theShader == anIter.Value())
|
|
{
|
|
myShaderObjects.Remove (anIter);
|
|
break;
|
|
}
|
|
|
|
anIter.Next();
|
|
}
|
|
|
|
if (!anIter.More())
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Link
|
|
// purpose : Links the program object
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
|
|
{
|
|
if (myProgramID == NO_PROGRAM)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
GLint aStatus = GL_FALSE;
|
|
theCtx->core20fwd->glLinkProgram (myProgramID);
|
|
theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
|
|
if (aStatus == GL_FALSE)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
|
|
{
|
|
myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : FetchInfoLog
|
|
// purpose : Fetches information log of the last link operation
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
|
|
TCollection_AsciiString& theOutput)
|
|
{
|
|
if (myProgramID == NO_PROGRAM)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
GLint aLength = 0;
|
|
theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
|
|
if (aLength > 0)
|
|
{
|
|
GLchar* aLog = (GLchar*) alloca (aLength);
|
|
memset (aLog, 0, aLength);
|
|
theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
|
|
theOutput = aLog;
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : ApplyVariables
|
|
// purpose : Fetches uniform variables from proxy shader program
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
|
|
{
|
|
if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
|
|
{
|
|
mySetterSelector.Set (theCtx, anIter.Value(), this);
|
|
}
|
|
|
|
myProxy->ClearVariables();
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetUniformLocation
|
|
// purpose : Returns location (index) of the specific uniform variable
|
|
// =======================================================================
|
|
GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName) const
|
|
{
|
|
return myProgramID != NO_PROGRAM
|
|
? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
|
|
: INVALID_LOCATION;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetAttributeLocation
|
|
// purpose : Returns location (index) of the generic vertex attribute
|
|
// =======================================================================
|
|
GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName) const
|
|
{
|
|
return myProgramID != NO_PROGRAM
|
|
? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
|
|
: INVALID_LOCATION;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetStateLocation
|
|
// purpose : Returns location of the OCCT state uniform variable
|
|
// =======================================================================
|
|
GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
|
|
{
|
|
if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
|
|
{
|
|
return myStateLocations[theVariable];
|
|
}
|
|
return INVALID_LOCATION;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetUniform
|
|
// purpose : Returns the value of the integer uniform variable
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
OpenGl_Vec4i& theValue) const
|
|
{
|
|
return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetUniform
|
|
// purpose : Returns the value of the integer uniform variable
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
OpenGl_Vec4i& theValue) const
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetUniform
|
|
// purpose : Returns the value of the floating-point uniform variable
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
OpenGl_Vec4& theValue) const
|
|
{
|
|
return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetUniform
|
|
// purpose : Returns the value of the floating-point uniform variable
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
OpenGl_Vec4& theValue) const
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetAttribute
|
|
// purpose : Returns the integer vertex attribute
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
OpenGl_Vec4i& theValue) const
|
|
{
|
|
return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetAttribute
|
|
// purpose : Returns the integer vertex attribute
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theIndex,
|
|
OpenGl_Vec4i& theValue) const
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetAttribute
|
|
// purpose : Returns the floating-point vertex attribute
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
OpenGl_Vec4& theValue) const
|
|
{
|
|
return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GetAttribute
|
|
// purpose : Returns the floating-point vertex attribute
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theIndex,
|
|
OpenGl_Vec4& theValue) const
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetAttributeName
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theIndex,
|
|
const GLchar* theName)
|
|
{
|
|
theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetAttribute
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
GLfloat theValue)
|
|
{
|
|
return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetAttribute
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theIndex,
|
|
GLfloat theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetAttribute
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Vec2& theValue)
|
|
{
|
|
return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetAttribute
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theIndex,
|
|
const OpenGl_Vec2& theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetAttribute
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Vec3& theValue)
|
|
{
|
|
return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetAttribute
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theIndex,
|
|
const OpenGl_Vec3& theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetAttribute
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Vec4& theValue)
|
|
{
|
|
return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetAttribute
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theIndex,
|
|
const OpenGl_Vec4& theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the integer uniform variable
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
GLint theValue)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the integer uniform variable
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
GLint theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform1i (theLocation, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Vec2u& theValue)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const OpenGl_Vec2u& theValue)
|
|
{
|
|
if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
#if !defined(GL_ES_VERSION_2_0)
|
|
theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
|
|
return Standard_True;
|
|
#else
|
|
(void )theValue;
|
|
return Standard_False;
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const GLsizei theCount,
|
|
const OpenGl_Vec2u* theValue)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const GLsizei theCount,
|
|
const OpenGl_Vec2u* theValue)
|
|
{
|
|
if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
#if !defined(GL_ES_VERSION_2_0)
|
|
theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
|
|
return Standard_True;
|
|
#else
|
|
(void )theCount;
|
|
(void )theValue;
|
|
return Standard_False;
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform variable
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
GLfloat theValue)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform variable
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
GLfloat theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform1f (theLocation, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the integer uniform 2D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Vec2i& theValue)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the integer uniform 2D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const OpenGl_Vec2i& theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the integer uniform 3D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Vec3i& theValue)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the integer uniform 3D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const OpenGl_Vec3i& theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the integer uniform 4D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Vec4i& theValue)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the integer uniform 4D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const OpenGl_Vec4i& theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform 2D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Vec2& theValue)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform 2D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const OpenGl_Vec2& theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform 3D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Vec3& theValue)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform 3D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const OpenGl_Vec3& theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform 4D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Vec4& theValue)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform 4D vector
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const OpenGl_Vec4& theValue)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform 4x4 matrix
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Mat4& theValue,
|
|
GLboolean theTranspose)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform 4x4 matrix
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const OpenGl_Mat4& theValue,
|
|
GLboolean theTranspose)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform 4x4 matrix
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const OpenGl_Matrix& theValue,
|
|
GLboolean theTranspose)
|
|
{
|
|
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the floating-point uniform 4x4 matrix
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const OpenGl_Matrix& theValue,
|
|
GLboolean theTranspose)
|
|
{
|
|
return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the float uniform array
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
GLuint theCount,
|
|
const Standard_ShortReal* theData)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the float2 uniform array
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
GLuint theCount,
|
|
const OpenGl_Vec2* theData)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the float3 uniform array
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
GLuint theCount,
|
|
const OpenGl_Vec3* theData)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the float4 uniform array
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
GLuint theCount,
|
|
const OpenGl_Vec4* theData)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the integer uniform array
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
GLuint theCount,
|
|
const Standard_Integer* theData)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the int2 uniform array
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
GLuint theCount,
|
|
const OpenGl_Vec2i* theData)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the int3 uniform array
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
GLuint theCount,
|
|
const OpenGl_Vec3i* theData)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetUniform
|
|
// purpose : Specifies the value of the int4 uniform array
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
GLuint theCount,
|
|
const OpenGl_Vec4i* theData)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetSampler
|
|
// purpose : Specifies the value of the sampler uniform variable
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
|
|
const GLchar* theName,
|
|
const Graphic3d_TextureUnit theTextureUnit)
|
|
{
|
|
return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetSampler
|
|
// purpose : Specifies the value of the sampler uniform variable
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
|
|
GLint theLocation,
|
|
const Graphic3d_TextureUnit theTextureUnit)
|
|
{
|
|
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Create
|
|
// purpose : Creates new empty shader program of specified type
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
|
|
{
|
|
if (myProgramID == NO_PROGRAM
|
|
&& theCtx->core20fwd != NULL)
|
|
{
|
|
myProgramID = theCtx->core20fwd->glCreateProgram();
|
|
}
|
|
|
|
return myProgramID != NO_PROGRAM;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Release
|
|
// purpose : Destroys shader program
|
|
// =======================================================================
|
|
void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
|
|
{
|
|
if (myProgramID == NO_PROGRAM)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Standard_ASSERT_RETURN (theCtx != NULL,
|
|
"OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
|
|
|
|
for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
|
|
{
|
|
if (!anIter.Value().IsNull())
|
|
{
|
|
anIter.ChangeValue()->Release (theCtx);
|
|
anIter.ChangeValue().Nullify();
|
|
}
|
|
}
|
|
|
|
if (theCtx->core20fwd != NULL
|
|
&& theCtx->IsValid())
|
|
{
|
|
theCtx->core20fwd->glDeleteProgram (myProgramID);
|
|
}
|
|
|
|
myProgramID = NO_PROGRAM;
|
|
}
|