0024192: Adding support for shaders to OCCT visualization toolkit
[occt.git] / src / OpenGl / OpenGl_Group.cxx
1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 #include <OpenGl_Group.hxx>
21
22 #include <OpenGl_PrimitiveArray.hxx>
23 #include <OpenGl_Workspace.hxx>
24
25 // =======================================================================
26 // function : OpenGl_Group
27 // purpose  :
28 // =======================================================================
29 OpenGl_Group::OpenGl_Group ()
30 : myAspectLine (NULL),
31   myAspectFace (NULL),
32   myAspectMarker (NULL),
33   myAspectText (NULL),
34   myFirst (NULL),
35   myLast (NULL)
36 {
37 }
38
39 // =======================================================================
40 // function : ~OpenGl_Group
41 // purpose  :
42 // =======================================================================
43 OpenGl_Group::~OpenGl_Group()
44 {
45   Release (Handle(OpenGl_Context)());
46 }
47
48 // =======================================================================
49 // function : SetAspectLine
50 // purpose  :
51 // =======================================================================
52 void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theAspect,
53                                   const Standard_Boolean theIsGlobal)
54 {
55   if (theIsGlobal || myFirst == NULL)
56   {
57     if (myAspectLine == NULL)
58     {
59       myAspectLine = new OpenGl_AspectLine();
60     }
61     myAspectLine->SetAspect (theAspect);
62   }
63   else
64   {
65     OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
66     anAspectLine->SetAspect (theAspect);
67     AddElement (TelNil/*TelAspectLine*/, anAspectLine);
68   }
69 }
70
71 // =======================================================================
72 // function : SetAspectFace
73 // purpose  :
74 // =======================================================================
75 void OpenGl_Group::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect,
76                                   const Standard_Boolean          theIsGlobal)
77 {
78   if (theIsGlobal || myFirst == NULL)
79   {
80     if (myAspectFace == NULL)
81     {
82       myAspectFace = new OpenGl_AspectFace();
83     }
84     myAspectFace->SetAspect (theAspect);
85   }
86   else
87   {
88     OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
89     anAspectFace->SetAspect (theAspect);
90     AddElement (TelNil/*TelAspectFace*/, anAspectFace);
91   }
92 }
93
94 // =======================================================================
95 // function : SetAspectMarker
96 // purpose  :
97 // =======================================================================
98 void OpenGl_Group::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect,
99                                     const Standard_Boolean theIsGlobal)
100 {
101   if (theIsGlobal || myFirst == NULL)
102   {
103     if (myAspectMarker == NULL)
104     {
105       myAspectMarker = new OpenGl_AspectMarker();
106     }
107     myAspectMarker->SetAspect (theAspect);
108   }
109   else
110   {
111     OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
112     anAspectMarker->SetAspect (theAspect);
113     AddElement (TelNil/*TelAspectMarker*/, anAspectMarker);
114   }
115 }
116
117 // =======================================================================
118 // function : SetAspectText
119 // purpose  :
120 // =======================================================================
121 void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theAspect,
122                                   const Standard_Boolean theIsGlobal)
123 {
124   if (theIsGlobal || myFirst == NULL)
125   {
126     if (myAspectText == NULL)
127     {
128       myAspectText = new OpenGl_AspectText();
129     }
130     myAspectText->SetAspect (theAspect);
131   }
132   else
133   {
134     OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
135     anAspectText->SetAspect (theAspect);
136     AddElement ( TelNil/*TelAspectText*/, anAspectText);
137   }
138 }
139
140 // =======================================================================
141 // function : AddElement
142 // purpose  :
143 // =======================================================================
144 void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem )
145 {
146   OpenGl_ElementNode *node = new OpenGl_ElementNode();
147
148   node->type = AType;
149   node->elem = AElem;
150   node->next = NULL;
151   (myLast? myLast->next : myFirst) = node;
152   myLast = node;
153 }
154
155 // =======================================================================
156 // function : Render
157 // purpose  :
158 // =======================================================================
159 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
160 {
161   // Is rendering in ADD or IMMEDIATE mode?
162   const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
163   const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
164
165   // Setup aspects
166   const OpenGl_AspectLine*   aBackAspectLine   = theWorkspace->AspectLine   (Standard_False);
167   const OpenGl_AspectFace*   aBackAspectFace   = theWorkspace->AspectFace   (Standard_False);
168   const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
169   const OpenGl_AspectText*   aBackAspectText   = theWorkspace->AspectText   (Standard_False);
170   Standard_Boolean isLineSet   = myAspectLine   && myAspectLine->RenderFiltered (theWorkspace, aFilter);
171   Standard_Boolean isFaceSet   = myAspectFace   && myAspectFace->RenderFiltered (theWorkspace, aFilter);
172   Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
173   Standard_Boolean isTextSet   = myAspectText   && myAspectText->RenderFiltered (theWorkspace, aFilter);
174
175   // Render group elements
176   for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
177   {
178     switch (aNodeIter->type)
179     {
180       case TelMarker:
181       case TelMarkerSet:
182       case TelText:
183       {
184         glDisable (GL_LIGHTING);
185         if (isImmediate)
186         {
187           glDepthMask (GL_FALSE);
188         }
189
190         aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
191         break;
192       }
193       default:
194       {
195         aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
196         break;
197       }
198     }
199   }
200
201   // Restore aspects
202   if (isLineSet)
203     theWorkspace->SetAspectLine (aBackAspectLine);
204   if (isFaceSet)
205     theWorkspace->SetAspectFace (aBackAspectFace);
206   if (isMarkerSet)
207     theWorkspace->SetAspectMarker (aBackAspectMarker);
208   if (isTextSet)
209     theWorkspace->SetAspectText (aBackAspectText);
210 }
211
212 // =======================================================================
213 // function : Release
214 // purpose  :
215 // =======================================================================
216 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
217 {
218   // Delete elements
219   while (myFirst != NULL)
220   {
221     OpenGl_ElementNode* aNext = myFirst->next;
222     OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
223     delete myFirst;
224     myFirst = aNext;
225   }
226   myLast = NULL;
227
228   OpenGl_Element::Destroy (theGlCtx, myAspectLine);
229   OpenGl_Element::Destroy (theGlCtx, myAspectFace);
230   OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
231   OpenGl_Element::Destroy (theGlCtx, myAspectText);
232 }