// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <OpenGl_AspectFace.hxx>
+#include <OpenGl_Aspects.hxx>
#include <OpenGl_Context.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <OpenGl_IndexBuffer.hxx>
#include <OpenGl_PointSprite.hxx>
#include <OpenGl_PrimitiveArray.hxx>
+#include <OpenGl_Sampler.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_Structure.hxx>
#include <OpenGl_VertexBufferCompat.hxx>
+#include <OpenGl_View.hxx>
#include <OpenGl_Workspace.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <NCollection_AlignedAllocator.hxx>
template<class TheBaseClass, int NbAttributes>
class OpenGl_VertexBufferT : public TheBaseClass
{
-
public:
- //! Create uninitialized VBO.
- OpenGl_VertexBufferT (const Graphic3d_Attribute* theAttribs,
- const Standard_Integer theStride)
- : Stride (theStride)
- {
- memcpy (Attribs, theAttribs, sizeof(Graphic3d_Attribute) * NbAttributes);
- }
-
//! Create uninitialized VBO.
OpenGl_VertexBufferT (const Graphic3d_Buffer& theAttribs)
- : Stride (theAttribs.Stride)
+ : Stride (theAttribs.IsInterleaved() ? theAttribs.Stride : 0)
{
memcpy (Attribs, theAttribs.AttributesArray(), sizeof(Graphic3d_Attribute) * NbAttributes);
}
TheBaseClass::Bind (theGlCtx);
GLint aNbComp;
const GLubyte* anOffset = TheBaseClass::myOffset;
+ const Standard_Size aMuliplier = Stride != 0 ? 1 : TheBaseClass::myElemsNb;
for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
{
const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
const GLenum aDataType = toGlDataType (anAttrib.DataType, aNbComp);
- if (aDataType == GL_NONE)
- {
- continue;
- }
- else if (anAttrib.Id == Graphic3d_TOA_POS)
+ if (anAttrib.Id == Graphic3d_TOA_POS
+ && aDataType != GL_NONE)
{
TheBaseClass::bindAttribute (theGlCtx, Graphic3d_TOA_POS, aNbComp, aDataType, Stride, anOffset);
break;
}
- anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType);
+ anOffset += aMuliplier * Graphic3d_Attribute::Stride (anAttrib.DataType);
}
}
TheBaseClass::Bind (theGlCtx);
GLint aNbComp;
const GLubyte* anOffset = TheBaseClass::myOffset;
+ const Standard_Size aMuliplier = Stride != 0 ? 1 : TheBaseClass::myElemsNb;
for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
{
const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
const GLenum aDataType = toGlDataType (anAttrib.DataType, aNbComp);
- if (aDataType == GL_NONE)
+ if (aDataType != GL_NONE)
{
- continue;
+ TheBaseClass::bindAttribute (theGlCtx, anAttrib.Id, aNbComp, aDataType, Stride, anOffset);
}
-
- TheBaseClass::bindAttribute (theGlCtx, anAttrib.Id, aNbComp, aDataType, Stride, anOffset);
- anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType);
+ anOffset += aMuliplier * Graphic3d_Attribute::Stride (anAttrib.DataType);
}
}
}
}
-public:
+private:
Graphic3d_Attribute Attribs[NbAttributes];
Standard_Integer Stride;
case 10: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 10>(*myAttribs); break;
}
- if (!myVboAttribs->init (theCtx, 0, myAttribs->NbElements, myAttribs->Data(), GL_NONE, myAttribs->Stride))
+ const Standard_Boolean isAttribMutable = myAttribs->IsMutable();
+ const Standard_Boolean isAttribInterleaved = myAttribs->IsInterleaved();
+ if (myAttribs->NbElements != myAttribs->NbMaxElements()
+ && myIndices.IsNull()
+ && (!isAttribInterleaved || isAttribMutable))
+ {
+ throw Standard_ProgramError ("OpenGl_PrimitiveArray::buildVBO() - vertex attribute data with reserved size is not supported");
+ }
+
+ // specify data type as Byte and NbComponents as Stride, so that OpenGl_VertexBuffer::EstimatedDataSize() will return correct value
+ const Standard_Integer aNbVertexes = (isAttribMutable || !isAttribInterleaved) ? myAttribs->NbMaxElements() : myAttribs->NbElements;
+ if (!myVboAttribs->init (theCtx, myAttribs->Stride, aNbVertexes, myAttribs->Data(), GL_UNSIGNED_BYTE, myAttribs->Stride))
{
- TCollection_ExtendedString aMsg;
- aMsg += "VBO creation for Primitive Array has failed for ";
- aMsg += myAttribs->NbElements;
- aMsg += " vertices. Out of memory?";
+ TCollection_ExtendedString aMsg = TCollection_ExtendedString("VBO creation for Primitive Array has failed for ") + aNbVertexes + " vertices. Out of memory?";
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
clearMemoryGL (theCtx);
}
else if (myIndices.IsNull())
{
+ if (isAttribMutable && isAttribInterleaved)
+ {
+ // for mutable interlaced array we can change dynamically number of vertexes (they will be just skipped at the end of buffer);
+ // this doesn't matter in case if we have indexed array
+ myVboAttribs->SetElemsNb (myAttribs->NbElements);
+ }
return Standard_True;
}
+ const Standard_Integer aNbIndexes = !myIndices->IsMutable() ? myIndices->NbElements : myIndices->NbMaxElements();
myVboIndices = new OpenGl_IndexBuffer();
bool isOk = false;
switch (myIndices->Stride)
{
case 2:
{
- isOk = myVboIndices->Init (theCtx, 1, myIndices->NbElements, reinterpret_cast<const GLushort*> (myIndices->Data()));
+ isOk = myVboIndices->Init (theCtx, 1, aNbIndexes, reinterpret_cast<const GLushort*> (myIndices->Data()));
+ myVboIndices->SetElemsNb (myIndices->NbElements);
+ myIndices->Validate();
break;
}
case 4:
{
- isOk = myVboIndices->Init (theCtx, 1, myIndices->NbElements, reinterpret_cast<const GLuint*> (myIndices->Data()));
+ isOk = myVboIndices->Init (theCtx, 1, aNbIndexes, reinterpret_cast<const GLuint*> (myIndices->Data()));
+ myVboIndices->SetElemsNb (myIndices->NbElements);
+ myIndices->Validate();
break;
}
default:
}
if (!isOk)
{
- TCollection_ExtendedString aMsg;
- aMsg += "VBO creation for Primitive Array has failed for ";
- aMsg += myIndices->NbElements;
- aMsg += " indices. Out of memory?";
+ TCollection_ExtendedString aMsg = TCollection_ExtendedString("VBO creation for Primitive Array has failed for ") + aNbIndexes + " indices. Out of memory?";
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
clearMemoryGL (theCtx);
return Standard_False;
&& initNormalVbo (theCtx))
{
if (!theCtx->caps->keepArrayData
- && !theToKeepData)
+ && !theToKeepData
+ && !myAttribs->IsMutable())
{
myIndices.Nullify();
myAttribs.Nullify();
}
+ else
+ {
+ myAttribs->Validate();
+ }
return Standard_True;
}
return Standard_True;
}
+// =======================================================================
+// function : updateVBO
+// purpose :
+// =======================================================================
+void OpenGl_PrimitiveArray::updateVBO (const Handle(OpenGl_Context)& theCtx) const
+{
+ if (!myAttribs.IsNull())
+ {
+ Graphic3d_BufferRange aRange = myAttribs->InvalidatedRange();
+ if (!aRange.IsEmpty()
+ && myVboAttribs->IsValid()
+ && !myVboAttribs->IsVirtual())
+ {
+ myVboAttribs->Bind (theCtx);
+ theCtx->core15fwd->glBufferSubData (myVboAttribs->GetTarget(),
+ aRange.Start,
+ aRange.Length,
+ myAttribs->Data() + aRange.Start);
+ myVboAttribs->Unbind (theCtx);
+ if (myAttribs->IsInterleaved())
+ {
+ myVboAttribs->SetElemsNb (myAttribs->NbElements);
+ }
+ }
+ myAttribs->Validate();
+ }
+ if (!myIndices.IsNull())
+ {
+ Graphic3d_BufferRange aRange = myIndices->InvalidatedRange();
+ if (!aRange.IsEmpty()
+ && myVboIndices->IsValid()
+ && !myVboIndices->IsVirtual())
+ {
+ myVboIndices->Bind (theCtx);
+ theCtx->core15fwd->glBufferSubData (myVboIndices->GetTarget(),
+ aRange.Start,
+ aRange.Length,
+ myIndices->Data() + aRange.Start);
+ myVboIndices->Unbind (theCtx);
+ myVboIndices->SetElemsNb (myIndices->NbElements);
+ }
+ myIndices->Validate();
+ }
+}
+
// =======================================================================
// function : drawArray
// purpose :
const Graphic3d_Vec4* theFaceColors,
const Standard_Boolean theHasVertColor) const
{
- const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
- const bool toHilight = theWorkspace->ToHighlight();
- bool hasVColors = theHasVertColor && !toHilight;
if (myVboAttribs.IsNull())
{
#if !defined(GL_ES_VERSION_2_0)
return;
}
+ const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
+ const bool toHilight = theWorkspace->ToHighlight();
+ const GLenum aDrawMode = !aGlContext->ActiveProgram().IsNull()
+ && aGlContext->ActiveProgram()->HasTessellationStage()
+ ? GL_PATCHES
+ : myDrawMode;
myVboAttribs->BindAllAttributes (aGlContext);
if (theHasVertColor && toHilight)
{
{
const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
if (theFaceColors != NULL) aGlContext->SetColor4fv (theFaceColors[aGroupIter]);
- glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
+ glDrawElements (aDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
anOffset += aStride * aNbElemsInGroup;
}
}
else
{
// draw one (or sequential) primitive by the indices
- glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), anOffset);
+ glDrawElements (aDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), anOffset);
}
myVboIndices->Unbind (aGlContext);
}
{
const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
if (theFaceColors != NULL) aGlContext->SetColor4fv (theFaceColors[aGroupIter]);
- glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
+ glDrawArrays (aDrawMode, aFirstElem, aNbElemsInGroup);
aFirstElem += aNbElemsInGroup;
}
}
}
else
{
- glDrawArrays (myDrawMode, 0, myVboAttribs->GetElemsNb());
+ glDrawArrays (aDrawMode, 0, myVboAttribs->GetElemsNb());
}
}
// bind with 0
myVboAttribs->UnbindAllAttributes (aGlContext);
-
- if (hasVColors)
- {
- theWorkspace->NamedStatus |= OPENGL_NS_RESMAT;
- }
}
// =======================================================================
// function : drawEdges
// purpose :
// =======================================================================
-void OpenGl_PrimitiveArray::drawEdges (const TEL_COLOUR* theEdgeColour,
- const Handle(OpenGl_Workspace)& theWorkspace) const
+void OpenGl_PrimitiveArray::drawEdges (const Handle(OpenGl_Workspace)& theWorkspace) const
{
const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
if (myVboAttribs.IsNull())
return;
}
+ const OpenGl_Aspects* anAspect = theWorkspace->Aspects();
#if !defined(GL_ES_VERSION_2_0)
- if (aGlContext->core11 != NULL)
- {
- glDisable (GL_LIGHTING);
- }
-#endif
-
- const OpenGl_AspectLine* anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace()->AspectEdge());
- const OpenGl_AspectLine* anAspect = theWorkspace->ApplyAspectLine();
-
-#if !defined(GL_ES_VERSION_2_0)
- glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
+ const Standard_Integer aPolyModeOld = aGlContext->SetPolygonMode (GL_LINE);
#endif
if (aGlContext->core20fwd != NULL)
{
- aGlContext->ShaderManager()->BindLineProgram (NULL, anAspect->Type() != Aspect_TOL_SOLID, Standard_False, Standard_False, anAspect->ShaderProgramRes (aGlContext));
+ aGlContext->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), anAspect->Aspect()->EdgeLineType(),
+ Graphic3d_TOSM_UNLIT, Graphic3d_AlphaMode_Opaque, Standard_False,
+ anAspect->ShaderProgramRes (aGlContext));
+ }
+ aGlContext->SetSampleAlphaToCoverage (aGlContext->ShaderManager()->MaterialState().HasAlphaCutoff());
+ const GLenum aDrawMode = !aGlContext->ActiveProgram().IsNull()
+ && aGlContext->ActiveProgram()->HasTessellationStage()
+ ? GL_PATCHES
+ : myDrawMode;
+#if !defined(GL_ES_VERSION_2_0)
+ if (aGlContext->ActiveProgram().IsNull()
+ && aGlContext->core11 != NULL)
+ {
+ glDisable (GL_LIGHTING);
}
+#endif
/// OCC22236 NOTE: draw edges for all situations:
/// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indices array
/// 3) draw primitive's edges by vertexes if no edges and bounds array is specified
myVboAttribs->BindPositionAttribute (aGlContext);
- aGlContext->SetColor4fv (*(const OpenGl_Vec4* )theEdgeColour->rgb);
- aGlContext->SetTypeOfLine (anAspect->Type());
- aGlContext->SetLineWidth (anAspect->Width());
+ aGlContext->SetColor4fv (theWorkspace->EdgeColor().a() >= 0.1f
+ ? theWorkspace->EdgeColor()
+ : theWorkspace->View()->BackgroundColor());
+ aGlContext->SetTypeOfLine (anAspect->Aspect()->EdgeLineType());
+ aGlContext->SetLineWidth (anAspect->Aspect()->EdgeWidth());
if (!myVboIndices.IsNull())
{
for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
{
const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
- glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
+ glDrawElements (aDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
anOffset += aStride * aNbElemsInGroup;
}
}
// draw one (or sequential) primitive by the indices
else
{
- glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), anOffset);
+ glDrawElements (aDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), anOffset);
}
myVboIndices->Unbind (aGlContext);
}
for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
{
const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
- glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
+ glDrawArrays (aDrawMode, aFirstElem, aNbElemsInGroup);
aFirstElem += aNbElemsInGroup;
}
}
else
{
- glDrawArrays (myDrawMode, 0, myAttribs->NbElements);
+ glDrawArrays (aDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
}
// unbind buffers
myVboAttribs->UnbindAttribute (aGlContext, Graphic3d_TOA_POS);
// restore line context
- theWorkspace->SetAspectLine (anAspectLineOld);
+#if !defined(GL_ES_VERSION_2_0)
+ aGlContext->SetPolygonMode (aPolyModeOld);
+#endif
}
// =======================================================================
// =======================================================================
void OpenGl_PrimitiveArray::drawMarkers (const Handle(OpenGl_Workspace)& theWorkspace) const
{
- const OpenGl_AspectMarker* anAspectMarker = theWorkspace->ApplyAspectMarker();
- const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx);
- if (!aSpriteNorm.IsNull()
- && !aSpriteNorm->IsDisplayList())
+ const OpenGl_Aspects* anAspectMarker = theWorkspace->Aspects();
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+ const GLenum aDrawMode = !aCtx->ActiveProgram().IsNull()
+ && aCtx->ActiveProgram()->HasTessellationStage()
+ ? GL_PATCHES
+ : myDrawMode;
+ if (anAspectMarker->HasPointSprite (aCtx))
{
// Textured markers will be drawn with the point sprites
aCtx->SetPointSize (anAspectMarker->MarkerSize());
aCtx->core11fwd->glEnable (GL_BLEND);
aCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- aCtx->core11fwd->glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
+ aCtx->core11fwd->glDrawArrays (aDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
aCtx->core11fwd->glDisable (GL_BLEND);
#if !defined(GL_ES_VERSION_2_0)
if (aCtx->core11 != NULL)
{
- aCtx->core11fwd->glDisable (GL_ALPHA_TEST);
+ if (aCtx->ShaderManager()->MaterialState().AlphaCutoff() >= ShortRealLast())
+ {
+ aCtx->core11fwd->glDisable (GL_ALPHA_TEST);
+ }
+ else
+ {
+ aCtx->core11fwd->glAlphaFunc (GL_GEQUAL, aCtx->ShaderManager()->MaterialState().AlphaCutoff());
+ }
}
#endif
aCtx->SetPointSize (1.0f);
return;
}
- else if (anAspectMarker->Type() == Aspect_TOM_POINT)
+ else if (anAspectMarker->Aspect()->MarkerType() == Aspect_TOM_POINT)
{
aCtx->SetPointSize (anAspectMarker->MarkerSize());
- aCtx->core11fwd->glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
+ aCtx->core11fwd->glDrawArrays (aDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
aCtx->SetPointSize (1.0f);
}
#if !defined(GL_ES_VERSION_2_0)
// Textured markers will be drawn with the glBitmap
- else if (anAspectMarker->Type() != Aspect_TOM_POINT
- && !aSpriteNorm.IsNull())
+ else if (anAspectMarker->Aspect()->MarkerType() != Aspect_TOM_POINT)
{
+ const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx, false);
+ if (aSpriteNorm.IsNull())
+ {
+ return;
+ }
+
/**if (!isHilight && (myPArray->vcolours != NULL))
{
for (Standard_Integer anIter = 0; anIter < myAttribs->NbElements; anIter++)
OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (const OpenGl_GraphicDriver* theDriver)
: myDrawMode (DRAW_MODE_NONE),
+ myIsFillType(Standard_False),
myIsVboInit (Standard_False)
{
if (theDriver != NULL)
myAttribs (theAttribs),
myBounds (theBounds),
myDrawMode (DRAW_MODE_NONE),
+ myIsFillType(Standard_False),
myIsVboInit (Standard_False)
{
if (!myIndices.IsNull()
return;
}
- const OpenGl_AspectFace* anAspectFace = theWorkspace->ApplyAspectFace();
- const OpenGl_AspectLine* anAspectLine = theWorkspace->ApplyAspectLine();
- const OpenGl_AspectMarker* anAspectMarker = myDrawMode == GL_POINTS
- ? theWorkspace->ApplyAspectMarker()
- : theWorkspace->AspectMarker();
+ const OpenGl_Aspects* anAspectFace = theWorkspace->ApplyAspects();
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+
+ const bool toEnableEnvMap = !aCtx->ActiveTextures().IsNull()
+ && aCtx->ActiveTextures() == theWorkspace->EnvironmentTexture();
+ bool toDrawArray = true;
+ int toDrawInteriorEdges = 0; // 0 - no edges, 1 - glsl edges, 2 - polygonMode
+ if (myIsFillType)
+ {
+ toDrawArray = anAspectFace->Aspect()->InteriorStyle() != Aspect_IS_EMPTY;
+ if (anAspectFace->Aspect()->ToDrawEdges())
+ {
+ toDrawInteriorEdges = 1;
+ toDrawArray = true;
+ #if !defined(GL_ES_VERSION_2_0)
+ if (anAspectFace->Aspect()->EdgeLineType() != Aspect_TOL_SOLID
+ || aCtx->hasGeometryStage == OpenGl_FeatureNotAvailable
+ || aCtx->caps->usePolygonMode)
+ {
+ toDrawInteriorEdges = 2;
+ if (anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_EMPTY)
+ {
+ if (anAspectFace->Aspect()->EdgeLineType() != Aspect_TOL_SOLID)
+ {
+ toDrawArray = false;
+ }
+ else
+ {
+ aCtx->SetPolygonMode (GL_LINE);
+ }
+ }
+ }
+ #endif
+ }
+ }
+ else
+ {
+ if (myDrawMode == GL_POINTS)
+ {
+ if (anAspectFace->Aspect()->MarkerType() == Aspect_TOM_EMPTY)
+ {
+ return;
+ }
+ }
+ else
+ {
+ if (anAspectFace->Aspect()->LineType() == Aspect_TOL_EMPTY)
+ {
+ return;
+ }
+ }
+ }
// create VBOs on first render call
- const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
if (!myIsVboInit)
{
// compatibility - keep data to draw markers using display lists
- const Standard_Boolean toKeepData = myDrawMode == GL_POINTS
- && !anAspectMarker->SpriteRes (aCtx).IsNull()
- && anAspectMarker->SpriteRes (aCtx)->IsDisplayList();
+ Standard_Boolean toKeepData = myDrawMode == GL_POINTS
+ && anAspectFace->IsDisplayListSprite (aCtx);
#if defined (GL_ES_VERSION_2_0)
processIndices (aCtx);
#endif
buildVBO (aCtx, toKeepData);
myIsVboInit = Standard_True;
}
-
- Tint aFrontLightingModel = anAspectFace->IntFront().color_mask;
- const Standard_Boolean hasColorAttrib = !myVboAttribs.IsNull()
- && myVboAttribs->HasColorAttribute();
- const Standard_Boolean isLightOn = aFrontLightingModel != 0
- && !myVboAttribs.IsNull()
- && myVboAttribs->HasNormalAttribute();
-#if !defined(GL_ES_VERSION_2_0)
- // manage FFP lighting
- if (aCtx->core11 != NULL)
- {
- if (!isLightOn)
- {
- glDisable (GL_LIGHTING);
- }
- else
- {
- glEnable (GL_LIGHTING);
- }
- }
-#endif
- // Temporarily disable environment mapping
- Handle(OpenGl_Texture) aTextureBack;
- if (myDrawMode <= GL_LINE_STRIP)
+ else if ((!myAttribs.IsNull()
+ && myAttribs->IsMutable())
+ || (!myIndices.IsNull()
+ && myIndices->IsMutable()))
{
- aTextureBack = theWorkspace->DisableTexture();
+ updateVBO (aCtx);
}
- if ((myDrawMode > GL_LINE_STRIP && anAspectFace->InteriorStyle() != Aspect_IS_EMPTY) ||
- (myDrawMode <= GL_LINE_STRIP))
+ Graphic3d_TypeOfShadingModel aShadingModel = Graphic3d_TOSM_UNLIT;
+ if (toDrawArray)
{
- const bool toHilight = theWorkspace->ToHighlight();
- const Standard_Boolean hasVertColor = hasColorAttrib && !toHilight;
- if (aCtx->core20fwd != NULL)
+ const bool hasColorAttrib = !myVboAttribs.IsNull()
+ && myVboAttribs->HasColorAttribute();
+ const bool toHilight = theWorkspace->ToHighlight();
+ const bool hasVertColor = hasColorAttrib && !toHilight;
+ const bool hasVertNorm = !myVboAttribs.IsNull() && myVboAttribs->HasNormalAttribute();
+ switch (myDrawMode)
{
- switch (myDrawMode)
+ case GL_POINTS:
{
- case GL_POINTS:
- {
- const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx);
- if (!aSpriteNorm.IsNull()
- && !aSpriteNorm->IsDisplayList())
- {
- const Handle(OpenGl_PointSprite)& aSprite = (toHilight && anAspectMarker->SpriteHighlightRes (aCtx)->IsValid())
- ? anAspectMarker->SpriteHighlightRes (aCtx)
- : aSpriteNorm;
- theWorkspace->EnableTexture (aSprite);
- aCtx->ShaderManager()->BindMarkerProgram (aSprite, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
- }
- else
- {
- aCtx->ShaderManager()->BindMarkerProgram (NULL, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
- }
- break;
- }
- case GL_LINES:
- case GL_LINE_STRIP:
- {
- aCtx->ShaderManager()->BindLineProgram (NULL, anAspectLine->Type() != Aspect_TOL_SOLID, isLightOn, hasVertColor, anAspectLine->ShaderProgramRes (aCtx));
- break;
- }
- default:
+ aShadingModel = aCtx->ShaderManager()->ChooseMarkerShadingModel (anAspectFace->ShadingModel(), hasVertNorm);
+ aCtx->ShaderManager()->BindMarkerProgram (aCtx->ActiveTextures(),
+ aShadingModel, Graphic3d_AlphaMode_Opaque,
+ hasVertColor, anAspectFace->ShaderProgramRes (aCtx));
+ break;
+ }
+ case GL_LINES:
+ case GL_LINE_STRIP:
+ {
+ aShadingModel = aCtx->ShaderManager()->ChooseLineShadingModel (anAspectFace->ShadingModel(), hasVertNorm);
+ aCtx->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(),
+ anAspectFace->Aspect()->LineType(),
+ aShadingModel,
+ Graphic3d_AlphaMode_Opaque,
+ hasVertColor,
+ anAspectFace->ShaderProgramRes (aCtx));
+ break;
+ }
+ default:
+ {
+ aShadingModel = aCtx->ShaderManager()->ChooseFaceShadingModel (anAspectFace->ShadingModel(), hasVertNorm);
+ aCtx->ShaderManager()->BindFaceProgram (aCtx->ActiveTextures(),
+ aShadingModel,
+ aCtx->ShaderManager()->MaterialState().HasAlphaCutoff() ? Graphic3d_AlphaMode_Mask : Graphic3d_AlphaMode_Opaque,
+ toDrawInteriorEdges == 1 ? anAspectFace->Aspect()->InteriorStyle() : Aspect_IS_SOLID,
+ hasVertColor,
+ toEnableEnvMap,
+ toDrawInteriorEdges == 1,
+ anAspectFace->ShaderProgramRes (aCtx));
+ if (toDrawInteriorEdges == 1)
{
- const Handle(OpenGl_Texture)& aTexture = theWorkspace->ActiveTexture();
- const Standard_Boolean isLightOnFace = isLightOn
- && (aTexture.IsNull()
- || aTexture->GetParams()->IsModulate());
- const Standard_Boolean toEnableEnvMap = (!aTexture.IsNull() && (aTexture == theWorkspace->EnvironmentTexture()));
- aCtx->ShaderManager()->BindFaceProgram (aTexture,
- isLightOnFace,
- hasVertColor,
- toEnableEnvMap,
- anAspectFace->ShaderProgramRes (aCtx));
- break;
+ aCtx->ShaderManager()->PushInteriorState (aCtx->ActiveProgram(), anAspectFace->Aspect());
}
+ break;
}
}
- // All primitives should gather material properties from the AspectFace in shading mode
- if (isLightOn)
+ #if !defined(GL_ES_VERSION_2_0)
+ // manage FFP lighting
+ if (aCtx->ActiveProgram().IsNull()
+ && aCtx->core11 != NULL)
{
- aCtx->SetShadingMaterial (anAspectFace, theWorkspace->ToHighlight() ? (const OpenGl_Vec4* )theWorkspace->HighlightColor : NULL);
+ if (aShadingModel == Graphic3d_TOSM_UNLIT)
+ {
+ glDisable (GL_LIGHTING);
+ }
+ else
+ {
+ glEnable (GL_LIGHTING);
+ }
}
+ #endif
- if (!theWorkspace->ActiveTexture().IsNull()
+ if (!aCtx->ActiveTextures().IsNull()
+ && !aCtx->ActiveTextures()->IsEmpty()
+ && !aCtx->ActiveTextures()->First().IsNull()
&& myDrawMode != GL_POINTS) // transformation is not supported within point sprites
{
- aCtx->SetTextureMatrix (theWorkspace->ActiveTexture()->GetParams());
+ aCtx->SetTextureMatrix (aCtx->ActiveTextures()->First()->Sampler()->Parameters());
}
+ aCtx->SetSampleAlphaToCoverage (aCtx->ShaderManager()->MaterialState().HasAlphaCutoff());
- if (myDrawMode <= GL_LINE_STRIP)
- {
- const TEL_COLOUR& aLineColor = myDrawMode == GL_POINTS ? theWorkspace->MarkerColor() : theWorkspace->LineColor();
- aCtx->SetColor4fv (*(const OpenGl_Vec4* )aLineColor.rgb);
- }
- else
- {
- const TEL_COLOUR& anInteriorColor = theWorkspace->InteriorColor();
- aCtx->SetColor4fv (*(const OpenGl_Vec4* )anInteriorColor.rgb);
- }
- if (myDrawMode == GL_LINES
- || myDrawMode == GL_LINE_STRIP)
+ const Graphic3d_Vec4* aFaceColors = !myBounds.IsNull() && !toHilight && anAspectFace->Aspect()->InteriorStyle() != Aspect_IS_HIDDENLINE
+ ? myBounds->Colors
+ : NULL;
+ const OpenGl_Vec4& anInteriorColor = theWorkspace->InteriorColor();
+ aCtx->SetColor4fv (anInteriorColor);
+ if (!myIsFillType)
{
- aCtx->SetTypeOfLine (anAspectLine->Type());
- aCtx->SetLineWidth (anAspectLine->Width());
+ if (myDrawMode == GL_LINES
+ || myDrawMode == GL_LINE_STRIP)
+ {
+ aCtx->SetTypeOfLine (anAspectFace->Aspect()->LineType());
+ aCtx->SetLineWidth (anAspectFace->Aspect()->LineWidth());
+ }
+
+ drawArray (theWorkspace, aFaceColors, hasColorAttrib);
+ return;
}
- const Graphic3d_Vec4* aFaceColors = !myBounds.IsNull() && !toHilight && anAspectFace->InteriorStyle() != Aspect_IS_HIDDENLINE
- ? myBounds->Colors
- : NULL;
drawArray (theWorkspace, aFaceColors, hasColorAttrib);
- }
- if (myDrawMode <= GL_LINE_STRIP)
- {
- theWorkspace->EnableTexture (aTextureBack);
- }
- else
- {
- if (anAspectFace->Edge()
- || anAspectFace->InteriorStyle() == Aspect_IS_HIDDENLINE)
+ // draw outline - only closed triangulation with defined vertex normals can be drawn in this way
+ if (anAspectFace->Aspect()->ToDrawSilhouette()
+ && aCtx->ToCullBackFaces()
+ && aCtx->ShaderManager()->BindOutlineProgram())
{
- const TEL_COLOUR* anEdgeColor = &theWorkspace->EdgeColor();
- drawEdges (anEdgeColor, theWorkspace);
+ const Graphic3d_Vec2i aViewSize (aCtx->Viewport()[2], aCtx->Viewport()[3]);
+ const Standard_Integer aMin = aViewSize.minComp();
+ const GLfloat anEdgeWidth = (GLfloat )anAspectFace->Aspect()->EdgeWidth() * aCtx->LineWidthScale() / (GLfloat )aMin;
+ const GLfloat anOrthoScale = theWorkspace->View()->Camera()->IsOrthographic() ? (GLfloat )theWorkspace->View()->Camera()->Scale() : -1.0f;
- // restore OpenGL polygon mode if needed
- #if !defined(GL_ES_VERSION_2_0)
- if (anAspectFace->InteriorStyle() >= Aspect_IS_HATCH)
- {
- glPolygonMode (GL_FRONT_AND_BACK,
- anAspectFace->InteriorStyle() == Aspect_IS_POINT ? GL_POINT : GL_FILL);
- }
- #endif
+ const Handle(OpenGl_ShaderProgram)& anOutlineProgram = aCtx->ActiveProgram();
+ anOutlineProgram->SetUniform (aCtx, anOutlineProgram->GetStateLocation (OpenGl_OCCT_SILHOUETTE_THICKNESS), anEdgeWidth);
+ anOutlineProgram->SetUniform (aCtx, anOutlineProgram->GetStateLocation (OpenGl_OCCT_ORTHO_SCALE), anOrthoScale);
+ aCtx->SetColor4fv (anAspectFace->Aspect()->EdgeColorRGBA());
+
+ aCtx->core11fwd->glCullFace (GL_FRONT);
+ drawArray (theWorkspace, NULL, false);
+
+ aCtx->core11fwd->glCullFace (GL_BACK);
}
}
- aCtx->BindProgram (NULL);
+#if !defined(GL_ES_VERSION_2_0)
+ // draw triangulation edges using Polygon Mode
+ if (toDrawInteriorEdges == 2)
+ {
+ if (anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_HOLLOW
+ && anAspectFace->Aspect()->EdgeLineType() == Aspect_TOL_SOLID)
+ {
+ aCtx->SetPolygonMode (GL_FILL);
+ }
+ else
+ {
+ drawEdges (theWorkspace);
+ }
+ }
+#endif
}
// =======================================================================
if (myAttribs.IsNull())
{
myDrawMode = DRAW_MODE_NONE;
+ myIsFillType = false;
return;
}
switch (theType)
{
case Graphic3d_TOPA_POINTS:
- myDrawMode = GL_POINTS;
- break;
- case Graphic3d_TOPA_POLYLINES:
- myDrawMode = GL_LINE_STRIP;
+ myDrawMode = GL_POINTS;
+ myIsFillType = false;
break;
case Graphic3d_TOPA_SEGMENTS:
- myDrawMode = GL_LINES;
+ myDrawMode = GL_LINES;
+ myIsFillType = false;
+ break;
+ case Graphic3d_TOPA_POLYLINES:
+ myDrawMode = GL_LINE_STRIP;
+ myIsFillType = false;
break;
case Graphic3d_TOPA_TRIANGLES:
- myDrawMode = GL_TRIANGLES;
+ myDrawMode = GL_TRIANGLES;
+ myIsFillType = true;
break;
case Graphic3d_TOPA_TRIANGLESTRIPS:
- myDrawMode = GL_TRIANGLE_STRIP;
+ myDrawMode = GL_TRIANGLE_STRIP;
+ myIsFillType = true;
break;
case Graphic3d_TOPA_TRIANGLEFANS:
- myDrawMode = GL_TRIANGLE_FAN;
+ myDrawMode = GL_TRIANGLE_FAN;
+ myIsFillType = true;
break;
- #if !defined(GL_ES_VERSION_2_0)
- case Graphic3d_TOPA_POLYGONS:
- myDrawMode = GL_POLYGON;
+ //
+ case Graphic3d_TOPA_LINES_ADJACENCY:
+ myDrawMode = GL_LINES_ADJACENCY;
+ myIsFillType = false;
+ break;
+ case Graphic3d_TOPA_LINE_STRIP_ADJACENCY:
+ myDrawMode = GL_LINE_STRIP_ADJACENCY;
+ myIsFillType = false;
+ break;
+ case Graphic3d_TOPA_TRIANGLES_ADJACENCY:
+ myDrawMode = GL_TRIANGLES_ADJACENCY;
+ myIsFillType = true;
+ break;
+ case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY:
+ myDrawMode = GL_TRIANGLE_STRIP_ADJACENCY;
+ myIsFillType = true;
break;
+ //
+ #if !defined(GL_ES_VERSION_2_0)
case Graphic3d_TOPA_QUADRANGLES:
- myDrawMode = GL_QUADS;
+ myDrawMode = GL_QUADS;
+ myIsFillType = true;
break;
case Graphic3d_TOPA_QUADRANGLESTRIPS:
- myDrawMode = GL_QUAD_STRIP;
+ myDrawMode = GL_QUAD_STRIP;
+ myIsFillType = true;
break;
- #else
case Graphic3d_TOPA_POLYGONS:
+ myDrawMode = GL_POLYGON;
+ myIsFillType = true;
+ break;
+ #else
case Graphic3d_TOPA_QUADRANGLES:
case Graphic3d_TOPA_QUADRANGLESTRIPS:
+ case Graphic3d_TOPA_POLYGONS:
#endif
case Graphic3d_TOPA_UNDEFINED:
+ myDrawMode = DRAW_MODE_NONE;
+ myIsFillType = false;
break;
}
}
Standard_Boolean OpenGl_PrimitiveArray::processIndices (const Handle(OpenGl_Context)& theContext) const
{
if (myIndices.IsNull()
+ || myAttribs.IsNull()
|| theContext->hasUintIndex)
{
return Standard_True;
}
- if (myIndices->NbElements > std::numeric_limits<GLushort>::max())
+ if (myAttribs->NbElements > std::numeric_limits<GLushort>::max())
{
Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (new NCollection_AlignedAllocator (16));
if (!anAttribs->Init (myIndices->NbElements, myAttribs->AttributesArray(), myAttribs->NbAttributes))
const Handle(Graphic3d_BoundBuffer)& theBounds)
{
// Release old graphic resources
- Release (theContext.operator->());
+ Release (theContext.get());
myIndices = theIndices;
myAttribs = theAttribs;