mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
0024250: TKOpenGl - per-pixel lighting using GLSL program (Phong shading)
This commit is contained in:
parent
65993a9537
commit
392ac9808e
@ -23,6 +23,10 @@
|
|||||||
#include <Graphic3d_GraphicDriver.hxx>
|
#include <Graphic3d_GraphicDriver.hxx>
|
||||||
#include <Graphic3d_ShaderObject.hxx>
|
#include <Graphic3d_ShaderObject.hxx>
|
||||||
#include <Graphic3d_ShaderProgram.hxx>
|
#include <Graphic3d_ShaderProgram.hxx>
|
||||||
|
#include <OSD_Directory.hxx>
|
||||||
|
#include <OSD_Environment.hxx>
|
||||||
|
#include <OSD_File.hxx>
|
||||||
|
#include <OSD_Path.hxx>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -32,6 +36,52 @@ namespace
|
|||||||
IMPLEMENT_STANDARD_HANDLE (Graphic3d_ShaderProgram, Standard_Transient)
|
IMPLEMENT_STANDARD_HANDLE (Graphic3d_ShaderProgram, Standard_Transient)
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ShaderProgram, Standard_Transient)
|
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ShaderProgram, Standard_Transient)
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ShadersFolder
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
const TCollection_AsciiString& Graphic3d_ShaderProgram::ShadersFolder()
|
||||||
|
{
|
||||||
|
static Standard_Boolean THE_IS_DEFINED = Standard_False;
|
||||||
|
static TCollection_AsciiString THE_SHADERS_FOLDER;
|
||||||
|
if (!THE_IS_DEFINED)
|
||||||
|
{
|
||||||
|
THE_IS_DEFINED = Standard_True;
|
||||||
|
OSD_Environment aDirEnv ("CSF_ShadersDirectory");
|
||||||
|
THE_SHADERS_FOLDER = aDirEnv.Value();
|
||||||
|
if (THE_SHADERS_FOLDER.IsEmpty())
|
||||||
|
{
|
||||||
|
OSD_Environment aCasRootEnv ("CASROOT");
|
||||||
|
THE_SHADERS_FOLDER = aCasRootEnv.Value();
|
||||||
|
if (!THE_SHADERS_FOLDER.IsEmpty())
|
||||||
|
{
|
||||||
|
THE_SHADERS_FOLDER += "/src/Shaders";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (THE_SHADERS_FOLDER.IsEmpty())
|
||||||
|
{
|
||||||
|
std::cerr << "Both environment variables CSF_ShadersDirectory and CASROOT are undefined!\n"
|
||||||
|
<< "At least one should be defined to use standard GLSL programs.\n";
|
||||||
|
Standard_Failure::Raise ("CSF_ShadersDirectory and CASROOT are undefined");
|
||||||
|
return THE_SHADERS_FOLDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
const OSD_Path aDirPath (THE_SHADERS_FOLDER);
|
||||||
|
OSD_Directory aDir (aDirPath);
|
||||||
|
const TCollection_AsciiString aProgram = THE_SHADERS_FOLDER + "/Declarations.glsl";
|
||||||
|
OSD_File aProgramFile (aProgram);
|
||||||
|
if (!aDir.Exists()
|
||||||
|
|| !aProgramFile.Exists())
|
||||||
|
{
|
||||||
|
std::cerr << "Standard GLSL programs are not found in: " << THE_SHADERS_FOLDER.ToCString() << std::endl;
|
||||||
|
Standard_Failure::Raise ("CSF_ShadersDirectory or CASROOT is set incorrectly");
|
||||||
|
return THE_SHADERS_FOLDER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return THE_SHADERS_FOLDER;
|
||||||
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : Graphic3d_ShaderProgram
|
// function : Graphic3d_ShaderProgram
|
||||||
// purpose : Creates new empty program object
|
// purpose : Creates new empty program object
|
||||||
@ -42,6 +92,47 @@ Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
|
|||||||
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER));
|
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Graphic3d_ShaderProgram
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Graphic3d_ShaderProgram::Graphic3d_ShaderProgram (const Graphic3d_ShaderProgram::ShaderName theName)
|
||||||
|
{
|
||||||
|
const TCollection_AsciiString& aShadersRoot = Graphic3d_ShaderProgram::ShadersFolder();
|
||||||
|
switch (theName)
|
||||||
|
{
|
||||||
|
case ShaderName_Phong:
|
||||||
|
{
|
||||||
|
myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_Phong");
|
||||||
|
const TCollection_AsciiString aSrcVert = aShadersRoot + "/PhongShading.vs";
|
||||||
|
const TCollection_AsciiString aSrcFrag = aShadersRoot + "/PhongShading.fs";
|
||||||
|
|
||||||
|
if (!aSrcVert.IsEmpty()
|
||||||
|
&& !OSD_File (aSrcVert).Exists())
|
||||||
|
{
|
||||||
|
Standard_Failure::Raise ("Graphic3d_ShaderProgram, PhongShading.vs is not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!aSrcFrag.IsEmpty()
|
||||||
|
&& !OSD_File (aSrcFrag).Exists())
|
||||||
|
{
|
||||||
|
Standard_Failure::Raise ("Graphic3d_ShaderProgram, PhongShading.fs is not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||||
|
AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ShaderName_UNKNOWN:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Standard_Failure::Raise ("Graphic3d_ShaderProgram, unknown program name");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : ~Graphic3d_ShaderProgram
|
// function : ~Graphic3d_ShaderProgram
|
||||||
// purpose : Releases resources of program object
|
// purpose : Releases resources of program object
|
||||||
|
@ -34,11 +34,25 @@ typedef NCollection_Sequence<Handle(Graphic3d_ShaderVariable)> Graphic3d_ShaderV
|
|||||||
//! This class is responsible for managing shader programs.
|
//! This class is responsible for managing shader programs.
|
||||||
class Graphic3d_ShaderProgram : public Standard_Transient
|
class Graphic3d_ShaderProgram : public Standard_Transient
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! The list of built-in GLSL programs
|
||||||
|
enum ShaderName
|
||||||
|
{
|
||||||
|
ShaderName_UNKNOWN, //!< undefined program
|
||||||
|
ShaderName_Phong //!< per-pixel lighting (Phong shading)
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Creates new empty program object.
|
//! Creates new empty program object.
|
||||||
Standard_EXPORT Graphic3d_ShaderProgram();
|
Standard_EXPORT Graphic3d_ShaderProgram();
|
||||||
|
|
||||||
|
//! Creates program object from pre-defined shaders.
|
||||||
|
//! Raises Standard_Failure exception if shader resources are unavailable.
|
||||||
|
Standard_EXPORT Graphic3d_ShaderProgram (const Graphic3d_ShaderProgram::ShaderName theName);
|
||||||
|
|
||||||
//! Releases resources of program object.
|
//! Releases resources of program object.
|
||||||
Standard_EXPORT virtual ~Graphic3d_ShaderProgram();
|
Standard_EXPORT virtual ~Graphic3d_ShaderProgram();
|
||||||
|
|
||||||
@ -71,6 +85,12 @@ public:
|
|||||||
//! Removes all custom uniform variables from the program.
|
//! Removes all custom uniform variables from the program.
|
||||||
Standard_EXPORT void ClearVariables();
|
Standard_EXPORT void ClearVariables();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! The path to GLSL programs determined from CSF_ShadersDirectory or CASROOT environment variables.
|
||||||
|
//! @return the root folder with default GLSL programs.
|
||||||
|
Standard_EXPORT static const TCollection_AsciiString& ShadersFolder();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTI (Graphic3d_ShaderProgram)
|
DEFINE_STANDARD_RTTI (Graphic3d_ShaderProgram)
|
||||||
|
@ -60,9 +60,9 @@ TCollection_AsciiString Graphic3d_TextureRoot::TexturesFolder()
|
|||||||
|
|
||||||
if (VarName.IsEmpty())
|
if (VarName.IsEmpty())
|
||||||
{
|
{
|
||||||
std::cerr << " CSF_MDTVTexturesDirectory and CASROOT not setted\n";
|
std::cerr << "Both environment variables CSF_MDTVTexturesDirectory and CASROOT are undefined!\n"
|
||||||
std::cerr << " one of these variable are mandatory to use this functionality\n";
|
<< "At least one should be defined to use standard Textures.\n";
|
||||||
Standard_Failure::Raise ("CSF_MDTVTexturesDirectory and CASROOT not setted");
|
Standard_Failure::Raise ("CSF_MDTVTexturesDirectory and CASROOT are undefined");
|
||||||
return VarName;
|
return VarName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,6 @@ void OpenGl_AspectFace::SetAspect (const CALL_DEF_CONTEXTFILLAREA& theAspect)
|
|||||||
myTexture = theAspect.Texture.TextureMap;
|
myTexture = theAspect.Texture.TextureMap;
|
||||||
|
|
||||||
const TCollection_AsciiString& aTextureKey = myTexture.IsNull() ? THE_EMPTY_KEY : myTexture->GetId();
|
const TCollection_AsciiString& aTextureKey = myTexture.IsNull() ? THE_EMPTY_KEY : myTexture->GetId();
|
||||||
|
|
||||||
if (aTextureKey.IsEmpty() || myResources.TextureId != aTextureKey)
|
if (aTextureKey.IsEmpty() || myResources.TextureId != aTextureKey)
|
||||||
{
|
{
|
||||||
myResources.ResetTexture();
|
myResources.ResetTexture();
|
||||||
@ -234,7 +233,6 @@ void OpenGl_AspectFace::SetAspect (const CALL_DEF_CONTEXTFILLAREA& theAspect)
|
|||||||
myShaderProgram = theAspect.ShaderProgram;
|
myShaderProgram = theAspect.ShaderProgram;
|
||||||
|
|
||||||
const TCollection_AsciiString& aShaderKey = myShaderProgram.IsNull() ? THE_EMPTY_KEY : myShaderProgram->GetId();
|
const TCollection_AsciiString& aShaderKey = myShaderProgram.IsNull() ? THE_EMPTY_KEY : myShaderProgram->GetId();
|
||||||
|
|
||||||
if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
|
if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
|
||||||
{
|
{
|
||||||
myResources.ResetShader();
|
myResources.ResetShader();
|
||||||
@ -415,9 +413,11 @@ void OpenGl_AspectFace::Release (const Handle(OpenGl_Context)& theContext)
|
|||||||
myResources.TextureId.Clear();
|
myResources.TextureId.Clear();
|
||||||
myResources.ResetTexture();
|
myResources.ResetTexture();
|
||||||
|
|
||||||
if (!myResources.ShaderProgram.IsNull() && !theContext.IsNull())
|
if (!myResources.ShaderProgram.IsNull()
|
||||||
|
&& !theContext.IsNull())
|
||||||
{
|
{
|
||||||
theContext->ShaderManager()->Unregister (myResources.ShaderProgram);
|
theContext->ShaderManager()->Unregister (myResources.ShaderProgramId,
|
||||||
|
myResources.ShaderProgram);
|
||||||
}
|
}
|
||||||
myResources.ShaderProgramId.Clear();
|
myResources.ShaderProgramId.Clear();
|
||||||
myResources.ResetShader();
|
myResources.ResetShader();
|
||||||
@ -471,35 +471,24 @@ void OpenGl_AspectFace::Resources::BuildTexture (const Handle(OpenGl_Workspace)&
|
|||||||
// function : BuildShader
|
// function : BuildShader
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_AspectFace::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
|
void OpenGl_AspectFace::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
|
||||||
const Handle(Graphic3d_ShaderProgram)& theShader)
|
const Handle(Graphic3d_ShaderProgram)& theShader)
|
||||||
{
|
{
|
||||||
const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
|
const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
|
||||||
|
|
||||||
if (!aContext->IsGlGreaterEqual (2, 0))
|
if (!aContext->IsGlGreaterEqual (2, 0))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// release old shader program resources
|
// release old shader program resources
|
||||||
if (!ShaderProgram.IsNull())
|
if (!ShaderProgram.IsNull())
|
||||||
{
|
{
|
||||||
aContext->ShaderManager()->Unregister (ShaderProgram);
|
aContext->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
|
||||||
|
}
|
||||||
|
if (theShader.IsNull())
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderProgramId = theShader.IsNull() ? THE_EMPTY_KEY : theShader->GetId();
|
aContext->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
|
||||||
|
|
||||||
if (!theShader.IsNull())
|
|
||||||
{
|
|
||||||
if (!aContext->GetResource<Handle(OpenGl_ShaderProgram)> (ShaderProgramId, ShaderProgram))
|
|
||||||
{
|
|
||||||
ShaderProgram = aContext->ShaderManager()->Create (theShader);
|
|
||||||
if (!ShaderProgramId.IsEmpty())
|
|
||||||
{
|
|
||||||
aContext->ShareResource (ShaderProgramId, ShaderProgram);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ShaderProgram.Nullify();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,6 @@ void OpenGl_AspectLine::SetAspect (const CALL_DEF_CONTEXTLINE &theAspect)
|
|||||||
myShaderProgram = theAspect.ShaderProgram;
|
myShaderProgram = theAspect.ShaderProgram;
|
||||||
|
|
||||||
const TCollection_AsciiString& aShaderKey = myShaderProgram.IsNull() ? THE_EMPTY_KEY : myShaderProgram->GetId();
|
const TCollection_AsciiString& aShaderKey = myShaderProgram.IsNull() ? THE_EMPTY_KEY : myShaderProgram->GetId();
|
||||||
|
|
||||||
if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
|
if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
|
||||||
{
|
{
|
||||||
myResources.ResetShader();
|
myResources.ResetShader();
|
||||||
@ -90,9 +89,11 @@ void OpenGl_AspectLine::Render (const Handle(OpenGl_Workspace) &theWorkspace) co
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_AspectLine::Release (const Handle(OpenGl_Context)& theContext)
|
void OpenGl_AspectLine::Release (const Handle(OpenGl_Context)& theContext)
|
||||||
{
|
{
|
||||||
if (!myResources.ShaderProgram.IsNull() && !theContext.IsNull())
|
if (!myResources.ShaderProgram.IsNull()
|
||||||
|
&& !theContext.IsNull())
|
||||||
{
|
{
|
||||||
theContext->ShaderManager()->Unregister (myResources.ShaderProgram);
|
theContext->ShaderManager()->Unregister (myResources.ShaderProgramId,
|
||||||
|
myResources.ShaderProgram);
|
||||||
}
|
}
|
||||||
myResources.ShaderProgramId.Clear();
|
myResources.ShaderProgramId.Clear();
|
||||||
myResources.ResetShader();
|
myResources.ResetShader();
|
||||||
@ -102,35 +103,24 @@ void OpenGl_AspectLine::Release (const Handle(OpenGl_Context)& theContext)
|
|||||||
// function : BuildShader
|
// function : BuildShader
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_AspectLine::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
|
void OpenGl_AspectLine::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
|
||||||
const Handle(Graphic3d_ShaderProgram)& theShader)
|
const Handle(Graphic3d_ShaderProgram)& theShader)
|
||||||
{
|
{
|
||||||
const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
|
const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
|
||||||
|
|
||||||
if (!aContext->IsGlGreaterEqual (2, 0))
|
if (!aContext->IsGlGreaterEqual (2, 0))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// release old shader program resources
|
// release old shader program resources
|
||||||
if (!ShaderProgram.IsNull())
|
if (!ShaderProgram.IsNull())
|
||||||
{
|
{
|
||||||
aContext->ShaderManager()->Unregister (ShaderProgram);
|
aContext->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
|
||||||
|
}
|
||||||
|
if (theShader.IsNull())
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderProgramId = theShader.IsNull() ? THE_EMPTY_KEY : theShader->GetId();
|
aContext->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
|
||||||
|
|
||||||
if (!theShader.IsNull())
|
|
||||||
{
|
|
||||||
if (!aContext->GetResource<Handle(OpenGl_ShaderProgram)> (ShaderProgramId, ShaderProgram))
|
|
||||||
{
|
|
||||||
ShaderProgram = aContext->ShaderManager()->Create (theShader);
|
|
||||||
if (!ShaderProgramId.IsEmpty())
|
|
||||||
{
|
|
||||||
aContext->ShareResource (ShaderProgramId, ShaderProgram);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ShaderProgram.Nullify();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1539,7 +1539,8 @@ void OpenGl_AspectMarker::Release (const Handle(OpenGl_Context)& theCtx)
|
|||||||
|
|
||||||
if (!myResources.ShaderProgram.IsNull() && !theCtx.IsNull())
|
if (!myResources.ShaderProgram.IsNull() && !theCtx.IsNull())
|
||||||
{
|
{
|
||||||
theCtx->ShaderManager()->Unregister (myResources.ShaderProgram);
|
theCtx->ShaderManager()->Unregister (myResources.ShaderProgramId,
|
||||||
|
myResources.ShaderProgram);
|
||||||
}
|
}
|
||||||
myResources.ShaderProgramId.Clear();
|
myResources.ShaderProgramId.Clear();
|
||||||
myResources.ResetShader();
|
myResources.ResetShader();
|
||||||
@ -1895,37 +1896,26 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
|
|||||||
// function : BuildShader
|
// function : BuildShader
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
|
void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
|
||||||
const Handle(Graphic3d_ShaderProgram)& theShader)
|
const Handle(Graphic3d_ShaderProgram)& theShader)
|
||||||
{
|
{
|
||||||
const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
|
const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
|
||||||
|
|
||||||
if (!aContext->IsGlGreaterEqual (2, 0))
|
if (!aContext->IsGlGreaterEqual (2, 0))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// release old shader program resources
|
// release old shader program resources
|
||||||
if (!ShaderProgram.IsNull())
|
if (!ShaderProgram.IsNull())
|
||||||
{
|
{
|
||||||
aContext->ShaderManager()->Unregister (ShaderProgram);
|
aContext->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
|
||||||
|
}
|
||||||
|
if (theShader.IsNull())
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderProgramId = theShader.IsNull() ? THE_EMPTY_KEY : theShader->GetId();
|
aContext->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
|
||||||
|
|
||||||
if (!theShader.IsNull())
|
|
||||||
{
|
|
||||||
if (!aContext->GetResource<Handle(OpenGl_ShaderProgram)> (ShaderProgramId, ShaderProgram))
|
|
||||||
{
|
|
||||||
ShaderProgram = aContext->ShaderManager()->Create (theShader);
|
|
||||||
if (!ShaderProgramId.IsEmpty())
|
|
||||||
{
|
|
||||||
aContext->ShareResource (ShaderProgramId, ShaderProgram);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ShaderProgram.Nullify();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
|
@ -107,9 +107,11 @@ void OpenGl_AspectText::Render (const Handle(OpenGl_Workspace)& theWorkspace) co
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_AspectText::Release (const Handle(OpenGl_Context)& theContext)
|
void OpenGl_AspectText::Release (const Handle(OpenGl_Context)& theContext)
|
||||||
{
|
{
|
||||||
if (!myResources.ShaderProgram.IsNull() && !theContext.IsNull())
|
if (!myResources.ShaderProgram.IsNull()
|
||||||
|
&& !theContext.IsNull())
|
||||||
{
|
{
|
||||||
theContext->ShaderManager()->Unregister (myResources.ShaderProgram);
|
theContext->ShaderManager()->Unregister (myResources.ShaderProgramId,
|
||||||
|
myResources.ShaderProgram);
|
||||||
}
|
}
|
||||||
myResources.ShaderProgramId.Clear();
|
myResources.ShaderProgramId.Clear();
|
||||||
myResources.ResetShader();
|
myResources.ResetShader();
|
||||||
@ -119,35 +121,24 @@ void OpenGl_AspectText::Release (const Handle(OpenGl_Context)& theContext)
|
|||||||
// function : BuildShader
|
// function : BuildShader
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_AspectText::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
|
void OpenGl_AspectText::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
|
||||||
const Handle(Graphic3d_ShaderProgram)& theShader)
|
const Handle(Graphic3d_ShaderProgram)& theShader)
|
||||||
{
|
{
|
||||||
const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
|
const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
|
||||||
|
|
||||||
if (!aContext->IsGlGreaterEqual (2, 0))
|
if (!aContext->IsGlGreaterEqual (2, 0))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// release old shader program resources
|
// release old shader program resources
|
||||||
if (!ShaderProgram.IsNull())
|
if (!ShaderProgram.IsNull())
|
||||||
{
|
{
|
||||||
aContext->ShaderManager()->Unregister (ShaderProgram);
|
aContext->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
|
||||||
|
}
|
||||||
|
if (theShader.IsNull())
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderProgramId = theShader.IsNull() ? THE_EMPTY_KEY : theShader->GetId();
|
aContext->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
|
||||||
|
|
||||||
if (!theShader.IsNull())
|
|
||||||
{
|
|
||||||
if (!aContext->GetResource<Handle(OpenGl_ShaderProgram)> (ShaderProgramId, ShaderProgram))
|
|
||||||
{
|
|
||||||
ShaderProgram = aContext->ShaderManager()->Create (theShader);
|
|
||||||
if (!ShaderProgramId.IsEmpty())
|
|
||||||
{
|
|
||||||
aContext->ShareResource (ShaderProgramId, ShaderProgram);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ShaderProgram.Nullify();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ void OpenGl_CappingAlgo::RenderPlane (const Handle(OpenGl_Workspace)& theWorkspa
|
|||||||
glDisableClientState (GL_VERTEX_ARRAY);
|
glDisableClientState (GL_VERTEX_ARRAY);
|
||||||
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
|
||||||
|
|
||||||
theWorkspace->SetStructureMatrix (aModelMatrix);
|
theWorkspace->SetStructureMatrix (aModelMatrix, true);
|
||||||
theWorkspace->SetAspectFace (aFaceAspect);
|
theWorkspace->SetAspectFace (aFaceAspect);
|
||||||
|
|
||||||
// set delayed resource release
|
// set delayed resource release
|
||||||
|
@ -29,6 +29,7 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Caps, Standard_Transient)
|
|||||||
OpenGl_Caps::OpenGl_Caps()
|
OpenGl_Caps::OpenGl_Caps()
|
||||||
: vboDisable (Standard_False),
|
: vboDisable (Standard_False),
|
||||||
pntSpritesDisable (Standard_False),
|
pntSpritesDisable (Standard_False),
|
||||||
|
keepArrayData (Standard_False),
|
||||||
contextStereo (Standard_False),
|
contextStereo (Standard_False),
|
||||||
#ifdef DEB
|
#ifdef DEB
|
||||||
contextDebug (Standard_True),
|
contextDebug (Standard_True),
|
||||||
@ -36,7 +37,7 @@ OpenGl_Caps::OpenGl_Caps()
|
|||||||
contextDebug (Standard_False),
|
contextDebug (Standard_False),
|
||||||
#endif
|
#endif
|
||||||
contextNoAccel (Standard_False),
|
contextNoAccel (Standard_False),
|
||||||
keepArrayData (Standard_False)
|
glslWarnings (Standard_False)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
@ -49,9 +50,11 @@ OpenGl_Caps& OpenGl_Caps::operator= (const OpenGl_Caps& theCopy)
|
|||||||
{
|
{
|
||||||
vboDisable = theCopy.vboDisable;
|
vboDisable = theCopy.vboDisable;
|
||||||
pntSpritesDisable = theCopy.pntSpritesDisable;
|
pntSpritesDisable = theCopy.pntSpritesDisable;
|
||||||
|
keepArrayData = theCopy.keepArrayData;
|
||||||
contextStereo = theCopy.contextStereo;
|
contextStereo = theCopy.contextStereo;
|
||||||
contextDebug = theCopy.contextDebug;
|
contextDebug = theCopy.contextDebug;
|
||||||
contextNoAccel = theCopy.contextNoAccel;
|
contextNoAccel = theCopy.contextNoAccel;
|
||||||
|
glslWarnings = theCopy.glslWarnings;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ public: //! @name flags to disable particular functionality, should be used only
|
|||||||
|
|
||||||
Standard_Boolean vboDisable; //!< flag permits VBO usage, will significantly affect performance (OFF by default)
|
Standard_Boolean vboDisable; //!< flag permits VBO usage, will significantly affect performance (OFF by default)
|
||||||
Standard_Boolean pntSpritesDisable; //!< flag permits Point Sprites usage, will significantly affect performance (OFF by default)
|
Standard_Boolean pntSpritesDisable; //!< flag permits Point Sprites usage, will significantly affect performance (OFF by default)
|
||||||
|
Standard_Boolean keepArrayData; //!< Disables freeing CPU memory after building VBOs (OFF by default)
|
||||||
|
|
||||||
public: //! @name context creation parameters
|
public: //! @name context creation parameters
|
||||||
|
|
||||||
@ -67,12 +68,10 @@ public: //! @name context creation parameters
|
|||||||
*/
|
*/
|
||||||
Standard_Boolean contextNoAccel;
|
Standard_Boolean contextNoAccel;
|
||||||
|
|
||||||
/**
|
public: //! @name flags to activate verbose output
|
||||||
* Disables freeing CPU memory after building VBOs.
|
|
||||||
*
|
//! Print GLSL program compilation/linkage warnings, if any. OFF by default.
|
||||||
* OFF by default.
|
Standard_Boolean glslWarnings;
|
||||||
*/
|
|
||||||
Standard_Boolean keepArrayData;
|
|
||||||
|
|
||||||
public: //! @name class methods
|
public: //! @name class methods
|
||||||
|
|
||||||
|
@ -135,12 +135,17 @@ OpenGl_Context::~OpenGl_Context()
|
|||||||
// release shared resources if any
|
// release shared resources if any
|
||||||
if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
|
if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
|
||||||
{
|
{
|
||||||
|
myShaderManager.Nullify();
|
||||||
for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
|
for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
|
||||||
anIter.More(); anIter.Next())
|
anIter.More(); anIter.Next())
|
||||||
{
|
{
|
||||||
anIter.Value()->Release (this);
|
anIter.Value()->Release (this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myShaderManager->SetContext (NULL);
|
||||||
|
}
|
||||||
mySharedResources.Nullify();
|
mySharedResources.Nullify();
|
||||||
myDelayed.Nullify();
|
myDelayed.Nullify();
|
||||||
|
|
||||||
@ -203,6 +208,7 @@ void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
|
|||||||
mySharedResources = theShareCtx->mySharedResources;
|
mySharedResources = theShareCtx->mySharedResources;
|
||||||
myDelayed = theShareCtx->myDelayed;
|
myDelayed = theShareCtx->myDelayed;
|
||||||
myReleaseQueue = theShareCtx->myReleaseQueue;
|
myReleaseQueue = theShareCtx->myReleaseQueue;
|
||||||
|
myShaderManager = theShareCtx->myShaderManager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,6 +256,7 @@ Standard_Boolean OpenGl_Context::MakeCurrent()
|
|||||||
// however some drivers (Intel etc.) may FAIL doing this for unknown reason
|
// however some drivers (Intel etc.) may FAIL doing this for unknown reason
|
||||||
if (IsCurrent())
|
if (IsCurrent())
|
||||||
{
|
{
|
||||||
|
myShaderManager->SetContext (this);
|
||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
|
else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
|
||||||
@ -285,6 +292,7 @@ Standard_Boolean OpenGl_Context::MakeCurrent()
|
|||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
myShaderManager->SetContext (this);
|
||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,21 @@ class OpenGl_Element;
|
|||||||
class OpenGl_Structure;
|
class OpenGl_Structure;
|
||||||
class OpenGl_Text;
|
class OpenGl_Text;
|
||||||
|
|
||||||
|
//! Tool class to implement consistent state counter
|
||||||
|
//! for objects inside the same driver instance.
|
||||||
|
class OpenGl_StateCounter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
OpenGl_StateCounter() : myCounter (0) { }
|
||||||
|
|
||||||
|
Standard_Size Increment() { return ++myCounter; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Standard_Size myCounter;
|
||||||
|
};
|
||||||
|
|
||||||
//! This class defines an OpenGl graphic driver <br>
|
//! This class defines an OpenGl graphic driver <br>
|
||||||
class OpenGl_GraphicDriver : public Graphic3d_GraphicDriver
|
class OpenGl_GraphicDriver : public Graphic3d_GraphicDriver
|
||||||
{
|
{
|
||||||
@ -351,6 +366,14 @@ private:
|
|||||||
OpenGl_UserDrawCallback_t myUserDrawCallback;
|
OpenGl_UserDrawCallback_t myUserDrawCallback;
|
||||||
OpenGl_Text* myTempText; //!< variable for compatibility (drawing text in layers)
|
OpenGl_Text* myTempText; //!< variable for compatibility (drawing text in layers)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
OpenGl_StateCounter* GetStateCounter() const { return &myStateCounter; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
mutable OpenGl_StateCounter myStateCounter;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_OpenGl_GraphicDriver_HeaderFile
|
#endif //_OpenGl_GraphicDriver_HeaderFile
|
||||||
|
@ -558,7 +558,7 @@ Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& theCView)
|
|||||||
|
|
||||||
Handle(OpenGl_Context) aShareCtx = GetSharedContext();
|
Handle(OpenGl_Context) aShareCtx = GetSharedContext();
|
||||||
Handle(OpenGl_Workspace) aWS = new OpenGl_Workspace (myGlDisplay, theCView.DefWindow, theCView.GContext, myCaps, aShareCtx);
|
Handle(OpenGl_Workspace) aWS = new OpenGl_Workspace (myGlDisplay, theCView.DefWindow, theCView.GContext, myCaps, aShareCtx);
|
||||||
Handle(OpenGl_View) aView = new OpenGl_View (theCView.Context);
|
Handle(OpenGl_View) aView = new OpenGl_View (theCView.Context, &myStateCounter);
|
||||||
myMapOfWS .Bind (theCView.WsId, aWS);
|
myMapOfWS .Bind (theCView.WsId, aWS);
|
||||||
myMapOfView.Bind (theCView.ViewId, aView);
|
myMapOfView.Bind (theCView.ViewId, aView);
|
||||||
|
|
||||||
|
@ -55,35 +55,56 @@ OpenGl_ShaderManager::~OpenGl_ShaderManager()
|
|||||||
// function : Create
|
// function : Create
|
||||||
// purpose : Creates new shader program
|
// purpose : Creates new shader program
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
Handle(OpenGl_ShaderProgram) OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxyProgram)
|
void OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
|
||||||
|
TCollection_AsciiString& theShareKey,
|
||||||
|
Handle(OpenGl_ShaderProgram)& theProgram)
|
||||||
{
|
{
|
||||||
if (theProxyProgram.IsNull())
|
theProgram.Nullify();
|
||||||
|
if (theProxy.IsNull())
|
||||||
{
|
{
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(OpenGl_ShaderProgram) aProgram = new OpenGl_ShaderProgram (theProxyProgram);
|
|
||||||
if (!aProgram->Initialize (myContext, theProxyProgram->ShaderObjects()))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
myProgramList.Append (aProgram);
|
|
||||||
|
|
||||||
return aProgram;
|
theShareKey = theProxy->GetId();
|
||||||
|
if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram))
|
||||||
|
{
|
||||||
|
theProgram->Share();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
theProgram = new OpenGl_ShaderProgram (theProxy);
|
||||||
|
if (!theProgram->Initialize (myContext, theProxy->ShaderObjects()))
|
||||||
|
{
|
||||||
|
theProgram->Release (myContext);
|
||||||
|
theShareKey.Clear();
|
||||||
|
theProgram.Nullify();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
myProgramList.Append (theProgram);
|
||||||
|
myContext->ShareResource (theShareKey, theProgram);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : Unregister
|
// function : Unregister
|
||||||
// purpose : Removes specified shader program from the manager
|
// purpose : Removes specified shader program from the manager
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_ShaderManager::Unregister (Handle(OpenGl_ShaderProgram)& theProgram)
|
void OpenGl_ShaderManager::Unregister (TCollection_AsciiString& theShareKey,
|
||||||
|
Handle(OpenGl_ShaderProgram)& theProgram)
|
||||||
{
|
{
|
||||||
for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
|
for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
|
||||||
{
|
{
|
||||||
if (anIt.Value() == theProgram)
|
if (anIt.Value() == theProgram)
|
||||||
{
|
{
|
||||||
|
if (!theProgram->UnShare())
|
||||||
|
{
|
||||||
|
theShareKey.Clear();
|
||||||
|
theProgram.Nullify();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
myProgramList.Remove (anIt);
|
myProgramList.Remove (anIt);
|
||||||
|
myMaterialStates.UnBind (theProgram);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,11 +48,17 @@ public:
|
|||||||
//! Releases resources of shader manager.
|
//! Releases resources of shader manager.
|
||||||
Standard_EXPORT virtual ~OpenGl_ShaderManager();
|
Standard_EXPORT virtual ~OpenGl_ShaderManager();
|
||||||
|
|
||||||
//! Creates new shader program.
|
//! Creates new shader program or re-use shared instance.
|
||||||
Standard_EXPORT Handle(OpenGl_ShaderProgram) Create (const Handle(Graphic3d_ShaderProgram)& theProxyProgram = NULL);
|
//! @param theProxy [IN] program definition
|
||||||
|
//! @param theShareKey [OUT] sharing key
|
||||||
|
//! @param theProgram [OUT] OpenGL program
|
||||||
|
Standard_EXPORT void Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
|
||||||
|
TCollection_AsciiString& theShareKey,
|
||||||
|
Handle(OpenGl_ShaderProgram)& theProgram);
|
||||||
|
|
||||||
//! Unregisters specified shader program.
|
//! Unregisters specified shader program.
|
||||||
Standard_EXPORT void Unregister (Handle(OpenGl_ShaderProgram)& theProgram);
|
Standard_EXPORT void Unregister (TCollection_AsciiString& theShareKey,
|
||||||
|
Handle(OpenGl_ShaderProgram)& theProgram);
|
||||||
|
|
||||||
//! Returns list of registered shader programs.
|
//! Returns list of registered shader programs.
|
||||||
Standard_EXPORT const OpenGl_ShaderProgramList& ShaderPrograms() const;
|
Standard_EXPORT const OpenGl_ShaderProgramList& ShaderPrograms() const;
|
||||||
@ -155,6 +161,14 @@ public:
|
|||||||
//! Pushes current state of OCCT graphics parameters to specified program.
|
//! Pushes current state of OCCT graphics parameters to specified program.
|
||||||
Standard_EXPORT void PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
|
Standard_EXPORT void PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Overwrites context
|
||||||
|
void SetContext (OpenGl_Context* theCtx)
|
||||||
|
{
|
||||||
|
myContext = theCtx;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
OpenGl_ShaderProgramList myProgramList; //!< The list of shader programs
|
OpenGl_ShaderProgramList myProgramList; //!< The list of shader programs
|
||||||
|
@ -238,7 +238,8 @@ void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)&
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
|
OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
|
||||||
: myProgramID (NO_PROGRAM),
|
: myProgramID (NO_PROGRAM),
|
||||||
myProxy (theProxy)
|
myProxy (theProxy),
|
||||||
|
myShareCount(1)
|
||||||
{
|
{
|
||||||
memset (myCurrentState, 0, sizeof (myCurrentState));
|
memset (myCurrentState, 0, sizeof (myCurrentState));
|
||||||
for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
|
for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
|
||||||
@ -259,31 +260,15 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
|||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLchar *aShaderDir = getenv ("CSF_ShadersDirectory");
|
OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
|
||||||
if (aShaderDir == NULL)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSD_File aDeclFile (TCollection_AsciiString (aShaderDir) + "/Declarations.glsl");
|
|
||||||
if (!aDeclFile.Exists())
|
if (!aDeclFile.Exists())
|
||||||
{
|
{
|
||||||
TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
|
const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
|
||||||
|
|
||||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
||||||
GL_DEBUG_TYPE_ERROR_ARB,
|
GL_DEBUG_TYPE_ERROR_ARB,
|
||||||
0,
|
0,
|
||||||
GL_DEBUG_SEVERITY_HIGH_ARB,
|
GL_DEBUG_SEVERITY_HIGH_ARB,
|
||||||
aMsg);
|
aMsg);
|
||||||
|
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,14 +283,12 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
|||||||
{
|
{
|
||||||
if (!anIter.Value()->IsDone())
|
if (!anIter.Value()->IsDone())
|
||||||
{
|
{
|
||||||
TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
|
const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
|
||||||
|
|
||||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
||||||
GL_DEBUG_TYPE_ERROR_ARB,
|
GL_DEBUG_TYPE_ERROR_ARB,
|
||||||
0,
|
0,
|
||||||
GL_DEBUG_SEVERITY_HIGH_ARB,
|
GL_DEBUG_SEVERITY_HIGH_ARB,
|
||||||
aMsg);
|
aMsg);
|
||||||
|
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,23 +309,21 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
|||||||
if (aShader.IsNull())
|
if (aShader.IsNull())
|
||||||
{
|
{
|
||||||
TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
|
TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
|
||||||
|
|
||||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
||||||
GL_DEBUG_TYPE_ERROR_ARB,
|
GL_DEBUG_TYPE_ERROR_ARB,
|
||||||
0,
|
0,
|
||||||
GL_DEBUG_SEVERITY_HIGH_ARB,
|
GL_DEBUG_SEVERITY_HIGH_ARB,
|
||||||
aMsg);
|
aMsg);
|
||||||
|
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aShader->Create (theCtx))
|
if (!aShader->Create (theCtx))
|
||||||
{
|
{
|
||||||
|
aShader->Release (theCtx.operator->());
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
|
TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
|
||||||
|
|
||||||
if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX)
|
if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX)
|
||||||
{
|
{
|
||||||
aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
|
aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
|
||||||
@ -350,76 +331,83 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
|||||||
|
|
||||||
if (!aShader->LoadSource (theCtx, aSource))
|
if (!aShader->LoadSource (theCtx, aSource))
|
||||||
{
|
{
|
||||||
TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
|
const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
|
||||||
|
|
||||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
||||||
GL_DEBUG_TYPE_ERROR_ARB,
|
GL_DEBUG_TYPE_ERROR_ARB,
|
||||||
0,
|
0,
|
||||||
GL_DEBUG_SEVERITY_HIGH_ARB,
|
GL_DEBUG_SEVERITY_HIGH_ARB,
|
||||||
aMsg);
|
aMsg);
|
||||||
|
aShader->Release (theCtx.operator->());
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aShader->Compile (theCtx))
|
if (!aShader->Compile (theCtx))
|
||||||
{
|
{
|
||||||
TCollection_ExtendedString aMsg = "Error! Failed to compile shader object";
|
TCollection_AsciiString aLog;
|
||||||
|
aShader->FetchInfoLog (theCtx, aLog);
|
||||||
|
if (aLog.IsEmpty())
|
||||||
|
{
|
||||||
|
aLog = "Compilation log is empty.";
|
||||||
|
}
|
||||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
||||||
GL_DEBUG_TYPE_ERROR_ARB,
|
GL_DEBUG_TYPE_ERROR_ARB,
|
||||||
0,
|
0,
|
||||||
GL_DEBUG_SEVERITY_HIGH_ARB,
|
GL_DEBUG_SEVERITY_HIGH_ARB,
|
||||||
aMsg);
|
TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
|
||||||
|
aShader->Release (theCtx.operator->());
|
||||||
if (theCtx->caps->contextDebug)
|
|
||||||
{
|
|
||||||
TCollection_AsciiString aLog;
|
|
||||||
aShader->FetchInfoLog (theCtx, aLog);
|
|
||||||
if (!aLog.IsEmpty())
|
|
||||||
{
|
|
||||||
std::cout << aLog.ToCString() << std::endl << std::flush;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Information log is empty" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Standard_False;
|
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_ARB,
|
||||||
|
GL_DEBUG_TYPE_PORTABILITY_ARB,
|
||||||
|
0,
|
||||||
|
GL_DEBUG_SEVERITY_LOW_ARB,
|
||||||
|
TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!AttachShader (theCtx, aShader))
|
if (!AttachShader (theCtx, aShader))
|
||||||
{
|
{
|
||||||
|
aShader->Release (theCtx.operator->());
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Link (theCtx))
|
if (!Link (theCtx))
|
||||||
{
|
{
|
||||||
TCollection_ExtendedString aMsg = "Error! Failed to link program object";
|
TCollection_AsciiString aLog;
|
||||||
|
FetchInfoLog (theCtx, aLog);
|
||||||
|
if (aLog.IsEmpty())
|
||||||
|
{
|
||||||
|
aLog = "Linker log is empty.";
|
||||||
|
}
|
||||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
||||||
GL_DEBUG_TYPE_ERROR_ARB,
|
GL_DEBUG_TYPE_ERROR_ARB,
|
||||||
0,
|
0,
|
||||||
GL_DEBUG_SEVERITY_HIGH_ARB,
|
GL_DEBUG_SEVERITY_HIGH_ARB,
|
||||||
aMsg);
|
TCollection_ExtendedString ("Failed to link program object! Linker log:\n"));
|
||||||
|
|
||||||
if (theCtx->caps->contextDebug)
|
|
||||||
{
|
|
||||||
TCollection_AsciiString aLog;
|
|
||||||
FetchInfoLog (theCtx, aLog);
|
|
||||||
if (!aLog.IsEmpty())
|
|
||||||
{
|
|
||||||
std::cout << aLog.ToCString() << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Information log is empty" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Standard_False;
|
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_ARB,
|
||||||
|
GL_DEBUG_TYPE_PORTABILITY_ARB,
|
||||||
|
0,
|
||||||
|
GL_DEBUG_SEVERITY_LOW_ARB,
|
||||||
|
TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
|
@ -491,9 +491,27 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
GLuint myProgramID; //! Handle of OpenGL shader program
|
//! Increments counter of users.
|
||||||
OpenGl_ShaderList myShaderObjects; //! List of attached shader objects
|
//! Used by OpenGl_ShaderManager.
|
||||||
Handle(Graphic3d_ShaderProgram) myProxy; //! Proxy shader program (from application layer)
|
void Share()
|
||||||
|
{
|
||||||
|
++myShareCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Decrements counter of users.
|
||||||
|
//! Used by OpenGl_ShaderManager.
|
||||||
|
//! @return true when there are no more users of this program has been left
|
||||||
|
bool UnShare()
|
||||||
|
{
|
||||||
|
return --myShareCount == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
GLuint myProgramID; //!< Handle of OpenGL shader program
|
||||||
|
OpenGl_ShaderList myShaderObjects; //!< List of attached shader objects
|
||||||
|
Handle(Graphic3d_ShaderProgram) myProxy; //!< Proxy shader program (from application layer)
|
||||||
|
Standard_Integer myShareCount; //!< program users count, initialized with 1 (already shared by one user)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
// purpose or non-infringement. Please see the License for the specific terms
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
// and conditions governing the rights and limitations under the License.
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
@ -28,6 +27,7 @@
|
|||||||
#include <OpenGl_Display.hxx>
|
#include <OpenGl_Display.hxx>
|
||||||
#include <OpenGl_GlCore11.hxx>
|
#include <OpenGl_GlCore11.hxx>
|
||||||
#include <OpenGl_GraduatedTrihedron.hxx>
|
#include <OpenGl_GraduatedTrihedron.hxx>
|
||||||
|
#include <OpenGl_GraphicDriver.hxx>
|
||||||
#include <OpenGl_ShaderManager.hxx>
|
#include <OpenGl_ShaderManager.hxx>
|
||||||
#include <OpenGl_Texture.hxx>
|
#include <OpenGl_Texture.hxx>
|
||||||
#include <OpenGl_Trihedron.hxx>
|
#include <OpenGl_Trihedron.hxx>
|
||||||
@ -87,7 +87,8 @@ static const GLdouble THE_IDENTITY_MATRIX[4][4] =
|
|||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
|
OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
|
||||||
|
OpenGl_StateCounter* theCounter)
|
||||||
: mySurfaceDetail(Visual3d_TOD_NONE),
|
: mySurfaceDetail(Visual3d_TOD_NONE),
|
||||||
myBackfacing(0),
|
myBackfacing(0),
|
||||||
myBgTexture(myDefaultBgTexture),
|
myBgTexture(myDefaultBgTexture),
|
||||||
@ -109,9 +110,10 @@ OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
|
|||||||
myAntiAliasing(Standard_False),
|
myAntiAliasing(Standard_False),
|
||||||
myTransPers(&myDefaultTransPers),
|
myTransPers(&myDefaultTransPers),
|
||||||
myIsTransPers(Standard_False),
|
myIsTransPers(Standard_False),
|
||||||
myOrientationChanged (Standard_True),
|
myStateCounter (theCounter),
|
||||||
myViewMappingChanged (Standard_True),
|
myLastOrientationState (0, 0),
|
||||||
myLightSourcesChanged (Standard_True)
|
myLastViewMappingState (0, 0),
|
||||||
|
myLastLightSourceState (0, 0)
|
||||||
{
|
{
|
||||||
// Initialize matrices
|
// Initialize matrices
|
||||||
memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
|
memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
|
||||||
@ -129,6 +131,10 @@ OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myCurrOrientationState = myStateCounter->Increment(); // <-- delete after merge with camera
|
||||||
|
myCurrViewMappingState = myStateCounter->Increment(); // <-- delete after merge with camera
|
||||||
|
myCurrLightSourceState = myStateCounter->Increment();
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
#ifdef HAVE_OPENCL
|
||||||
myModificationState = 1; // initial state
|
myModificationState = 1; // initial state
|
||||||
#endif
|
#endif
|
||||||
@ -268,7 +274,7 @@ void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext)
|
|||||||
myLights.Append(rep);
|
myLights.Append(rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
myLightSourcesChanged = Standard_True;
|
myCurrLightSourceState = myStateCounter->Increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
@ -381,7 +387,7 @@ void OpenGl_View::SetMapping (const Handle(OpenGl_Display)& theGlDisplay,
|
|||||||
if (!err_ind)
|
if (!err_ind)
|
||||||
myExtra.map = Map;
|
myExtra.map = Map;
|
||||||
|
|
||||||
myViewMappingChanged = Standard_True;
|
myCurrViewMappingState = myStateCounter->Increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
@ -444,7 +450,7 @@ void OpenGl_View::SetOrientation (const Graphic3d_CView& theCView)
|
|||||||
myExtra.scaleFactors[2] = ScaleFactors[2];
|
myExtra.scaleFactors[2] = ScaleFactors[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
myOrientationChanged = Standard_True;
|
myCurrOrientationState = myStateCounter->Increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include <OpenGl_Light.hxx>
|
#include <OpenGl_Light.hxx>
|
||||||
|
|
||||||
#include <Handle_OpenGl_Context.hxx>
|
#include <Handle_OpenGl_Context.hxx>
|
||||||
|
#include <Handle_OpenGl_GraphicDriver.hxx>
|
||||||
#include <Handle_OpenGl_Display.hxx>
|
#include <Handle_OpenGl_Display.hxx>
|
||||||
#include <Handle_OpenGl_Workspace.hxx>
|
#include <Handle_OpenGl_Workspace.hxx>
|
||||||
#include <Handle_OpenGl_View.hxx>
|
#include <Handle_OpenGl_View.hxx>
|
||||||
@ -98,11 +99,12 @@ class OpenGl_GraduatedTrihedron;
|
|||||||
class OpenGl_Structure;
|
class OpenGl_Structure;
|
||||||
class OpenGl_Trihedron;
|
class OpenGl_Trihedron;
|
||||||
class Handle(OpenGl_PrinterContext);
|
class Handle(OpenGl_PrinterContext);
|
||||||
|
class OpenGl_StateCounter;
|
||||||
|
|
||||||
class OpenGl_View : public MMgt_TShared
|
class OpenGl_View : public MMgt_TShared
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext);
|
OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext, OpenGl_StateCounter* theCounter);
|
||||||
virtual ~OpenGl_View ();
|
virtual ~OpenGl_View ();
|
||||||
|
|
||||||
void ReleaseGlResources (const Handle(OpenGl_Context)& theCtx);
|
void ReleaseGlResources (const Handle(OpenGl_Context)& theCtx);
|
||||||
@ -265,10 +267,17 @@ public:
|
|||||||
const TEL_TRANSFORM_PERSISTENCE *myTransPers;
|
const TEL_TRANSFORM_PERSISTENCE *myTransPers;
|
||||||
Standard_Boolean myIsTransPers;
|
Standard_Boolean myIsTransPers;
|
||||||
|
|
||||||
//! Modification flags.
|
OpenGl_StateCounter* myStateCounter;
|
||||||
Standard_Boolean myOrientationChanged;
|
|
||||||
Standard_Boolean myViewMappingChanged;
|
Standard_Size myCurrOrientationState; // <-- delete it after merge with new camera
|
||||||
Standard_Boolean myLightSourcesChanged;
|
Standard_Size myCurrViewMappingState; // <-- delete it after merge with new camera
|
||||||
|
Standard_Size myCurrLightSourceState;
|
||||||
|
|
||||||
|
typedef std::pair<Standard_Size, Standard_Size> StateInfo;
|
||||||
|
|
||||||
|
StateInfo myLastOrientationState;
|
||||||
|
StateInfo myLastViewMappingState;
|
||||||
|
StateInfo myLastLightSourceState;
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
#ifdef HAVE_OPENCL
|
||||||
Standard_Size myModificationState;
|
Standard_Size myModificationState;
|
||||||
|
@ -865,36 +865,30 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set OCCT state uniform variables
|
// Set OCCT state uniform variables
|
||||||
|
const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
|
||||||
if (!aContext->ShaderManager()->IsEmpty())
|
if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
|
||||||
{
|
{
|
||||||
if (myLightSourcesChanged)
|
aManager->UpdateLightSourceStateTo (&myLights);
|
||||||
{
|
myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
|
||||||
aContext->ShaderManager()->UpdateLightSourceStateTo (&myLights);
|
}
|
||||||
myLightSourcesChanged = Standard_False;
|
if (StateInfo (myCurrViewMappingState, aManager->ProjectionState().Index()) != myLastViewMappingState)
|
||||||
}
|
{
|
||||||
|
aManager->UpdateProjectionStateTo (myMappingMatrix);
|
||||||
if (myViewMappingChanged)
|
myLastViewMappingState = StateInfo (myCurrViewMappingState, aManager->ProjectionState().Index());
|
||||||
{
|
}
|
||||||
aContext->ShaderManager()->UpdateProjectionStateTo (myMappingMatrix);
|
if (StateInfo (myCurrOrientationState, aManager->WorldViewState().Index()) != myLastOrientationState)
|
||||||
myViewMappingChanged = Standard_False;
|
{
|
||||||
}
|
aManager->UpdateWorldViewStateTo (myOrientationMatrix);
|
||||||
|
myLastOrientationState = StateInfo (myCurrOrientationState, aManager->WorldViewState().Index());
|
||||||
if (myOrientationChanged)
|
}
|
||||||
{
|
if (aManager->ModelWorldState().Index() == 0)
|
||||||
aContext->ShaderManager()->UpdateWorldViewStateTo (myOrientationMatrix);
|
{
|
||||||
myOrientationChanged = Standard_False;
|
Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
|
||||||
}
|
{ 0.f, 1.f, 0.f, 0.f },
|
||||||
|
{ 0.f, 0.f, 1.f, 0.f },
|
||||||
if (aContext->ShaderManager()->ModelWorldState().Index() == 0)
|
{ 0.f, 0.f, 0.f, 1.f } };
|
||||||
{
|
|
||||||
Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
|
aManager->UpdateModelWorldStateTo (aModelWorldState);
|
||||||
{ 0.f, 1.f, 0.f, 0.f },
|
|
||||||
{ 0.f, 0.f, 1.f, 0.f },
|
|
||||||
{ 0.f, 0.f, 0.f, 1.f } };
|
|
||||||
|
|
||||||
aContext->ShaderManager()->UpdateModelWorldStateTo (aModelWorldState);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1100,9 +1094,9 @@ D = -[Px,Py,Pz] dot |Nx|
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aContext->ShaderManager()->IsEmpty())
|
if (!aManager->IsEmpty())
|
||||||
{
|
{
|
||||||
aContext->ShaderManager()->UpdateClippingState();
|
aManager->UpdateClippingState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1191,10 +1185,15 @@ D = -[Px,Py,Pz] dot |Nx|
|
|||||||
|
|
||||||
aContext->ChangeClipping().RemoveAll();
|
aContext->ChangeClipping().RemoveAll();
|
||||||
|
|
||||||
if (!aContext->ShaderManager()->IsEmpty())
|
if (!aManager->IsEmpty())
|
||||||
{
|
{
|
||||||
aContext->ShaderManager()->ResetMaterialStates();
|
aManager->ResetMaterialStates();
|
||||||
aContext->ShaderManager()->RevertClippingState();
|
aManager->RevertClippingState();
|
||||||
|
|
||||||
|
// We need to disable (unbind) all shaders programs to ensure
|
||||||
|
// that all objects without specified aspect will be drawn
|
||||||
|
// correctly (such as background)
|
||||||
|
OpenGl_ShaderProgram::Unbind (aContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
// display global trihedron
|
// display global trihedron
|
||||||
|
@ -459,9 +459,13 @@ const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix (const OpenGl_Matrix
|
|||||||
if (!myGlContext->ShaderManager()->IsEmpty())
|
if (!myGlContext->ShaderManager()->IsEmpty())
|
||||||
{
|
{
|
||||||
if (aRevert)
|
if (aRevert)
|
||||||
myGlContext->ShaderManager()->UpdateModelWorldStateTo (lmat.mat);
|
{
|
||||||
else
|
|
||||||
myGlContext->ShaderManager()->RevertModelWorldStateTo (lmat.mat);
|
myGlContext->ShaderManager()->RevertModelWorldStateTo (lmat.mat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myGlContext->ShaderManager()->UpdateModelWorldStateTo (lmat.mat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return StructureMatrix_old;
|
return StructureMatrix_old;
|
||||||
|
170
src/Shaders/PhongShading.fs
Normal file
170
src/Shaders/PhongShading.fs
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
// Created on: 2013-10-10
|
||||||
|
// Created by: Denis BOGOLEPOV
|
||||||
|
// Copyright (c) 2013 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.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
//! Direction to the viewer.
|
||||||
|
varying vec3 View;
|
||||||
|
|
||||||
|
//! Vertex normal in view space.
|
||||||
|
varying vec3 Normal;
|
||||||
|
|
||||||
|
//! Vertex position in view space.
|
||||||
|
varying vec4 Position;
|
||||||
|
|
||||||
|
|
||||||
|
//! Ambient contribution of light sources.
|
||||||
|
vec3 Ambient;
|
||||||
|
|
||||||
|
//! Diffuse contribution of light sources.
|
||||||
|
vec3 Diffuse;
|
||||||
|
|
||||||
|
//! Specular contribution of light sources.
|
||||||
|
vec3 Specular;
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : AmbientLight
|
||||||
|
// purpose : Computes contribution of OCCT pure ambient light source
|
||||||
|
// =======================================================================
|
||||||
|
void AmbientLight (in int theIndex)
|
||||||
|
{
|
||||||
|
Ambient += occLightSources[theIndex].Ambient;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : PointLight
|
||||||
|
// purpose : Computes contribution of OCCT isotropic point light source
|
||||||
|
// =======================================================================
|
||||||
|
void PointLight (in int theIndex,
|
||||||
|
in vec3 theNormal,
|
||||||
|
in vec3 theView,
|
||||||
|
in vec3 thePoint)
|
||||||
|
{
|
||||||
|
vec3 aLight = occLightSources[theIndex].Position;
|
||||||
|
if (occLightSources[theIndex].Head == 0)
|
||||||
|
{
|
||||||
|
aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0));
|
||||||
|
}
|
||||||
|
aLight -= thePoint;
|
||||||
|
|
||||||
|
float aDist = length (aLight);
|
||||||
|
aLight = aLight * (1.0 / aDist);
|
||||||
|
|
||||||
|
float anAttenuation = 1.0 / (occLightSources[theIndex].ConstAttenuation +
|
||||||
|
occLightSources[theIndex].LinearAttenuation * aDist);
|
||||||
|
|
||||||
|
vec3 aHalf = normalize (aLight + theView);
|
||||||
|
|
||||||
|
float aNdotL = max (0.0, dot (theNormal, aLight));
|
||||||
|
float aNdotH = max (0.0, dot (theNormal, aHalf));
|
||||||
|
|
||||||
|
float aSpecl = 0.0;
|
||||||
|
if (aNdotL > 0.0)
|
||||||
|
{
|
||||||
|
aSpecl = pow (aNdotH, occFrontMaterial.Shininess);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ambient += occLightSources[theIndex].Ambient * anAttenuation;
|
||||||
|
Diffuse += occLightSources[theIndex].Diffuse * aNdotL * anAttenuation;
|
||||||
|
Specular += occLightSources[theIndex].Specular * aSpecl * anAttenuation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : DirectionalLight
|
||||||
|
// purpose : Computes contribution of OCCT directional light source
|
||||||
|
// =======================================================================
|
||||||
|
void DirectionalLight (in int theIndex,
|
||||||
|
in vec3 theNormal,
|
||||||
|
in vec3 theView)
|
||||||
|
{
|
||||||
|
vec3 aLight = normalize (occLightSources[theIndex].Position);
|
||||||
|
|
||||||
|
if (occLightSources[theIndex].Head == 0)
|
||||||
|
{
|
||||||
|
aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 aHalf = normalize (aLight + theView);
|
||||||
|
|
||||||
|
float aNdotL = max (0.0, dot (theNormal, aLight));
|
||||||
|
float aNdotH = max (0.0, dot (theNormal, aHalf));
|
||||||
|
|
||||||
|
float aSpecl = 0.0;
|
||||||
|
|
||||||
|
if (aNdotL > 0.0)
|
||||||
|
{
|
||||||
|
aSpecl = pow (aNdotH, occFrontMaterial.Shininess);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ambient += occLightSources[theIndex].Ambient;
|
||||||
|
Diffuse += occLightSources[theIndex].Diffuse * aNdotL;
|
||||||
|
Specular += occLightSources[theIndex].Specular * aSpecl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ComputeLighting
|
||||||
|
// purpose : Computes illumination from OCCT light sources
|
||||||
|
// =======================================================================
|
||||||
|
vec4 ComputeLighting (in vec3 theNormal,
|
||||||
|
in vec3 theView,
|
||||||
|
in vec4 thePoint)
|
||||||
|
{
|
||||||
|
// Clear the light intensity accumulators
|
||||||
|
Ambient = vec3 (0.0);
|
||||||
|
Diffuse = vec3 (0.0);
|
||||||
|
Specular = vec3 (0.0);
|
||||||
|
|
||||||
|
vec3 aPoint = thePoint.xyz / thePoint.w;
|
||||||
|
|
||||||
|
for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)
|
||||||
|
{
|
||||||
|
occLightSource light = occLightSources[anIndex];
|
||||||
|
|
||||||
|
if (light.Type == occAmbientLight)
|
||||||
|
{
|
||||||
|
AmbientLight (anIndex);
|
||||||
|
}
|
||||||
|
else if (light.Type == occDirectLight)
|
||||||
|
{
|
||||||
|
DirectionalLight (anIndex, theNormal, theView);
|
||||||
|
}
|
||||||
|
else if (light.Type == occPointLight)
|
||||||
|
{
|
||||||
|
PointLight (anIndex, theNormal, theView, aPoint);
|
||||||
|
}
|
||||||
|
else if (light.Type == occSpotLight)
|
||||||
|
{
|
||||||
|
/* Not implemented */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec4 (Ambient, 1.0) * occFrontMaterial.Ambient +
|
||||||
|
vec4 (Diffuse, 1.0) * occFrontMaterial.Diffuse +
|
||||||
|
vec4 (Specular, 1.0) * occFrontMaterial.Specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : main
|
||||||
|
// purpose : Entry point to the fragment shader
|
||||||
|
// =======================================================================
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = ComputeLighting (normalize (Normal),
|
||||||
|
normalize (View),
|
||||||
|
Position);
|
||||||
|
}
|
60
src/Shaders/PhongShading.vs
Normal file
60
src/Shaders/PhongShading.vs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Created on: 2013-10-10
|
||||||
|
// Created by: Denis BOGOLEPOV
|
||||||
|
// Copyright (c) 2013 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.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
//! Direction to the viewer.
|
||||||
|
varying vec3 View;
|
||||||
|
|
||||||
|
//! Vertex normal in view space.
|
||||||
|
varying vec3 Normal;
|
||||||
|
|
||||||
|
//! Vertex position in view space.
|
||||||
|
varying vec4 Position;
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : TransformNormal
|
||||||
|
// purpose : Computes the normal in view space
|
||||||
|
// =======================================================================
|
||||||
|
vec3 TransformNormal (in vec3 theNormal)
|
||||||
|
{
|
||||||
|
vec4 aResult = occWorldViewMatrixInverseTranspose *
|
||||||
|
occModelWorldMatrixInverseTranspose * vec4 (theNormal, 0.0);
|
||||||
|
|
||||||
|
return normalize (aResult.xyz);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : main
|
||||||
|
// purpose : Entry point to the vertex shader
|
||||||
|
// =======================================================================
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Compute vertex position in the view space
|
||||||
|
Position = occWorldViewMatrix * occModelWorldMatrix * occVertex;
|
||||||
|
|
||||||
|
// Compute vertex normal in the view space
|
||||||
|
Normal = TransformNormal (occNormal);
|
||||||
|
|
||||||
|
// Note: The specified view vector is absolutely correct only for the orthogonal
|
||||||
|
// projection. For perspective projection it will be approximate, but it is in
|
||||||
|
// good agreement with the OpenGL calculations
|
||||||
|
View = vec3 (0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
// Do fixed functionality vertex transform
|
||||||
|
gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;
|
||||||
|
}
|
@ -32,9 +32,6 @@
|
|||||||
#include <TopLoc_Location.hxx>
|
#include <TopLoc_Location.hxx>
|
||||||
#include <TopTools_HArray1OfShape.hxx>
|
#include <TopTools_HArray1OfShape.hxx>
|
||||||
#include <TColStd_HArray1OfTransient.hxx>
|
#include <TColStd_HArray1OfTransient.hxx>
|
||||||
#include <OSD_Directory.hxx>
|
|
||||||
#include <OSD_File.hxx>
|
|
||||||
#include <OSD_Path.hxx>
|
|
||||||
#include <OSD_Timer.hxx>
|
#include <OSD_Timer.hxx>
|
||||||
#include <Geom_Axis2Placement.hxx>
|
#include <Geom_Axis2Placement.hxx>
|
||||||
#include <Geom_Axis1Placement.hxx>
|
#include <Geom_Axis1Placement.hxx>
|
||||||
@ -54,10 +51,8 @@
|
|||||||
#include <AIS_ListIteratorOfListOfInteractive.hxx>
|
#include <AIS_ListIteratorOfListOfInteractive.hxx>
|
||||||
#include <Aspect_InteriorStyle.hxx>
|
#include <Aspect_InteriorStyle.hxx>
|
||||||
#include <Graphic3d_AspectFillArea3d.hxx>
|
#include <Graphic3d_AspectFillArea3d.hxx>
|
||||||
#include <Graphic3d_TextureRoot.hxx>
|
|
||||||
#include <Graphic3d_AspectLine3d.hxx>
|
#include <Graphic3d_AspectLine3d.hxx>
|
||||||
#include <Graphic3d_ShaderObject.hxx>
|
#include <Graphic3d_TextureRoot.hxx>
|
||||||
#include <Graphic3d_ShaderProgram.hxx>
|
|
||||||
#include <Image_AlienPixMap.hxx>
|
#include <Image_AlienPixMap.hxx>
|
||||||
#include <Prs3d_ShadingAspect.hxx>
|
#include <Prs3d_ShadingAspect.hxx>
|
||||||
#include <Prs3d_IsoAspect.hxx>
|
#include <Prs3d_IsoAspect.hxx>
|
||||||
@ -1899,64 +1894,6 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
//function : VShaderProg
|
|
||||||
//purpose : Sets the pair of vertex and fragment shaders for the object
|
|
||||||
//==============================================================================
|
|
||||||
static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
|
|
||||||
Standard_Integer theArgNb,
|
|
||||||
const char** theArgVec)
|
|
||||||
{
|
|
||||||
Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
|
|
||||||
if (anAISContext.IsNull())
|
|
||||||
{
|
|
||||||
std::cerr << "Use 'vinit' command before " << theArgVec[0] << "\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theArgNb < 3)
|
|
||||||
{
|
|
||||||
std::cerr << theArgVec[0] <<" syntax error: lack of arguments - Type 'help vshaderprog\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TCollection_AsciiString aShapeName = theArgVec[1];
|
|
||||||
if (!GetMapOfAIS().IsBound2 (aShapeName))
|
|
||||||
{
|
|
||||||
std::cerr << theArgVec[0] << ": Use 'vdisplay' before\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aShapeName));
|
|
||||||
if (anIO.IsNull())
|
|
||||||
{
|
|
||||||
std::cerr << "Shape " << aShapeName.ToCString() << " does not exist\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram();
|
|
||||||
const TCollection_AsciiString aVertexSource (theArgVec[2]);
|
|
||||||
if (!aVertexSource.IsEmpty() && !OSD_File(aVertexSource).Exists())
|
|
||||||
{
|
|
||||||
std::cerr << "Non-existing vertex shader source\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
TCollection_AsciiString aFragmentSource (theArgVec[3]);
|
|
||||||
if (!aFragmentSource.IsEmpty() && !OSD_File(aFragmentSource).Exists())
|
|
||||||
{
|
|
||||||
std::cerr << "Non-existing fragment shader source\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aVertexSource));
|
|
||||||
aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aFragmentSource));
|
|
||||||
anIO->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
|
|
||||||
|
|
||||||
anAISContext->Redisplay (anIO);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
//function : VDisplay2
|
//function : VDisplay2
|
||||||
//author : ege
|
//author : ege
|
||||||
@ -3341,10 +3278,6 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
|
|||||||
or 'vtexture NameOfShape IdOfTexture' (0<=IdOfTexture<=20)' to use predefined textures\n ",
|
or 'vtexture NameOfShape IdOfTexture' (0<=IdOfTexture<=20)' to use predefined textures\n ",
|
||||||
__FILE__,VTexture,group);
|
__FILE__,VTexture,group);
|
||||||
|
|
||||||
theCommands.Add("vshaderprog",
|
|
||||||
"'vshaderprog NameOfShape VertexShaderFile FragmentShaderFile'",
|
|
||||||
__FILE__,VShaderProg,group);
|
|
||||||
|
|
||||||
theCommands.Add("vtexscale",
|
theCommands.Add("vtexscale",
|
||||||
"'vtexscale NameOfShape ScaleU ScaleV' \n \
|
"'vtexscale NameOfShape ScaleU ScaleV' \n \
|
||||||
or 'vtexscale NameOfShape ScaleUV' \n \
|
or 'vtexscale NameOfShape ScaleUV' \n \
|
||||||
|
@ -23,11 +23,14 @@
|
|||||||
|
|
||||||
#include <ViewerTest.hxx>
|
#include <ViewerTest.hxx>
|
||||||
|
|
||||||
|
#include <AIS_Drawer.hxx>
|
||||||
#include <AIS_InteractiveContext.hxx>
|
#include <AIS_InteractiveContext.hxx>
|
||||||
#include <AIS_InteractiveObject.hxx>
|
#include <AIS_InteractiveObject.hxx>
|
||||||
#include <Draw.hxx>
|
#include <Draw.hxx>
|
||||||
#include <Draw_Interpretor.hxx>
|
#include <Draw_Interpretor.hxx>
|
||||||
#include <Graphic3d_Group.hxx>
|
#include <Graphic3d_Group.hxx>
|
||||||
|
#include <Graphic3d_ShaderObject.hxx>
|
||||||
|
#include <Graphic3d_ShaderProgram.hxx>
|
||||||
#include <OpenGl_ArbVBO.hxx>
|
#include <OpenGl_ArbVBO.hxx>
|
||||||
#include <OpenGl_AspectFace.hxx>
|
#include <OpenGl_AspectFace.hxx>
|
||||||
#include <OpenGl_AspectLine.hxx>
|
#include <OpenGl_AspectLine.hxx>
|
||||||
@ -39,19 +42,25 @@
|
|||||||
#include <OpenGl_GlCore20.hxx>
|
#include <OpenGl_GlCore20.hxx>
|
||||||
#include <OpenGl_GraphicDriver.hxx>
|
#include <OpenGl_GraphicDriver.hxx>
|
||||||
#include <OpenGl_Workspace.hxx>
|
#include <OpenGl_Workspace.hxx>
|
||||||
|
#include <OSD_Environment.hxx>
|
||||||
|
#include <OSD_File.hxx>
|
||||||
#include <Prs3d_Presentation.hxx>
|
#include <Prs3d_Presentation.hxx>
|
||||||
#include <Prs3d_Root.hxx>
|
#include <Prs3d_Root.hxx>
|
||||||
|
#include <Prs3d_ShadingAspect.hxx>
|
||||||
#include <Select3D_SensitiveCurve.hxx>
|
#include <Select3D_SensitiveCurve.hxx>
|
||||||
#include <SelectMgr_EntityOwner.hxx>
|
#include <SelectMgr_EntityOwner.hxx>
|
||||||
#include <SelectMgr_Selection.hxx>
|
#include <SelectMgr_Selection.hxx>
|
||||||
#include <V3d_Viewer.hxx>
|
|
||||||
#include <TCollection_AsciiString.hxx>
|
#include <TCollection_AsciiString.hxx>
|
||||||
#include <V3d_View.hxx>
|
#include <V3d_View.hxx>
|
||||||
|
#include <V3d_Viewer.hxx>
|
||||||
#include <Visual3d_View.hxx>
|
#include <Visual3d_View.hxx>
|
||||||
|
#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
|
||||||
|
#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
|
||||||
|
|
||||||
extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
|
extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
|
||||||
const Handle(AIS_InteractiveObject)& theAISObj,
|
const Handle(AIS_InteractiveObject)& theAISObj,
|
||||||
Standard_Boolean theReplaceIfExists = Standard_True);
|
Standard_Boolean theReplaceIfExists = Standard_True);
|
||||||
|
extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : VUserDraw
|
//function : VUserDraw
|
||||||
@ -505,6 +514,107 @@ static int VGlInfo (Draw_Interpretor& theDI,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
//function : VShaderProg
|
||||||
|
//purpose : Sets the pair of vertex and fragment shaders for the object
|
||||||
|
//==============================================================================
|
||||||
|
static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
|
||||||
|
Standard_Integer theArgNb,
|
||||||
|
const char** theArgVec)
|
||||||
|
{
|
||||||
|
Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
|
||||||
|
if (aCtx.IsNull())
|
||||||
|
{
|
||||||
|
std::cerr << "Use 'vinit' command before " << theArgVec[0] << "\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (theArgNb < 2)
|
||||||
|
{
|
||||||
|
std::cerr << theArgVec[0] << " syntax error: lack of arguments\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TCollection_AsciiString aLastArg (theArgVec[theArgNb - 1]);
|
||||||
|
aLastArg.UpperCase();
|
||||||
|
const Standard_Boolean toTurnOff = aLastArg == "OFF";
|
||||||
|
Standard_Integer anArgsNb = theArgNb - 1;
|
||||||
|
Handle(Graphic3d_ShaderProgram) aProgram;
|
||||||
|
if (!toTurnOff
|
||||||
|
&& aLastArg == "PHONG")
|
||||||
|
{
|
||||||
|
aProgram = new Graphic3d_ShaderProgram (Graphic3d_ShaderProgram::ShaderName_Phong);
|
||||||
|
}
|
||||||
|
if (!toTurnOff
|
||||||
|
&& aProgram.IsNull())
|
||||||
|
{
|
||||||
|
if (theArgNb < 3)
|
||||||
|
{
|
||||||
|
std::cerr << theArgVec[0] << " syntax error: lack of arguments\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TCollection_AsciiString aSrcVert = theArgVec[theArgNb - 2];
|
||||||
|
const TCollection_AsciiString aSrcFrag = theArgVec[theArgNb - 1];
|
||||||
|
if (!aSrcVert.IsEmpty()
|
||||||
|
&& !OSD_File (aSrcVert).Exists())
|
||||||
|
{
|
||||||
|
std::cerr << "Non-existing vertex shader source\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!aSrcFrag.IsEmpty()
|
||||||
|
&& !OSD_File (aSrcFrag).Exists())
|
||||||
|
{
|
||||||
|
std::cerr << "Non-existing fragment shader source\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
aProgram = new Graphic3d_ShaderProgram();
|
||||||
|
aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||||
|
aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||||
|
anArgsNb = theArgNb - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle(AIS_InteractiveObject) anIO;
|
||||||
|
if (anArgsNb <= 1
|
||||||
|
|| *theArgVec[1] == '*')
|
||||||
|
{
|
||||||
|
for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
|
||||||
|
anIter.More(); anIter.Next())
|
||||||
|
{
|
||||||
|
anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
|
||||||
|
if (!anIO.IsNull())
|
||||||
|
{
|
||||||
|
anIO->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
|
||||||
|
aCtx->Redisplay (anIO, Standard_False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aCtx->UpdateCurrentViewer();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Standard_Integer anArgIter = 1; anArgIter < anArgsNb; ++anArgIter)
|
||||||
|
{
|
||||||
|
const TCollection_AsciiString aName (theArgVec[anArgIter]);
|
||||||
|
if (!GetMapOfAIS().IsBound2 (aName))
|
||||||
|
{
|
||||||
|
std::cerr << "Warning: " << aName.ToCString() << " is not displayed\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
|
||||||
|
if (anIO.IsNull())
|
||||||
|
{
|
||||||
|
std::cerr << "Warning: " << aName.ToCString() << " is not an AIS object\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
anIO->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
|
||||||
|
aCtx->Redisplay (anIO, Standard_False);
|
||||||
|
}
|
||||||
|
|
||||||
|
aCtx->UpdateCurrentViewer();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : OpenGlCommands
|
//function : OpenGlCommands
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -523,9 +633,14 @@ void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands)
|
|||||||
theCommands.Add("vimmediatefront",
|
theCommands.Add("vimmediatefront",
|
||||||
"vimmediatefront : render immediate mode to front buffer or to back buffer",
|
"vimmediatefront : render immediate mode to front buffer or to back buffer",
|
||||||
__FILE__, VImmediateFront, aGroup);
|
__FILE__, VImmediateFront, aGroup);
|
||||||
|
|
||||||
theCommands.Add("vglinfo",
|
theCommands.Add("vglinfo",
|
||||||
"vglinfo [GL_VENDOR] [GL_RENDERER] [GL_VERSION] [GL_SHADING_LANGUAGE_VERSION] [GL_EXTENSIONS]"
|
"vglinfo [GL_VENDOR] [GL_RENDERER] [GL_VERSION] [GL_SHADING_LANGUAGE_VERSION] [GL_EXTENSIONS]"
|
||||||
" : prints GL info",
|
" : prints GL info",
|
||||||
__FILE__, VGlInfo, aGroup);
|
__FILE__, VGlInfo, aGroup);
|
||||||
|
theCommands.Add("vshaderprog",
|
||||||
|
" 'vshaderprog [name] pathToVertexShader pathToFragmentShader'"
|
||||||
|
"\n\t\t: or 'vshaderprog [name] off' to disable GLSL program"
|
||||||
|
"\n\t\t: or 'vshaderprog [name] phong' to enable per-pixel lighting calculations"
|
||||||
|
"\n\t\t: * might be used to specify all displayed objects",
|
||||||
|
__FILE__, VShaderProg, aGroup);
|
||||||
}
|
}
|
||||||
|
@ -724,12 +724,12 @@ void ViewerTest::RedrawAllViews()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
//function : SplitParameter
|
//function : splitParameter
|
||||||
//purpose : Split parameter string to parameter name an patameter value
|
//purpose : Split parameter string to parameter name an parameter value
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
Standard_Boolean SplitParameter (const TCollection_AsciiString& theString,
|
Standard_Boolean splitParameter (const TCollection_AsciiString& theString,
|
||||||
TCollection_AsciiString& theName,
|
TCollection_AsciiString& theName,
|
||||||
TCollection_AsciiString& theValue)
|
TCollection_AsciiString& theValue)
|
||||||
{
|
{
|
||||||
Standard_Integer aParamNameEnd = theString.FirstLocationInSet("=",1, theString.Length());
|
Standard_Integer aParamNameEnd = theString.FirstLocationInSet("=",1, theString.Length());
|
||||||
if (aParamNameEnd == 0)
|
if (aParamNameEnd == 0)
|
||||||
@ -768,7 +768,7 @@ if (theArgsNb > 9)
|
|||||||
for (Standard_Integer i = 1; i < theArgsNb; ++i)
|
for (Standard_Integer i = 1; i < theArgsNb; ++i)
|
||||||
{
|
{
|
||||||
TCollection_AsciiString aName = "", aValue = "";
|
TCollection_AsciiString aName = "", aValue = "";
|
||||||
if(!SplitParameter (TCollection_AsciiString(theArgVec[i]),aName,aValue) && theArgsNb == 2)
|
if(!splitParameter (TCollection_AsciiString(theArgVec[i]),aName,aValue) && theArgsNb == 2)
|
||||||
{
|
{
|
||||||
// In case of syntax: vinit ViewName
|
// In case of syntax: vinit ViewName
|
||||||
aViewName = theArgVec[1];
|
aViewName = theArgVec[1];
|
||||||
@ -5276,6 +5276,83 @@ static int VSetTextureMode (Draw_Interpretor& theDi, Standard_Integer theArgsNb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===============================================================================================
|
||||||
|
//function : VDefaults
|
||||||
|
//purpose :
|
||||||
|
//===============================================================================================
|
||||||
|
static int VDefaults (Draw_Interpretor& theDi,
|
||||||
|
Standard_Integer theArgsNb,
|
||||||
|
const char** theArgVec)
|
||||||
|
{
|
||||||
|
const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
|
||||||
|
if (aCtx.IsNull())
|
||||||
|
{
|
||||||
|
std::cerr << "No active viewer!\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
|
||||||
|
if (theArgsNb < 2)
|
||||||
|
{
|
||||||
|
if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
|
||||||
|
{
|
||||||
|
theDi << "DeflType: relative\n"
|
||||||
|
<< "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theDi << "DeflType: absolute\n"
|
||||||
|
<< "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
|
||||||
|
}
|
||||||
|
theDi << "AngularDeflection: " << (180.0 * aDefParams->HLRAngle() / M_PI) << "\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
||||||
|
{
|
||||||
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
||||||
|
TCollection_AsciiString aKey, aValue;
|
||||||
|
if (!splitParameter (anArg, aKey, aValue)
|
||||||
|
|| aValue.IsEmpty())
|
||||||
|
{
|
||||||
|
std::cerr << "Error, wrong syntax at: '" << anArg.ToCString() << "'!\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
aKey.UpperCase();
|
||||||
|
if (aKey == "ABSDEFL"
|
||||||
|
|| aKey == "ABSOLUTEDEFLECTION"
|
||||||
|
|| aKey == "DEFL"
|
||||||
|
|| aKey == "DEFLECTION")
|
||||||
|
{
|
||||||
|
aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
|
||||||
|
aDefParams->SetMaximalChordialDeviation (aValue.RealValue());
|
||||||
|
}
|
||||||
|
else if (aKey == "RELDEFL"
|
||||||
|
|| aKey == "RELATIVEDEFLECTION"
|
||||||
|
|| aKey == "DEVCOEFF"
|
||||||
|
|| aKey == "DEVIATIONCOEFF"
|
||||||
|
|| aKey == "DEVIATIONCOEFFICIENT")
|
||||||
|
{
|
||||||
|
aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
|
||||||
|
aDefParams->SetDeviationCoefficient (aValue.RealValue());
|
||||||
|
}
|
||||||
|
else if (aKey == "ANGDEFL"
|
||||||
|
|| aKey == "ANGULARDEFL"
|
||||||
|
|| aKey == "ANGULARDEFLECTION")
|
||||||
|
{
|
||||||
|
// currently HLRDeviationAngle is used instead of DeviationAngle in most places
|
||||||
|
aDefParams->SetHLRAngle (M_PI * aValue.RealValue() / 180.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Warning, unknown argument '" << anArg.ToCString() << "'\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
//function : VClInfo
|
//function : VClInfo
|
||||||
//purpose : Prints info about active OpenCL device
|
//purpose : Prints info about active OpenCL device
|
||||||
@ -5726,6 +5803,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
|||||||
" 2 - all textures enabled.\n"
|
" 2 - all textures enabled.\n"
|
||||||
" this command sets texture details mode for the specified view.\n"
|
" this command sets texture details mode for the specified view.\n"
|
||||||
, __FILE__, VSetTextureMode, group);
|
, __FILE__, VSetTextureMode, group);
|
||||||
|
theCommands.Add("vdefaults",
|
||||||
|
"vdefaults [absDefl=value] [devCoeff=value] [angDefl=value]",
|
||||||
|
__FILE__, VDefaults, group);
|
||||||
theCommands.Add("vraytrace",
|
theCommands.Add("vraytrace",
|
||||||
"vraytrace 0|1",
|
"vraytrace 0|1",
|
||||||
__FILE__,VRaytrace,group);
|
__FILE__,VRaytrace,group);
|
||||||
|
@ -2,18 +2,13 @@ cpulimit 300
|
|||||||
set group "v3d"
|
set group "v3d"
|
||||||
|
|
||||||
pload VISUALIZATION
|
pload VISUALIZATION
|
||||||
vinit
|
vinit View1
|
||||||
pload TOPTEST
|
pload TOPTEST
|
||||||
|
|
||||||
if { [info exists imagedir] == 0 } {
|
if { [info exists imagedir] == 0 } {
|
||||||
set imagedir .
|
set imagedir .
|
||||||
}
|
}
|
||||||
|
|
||||||
if { [info exists test_image ] == 0 } {
|
if { [info exists test_image ] == 0 } {
|
||||||
set test_image photo
|
set test_image photo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
catch { vfit }
|
catch { vfit }
|
||||||
if { [ catch { vdump $imagedir/${test_image}.png } catch_result ] } {
|
if { [ catch { vdump $imagedir/${test_image}.png } catch_result ] } {
|
||||||
puts $catch_result
|
puts $catch_result
|
||||||
}
|
}
|
||||||
|
catch { vglinfo }
|
||||||
|
|
||||||
puts "TEST COMPLETED"
|
puts "TEST COMPLETED"
|
||||||
|
|
||||||
|
|
||||||
|
25
tests/v3d/glsl/phong_box
Normal file
25
tests/v3d/glsl/phong_box
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "Per-pixel lighting using GLSL program (Phong shading)"
|
||||||
|
puts "========"
|
||||||
|
|
||||||
|
# create box
|
||||||
|
box b 1 2 3
|
||||||
|
|
||||||
|
# draw box
|
||||||
|
vinit View1
|
||||||
|
vclear
|
||||||
|
vsetdispmode 1
|
||||||
|
vdisplay b
|
||||||
|
vfit
|
||||||
|
vrotate 0.2 0.0 0.0
|
||||||
|
|
||||||
|
# take snapshot with fixed pipeline
|
||||||
|
vdump $::imagedir/${::casename}_OFF.png
|
||||||
|
vshaderprog b phong
|
||||||
|
vdump $::imagedir/${::casename}_ph1.png
|
||||||
|
|
||||||
|
vclear
|
||||||
|
vdisplay b
|
||||||
|
vshaderprog b phong
|
||||||
|
vdump $::imagedir/${::casename}_ph2.png
|
||||||
|
vmoveto 250 250
|
29
tests/v3d/glsl/phong_couple
Normal file
29
tests/v3d/glsl/phong_couple
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "Per-pixel lighting using GLSL program (Phong shading)"
|
||||||
|
puts "========"
|
||||||
|
|
||||||
|
# import model
|
||||||
|
restore [locate_data_file occ/fuse.brep] f
|
||||||
|
tclean f
|
||||||
|
box b 2 0 0 1 0.5 0.25
|
||||||
|
|
||||||
|
# draw box
|
||||||
|
vinit View1
|
||||||
|
vclear
|
||||||
|
vdefaults absDefl=0.5
|
||||||
|
vsetdispmode 1
|
||||||
|
vdisplay f
|
||||||
|
vfit
|
||||||
|
vrotate -0.5 0.0 0.0
|
||||||
|
vdisplay b
|
||||||
|
vfit
|
||||||
|
|
||||||
|
# take snapshot with fixed pipeline
|
||||||
|
vdump $::imagedir/${::casename}_OFF.png
|
||||||
|
|
||||||
|
vshaderprog f phong
|
||||||
|
vshaderprog b phong
|
||||||
|
vshaderprog b off
|
||||||
|
vrotate -0.2 0.0 0.0
|
||||||
|
vmoveto 100 100
|
||||||
|
vdump $::imagedir/${::casename}_ph1.png
|
28
tests/v3d/glsl/phong_fuse
Normal file
28
tests/v3d/glsl/phong_fuse
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "Per-pixel lighting using GLSL program (Phong shading)"
|
||||||
|
puts "========"
|
||||||
|
|
||||||
|
# import model
|
||||||
|
restore [locate_data_file occ/fuse.brep] f
|
||||||
|
tclean f
|
||||||
|
|
||||||
|
# draw box
|
||||||
|
vinit View1
|
||||||
|
vclear
|
||||||
|
vdefaults absDefl=0.5
|
||||||
|
vsetdispmode 1
|
||||||
|
vdisplay f
|
||||||
|
vfit
|
||||||
|
vrotate -0.5 0.0 0.0
|
||||||
|
vfit
|
||||||
|
|
||||||
|
# take snapshot with fixed pipeline
|
||||||
|
vdump $::imagedir/${::casename}_OFF.png
|
||||||
|
vshaderprog f phong
|
||||||
|
vdump $::imagedir/${::casename}_ph1.png
|
||||||
|
|
||||||
|
vclear
|
||||||
|
vdisplay f
|
||||||
|
vshaderprog f phong
|
||||||
|
vdump $::imagedir/${::casename}_ph2.png
|
||||||
|
vmoveto 250 250
|
21
tests/v3d/glsl/phong_views
Normal file
21
tests/v3d/glsl/phong_views
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "Per-pixel lighting using GLSL program (Phong shading)"
|
||||||
|
puts "========"
|
||||||
|
|
||||||
|
# create box
|
||||||
|
box b 1 2 3
|
||||||
|
|
||||||
|
# draw box
|
||||||
|
vinit View1
|
||||||
|
vclear
|
||||||
|
vsetdispmode 1
|
||||||
|
vdisplay b
|
||||||
|
vfit
|
||||||
|
vrotate 0.2 0.0 0.0
|
||||||
|
|
||||||
|
vshaderprog b phong
|
||||||
|
vdump $::imagedir/${::casename}_1.png
|
||||||
|
|
||||||
|
vinit View2
|
||||||
|
vdump $::imagedir/${::casename}_2.png
|
||||||
|
vclose View2
|
@ -10,3 +10,4 @@
|
|||||||
010 wire
|
010 wire
|
||||||
011 wire_solid
|
011 wire_solid
|
||||||
012 voxel
|
012 voxel
|
||||||
|
013 glsl
|
||||||
|
Loading…
x
Reference in New Issue
Block a user