mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-16 10:08:36 +03:00
1804 lines
54 KiB
C++
Executable File
1804 lines
54 KiB
C++
Executable File
// Created on: 2011-07-13
|
|
// Created by: Sergey ZERCHANINOV
|
|
// Copyright (c) 2011-2012 OPEN CASCADE SAS
|
|
//
|
|
// The content of this file is subject to the Open CASCADE Technology Public
|
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
// except in compliance with the License. Please obtain a copy of the License
|
|
// at http://www.opencascade.org and read it completely before using this file.
|
|
//
|
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
//
|
|
// The Original Code and all software distributed under the License is
|
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
// Initial Developer hereby disclaims all such warranties, including without
|
|
// limitation, any warranties of merchantability, fitness for a particular
|
|
// purpose or non-infringement. Please see the License for the specific terms
|
|
// and conditions governing the rights and limitations under the License.
|
|
|
|
|
|
#include <OpenGl_ArbVBO.hxx>
|
|
#include <OpenGl_Context.hxx>
|
|
|
|
#include <OpenGl_PrimitiveArray.hxx>
|
|
|
|
#include <OpenGl_AspectFace.hxx>
|
|
#include <OpenGl_GraphicDriver.hxx>
|
|
#include <OpenGl_ResourceCleaner.hxx>
|
|
#include <OpenGl_ResourceVBO.hxx>
|
|
#include <OpenGl_Structure.hxx>
|
|
#include <OpenGl_TextureBox.hxx>
|
|
|
|
#include <InterfaceGraphic_PrimitiveArray.hxx>
|
|
|
|
enum
|
|
{
|
|
VBO_NOT_INITIALIZED = -1,
|
|
VBO_ERROR = 0,
|
|
VBO_OK = 1
|
|
};
|
|
|
|
namespace
|
|
{
|
|
static unsigned long vRand = 1L;
|
|
#define OGL_Rand() (vRand = vRand * 214013L + 2531011L)
|
|
};
|
|
|
|
// =======================================================================
|
|
// function : clearMemoryOwn
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::clearMemoryOwn() const
|
|
{
|
|
if (myPArray->bufferVBO[VBOEdges] != 0)
|
|
{
|
|
Standard::Free ((Standard_Address& )myPArray->edges);
|
|
myPArray->edges = NULL;
|
|
}
|
|
if (myPArray->bufferVBO[VBOVertices] != 0)
|
|
{
|
|
Standard::Free ((Standard_Address& )myPArray->vertices);
|
|
myPArray->vertices = NULL;
|
|
}
|
|
if (myPArray->bufferVBO[VBOVcolours] != 0)
|
|
{
|
|
Standard::Free ((Standard_Address& )myPArray->vcolours);
|
|
myPArray->vcolours = NULL;
|
|
}
|
|
if (myPArray->bufferVBO[VBOVnormals] != 0)
|
|
{
|
|
Standard::Free ((Standard_Address& )myPArray->vnormals);
|
|
myPArray->vnormals = NULL;
|
|
}
|
|
if (myPArray->bufferVBO[VBOVtexels] != 0)
|
|
{
|
|
Standard::Free ((Standard_Address& )myPArray->vtexels);
|
|
myPArray->vtexels = NULL;
|
|
}
|
|
if (myPArray->edge_vis != NULL) /// ????
|
|
{
|
|
Standard::Free ((Standard_Address& )myPArray->edge_vis);
|
|
myPArray->edge_vis = NULL;
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : clearMemoryGL
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlContext) const
|
|
{
|
|
if (myPArray->bufferVBO[VBOEdges] != 0)
|
|
{
|
|
theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
|
|
}
|
|
if (myPArray->bufferVBO[VBOVertices] != 0)
|
|
{
|
|
theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
|
|
}
|
|
if (myPArray->bufferVBO[VBOVcolours] != 0)
|
|
{
|
|
theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
|
|
}
|
|
if (myPArray->bufferVBO[VBOVnormals] != 0)
|
|
{
|
|
theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
|
|
}
|
|
if (myPArray->bufferVBO[VBOVtexels] != 0)
|
|
{
|
|
theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
|
|
}
|
|
theGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
|
|
theGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : checkSizeForGraphicMemory
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_PrimitiveArray::checkSizeForGraphicMemory (const Handle(OpenGl_Context)& theGlContext) const
|
|
{
|
|
if (glGetError() == GL_OUT_OF_MEMORY)
|
|
{
|
|
myPArray->flagBufferVBO = VBO_ERROR;
|
|
clearMemoryGL (theGlContext);
|
|
}
|
|
else
|
|
{
|
|
myPArray->flagBufferVBO = VBO_OK;
|
|
}
|
|
return myPArray->flagBufferVBO == VBO_OK;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : BuildVBO
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
|
|
{
|
|
int size_reqd = 0;
|
|
const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
|
|
if (myPArray->edges != NULL)
|
|
{
|
|
size_reqd = myPArray->num_edges * sizeof(Tint);
|
|
aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
|
|
aGlContext->arbVBO->glBufferDataARB (GL_ELEMENT_ARRAY_BUFFER_ARB, size_reqd, myPArray->edges, GL_STATIC_DRAW_ARB);
|
|
if (!checkSizeForGraphicMemory (aGlContext))
|
|
return Standard_False;
|
|
}
|
|
|
|
if (myPArray->vertices != NULL)
|
|
{
|
|
size_reqd = myPArray->num_vertexs * sizeof(TEL_POINT);
|
|
aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
|
|
aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vertices, GL_STATIC_DRAW_ARB);
|
|
if (!checkSizeForGraphicMemory (aGlContext))
|
|
return Standard_False;
|
|
}
|
|
|
|
if (myPArray->vcolours != NULL)
|
|
{
|
|
size_reqd = myPArray->num_vertexs * sizeof(Tint);
|
|
aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]);
|
|
aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vcolours, GL_STATIC_DRAW_ARB);
|
|
if (!checkSizeForGraphicMemory (aGlContext))
|
|
return Standard_False;
|
|
}
|
|
|
|
if (myPArray->vnormals != NULL)
|
|
{
|
|
size_reqd = myPArray->num_vertexs * sizeof(TEL_POINT);
|
|
aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
|
|
aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vnormals, GL_STATIC_DRAW_ARB);
|
|
if (!checkSizeForGraphicMemory (aGlContext))
|
|
return Standard_False;
|
|
}
|
|
|
|
if (myPArray->vtexels)
|
|
{
|
|
size_reqd = myPArray->num_vertexs * sizeof(TEL_TEXTURE_COORD);
|
|
aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
|
|
aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vtexels, GL_STATIC_DRAW_ARB);
|
|
if (!checkSizeForGraphicMemory (aGlContext))
|
|
return Standard_False;
|
|
}
|
|
|
|
if (myPArray->flagBufferVBO == VBO_OK)
|
|
clearMemoryOwn();
|
|
|
|
// specify context for VBO resource
|
|
myPArray->contextId = (Standard_Address )theWorkspace->GetGContext();
|
|
return Standard_True;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawArrays
|
|
// purpose : Auxiliary method to split Feedback/Normal rendering modes
|
|
// =======================================================================
|
|
inline void DrawArrays (const Handle(OpenGl_Workspace)& theWorkspace,
|
|
const CALL_DEF_PARRAY* thePArray,
|
|
const Standard_Boolean theIsFeedback,
|
|
GLenum theMode,
|
|
GLint theFirst,
|
|
GLsizei theCount)
|
|
{
|
|
if (!theIsFeedback)
|
|
{
|
|
glDrawArrays (theMode, theFirst, theCount);
|
|
return;
|
|
}
|
|
|
|
glBegin (theMode);
|
|
for (int anIter = theFirst; anIter < (theFirst + theCount); ++anIter)
|
|
{
|
|
if (thePArray->vnormals != NULL)
|
|
glNormal3fv (thePArray->vnormals[anIter].xyz);
|
|
if (thePArray->vtexels != NULL && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
|
|
glTexCoord3fv (thePArray->vtexels[anIter].xy);
|
|
if (thePArray->vertices != NULL)
|
|
glVertex3fv (thePArray->vertices[anIter].xyz);
|
|
if (thePArray->vcolours != NULL)
|
|
glColor4ubv((GLubyte* )thePArray->vcolours[anIter]);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawElements
|
|
// purpose : Auxiliary method to split Feedback/Normal rendering modes
|
|
// =======================================================================
|
|
inline void DrawElements (const Handle(OpenGl_Workspace)& theWorkspace,
|
|
const CALL_DEF_PARRAY* thePArray,
|
|
const Standard_Boolean theIsFeedback,
|
|
GLenum theMode,
|
|
GLsizei theCount,
|
|
GLenum* theIndices)
|
|
{
|
|
if (!theIsFeedback)
|
|
{
|
|
glDrawElements (theMode, theCount, GL_UNSIGNED_INT, theIndices);
|
|
return;
|
|
}
|
|
|
|
GLenum anIndex;
|
|
glBegin (theMode);
|
|
for (GLsizei anIter = 0; anIter < theCount; ++anIter)
|
|
{
|
|
anIndex = theIndices[anIter];
|
|
if (thePArray->vnormals != NULL)
|
|
glNormal3fv (thePArray->vnormals[anIndex].xyz);
|
|
if (thePArray->vtexels != NULL && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
|
|
glTexCoord3fv (thePArray->vtexels[anIndex].xy);
|
|
if (thePArray->vertices != NULL)
|
|
glVertex3fv (thePArray->vertices[anIndex].xyz);
|
|
if (thePArray->vcolours != NULL)
|
|
glColor4ubv ((GLubyte* )thePArray->vcolours[anIndex]);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawArray
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
|
|
const Aspect_InteriorStyle theInteriorStyle,
|
|
Tint theEdgeFlag,
|
|
const TEL_COLOUR* theInteriorColour,
|
|
const TEL_COLOUR* theLineColour,
|
|
const TEL_COLOUR* theEdgeColour,
|
|
const OPENGL_SURF_PROP* theFaceProp,
|
|
const Handle(OpenGl_Workspace)& theWorkspace) const
|
|
{
|
|
const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
|
|
|
|
Tint i,n;
|
|
Tint transp = 0;
|
|
// Following pointers have been provided for performance improvement
|
|
tel_colour pfc = myPArray->fcolours;
|
|
Tint* pvc = myPArray->vcolours;
|
|
if (pvc != NULL)
|
|
{
|
|
for (i = 0; i < myPArray->num_vertexs; ++i)
|
|
{
|
|
transp = int(theFaceProp->trans * 255.0f);
|
|
#if defined (sparc) || defined (__sparc__) || defined (__sparc)
|
|
pvc[i] = (pvc[i] & 0xffffff00);
|
|
pvc[i] += transp;
|
|
#else
|
|
pvc[i] = (pvc[i] & 0x00ffffff);
|
|
pvc[i] += transp << 24;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
switch (myPArray->type)
|
|
{
|
|
case TelPointsArrayType:
|
|
case TelPolylinesArrayType:
|
|
case TelSegmentsArrayType:
|
|
glColor3fv (theLineColour->rgb);
|
|
break;
|
|
case TelPolygonsArrayType:
|
|
case TelTrianglesArrayType:
|
|
case TelQuadranglesArrayType:
|
|
case TelTriangleStripsArrayType:
|
|
case TelQuadrangleStripsArrayType:
|
|
case TelTriangleFansArrayType:
|
|
glColor3fv (theInteriorColour->rgb);
|
|
break;
|
|
}
|
|
|
|
// Temporarily disable environment mapping
|
|
if (myDrawMode <= GL_LINE_STRIP)
|
|
{
|
|
glPushAttrib (GL_ENABLE_BIT);
|
|
glDisable (GL_TEXTURE_1D);
|
|
glDisable (GL_TEXTURE_2D);
|
|
}
|
|
|
|
if (theWorkspace->DegenerateModel < 2 &&
|
|
((myDrawMode > GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) ||
|
|
(myDrawMode <= GL_LINE_STRIP)))
|
|
{
|
|
if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
|
|
{
|
|
pfc = NULL;
|
|
pvc = NULL;
|
|
}
|
|
|
|
if (theInteriorStyle == Aspect_IS_HIDDENLINE)
|
|
{
|
|
theEdgeFlag = 1;
|
|
pfc = NULL;
|
|
pvc = NULL;
|
|
}
|
|
|
|
// Sometimes the GL_LIGHTING mode is activated here
|
|
// without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary
|
|
// to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism*
|
|
if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP)
|
|
glDisable (GL_LIGHTING);
|
|
else
|
|
glEnable (GL_LIGHTING);
|
|
|
|
if (myPArray->num_vertexs > 0
|
|
&& myPArray->flagBufferVBO != VBO_OK
|
|
&& !aGlContext->IsFeedback())
|
|
{
|
|
if (myPArray->vertices != NULL)
|
|
{
|
|
glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
|
|
glEnableClientState (GL_VERTEX_ARRAY);
|
|
}
|
|
if (myPArray->vnormals != NULL)
|
|
{
|
|
glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals
|
|
glEnableClientState (GL_NORMAL_ARRAY);
|
|
}
|
|
if (myPArray->vtexels != NULL)
|
|
{
|
|
glTexCoordPointer (2, GL_FLOAT, 0, myPArray->vtexels); // array of texture coordinates
|
|
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
|
|
if (pvc != NULL)
|
|
{
|
|
glColorPointer (4, GL_UNSIGNED_BYTE, 0, pvc); // array of colors
|
|
glEnableClientState (GL_COLOR_ARRAY);
|
|
glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
|
|
glEnable (GL_COLOR_MATERIAL);
|
|
}
|
|
}
|
|
else if (myPArray->num_vertexs > 0
|
|
&& myPArray->flagBufferVBO == VBO_OK)
|
|
{
|
|
// Bindings concrete pointer in accordance with VBO buffer
|
|
if (myPArray->bufferVBO[VBOVertices] != 0)
|
|
{
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
|
|
glVertexPointer (3, GL_FLOAT, 0, NULL); // array of vertices
|
|
glEnableClientState (GL_VERTEX_ARRAY);
|
|
}
|
|
if (myPArray->bufferVBO[VBOVnormals] != 0)
|
|
{
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
|
|
glNormalPointer (GL_FLOAT, 0, NULL); // array of normals
|
|
glEnableClientState (GL_NORMAL_ARRAY);
|
|
}
|
|
if (myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
|
|
{
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
|
|
glTexCoordPointer (2, GL_FLOAT, 0, NULL); // array of texture coordinates
|
|
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
if (myPArray->bufferVBO[VBOVcolours] != 0)
|
|
{
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]);
|
|
glColorPointer (4, GL_UNSIGNED_BYTE, 0, NULL); // array of colors
|
|
glEnableClientState (GL_COLOR_ARRAY);
|
|
glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
|
|
glEnable (GL_COLOR_MATERIAL);
|
|
}
|
|
}
|
|
|
|
// OCC22236 NOTE: draw for all situations:
|
|
// 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
|
|
// 2) draw elements from vertice array, when bounds defines count of primitive's verts.
|
|
// 3) draw primitive by vertexes if no edges and bounds array is specified
|
|
if (myPArray->flagBufferVBO == VBO_OK)
|
|
{
|
|
if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges] != 0)
|
|
{
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]); // for edge indices
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
// draw primitives by vertex count with the indicies
|
|
Tint* anOffset = NULL;
|
|
for (i = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, anOffset);
|
|
anOffset += myPArray->bounds[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// draw one (or sequential) primitive by the indicies
|
|
glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
|
|
}
|
|
}
|
|
else if (myPArray->num_bounds > 0)
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
|
|
}
|
|
|
|
// bind with 0
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
|
}
|
|
else
|
|
{
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
if (myPArray->num_edges > 0)
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
if (pfc != NULL) glColor3fv (pfc[i].rgb);
|
|
DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
|
|
myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
if (pfc != NULL)
|
|
{
|
|
glColor3fv (pfc[i].rgb);
|
|
}
|
|
DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
|
|
n, myPArray->bounds[i]);
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
}
|
|
else if (myPArray->num_edges > 0)
|
|
{
|
|
DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
|
|
myPArray->num_edges, (GLenum* )myPArray->edges);
|
|
}
|
|
else
|
|
{
|
|
DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
|
|
0, myPArray->num_vertexs);
|
|
}
|
|
}
|
|
|
|
if (myPArray->bufferVBO[VBOVcolours] != 0 || pvc != NULL)
|
|
{
|
|
glDisable (GL_COLOR_MATERIAL);
|
|
theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
|
|
}
|
|
|
|
if (myPArray->bufferVBO[VBOVertices] != 0 || myPArray->vertices != NULL)
|
|
glDisableClientState (GL_VERTEX_ARRAY);
|
|
if (myPArray->bufferVBO[VBOVcolours] != 0 || myPArray->vcolours != NULL)
|
|
glDisableClientState (GL_COLOR_ARRAY);
|
|
if (myPArray->bufferVBO[VBOVnormals] != 0 || myPArray->vnormals != NULL)
|
|
glDisableClientState (GL_NORMAL_ARRAY);
|
|
if ((myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0) || myPArray->vtexels != NULL)
|
|
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
|
|
|
|
if (theWorkspace->DegenerateModel)
|
|
{
|
|
if (myDrawMode <= GL_LINE_STRIP)
|
|
{
|
|
glPopAttrib();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (theEdgeFlag || theWorkspace->DegenerateModel)
|
|
{
|
|
switch (theWorkspace->DegenerateModel)
|
|
{
|
|
default: // XXX_TDM_NODE or TINY
|
|
// On some NVIDIA graphic cards, using glEdgeFlagPointer() in
|
|
// combination with VBO ( edge flag data put into a VBO buffer)
|
|
// leads to a crash in a driver. Therefore, edge flags are simply
|
|
// igonored when VBOs are enabled, so all the edges are drawn if
|
|
// edge visibility is turned on. In order to draw edges selectively,
|
|
// either disable VBO or turn off edge visibilty in the current
|
|
// primitive array and create a separate primitive array (segments)
|
|
// and put edges to be drawn into it.
|
|
if (myDrawMode > GL_LINE_STRIP)
|
|
{
|
|
DrawEdges (theEdgeFlag ? theEdgeColour : theInteriorColour, theWorkspace);
|
|
}
|
|
break;
|
|
// DegenerateModel(as Lines, Points, BBoxs) are used only without VBO
|
|
case 2: // XXX_TDM_WIREFRAME
|
|
if (myPArray->VBOEnabled == 0)
|
|
DrawDegeneratesAsLines ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace);
|
|
break;
|
|
case 3: // XXX_TDM_MARKER
|
|
if (myPArray->VBOEnabled == 0)
|
|
DrawDegeneratesAsPoints ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace->SkipRatio);
|
|
break;
|
|
case 4: // XXX_TDM_BBOX
|
|
if (myPArray->VBOEnabled == 0)
|
|
DrawDegeneratesAsBBoxs (theEdgeFlag ? theEdgeColour : theInteriorColour);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (myDrawMode <= GL_LINE_STRIP)
|
|
glPopAttrib();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawEdges
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR* theEdgeColour,
|
|
const Handle(OpenGl_Workspace)& theWorkspace) const
|
|
{
|
|
glDisable (GL_LIGHTING);
|
|
|
|
const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
|
|
const OpenGl_AspectLine* anAspectLineOld = NULL;
|
|
if (myDrawMode > GL_LINE_STRIP)
|
|
{
|
|
anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge());
|
|
theWorkspace->AspectLine (Standard_True);
|
|
|
|
glPushAttrib (GL_POLYGON_BIT);
|
|
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
|
|
}
|
|
|
|
Tint i, j, n;
|
|
|
|
// OCC22236 NOTE: draw edges for all situations:
|
|
// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
|
|
// 2) draw elements from vertice array, when bounds defines count of primitive's verts.
|
|
// 3) draw primitive's edges by vertexes if no edges and bounds array is specified
|
|
if (myPArray->flagBufferVBO == VBO_OK)
|
|
{
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
|
|
glEnableClientState (GL_VERTEX_ARRAY);
|
|
glColor3fv (theEdgeColour->rgb);
|
|
if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges])
|
|
{
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
|
|
|
|
// draw primitives by vertex count with the indicies
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
Tint* offset = 0;
|
|
for (i = 0, offset = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, offset);
|
|
offset += myPArray->bounds[i];
|
|
}
|
|
}
|
|
// draw one (or sequential) primitive by the indicies
|
|
else
|
|
{
|
|
glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
|
|
}
|
|
}
|
|
else if (myPArray->num_bounds > 0)
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
|
|
}
|
|
|
|
// unbind buffers
|
|
glDisableClientState (GL_VERTEX_ARRAY);
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
|
|
aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
|
}
|
|
else
|
|
{
|
|
glEnableClientState (GL_VERTEX_ARRAY);
|
|
glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
|
|
|
|
glColor3fv (theEdgeColour->rgb);
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
if (myPArray->num_edges > 0)
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
if (myPArray->edge_vis)
|
|
{
|
|
glBegin (myDrawMode);
|
|
for (j = 0; j < myPArray->bounds[i]; ++j)
|
|
{
|
|
glEdgeFlag (myPArray->edge_vis[n+j]);
|
|
glVertex3fv (&myPArray->vertices[myPArray->edges[n+j]].xyz[0]);
|
|
}
|
|
glEnd();
|
|
}
|
|
else
|
|
{
|
|
DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
|
|
myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
|
|
}
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = n = 0 ; i < myPArray->num_bounds; ++i)
|
|
{
|
|
DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
|
|
n, myPArray->bounds[i]);
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
}
|
|
else if (myPArray->num_edges > 0)
|
|
{
|
|
if (myPArray->edge_vis)
|
|
{
|
|
glBegin (myDrawMode);
|
|
for (i = 0; i < myPArray->num_edges; ++i)
|
|
{
|
|
glEdgeFlag (myPArray->edge_vis[i]);
|
|
glVertex3fv (&myPArray->vertices[myPArray->edges[i]].xyz[0]);
|
|
}
|
|
glEnd();
|
|
}
|
|
else
|
|
{
|
|
DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
|
|
myPArray->num_edges, (GLenum* )myPArray->edges);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
|
|
0, myPArray->num_vertexs);
|
|
}
|
|
}
|
|
|
|
if (myDrawMode > GL_LINE_STRIP)
|
|
{
|
|
// Restore line context
|
|
theWorkspace->SetAspectLine (anAspectLineOld);
|
|
glPopAttrib();
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesPointsAsPoints
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesPointsAsPoints() const
|
|
{
|
|
tel_point pv = myPArray->vertices;
|
|
for (Tint aVertId = 0; aVertId < myPArray->num_vertexs; ++aVertId)
|
|
{
|
|
glVertex3fv (&pv[aVertId].xyz[0]);
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesLinesAsPoints
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsPoints() const
|
|
{
|
|
GLfloat pt[3];
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
Tint j = 0;
|
|
while (j < myPArray->num_vertexs)
|
|
{
|
|
pt[0] = pv[j].xyz[0];
|
|
pt[1] = pv[j].xyz[1];
|
|
pt[2] = pv[j].xyz[2]; ++j;
|
|
pt[0] += pv[j].xyz[0];
|
|
pt[1] += pv[j].xyz[1];
|
|
pt[2] += pv[j].xyz[2]; ++j;
|
|
pt[0] *= 0.5f;
|
|
pt[1] *= 0.5f;
|
|
pt[2] *= 0.5f;
|
|
glVertex3fv (pt);
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesTrianglesAsPoints
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsPoints() const
|
|
{
|
|
Tint i, j, iv;
|
|
GLfloat pt[ 3 ];
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
if (myPArray->num_edges > 0)
|
|
{
|
|
for (j = 0; j < myPArray->num_edges; j += 3)
|
|
{
|
|
iv = myPArray->edges[j];
|
|
pt[0] = pv[iv].xyz[0];
|
|
pt[1] = pv[iv].xyz[1];
|
|
pt[2] = pv[iv].xyz[2];
|
|
for (i = 1; i < 3; ++i)
|
|
{
|
|
iv = myPArray->edges[j+i];
|
|
pt[0] += pv[iv].xyz[0];
|
|
pt[1] += pv[iv].xyz[1];
|
|
pt[2] += pv[iv].xyz[2];
|
|
}
|
|
pt[0] /= 3.f;
|
|
pt[1] /= 3.f;
|
|
pt[2] /= 3.f;
|
|
glVertex3fv (pt);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (j = 0; j < myPArray->num_vertexs; j += 3)
|
|
{
|
|
pt[0] = pv[j].xyz[0];
|
|
pt[1] = pv[j].xyz[1];
|
|
pt[2] = pv[j].xyz[2];
|
|
for (i = 1; i < 3; ++i)
|
|
{
|
|
pt[0] += pv[j+i].xyz[0];
|
|
pt[1] += pv[j+i].xyz[1];
|
|
pt[2] += pv[j+i].xyz[2];
|
|
}
|
|
pt[0] /= 3.f;
|
|
pt[1] /= 3.f;
|
|
pt[2] /= 3.f;
|
|
glVertex3fv (pt);
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesTrianglesAsPoints
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsPoints() const
|
|
{
|
|
Tint i, j, k, n;
|
|
GLfloat pt[ 3 ];
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
for (k = n = 0; k < myPArray->num_bounds; ++k)
|
|
{
|
|
for (j = 0; j < myPArray->bounds[k] - 2; ++j)
|
|
{
|
|
pt[0] = pv[n+j].xyz[0];
|
|
pt[1] = pv[n+j].xyz[1];
|
|
pt[2] = pv[n+j].xyz[2];
|
|
for (i = 1; i < 3; ++i)
|
|
{
|
|
pt[0] += pv[n+j+i].xyz[0];
|
|
pt[1] += pv[n+j+i].xyz[1];
|
|
pt[2] += pv[n+j+i].xyz[2];
|
|
}
|
|
pt[0] /= 3.f;
|
|
pt[1] /= 3.f;
|
|
pt[2] /= 3.f;
|
|
glVertex3fv (pt);
|
|
}
|
|
n += myPArray->bounds[k];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (j = 0; j < myPArray->num_vertexs - 2; ++j)
|
|
{
|
|
pt[0] = pv[j].xyz[0];
|
|
pt[1] = pv[j].xyz[1];
|
|
pt[2] = pv[j].xyz[2];
|
|
for (i = 1; i < 3; ++i)
|
|
{
|
|
pt[0] += pv[j+i].xyz[0];
|
|
pt[1] += pv[j+i].xyz[1];
|
|
pt[2] += pv[j+i].xyz[2];
|
|
}
|
|
pt[0] /= 3.f;
|
|
pt[1] /= 3.f;
|
|
pt[2] /= 3.f;
|
|
glVertex3fv (pt);
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesPolygonsAsPoints
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsPoints() const
|
|
{
|
|
Tint j, k, n, iv;
|
|
GLfloat pt[3];
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
if (myPArray->num_edges > 0)
|
|
{
|
|
for (k = n = 0; k < myPArray->num_bounds; ++k)
|
|
{
|
|
pt[0] = pt[1] = pt[2] = 0.0;
|
|
for (j = 0; j < myPArray->bounds[k]; ++j)
|
|
{
|
|
iv = myPArray->edges[n+j];
|
|
pt[0] += pv[iv].xyz[0];
|
|
pt[1] += pv[iv].xyz[1];
|
|
pt[2] += pv[iv].xyz[2];
|
|
}
|
|
pt[0] /= myPArray->bounds[k];
|
|
pt[1] /= myPArray->bounds[k];
|
|
pt[2] /= myPArray->bounds[k];
|
|
glVertex3fv (pt);
|
|
n += myPArray->bounds[k];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (k = n = 0; k < myPArray->num_bounds; ++k)
|
|
{
|
|
pt[0] = pt[1] = pt[2] = 0.0;
|
|
for (j = 0; j < myPArray->bounds[k]; ++j)
|
|
{
|
|
pt[0] += pv[n+j].xyz[0];
|
|
pt[1] += pv[n+j].xyz[1];
|
|
pt[2] += pv[n+j].xyz[2];
|
|
}
|
|
pt[0] /= myPArray->bounds[k];
|
|
pt[1] /= myPArray->bounds[k];
|
|
pt[2] /= myPArray->bounds[k];
|
|
glVertex3fv (pt);
|
|
n += myPArray->bounds[k];
|
|
}
|
|
}
|
|
}
|
|
else if (myPArray->num_edges > 0)
|
|
{
|
|
pt[0] = pt[1] = pt[2] = 0.0;
|
|
for (j = 0; j < myPArray->num_edges; ++j)
|
|
{
|
|
iv = myPArray->edges[j];
|
|
pt[0] += pv[iv].xyz[0];
|
|
pt[1] += pv[iv].xyz[1];
|
|
pt[2] += pv[iv].xyz[2];
|
|
}
|
|
pt[0] /= myPArray->num_edges;
|
|
pt[1] /= myPArray->num_edges;
|
|
pt[2] /= myPArray->num_edges;
|
|
glVertex3fv (pt);
|
|
}
|
|
else
|
|
{
|
|
pt[0] = pt[1] = pt[2] = 0.0;
|
|
for (j = 0; j < myPArray->num_vertexs; ++j)
|
|
{
|
|
pt[0] += pv[j].xyz[0];
|
|
pt[1] += pv[j].xyz[1];
|
|
pt[2] += pv[j].xyz[2];
|
|
}
|
|
pt[0] /= myPArray->num_vertexs;
|
|
pt[1] /= myPArray->num_vertexs;
|
|
pt[2] /= myPArray->num_vertexs;
|
|
glVertex3fv (pt);
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesQuadranglesAsPoints
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsPoints() const
|
|
{
|
|
Tint i, j, iv;
|
|
GLfloat pt[ 3 ];
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
if (myPArray->num_edges > 0)
|
|
{
|
|
for (j = 0; j < myPArray->num_edges; j += 4)
|
|
{
|
|
pt[0] = pt[1] = pt[2] = 0.0;
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
iv = myPArray->edges[j+i];
|
|
pt[0] += pv[iv].xyz[0];
|
|
pt[1] += pv[iv].xyz[1];
|
|
pt[2] += pv[iv].xyz[2];
|
|
}
|
|
pt[0] /= 4;
|
|
pt[1] /= 4;
|
|
pt[2] /= 4;
|
|
glVertex3fv ( pt );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (j = 0; j < myPArray->num_vertexs; j += 4)
|
|
{
|
|
pt[0] = pt[1] = pt[2] = 0.0;
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
pt[0] += pv[j+i].xyz[0];
|
|
pt[1] += pv[j+i].xyz[1];
|
|
pt[2] += pv[j+i].xyz[2];
|
|
}
|
|
pt[0] /= 4;
|
|
pt[1] /= 4;
|
|
pt[2] /= 4;
|
|
glVertex3fv (pt);
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesAsPoints
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsPoints() const
|
|
{
|
|
Tint i, j, k, n;
|
|
GLfloat pt[3];
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
for (k = n = 0; k < myPArray->num_bounds; ++k)
|
|
{
|
|
for (j = 0; j < myPArray->bounds[k] - 2; j += 2)
|
|
{
|
|
pt[0] = pt[1] = pt[2] = 0.;
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
pt[0] += pv[n+j+i].xyz[0];
|
|
pt[1] += pv[n+j+i].xyz[1];
|
|
pt[2] += pv[n+j+i].xyz[2];
|
|
}
|
|
pt[0] /= 4;
|
|
pt[1] /= 4;
|
|
pt[2] /= 4;
|
|
glVertex3fv (pt);
|
|
}
|
|
n += myPArray->bounds[k];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (j = 0; j < myPArray->num_vertexs - 2; j += 2)
|
|
{
|
|
pt[0] = pt[1] = pt[2] = 0.;
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
pt[0] += pv[j+i].xyz[0];
|
|
pt[1] += pv[j+i].xyz[1];
|
|
pt[2] += pv[j+i].xyz[2];
|
|
}
|
|
pt[0] /= 4;
|
|
pt[1] /= 4;
|
|
pt[2] /= 4;
|
|
glVertex3fv (pt);
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesAsPoints
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesAsPoints (const TEL_COLOUR* theEdgeColour,
|
|
const float theSkipRatio) const
|
|
{
|
|
if (theSkipRatio >= 1.0f)
|
|
return;
|
|
|
|
GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
|
|
glDisable (GL_LIGHTING);
|
|
if (zbuff_state)
|
|
glDisable (GL_DEPTH_TEST);
|
|
glColor3fv (theEdgeColour->rgb);
|
|
|
|
glBegin (GL_POINTS);
|
|
switch (myDrawMode)
|
|
{
|
|
case GL_POINTS:
|
|
DrawDegeneratesPointsAsPoints();
|
|
break;
|
|
case GL_LINES:
|
|
DrawDegeneratesLinesAsPoints();
|
|
break;
|
|
case GL_LINE_STRIP:
|
|
case GL_POLYGON:
|
|
DrawDegeneratesPolygonsAsPoints();
|
|
break;
|
|
case GL_TRIANGLES:
|
|
DrawDegeneratesTrianglesAsPoints();
|
|
break;
|
|
case GL_QUADS:
|
|
DrawDegeneratesQuadranglesAsPoints();
|
|
break;
|
|
case GL_TRIANGLE_FAN:
|
|
case GL_TRIANGLE_STRIP:
|
|
DrawDegeneratesTrianglestripsAsPoints();
|
|
break;
|
|
case GL_QUAD_STRIP:
|
|
DrawDegeneratesQuadranglestripsAsPoints();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
glEnd();
|
|
if (zbuff_state)
|
|
glEnable (GL_DEPTH_TEST);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesLinesAsLines
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsLines (const float theSkipRatio) const
|
|
{
|
|
Tint i, iv;
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
Tint n = myPArray->num_vertexs;
|
|
Tint j = int((1.0f - theSkipRatio) * n);
|
|
for (; j > 0; --j)
|
|
{
|
|
i = OGL_Rand() % n;
|
|
myPArray->keys[i] = -myPArray->keys[i];
|
|
}
|
|
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
if (myPArray->num_edges > 0)
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
glBegin (GL_LINES);
|
|
for (j = 0; j < myPArray->bounds[i]; ++j)
|
|
{
|
|
iv = myPArray->edges[n + j];
|
|
if (myPArray->keys[iv] < 0)
|
|
{
|
|
myPArray->keys[iv] = -myPArray->keys[iv];
|
|
glVertex3fv (pv[iv].xyz);
|
|
}
|
|
}
|
|
glEnd();
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
glBegin (GL_LINES);
|
|
for (j = 0; j < myPArray->bounds[i]; ++j)
|
|
{
|
|
if (myPArray->keys[n+j] < 0)
|
|
{
|
|
myPArray->keys[n+j] = -myPArray->keys[n+j];
|
|
glVertex3fv (pv[n+j].xyz);
|
|
}
|
|
}
|
|
glEnd();
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
}
|
|
else if (myPArray->num_edges > 0)
|
|
{
|
|
glBegin (GL_LINES);
|
|
for (j = 0; j < myPArray->num_edges; ++j)
|
|
{
|
|
iv = myPArray->edges[j];
|
|
if (myPArray->keys[iv] < 0)
|
|
{
|
|
myPArray->keys[iv] = -myPArray->keys[iv];
|
|
glVertex3fv (pv[iv].xyz);
|
|
}
|
|
}
|
|
glEnd();
|
|
}
|
|
else
|
|
{
|
|
glBegin (GL_LINES);
|
|
for (j = 0; j < myPArray->num_vertexs; ++j)
|
|
{
|
|
if (myPArray->keys[j] < 0)
|
|
{
|
|
myPArray->keys[j] = -myPArray->keys[j];
|
|
glVertex3fv (pv[j].xyz);
|
|
}
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesTrianglesAsLines
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsLines (const float theSkipRatio) const
|
|
{
|
|
Tint i, iv;
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
Tint n = myPArray->num_vertexs / 3;
|
|
Tint j = int((1.0f - theSkipRatio) * n);
|
|
for (; j > 0; --j)
|
|
{
|
|
i = OGL_Rand() % n; i *= 3;
|
|
myPArray->keys[i] = -myPArray->keys[i];
|
|
}
|
|
|
|
if (myPArray->num_edges > 0)
|
|
{
|
|
for (j = 0; j < myPArray->num_edges; j += 3)
|
|
{
|
|
iv = myPArray->edges[j];
|
|
if (myPArray->keys[iv] < 0)
|
|
{
|
|
myPArray->keys[iv] = -myPArray->keys[iv];
|
|
glBegin (GL_LINE_LOOP);
|
|
for (i = 0; i < 3; ++i)
|
|
{
|
|
iv = myPArray->edges[j+i];
|
|
glVertex3fv (pv[iv].xyz);
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (j = 0; j < myPArray->num_vertexs; j += 3)
|
|
{
|
|
if (myPArray->keys[j] < 0)
|
|
{
|
|
myPArray->keys[j] = -myPArray->keys[j];
|
|
glBegin (GL_LINE_LOOP);
|
|
for (i = 0; i < 3; ++i)
|
|
{
|
|
glVertex3fv (pv[j+i].xyz);
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesTrianglesAsLines
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsLines (const float theSkipRatio) const
|
|
{
|
|
Tint i, j, k, n, ni;
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
ni = myPArray->bounds[i] - 2;
|
|
k = int((1.0f - theSkipRatio) * ni);
|
|
for (; k > 0; --k)
|
|
{
|
|
j = OGL_Rand() % ni; j += 2;
|
|
myPArray->keys[n+j] = -myPArray->keys[n+j];
|
|
}
|
|
for (j = 2; j < myPArray->bounds[i]; ++j)
|
|
{
|
|
if (myPArray->keys[n+j] < 0)
|
|
{
|
|
myPArray->keys[n+j] = -myPArray->keys[n+j];
|
|
glBegin (GL_LINE_LOOP);
|
|
glVertex3fv (pv[n+j-2].xyz);
|
|
glVertex3fv (pv[n+j-1].xyz);
|
|
glVertex3fv (pv[n+j].xyz);
|
|
glEnd();
|
|
}
|
|
}
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ni = myPArray->num_vertexs - 2;
|
|
k = int((1.0f - theSkipRatio) * ni);
|
|
for (; k > 0; --k)
|
|
{
|
|
j = OGL_Rand() % ni; j += 2;
|
|
myPArray->keys[j] = -myPArray->keys[j];
|
|
}
|
|
for (j = 2; j < myPArray->num_vertexs; ++j)
|
|
{
|
|
if (myPArray->keys[j] < 0)
|
|
{
|
|
myPArray->keys[j] = -myPArray->keys[j];
|
|
glBegin (GL_LINE_LOOP);
|
|
glVertex3fv (pv[j-2].xyz);
|
|
glVertex3fv (pv[j-1].xyz);
|
|
glVertex3fv (pv[j].xyz);
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesPolygonsAsLines
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsLines (const float theSkipRatio) const
|
|
{
|
|
Tint i, iv;
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
Tint n = myPArray->num_vertexs;
|
|
Tint j = int((1.0f - theSkipRatio) * n);
|
|
for (; j > 0; --j)
|
|
{
|
|
i = OGL_Rand() % n;
|
|
myPArray->keys[i] = -myPArray->keys[i];
|
|
}
|
|
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
if (myPArray->num_edges > 0)
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
glBegin (GL_LINE_LOOP);
|
|
for (j = 0; j < myPArray->bounds[i]; ++j)
|
|
{
|
|
iv = myPArray->edges[n+j];
|
|
if (myPArray->keys[iv] < 0)
|
|
{
|
|
myPArray->keys[iv] = -myPArray->keys[iv];
|
|
glVertex3fv (pv[iv].xyz);
|
|
}
|
|
}
|
|
glEnd();
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
glBegin (GL_LINE_LOOP);
|
|
for (j = 0; j < myPArray->bounds[i]; ++j)
|
|
{
|
|
if (myPArray->keys[n+j] < 0)
|
|
{
|
|
myPArray->keys[n+j] = -myPArray->keys[n+j];
|
|
glVertex3fv (pv[n+j].xyz);
|
|
}
|
|
}
|
|
glEnd();
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
}
|
|
else if (myPArray->num_edges > 0)
|
|
{
|
|
glBegin (GL_LINE_LOOP);
|
|
for (j = 0; j < myPArray->num_edges; ++j)
|
|
{
|
|
iv = myPArray->edges[j];
|
|
if (myPArray->keys[iv] < 0)
|
|
{
|
|
myPArray->keys[iv] = -myPArray->keys[iv];
|
|
glVertex3fv (pv[iv].xyz);
|
|
}
|
|
}
|
|
glEnd();
|
|
}
|
|
else
|
|
{
|
|
glBegin (GL_LINE_LOOP);
|
|
for (j = 0; j < myPArray->num_vertexs; ++j)
|
|
{
|
|
if (myPArray->keys[j] < 0)
|
|
{
|
|
myPArray->keys[j] = -myPArray->keys[j];
|
|
glVertex3fv (pv[j].xyz);
|
|
}
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesQuadranglesAsLines
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsLines (const float theSkipRatio) const
|
|
{
|
|
Tint i, iv;
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
Tint n = myPArray->num_vertexs / 4;
|
|
Tint j = int((1.0f - theSkipRatio) * n);
|
|
for (; j > 0; --j)
|
|
{
|
|
i = OGL_Rand() % n; i *= 4;
|
|
myPArray->keys[i] = -myPArray->keys[i];
|
|
}
|
|
|
|
if (myPArray->num_edges > 0)
|
|
{
|
|
for (j = 0; j < myPArray->num_edges; j += 4)
|
|
{
|
|
iv = myPArray->edges[j];
|
|
if (myPArray->keys[iv] < 0)
|
|
{
|
|
myPArray->keys[iv] = -myPArray->keys[iv];
|
|
glBegin (GL_LINE_LOOP);
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
iv = myPArray->edges[j+i];
|
|
glVertex3fv (pv[iv].xyz);
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (j = 0; j < myPArray->num_vertexs; j += 4)
|
|
{
|
|
if (myPArray->keys[j] < 0)
|
|
{
|
|
myPArray->keys[j] = -myPArray->keys[j];
|
|
glBegin (GL_LINE_LOOP);
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
glVertex3fv (pv[j+i].xyz);
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesQuadranglesAsLines
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsLines (const float theSkipRatio) const
|
|
{
|
|
Tint i, j, k, n, ni;
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
ni = myPArray->bounds[i] / 2 - 2;
|
|
k = int((1.0f - theSkipRatio) * ni);
|
|
for (; k > 0; --k)
|
|
{
|
|
j = OGL_Rand() % ni; j = j * 2 + 2;
|
|
myPArray->keys[n+j] = -myPArray->keys[n+j];
|
|
}
|
|
for (j = 3; j < myPArray->bounds[i]; j += 2)
|
|
{
|
|
if (myPArray->keys[n+j] < 0)
|
|
{
|
|
myPArray->keys[n+j] = -myPArray->keys[n+j];
|
|
glBegin (GL_LINE_LOOP);
|
|
glVertex3fv (pv[n+j-3].xyz);
|
|
glVertex3fv (pv[n+j-2].xyz);
|
|
glVertex3fv (pv[n+j-1].xyz);
|
|
glVertex3fv (pv[n+j].xyz);
|
|
glEnd();
|
|
}
|
|
}
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ni = myPArray->num_vertexs / 2 - 2;
|
|
k = int((1.0f - theSkipRatio) * ni);
|
|
for (; k > 0; --k)
|
|
{
|
|
j = OGL_Rand() % ni; j = j * 2 + 2;
|
|
myPArray->keys[j] = -myPArray->keys[j];
|
|
}
|
|
for (j = 3; j < myPArray->num_vertexs; j += 2)
|
|
{
|
|
if (myPArray->keys[j] < 0)
|
|
{
|
|
myPArray->keys[j] = -myPArray->keys[j];
|
|
glBegin (GL_LINE_LOOP);
|
|
glVertex3fv (pv[j-3].xyz);
|
|
glVertex3fv (pv[j-2].xyz);
|
|
glVertex3fv (pv[j-1].xyz);
|
|
glVertex3fv (pv[j].xyz);
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesAsLines
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesAsLines (const TEL_COLOUR* theEdgeColour,
|
|
const Handle(OpenGl_Workspace)& theWorkspace) const
|
|
{
|
|
const float aSkipRatio = theWorkspace->SkipRatio;
|
|
|
|
GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
|
|
|
|
glDisable (GL_LIGHTING);
|
|
|
|
if (zbuff_state)
|
|
glDisable (GL_DEPTH_TEST);
|
|
|
|
glColor3fv (theEdgeColour->rgb);
|
|
|
|
if (aSkipRatio != 0.0f)
|
|
{
|
|
switch (myDrawMode)
|
|
{
|
|
case GL_POINTS:
|
|
if (aSkipRatio < 1.0f)
|
|
DrawDegeneratesPointsAsPoints();
|
|
break;
|
|
case GL_LINES:
|
|
DrawDegeneratesLinesAsLines (aSkipRatio);
|
|
break;
|
|
case GL_LINE_STRIP:
|
|
case GL_POLYGON:
|
|
DrawDegeneratesPolygonsAsLines (aSkipRatio);
|
|
break;
|
|
case GL_TRIANGLES:
|
|
DrawDegeneratesTrianglesAsLines (aSkipRatio);
|
|
break;
|
|
case GL_QUADS:
|
|
DrawDegeneratesQuadranglesAsLines (aSkipRatio);
|
|
break;
|
|
case GL_TRIANGLE_FAN:
|
|
case GL_TRIANGLE_STRIP:
|
|
DrawDegeneratesTrianglestripsAsLines (aSkipRatio);
|
|
break;
|
|
case GL_QUAD_STRIP:
|
|
DrawDegeneratesQuadranglestripsAsLines (aSkipRatio);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int i,n;
|
|
Standard_Boolean isFeedback = theWorkspace->GetGlContext()->IsFeedback();
|
|
glPushAttrib (GL_POLYGON_BIT);
|
|
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
|
|
|
|
GLboolean color_array_mode = glIsEnabled (GL_COLOR_ARRAY);
|
|
GLboolean edge_flag_array_mode = glIsEnabled (GL_EDGE_FLAG_ARRAY);
|
|
GLboolean index_array_mode = glIsEnabled (GL_INDEX_ARRAY);
|
|
GLboolean normal_array_mode = glIsEnabled (GL_NORMAL_ARRAY);
|
|
GLboolean texture_coord_array_mode = glIsEnabled (GL_TEXTURE_COORD_ARRAY);
|
|
GLboolean vertex_array_mode = glIsEnabled (GL_VERTEX_ARRAY);
|
|
|
|
glDisableClientState (GL_COLOR_ARRAY);
|
|
glDisableClientState (GL_EDGE_FLAG_ARRAY);
|
|
glDisableClientState (GL_INDEX_ARRAY);
|
|
glDisableClientState (GL_NORMAL_ARRAY);
|
|
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
|
|
|
|
if (!vertex_array_mode)
|
|
glEnableClientState (GL_VERTEX_ARRAY);
|
|
|
|
glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
|
|
|
|
if (myPArray->num_bounds > 0)
|
|
{
|
|
if (myPArray->num_edges > 0)
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
DrawElements (theWorkspace, myPArray, isFeedback, myDrawMode,
|
|
myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = n = 0; i < myPArray->num_bounds; ++i)
|
|
{
|
|
DrawArrays (theWorkspace, myPArray, isFeedback, myDrawMode,
|
|
n, myPArray->bounds[i]);
|
|
n += myPArray->bounds[i];
|
|
}
|
|
}
|
|
}
|
|
else if (myPArray->num_edges > 0)
|
|
{
|
|
DrawElements (theWorkspace, myPArray, isFeedback, myDrawMode,
|
|
myPArray->num_edges, (GLenum* )myPArray->edges);
|
|
}
|
|
else
|
|
{
|
|
DrawArrays (theWorkspace, myPArray, isFeedback, myDrawMode,
|
|
0, myPArray->num_vertexs);
|
|
}
|
|
|
|
if (!vertex_array_mode) glDisableClientState (GL_VERTEX_ARRAY);
|
|
|
|
if (color_array_mode) glEnableClientState (GL_COLOR_ARRAY);
|
|
if (edge_flag_array_mode) glEnableClientState (GL_EDGE_FLAG_ARRAY);
|
|
if (index_array_mode) glEnableClientState (GL_INDEX_ARRAY);
|
|
if (normal_array_mode) glEnableClientState (GL_NORMAL_ARRAY);
|
|
if (texture_coord_array_mode) glEnableClientState (GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glPopAttrib();
|
|
}
|
|
|
|
if (zbuff_state)
|
|
glEnable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DrawDegeneratesAsBBoxs
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::DrawDegeneratesAsBBoxs (const TEL_COLOUR* theEdgeColour) const
|
|
{
|
|
GLfloat minp[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
|
|
GLfloat maxp[3] = { FLT_MIN, FLT_MIN, FLT_MIN };
|
|
tel_point pv = myPArray->vertices;
|
|
|
|
glDisable (GL_LIGHTING);
|
|
|
|
glColor3fv (theEdgeColour->rgb);
|
|
|
|
for (Tint i = 0; i < myPArray->num_vertexs; ++i)
|
|
{
|
|
if (pv[i].xyz[0] < minp[0])
|
|
minp[0] = pv[i].xyz[0];
|
|
if (pv[i].xyz[1] < minp[1])
|
|
minp[1] = pv[i].xyz[1];
|
|
if (pv[i].xyz[2] < minp[2])
|
|
minp[2] = pv[i].xyz[2];
|
|
|
|
if (pv[i].xyz[0] > maxp[0])
|
|
maxp[0] = pv[i].xyz[0];
|
|
if (pv[i].xyz[1] > maxp[1])
|
|
maxp[1] = pv[i].xyz[1];
|
|
if (pv[i].xyz[2] > maxp[2])
|
|
maxp[2] = pv[i].xyz[2];
|
|
}
|
|
|
|
glBegin (GL_LINE_STRIP);
|
|
|
|
glVertex3fv (minp);
|
|
glVertex3f (minp[0], maxp[1], minp[2]);
|
|
glVertex3f (minp[0], maxp[1], maxp[2]);
|
|
glVertex3f (minp[0], minp[1], maxp[2]);
|
|
glVertex3f (minp[0], minp[1], minp[2]);
|
|
|
|
glVertex3f (maxp[0], minp[1], minp[2]);
|
|
glVertex3f (maxp[0], maxp[1], minp[2]);
|
|
glVertex3f (maxp[0], maxp[1], maxp[2]);
|
|
glVertex3f (maxp[0], minp[1], maxp[2]);
|
|
glVertex3f (maxp[0], minp[1], minp[2]);
|
|
|
|
glVertex3f (maxp[0], minp[1], maxp[2]);
|
|
glVertex3f (minp[0], minp[1], maxp[2]);
|
|
glVertex3f (minp[0], maxp[1], maxp[2]);
|
|
glVertex3fv (maxp);
|
|
glVertex3f (maxp[0], maxp[1], minp[2]);
|
|
glVertex3f (minp[0], maxp[1], minp[2]);
|
|
|
|
glEnd();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : OpenGl_PrimitiveArray
|
|
// purpose :
|
|
// =======================================================================
|
|
OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
|
|
: myPArray (thePArray),
|
|
myDrawMode (GL_NONE)
|
|
{
|
|
switch (myPArray->type)
|
|
{
|
|
case TelPointsArrayType:
|
|
myDrawMode = GL_POINTS;
|
|
break;
|
|
case TelPolylinesArrayType:
|
|
myDrawMode = GL_LINE_STRIP;
|
|
break;
|
|
case TelSegmentsArrayType:
|
|
myDrawMode = GL_LINES;
|
|
break;
|
|
case TelPolygonsArrayType:
|
|
myDrawMode = GL_POLYGON;
|
|
break;
|
|
case TelTrianglesArrayType:
|
|
myDrawMode = GL_TRIANGLES;
|
|
break;
|
|
case TelQuadranglesArrayType:
|
|
myDrawMode = GL_QUADS;
|
|
break;
|
|
case TelTriangleStripsArrayType:
|
|
myDrawMode = GL_TRIANGLE_STRIP;
|
|
break;
|
|
case TelQuadrangleStripsArrayType:
|
|
myDrawMode = GL_QUAD_STRIP;
|
|
break;
|
|
case TelTriangleFansArrayType:
|
|
myDrawMode = GL_TRIANGLE_FAN;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : ~OpenGl_PrimitiveArray
|
|
// purpose :
|
|
// =======================================================================
|
|
OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray ()
|
|
{
|
|
if (myPArray == NULL)
|
|
return;
|
|
|
|
if (myPArray->VBOEnabled == VBO_OK)
|
|
{
|
|
OpenGl_ResourceCleaner* aResCleaner = OpenGl_ResourceCleaner::GetInstance();
|
|
if (myPArray->bufferVBO[VBOEdges] != 0)
|
|
aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
|
|
new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOEdges]));
|
|
if (myPArray->bufferVBO[VBOVertices] != 0)
|
|
aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
|
|
new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVertices]));
|
|
if (myPArray->bufferVBO[VBOVcolours] != 0)
|
|
aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
|
|
new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVcolours]));
|
|
if (myPArray->bufferVBO[VBOVnormals] != 0)
|
|
aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
|
|
new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVnormals]));
|
|
if (myPArray->bufferVBO[VBOVtexels] != 0)
|
|
aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
|
|
new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVtexels]));
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Render
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
|
|
{
|
|
if (myPArray == NULL || myDrawMode == GL_NONE)
|
|
return;
|
|
|
|
// create VBOs on first render call
|
|
if (myPArray->VBOEnabled == -1) // special value for uninitialized state
|
|
{
|
|
myPArray->VBOEnabled = OpenGl_GraphicDriver::ToUseVBO() && (theWorkspace->GetGlContext()->arbVBO != NULL);
|
|
if (myPArray->VBOEnabled != 0)
|
|
BuildVBO (theWorkspace);
|
|
}
|
|
|
|
switch (myPArray->type)
|
|
{
|
|
case TelPointsArrayType:
|
|
case TelPolylinesArrayType:
|
|
case TelSegmentsArrayType:
|
|
{
|
|
glDisable (GL_LIGHTING);
|
|
|
|
if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
|
|
(theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 &&
|
|
theWorkspace->DegenerateModel)
|
|
{
|
|
glDisable (GL_DEPTH_TEST);
|
|
if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
|
|
DisableTexture();
|
|
theWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME;
|
|
}
|
|
break;
|
|
}
|
|
case TelPolygonsArrayType:
|
|
case TelTrianglesArrayType:
|
|
case TelQuadranglesArrayType:
|
|
case TelTriangleStripsArrayType:
|
|
case TelTriangleFansArrayType:
|
|
case TelQuadrangleStripsArrayType:
|
|
{
|
|
if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
|
|
(theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 &&
|
|
theWorkspace->DegenerateModel < 2)
|
|
{
|
|
if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
|
|
EnableTexture();
|
|
glEnable (GL_DEPTH_TEST);
|
|
theWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_True);
|
|
const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
|
|
|
|
Tint aFrontLightingModel = anAspectFace->Context().IntFront.color_mask;
|
|
const TEL_COLOUR* anInteriorColor = &anAspectFace->Context().IntFront.matcol;
|
|
const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color();
|
|
const TEL_COLOUR* aLineColor = &anAspectLine->Color();
|
|
|
|
// Use highlight colors
|
|
if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
|
|
{
|
|
anEdgeColor = anInteriorColor = aLineColor = theWorkspace->HighlightColor;
|
|
aFrontLightingModel = 0;
|
|
}
|
|
|
|
DrawArray (aFrontLightingModel,
|
|
anAspectFace->Context().InteriorStyle,
|
|
anAspectFace->Context().Edge,
|
|
anInteriorColor,
|
|
aLineColor,
|
|
anEdgeColor,
|
|
&anAspectFace->Context().IntFront,
|
|
theWorkspace);
|
|
|
|
switch (myPArray->type)
|
|
{
|
|
case TelPointsArrayType:
|
|
case TelPolylinesArrayType:
|
|
case TelSegmentsArrayType:
|
|
{
|
|
if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
|
|
EnableTexture();
|
|
}
|
|
}
|
|
}
|