// Created on: 2013-09-19
// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013 OPEN CASCADE SAS
+// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// 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.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// 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>
-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_NamedResource)
OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
// Declare OCCT-specific OpenGL/GLSL shader variables
Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
{
- /* OpenGl_OCC_MODEL_WORLD_MATRIX */ "occModelWorldMatrix",
- /* OpenGl_OCC_WORLD_VIEW_MATRIX */ "occWorldViewMatrix",
- /* OpenGl_OCC_PROJECTION_MATRIX */ "occProjectionMatrix",
- /* OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE */ "occModelWorldMatrixInverse",
- /* OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE */ "occWorldViewMatrixInverse",
- /* OpenGl_OCC_PROJECTION_MATRIX_INVERSE */ "occProjectionMatrixInverse",
- /* OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE */ "occModelWorldMatrixTranspose",
- /* OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE */ "occWorldViewMatrixTranspose",
- /* OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE */ "occProjectionMatrixTranspose",
- /* OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE */ "occModelWorldMatrixInverseTranspose",
- /* OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE */ "occWorldViewMatrixInverseTranspose",
- /* OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE */ "occProjectionMatrixInverseTranspose",
-
- /* OpenGl_OCC_CLIP_PLANE_0_EQUATION */ "occClipPlanes[0].Equation",
- /* OpenGl_OCC_CLIP_PLANE_1_EQUATION */ "occClipPlanes[1].Equation",
- /* OpenGl_OCC_CLIP_PLANE_2_EQUATION */ "occClipPlanes[2].Equation",
- /* OpenGl_OCC_CLIP_PLANE_3_EQUATION */ "occClipPlanes[3].Equation",
- /* OpenGl_OCC_CLIP_PLANE_4_EQUATION */ "occClipPlanes[4].Equation",
- /* OpenGl_OCC_CLIP_PLANE_5_EQUATION */ "occClipPlanes[5].Equation",
- /* OpenGl_OCC_CLIP_PLANE_6_EQUATION */ "occClipPlanes[6].Equation",
- /* OpenGl_OCC_CLIP_PLANE_7_EQUATION */ "occClipPlanes[7].Equation",
-
- /* OpenGl_OCC_CLIP_PLANE_0_SPACE */ "occClipPlanes[0].Space",
- /* OpenGl_OCC_CLIP_PLANE_1_SPACE */ "occClipPlanes[1].Space",
- /* OpenGl_OCC_CLIP_PLANE_2_SPACE */ "occClipPlanes[2].Space",
- /* OpenGl_OCC_CLIP_PLANE_3_SPACE */ "occClipPlanes[3].Space",
- /* OpenGl_OCC_CLIP_PLANE_4_SPACE */ "occClipPlanes[4].Space",
- /* OpenGl_OCC_CLIP_PLANE_5_SPACE */ "occClipPlanes[5].Space",
- /* OpenGl_OCC_CLIP_PLANE_6_SPACE */ "occClipPlanes[6].Space",
- /* OpenGl_OCC_CLIP_PLANE_7_SPACE */ "occClipPlanes[7].Space",
-
- /* OpenGl_OCC_LIGHT_SOURCE_COUNT */ "occLightSourcesCount",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_TYPE */ "occLightSources[0].Type",
- /* OpenGl_OCC_LIGHT_SOURCE_1_TYPE */ "occLightSources[1].Type",
- /* OpenGl_OCC_LIGHT_SOURCE_2_TYPE */ "occLightSources[2].Type",
- /* OpenGl_OCC_LIGHT_SOURCE_3_TYPE */ "occLightSources[3].Type",
- /* OpenGl_OCC_LIGHT_SOURCE_4_TYPE */ "occLightSources[4].Type",
- /* OpenGl_OCC_LIGHT_SOURCE_5_TYPE */ "occLightSources[5].Type",
- /* OpenGl_OCC_LIGHT_SOURCE_6_TYPE */ "occLightSources[6].Type",
- /* OpenGl_OCC_LIGHT_SOURCE_7_TYPE */ "occLightSources[7].Type",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_HEAD */ "occLightSources[0].Head",
- /* OpenGl_OCC_LIGHT_SOURCE_1_HEAD */ "occLightSources[1].Head",
- /* OpenGl_OCC_LIGHT_SOURCE_2_HEAD */ "occLightSources[2].Head",
- /* OpenGl_OCC_LIGHT_SOURCE_3_HEAD */ "occLightSources[3].Head",
- /* OpenGl_OCC_LIGHT_SOURCE_4_HEAD */ "occLightSources[4].Head",
- /* OpenGl_OCC_LIGHT_SOURCE_5_HEAD */ "occLightSources[5].Head",
- /* OpenGl_OCC_LIGHT_SOURCE_6_HEAD */ "occLightSources[6].Head",
- /* OpenGl_OCC_LIGHT_SOURCE_7_HEAD */ "occLightSources[7].Head",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT */ "occLightSources[0].Ambient",
- /* OpenGl_OCC_LIGHT_SOURCE_1_AMBIENT */ "occLightSources[1].Ambient",
- /* OpenGl_OCC_LIGHT_SOURCE_2_AMBIENT */ "occLightSources[2].Ambient",
- /* OpenGl_OCC_LIGHT_SOURCE_3_AMBIENT */ "occLightSources[3].Ambient",
- /* OpenGl_OCC_LIGHT_SOURCE_4_AMBIENT */ "occLightSources[4].Ambient",
- /* OpenGl_OCC_LIGHT_SOURCE_5_AMBIENT */ "occLightSources[5].Ambient",
- /* OpenGl_OCC_LIGHT_SOURCE_6_AMBIENT */ "occLightSources[6].Ambient",
- /* OpenGl_OCC_LIGHT_SOURCE_7_AMBIENT */ "occLightSources[7].Ambient",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE */ "occLightSources[0].Diffuse",
- /* OpenGl_OCC_LIGHT_SOURCE_1_DIFFUSE */ "occLightSources[1].Diffuse",
- /* OpenGl_OCC_LIGHT_SOURCE_2_DIFFUSE */ "occLightSources[2].Diffuse",
- /* OpenGl_OCC_LIGHT_SOURCE_3_DIFFUSE */ "occLightSources[3].Diffuse",
- /* OpenGl_OCC_LIGHT_SOURCE_4_DIFFUSE */ "occLightSources[4].Diffuse",
- /* OpenGl_OCC_LIGHT_SOURCE_5_DIFFUSE */ "occLightSources[5].Diffuse",
- /* OpenGl_OCC_LIGHT_SOURCE_6_DIFFUSE */ "occLightSources[6].Diffuse",
- /* OpenGl_OCC_LIGHT_SOURCE_7_DIFFUSE */ "occLightSources[7].Diffuse",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR */ "occLightSources[0].Specular",
- /* OpenGl_OCC_LIGHT_SOURCE_1_SPECULAR */ "occLightSources[1].Specular",
- /* OpenGl_OCC_LIGHT_SOURCE_2_SPECULAR */ "occLightSources[2].Specular",
- /* OpenGl_OCC_LIGHT_SOURCE_3_SPECULAR */ "occLightSources[3].Specular",
- /* OpenGl_OCC_LIGHT_SOURCE_4_SPECULAR */ "occLightSources[4].Specular",
- /* OpenGl_OCC_LIGHT_SOURCE_5_SPECULAR */ "occLightSources[5].Specular",
- /* OpenGl_OCC_LIGHT_SOURCE_6_SPECULAR */ "occLightSources[6].Specular",
- /* OpenGl_OCC_LIGHT_SOURCE_7_SPECULAR */ "occLightSources[7].Specular",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_POSITION */ "occLightSources[0].Position",
- /* OpenGl_OCC_LIGHT_SOURCE_1_POSITION */ "occLightSources[1].Position",
- /* OpenGl_OCC_LIGHT_SOURCE_2_POSITION */ "occLightSources[2].Position",
- /* OpenGl_OCC_LIGHT_SOURCE_3_POSITION */ "occLightSources[3].Position",
- /* OpenGl_OCC_LIGHT_SOURCE_4_POSITION */ "occLightSources[4].Position",
- /* OpenGl_OCC_LIGHT_SOURCE_5_POSITION */ "occLightSources[5].Position",
- /* OpenGl_OCC_LIGHT_SOURCE_6_POSITION */ "occLightSources[6].Position",
- /* OpenGl_OCC_LIGHT_SOURCE_7_POSITION */ "occLightSources[7].Position",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF */ "occLightSources[0].SpotCutoff",
- /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_CUTOFF */ "occLightSources[1].SpotCutoff",
- /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_CUTOFF */ "occLightSources[2].SpotCutoff",
- /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_CUTOFF */ "occLightSources[3].SpotCutoff",
- /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_CUTOFF */ "occLightSources[4].SpotCutoff",
- /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_CUTOFF */ "occLightSources[5].SpotCutoff",
- /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_CUTOFF */ "occLightSources[6].SpotCutoff",
- /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_CUTOFF */ "occLightSources[7].SpotCutoff",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT */ "occLightSources[0].SpotExponent",
- /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_EXPONENT */ "occLightSources[1].SpotExponent",
- /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_EXPONENT */ "occLightSources[2].SpotExponent",
- /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_EXPONENT */ "occLightSources[3].SpotExponent",
- /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_EXPONENT */ "occLightSources[4].SpotExponent",
- /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_EXPONENT */ "occLightSources[5].SpotExponent",
- /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_EXPONENT */ "occLightSources[6].SpotExponent",
- /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_EXPONENT */ "occLightSources[7].SpotExponent",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION */ "occLightSources[0].SpotDirection",
- /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_DIRECTION */ "occLightSources[1].SpotDirection",
- /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_DIRECTION */ "occLightSources[2].SpotDirection",
- /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_DIRECTION */ "occLightSources[3].SpotDirection",
- /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_DIRECTION */ "occLightSources[4].SpotDirection",
- /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_DIRECTION */ "occLightSources[5].SpotDirection",
- /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_DIRECTION */ "occLightSources[6].SpotDirection",
- /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_DIRECTION */ "occLightSources[7].SpotDirection",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION */ "occLightSources[0].ConstAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_1_CONST_ATTENUATION */ "occLightSources[1].ConstAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_2_CONST_ATTENUATION */ "occLightSources[2].ConstAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_3_CONST_ATTENUATION */ "occLightSources[3].ConstAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_4_CONST_ATTENUATION */ "occLightSources[4].ConstAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_5_CONST_ATTENUATION */ "occLightSources[5].ConstAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_6_CONST_ATTENUATION */ "occLightSources[6].ConstAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_7_CONST_ATTENUATION */ "occLightSources[7].ConstAttenuation",
-
- /* OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION */ "occLightSources[0].LinearAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_1_LINEAR_ATTENUATION */ "occLightSources[1].LinearAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_2_LINEAR_ATTENUATION */ "occLightSources[2].LinearAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_3_LINEAR_ATTENUATION */ "occLightSources[3].LinearAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_4_LINEAR_ATTENUATION */ "occLightSources[4].LinearAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_5_LINEAR_ATTENUATION */ "occLightSources[5].LinearAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_6_LINEAR_ATTENUATION */ "occLightSources[6].LinearAttenuation",
- /* OpenGl_OCC_LIGHT_SOURCE_7_LINEAR_ATTENUATION */ "occLightSources[7].LinearAttenuation",
-
- /* OpenGl_OCCT_ACTIVE_SAMPLER */ "occActiveSampler",
- /* OpenGl_OCCT_TEXTURE_ENABLE */ "occTextureEnable",
- /* OpenGl_OCCT_DISTINGUISH_MODE */ "occDistinguishingMode",
- /* OpenGl_OCCT_FRONT_MATERIAL_AMBIENT */ "occFrontMaterial.Ambient",
- /* OpenGl_OCCT_BACK_MATERIAL_AMBIENT */ "occBackMaterial.Ambient",
- /* OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE */ "occFrontMaterial.Diffuse",
- /* OpenGl_OCCT_BACK_MATERIAL_DIFFUSE */ "occBackMaterial.Diffuse",
- /* OpenGl_OCCT_FRONT_MATERIAL_SPECULAR */ "occFrontMaterial.Specular",
- /* OpenGl_OCCT_BACK_MATERIAL_SPECULAR */ "occBackMaterial.Specular",
- /* OpenGl_OCCT_FRONT_MATERIAL_EMISSION */ "occFrontMaterial.Emission",
- /* OpenGl_OCCT_BACK_MATERIAL_EMISSION */ "occBackMaterial.Emission",
- /* OpenGl_OCCT_FRONT_MATERIAL_SHININESS */ "occFrontMaterial.Shininess",
- /* OpenGl_OCCT_BACK_MATERIAL_SHININESS */ "occBackMaterial.Shininess",
- /* OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY */ "occFrontMaterial.Transparency",
- /* OpenGl_OCCT_BACK_MATERIAL_TRANSPARENCY */ "occBackMaterial.Transparency"
-
+ "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
+ "occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS
+ "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
};
+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
// purpose : Creates uninitialized shader program
// =======================================================================
OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
-: myProgramID (NO_PROGRAM),
- myProxy (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)
Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
const Graphic3d_ShaderObjectList& theShaders)
{
+ myHasTessShader = false;
if (theCtx.IsNull() || !Create (theCtx))
{
return Standard_False;
}
- GLchar *aShaderDir = getenv ("CSF_ShadersDirectory");
- if (aShaderDir == NULL)
+ TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString();
+ int aShaderMask = 0;
+ for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
{
- TCollection_ExtendedString aMsg = "Error! Failed to get OCCT shaders directory";
-
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
- 0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
- aMsg);
-
- return Standard_False;
+ aShaderMask |= anIter.Value()->Type();
}
-
- OSD_File aDeclFile (TCollection_AsciiString (aShaderDir) + "/Declarations.glsl");
- if (!aDeclFile.Exists())
+ 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)
{
- 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;
+ 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";
+ }
}
-
- TCollection_AsciiString aDeclarations;
-
- aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
- aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
- aDeclFile.Close();
-
- for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
- anIter.More(); anIter.Next())
+ else if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
{
- if (!anIter.Value()->IsDone())
+ if (!theCtx->IsGlGreaterEqual (3, 1))
{
- TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
-
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
- 0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
- aMsg);
-
- return Standard_False;
+ 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;
}
-
- Handle(OpenGl_ShaderObject) aShader;
-
- // Note: Add support of other shader types here
- switch (anIter.Value()->Type())
+ else if (aHeaderVer.IsEmpty())
{
- case Graphic3d_TOS_VERTEX:
- aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
- break;
- case Graphic3d_TOS_FRAGMENT:
- aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
- break;
+ aHeaderVer = "#version 310 es";
}
-
- // Is unsupported shader type?
- if (aShader.IsNull())
+ }
+#else
+ if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
+ {
+ if (!theCtx->IsGlGreaterEqual (4, 3))
{
- TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
-
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
- 0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
- aMsg);
-
- return Standard_False;
+ 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
- if (!aShader->Create (theCtx))
+ 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;
}
- TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
-
- if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX)
+ const GLenum aShaderType = shaderTypeToGl (anIter.Value()->Type());
+ if (aShaderType == 0)
{
- aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
+ return Standard_False;
}
- if (!aShader->LoadSource (theCtx, aSource))
+ Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (aShaderType);
+ if (!aShader->Create (theCtx))
{
- TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
-
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
- 0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
- aMsg);
-
+ aShader->Release (theCtx.operator->());
return Standard_False;
}
- if (!aShader->Compile (theCtx))
+ TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
+ if (myNbFragOutputs > 1)
{
- TCollection_ExtendedString aMsg = "Error! Failed to compile shader object";
-
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
- 0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
- aMsg);
+ 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->caps->contextDebug)
+ if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
{
- TCollection_AsciiString aLog;
- aShader->FetchInfoLog (theCtx, aLog);
- if (!aLog.IsEmpty())
+ if (theCtx->arbDrawBuffers)
{
- std::cout << aLog.ToCString() << std::endl << std::flush;
+ anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
}
- else
+ else if (theCtx->extDrawBuffers)
{
- std::cout << "Information log is empty" << std::endl;
+ anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
}
}
+ }
+ if (myHasAlphaTest)
+ {
+ anExtensions += "#define OCC_ALPHA_TEST\n";
+ }
- return Standard_False;
+ 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
}
- if (!AttachShader (theCtx, aShader))
+ TCollection_AsciiString aPrecisionHeader;
+ if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT)
{
- return Standard_False;
+ #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
}
- }
- if (!Link (theCtx))
- {
- TCollection_ExtendedString aMsg = "Error! Failed to link program object";
+ 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; }
+ }
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
- 0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
- aMsg);
+ 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->LoadAndCompile (theCtx, aSource))
+ {
+ return Standard_False;
+ }
- if (theCtx->caps->contextDebug)
+ if (theCtx->caps->glslDumpLevel)
{
- TCollection_AsciiString aLog;
- FetchInfoLog (theCtx, aLog);
- if (!aLog.IsEmpty())
+ TCollection_AsciiString aShaderTypeMsg;
+ switch (anIter.Value()->Type())
{
- std::cout << aLog.ToCString() << std::endl;
+ case Graphic3d_TOS_COMPUTE: { aShaderTypeMsg = "Compute shader source code:\n"; break; }
+ case Graphic3d_TOS_VERTEX: { aShaderTypeMsg = "Vertex shader source code:\n"; break; }
+ case Graphic3d_TOS_TESS_CONTROL: { aShaderTypeMsg = "Tesselation control shader source code:\n"; break; }
+ case Graphic3d_TOS_TESS_EVALUATION: { aShaderTypeMsg = "Tesselation evaluation shader source code:\n"; break; }
+ case Graphic3d_TOS_GEOMETRY: { aShaderTypeMsg = "Geometry shader source code:\n"; break; }
+ case Graphic3d_TOS_FRAGMENT: { aShaderTypeMsg = "Fragment shader source code:\n"; break; }
}
- else
+ TCollection_AsciiString anOutputSource = aSource;
+ if (theCtx->caps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short)
{
- std::cout << "Information log is empty" << std::endl;
+ anOutputSource = aHeaderVer
+ + (!aHeaderVer.IsEmpty() ? "\n" : "")
+ + anExtensions
+ + aPrecisionHeader
+ + aHeaderType
+ + aHeaderConstants
+ + anIter.Value()->Source();
}
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_MEDIUM,
+ TCollection_ExtendedString (aShaderTypeMsg + anOutputSource));
}
+ 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))
+ {
return Standard_False;
}
+ // 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;
}
}
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;
}
// 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_False;
}
- theCtx->core20->glLinkProgram (myProgramID);
-
GLint aStatus = GL_FALSE;
- 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;
+ }
for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
{
myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
}
+ return Standard_True;
+}
- return aStatus != GL_FALSE;
+// =======================================================================
+// 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;
}
// =======================================================================
}
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;
}
-// =======================================================================
-// function : Bind
-// purpose : Sets the program object as part of current rendering state
-// =======================================================================
-void OpenGl_ShaderProgram::Bind (const Handle(OpenGl_Context)& theCtx) const
-{
- if (myProgramID == NO_PROGRAM)
- {
- return;
- }
-
- theCtx->core20->glUseProgram (myProgramID);
- theCtx->ShaderManager()->myIsPP = Standard_True;
-}
-
// =======================================================================
// function : ApplyVariables
// purpose : Fetches uniform variables from proxy shader program
return Standard_True;
}
-// =======================================================================
-// function : BindWithVariables
-// purpose : Binds the program object and applies variables
-// =======================================================================
-Standard_Boolean OpenGl_ShaderProgram::BindWithVariables (const Handle(OpenGl_Context)& theCtx)
-{
- Bind (theCtx);
- return ApplyVariables (theCtx);
-}
-
-// =======================================================================
-// function : Unbind
-// purpose : Reverts to fixed-function graphics pipeline (FFP)
-// =======================================================================
-void OpenGl_ShaderProgram::Unbind (const Handle(OpenGl_Context)& theCtx)
-{
- if (theCtx->ShaderManager()->myIsPP)
- {
- theCtx->core20->glUseProgram (NO_PROGRAM);
- theCtx->ShaderManager()->myIsPP = Standard_False;
- }
-}
-
-// =======================================================================
-// 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;
+}
+
+// =======================================================================
+// 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;
}
return Standard_False;
}
- theCtx->core20->glUniform1i (theLocation, theValue);
+ 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
}
// =======================================================================
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;
}
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
const GLchar* theName,
- const OpenGl_Matrix& theValue,
+ const OpenGl_Mat4& theValue,
GLboolean theTranspose)
{
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
GLint theLocation,
- const OpenGl_Matrix& theValue,
+ const OpenGl_Mat4& theValue,
GLboolean theTranspose)
{
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
return Standard_False;
}
- theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat);
+ theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
return Standard_True;
}
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
const GLchar* theName,
- const Tmatrix3& theValue,
+ const OpenGl_Matrix& theValue,
GLboolean theTranspose)
{
return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
GLint theLocation,
- const Tmatrix3& theValue,
+ 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->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue);
+ 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;
}
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
const GLchar* theName,
- const GLenum theTextureUnit)
+ const Graphic3d_TextureUnit theTextureUnit)
{
return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
}
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
GLint theLocation,
- const GLenum theTextureUnit)
+ const Graphic3d_TextureUnit theTextureUnit)
{
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
{
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;
// function : Release
// purpose : Destroys shader program
// =======================================================================
-void OpenGl_ShaderProgram::Release (const OpenGl_Context* theCtx)
+void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
{
if (myProgramID == NO_PROGRAM)
{
for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
{
- anIter.ChangeValue()->Release (theCtx);
- anIter.ChangeValue().Nullify();
+ if (!anIter.Value().IsNull())
+ {
+ anIter.ChangeValue()->Release (theCtx);
+ anIter.ChangeValue().Nullify();
+ }
}
- if (theCtx->core20 != NULL)
+ if (theCtx->core20fwd != NULL
+ && theCtx->IsValid())
{
- theCtx->core20->glDeleteProgram (myProgramID);
+ theCtx->core20fwd->glDeleteProgram (myProgramID);
}
myProgramID = NO_PROGRAM;