#include <OpenGl_Context.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_ShaderProgram.hxx>
+#include <OpenGl_Workspace.hxx>
IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderManager, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
OpenGl_Vec4 Parameters;
//! Returns packed (serialized) representation of light source properties
- const OpenGl_Vec4* Packed() { return reinterpret_cast<OpenGl_Vec4*> (this); }
+ const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
static Standard_Integer NbOfVec4() { return 4; }
};
Standard_Integer IsHeadlight;
//! Returns packed (serialized) representation of light source type
- const OpenGl_Vec2i* Packed() { return reinterpret_cast<OpenGl_Vec2i*> (this); }
+ const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
static Standard_Integer NbOfVec2i() { return 1; }
};
theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
theAspect->DistinguishingMode());
- const float aDefSpecCol[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- OpenGl_Vec4 aParams[5];
+ OpenGl_Material aParams;
for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
{
const GLint aLoc = theProgram->GetStateLocation (anIndex == 0
continue;
}
- const OPENGL_SURF_PROP& aProps = (anIndex == 0) ? theAspect->IntFront() : theAspect->IntBack();
- const float* aSrcEms = aProps.isphysic ? aProps.emscol.rgb : aProps.matcol.rgb;
- const OpenGl_Vec4 anEmission (aSrcEms[0] * aProps.emsv,
- aSrcEms[1] * aProps.emsv,
- aSrcEms[2] * aProps.emsv,
- 1.0f);
- const float* aSrcAmb = aProps.isphysic ? aProps.ambcol.rgb : aProps.matcol.rgb;
- const OpenGl_Vec4 anAmbient (aSrcAmb[0] * aProps.amb,
- aSrcAmb[1] * aProps.amb,
- aSrcAmb[2] * aProps.amb,
- 1.0f);
- const float* aSrcDif = aProps.isphysic ? aProps.difcol.rgb : aProps.matcol.rgb;
- const OpenGl_Vec4 aDiffuse (aSrcDif[0] * aProps.diff,
- aSrcDif[1] * aProps.diff,
- aSrcDif[2] * aProps.diff,
- 1.0f);
- const float* aSrcSpe = aProps.isphysic ? aProps.speccol.rgb : aDefSpecCol;
- const OpenGl_Vec4 aSpecular (aSrcSpe[0] * aProps.spec,
- aSrcSpe[1] * aProps.spec,
- aSrcSpe[2] * aProps.spec,
- 1.0f);
-
- aParams[0] = anEmission;
- aParams[1] = anAmbient;
- aParams[2] = aDiffuse;
- aParams[3] = aSpecular;
- aParams[4].x() = aProps.shine;
- aParams[4].y() = aProps.trans;
- theProgram->SetUniform (theCtx, aLoc, 5, aParams);
+ aParams.Init (anIndex == 0 ? theAspect->IntFront() : theAspect->IntBack());
+ theProgram->SetUniform (theCtx, aLoc, OpenGl_Material::NbOfVec4(),
+ aParams.Packed());
}
}
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
-
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
namespace
{
- static const TEL_COLOUR myDefaultHighlightColor = { { 1.F, 1.F, 1.F, 1.F } };
+ static const TEL_COLOUR THE_WHITE_COLOR = { { 1.0f, 1.0f, 1.0f, 1.0f } };
+ static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f);
static const OpenGl_AspectLine myDefaultAspectLine;
static const OpenGl_AspectFace myDefaultAspectFace;
};
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+void OpenGl_Material::Init (const OPENGL_SURF_PROP& theProp)
+{
+ // ambient component
+ if (theProp.color_mask & OPENGL_AMBIENT_MASK)
+ {
+ const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb;
+ Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb,
+ aSrcAmb[1] * theProp.amb,
+ aSrcAmb[2] * theProp.amb,
+ 1.0f);
+ }
+ else
+ {
+ Ambient = THE_BLACK_COLOR;
+ }
+
+ // diffusion component
+ if (theProp.color_mask & OPENGL_DIFFUSE_MASK)
+ {
+ const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb;
+ Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff,
+ aSrcDif[1] * theProp.diff,
+ aSrcDif[2] * theProp.diff,
+ 1.0f);
+ }
+ else
+ {
+ Diffuse = THE_BLACK_COLOR;
+ }
+
+ // specular component
+ if (theProp.color_mask & OPENGL_SPECULAR_MASK)
+ {
+ const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb;
+ Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec,
+ aSrcSpe[1] * theProp.spec,
+ aSrcSpe[2] * theProp.spec,
+ 1.0f);
+ }
+ else
+ {
+ Specular = THE_BLACK_COLOR;
+ }
+
+ // emission component
+ if (theProp.color_mask & OPENGL_EMISSIVE_MASK)
+ {
+ const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb;
+ Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv,
+ aSrcEms[1] * theProp.emsv,
+ aSrcEms[2] * theProp.emsv,
+ 1.0f);
+ }
+ else
+ {
+ Emission = THE_BLACK_COLOR;
+ }
+
+ ChangeShine() = theProp.shine;
+ ChangeTransparency() = theProp.trans;
+}
+
// =======================================================================
// function : OpenGl_Workspace
// purpose :
const Handle(OpenGl_Context)& theShareCtx)
: OpenGl_Window (theDisplay, theCWindow, theGContext, theCaps, theShareCtx),
NamedStatus (0),
- HighlightColor (&myDefaultHighlightColor),
+ HighlightColor (&THE_WHITE_COLOR),
//
myIsTransientOpen (Standard_False),
myRetainMode (Standard_False),
void OpenGl_Workspace::ResetAppliedAspect()
{
NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
- HighlightColor = &myDefaultHighlightColor;
+ HighlightColor = &THE_WHITE_COLOR;
AspectLine_set = &myDefaultAspectLine;
AspectLine_applied = NULL;
AspectFace_set = &myDefaultAspectFace;
/*----------------------------------------------------------------------*/
-void OpenGl_Workspace::UpdateMaterial( const int flag )
+void OpenGl_Workspace::updateMaterial (const int theFlag)
{
// Case of hidden line
if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE)
return;
}
- const OPENGL_SURF_PROP *prop = NULL;
- GLenum face = 0;
- if ( flag == TEL_FRONT_MATERIAL )
+ const OPENGL_SURF_PROP* aProps = &AspectFace_set->IntFront();
+ GLenum aFace = GL_FRONT_AND_BACK;
+ if (theFlag == TEL_BACK_MATERIAL)
{
- prop = &AspectFace_set->IntFront();
- face = GL_FRONT_AND_BACK;
+ aFace = GL_BACK;
+ aProps = &AspectFace_set->IntBack();
}
- else
+ else if (AspectFace_set->DistinguishingMode() == TOn
+ && !(NamedStatus & OPENGL_NS_RESMAT))
{
- prop = &AspectFace_set->IntBack();
- face = GL_BACK;
+ aFace = GL_FRONT;
}
- // Handling transparency
- if ( (NamedStatus & OPENGL_NS_2NDPASSDO) == 0 )
+ myMatTmp.Init (*aProps);
+
+ // handling transparency
+ if (NamedStatus & OPENGL_NS_2NDPASSDO)
+ {
+ // second pass
+ myMatTmp.Diffuse.a() = aProps->env_reflexion;
+ }
+ else
{
- if ( myUseTransparency && prop->trans != 1.0F )
+ if (aProps->env_reflexion != 0.0f)
+ {
+ // if the material reflects the environment scene, the second pass is needed
+ NamedStatus |= OPENGL_NS_2NDPASSNEED;
+ }
+
+ if (myUseTransparency && aProps->trans != 1.0f)
{
- // Render transparent
+ // render transparent
+ myMatTmp.Diffuse.a() = aProps->trans;
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
+ glEnable (GL_BLEND);
glDepthMask (GL_FALSE);
}
else
{
- // Render opaque
- if ( (NamedStatus & OPENGL_NS_ANTIALIASING) == 0 )
+ // render opaque
+ if ((NamedStatus & OPENGL_NS_ANTIALIASING) == 0)
{
glBlendFunc (GL_ONE, GL_ZERO);
- glDisable (GL_BLEND);
+ glDisable (GL_BLEND);
}
glDepthMask (GL_TRUE);
}
}
- // Obtaining reflection mode flags to update GL material properties
- const unsigned int aReflectionMode = prop->color_mask;
-
- // Do not update material properties in case of zero reflection mode,
- // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray()
- // anyway.
- if ( !aReflectionMode ) return;
-
- static float mAmb[4];
- static float mDiff[4];
- static float mSpec[4];
- static float mEmsv[4];
- static float mShin;
-
- static const float defspeccol[4] = { 1.F, 1.F, 1.F, 1.F };
-
- // Reset material
- if ( NamedStatus & OPENGL_NS_RESMAT )
+ // do not update material properties in case of zero reflection mode,
+ // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
+ if (aProps->color_mask == 0)
{
- // Ambient component
- if( aReflectionMode & OPENGL_AMBIENT_MASK )
- {
- const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
-
- mAmb[0] = prop->amb * c[0];
- mAmb[1] = prop->amb * c[1];
- mAmb[2] = prop->amb * c[2];
- }
- else
- {
- mAmb[0] = 0.F;
- mAmb[1] = 0.F;
- mAmb[2] = 0.F;
- }
- mAmb[3] = 1.F;
-
- // Diffusion component
- if( aReflectionMode & OPENGL_DIFFUSE_MASK )
- {
- const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
-
- mDiff[0] = prop->diff * c[0];
- mDiff[1] = prop->diff * c[1];
- mDiff[2] = prop->diff * c[2];
- }
- else
- {
- mDiff[0] = 0.F;
- mDiff[1] = 0.F;
- mDiff[2] = 0.F;
- }
- mDiff[3] = 1.F;
-
- if (NamedStatus & OPENGL_NS_2NDPASSDO)
- {
- mDiff[3] = prop->env_reflexion;
- }
- else
- {
- if (myUseTransparency) mDiff[3] = prop->trans;
- // If the material reflects the environment scene, the second pass is needed
- if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
- }
-
- // Specular component
- if( aReflectionMode & OPENGL_SPECULAR_MASK )
- {
- const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
-
- mSpec[0] = prop->spec * c[0];
- mSpec[1] = prop->spec * c[1];
- mSpec[2] = prop->spec * c[2];
- }
- else {
- mSpec[0] = 0.F;
- mSpec[1] = 0.F;
- mSpec[2] = 0.F;
- }
- mSpec[3] = 1.F;
-
- // Emissive component
- if( aReflectionMode & OPENGL_EMISSIVE_MASK )
- {
- const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
-
- mEmsv[0] = prop->emsv * c[0];
- mEmsv[1] = prop->emsv * c[1];
- mEmsv[2] = prop->emsv * c[2];
- }
- else {
- mEmsv[0] = 0.F;
- mEmsv[1] = 0.F;
- mEmsv[2] = 0.F;
- }
- mEmsv[3] = 1.F;
-
- /* Coeficient de brillance */
- mShin = prop->shine;
-
- glMaterialfv(face, GL_AMBIENT, mAmb );
- glMaterialfv(face, GL_DIFFUSE, mDiff );
- glMaterialfv(face, GL_SPECULAR, mSpec);
- glMaterialfv(face, GL_EMISSION, mEmsv);
- glMaterialf(face, GL_SHININESS, mShin);
-
- NamedStatus &= ~OPENGL_NS_RESMAT;
+ return;
}
- // Set Material Optimize
- else
+ // reset material
+ if (NamedStatus & OPENGL_NS_RESMAT)
{
- // Ambient component
- if( aReflectionMode & OPENGL_AMBIENT_MASK )
- {
- const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
+ glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
+ glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
+ glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
+ glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
+ glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
- if (mAmb[0] != prop->amb * c[0] ||
- mAmb[1] != prop->amb * c[1] ||
- mAmb[2] != prop->amb * c[2] )
- {
- mAmb[0] = prop->amb * c[0];
- mAmb[1] = prop->amb * c[1];
- mAmb[2] = prop->amb * c[2];
- mAmb[3] = 1.F;
-
- glMaterialfv(face, GL_AMBIENT, mAmb);
- }
- }
- else
+ if (theFlag == TEL_FRONT_MATERIAL)
{
- if ( mAmb[0] != 0.F || mAmb[1] != 0.F || mAmb[2] != 0.F )
- {
- mAmb[0] = 0.F;
- mAmb[1] = 0.F;
- mAmb[2] = 0.F;
- mAmb[3] = 1.F;
-
- glMaterialfv(face, GL_AMBIENT, mAmb);
- }
- }
-
- // Diffusion component
- if( aReflectionMode & OPENGL_DIFFUSE_MASK )
- {
- const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
-
- if (mDiff[0] != prop->diff * c[0] ||
- mDiff[1] != prop->diff * c[1] ||
- mDiff[2] != prop->diff * c[2] ||
- mDiff[3] != ((NamedStatus & OPENGL_NS_2NDPASSDO)? prop->env_reflexion : (myUseTransparency? prop->trans : 1.0F)))
- {
- mDiff[0] = prop->diff * c[0];
- mDiff[1] = prop->diff * c[1];
- mDiff[2] = prop->diff * c[2];
- mDiff[3] = 1.F;
-
- if (NamedStatus & OPENGL_NS_2NDPASSDO)
- {
- mDiff[3] = prop->env_reflexion;
- }
- else
- {
- if (myUseTransparency) mDiff[3] = prop->trans;
- // If the material reflects the environment scene, the second pass is needed
- if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
- }
-
- glMaterialfv(face, GL_DIFFUSE, mDiff );
- }
+ myMatFront = myMatTmp;
+ myMatBack = myMatTmp;
}
else
{
- Tfloat newDiff3 = 1.F;
-
- if (NamedStatus & OPENGL_NS_2NDPASSDO)
- {
- newDiff3 = prop->env_reflexion;
- }
- else
- {
- if (myUseTransparency) newDiff3 = prop->trans;
- // If the material reflects the environment scene, the second pass is needed
- if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
- }
-
- /* OCC19915: Even if diffuse reflectance is disabled,
- still trying to update the current transparency if it
- differs from the previous value */
- if ( mDiff[0] != 0.F || mDiff[1] != 0.F || mDiff[2] != 0.F || fabs(mDiff[3] - newDiff3) > 0.01F )
- {
- mDiff[0] = 0.F;
- mDiff[1] = 0.F;
- mDiff[2] = 0.F;
- mDiff[3] = newDiff3;
-
- glMaterialfv(face, GL_DIFFUSE, mDiff);
- }
- }
-
- // Specular component
- if( aReflectionMode & OPENGL_SPECULAR_MASK )
- {
- const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
-
- if (mSpec[0] != prop->spec * c[0] ||
- mSpec[1] != prop->spec * c[1] ||
- mSpec[2] != prop->spec * c[2])
- {
- mSpec[0] = prop->spec * c[0];
- mSpec[1] = prop->spec * c[1];
- mSpec[2] = prop->spec * c[2];
- mSpec[3] = 1.F;
-
- glMaterialfv(face, GL_SPECULAR, mSpec);
- }
- }
- else
- {
- if ( mSpec[0] != 0.F || mSpec[1] != 0.F || mSpec[2] != 0.F )
- {
- mSpec[0] = 0.F;
- mSpec[1] = 0.F;
- mSpec[2] = 0.F;
- mSpec[3] = 1.F;
-
- glMaterialfv(face, GL_SPECULAR, mSpec);
- }
+ myMatBack = myMatTmp;
}
- // Emissive component
- if( aReflectionMode & OPENGL_EMISSIVE_MASK )
- {
- const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
+ NamedStatus &= ~OPENGL_NS_RESMAT;
+ return;
+ }
- if (mEmsv[0] != prop->emsv * c[0] ||
- mEmsv[1] != prop->emsv * c[1] ||
- mEmsv[2] != prop->emsv * c[2])
- {
- mEmsv[0] = prop->emsv * c[0];
- mEmsv[1] = prop->emsv * c[1];
- mEmsv[2] = prop->emsv * c[2];
- mEmsv[3] = 1.F;
+ // reduce updates
+ OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
+ ? myMatFront
+ : myMatBack;
- glMaterialfv(face, GL_EMISSION, mEmsv);
- }
- }
- else
- {
- if ( mEmsv[0] != 0.F || mEmsv[1] != 0.F || mEmsv[2] != 0.F )
- {
- mEmsv[0] = 0.F;
- mEmsv[1] = 0.F;
- mEmsv[2] = 0.F;
- mEmsv[3] = 1.F;
-
- glMaterialfv(face, GL_EMISSION, mEmsv);
- }
- }
-
- // Shining coefficient
- if( mShin != prop->shine )
- {
- mShin = prop->shine;
- glMaterialf(face, GL_SHININESS, mShin);
- }
+ if (myMatTmp.Ambient.r() != anOld.Ambient.r()
+ || myMatTmp.Ambient.g() != anOld.Ambient.g()
+ || myMatTmp.Ambient.b() != anOld.Ambient.b())
+ {
+ glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
+ }
+ if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
+ || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
+ || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
+ || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
+ {
+ glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
+ }
+ if (myMatTmp.Specular.r() != anOld.Specular.r()
+ || myMatTmp.Specular.g() != anOld.Specular.g()
+ || myMatTmp.Specular.b() != anOld.Specular.b())
+ {
+ glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
+ }
+ if (myMatTmp.Emission.r() != anOld.Emission.r()
+ || myMatTmp.Emission.g() != anOld.Emission.g()
+ || myMatTmp.Emission.b() != anOld.Emission.b())
+ {
+ glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
+ }
+ if (myMatTmp.Shine() != anOld.Shine())
+ {
+ glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
+ }
+ anOld = myMatTmp;
+ if (aFace == GL_FRONT_AND_BACK)
+ {
+ myMatBack = myMatTmp;
}
}
glDisable (GL_POLYGON_STIPPLE);
break;
}
- case Aspect_IS_POINT: //szvgl - no corresponding enumeration item Aspect_IS_POINT // = 5
+ case Aspect_IS_POINT:
{
- glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
+ glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
break;
}
}
}
}
- UpdateMaterial (TEL_FRONT_MATERIAL);
+ updateMaterial (TEL_FRONT_MATERIAL);
if (AspectFace_set->DistinguishingMode() == TOn)
{
- UpdateMaterial (TEL_BACK_MATERIAL);
+ updateMaterial (TEL_BACK_MATERIAL);
}
if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)