1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0028069: Visualization, TKOpenGl - handle flat shading model within GLSL programs

This commit is contained in:
kgv 2017-09-10 17:06:19 +03:00 committed by bugmaster
parent 048e1b3b03
commit 8c3237d451
5 changed files with 79 additions and 12 deletions

View File

@ -152,6 +152,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
atiMem (Standard_False),
nvxMem (Standard_False),
oesSampleVariables (Standard_False),
oesStdDerivatives (Standard_False),
mySharedResources (new OpenGl_ResourcesMap()),
myDelayed (new OpenGl_DelayReleaseMap()),
myUnusedResources (new OpenGl_ResourcesStack()),
@ -1412,6 +1413,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
: OpenGl_FeatureNotAvailable;
oesSampleVariables = CheckExtension ("GL_OES_sample_variables");
oesStdDerivatives = CheckExtension ("GL_OES_standard_derivatives");
hasSampleVariables = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
oesSampleVariables ? OpenGl_FeatureInExtensions
: OpenGl_FeatureNotAvailable;

View File

@ -823,6 +823,7 @@ public: //! @name extensions
Standard_Boolean atiMem; //!< GL_ATI_meminfo
Standard_Boolean nvxMem; //!< GL_NVX_gpu_memory_info
Standard_Boolean oesSampleVariables; //!< GL_OES_sample_variables
Standard_Boolean oesStdDerivatives; //!< GL_OES_standard_derivatives
public: //! @name public properties tracking current state

View File

@ -479,7 +479,14 @@ Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
// =======================================================================
void OpenGl_ShaderManager::switchLightPrograms()
{
TCollection_AsciiString aKey (myShadingModel == Graphic3d_TOSM_FRAGMENT ? "p_" : "g_");
TCollection_AsciiString aKey;
switch (myShadingModel)
{
case Graphic3d_TOSM_NONE: aKey = "c_"; break;
case Graphic3d_TOSM_FACET: aKey = "f_"; break;
case Graphic3d_TOSM_VERTEX: aKey = "g_"; break;
case Graphic3d_TOSM_FRAGMENT: aKey = "p_"; break;
}
const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
if (aLights != NULL)
{
@ -1847,9 +1854,17 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
// purpose :
// =======================================================================
Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
const Standard_Integer theBits)
const Standard_Integer theBits,
const Standard_Boolean theIsFlatNormal)
{
#define thePhongCompLight "computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing)"
#if defined(GL_ES_VERSION_2_0)
const bool isFlatNormal = theIsFlatNormal
&& (myContext->IsGlGreaterEqual (3, 0)
|| myContext->oesStdDerivatives);
#else
const bool isFlatNormal = theIsFlatNormal;
#endif
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain;
@ -1920,20 +1935,22 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
}
aSrcVert = TCollection_AsciiString()
+ THE_FUNC_transformNormal
+ (isFlatNormal ? "" : THE_FUNC_transformNormal)
+ EOL
EOL"THE_SHADER_OUT vec4 PositionWorld;"
EOL"THE_SHADER_OUT vec4 Position;"
EOL"THE_SHADER_OUT vec3 Normal;"
EOL"THE_SHADER_OUT vec3 View;"
EOL
+ (isFlatNormal ? ""
: EOL"THE_SHADER_OUT vec3 Normal;")
+ EOL
+ aSrcVertExtraOut
+ EOL"void main()"
EOL"{"
EOL" PositionWorld = occModelWorldMatrix * occVertex;"
EOL" Position = occWorldViewMatrix * PositionWorld;"
EOL" Normal = transformNormal (occNormal);"
EOL" View = vec3 (0.0, 0.0, 1.0);"
+ (isFlatNormal ? ""
: EOL" Normal = transformNormal (occNormal);")
+ EOL" View = vec3 (0.0, 0.0, 1.0);"
+ aSrcVertExtraMain
+ EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
EOL"}";
@ -1942,8 +1959,10 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
aSrcFrag = TCollection_AsciiString()
+ EOL"THE_SHADER_IN vec4 PositionWorld;"
EOL"THE_SHADER_IN vec4 Position;"
EOL"THE_SHADER_IN vec3 Normal;"
EOL"THE_SHADER_IN vec3 View;"
+ (isFlatNormal
? EOL"vec3 Normal;"
: EOL"THE_SHADER_IN vec3 Normal;")
+ EOL
+ aSrcFragExtraOut
+ aSrcFragGetVertColor
@ -1953,6 +1972,9 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
EOL"void main()"
EOL"{"
+ aSrcFragExtraMain
+ (isFlatNormal
? EOL" Normal = normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));"
: "")
+ EOL" occFragColor = getColor();"
+ aSrcFragWriteOit
+ EOL"}";
@ -1967,6 +1989,19 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
{
aProgramSrc->SetHeader ("#version 300 es");
}
else if (isFlatNormal)
{
if (myContext->oesStdDerivatives)
{
aProgramSrc->SetHeader ("#extension GL_OES_standard_derivatives : enable");
}
else
{
myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
"Warning: flat shading requires OpenGL ES 3.0+ or GL_OES_standard_derivatives extension.");
}
}
#endif
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));

View File

@ -423,9 +423,14 @@ protected:
Standard_Boolean prepareStdProgramLight (Handle(OpenGl_ShaderProgram)& theProgram,
const Standard_Integer theBits)
{
return myShadingModel == Graphic3d_TOSM_FRAGMENT
? prepareStdProgramPhong (theProgram, theBits)
: prepareStdProgramGouraud (theProgram, theBits);
switch (myShadingModel)
{
case Graphic3d_TOSM_NONE: return prepareStdProgramFlat (theProgram, theBits);
case Graphic3d_TOSM_FACET: return prepareStdProgramPhong (theProgram, theBits, true);
case Graphic3d_TOSM_VERTEX: return prepareStdProgramGouraud(theProgram, theBits);
case Graphic3d_TOSM_FRAGMENT: return prepareStdProgramPhong (theProgram, theBits, false);
}
return false;
}
//! Prepare standard GLSL program with per-vertex lighting.
@ -433,8 +438,10 @@ protected:
const Standard_Integer theBits);
//! Prepare standard GLSL program with per-pixel lighting.
//! @param theIsFlatNormal when TRUE, the Vertex normals will be ignored and Face normal will be computed instead
Standard_EXPORT Standard_Boolean prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
const Standard_Integer theBits);
const Standard_Integer theBits,
const Standard_Boolean theIsFlatNormal = false);
//! Define computeLighting GLSL function depending on current lights configuration
//! @param theHasVertColor flag to use getVertColor() instead of Ambient and Diffuse components of active material

22
tests/v3d/glsl/flat_fuse1 Normal file
View File

@ -0,0 +1,22 @@
puts "========"
puts "0028069: Visualization, TKOpenGl - handle flat shading model within GLSL programs"
puts "========"
vclear
vclose ALL
vinit View1
vviewparams -scale 551.55 -proj 0.85 -0.16 0.51 -up -0.41 0.41 0.82 -at 0.55 0.55 0.55
restore [locate_data_file occ/fuse.brep] f
tclean f
vdefaults -absDefl 0.5
vdisplay -dispMode 1 f
# setup lights
vlight clear
vlight add ambient color WHITE
vlight add directional dir 1 0 0 color GREEN headlight 1
vlight add directional dir -1 0 0 color RED1 headlight 1
vrenderparams -shadingModel flat
vdump $::imagedir/${::casename}.png