From 123813413566a4fc07c6e57a8f9fb0709bbb14ab Mon Sep 17 00:00:00 2001 From: kgv Date: Mon, 4 Nov 2013 04:42:44 +0400 Subject: [PATCH] 0024310: TKOpenGl - GLSL compatibility issues Lights defintion clean up: - remove duplicated enumeration TLightType (equals to Visual3d_TypeOfLightSource) - remove unused fields from Graphic3d_CLight - OpenGl_Light, reuse Graphic3d_CLight definition Phong GLSL program: - move out cumulative ambient light intencity from limited list of lights - compatibility issues, replace array of structures (light sources, materials, clipping planes) with arrays of primitive types New Draw Harness command vlight to alter light sources definition. OpenGl_ShaderProgram::Initialize() - add missing Linker log --- src/Graphic3d/Graphic3d_CLight.hxx | 72 +- src/Graphic3d/Graphic3d_CView.hxx | 4 +- src/Graphic3d/Graphic3d_GraphicDriver.cdl | 10 - src/Graphic3d/Graphic3d_GraphicDriver.cxx | 25 +- .../InterfaceGraphic_Visual3d.hxx | 31 - .../InterfaceGraphic_telem.hxx | 8 - src/NCollection/NCollection_Vec4.hxx | 6 + src/OpenGl/OpenGl_Light.hxx | 23 +- src/OpenGl/OpenGl_ShaderManager.cxx | 346 ++++---- src/OpenGl/OpenGl_ShaderProgram.cxx | 182 +--- src/OpenGl/OpenGl_ShaderProgram.hxx | 132 +-- src/OpenGl/OpenGl_View.cxx | 79 +- src/OpenGl/OpenGl_View_2.cxx | 263 +++--- src/OpenGl/OpenGl_Workspace_Raytrace.cxx | 44 +- src/Shaders/Declarations.glsl | 237 ++---- src/Shaders/DeclarationsImpl.glsl | 37 + src/Shaders/PhongShading.fs | 139 ++-- src/Shaders/PhongShading.vs | 41 +- src/V3d/V3d_Light.cdl | 4 + src/V3d/V3d_Light.cxx | 5 + src/ViewerTest/ViewerTest_ViewerCommands.cxx | 457 +++++++++- src/Visual3d/Visual3d_Light.cdl | 65 +- src/Visual3d/Visual3d_Light.cxx | 779 ++++++++---------- src/Visual3d/Visual3d_View.cxx | 178 +--- tests/v3d/glsl/phong_box | 1 + tests/v3d/glsl/phong_couple | 1 + tests/v3d/glsl/phong_fuse | 1 + tests/v3d/glsl/phong_fuse2 | 39 + tests/v3d/glsl/phong_views | 1 + 29 files changed, 1453 insertions(+), 1757 deletions(-) create mode 100644 src/Shaders/DeclarationsImpl.glsl create mode 100644 tests/v3d/glsl/phong_fuse2 diff --git a/src/Graphic3d/Graphic3d_CLight.hxx b/src/Graphic3d/Graphic3d_CLight.hxx index 5f3c1b76a3..a29b721802 100755 --- a/src/Graphic3d/Graphic3d_CLight.hxx +++ b/src/Graphic3d/Graphic3d_CLight.hxx @@ -15,26 +15,66 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. -/*============================================================================*/ -/*==== Titre: Graphic3d_CLight.hxx */ -/*==== Role : The header file of primitive type "CLight" from Graphic3d */ -/*==== */ -/*==== Implementation: This is a primitive type implemented with typedef */ -/*============================================================================*/ - #ifndef _Graphic3d_CLight_HeaderFile #define _Graphic3d_CLight_HeaderFile #include #include -typedef CALL_DEF_LIGHT Graphic3d_CLight; - -#if defined(__cplusplus) || defined(c_plusplus) -/*==== Definition de Type ====================================================*/ - +#include #include -const Handle(Standard_Type)& TYPE(Graphic3d_CLight); -/*============================================================================*/ -#endif -#endif /*Graphic3d_CLight_HeaderFile*/ +//! Light definition +struct Graphic3d_CLight +{ + +public: + + Graphic3d_Vec4 Color; //!< light color + Graphic3d_Vec4 Position; //!< light position + Graphic3d_Vec4 Direction; //!< direction of directional/spot light + Graphic3d_Vec4 Params; //!< packed light parameters + Standard_Integer Type; //!< Visual3d_TypeOfLightSource enumeration + Standard_Boolean IsHeadlight; //!< flag to mark head light + + //! Const attenuation factor of positional light source + Standard_ShortReal ConstAttenuation() const { return Params.x(); } + + //! Linear attenuation factor of positional light source + Standard_ShortReal LinearAttenuation() const { return Params.y(); } + + //! Const, Linear attenuation factors of positional light source + Graphic3d_Vec2 Attenuation() const { return Params.xy(); } + + //! Angle in radians of the cone created by the spot + Standard_ShortReal Angle() const { return Params.z(); } + + //! Intensity distribution of the spot light, with 0..1 range. + Standard_ShortReal Concentration() const { return Params.w(); } + + Standard_ShortReal& ChangeConstAttenuation() { return Params.x(); } + Standard_ShortReal& ChangeLinearAttenuation() { return Params.y(); } + Graphic3d_Vec2& ChangeAttenuation() { return Params.xy(); } + Standard_ShortReal& ChangeAngle() { return Params.z(); } + Standard_ShortReal& ChangeConcentration() { return Params.w(); } + +public: + + //! Empty constructor + Graphic3d_CLight() + : Color (1.0f, 1.0f, 1.0f, 1.0f), + Position (0.0f, 0.0f, 0.0f, 1.0f), + Direction (0.0f, 0.0f, 0.0f, 0.0f), + Params (0.0f, 0.0f, 0.0f, 0.0f), + Type (0), + IsHeadlight (Standard_False) + { + // + } + +public: + + DEFINE_STANDARD_ALLOC + +}; + +#endif // Graphic3d_CLight_HeaderFile diff --git a/src/Graphic3d/Graphic3d_CView.hxx b/src/Graphic3d/Graphic3d_CView.hxx index f2b46ecc69..33d0040b28 100755 --- a/src/Graphic3d/Graphic3d_CView.hxx +++ b/src/Graphic3d/Graphic3d_CView.hxx @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include class CALL_DEF_VIEWCONTEXT @@ -69,7 +69,7 @@ public: int Visualization; int NbActiveLight; - CALL_DEF_LIGHT* ActiveLight; + Graphic3d_CLight* ActiveLight; Handle(Graphic3d_TextureEnv) TextureEnv; int SurfaceDetail; diff --git a/src/Graphic3d/Graphic3d_GraphicDriver.cdl b/src/Graphic3d/Graphic3d_GraphicDriver.cdl index 235fa629f9..63d7cab9dc 100755 --- a/src/Graphic3d/Graphic3d_GraphicDriver.cdl +++ b/src/Graphic3d/Graphic3d_GraphicDriver.cdl @@ -941,16 +941,6 @@ is ---Purpose: Get Z layer ID of structure. If the structure doesn't -- exists in graphic driver, the method returns -1. - -------------------------- - -- Category: Class methods - -------------------------- - - Light ( myclass; - ACLight : CLight from Graphic3d; - Update : Boolean from Standard ) - returns Integer from Standard; - ---Purpose: call_togl_light - ----------------------------- -- Category: Internal methods ----------------------------- diff --git a/src/Graphic3d/Graphic3d_GraphicDriver.cxx b/src/Graphic3d/Graphic3d_GraphicDriver.cxx index 6122ea7dd6..247804d8b2 100755 --- a/src/Graphic3d/Graphic3d_GraphicDriver.cxx +++ b/src/Graphic3d/Graphic3d_GraphicDriver.cxx @@ -55,18 +55,6 @@ Graphic3d_GraphicDriver::Graphic3d_GraphicDriver (const Standard_CString AShrNam } -//-Methods, in order - -Standard_Integer Graphic3d_GraphicDriver::Light (const Graphic3d_CLight& ACLight, const Standard_Boolean Update) { - - static Standard_Integer NbLights = 1; - Standard_Boolean Result; - - Result = Update ? ACLight.LightId : NbLights++; - return Result; - -} - //-Internal methods, in order void Graphic3d_GraphicDriver::PrintBoolean (const Standard_CString AComment, const Standard_Boolean AValue) const { @@ -87,12 +75,12 @@ void Graphic3d_GraphicDriver::PrintCGroup (const Graphic3d_CGroup& ACGroup, cons } -void Graphic3d_GraphicDriver::PrintCLight (const Graphic3d_CLight& ACLight, const Standard_Integer AField) const { - - if (AField) { - cout << "\tws id " << ACLight.WsId << ", " - << "view id " << ACLight.ViewId << "\n"; - switch (ACLight.LightType) { +void Graphic3d_GraphicDriver::PrintCLight (const Graphic3d_CLight& theCLight, + const Standard_Integer theField) const +{ + if (theField) + { + switch (theCLight.Type) { case 0 : cout << "\tlight type : ambient\n"; break; @@ -111,7 +99,6 @@ void Graphic3d_GraphicDriver::PrintCLight (const Graphic3d_CLight& ACLight, cons } cout << flush; } - } void Graphic3d_GraphicDriver::PrintCPick (const Graphic3d_CPick& ACPick, const Standard_Integer AField) const { diff --git a/src/InterfaceGraphic/InterfaceGraphic_Visual3d.hxx b/src/InterfaceGraphic/InterfaceGraphic_Visual3d.hxx index 3218bb30e6..a32623bff9 100755 --- a/src/InterfaceGraphic/InterfaceGraphic_Visual3d.hxx +++ b/src/InterfaceGraphic/InterfaceGraphic_Visual3d.hxx @@ -35,37 +35,6 @@ typedef struct { } CALL_DEF_VERTEX; -/* SOURCE LUMINEUSE */ - -typedef struct { - - int WsId; - - int ViewId; - - int LightId; - - int Active; - - int LightType; - - int Headlight; - - CALL_DEF_COLOR Color; - - CALL_DEF_VERTEX Position; - - CALL_DEF_VERTEX Direction; - - float Concentration; - - float Attenuation[2]; - - float Angle; - -} CALL_DEF_LIGHT; - - /* ORIENTATION */ typedef struct { diff --git a/src/InterfaceGraphic/InterfaceGraphic_telem.hxx b/src/InterfaceGraphic/InterfaceGraphic_telem.hxx index 4f6916c57f..556f3e378d 100755 --- a/src/InterfaceGraphic/InterfaceGraphic_telem.hxx +++ b/src/InterfaceGraphic/InterfaceGraphic_telem.hxx @@ -48,14 +48,6 @@ struct TEL_COLOUR }; typedef TEL_COLOUR* tel_colour; -typedef enum -{ - TLightAmbient, - TLightDirectional, - TLightPositional, - TLightSpot -} TLightType; - typedef enum { TelCullNone, diff --git a/src/NCollection/NCollection_Vec4.hxx b/src/NCollection/NCollection_Vec4.hxx index d72e93f937..e5d11fee1e 100644 --- a/src/NCollection/NCollection_Vec4.hxx +++ b/src/NCollection/NCollection_Vec4.hxx @@ -215,6 +215,12 @@ public: return aSumm += theRight; } + //! Unary -. + NCollection_Vec4 operator-() const + { + return NCollection_Vec4 (-x(), -y(), -z(), -w()); + } + //! Compute per-component subtraction. NCollection_Vec4& operator-= (const NCollection_Vec4& theDec) { diff --git a/src/OpenGl/OpenGl_Light.hxx b/src/OpenGl/OpenGl_Light.hxx index 0c18fcae48..908f1e2414 100644 --- a/src/OpenGl/OpenGl_Light.hxx +++ b/src/OpenGl/OpenGl_Light.hxx @@ -17,29 +17,16 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. - #ifndef OpenGl_Light_Header #define OpenGl_Light_Header +#include +#include #include -#include - -#define OpenGLMaxLights 8 - -struct OpenGl_Light -{ - TLightType type; - int HeadLight; - TEL_COLOUR col; - Tfloat pos[3]; - Tfloat dir[3]; - Tfloat shine; - Tfloat atten[2]; - Tfloat angle; - DEFINE_STANDARD_ALLOC -}; +#define OpenGLMaxLights 8 +typedef Graphic3d_CLight OpenGl_Light; typedef NCollection_List OpenGl_ListOfLight; -#endif //OpenGl_Light_Header +#endif // OpenGl_Light_Header diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index 6b0419d171..95491ade66 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -255,89 +255,75 @@ const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const // ======================================================================= void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const { - if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)) + if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE) + || !theProgram->IsValid()) { return; } - - theProgram->SetUniform (myContext, theProgram->GetStateLocation ( - OpenGl_OCC_LIGHT_SOURCE_COUNT), myLightSourceState.LightSources()->Size()); - OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); - for (unsigned int anIndex = 0; anIter.More(); anIter.Next()) + const GLint aTypesLoc = theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES); + const GLint aParamsLoc = theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS); + + const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights); + if (aLightsDefNb < 1) { - if (anIndex >= OpenGLMaxLights) - { - break; - } - - const OpenGl_Light& aLight = anIter.Value(); - if (aLight.type == TLightAmbient) - { - OpenGl_Vec3 anAmbient (aLight.col.rgb[0], - aLight.col.rgb[1], - aLight.col.rgb[2]); - - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT + anIndex), anAmbient); - - anIter.Next(); - if (!anIter.More()) - { - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_TYPE + anIndex), int (aLight.type)); - break; - } - } - - OpenGl_Vec3 aDiffuse (aLight.col.rgb[0], - aLight.col.rgb[1], - aLight.col.rgb[2]); - - OpenGl_Vec3 aPosition (aLight.type == TLightDirectional ? -aLight.dir[0] : aLight.pos[0], - aLight.type == TLightDirectional ? -aLight.dir[1] : aLight.pos[1], - aLight.type == TLightDirectional ? -aLight.dir[2] : aLight.pos[2]); - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_TYPE + anIndex), int (aLight.type)); - + theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT), + 0); theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_HEAD + anIndex), aLight.HeadLight); - - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE + anIndex), aDiffuse); - - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR + anIndex), aDiffuse); - - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_POSITION + anIndex), aPosition); - - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION + anIndex), aLight.atten[0]); - - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION + anIndex), aLight.atten[1]); - - if (aLight.type == TLightSpot) - { - OpenGl_Vec3 aDirection (aLight.dir[0], - aLight.dir[1], - aLight.dir[2]); - - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF + anIndex), aLight.angle); - - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT + anIndex), aLight.shine); - - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION + anIndex), aDirection); - } - - ++anIndex; + theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT), + OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f)); + theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index()); + return; } + OpenGl_Vec2i* aTypesArray = new OpenGl_Vec2i[aLightsDefNb]; + OpenGl_Vec4* aParamsArray = new OpenGl_Vec4 [aLightsDefNb * 4]; + + OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f); + Standard_Integer aLightsNb = 0; + for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next()) + { + const OpenGl_Light& aLight = anIter.Value(); + if (aLight.Type == Visual3d_TOLS_AMBIENT) + { + anAmbient += aLight.Color; + continue; + } + else if (aLightsNb >= OpenGLMaxLights) + { + continue; + } + + aTypesArray[aLightsNb].x() = aLight.Type; + aTypesArray[aLightsNb].y() = aLight.IsHeadlight; + + aParamsArray[aLightsNb * 4 + 0] = aLight.Color; + aParamsArray[aLightsNb * 4 + 1] = aLight.Type == Visual3d_TOLS_DIRECTIONAL + ? -aLight.Direction + : aLight.Position; + if (aLight.Type == Visual3d_TOLS_SPOT) + { + aParamsArray[aLightsNb * 4 + 2] = aLight.Direction; + } + aParamsArray[aLightsNb * 4 + 3] = aLight.Params; + ++aLightsNb; + } + + theProgram->SetUniform (myContext, + theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT), + aLightsNb); + theProgram->SetUniform (myContext, + theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT), + anAmbient); + if (aLightsNb > 0) + { + myContext->core20->glUniform2iv (aTypesLoc, aLightsNb, aTypesArray [0].GetData()); + myContext->core20->glUniform4fv (aParamsLoc, aLightsNb * 4, aParamsArray[0].GetData()); + } + delete[] aTypesArray; + delete[] aParamsArray; + theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index()); } @@ -472,8 +458,18 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram) return; } - Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes()); - for (GLuint anIndex = 0; anIter.More(); anIter.Next()) + theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index()); + const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS); + const GLint aLocSpaces = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_SPACES); + if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION + && aLocSpaces == OpenGl_ShaderProgram::INVALID_LOCATION) + { + return; + } + + GLuint aPlanesNb = 0; + for (Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes()); + anIter.More(); anIter.Next()) { const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value(); if (!myContext->Clipping().IsEnabled (aPlane)) @@ -481,23 +477,37 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram) continue; } - GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_0_EQUATION + anIndex); - if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) - { - const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation(); - theProgram->SetUniform (myContext, aLocation, OpenGl_Vec4 ((float) anEquation.x(), - (float) anEquation.y(), - (float) anEquation.z(), - (float) anEquation.w())); - } - - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_0_SPACE + anIndex), - myContext->Clipping().GetEquationSpace (aPlane)); - ++anIndex; + ++aPlanesNb; + } + if (aPlanesNb < 1) + { + return; } - theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index()); + OpenGl_Vec4* anEquations = new OpenGl_Vec4[aPlanesNb]; + GLint* aSpaces = new GLint [aPlanesNb]; + GLuint aPlaneId = 0; + for (Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes()); + anIter.More(); anIter.Next()) + { + const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value(); + if (!myContext->Clipping().IsEnabled (aPlane)) + { + continue; + } + + const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation(); + anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(), + (float) anEquation.y(), + (float) anEquation.z(), + (float) anEquation.w()); + aSpaces[aPlaneId] = myContext->Clipping().GetEquationSpace (aPlane); + ++aPlaneId; + } + myContext->core20->glUniform4fv (aLocEquations, aPlanesNb, anEquations[0].GetData()); + myContext->core20->glUniform1iv (aLocSpaces, aPlanesNb, aSpaces); + delete[] anEquations; + delete[] aSpaces; } // ======================================================================= @@ -559,65 +569,48 @@ static void PushAspectFace (const Handle(OpenGl_Context)& theCtx, theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), theAspect->DoTextureMap()); - theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */); - theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), theAspect->DistinguishingMode()); - for (int anIndex = 0; anIndex < 2; ++anIndex) + OpenGl_Vec4 aParams[5]; + for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex) { - const OPENGL_SURF_PROP& aProperties = (anIndex == 0) ? theAspect->IntFront() : theAspect->IntBack(); - GLint aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT + anIndex); - if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) + const GLint aLoc = theProgram->GetStateLocation (anIndex == 0 + ? OpenGl_OCCT_FRONT_MATERIAL + : OpenGl_OCCT_BACK_MATERIAL); + if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION) { - OpenGl_Vec4 anAmbient (aProperties.ambcol.rgb[0] * aProperties.amb, - aProperties.ambcol.rgb[1] * aProperties.amb, - aProperties.ambcol.rgb[2] * aProperties.amb, - aProperties.ambcol.rgb[3] * aProperties.amb); - theProgram->SetUniform (theCtx, aLocation, anAmbient); + continue; } - aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE + anIndex); - if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) - { - OpenGl_Vec4 aDiffuse (aProperties.difcol.rgb[0] * aProperties.diff, - aProperties.difcol.rgb[1] * aProperties.diff, - aProperties.difcol.rgb[2] * aProperties.diff, - aProperties.difcol.rgb[3] * aProperties.diff); - theProgram->SetUniform (theCtx, aLocation, aDiffuse); - } - - aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR + anIndex); - if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) - { - OpenGl_Vec4 aSpecular (aProperties.speccol.rgb[0] * aProperties.spec, - aProperties.speccol.rgb[1] * aProperties.spec, - aProperties.speccol.rgb[2] * aProperties.spec, - aProperties.speccol.rgb[3] * aProperties.spec); - theProgram->SetUniform (theCtx, aLocation, aSpecular); - } - - aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION + anIndex); - if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) - { - OpenGl_Vec4 anEmission (aProperties.emscol.rgb[0] * aProperties.emsv, - aProperties.emscol.rgb[1] * aProperties.emsv, - aProperties.emscol.rgb[2] * aProperties.emsv, - aProperties.emscol.rgb[3] * aProperties.emsv); - theProgram->SetUniform (theCtx, aLocation, anEmission); - } - - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SHININESS + anIndex), - aProperties.shine); - - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY + anIndex), - aProperties.trans); + const OPENGL_SURF_PROP& aProps = (anIndex == 0) ? theAspect->IntFront() : theAspect->IntBack(); + const OpenGl_Vec4 anEmission (aProps.emscol.rgb[0] * aProps.emsv, + aProps.emscol.rgb[1] * aProps.emsv, + aProps.emscol.rgb[2] * aProps.emsv, + aProps.emscol.rgb[3] * aProps.emsv); + const OpenGl_Vec4 anAmbient (aProps.ambcol.rgb[0] * aProps.amb, + aProps.ambcol.rgb[1] * aProps.amb, + aProps.ambcol.rgb[2] * aProps.amb, + aProps.ambcol.rgb[3] * aProps.amb); + const OpenGl_Vec4 aDiffuse (aProps.difcol.rgb[0] * aProps.diff, + aProps.difcol.rgb[1] * aProps.diff, + aProps.difcol.rgb[2] * aProps.diff, + aProps.difcol.rgb[3] * aProps.diff); + const OpenGl_Vec4 aSpecular (aProps.speccol.rgb[0] * aProps.spec, + aProps.speccol.rgb[1] * aProps.spec, + aProps.speccol.rgb[2] * aProps.spec, + aProps.speccol.rgb[3] * aProps.spec); + aParams[0] = anEmission; + aParams[1] = anAmbient; + aParams[2] = aDiffuse; + aParams[3] = aSpecular; + aParams[4].x() = aProps.shine; + aParams[4].y() = aProps.trans; + theCtx->core20->glUniform4fv (aLoc, 5, aParams[0].GetData()); } } @@ -636,21 +629,15 @@ static void PushAspectLine (const Handle(OpenGl_Context)& theCtx, theAspect->Color().rgb[1], theAspect->Color().rgb[2], theAspect->Color().rgb[3]); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT), - THE_COLOR_BLACK_VEC4); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE), - aDiffuse); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR), - THE_COLOR_BLACK_VEC4); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION), - THE_COLOR_BLACK_VEC4); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY), - 0.0f); + OpenGl_Vec4 aParams[5]; + aParams[0] = THE_COLOR_BLACK_VEC4; + aParams[1] = THE_COLOR_BLACK_VEC4; + aParams[2] = aDiffuse; + aParams[3] = THE_COLOR_BLACK_VEC4; + aParams[4].x() = 0.0f; // shininess + aParams[4].y() = 0.0f; // transparency + theCtx->core20->glUniform4fv (theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL), + 5, aParams[0].GetData()); } // ======================================================================= @@ -678,21 +665,15 @@ static void PushAspectText (const Handle(OpenGl_Context)& theCtx, theAspect->SubtitleColor().rgb[3]); } - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT), - THE_COLOR_BLACK_VEC4); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE), - aDiffuse); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR), - THE_COLOR_BLACK_VEC4); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION), - THE_COLOR_BLACK_VEC4); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY), - 0.0f); + OpenGl_Vec4 aParams[5]; + aParams[0] = THE_COLOR_BLACK_VEC4; + aParams[1] = THE_COLOR_BLACK_VEC4; + aParams[2] = aDiffuse; + aParams[3] = THE_COLOR_BLACK_VEC4; + aParams[4].x() = 0.0f; // shininess + aParams[4].y() = 0.0f; // transparency + theCtx->core20->glUniform4fv (theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL), + 5, aParams[0].GetData()); } // ======================================================================= @@ -711,22 +692,15 @@ static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx, theAspect->Color().rgb[1], theAspect->Color().rgb[2], theAspect->Color().rgb[3]); - - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT), - THE_COLOR_BLACK_VEC4); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE), - aDiffuse); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR), - THE_COLOR_BLACK_VEC4); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION), - THE_COLOR_BLACK_VEC4); - theProgram->SetUniform (theCtx, - theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY), - 0.0f); + OpenGl_Vec4 aParams[5]; + aParams[0] = THE_COLOR_BLACK_VEC4; + aParams[1] = THE_COLOR_BLACK_VEC4; + aParams[2] = aDiffuse; + aParams[3] = THE_COLOR_BLACK_VEC4; + aParams[4].x() = 0.0f; // shininess + aParams[4].y() = 0.0f; // transparency + theCtx->core20->glUniform4fv (theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL), + 5, aParams[0].GetData()); } }; // nameless namespace @@ -780,4 +754,4 @@ void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& thePro PushModelWorldState (theProgram); PushProjectionState (theProgram); PushLightSourceState (theProgram); -} \ No newline at end of file +} diff --git a/src/OpenGl/OpenGl_ShaderProgram.cxx b/src/OpenGl/OpenGl_ShaderProgram.cxx index 59903d2f86..34f72b4b6e 100644 --- a/src/OpenGl/OpenGl_ShaderProgram.cxx +++ b/src/OpenGl/OpenGl_ShaderProgram.cxx @@ -36,153 +36,32 @@ OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_Va // Declare OCCT-specific OpenGL/GLSL shader variables Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] = { - /* OpenGl_OCC_MODEL_WORLD_MATRIX */ "occModelWorldMatrix", - /* OpenGl_OCC_WORLD_VIEW_MATRIX */ "occWorldViewMatrix", - /* OpenGl_OCC_PROJECTION_MATRIX */ "occProjectionMatrix", - /* OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE */ "occModelWorldMatrixInverse", - /* OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE */ "occWorldViewMatrixInverse", - /* OpenGl_OCC_PROJECTION_MATRIX_INVERSE */ "occProjectionMatrixInverse", - /* OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE */ "occModelWorldMatrixTranspose", - /* OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE */ "occWorldViewMatrixTranspose", - /* OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE */ "occProjectionMatrixTranspose", - /* OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE */ "occModelWorldMatrixInverseTranspose", - /* OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE */ "occWorldViewMatrixInverseTranspose", - /* OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE */ "occProjectionMatrixInverseTranspose", + "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX + "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX + "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX + "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE + "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE + "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE + "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE + "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE + "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE + "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE + "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE + "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE - /* OpenGl_OCC_CLIP_PLANE_0_EQUATION */ "occClipPlanes[0].Equation", - /* OpenGl_OCC_CLIP_PLANE_1_EQUATION */ "occClipPlanes[1].Equation", - /* OpenGl_OCC_CLIP_PLANE_2_EQUATION */ "occClipPlanes[2].Equation", - /* OpenGl_OCC_CLIP_PLANE_3_EQUATION */ "occClipPlanes[3].Equation", - /* OpenGl_OCC_CLIP_PLANE_4_EQUATION */ "occClipPlanes[4].Equation", - /* OpenGl_OCC_CLIP_PLANE_5_EQUATION */ "occClipPlanes[5].Equation", - /* OpenGl_OCC_CLIP_PLANE_6_EQUATION */ "occClipPlanes[6].Equation", - /* OpenGl_OCC_CLIP_PLANE_7_EQUATION */ "occClipPlanes[7].Equation", + "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS + "occClipPlaneSpaces", // OpenGl_OCC_CLIP_PLANE_SPACES - /* OpenGl_OCC_CLIP_PLANE_0_SPACE */ "occClipPlanes[0].Space", - /* OpenGl_OCC_CLIP_PLANE_1_SPACE */ "occClipPlanes[1].Space", - /* OpenGl_OCC_CLIP_PLANE_2_SPACE */ "occClipPlanes[2].Space", - /* OpenGl_OCC_CLIP_PLANE_3_SPACE */ "occClipPlanes[3].Space", - /* OpenGl_OCC_CLIP_PLANE_4_SPACE */ "occClipPlanes[4].Space", - /* OpenGl_OCC_CLIP_PLANE_5_SPACE */ "occClipPlanes[5].Space", - /* OpenGl_OCC_CLIP_PLANE_6_SPACE */ "occClipPlanes[6].Space", - /* OpenGl_OCC_CLIP_PLANE_7_SPACE */ "occClipPlanes[7].Space", + "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT + "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES + "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS + "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT - /* OpenGl_OCC_LIGHT_SOURCE_COUNT */ "occLightSourcesCount", - - /* OpenGl_OCC_LIGHT_SOURCE_0_TYPE */ "occLightSources[0].Type", - /* OpenGl_OCC_LIGHT_SOURCE_1_TYPE */ "occLightSources[1].Type", - /* OpenGl_OCC_LIGHT_SOURCE_2_TYPE */ "occLightSources[2].Type", - /* OpenGl_OCC_LIGHT_SOURCE_3_TYPE */ "occLightSources[3].Type", - /* OpenGl_OCC_LIGHT_SOURCE_4_TYPE */ "occLightSources[4].Type", - /* OpenGl_OCC_LIGHT_SOURCE_5_TYPE */ "occLightSources[5].Type", - /* OpenGl_OCC_LIGHT_SOURCE_6_TYPE */ "occLightSources[6].Type", - /* OpenGl_OCC_LIGHT_SOURCE_7_TYPE */ "occLightSources[7].Type", - - /* OpenGl_OCC_LIGHT_SOURCE_0_HEAD */ "occLightSources[0].Head", - /* OpenGl_OCC_LIGHT_SOURCE_1_HEAD */ "occLightSources[1].Head", - /* OpenGl_OCC_LIGHT_SOURCE_2_HEAD */ "occLightSources[2].Head", - /* OpenGl_OCC_LIGHT_SOURCE_3_HEAD */ "occLightSources[3].Head", - /* OpenGl_OCC_LIGHT_SOURCE_4_HEAD */ "occLightSources[4].Head", - /* OpenGl_OCC_LIGHT_SOURCE_5_HEAD */ "occLightSources[5].Head", - /* OpenGl_OCC_LIGHT_SOURCE_6_HEAD */ "occLightSources[6].Head", - /* OpenGl_OCC_LIGHT_SOURCE_7_HEAD */ "occLightSources[7].Head", - - /* OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT */ "occLightSources[0].Ambient", - /* OpenGl_OCC_LIGHT_SOURCE_1_AMBIENT */ "occLightSources[1].Ambient", - /* OpenGl_OCC_LIGHT_SOURCE_2_AMBIENT */ "occLightSources[2].Ambient", - /* OpenGl_OCC_LIGHT_SOURCE_3_AMBIENT */ "occLightSources[3].Ambient", - /* OpenGl_OCC_LIGHT_SOURCE_4_AMBIENT */ "occLightSources[4].Ambient", - /* OpenGl_OCC_LIGHT_SOURCE_5_AMBIENT */ "occLightSources[5].Ambient", - /* OpenGl_OCC_LIGHT_SOURCE_6_AMBIENT */ "occLightSources[6].Ambient", - /* OpenGl_OCC_LIGHT_SOURCE_7_AMBIENT */ "occLightSources[7].Ambient", - - /* OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE */ "occLightSources[0].Diffuse", - /* OpenGl_OCC_LIGHT_SOURCE_1_DIFFUSE */ "occLightSources[1].Diffuse", - /* OpenGl_OCC_LIGHT_SOURCE_2_DIFFUSE */ "occLightSources[2].Diffuse", - /* OpenGl_OCC_LIGHT_SOURCE_3_DIFFUSE */ "occLightSources[3].Diffuse", - /* OpenGl_OCC_LIGHT_SOURCE_4_DIFFUSE */ "occLightSources[4].Diffuse", - /* OpenGl_OCC_LIGHT_SOURCE_5_DIFFUSE */ "occLightSources[5].Diffuse", - /* OpenGl_OCC_LIGHT_SOURCE_6_DIFFUSE */ "occLightSources[6].Diffuse", - /* OpenGl_OCC_LIGHT_SOURCE_7_DIFFUSE */ "occLightSources[7].Diffuse", - - /* OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR */ "occLightSources[0].Specular", - /* OpenGl_OCC_LIGHT_SOURCE_1_SPECULAR */ "occLightSources[1].Specular", - /* OpenGl_OCC_LIGHT_SOURCE_2_SPECULAR */ "occLightSources[2].Specular", - /* OpenGl_OCC_LIGHT_SOURCE_3_SPECULAR */ "occLightSources[3].Specular", - /* OpenGl_OCC_LIGHT_SOURCE_4_SPECULAR */ "occLightSources[4].Specular", - /* OpenGl_OCC_LIGHT_SOURCE_5_SPECULAR */ "occLightSources[5].Specular", - /* OpenGl_OCC_LIGHT_SOURCE_6_SPECULAR */ "occLightSources[6].Specular", - /* OpenGl_OCC_LIGHT_SOURCE_7_SPECULAR */ "occLightSources[7].Specular", - - /* OpenGl_OCC_LIGHT_SOURCE_0_POSITION */ "occLightSources[0].Position", - /* OpenGl_OCC_LIGHT_SOURCE_1_POSITION */ "occLightSources[1].Position", - /* OpenGl_OCC_LIGHT_SOURCE_2_POSITION */ "occLightSources[2].Position", - /* OpenGl_OCC_LIGHT_SOURCE_3_POSITION */ "occLightSources[3].Position", - /* OpenGl_OCC_LIGHT_SOURCE_4_POSITION */ "occLightSources[4].Position", - /* OpenGl_OCC_LIGHT_SOURCE_5_POSITION */ "occLightSources[5].Position", - /* OpenGl_OCC_LIGHT_SOURCE_6_POSITION */ "occLightSources[6].Position", - /* OpenGl_OCC_LIGHT_SOURCE_7_POSITION */ "occLightSources[7].Position", - - /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF */ "occLightSources[0].SpotCutoff", - /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_CUTOFF */ "occLightSources[1].SpotCutoff", - /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_CUTOFF */ "occLightSources[2].SpotCutoff", - /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_CUTOFF */ "occLightSources[3].SpotCutoff", - /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_CUTOFF */ "occLightSources[4].SpotCutoff", - /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_CUTOFF */ "occLightSources[5].SpotCutoff", - /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_CUTOFF */ "occLightSources[6].SpotCutoff", - /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_CUTOFF */ "occLightSources[7].SpotCutoff", - - /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT */ "occLightSources[0].SpotExponent", - /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_EXPONENT */ "occLightSources[1].SpotExponent", - /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_EXPONENT */ "occLightSources[2].SpotExponent", - /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_EXPONENT */ "occLightSources[3].SpotExponent", - /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_EXPONENT */ "occLightSources[4].SpotExponent", - /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_EXPONENT */ "occLightSources[5].SpotExponent", - /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_EXPONENT */ "occLightSources[6].SpotExponent", - /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_EXPONENT */ "occLightSources[7].SpotExponent", - - /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION */ "occLightSources[0].SpotDirection", - /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_DIRECTION */ "occLightSources[1].SpotDirection", - /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_DIRECTION */ "occLightSources[2].SpotDirection", - /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_DIRECTION */ "occLightSources[3].SpotDirection", - /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_DIRECTION */ "occLightSources[4].SpotDirection", - /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_DIRECTION */ "occLightSources[5].SpotDirection", - /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_DIRECTION */ "occLightSources[6].SpotDirection", - /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_DIRECTION */ "occLightSources[7].SpotDirection", - - /* OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION */ "occLightSources[0].ConstAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_1_CONST_ATTENUATION */ "occLightSources[1].ConstAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_2_CONST_ATTENUATION */ "occLightSources[2].ConstAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_3_CONST_ATTENUATION */ "occLightSources[3].ConstAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_4_CONST_ATTENUATION */ "occLightSources[4].ConstAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_5_CONST_ATTENUATION */ "occLightSources[5].ConstAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_6_CONST_ATTENUATION */ "occLightSources[6].ConstAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_7_CONST_ATTENUATION */ "occLightSources[7].ConstAttenuation", - - /* OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION */ "occLightSources[0].LinearAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_1_LINEAR_ATTENUATION */ "occLightSources[1].LinearAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_2_LINEAR_ATTENUATION */ "occLightSources[2].LinearAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_3_LINEAR_ATTENUATION */ "occLightSources[3].LinearAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_4_LINEAR_ATTENUATION */ "occLightSources[4].LinearAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_5_LINEAR_ATTENUATION */ "occLightSources[5].LinearAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_6_LINEAR_ATTENUATION */ "occLightSources[6].LinearAttenuation", - /* OpenGl_OCC_LIGHT_SOURCE_7_LINEAR_ATTENUATION */ "occLightSources[7].LinearAttenuation", - - /* OpenGl_OCCT_ACTIVE_SAMPLER */ "occActiveSampler", - /* OpenGl_OCCT_TEXTURE_ENABLE */ "occTextureEnable", - /* OpenGl_OCCT_DISTINGUISH_MODE */ "occDistinguishingMode", - /* OpenGl_OCCT_FRONT_MATERIAL_AMBIENT */ "occFrontMaterial.Ambient", - /* OpenGl_OCCT_BACK_MATERIAL_AMBIENT */ "occBackMaterial.Ambient", - /* OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE */ "occFrontMaterial.Diffuse", - /* OpenGl_OCCT_BACK_MATERIAL_DIFFUSE */ "occBackMaterial.Diffuse", - /* OpenGl_OCCT_FRONT_MATERIAL_SPECULAR */ "occFrontMaterial.Specular", - /* OpenGl_OCCT_BACK_MATERIAL_SPECULAR */ "occBackMaterial.Specular", - /* OpenGl_OCCT_FRONT_MATERIAL_EMISSION */ "occFrontMaterial.Emission", - /* OpenGl_OCCT_BACK_MATERIAL_EMISSION */ "occBackMaterial.Emission", - /* OpenGl_OCCT_FRONT_MATERIAL_SHININESS */ "occFrontMaterial.Shininess", - /* OpenGl_OCCT_BACK_MATERIAL_SHININESS */ "occBackMaterial.Shininess", - /* OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY */ "occFrontMaterial.Transparency", - /* OpenGl_OCCT_BACK_MATERIAL_TRANSPARENCY */ "occBackMaterial.Transparency" + "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER + "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE + "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE + "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL + "occBackMaterial" // OpenGl_OCCT_BACK_MATERIAL }; @@ -260,8 +139,10 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& return Standard_False; } - OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl"); - if (!aDeclFile.Exists()) + OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl"); + OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl"); + if (!aDeclFile.Exists() + || !aDeclImplFile.Exists()) { const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file"; theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, @@ -273,11 +154,16 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& } TCollection_AsciiString aDeclarations; - aDeclFile.Open (OSD_ReadOnly, OSD_Protection()); aDeclFile.Read (aDeclarations, (int)aDeclFile.Size()); aDeclFile.Close(); + TCollection_AsciiString aDeclImpl; + aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection()); + aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size()); + aDeclImplFile.Close(); + aDeclarations += aDeclImpl; + for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next()) { @@ -391,7 +277,7 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, - TCollection_ExtendedString ("Failed to link program object! Linker log:\n")); + TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog); return Standard_False; } else if (theCtx->caps->glslWarnings) diff --git a/src/OpenGl/OpenGl_ShaderProgram.hxx b/src/OpenGl/OpenGl_ShaderProgram.hxx index b97ec3ae8a..0efb326fd3 100644 --- a/src/OpenGl/OpenGl_ShaderProgram.hxx +++ b/src/OpenGl/OpenGl_ShaderProgram.hxx @@ -52,131 +52,21 @@ enum OpenGl_StateVariable OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE, // OpenGL clip planes state - OpenGl_OCC_CLIP_PLANE_0_EQUATION, - OpenGl_OCC_CLIP_PLANE_1_EQUATION, - OpenGl_OCC_CLIP_PLANE_2_EQUATION, - OpenGl_OCC_CLIP_PLANE_3_EQUATION, - OpenGl_OCC_CLIP_PLANE_4_EQUATION, - OpenGl_OCC_CLIP_PLANE_5_EQUATION, - OpenGl_OCC_CLIP_PLANE_6_EQUATION, - OpenGl_OCC_CLIP_PLANE_7_EQUATION, - OpenGl_OCC_CLIP_PLANE_0_SPACE, - OpenGl_OCC_CLIP_PLANE_1_SPACE, - OpenGl_OCC_CLIP_PLANE_2_SPACE, - OpenGl_OCC_CLIP_PLANE_3_SPACE, - OpenGl_OCC_CLIP_PLANE_4_SPACE, - OpenGl_OCC_CLIP_PLANE_5_SPACE, - OpenGl_OCC_CLIP_PLANE_6_SPACE, - OpenGl_OCC_CLIP_PLANE_7_SPACE, - - OpenGl_OCC_LIGHT_SOURCE_COUNT, + OpenGl_OCC_CLIP_PLANE_EQUATIONS, + OpenGl_OCC_CLIP_PLANE_SPACES, // OpenGL light state - OpenGl_OCC_LIGHT_SOURCE_0_TYPE, - OpenGl_OCC_LIGHT_SOURCE_1_TYPE, - OpenGl_OCC_LIGHT_SOURCE_2_TYPE, - OpenGl_OCC_LIGHT_SOURCE_3_TYPE, - OpenGl_OCC_LIGHT_SOURCE_4_TYPE, - OpenGl_OCC_LIGHT_SOURCE_5_TYPE, - OpenGl_OCC_LIGHT_SOURCE_6_TYPE, - OpenGl_OCC_LIGHT_SOURCE_7_TYPE, - OpenGl_OCC_LIGHT_SOURCE_0_HEAD, - OpenGl_OCC_LIGHT_SOURCE_1_HEAD, - OpenGl_OCC_LIGHT_SOURCE_2_HEAD, - OpenGl_OCC_LIGHT_SOURCE_3_HEAD, - OpenGl_OCC_LIGHT_SOURCE_4_HEAD, - OpenGl_OCC_LIGHT_SOURCE_5_HEAD, - OpenGl_OCC_LIGHT_SOURCE_6_HEAD, - OpenGl_OCC_LIGHT_SOURCE_7_HEAD, - OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT, - OpenGl_OCC_LIGHT_SOURCE_1_AMBIENT, - OpenGl_OCC_LIGHT_SOURCE_2_AMBIENT, - OpenGl_OCC_LIGHT_SOURCE_3_AMBIENT, - OpenGl_OCC_LIGHT_SOURCE_4_AMBIENT, - OpenGl_OCC_LIGHT_SOURCE_5_AMBIENT, - OpenGl_OCC_LIGHT_SOURCE_6_AMBIENT, - OpenGl_OCC_LIGHT_SOURCE_7_AMBIENT, - OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE, - OpenGl_OCC_LIGHT_SOURCE_1_DIFFUSE, - OpenGl_OCC_LIGHT_SOURCE_2_DIFFUSE, - OpenGl_OCC_LIGHT_SOURCE_3_DIFFUSE, - OpenGl_OCC_LIGHT_SOURCE_4_DIFFUSE, - OpenGl_OCC_LIGHT_SOURCE_5_DIFFUSE, - OpenGl_OCC_LIGHT_SOURCE_6_DIFFUSE, - OpenGl_OCC_LIGHT_SOURCE_7_DIFFUSE, - OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR, - OpenGl_OCC_LIGHT_SOURCE_1_SPECULAR, - OpenGl_OCC_LIGHT_SOURCE_2_SPECULAR, - OpenGl_OCC_LIGHT_SOURCE_3_SPECULAR, - OpenGl_OCC_LIGHT_SOURCE_4_SPECULAR, - OpenGl_OCC_LIGHT_SOURCE_5_SPECULAR, - OpenGl_OCC_LIGHT_SOURCE_6_SPECULAR, - OpenGl_OCC_LIGHT_SOURCE_7_SPECULAR, - OpenGl_OCC_LIGHT_SOURCE_0_POSITION, - OpenGl_OCC_LIGHT_SOURCE_1_POSITION, - OpenGl_OCC_LIGHT_SOURCE_2_POSITION, - OpenGl_OCC_LIGHT_SOURCE_3_POSITION, - OpenGl_OCC_LIGHT_SOURCE_4_POSITION, - OpenGl_OCC_LIGHT_SOURCE_5_POSITION, - OpenGl_OCC_LIGHT_SOURCE_6_POSITION, - OpenGl_OCC_LIGHT_SOURCE_7_POSITION, - OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF, - OpenGl_OCC_LIGHT_SOURCE_1_SPOT_CUTOFF, - OpenGl_OCC_LIGHT_SOURCE_2_SPOT_CUTOFF, - OpenGl_OCC_LIGHT_SOURCE_3_SPOT_CUTOFF, - OpenGl_OCC_LIGHT_SOURCE_4_SPOT_CUTOFF, - OpenGl_OCC_LIGHT_SOURCE_5_SPOT_CUTOFF, - OpenGl_OCC_LIGHT_SOURCE_6_SPOT_CUTOFF, - OpenGl_OCC_LIGHT_SOURCE_7_SPOT_CUTOFF, - OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT, - OpenGl_OCC_LIGHT_SOURCE_1_SPOT_EXPONENT, - OpenGl_OCC_LIGHT_SOURCE_2_SPOT_EXPONENT, - OpenGl_OCC_LIGHT_SOURCE_3_SPOT_EXPONENT, - OpenGl_OCC_LIGHT_SOURCE_4_SPOT_EXPONENT, - OpenGl_OCC_LIGHT_SOURCE_5_SPOT_EXPONENT, - OpenGl_OCC_LIGHT_SOURCE_6_SPOT_EXPONENT, - OpenGl_OCC_LIGHT_SOURCE_7_SPOT_EXPONENT, - OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION, - OpenGl_OCC_LIGHT_SOURCE_1_SPOT_DIRECTION, - OpenGl_OCC_LIGHT_SOURCE_2_SPOT_DIRECTION, - OpenGl_OCC_LIGHT_SOURCE_3_SPOT_DIRECTION, - OpenGl_OCC_LIGHT_SOURCE_4_SPOT_DIRECTION, - OpenGl_OCC_LIGHT_SOURCE_5_SPOT_DIRECTION, - OpenGl_OCC_LIGHT_SOURCE_6_SPOT_DIRECTION, - OpenGl_OCC_LIGHT_SOURCE_7_SPOT_DIRECTION, - OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_1_CONST_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_2_CONST_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_3_CONST_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_4_CONST_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_5_CONST_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_6_CONST_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_7_CONST_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_1_LINEAR_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_2_LINEAR_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_3_LINEAR_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_4_LINEAR_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_5_LINEAR_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_6_LINEAR_ATTENUATION, - OpenGl_OCC_LIGHT_SOURCE_7_LINEAR_ATTENUATION, + OpenGl_OCC_LIGHT_SOURCE_COUNT, + OpenGl_OCC_LIGHT_SOURCE_TYPES, + OpenGl_OCC_LIGHT_SOURCE_PARAMS, + OpenGl_OCC_LIGHT_AMBIENT, // Material state OpenGl_OCCT_ACTIVE_SAMPLER, OpenGl_OCCT_TEXTURE_ENABLE, OpenGl_OCCT_DISTINGUISH_MODE, - OpenGl_OCCT_FRONT_MATERIAL_AMBIENT, - OpenGl_OCCT_BACK_MATERIAL_AMBIENT, - OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE, - OpenGl_OCCT_BACK_MATERIAL_DIFFUSE, - OpenGl_OCCT_FRONT_MATERIAL_SPECULAR, - OpenGl_OCCT_BACK_MATERIAL_SPECULAR, - OpenGl_OCCT_FRONT_MATERIAL_EMISSION, - OpenGl_OCCT_BACK_MATERIAL_EMISSION, - OpenGl_OCCT_FRONT_MATERIAL_SHININESS, - OpenGl_OCCT_BACK_MATERIAL_SHININESS, - OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY, - OpenGl_OCCT_BACK_MATERIAL_TRANSPARENCY, + OpenGl_OCCT_FRONT_MATERIAL, + OpenGl_OCCT_BACK_MATERIAL, // DON'T MODIFY THIS ITEM (insert new items before it) OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES @@ -302,6 +192,12 @@ public: //! Reverts to fixed-function graphics pipeline (FFP). Standard_EXPORT static void Unbind (const Handle(OpenGl_Context)& theCtx); + //! @return true if current object was initialized + inline bool IsValid() const + { + return myProgramID != NO_PROGRAM; + } + private: //! Returns index of last modification of variables of specified state type. diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index 2df7ae10bc..6a7631d702 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -197,83 +197,26 @@ void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode) #endif } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetBackfacing +// purpose : +// ======================================================================= void OpenGl_View::SetBackfacing (const Standard_Integer theMode) { myBackfacing = theMode; } -/*----------------------------------------------------------------------*/ - -//call_togl_setlight -void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext) +// ======================================================================= +// function : SetLights +// purpose : +// ======================================================================= +void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx) { myLights.Clear(); - - const int nb_lights = AContext.NbActiveLight; - - int i = 0; - const CALL_DEF_LIGHT *alight = &(AContext.ActiveLight[0]); - for ( ; i < nb_lights; i++, alight++ ) + for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt) { - OpenGl_Light rep; - memset(&rep,0,sizeof(rep)); - - switch( alight->LightType ) - { - case 0 : /* TOLS_AMBIENT */ - rep.type = TLightAmbient; - rep.col.rgb[0] = alight->Color.r; - rep.col.rgb[1] = alight->Color.g; - rep.col.rgb[2] = alight->Color.b; - break; - - case 1 : /* TOLS_DIRECTIONAL */ - rep.type = TLightDirectional; - rep.col.rgb[0] = alight->Color.r; - rep.col.rgb[1] = alight->Color.g; - rep.col.rgb[2] = alight->Color.b; - rep.dir[0] = alight->Direction.x; - rep.dir[1] = alight->Direction.y; - rep.dir[2] = alight->Direction.z; - break; - - case 2 : /* TOLS_POSITIONAL */ - rep.type = TLightPositional; - rep.col.rgb[0] = alight->Color.r; - rep.col.rgb[1] = alight->Color.g; - rep.col.rgb[2] = alight->Color.b; - rep.pos[0] = alight->Position.x; - rep.pos[1] = alight->Position.y; - rep.pos[2] = alight->Position.z; - rep.atten[0] = alight->Attenuation[0]; - rep.atten[1] = alight->Attenuation[1]; - break; - - case 3 : /* TOLS_SPOT */ - rep.type = TLightSpot; - rep.col.rgb[0] = alight->Color.r; - rep.col.rgb[1] = alight->Color.g; - rep.col.rgb[2] = alight->Color.b; - rep.pos[0] = alight->Position.x; - rep.pos[1] = alight->Position.y; - rep.pos[2] = alight->Position.z; - rep.dir[0] = alight->Direction.x; - rep.dir[1] = alight->Direction.y; - rep.dir[2] = alight->Direction.z; - rep.shine = alight->Concentration; - rep.atten[0] = alight->Attenuation[0]; - rep.atten[1] = alight->Attenuation[1]; - rep.angle = alight->Angle; - break; - } - - rep.HeadLight = alight->Headlight; - - myLights.Append(rep); + myLights.Append (theViewCtx.ActiveLight[aLightIt]); } - myCurrLightSourceState = myStateCounter->Increment(); } diff --git a/src/OpenGl/OpenGl_View_2.cxx b/src/OpenGl/OpenGl_View_2.cxx index e00f141017..3632e78dd7 100644 --- a/src/OpenGl/OpenGl_View_2.cxx +++ b/src/OpenGl/OpenGl_View_2.cxx @@ -43,10 +43,15 @@ #define EPSI 0.0001 -static const GLfloat default_amb[4] = { 0.F, 0.F, 0.F, 1.F }; -static const GLfloat default_sptdir[3] = { 0.F, 0.F, -1.F }; -static const GLfloat default_sptexpo = 0.F; -static const GLfloat default_sptcutoff = 180.F; +namespace +{ + + static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f }; + static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f; + static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f; + +}; extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx @@ -68,171 +73,89 @@ struct OPENGL_CLIP_PLANE /* * Set des lumieres */ -static void bind_light(const OpenGl_Light *lptr, int *gl_lid) +static void bind_light (const OpenGl_Light& theLight, + GLenum& theLightGlId) { // Only 8 lights in OpenGL... - if (*gl_lid > GL_LIGHT7) return; - - // the light is a headlight ? - GLint cur_matrix = 0; - if (lptr->HeadLight) + if (theLightGlId > GL_LIGHT7) { - glGetIntegerv(GL_MATRIX_MODE, &cur_matrix); - glMatrixMode(GL_MODELVIEW); + return; + } + + if (theLight.Type == Visual3d_TOLS_AMBIENT) + { + // setup RGBA intensity of the ambient light + glLightModelfv (GL_LIGHT_MODEL_AMBIENT, theLight.Color.GetData()); + return; + } + + // the light is a headlight? + GLint aMatrixModeOld = 0; + if (theLight.IsHeadlight) + { + glGetIntegerv (GL_MATRIX_MODE, &aMatrixModeOld); + glMatrixMode (GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); } - GLfloat data_amb[4]; - GLfloat data_diffu[4]; - GLfloat data_pos[4]; - GLfloat data_sptdir[3]; - GLfloat data_sptexpo; - GLfloat data_sptcutoff; - GLfloat data_constantattenuation; - GLfloat data_linearattenuation; - - /* set la light en fonction de son type */ - switch (lptr->type) + // setup light type + switch (theLight.Type) { - case TLightAmbient: - data_amb[0] = lptr->col.rgb[0]; - data_amb[1] = lptr->col.rgb[1]; - data_amb[2] = lptr->col.rgb[2]; - data_amb[3] = 1.0; + case Visual3d_TOLS_DIRECTIONAL: + { + // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one + const OpenGl_Vec4 anInfDir = -theLight.Direction; - /*------------------------- Ambient ---------------------------*/ - /* - * The GL_AMBIENT parameter refers to RGBA intensity of the ambient - * light. - */ - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data_amb); - break; - - - case TLightDirectional: - data_diffu[0] = lptr->col.rgb[0]; - data_diffu[1] = lptr->col.rgb[1]; - data_diffu[2] = lptr->col.rgb[2]; - data_diffu[3] = 1.0; - - /*------------------------- Direction ---------------------------*/ - /* From Open GL Programming Rev 1 Guide Chapt 6 : - Lighting The Mathematics of Lighting ( p 168 ) - - Directional Light Source ( Infinite ) : - if the last parameter of GL_POSITION , w , is zero, the - corresponding light source is a Directional one. - - GL_SPOT_CUTOFF a 180 signifie que ce n'est pas un spot. - To create a realistic effect, set the GL_SPECULAR parameter - to the same value as the GL_DIFFUSE. - */ - - data_pos[0] = -lptr->dir[0]; - data_pos[1] = -lptr->dir[1]; - data_pos[2] = -lptr->dir[2]; - data_pos[3] = 0.0; - - glLightfv(*gl_lid, GL_AMBIENT, default_amb); - glLightfv(*gl_lid, GL_DIFFUSE, data_diffu); - glLightfv(*gl_lid, GL_SPECULAR, data_diffu); - - glLightfv(*gl_lid, GL_POSITION, data_pos); - glLightfv(*gl_lid, GL_SPOT_DIRECTION, default_sptdir); - glLightf(*gl_lid, GL_SPOT_EXPONENT, default_sptexpo); - glLightf(*gl_lid, GL_SPOT_CUTOFF, default_sptcutoff); - break; - - - case TLightPositional: - data_diffu[0] = lptr->col.rgb[0]; - data_diffu[1] = lptr->col.rgb[1]; - data_diffu[2] = lptr->col.rgb[2]; - data_diffu[3] = 1.0; - - /*------------------------- Position -----------------------------*/ - /* From Open GL Programming Rev 1 Guide Chapt 6 : - Lighting The Mathematics of Lighting ( p 168 ) - Positional Light Source : - if the last parameter of GL_POSITION , w , is nonzero, - the corresponding light source is a Positional one. - - GL_SPOT_CUTOFF a 180 signifie que ce n'est pas un spot. - - To create a realistic effect, set the GL_SPECULAR parameter - to the same value as the GL_DIFFUSE. - */ - - data_pos[0] = lptr->pos[0]; - data_pos[1] = lptr->pos[1]; - data_pos[2] = lptr->pos[2]; - data_pos[3] = 1.0; - - data_constantattenuation = lptr->atten[0]; - data_linearattenuation = lptr->atten[1]; - - glLightfv(*gl_lid, GL_AMBIENT, default_amb); - glLightfv(*gl_lid, GL_DIFFUSE, data_diffu); - glLightfv(*gl_lid, GL_SPECULAR, data_diffu); - - glLightfv(*gl_lid, GL_POSITION, data_pos); - glLightfv(*gl_lid, GL_SPOT_DIRECTION, default_sptdir); - glLightf(*gl_lid, GL_SPOT_EXPONENT, default_sptexpo); - glLightf(*gl_lid, GL_SPOT_CUTOFF, default_sptcutoff); - glLightf(*gl_lid, GL_CONSTANT_ATTENUATION, data_constantattenuation); - glLightf(*gl_lid, GL_LINEAR_ATTENUATION, data_linearattenuation); - glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0); - break; - - - case TLightSpot: - data_diffu[0] = lptr->col.rgb[0]; - data_diffu[1] = lptr->col.rgb[1]; - data_diffu[2] = lptr->col.rgb[2]; - data_diffu[3] = 1.0; - - data_pos[0] = lptr->pos[0]; - data_pos[1] = lptr->pos[1]; - data_pos[2] = lptr->pos[2]; - data_pos[3] = 1.0; - - data_sptdir[0] = lptr->dir[0]; - data_sptdir[1] = lptr->dir[1]; - data_sptdir[2] = lptr->dir[2]; - - data_sptexpo = ( float )lptr->shine * 128.0F; - data_sptcutoff = ( float )(lptr->angle * 180.0F)/( float )M_PI; - - data_constantattenuation = lptr->atten[0]; - data_linearattenuation = lptr->atten[1]; - - glLightfv(*gl_lid, GL_AMBIENT, default_amb); - glLightfv(*gl_lid, GL_DIFFUSE, data_diffu); - glLightfv(*gl_lid, GL_SPECULAR, data_diffu); - - glLightfv(*gl_lid, GL_POSITION, data_pos); - glLightfv(*gl_lid, GL_SPOT_DIRECTION, data_sptdir); - glLightf(*gl_lid, GL_SPOT_EXPONENT, data_sptexpo); - glLightf(*gl_lid, GL_SPOT_CUTOFF, data_sptcutoff); - glLightf(*gl_lid, GL_CONSTANT_ATTENUATION, data_constantattenuation); - glLightf(*gl_lid, GL_LINEAR_ATTENUATION, data_linearattenuation); - glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0); - break; + // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE. + glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); + glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); + glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); + glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData()); + glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR); + glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT); + glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF); + break; + } + case Visual3d_TOLS_POSITIONAL: + { + // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE + glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); + glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); + glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); + glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData()); + glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR); + glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT); + glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF); + glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation()); + glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation()); + glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0); + break; + } + case Visual3d_TOLS_SPOT: + { + glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); + glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); + glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); + glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData()); + glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData()); + glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f); + glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI)); + glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation()); + glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation()); + glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f); + break; + } } - if (lptr->type != TLightAmbient) - { - glEnable(*gl_lid); - (*gl_lid)++; - } - - /* si la light etait une headlight alors restaure la matrice precedente */ - if (lptr->HeadLight) + // restore matrix in case of headlight + if (theLight.IsHeadlight) { glPopMatrix(); - glMatrixMode(cur_matrix); + glMatrixMode (aMatrixModeOld); } + + glEnable (theLightGlId++); } /*----------------------------------------------------------------------*/ @@ -1009,23 +932,23 @@ D = -[Px,Py,Pz] dot |Nx| // Apply Lights { - int i; - - // Switch off all lights - for (i = GL_LIGHT0; i <= GL_LIGHT7; i++) - glDisable(i); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, default_amb); - - /* set les lights */ - int gl_lid = GL_LIGHT0; - OpenGl_ListOfLight::Iterator itl(myLights); - for (; itl.More(); itl.Next()) + // setup lights + glLightModelfv (GL_LIGHT_MODEL_AMBIENT, THE_DEFAULT_AMBIENT); + GLenum aLightGlId = GL_LIGHT0; + for (OpenGl_ListOfLight::Iterator aLightIt (myLights); + aLightIt.More(); aLightIt.Next()) { - const OpenGl_Light &alight = itl.Value(); - bind_light(&alight, &gl_lid); + bind_light (aLightIt.Value(), aLightGlId); + } + if (aLightGlId != GL_LIGHT0) + { + glEnable (GL_LIGHTING); + } + // switch off unused lights + for (; aLightGlId <= GL_LIGHT7; ++aLightGlId) + { + glDisable (aLightGlId); } - - if (gl_lid != GL_LIGHT0) glEnable(GL_LIGHTING); } // Apply InteriorShadingMethod diff --git a/src/OpenGl/OpenGl_Workspace_Raytrace.cxx b/src/OpenGl/OpenGl_Workspace_Raytrace.cxx index 71eeed1988..6a181fc796 100644 --- a/src/OpenGl/OpenGl_Workspace_Raytrace.cxx +++ b/src/OpenGl/OpenGl_Workspace_Raytrace.cxx @@ -917,42 +917,24 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceLightSources (const GLdouble th { myRaytraceSceneData.LightSources.clear(); - OpenGl_ListOfLight::Iterator anItl (myView->LightList()); - - OpenGl_RTVec4f aAmbient (0.f, 0.f, 0.f, 0.f); - - for (; anItl.More(); anItl.Next()) + OpenGl_RTVec4f anAmbient (0.0f, 0.0f, 0.0f, 0.0f); + for (OpenGl_ListOfLight::Iterator anItl (myView->LightList()); + anItl.More(); anItl.Next()) { - const OpenGl_Light &aLight = anItl.Value(); - - if (aLight.type == TLightAmbient) + const OpenGl_Light& aLight = anItl.Value(); + if (aLight.Type == Visual3d_TOLS_AMBIENT) { - aAmbient += OpenGl_RTVec4f (aLight.col.rgb[0], - aLight.col.rgb[1], - aLight.col.rgb[2], - 0.f); + anAmbient += OpenGl_RTVec4f (aLight.Color.r(), aLight.Color.g(), aLight.Color.b(), 0.0f); continue; } - OpenGl_RTVec4f aDiffuse (aLight.col.rgb[0], - aLight.col.rgb[1], - aLight.col.rgb[2], - 1.f); - - OpenGl_RTVec4f aPosition (-aLight.dir[0], - -aLight.dir[1], - -aLight.dir[2], - 0.f); - - if (aLight.type != TLightDirectional) + OpenGl_RTVec4f aDiffuse (aLight.Color.r(), aLight.Color.g(), aLight.Color.b(), 1.0f); + OpenGl_RTVec4f aPosition (-aLight.Direction.x(), -aLight.Direction.y(), -aLight.Direction.z(), 0.0f); + if (aLight.Type != Visual3d_TOLS_DIRECTIONAL) { - aPosition = OpenGl_RTVec4f (aLight.pos[0], - aLight.pos[1], - aLight.pos[2], - 1.f); + aPosition = OpenGl_RTVec4f (aLight.Position.x(), aLight.Position.y(), aLight.Position.z(), 1.0f); } - - if (aLight.HeadLight) + if (aLight.IsHeadlight) { aPosition = MatVecMult (theInvModelView, aPosition); } @@ -962,11 +944,11 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceLightSources (const GLdouble th if (myRaytraceSceneData.LightSources.size() > 0) { - myRaytraceSceneData.LightSources.front().Ambient += aAmbient; + myRaytraceSceneData.LightSources.front().Ambient += anAmbient; } else { - myRaytraceSceneData.LightSources.push_back (OpenGl_RaytraceLight (OpenGl_RTVec4f (aAmbient.xyz(), -1.0f))); + myRaytraceSceneData.LightSources.push_back (OpenGl_RaytraceLight (OpenGl_RTVec4f (anAmbient.rgb(), -1.0f))); } cl_int anError = CL_SUCCESS; diff --git a/src/Shaders/Declarations.glsl b/src/Shaders/Declarations.glsl index 88046a8131..382f106b27 100644 --- a/src/Shaders/Declarations.glsl +++ b/src/Shaders/Declarations.glsl @@ -1,192 +1,79 @@ -#define _OCC_MAX_LIGHTS_ 8 +// This files includes definition of common uniform variables in OCCT GLSL programs -#define _OCC_MAX_CLIP_PLANES_ 8 - - -//! OCCT ambient light source. -const int occAmbientLight = 0; - -//! OCCT directional light source. -const int occDirectLight = 1; - -//! OCCT isotropic point light source. -const int occPointLight = 2; - -//! OCCT spot light source. -const int occSpotLight = 3; - - -//! Parameters of OCCT light source. -struct occLightSource -{ - //! Type of light source. - int Type; - - //! Is light a headlight? - int Head; - - //! Ambient intensity. - vec3 Ambient; - - //! Diffuse intensity. - vec3 Diffuse; - - //! Specular intensity. - vec3 Specular; - - //! Position of light source. - vec3 Position; - - //! Direction of the spot light. - vec3 SpotDirection; - - //! Maximum spread angle of the spot light (in radians). - float SpotCutoff; - - //! Attenuation of the spot light intensity (from 0 to 1). - float SpotExponent; - - //! Const attenuation factor of positional light source. - float ConstAttenuation; - - //! Linear attenuation factor of positional light source. - float LinearAttenuation; -}; - -//! Parameters of OCCT material. -struct occMaterialParams -{ - //! Emission color. - vec4 Emission; - - //! Ambient reflection. - vec4 Ambient; - - //! Diffuse reflection. - vec4 Diffuse; - - //! Specular reflection. - vec4 Specular; - - //! Specular exponent. - float Shininess; - - //! Transparency coefficient. - float Transparency; -}; - -//! OCCT view-space clipping plane. -const int occEquationCoordsView = 0; - -//! OCCT world-space clipping plane. -const int occEquationCoordsWorld = 1; - -//! Parameters of OCCT clipping plane. -struct occClipPlane -{ - //! Plane equation. - vec4 Equation; - - //! Equation space. - int Space; -}; - -#ifdef VERTEX_SHADER - -///////////////////////////////////////////////////////////////////// -// OCCT vertex attributes +#define THE_MAX_LIGHTS 8 +#define THE_MAX_CLIP_PLANES 8 +// Vertex attributes // Note: At the moment, we just 'rename' the default OpenGL // vertex attributes from compatibility profile. In the next // release old functionality will be removed from shader API. - -//! Vertex color. -#define occColor gl_Color - -//! Normal coordinates. -#define occNormal gl_Normal - -//! Vertex coordinates. -#define occVertex gl_Vertex - -//! Texture coordinates. -#define occTexCoord gl_MultiTexCoord0 - +#ifdef VERTEX_SHADER + #define occColor gl_Color //!< Vertex color + #define occNormal gl_Normal //!< Normal coordinates + #define occVertex gl_Vertex //!< Vertex coordinates + #define occTexCoord gl_MultiTexCoord0 //!< Texture coordinates #endif -///////////////////////////////////////////////////////////////////// -// OCCT matrix state +// Matrix state +uniform mat4 occWorldViewMatrix; //!< World-view matrix +uniform mat4 occProjectionMatrix; //!< Projection matrix +uniform mat4 occModelWorldMatrix; //!< Model-world matrix -//! World-view matrix. -uniform mat4 occWorldViewMatrix; +uniform mat4 occWorldViewMatrixInverse; //!< Inverse of the world-view matrix +uniform mat4 occProjectionMatrixInverse; //!< Inverse of the projection matrix +uniform mat4 occModelWorldMatrixInverse; //!< Inverse of the model-world matrix -//! Projection matrix. -uniform mat4 occProjectionMatrix; +uniform mat4 occWorldViewMatrixTranspose; //!< Transpose of the world-view matrix +uniform mat4 occProjectionMatrixTranspose; //!< Transpose of the projection matrix +uniform mat4 occModelWorldMatrixTranspose; //!< Transpose of the model-world matrix -//! Model-world matrix. -uniform mat4 occModelWorldMatrix; +uniform mat4 occWorldViewMatrixInverseTranspose; //!< Transpose of the inverse of the world-view matrix +uniform mat4 occProjectionMatrixInverseTranspose; //!< Transpose of the inverse of the projection matrix +uniform mat4 occModelWorldMatrixInverseTranspose; //!< Transpose of the inverse of the model-world matrix -//------------------------------------------------------- +// light type enumeration +const int OccLightType_Direct = 1; //!< directional light source +const int OccLightType_Point = 2; //!< isotropic point light source +const int OccLightType_Spot = 3; //!< spot light source -//! Inverse of the world-view matrix. -uniform mat4 occWorldViewMatrixInverse; +// Light sources +uniform vec4 occLightAmbient; //!< Cumulative ambient color +uniform int occLightSourcesCount; //!< Total number of light sources +int occLight_Type (in int theId); //!< Type of light source +int occLight_IsHeadlight (in int theId); //!< Is light a headlight? +vec4 occLight_Diffuse (in int theId); //!< Diffuse intensity for specified light source +vec4 occLight_Specular (in int theId); //!< Specular intensity (currently - equals to diffuse intencity) +vec4 occLight_Position (in int theId); //!< Position of specified light source +vec4 occLight_SpotDirection (in int theId); //!< Direction of specified spot light source +float occLight_ConstAttenuation (in int theId); //!< Const attenuation factor of positional light source +float occLight_LinearAttenuation (in int theId); //!< Linear attenuation factor of positional light source +float occLight_SpotCutOff (in int theId); //!< Maximum spread angle of the spot light (in radians) +float occLight_SpotExponent (in int theId); //!< Attenuation of the spot light intensity (from 0 to 1) -//! Inverse of the projection matrix. -uniform mat4 occProjectionMatrixInverse; +// Front material properties accessors +vec4 occFrontMaterial_Emission(void); //!< Emission color +vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection +vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection +vec4 occFrontMaterial_Specular(void); //!< Specular reflection +float occFrontMaterial_Shininess(void); //!< Specular exponent +float occFrontMaterial_Transparency(void); //!< Transparency coefficient -//! Inverse of the model-world matrix. -uniform mat4 occModelWorldMatrixInverse; +// Front material properties accessors +vec4 occBackMaterial_Emission(void); //!< Emission color +vec4 occBackMaterial_Ambient(void); //!< Ambient reflection +vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection +vec4 occBackMaterial_Specular(void); //!< Specular reflection +float occBackMaterial_Shininess(void); //!< Specular exponent +float occBackMaterial_Transparency(void); //!< Transparency coefficient -//------------------------------------------------------- +uniform int occDistinguishingMode; //!< Are front and back faces distinguished? +uniform int occTextureEnable; //!< Is texture enabled? +uniform sampler2D occActiveSampler; //!< Current active sampler -//! Transpose of the world-view matrix. -uniform mat4 occWorldViewMatrixTranspose; +// clipping planes state +const int OccEquationCoords_View = 0; //!< view-space clipping plane +const int OccEquationCoords_World = 1; //!< world-space clipping plane -//! Transpose of the projection matrix. -uniform mat4 occProjectionMatrixTranspose; - -//! Transpose of the model-world matrix. -uniform mat4 occModelWorldMatrixTranspose; - -//------------------------------------------------------- - -//! Transpose of the inverse of the world-view matrix. -uniform mat4 occWorldViewMatrixInverseTranspose; - -//! Transpose of the inverse of the projection matrix. -uniform mat4 occProjectionMatrixInverseTranspose; - -//! Transpose of the inverse of the model-world matrix. -uniform mat4 occModelWorldMatrixInverseTranspose; - -///////////////////////////////////////////////////////////////////// -// OCCT light source state - -//! Array of OCCT light sources. -uniform occLightSource occLightSources[_OCC_MAX_LIGHTS_]; - -//! Total number of OCCT light sources. -uniform int occLightSourcesCount; - -///////////////////////////////////////////////////////////////////// -// OCCT material state - -//! Parameters of OCCT back material. -uniform occMaterialParams occBackMaterial; - -//! Parameters of OCCT front material. -uniform occMaterialParams occFrontMaterial; - -//! Are front and back faces distinguished? -uniform int occDistinguishingMode; - -//! Is texture enabled? -uniform int occTextureEnable; - -//! Current active sampler. -uniform sampler2D occActiveSampler; - -///////////////////////////////////////////////////////////////////// -// OCCT clipping planes state - -uniform occClipPlane occClipPlanes[_OCC_MAX_CLIP_PLANES_]; +//! Parameters of clipping planes +uniform vec4 occClipPlaneEquations[THE_MAX_CLIP_PLANES]; +uniform int occClipPlaneSpaces [THE_MAX_CLIP_PLANES]; diff --git a/src/Shaders/DeclarationsImpl.glsl b/src/Shaders/DeclarationsImpl.glsl new file mode 100644 index 0000000000..9139789bd1 --- /dev/null +++ b/src/Shaders/DeclarationsImpl.glsl @@ -0,0 +1,37 @@ +// This file includes implementation of common functions and properties accessors + +// arrays of light sources +uniform ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types +uniform vec4 occLightSources[THE_MAX_LIGHTS * 4]; //!< packed light sources parameters + +// light source properties accessors +int occLight_Type (in int theId) { return occLightSourcesTypes[theId].x; } +int occLight_IsHeadlight (in int theId) { return occLightSourcesTypes[theId].y; } +vec4 occLight_Diffuse (in int theId) { return occLightSources[theId * 4 + 0]; } +vec4 occLight_Specular (in int theId) { return occLightSources[theId * 4 + 0]; } +vec4 occLight_Position (in int theId) { return occLightSources[theId * 4 + 1]; } +vec4 occLight_SpotDirection (in int theId) { return occLightSources[theId * 4 + 2]; } +float occLight_ConstAttenuation (in int theId) { return occLightSources[theId * 4 + 3].x; } +float occLight_LinearAttenuation (in int theId) { return occLightSources[theId * 4 + 3].y; } +float occLight_SpotCutOff (in int theId) { return occLightSources[theId * 4 + 3].z; } +float occLight_SpotExponent (in int theId) { return occLightSources[theId * 4 + 3].w; } + +// material state +uniform vec4 occFrontMaterial[5]; +uniform vec4 occBackMaterial[5]; + +// front material properties accessors +vec4 occFrontMaterial_Emission(void) { return occFrontMaterial[0]; } +vec4 occFrontMaterial_Ambient(void) { return occFrontMaterial[1]; } +vec4 occFrontMaterial_Diffuse(void) { return occFrontMaterial[2]; } +vec4 occFrontMaterial_Specular(void) { return occFrontMaterial[3]; } +float occFrontMaterial_Shininess(void) { return occFrontMaterial[4].x; } +float occFrontMaterial_Transparency(void) { return occFrontMaterial[4].y; } + +// back material properties accessors +vec4 occBackMaterial_Emission(void) { return occBackMaterial[0]; } +vec4 occBackMaterial_Ambient(void) { return occBackMaterial[1]; } +vec4 occBackMaterial_Diffuse(void) { return occBackMaterial[2]; } +vec4 occBackMaterial_Specular(void) { return occBackMaterial[3]; } +float occBackMaterial_Shininess(void) { return occBackMaterial[4].x; } +float occBackMaterial_Transparency(void) { return occBackMaterial[4].y; } diff --git a/src/Shaders/PhongShading.fs b/src/Shaders/PhongShading.fs index 70fb9491de..1b0779f026 100644 --- a/src/Shaders/PhongShading.fs +++ b/src/Shaders/PhongShading.fs @@ -17,46 +17,22 @@ // 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; +varying vec3 View; //!< Direction to the viewer +varying vec3 Normal; //!< Vertex normal in view space +varying vec4 Position; //!< Vertex position in view space. -//! Vertex normal in view space. -varying vec3 Normal; +vec3 Ambient; //!< Ambient contribution of light sources +vec3 Diffuse; //!< Diffuse contribution of light sources +vec3 Specular; //!< Specular contribution of light sources -//! 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, +//! Computes contribution of isotropic point light source +void pointLight (in int theId, in vec3 theNormal, in vec3 theView, in vec3 thePoint) { - vec3 aLight = occLightSources[theIndex].Position; - if (occLightSources[theIndex].Head == 0) + vec3 aLight = occLight_Position (theId).xyz; + if (occLight_IsHeadlight (theId) == 0) { aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0)); } @@ -64,107 +40,86 @@ void PointLight (in int theIndex, float aDist = length (aLight); aLight = aLight * (1.0 / aDist); - - float anAttenuation = 1.0 / (occLightSources[theIndex].ConstAttenuation + - occLightSources[theIndex].LinearAttenuation * aDist); + + float anAtten = 1.0 / (occLight_ConstAttenuation (theId) + + occLight_LinearAttenuation (theId) * aDist); vec3 aHalf = normalize (aLight + theView); float aNdotL = max (0.0, dot (theNormal, aLight)); - float aNdotH = max (0.0, dot (theNormal, aHalf)); + float aNdotH = max (0.0, dot (theNormal, aHalf )); float aSpecl = 0.0; if (aNdotL > 0.0) { - aSpecl = pow (aNdotH, occFrontMaterial.Shininess); + aSpecl = pow (aNdotH, occFrontMaterial_Shininess()); } - - Ambient += occLightSources[theIndex].Ambient * anAttenuation; - Diffuse += occLightSources[theIndex].Diffuse * aNdotL * anAttenuation; - Specular += occLightSources[theIndex].Specular * aSpecl * anAttenuation; + + Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten; + Specular += occLight_Specular (theId).rgb * aSpecl * anAtten; } -// ======================================================================= -// function : DirectionalLight -// purpose : Computes contribution of OCCT directional light source -// ======================================================================= -void DirectionalLight (in int theIndex, +//! Computes contribution of directional light source +void directionalLight (in int theId, in vec3 theNormal, in vec3 theView) { - vec3 aLight = normalize (occLightSources[theIndex].Position); - - if (occLightSources[theIndex].Head == 0) + vec3 aLight = normalize (occLight_Position (theId).xyz); + if (occLight_IsHeadlight (theId) == 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 aNdotH = max (0.0, dot (theNormal, aHalf )); float aSpecl = 0.0; - if (aNdotL > 0.0) { - aSpecl = pow (aNdotH, occFrontMaterial.Shininess); + aSpecl = pow (aNdotH, occFrontMaterial_Shininess()); } - Ambient += occLightSources[theIndex].Ambient; - Diffuse += occLightSources[theIndex].Diffuse * aNdotL; - Specular += occLightSources[theIndex].Specular * aSpecl; + Diffuse += occLight_Diffuse (theId).rgb * aNdotL; + Specular += occLight_Specular (theId).rgb * aSpecl; } -// ======================================================================= -// function : ComputeLighting -// purpose : Computes illumination from OCCT light sources -// ======================================================================= -vec4 ComputeLighting (in vec3 theNormal, +//! Computes illumination from light sources +vec4 computeLighting (in vec3 theNormal, in vec3 theView, in vec4 thePoint) { // Clear the light intensity accumulators - Ambient = vec3 (0.0); + Ambient = occLightAmbient.rgb; 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) + int aType = occLight_Type (anIndex); + if (aType == OccLightType_Direct) { - AmbientLight (anIndex); + directionalLight (anIndex, theNormal, theView); + } + else if (aType == OccLightType_Point) + { + pointLight (anIndex, theNormal, theView, aPoint); + } + else if (aType == OccLightType_Spot) + { + // Not implemented } - 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; + + 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 -// ======================================================================= +//! Entry point to the Fragment Shader void main() { - gl_FragColor = ComputeLighting (normalize (Normal), + gl_FragColor = computeLighting (normalize (Normal), normalize (View), Position); } diff --git a/src/Shaders/PhongShading.vs b/src/Shaders/PhongShading.vs index 3f7104d3f8..ec613acf0a 100644 --- a/src/Shaders/PhongShading.vs +++ b/src/Shaders/PhongShading.vs @@ -17,42 +17,27 @@ // 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; +varying vec3 View; //!< Direction to the viewer +varying vec3 Normal; //!< Vertex normal in view space +varying vec4 Position; //!< Vertex position in view space -//! 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 -// ======================================================================= +//! Computes the normal in view space vec3 TransformNormal (in vec3 theNormal) { - vec4 aResult = occWorldViewMatrixInverseTranspose * - occModelWorldMatrixInverseTranspose * vec4 (theNormal, 0.0); - + vec4 aResult = occWorldViewMatrixInverseTranspose + * occModelWorldMatrixInverseTranspose + * vec4 (theNormal, 0.0); return normalize (aResult.xyz); } -// ======================================================================= -// function : main -// purpose : Entry point to the vertex shader -// ======================================================================= +//! 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 + Position = occWorldViewMatrix * occModelWorldMatrix * occVertex; // position in the view space + Normal = TransformNormal (occNormal); // normal in the view space + + // 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 diff --git a/src/V3d/V3d_Light.cdl b/src/V3d/V3d_Light.cdl index d645083e93..b057228cea 100755 --- a/src/V3d/V3d_Light.cdl +++ b/src/V3d/V3d_Light.cdl @@ -106,6 +106,10 @@ is ---Level: Public ---Purpose: returns true if the light is a headlight + SetHeadlight( me : mutable; theValue : Boolean from Standard ) is static; + ---Level: Public + ---Purpose: Setup headlight flag. + IsDisplayed( me ) returns Boolean from Standard; ---Level: Public ---Purpose: Returns TRUE when a light representation is displayed diff --git a/src/V3d/V3d_Light.cxx b/src/V3d/V3d_Light.cxx index ca1928c194..a392122766 100755 --- a/src/V3d/V3d_Light.cxx +++ b/src/V3d/V3d_Light.cxx @@ -114,6 +114,11 @@ Standard_Boolean V3d_Light::Headlight() const { return MyLight->Headlight(); } +void V3d_Light::SetHeadlight (const Standard_Boolean theValue) +{ + MyLight->SetHeadlight (theValue); +} + void V3d_Light::SymetricPointOnSphere (const Handle(V3d_View)& aView, const Graphic3d_Vertex &Center, const Graphic3d_Vertex &aPoint, const Standard_Real Rayon, Standard_Real& X, Standard_Real& Y, Standard_Real& Z, Standard_Real& VX, Standard_Real& VY, Standard_Real& VZ ) { Standard_Real X0,Y0,Z0,XP,YP,ZP; diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index f764a1f20b..55aec6f739 100755 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -42,7 +42,12 @@ #include #include #include +#include +#include #include +#include +#include +#include #include #include #include @@ -61,8 +66,6 @@ #include #include #include -#include -#include #include #include #include @@ -5352,6 +5355,449 @@ static int VDefaults (Draw_Interpretor& theDi, return 0; } +//! Auxiliary method +inline void addLight (const Handle(V3d_Light)& theLightNew, + const Standard_Boolean theIsGlobal) +{ + if (theLightNew.IsNull()) + { + return; + } + + if (theIsGlobal) + { + ViewerTest::GetViewerFromContext()->SetLightOn (theLightNew); + } + else + { + ViewerTest::CurrentView()->SetLightOn (theLightNew); + } +} + +//! Auxiliary method +inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext) +{ + TCollection_AsciiString anArgNextCase (theArgNext); + anArgNextCase.UpperCase(); + if (anArgNextCase.Length() > 5 + && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT")) + { + return theArgNext.SubString (6, theArgNext.Length()).IntegerValue(); + } + else + { + return theArgNext.IntegerValue(); + } +} + +//=============================================================================================== +//function : VLight +//purpose : +//=============================================================================================== +static int VLight (Draw_Interpretor& theDi, + Standard_Integer theArgsNb, + const char** theArgVec) +{ + Handle(V3d_View) aView = ViewerTest::CurrentView(); + Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext(); + if (aView.IsNull() + || aViewer.IsNull()) + { + std::cerr << "No active viewer!\n"; + return 1; + } + + Standard_Real anXYZ[3]; + Quantity_Coefficient anAtten[2]; + if (theArgsNb < 2) + { + // print lights info + Standard_Integer aLightId = 0; + for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightId) + { + Handle(V3d_Light) aLight = aView->ActiveLight(); + const Quantity_Color aColor = aLight->Color(); + theDi << "Light" << aLightId << "\n"; + switch (aLight->Type()) + { + case V3d_AMBIENT: + { + theDi << " Type: Ambient\n"; + break; + } + case V3d_DIRECTIONAL: + { + Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLight); + theDi << " Type: Directional\n"; + theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"; + if (!aLightDir.IsNull()) + { + aLightDir->Position (anXYZ[0], anXYZ[1], anXYZ[2]); + theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; + aLightDir->Direction (anXYZ[0], anXYZ[1], anXYZ[2]); + theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; + } + break; + } + case V3d_POSITIONAL: + { + Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight)::DownCast (aLight); + theDi << " Type: Positional\n"; + theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"; + if (!aLightPos.IsNull()) + { + aLightPos->Position (anXYZ[0], anXYZ[1], anXYZ[2]); + theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; + aLightPos->Attenuation (anAtten[0], anAtten[1]); + theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n"; + } + break; + } + case V3d_SPOT: + { + Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight)::DownCast (aLight); + theDi << " Type: Spot\n"; + theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"; + if (!aLightSpot.IsNull()) + { + aLightSpot->Position (anXYZ[0], anXYZ[1], anXYZ[2]); + theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; + aLightSpot->Direction (anXYZ[0], anXYZ[1], anXYZ[2]); + theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; + aLightSpot->Attenuation (anAtten[0], anAtten[1]); + theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n"; + theDi << " Angle: " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n"; + theDi << " Exponent: " << aLightSpot->Concentration() << "\n"; + } + break; + } + default: + { + theDi << " Type: UNKNOWN\n"; + break; + } + } + theDi << " Color: " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << "\n"; + } + } + + Handle(V3d_Light) aLightNew; + Handle(V3d_Light) aLightOld; + Standard_Boolean isGlobal = Standard_True; + Standard_Boolean toCreate = Standard_False; + for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt) + { + Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew; + Handle(V3d_AmbientLight) aLightAmb = Handle(V3d_AmbientLight) ::DownCast (aLightCurr); + Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLightCurr); + Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight) ::DownCast (aLightCurr); + Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight) ::DownCast (aLightCurr); + + TCollection_AsciiString aName, aValue; + const TCollection_AsciiString anArg (theArgVec[anArgIt]); + TCollection_AsciiString anArgCase (anArg); + anArgCase.UpperCase(); + if (anArgCase.IsEqual ("NEW") + || anArgCase.IsEqual ("ADD") + || anArgCase.IsEqual ("CREATE")) + { + toCreate = Standard_True; + } + else if (anArgCase.IsEqual ("GLOB") + || anArgCase.IsEqual ("GLOBAL")) + { + isGlobal = Standard_True; + } + else if (anArgCase.IsEqual ("LOC") + || anArgCase.IsEqual ("LOCAL")) + { + isGlobal = Standard_False; + } + else if (anArgCase.IsEqual ("AMB") + || anArgCase.IsEqual ("AMBIENT") + || anArgCase.IsEqual ("AMBLIGHT")) + { + addLight (aLightNew, isGlobal); + if (!toCreate) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + toCreate = Standard_False; + aLightNew = new V3d_AmbientLight (aViewer); + } + else if (anArgCase.IsEqual ("DIRECTIONAL") + || anArgCase.IsEqual ("DIRLIGHT")) + { + addLight (aLightNew, isGlobal); + if (!toCreate) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + toCreate = Standard_False; + aLightNew = new V3d_DirectionalLight (aViewer); + } + else if (anArgCase.IsEqual ("SPOT") + || anArgCase.IsEqual ("SPOTLIGHT")) + { + addLight (aLightNew, isGlobal); + if (!toCreate) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + toCreate = Standard_False; + aLightNew = new V3d_SpotLight (aViewer, 0.0, 0.0, 0.0); + } + else if (anArgCase.IsEqual ("POSLIGHT") + || anArgCase.IsEqual ("POSITIONAL")) + { + addLight (aLightNew, isGlobal); + if (!toCreate) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + toCreate = Standard_False; + aLightNew = new V3d_PositionalLight (aViewer, 0.0, 0.0, 0.0); + } + else if (anArgCase.IsEqual ("CHANGE")) + { + addLight (aLightNew, isGlobal); + aLightNew.Nullify(); + if (++anArgIt >= theArgsNb) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]); + Standard_Integer aLightIt = 0; + for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightIt) + { + if (aLightIt == aLightId) + { + aLightOld = aView->ActiveLight(); + break; + } + } + + if (aLightOld.IsNull()) + { + std::cerr << "Light " << theArgVec[anArgIt] << " is undefined!\n"; + return 1; + } + } + else if (anArgCase.IsEqual ("DEL") + || anArgCase.IsEqual ("DELETE")) + { + Handle(V3d_Light) aLightDel; + if (++anArgIt >= theArgsNb) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + const TCollection_AsciiString anArgNext (theArgVec[anArgIt]); + const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]); + Standard_Integer aLightIt = 0; + for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightIt) + { + aLightDel = aView->ActiveLight(); + if (aLightIt == aLightDelId) + { + break; + } + } + if (!aLightDel.IsNull()) + { + aViewer->DelLight (aLightDel); + } + } + else if (anArgCase.IsEqual ("COLOR") + || anArgCase.IsEqual ("COLOUR")) + { + if (++anArgIt >= theArgsNb) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + TCollection_AsciiString anArgNext (theArgVec[anArgIt]); + anArgNext.UpperCase(); + const Quantity_Color aColor = ViewerTest::GetColorFromName (anArgNext.ToCString()); + if (!aLightCurr.IsNull()) + { + aLightCurr->SetColor (aColor); + } + } + else if (anArgCase.IsEqual ("POS") + || anArgCase.IsEqual ("POSITION")) + { + if ((anArgIt + 3) >= theArgsNb) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + anXYZ[0] = Atof (theArgVec[++anArgIt]); + anXYZ[1] = Atof (theArgVec[++anArgIt]); + anXYZ[2] = Atof (theArgVec[++anArgIt]); + if (!aLightDir.IsNull()) + { + aLightDir->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]); + } + else if (!aLightPos.IsNull()) + { + aLightPos->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]); + } + else if (!aLightSpot.IsNull()) + { + aLightSpot->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]); + } + else + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + } + else if (anArgCase.IsEqual ("DIR") + || anArgCase.IsEqual ("DIRECTION")) + { + if ((anArgIt + 3) >= theArgsNb) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + anXYZ[0] = Atof (theArgVec[++anArgIt]); + anXYZ[1] = Atof (theArgVec[++anArgIt]); + anXYZ[2] = Atof (theArgVec[++anArgIt]); + if (!aLightDir.IsNull()) + { + aLightDir->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]); + } + else if (!aLightSpot.IsNull()) + { + aLightSpot->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]); + } + else + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + } + else if (anArgCase.IsEqual ("CONSTATTEN") + || anArgCase.IsEqual ("CONSTATTENUATION")) + { + if (++anArgIt >= theArgsNb) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + if (!aLightPos.IsNull()) + { + aLightPos->Attenuation (anAtten[0], anAtten[1]); + anAtten[0] = Atof (theArgVec[anArgIt]); + aLightPos->SetAttenuation (anAtten[0], anAtten[1]); + } + else if (!aLightSpot.IsNull()) + { + aLightSpot->Attenuation (anAtten[0], anAtten[1]); + anAtten[0] = Atof (theArgVec[anArgIt]); + aLightSpot->SetAttenuation (anAtten[0], anAtten[1]); + } + else + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + } + else if (anArgCase.IsEqual ("LINATTEN") + || anArgCase.IsEqual ("LINEARATTEN") + || anArgCase.IsEqual ("LINEARATTENUATION")) + { + if (++anArgIt >= theArgsNb) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + if (!aLightPos.IsNull()) + { + aLightPos->Attenuation (anAtten[0], anAtten[1]); + anAtten[1] = Atof (theArgVec[anArgIt]); + aLightPos->SetAttenuation (anAtten[0], anAtten[1]); + } + else if (!aLightSpot.IsNull()) + { + aLightSpot->Attenuation (anAtten[0], anAtten[1]); + anAtten[1] = Atof (theArgVec[anArgIt]); + aLightSpot->SetAttenuation (anAtten[0], anAtten[1]); + } + else + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + } + else if (anArgCase.IsEqual ("EXP") + || anArgCase.IsEqual ("EXPONENT") + || anArgCase.IsEqual ("SPOTEXP") + || anArgCase.IsEqual ("SPOTEXPONENT")) + { + if (++anArgIt >= theArgsNb) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + if (!aLightSpot.IsNull()) + { + aLightSpot->SetConcentration (Atof (theArgVec[anArgIt])); + } + else + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + } + else if (anArgCase.IsEqual ("HEAD") + || anArgCase.IsEqual ("HEADLIGHT")) + { + if (++anArgIt >= theArgsNb) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + if (aLightAmb.IsNull() + && !aLightCurr.IsNull()) + { + aLightCurr->SetHeadlight (Draw::Atoi (theArgVec[anArgIt]) != 0); + } + else + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + } + else + { + std::cerr << "Warning: unknown argument '" << anArg << "'\n"; + } + } + + addLight (aLightNew, isGlobal); + aViewer->UpdateLights(); + + return 0; +} + + + //============================================================================== //function : VClInfo //purpose : Prints info about active OpenCL device @@ -5749,6 +6195,13 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) theCommands.Add("vdefaults", "vdefaults [absDefl=value] [devCoeff=value] [angDefl=value]", __FILE__, VDefaults, group); + theCommands.Add("vlight", + "vlight [add|new {amb}ient|directional|{spot}light|positional]" + "\n\t\t: [{del}ete|change lightId] [local|global]" + "\n\t\t: [{pos}ition X Y Z] [color colorName] [{head}light 0|1]" + "\n\t\t: [{constAtten}uation value] [{linearAtten}uation value]" + "\n\t\t: [angle angleDeg] [{spotexp}onent value]", + __FILE__, VLight, group); theCommands.Add("vraytrace", "vraytrace 0|1", __FILE__,VRaytrace,group); diff --git a/src/Visual3d/Visual3d_Light.cdl b/src/Visual3d/Visual3d_Light.cdl index a77a1e5a46..72d875d096 100755 --- a/src/Visual3d/Visual3d_Light.cdl +++ b/src/Visual3d/Visual3d_Light.cdl @@ -17,7 +17,6 @@ -- purpose or non-infringement. Please see the License for the specific terms -- and conditions governing the rights and limitations under the License. - class Light from Visual3d inherits TShared ---Version: @@ -43,17 +42,15 @@ class Light from Visual3d inherits TShared uses - Color from Quantity, - - CLight from Graphic3d, - Vector from Graphic3d, - Vertex from Graphic3d, - - TypeOfLightSource from Visual3d + Color from Quantity, + CLight from Graphic3d, + Vector from Graphic3d, + Vertex from Graphic3d, + TypeOfLightSource from Visual3d raises - LightDefinitionError from Visual3d + LightDefinitionError from Visual3d is @@ -207,12 +204,16 @@ is -- Category: Inquire methods ---------------------------- - Headlight ( me ) - returns Boolean from Standard is static; - ---Level: Public - ---Purpose: Returns the headlight state of the light - ---Category: Inquire methods - + Headlight ( me ) + returns Boolean from Standard is static; + ---Level: Public + ---Purpose: Returns the headlight state of the light + ---Category: Inquire methods + + SetHeadlight( me : mutable; theValue : Boolean from Standard ) is static; + ---Level: Public + ---Purpose: Setup headlight flag. + Color ( me ) returns Color from Quantity is static; ---Level: Public @@ -279,6 +280,14 @@ is -- if the type of the light is not TOLS_SPOT. raises LightDefinitionError is static; + CLight ( me ) + returns CLight from Graphic3d + is static; + ---C++: return const & + ---Level: Public + ---Purpose: Returns the light defintion. + ---Category: Inquire methods + -------------------------- -- Category: Class methods -------------------------- @@ -309,32 +318,12 @@ is -- spot light spread angle. ---Category: Private methods --- +-- fields --- --- Class : Visual3d_Light --- --- Purpose : Declaration of variables specific to light sources --- --- Reminder : A light source is defined by: --- - its type --- - its colour --- - the attenuation factor ( positional and spot only) --- - its angle ( spot only ) --- - its concentration ( spot only ) --- - its direction ( directional and spot only ) --- - its position ( positional and spot only ) --- --- It is actived in a context of view. --- - - -- the type - MyType : TypeOfLightSource from Visual3d; - - -- the associated C structure - MyCLight : CLight from Graphic3d; + -- the associated C structure + myCLight : CLight from Graphic3d; friends diff --git a/src/Visual3d/Visual3d_Light.cxx b/src/Visual3d/Visual3d_Light.cxx index 549ceaa8d5..4687a9ee99 100755 --- a/src/Visual3d/Visual3d_Light.cxx +++ b/src/Visual3d/Visual3d_Light.cxx @@ -16,509 +16,378 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. -/*********************************************************************** - - FUNCTION : - ---------- - File Visual3d_Light : - - Declaration of variables specific to light sources - - NOTES: - ---------- - - A light source is defined by : - - type - - color - - reduction factors ( for positional and spot only ) - - its angle ( for spot only ) - - its concentration ( for spot only ) - - its direction ( directional and spot only ) - - its position ( positional and spot only ) - - It is active in a view, in the associated context. - - ATTENTION: - ---------- - - - AngleCone is given in radian [Pex] while OpenGl works in - degreees. The limits for Pex are [0,PI] while for OpenGl this is [0,90]. - - Two reduction factors are used with Pex while OpenGl uses three. - - The ereduction factors have range [0.0,1.0] for Pex and - for OpenGl the range is [0.0,n] - - The concentration varies from [0.,1.0] for Pex to [0,128] for OpenGl. - -************************************************************************/ - -/*----------------------------------------------------------------------*/ -/* - * Includes - */ - #include #include -/*----------------------------------------------------------------------*/ - -Visual3d_Light::Visual3d_Light (): -MyType (Visual3d_TOLS_AMBIENT) { - - MyCLight.WsId = -1; - MyCLight.ViewId = 0; /* not used */ - MyCLight.LightType = int (MyType); - MyCLight.Headlight = 0; - -Quantity_Color White (Quantity_NOC_WHITE); - - MyCLight.Color.r = float (White.Red ()); - MyCLight.Color.g = float (White.Green ()); - MyCLight.Color.b = float (White.Blue ()); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_False); - +// ======================================================================= +// function : Visual3d_Light +// purpose : +// ======================================================================= +Visual3d_Light::Visual3d_Light() +{ + myCLight.Type = Visual3d_TOLS_AMBIENT; } -/*----------------------------------------------------------------------*/ - -Visual3d_Light::Visual3d_Light (const Quantity_Color& Color): -MyType (Visual3d_TOLS_AMBIENT) { - - MyCLight.WsId = -1; - MyCLight.ViewId = 0; /* not used */ - MyCLight.LightType = int (MyType); - MyCLight.Headlight = 0; - - MyCLight.Color.r = float (Color.Red ()); - MyCLight.Color.g = float (Color.Green ()); - MyCLight.Color.b = float (Color.Blue ()); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_False); - +// ======================================================================= +// function : Visual3d_Light +// purpose : +// ======================================================================= +Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor) +{ + myCLight.Type = Visual3d_TOLS_AMBIENT; + myCLight.Color.r() = Standard_ShortReal (theColor.Red()); + myCLight.Color.g() = Standard_ShortReal (theColor.Green()); + myCLight.Color.b() = Standard_ShortReal (theColor.Blue()); } -/*----------------------------------------------------------------------*/ - -Visual3d_Light::Visual3d_Light(const Quantity_Color& Color,const Graphic3d_Vector& Direction,const Standard_Boolean Headlight): MyType (Visual3d_TOLS_DIRECTIONAL) { - - if (Direction.LengthZero ()) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightDirection"); - - MyCLight.WsId = -1; - MyCLight.ViewId = 0; /* not used */ - MyCLight.LightType = int (MyType); - MyCLight.Headlight = Headlight? 1:0; - -Standard_Real Norme, X, Y, Z; - - Color.Values (X, Y, Z, Quantity_TOC_RGB); - MyCLight.Color.r = float (X); - MyCLight.Color.g = float (Y); - MyCLight.Color.b = float (Z); - - Direction.Coord (X, Y, Z); - Norme = Sqrt (X*X+Y*Y+Z*Z); - // Direction.LengthZero () == Standard_False - MyCLight.Direction.x = float (X/Norme); - MyCLight.Direction.y = float (Y/Norme); - MyCLight.Direction.z = float (Z/Norme); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_False); +// ======================================================================= +// function : Visual3d_Light +// purpose : +// ======================================================================= +Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor, + const Graphic3d_Vector& theDir, + const Standard_Boolean theIsHeadlight) +{ + Visual3d_LightDefinitionError_Raise_if (theDir.LengthZero(), + "Bad value for LightDirection"); + myCLight.Type = Visual3d_TOLS_DIRECTIONAL; + myCLight.IsHeadlight = theIsHeadlight; + myCLight.Color.r() = Standard_ShortReal (theColor.Red()); + myCLight.Color.g() = Standard_ShortReal (theColor.Green()); + myCLight.Color.b() = Standard_ShortReal (theColor.Blue()); + Standard_Real X, Y, Z; + theDir.Coord (X, Y, Z); + const Standard_Real aNorm = Sqrt (X * X + Y * Y + Z * Z); + myCLight.Direction.x() = Standard_ShortReal (X / aNorm); + myCLight.Direction.y() = Standard_ShortReal (Y / aNorm); + myCLight.Direction.z() = Standard_ShortReal (Z / aNorm); } -/*----------------------------------------------------------------------*/ - -Visual3d_Light::Visual3d_Light (const Quantity_Color& Color, const Graphic3d_Vertex& Position, const Standard_Real Fact1, const Standard_Real Fact2): -MyType (Visual3d_TOLS_POSITIONAL) { - - if ( (Fact1 == 0.0) && (Fact2 == 0.0) ) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightAttenuation"); - - if ( (Fact1 < 0.0) || (Fact1 > 1.0) ) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightAttenuation"); - - if ( (Fact2 < 0.0) || (Fact2 > 1.0) ) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightAttenuation"); - - MyCLight.WsId = -1; - MyCLight.ViewId = 0; /* not used */ - MyCLight.LightType = int (MyType); - MyCLight.Headlight = 0; - - MyCLight.Color.r = float (Color.Red ()); - MyCLight.Color.g = float (Color.Green ()); - MyCLight.Color.b = float (Color.Blue ()); - - MyCLight.Position.x = float (Position.X ()); - MyCLight.Position.y = float (Position.Y ()); - MyCLight.Position.z = float (Position.Z ()); - - MyCLight.Attenuation[0] = float (Fact1); - MyCLight.Attenuation[1] = float (Fact2); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_False); - +// ======================================================================= +// function : Visual3d_Light +// purpose : +// ======================================================================= +Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor, + const Graphic3d_Vertex& thePos, + const Standard_Real theFact1, + const Standard_Real theFact2) +{ + Visual3d_LightDefinitionError_Raise_if ((theFact1 == 0.0 && theFact2 == 0.0) + || (theFact1 < 0.0 || theFact1 > 1.0) + || (theFact2 < 0.0 || theFact2 > 1.0), + "Bad value for LightAttenuation"); + myCLight.Type = Visual3d_TOLS_POSITIONAL; + myCLight.IsHeadlight = Standard_False; + myCLight.Color.r() = Standard_ShortReal (theColor.Red()); + myCLight.Color.g() = Standard_ShortReal (theColor.Green()); + myCLight.Color.b() = Standard_ShortReal (theColor.Blue()); + myCLight.Position.x() = Standard_ShortReal (thePos.X()); + myCLight.Position.y() = Standard_ShortReal (thePos.Y()); + myCLight.Position.z() = Standard_ShortReal (thePos.Z()); + myCLight.ChangeConstAttenuation() = Standard_ShortReal (theFact1); + myCLight.ChangeLinearAttenuation() = Standard_ShortReal (theFact2); } -/*----------------------------------------------------------------------*/ +// ======================================================================= +// function : Visual3d_Light +// purpose : +// ======================================================================= +Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor, + const Graphic3d_Vertex& thePos, + const Graphic3d_Vector& theDir, + const Standard_Real theConcentration, + const Standard_Real theFact1, + const Standard_Real theFact2, + const Standard_Real theAngleCone) +{ + Visual3d_LightDefinitionError_Raise_if (theDir.LengthZero(), + "Bad value for LightDirection"); + Visual3d_LightDefinitionError_Raise_if (theConcentration < 0.0 || theConcentration > 1.0, + "Bad value for LightConcentration"); + Visual3d_LightDefinitionError_Raise_if ((theFact1 == 0.0 && theFact2 == 0.0) + || (theFact1 < 0.0 || theFact1 > 1.0) + || (theFact2 < 0.0 || theFact2 > 1.0), + "Bad value for LightAttenuation"); + Visual3d_LightDefinitionError_Raise_if (!Visual3d_Light::IsValid (theAngleCone), + "Bad value for LightAngle"); + myCLight.Type = Visual3d_TOLS_SPOT; + myCLight.IsHeadlight = Standard_False; + myCLight.Color.r() = Standard_ShortReal (theColor.Red()); + myCLight.Color.g() = Standard_ShortReal (theColor.Green()); + myCLight.Color.b() = Standard_ShortReal (theColor.Blue()); + myCLight.Position.x() = Standard_ShortReal (thePos.X()); + myCLight.Position.y() = Standard_ShortReal (thePos.Y()); + myCLight.Position.z() = Standard_ShortReal (thePos.Z()); -Visual3d_Light::Visual3d_Light (const Quantity_Color& Color, const Graphic3d_Vertex& Position, const Graphic3d_Vector& Direction, const Standard_Real Concentration, const Standard_Real Fact1, const Standard_Real Fact2, const Standard_Real AngleCone): -MyType (Visual3d_TOLS_SPOT) { - - if (Direction.LengthZero ()) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightDirection"); - - if ( (Concentration < 0.0) || (Concentration > 1.0) ) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightConcentration"); - - if ( (Fact1 == 0.0) && (Fact2 == 0.0) ) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightAttenuation"); - - if ( (Fact1 < 0.0) || (Fact1 > 1.0) ) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightAttenuation"); - - if ( (Fact2 < 0.0) || (Fact2 > 1.0) ) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightAttenuation"); - - if (Visual3d_Light::IsValid (AngleCone)) { - - MyCLight.WsId = -1; - MyCLight.ViewId = 0; /* not used */ - MyCLight.LightType = int (MyType); - MyCLight.Headlight = 0; - -Standard_Real X, Y, Z; - - Color.Values (X, Y, Z, Quantity_TOC_RGB); - MyCLight.Color.r = float (X); - MyCLight.Color.g = float (Y); - MyCLight.Color.b = float (Z); - - Position.Coord (X, Y, Z); - MyCLight.Position.x = float (X); - MyCLight.Position.y = float (Y); - MyCLight.Position.z = float (Z); - - Direction.Coord (X, Y, Z); - MyCLight.Direction.x = float (X); - MyCLight.Direction.y = float (Y); - MyCLight.Direction.z = float (Z); - - MyCLight.Concentration = float (Concentration); - - MyCLight.Attenuation[0] = float (Fact1); - MyCLight.Attenuation[1] = float (Fact2); - - MyCLight.Angle = float (AngleCone); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_False); - - } - else - Visual3d_LightDefinitionError::Raise - ("Bad value for LightAngle"); + Standard_Real X, Y, Z; + theDir.Coord (X, Y, Z); + myCLight.Direction.x() = Standard_ShortReal (X); + myCLight.Direction.y() = Standard_ShortReal (Y); + myCLight.Direction.z() = Standard_ShortReal (Z); + myCLight.ChangeConcentration() = Standard_ShortReal (theConcentration); + myCLight.ChangeConstAttenuation() = Standard_ShortReal (theFact1); + myCLight.ChangeLinearAttenuation() = Standard_ShortReal (theFact2); + myCLight.ChangeAngle() = Standard_ShortReal (theAngleCone); } -/*----------------------------------------------------------------------*/ - -Quantity_Color Visual3d_Light::Color () const { - -Quantity_Color AColor (Standard_Real (MyCLight.Color.r), - Standard_Real (MyCLight.Color.g), - Standard_Real (MyCLight.Color.b), - Quantity_TOC_RGB); - - return (AColor); - +// ======================================================================= +// function : Color +// purpose : +// ======================================================================= +Quantity_Color Visual3d_Light::Color() const +{ + return Quantity_Color (Standard_Real (myCLight.Color.r()), + Standard_Real (myCLight.Color.g()), + Standard_Real (myCLight.Color.b()), + Quantity_TOC_RGB); } -/*----------------------------------------------------------------------*/ - -Visual3d_TypeOfLightSource Visual3d_Light::LightType () const { - - return (MyType); - +// ======================================================================= +// function : LightType +// purpose : +// ======================================================================= +Visual3d_TypeOfLightSource Visual3d_Light::LightType() const +{ + return (Visual3d_TypeOfLightSource )myCLight.Type; } -/*----------------------------------------------------------------------*/ -Standard_Boolean Visual3d_Light::Headlight () const { - return MyCLight.Headlight==0? Standard_False:Standard_True; +// ======================================================================= +// function : Headlight +// purpose : +// ======================================================================= +Standard_Boolean Visual3d_Light::Headlight() const +{ + return myCLight.IsHeadlight; } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::Values (Quantity_Color& Color) const { - -Quantity_Color AColor (Standard_Real (MyCLight.Color.r), - Standard_Real (MyCLight.Color.g), - Standard_Real (MyCLight.Color.b), - Quantity_TOC_RGB); - - if (MyType == Visual3d_TOLS_AMBIENT) - Color = AColor; - else Visual3d_LightDefinitionError::Raise - ("Light Type != Visual3d_TOLS_AMBIENT"); - +// ======================================================================= +// function : SetHeadlight +// purpose : +// ======================================================================= +void Visual3d_Light::SetHeadlight (const Standard_Boolean theValue) +{ + myCLight.IsHeadlight = theValue; } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::Values (Quantity_Color& Color, Graphic3d_Vector& Direction) const { - -Quantity_Color AColor (Standard_Real (MyCLight.Color.r), - Standard_Real (MyCLight.Color.g), - Standard_Real (MyCLight.Color.b), - Quantity_TOC_RGB); - -Graphic3d_Vector ADirection (Standard_Real (MyCLight.Direction.x), - Standard_Real (MyCLight.Direction.y), - Standard_Real (MyCLight.Direction.z)); - - if (MyType == Visual3d_TOLS_DIRECTIONAL) { - Color = AColor; - Direction = ADirection; - } - else Visual3d_LightDefinitionError::Raise - ("Light Type != Visual3d_TOLS_DIRECTIONAL"); - +// ======================================================================= +// function : Values +// purpose : +// ======================================================================= +void Visual3d_Light::Values (Quantity_Color& theColor) const +{ + Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_AMBIENT, + "Light Type != Visual3d_TOLS_AMBIENT"); + theColor.SetValues (Standard_Real (myCLight.Color.r()), + Standard_Real (myCLight.Color.g()), + Standard_Real (myCLight.Color.b()), + Quantity_TOC_RGB); } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::Values (Quantity_Color& Color, Graphic3d_Vertex& Position, Standard_Real& Fact1, Standard_Real& Fact2) const { - -Quantity_Color AColor (Standard_Real (MyCLight.Color.r), - Standard_Real (MyCLight.Color.g), - Standard_Real (MyCLight.Color.b), - Quantity_TOC_RGB); - -Graphic3d_Vertex APosition (Standard_Real (MyCLight.Position.x), - Standard_Real (MyCLight.Position.y), - Standard_Real (MyCLight.Position.z)); - - if (MyType == Visual3d_TOLS_POSITIONAL) { - Color = AColor; - Position = APosition; - Fact1 = Standard_Real (MyCLight.Attenuation[0]); - Fact2 = Standard_Real (MyCLight.Attenuation[1]); - } - else Visual3d_LightDefinitionError::Raise - ("Light Type != Visual3d_TOLS_POSITIONAL"); - +// ======================================================================= +// function : Values +// purpose : +// ======================================================================= +void Visual3d_Light::Values (Quantity_Color& theColor, + Graphic3d_Vector& theDir) const +{ + Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_DIRECTIONAL, + "Light Type != Visual3d_TOLS_DIRECTIONAL"); + theColor.SetValues (Standard_Real (myCLight.Color.r()), + Standard_Real (myCLight.Color.g()), + Standard_Real (myCLight.Color.b()), + Quantity_TOC_RGB); + theDir.SetCoord (Standard_Real (myCLight.Direction.x()), + Standard_Real (myCLight.Direction.y()), + Standard_Real (myCLight.Direction.z())); } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::Values (Quantity_Color& Color, Graphic3d_Vertex& Position, Graphic3d_Vector& Direction, Standard_Real& Concentration, Standard_Real& Fact1, Standard_Real& Fact2, Standard_Real& AngleCone) const { - -Quantity_Color AColor (Standard_Real (MyCLight.Color.r), - Standard_Real (MyCLight.Color.g), - Standard_Real (MyCLight.Color.b), - Quantity_TOC_RGB); - -Graphic3d_Vertex APosition (Standard_Real (MyCLight.Position.x), - Standard_Real (MyCLight.Position.y), - Standard_Real (MyCLight.Position.z)); - -Graphic3d_Vector ADirection (Standard_Real (MyCLight.Direction.x), - Standard_Real (MyCLight.Direction.y), - Standard_Real (MyCLight.Direction.z)); - - if (MyType == Visual3d_TOLS_SPOT) { - Color = AColor; - Position = APosition; - Direction = ADirection; - Concentration = Standard_Real (MyCLight.Concentration); - Fact1 = Standard_Real (MyCLight.Attenuation[0]); - Fact2 = Standard_Real (MyCLight.Attenuation[1]); - AngleCone = Standard_Real (MyCLight.Angle); - } - else Visual3d_LightDefinitionError::Raise - ("Light Type != Visual3d_TOLS_SPOT"); - +// ======================================================================= +// function : Values +// purpose : +// ======================================================================= +void Visual3d_Light::Values (Quantity_Color& theColor, + Graphic3d_Vertex& thePos, + Standard_Real& theFact1, + Standard_Real& theFact2) const +{ + Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_POSITIONAL, + "Light Type != Visual3d_TOLS_POSITIONAL"); + theColor.SetValues (Standard_Real (myCLight.Color.r()), + Standard_Real (myCLight.Color.g()), + Standard_Real (myCLight.Color.b()), + Quantity_TOC_RGB); + thePos.SetCoord (Standard_Real (myCLight.Position.x()), + Standard_Real (myCLight.Position.y()), + Standard_Real (myCLight.Position.z())); + theFact1 = Standard_Real (myCLight.ConstAttenuation()); + theFact2 = Standard_Real (myCLight.LinearAttenuation()); } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::SetAngle (const Standard_Real AngleCone) { - - if (! Visual3d_Light::IsValid (AngleCone)) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightAngle"); - - if (MyType == Visual3d_TOLS_SPOT) { - MyCLight.Angle = float (AngleCone); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_True); - - } - else Visual3d_LightDefinitionError::Raise - ("Light Type != Visual3d_TOLS_SPOT"); - +// ======================================================================= +// function : Values +// purpose : +// ======================================================================= +void Visual3d_Light::Values (Quantity_Color& theColor, + Graphic3d_Vertex& thePos, + Graphic3d_Vector& theDir, + Standard_Real& theConcentration, + Standard_Real& theFact1, + Standard_Real& theFact2, + Standard_Real& theAngleCone) const +{ + Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT, + "Light Type != Visual3d_TOLS_SPOT"); + theColor.SetValues (Standard_Real (myCLight.Color.r()), + Standard_Real (myCLight.Color.g()), + Standard_Real (myCLight.Color.b()), + Quantity_TOC_RGB); + thePos.SetCoord (Standard_Real (myCLight.Position.x()), + Standard_Real (myCLight.Position.y()), + Standard_Real (myCLight.Position.z())); + theDir.SetCoord (Standard_Real (myCLight.Direction.x()), + Standard_Real (myCLight.Direction.y()), + Standard_Real (myCLight.Direction.z())); + theConcentration = Standard_Real (myCLight.Concentration()); + theFact1 = Standard_Real (myCLight.ConstAttenuation()); + theFact2 = Standard_Real (myCLight.LinearAttenuation()); + theAngleCone = Standard_Real (myCLight.Angle()); } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::SetAttenuation1 (const Standard_Real Fact1) { - - if ( (Fact1 < 0.0) || (Fact1 > 1.0) ) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightAttenuation"); - - if ( (MyType == Visual3d_TOLS_POSITIONAL) || - (MyType == Visual3d_TOLS_SPOT) ) { - MyCLight.Attenuation[0] = float (Fact1); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_True); - - } - else Visual3d_LightDefinitionError::Raise - ("Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT"); - +// ======================================================================= +// function : SetAngle +// purpose : +// ======================================================================= +void Visual3d_Light::SetAngle (const Standard_Real theAngleCone) +{ + Visual3d_LightDefinitionError_Raise_if (!Visual3d_Light::IsValid (theAngleCone), + "Bad value for LightAngle"); + Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT, + "Light Type != Visual3d_TOLS_SPOT"); + myCLight.ChangeAngle() = Standard_ShortReal (theAngleCone); } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::SetAttenuation2 (const Standard_Real Fact2) { - - if ( (Fact2 < 0.0) || (Fact2 > 1.0) ) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightAttenuation"); - - if ( (MyType == Visual3d_TOLS_POSITIONAL) || - (MyType == Visual3d_TOLS_SPOT) ) { - MyCLight.Attenuation[1] = float (Fact2); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_True); - - } - else Visual3d_LightDefinitionError::Raise - ("Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT"); - +// ======================================================================= +// function : SetAttenuation1 +// purpose : +// ======================================================================= +void Visual3d_Light::SetAttenuation1 (const Standard_Real theFact1) +{ + Visual3d_LightDefinitionError_Raise_if (theFact1 < 0.0 || theFact1 > 1.0, + "Bad value for LightAttenuation"); + Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_POSITIONAL + && myCLight.Type != Visual3d_TOLS_SPOT, + "Light Type != Visual3d_TOLS_SPOT and != Visual3d_TOLS_POSITIONAL"); + myCLight.ChangeConstAttenuation() = Standard_ShortReal (theFact1); } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::SetColor (const Quantity_Color& Color) { - - MyCLight.Color.r = float (Color.Red ()); - MyCLight.Color.g = float (Color.Green ()); - MyCLight.Color.b = float (Color.Blue ()); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_True); - +// ======================================================================= +// function : SetAttenuation2 +// purpose : +// ======================================================================= +void Visual3d_Light::SetAttenuation2 (const Standard_Real theFact2) +{ + Visual3d_LightDefinitionError_Raise_if (theFact2 < 0.0 || theFact2 > 1.0, + "Bad value for LightAttenuation"); + Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_POSITIONAL + && myCLight.Type != Visual3d_TOLS_SPOT, + "Light Type != Visual3d_TOLS_SPOT and != Visual3d_TOLS_POSITIONAL"); + myCLight.ChangeLinearAttenuation() = Standard_ShortReal (theFact2); } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::SetConcentration (const Standard_Real Concentration) { - - if ( (Concentration < 0.0) || (Concentration > 1.0) ) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightConcentration"); - - if (MyType == Visual3d_TOLS_SPOT) { - MyCLight.Concentration = float (Concentration); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_True); - } - else Visual3d_LightDefinitionError::Raise - ("Light Type != Visual3d_TOLS_SPOT"); - +// ======================================================================= +// function : SetColor +// purpose : +// ======================================================================= +void Visual3d_Light::SetColor (const Quantity_Color& theColor) +{ + myCLight.Color.r() = float (theColor.Red()); + myCLight.Color.g() = float (theColor.Green()); + myCLight.Color.b() = float (theColor.Blue()); } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::SetDirection (const Graphic3d_Vector& Direction) { - - if (Direction.LengthZero ()) - Visual3d_LightDefinitionError::Raise - ("Bad value for LightDirection"); - - if ( (MyType == Visual3d_TOLS_DIRECTIONAL) || - (MyType == Visual3d_TOLS_SPOT) ) { - -Standard_Real Norme, X, Y, Z; - Direction.Coord (X, Y, Z); - Norme = Sqrt (X*X+Y*Y+Z*Z); - // Direction.LengthZero () == Standard_False - MyCLight.Direction.x = float (X/Norme); - MyCLight.Direction.y = float (Y/Norme); - MyCLight.Direction.z = float (Z/Norme); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_True); - - } - else Visual3d_LightDefinitionError::Raise - ("Light Type != Visual3d_TOLS_DIRECTIONAL and != Visual3d_TOLS_SPOT"); - +// ======================================================================= +// function : SetConcentration +// purpose : +// ======================================================================= +void Visual3d_Light::SetConcentration (const Standard_Real theConcentration) +{ + Visual3d_LightDefinitionError_Raise_if (theConcentration < 0.0 || theConcentration > 1.0, + "Bad value for LightConcentration"); + Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT, + "Light Type != Visual3d_TOLS_SPOT"); + myCLight.ChangeConcentration() = Standard_ShortReal (theConcentration); } -/*----------------------------------------------------------------------*/ - -void Visual3d_Light::SetPosition (const Graphic3d_Vertex& Position) { - - if ( (MyType == Visual3d_TOLS_POSITIONAL) || - (MyType == Visual3d_TOLS_SPOT) ) { - - MyCLight.Position.x = float (Position.X ()); - MyCLight.Position.y = float (Position.Y ()); - MyCLight.Position.z = float (Position.Z ()); - - MyCLight.LightId = - Graphic3d_GraphicDriver::Light (MyCLight, Standard_True); - - } - else Visual3d_LightDefinitionError::Raise - ("Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT"); - +// ======================================================================= +// function : SetDirection +// purpose : +// ======================================================================= +void Visual3d_Light::SetDirection (const Graphic3d_Vector& theDir) +{ + Visual3d_LightDefinitionError_Raise_if (theDir.LengthZero(), + "Bad value for LightDirection"); + Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT + && myCLight.Type != Visual3d_TOLS_DIRECTIONAL, + "Light Type != Visual3d_TOLS_DIRECTIONAL and != Visual3d_TOLS_SPOT"); + Standard_Real X, Y, Z; + theDir.Coord (X, Y, Z); + const Standard_Real aNorm = Sqrt (X * X + Y * Y + Z * Z); + myCLight.Direction.x() = float (X / aNorm); + myCLight.Direction.y() = float (Y / aNorm); + myCLight.Direction.z() = float (Z / aNorm); } -/*----------------------------------------------------------------------*/ - -Standard_Integer Visual3d_Light::Limit () { - - // Old method, replaced by GraphicDriver::InquireLightLimit () - return 0; - +// ======================================================================= +// function : SetPosition +// purpose : +// ======================================================================= +void Visual3d_Light::SetPosition (const Graphic3d_Vertex& thePos) +{ + Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT + && myCLight.Type != Visual3d_TOLS_POSITIONAL, + "Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT"); + myCLight.Position.x() = float (thePos.X()); + myCLight.Position.y() = float (thePos.Y()); + myCLight.Position.z() = float (thePos.Z()); } -/*----------------------------------------------------------------------*/ - -Standard_Integer Visual3d_Light::Identification () const { - - return (Standard_Integer (MyCLight.LightId)); - +// ======================================================================= +// function : Limit +// purpose : +// ======================================================================= +Standard_Integer Visual3d_Light::Limit() +{ + // Old method, replaced by GraphicDriver::InquireLightLimit() + return 0; } -/*----------------------------------------------------------------------*/ - -Standard_Boolean Visual3d_Light::IsValid (const Standard_Real AAngle) { - - return ( (AAngle < M_PI) && (AAngle >= 0.0) ); - +// ======================================================================= +// function : Identification +// purpose : +// ======================================================================= +Standard_Integer Visual3d_Light::Identification() const +{ + return 0; } -/*----------------------------------------------------------------------*/ +// ======================================================================= +// function : IsValid +// purpose : +// ======================================================================= +Standard_Boolean Visual3d_Light::IsValid (const Standard_Real theAngle) +{ + return (theAngle < M_PI) + && (theAngle >= 0.0); +} + +// ======================================================================= +// function : CLight +// purpose : +// ======================================================================= +const Graphic3d_CLight& Visual3d_Light::CLight() const +{ + return myCLight; +} diff --git a/src/Visual3d/Visual3d_View.cxx b/src/Visual3d/Visual3d_View.cxx index a39d89b90a..ecdce08f66 100755 --- a/src/Visual3d/Visual3d_View.cxx +++ b/src/Visual3d/Visual3d_View.cxx @@ -79,9 +79,6 @@ #define BUC60572 //GG_03-08-99 Add protection on Zclipping & Zcueing planes // positions. -#define BUC60570 //GG 14-09-99 Don't activates lighting -// when the view shading model is NONE. - #define GER61454 //GG 14-09-99 Activates model clipping planes #define RIC120302 //GG Add a NEW SetWindow method which enable @@ -706,148 +703,45 @@ Standard_Real Rap; } -void Visual3d_View::UpdateLights () { - -Standard_Integer i, j; -CALL_DEF_LIGHT *lights=NULL; - -#ifdef BUC60570 - if( MyContext.Model() == Visual3d_TOM_NONE ) { -// Activates only a white ambient light - MyCView.Context.NbActiveLight = 1; - lights = new CALL_DEF_LIGHT [MyCView.Context.NbActiveLight]; - MyCView.Context.ActiveLight = lights; - - lights[0].WsId = MyCView.ViewId; - lights[0].ViewId = MyCView.ViewId; - lights[0].LightType = int (Visual3d_TOLS_AMBIENT); - lights[0].Active = 1; - lights[0].LightId = 0; - lights[0].Headlight = 0; - lights[0].Color.r = lights[0].Color.g = lights[0].Color.b = 1.; - } else { -#endif - i = MyContext.NumberOfActivatedLights (); - j = MyGraphicDriver->InquireLightLimit (); - MyCView.Context.NbActiveLight = (i > j ? j : i); - - if (MyCView.Context.NbActiveLight > 0) { - - // Dynamic Allocation - lights = new CALL_DEF_LIGHT [MyCView.Context.NbActiveLight]; - - MyCView.Context.ActiveLight = lights; - -Standard_Real X, Y, Z; - -Standard_Real LightConcentration = 0.; -Standard_Real LightAttenuation1 = 0.; -Standard_Real LightAttenuation2 = 0.; -Standard_Real LightAngle = 0.; -Quantity_Color LightColor; -Graphic3d_Vertex LightPosition; -Graphic3d_Vector LightDirection; -Visual3d_TypeOfLightSource LightType=Visual3d_TOLS_AMBIENT; - - // Parcing of light sources - for (j=0; jLightType (); - - lights[j].WsId = MyCView.ViewId; - lights[j].ViewId = MyCView.ViewId; - - lights[j].LightType = int (LightType); - lights[j].Active = 1; - lights[j].LightId = - int ((MyContext.ActivatedLight (j+1))->Identification ()); - lights[j].Headlight = (MyContext.ActivatedLight (j+1))->Headlight ()? 1:0; - - switch (LightType) { - - case Visual3d_TOLS_AMBIENT : - (MyContext.ActivatedLight (j+1))->Values ( - LightColor - ); - break; - - case Visual3d_TOLS_POSITIONAL : - (MyContext.ActivatedLight (j+1))->Values ( - LightColor, - LightPosition, - LightAttenuation1, - LightAttenuation2 - ); - break; - - case Visual3d_TOLS_DIRECTIONAL : - (MyContext.ActivatedLight (j+1))->Values ( - LightColor, - LightDirection - ); - break; - - case Visual3d_TOLS_SPOT : - (MyContext.ActivatedLight (j+1))->Values ( - LightColor, - LightPosition, - LightDirection, - LightConcentration, - LightAttenuation1, - LightAttenuation2, - LightAngle - ); - break; - - } - - lights[j].Color.r = float (LightColor.Red ()); - lights[j].Color.g = float (LightColor.Green ()); - lights[j].Color.b = float (LightColor.Blue ()); - - if ( (LightType == Visual3d_TOLS_POSITIONAL) || - (LightType == Visual3d_TOLS_SPOT) ) { - LightPosition.Coord (X, Y, Z); - lights[j].Position.x = float (X); - lights[j].Position.y = float (Y); - lights[j].Position.z = float (Z); - } - - if ( (LightType == Visual3d_TOLS_DIRECTIONAL) || - (LightType == Visual3d_TOLS_SPOT) ) { - LightDirection.Coord (X, Y, Z); - lights[j].Direction.x = float (X); - lights[j].Direction.y = float (Y); - lights[j].Direction.z = float (Z); - } - - if ( (LightType == Visual3d_TOLS_POSITIONAL) || - (LightType == Visual3d_TOLS_SPOT) ) { - lights[j].Attenuation[0] = - float (LightAttenuation1); - lights[j].Attenuation[1] = - float (LightAttenuation2); - } - - if (LightType == Visual3d_TOLS_SPOT) { - lights[j].Concentration = - float (LightConcentration); - lights[j].Angle = - float (LightAngle); - } - } - - } -#ifdef BUC60570 +void Visual3d_View::UpdateLights() +{ + if (IsDeleted() + || !IsDefined()) + { + return; } -#endif - // management of light sources - if (! IsDeleted ()) - if (IsDefined ()) - MyGraphicDriver->SetLight (MyCView); - // Dynamic allocation - if (MyCView.Context.NbActiveLight > 0) delete [] lights; + if (MyContext.Model() == Visual3d_TOM_NONE) + { + // activate only a white ambient light + Graphic3d_CLight aCLight; + aCLight.Type = Visual3d_TOLS_AMBIENT; + aCLight.IsHeadlight = Standard_False; + aCLight.Color.r() = aCLight.Color.g() = aCLight.Color.b() = 1.0f; + MyCView.Context.NbActiveLight = 1; + MyCView.Context.ActiveLight = &aCLight; + MyGraphicDriver->SetLight (MyCView); + MyCView.Context.ActiveLight = NULL; + return; + } + + MyCView.Context.NbActiveLight = Min (MyContext.NumberOfActivatedLights(), + MyGraphicDriver->InquireLightLimit()); + if (MyCView.Context.NbActiveLight < 1) + { + return; + } + + // parcing of light sources + MyCView.Context.ActiveLight = new Graphic3d_CLight[MyCView.Context.NbActiveLight]; + for (Standard_Integer aLightIter = 0; aLightIter < MyCView.Context.NbActiveLight; ++aLightIter) + { + MyCView.Context.ActiveLight[aLightIter] = MyContext.ActivatedLight (aLightIter + 1)->CLight(); + } + MyGraphicDriver->SetLight (MyCView); + delete[] MyCView.Context.ActiveLight; + MyCView.Context.ActiveLight = NULL; } void Visual3d_View::UpdatePlanes() diff --git a/tests/v3d/glsl/phong_box b/tests/v3d/glsl/phong_box index 896d63ba35..be9b093afb 100644 --- a/tests/v3d/glsl/phong_box +++ b/tests/v3d/glsl/phong_box @@ -9,6 +9,7 @@ box b 1 2 3 vinit View1 vclear vsetdispmode 1 +vaxo vdisplay b vfit vrotate 0.2 0.0 0.0 diff --git a/tests/v3d/glsl/phong_couple b/tests/v3d/glsl/phong_couple index 47cb3423c4..edcba9c633 100644 --- a/tests/v3d/glsl/phong_couple +++ b/tests/v3d/glsl/phong_couple @@ -12,6 +12,7 @@ vinit View1 vclear vdefaults absDefl=0.5 vsetdispmode 1 +vaxo vdisplay f vfit vrotate -0.5 0.0 0.0 diff --git a/tests/v3d/glsl/phong_fuse b/tests/v3d/glsl/phong_fuse index 1a94e3d23c..11fe8a931b 100644 --- a/tests/v3d/glsl/phong_fuse +++ b/tests/v3d/glsl/phong_fuse @@ -11,6 +11,7 @@ vinit View1 vclear vdefaults absDefl=0.5 vsetdispmode 1 +vaxo vdisplay f vfit vrotate -0.5 0.0 0.0 diff --git a/tests/v3d/glsl/phong_fuse2 b/tests/v3d/glsl/phong_fuse2 new file mode 100644 index 0000000000..f65abf9dd7 --- /dev/null +++ b/tests/v3d/glsl/phong_fuse2 @@ -0,0 +1,39 @@ +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 +vaxo +vdisplay f +vfit +vrotate -0.5 0.0 0.0 +vfit + +# setup lights +vlight delete 0 +vlight delete 0 +vlight delete 0 +vlight delete 0 +vlight delete 0 +vlight add ambient color WHITE +vlight add directional dir 1 0 0 color GREEN headlight 1 +vlight add directional dir -1 0 0 color RED1 headlight 1 + +# 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 diff --git a/tests/v3d/glsl/phong_views b/tests/v3d/glsl/phong_views index f6fa308761..f8b113692e 100644 --- a/tests/v3d/glsl/phong_views +++ b/tests/v3d/glsl/phong_views @@ -9,6 +9,7 @@ box b 1 2 3 vinit View1 vclear vsetdispmode 1 +vaxo vdisplay b vfit vrotate 0.2 0.0 0.0