1 // Created on: 2007-07-19
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2007-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <NIS_TriangulatedDrawer.hxx>
17 #include <NIS_InteractiveObject.hxx>
18 #include <NIS_Triangulated.hxx>
20 #include <Standard_ProgramError.hxx>
23 #include <OpenGl_GlCore11.hxx>
25 // Comment this line if you see no hilighting of triangulations due to negative
26 // polygon offsets. Disabling this macro means that all offsets will be created
27 // in the positive scale.
29 // But before changing this macro please play with your OpenGL video card
30 // settings in the direction of performance improvement. Particularly, I had a
31 // good result after checking "Enable write combining" option in NVIDIA 6600.
33 #define NEGATIVE_POFFSET
35 IMPLEMENT_STANDARD_HANDLE (NIS_TriangulatedDrawer, NIS_Drawer)
36 IMPLEMENT_STANDARD_RTTIEXT (NIS_TriangulatedDrawer, NIS_Drawer)
38 //=======================================================================
39 //function : NIS_TriangulatedDrawer()
40 //purpose : Constructor
41 //=======================================================================
43 NIS_TriangulatedDrawer::NIS_TriangulatedDrawer
44 (const Quantity_Color theNormal,
45 const Quantity_Color theHilight,
46 const Quantity_Color theDynHilight)
47 : myPolygonAsLineLoop (Standard_False),
49 myIsDrawPolygons (Standard_False),
50 myPolygonType (NIS_Triangulated::Polygon_Default)
52 myColor[Draw_Normal] = theNormal;
53 myColor[Draw_Top] = theNormal;
54 myColor[Draw_Transparent] = theNormal;
55 myColor[Draw_Hilighted] = theHilight;
56 myColor[Draw_DynHilighted] = theDynHilight;
59 //=======================================================================
62 //=======================================================================
64 void NIS_TriangulatedDrawer::Assign (const Handle(NIS_Drawer)& theOther)
66 if (theOther.IsNull() == Standard_False) {
67 NIS_Drawer::Assign (theOther);
68 const Handle(NIS_TriangulatedDrawer)& anOther =
69 static_cast <const Handle(NIS_TriangulatedDrawer)&> (theOther);
70 myColor[Draw_Normal] = anOther->myColor[Draw_Normal];
71 myColor[Draw_Top] = anOther->myColor[Draw_Top];
72 myColor[Draw_Transparent] = anOther->myColor[Draw_Transparent];
73 myColor[Draw_Hilighted] = anOther->myColor[Draw_Hilighted];
74 myColor[Draw_DynHilighted] = anOther->myColor[Draw_DynHilighted];
75 myLineWidth = anOther->myLineWidth;
76 myIsDrawPolygons = anOther->myIsDrawPolygons;
77 myPolygonType = anOther->myPolygonType;
81 static const Standard_Integer nObjPerDrawer = 64;
83 //=======================================================================
85 //purpose : Comparison of two Drawers (for Map impementation)
86 //=======================================================================
88 Standard_Boolean NIS_TriangulatedDrawer::IsEqual
89 (const Handle(NIS_Drawer)& theOther)const
91 static const Standard_Real anEpsilon2 (1e-7);
92 Standard_Boolean aResult (Standard_False);
93 const Handle(NIS_TriangulatedDrawer) anOther =
94 Handle(NIS_TriangulatedDrawer)::DownCast (theOther);
95 if (NIS_Drawer::IsEqual(theOther))
96 aResult = (anOther->myColor[Draw_Normal]
97 .SquareDistance (myColor[Draw_Normal]) < anEpsilon2 &&
98 anOther->myColor[Draw_Hilighted]
99 .SquareDistance (myColor[Draw_Hilighted]) < anEpsilon2 &&
100 anOther->myColor[Draw_DynHilighted]
101 .SquareDistance (myColor[Draw_DynHilighted]) < anEpsilon2 &&
102 (anOther->myLineWidth - myLineWidth) *
103 (anOther->myLineWidth - myLineWidth) < 0.01 &&
104 anOther->myIsDrawPolygons == myIsDrawPolygons &&
105 anOther->myPolygonType == myPolygonType);
109 //=======================================================================
110 //function : BeforeDraw
112 //=======================================================================
114 void NIS_TriangulatedDrawer::BeforeDraw (const DrawType theType,
117 Quantity_Parameter aValue[4];
118 Quantity_TypeOfColor bidTC (Quantity_TOC_RGB);
119 GLfloat aLineWidth (myLineWidth);
120 Standard_Integer anOffsetHilighted = 0;
122 case Draw_DynHilighted:
123 aLineWidth = myLineWidth + 1.f;
124 #ifdef NEGATIVE_POFFSET
125 anOffsetHilighted = -11;
128 switch (myPolygonType) {
130 case NIS_Triangulated::Polygon_Default:
131 if (myIsDrawPolygons) {
132 case NIS_Triangulated::Polygon_Line:
133 glEnable(GL_POLYGON_OFFSET_LINE);
135 case NIS_Triangulated::Polygon_Fill:
136 glEnable(GL_POLYGON_OFFSET_FILL);
139 if (theType == Draw_Hilighted)
141 #ifdef NEGATIVE_POFFSET
142 anOffsetHilighted = -10;
144 anOffsetHilighted = 1;
147 myColor[theType].Values (aValue[0], aValue[1], aValue[2], bidTC);
148 glColor3d (aValue[0], aValue[1], aValue[2]);
152 case Draw_Transparent:
153 #ifndef NEGATIVE_POFFSET
154 anOffsetHilighted = 11;
156 myColor[theType].Values (aValue[0], aValue[1], aValue[2], bidTC);
157 aValue[3] = 1. - myTransparency;
158 if (myTransparency > 0.01) {
160 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
162 glColor4d (aValue[0], aValue[1], aValue[2], aValue[3]);
167 if (anOffsetHilighted)
168 glPolygonOffset(1.f, static_cast<GLfloat>(anOffsetHilighted));
170 // myColor[theType].Values (aValue[0], aValue[1], aValue[2], bidTC);
171 // glColor3d (aValue[0], aValue[1], aValue[2]);
172 switch (myPolygonType) {
174 case NIS_Triangulated::Polygon_Default:
175 if (myIsDrawPolygons) {
176 case NIS_Triangulated::Polygon_Line:
177 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
179 case NIS_Triangulated::Polygon_Fill:
180 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
183 glEnableClientState (GL_VERTEX_ARRAY);
184 glLineWidth (aLineWidth);
185 glShadeModel(GL_FLAT);
186 glDisable(GL_LIGHTING);
189 //=======================================================================
190 //function : AfterDraw
192 //=======================================================================
194 void NIS_TriangulatedDrawer::AfterDraw (const DrawType theType,
199 case Draw_DynHilighted:
200 switch (myPolygonType) {
202 case NIS_Triangulated::Polygon_Default:
203 if (myIsDrawPolygons) {
204 case NIS_Triangulated::Polygon_Line:
205 glDisable(GL_POLYGON_OFFSET_LINE);
207 case NIS_Triangulated::Polygon_Fill:
208 glDisable(GL_POLYGON_OFFSET_FILL);
213 case Draw_Transparent:
214 glDisableClientState(GL_VERTEX_ARRAY);
215 if (myTransparency > 0.01)
219 if (myPolygonType == NIS_Triangulated::Polygon_Line ||
220 (myPolygonType == NIS_Triangulated::Polygon_Default && myIsDrawPolygons))
221 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
224 //=======================================================================
227 //=======================================================================
229 void NIS_TriangulatedDrawer::Draw (const Handle(NIS_InteractiveObject)& theObj,
230 const DrawType /*theType*/,
233 // Assertion for the type of the drawn object
235 static const Handle(Standard_Type) ThisType = STANDARD_TYPE(NIS_Triangulated);
236 if (theObj->IsKind(ThisType) == Standard_False)
237 Standard_ProgramError::Raise ("NIS_Triangulated::Draw: "
238 "irrelevant object type");
240 const NIS_Triangulated * pObject =
241 static_cast <const NIS_Triangulated *> (theObj.operator->());
242 glVertexPointer (pObject->myNodeCoord, GL_FLOAT, 0, pObject->Node(0));
244 GLenum aType = GL_UNSIGNED_INT;
245 if (pObject->myIndexType == 0)
246 aType = GL_UNSIGNED_BYTE;
247 else if (pObject->myIndexType == 1)
248 aType = GL_UNSIGNED_SHORT;
250 if (myIsDrawPolygons == Standard_False) {
251 if (pObject->IsTriangulation()) {
252 glDrawElements (GL_TRIANGLES, pObject->NTriangles()*3,
253 aType, pObject->mypTriangles);
256 if (pObject->IsPolygons()) {
257 GLenum aMode = GL_POLYGON;
258 if (myPolygonAsLineLoop &&
259 (myPolygonType == NIS_Triangulated::Polygon_Line ||
260 (myPolygonType == NIS_Triangulated::Polygon_Default &&
262 aMode = GL_LINE_LOOP;
263 const Standard_Integer nPoly = pObject->NPolygons();
264 for (Standard_Integer i = 0; i < nPoly; i++) {
265 const Standard_Integer nSize = pObject->NPolygonNodes(i);
267 if (pObject->myIndexType == 0)
268 anArray = reinterpret_cast<unsigned char *>(pObject->mypPolygons[i]) + 1;
269 else if (pObject->myIndexType == 1)
270 anArray = reinterpret_cast<unsigned short *>(pObject->mypPolygons[i]) + 1;
272 anArray = pObject->mypPolygons[i] + 1;
273 glDrawElements (aMode, nSize, aType, anArray);
277 if (pObject->IsSegments())
278 glDrawElements (GL_LINES, pObject->NLineNodes(),
279 aType, pObject->mypLines);
281 Standard_Boolean isLoop;
282 if (pObject->IsLine(isLoop))
285 // glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
286 glDrawElements (GL_LINE_LOOP, pObject->NLineNodes(),
287 aType, pObject->mypLines);
288 // glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
290 glDrawElements (GL_LINE_STRIP, pObject->NLineNodes(),
291 aType, pObject->mypLines);