0024001: Stereographic rendering support
[occt.git] / src / OpenGl / OpenGl_Workspace_3.cxx
1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public 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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <stdio.h>
17
18 #include <OpenGl_GlCore11.hxx>
19 #include <OpenGl_Context.hxx>
20 #include <OpenGl_Structure.hxx>
21 #include <OpenGl_Workspace.hxx>
22
23 /*----------------------------------------------------------------------*/
24 /*  Mode Ajout              */
25 /*----------------------------------------------------------------------*/
26
27 //call_togl_begin_ajout_mode
28 Standard_Boolean OpenGl_Workspace::BeginAddMode()
29 {
30   if (!Activate())
31   {
32     return Standard_False;
33   }
34
35   NamedStatus |= OPENGL_NS_ADD;
36
37   MakeFrontAndBackBufCurrent();
38
39   //TsmPushAttri();
40
41   return Standard_True;
42 }
43
44 /*----------------------------------------------------------------------*/
45
46 //call_togl_end_ajout_mode
47 void OpenGl_Workspace::EndAddMode ()
48 {
49   if (NamedStatus & OPENGL_NS_ADD)
50   {
51     OpenGl_Workspace::MakeBackBufCurrent();
52
53     // Clear add mode flag
54     NamedStatus &= ~OPENGL_NS_ADD;
55   }
56
57   // FMN necessaire pour l'affichage sur WNT
58   glFlush();
59
60   //TsmPopAttri();
61 }
62
63 /*----------------------------------------------------------------------*/
64 /*  Mode Transient              */
65 /*----------------------------------------------------------------------*/
66
67 //call_togl_clear_immediat_mode
68 void OpenGl_Workspace::ClearImmediatMode (const Graphic3d_CView& theCView,
69                                           const Standard_Boolean theToFlush)
70 {
71   if (myIsTransientOpen)
72   {
73     EndImmediatMode();
74   }
75
76   if (!Activate())
77   {
78     myTransientList.Clear(); // Clear current list contents
79     return;
80   }
81
82   GLboolean isDoubleBuffer = GL_FALSE;
83   glGetBooleanv (GL_DOUBLEBUFFER, &isDoubleBuffer);
84   if (!myBackBufferRestored || !myTransientDrawToFront || !isDoubleBuffer)
85   {
86     Redraw1 (theCView, *((CALL_DEF_LAYER* )theCView.ptrUnderLayer), *((CALL_DEF_LAYER* )theCView.ptrOverLayer), theToFlush);
87
88     // After a redraw,
89     // Made the back identical to the front buffer.
90     // Always perform full copy (partial update optimization is useless on mordern hardware)!
91     if (myRetainMode && myTransientDrawToFront && isDoubleBuffer)
92     {
93       const Standard_Boolean toCopyFrontToBack = Standard_True;
94       CopyBuffers (toCopyFrontToBack);
95     }
96
97     myBackBufferRestored = Standard_True;
98   }
99   else if (!myTransientList.IsEmpty() && isDoubleBuffer)
100   {
101     // restore pixels from the back buffer
102     const Standard_Boolean toCopyFrontToBack = Standard_False;
103     CopyBuffers (toCopyFrontToBack);
104   }
105
106   myTransientList.Clear(); // clear current list contents
107 }
108
109 /*----------------------------------------------------------------------*/
110
111 //call_togl_redraw_immediat_mode
112 void OpenGl_Workspace::RedrawImmediatMode()
113 {
114   if (!myRetainMode || myTransientList.IsEmpty())
115   {
116     return;
117   }
118
119   GLboolean isDoubleBuffer = GL_FALSE;
120   glGetBooleanv (GL_DOUBLEBUFFER, &isDoubleBuffer);
121   if (isDoubleBuffer && myTransientDrawToFront)
122   {
123     MakeFrontBufCurrent();
124   }
125   else
126   {
127     myBackBufferRestored = Standard_False;
128   }
129   glDisable (GL_LIGHTING);
130
131   Handle(OpenGl_Workspace) aWS (this);
132   for (Standard_Integer anIter = 1; anIter <= myTransientList.Size(); ++anIter)
133   {
134     const OpenGl_Structure* aStructure = myTransientList.Value (anIter);
135     aStructure->Render (aWS);
136   }
137
138   if (isDoubleBuffer && myTransientDrawToFront)
139   {
140     glFlush(); // FMN necessaire pour l'affichage sur WNT
141     MakeBackBufCurrent();
142   }
143 }
144
145 /*----------------------------------------------------------------------*/
146
147 //call_togl_begin_immediat_mode
148 Standard_Boolean OpenGl_Workspace::BeginImmediatMode (const Graphic3d_CView& theCView,
149                                                       const Standard_Boolean theToUseDepthTest,
150                                                       const Standard_Boolean theRetainMode)
151 {
152   if (!Activate())
153   {
154     return Standard_False;
155   }
156
157   OpenGl_Workspace::ClearImmediatMode (theCView, Standard_True);
158
159   NamedStatus |= OPENGL_NS_IMMEDIATE;
160   myRetainMode = theRetainMode;
161
162   if (myTransientDrawToFront)
163   {
164     MakeFrontBufCurrent();
165   }
166
167   //TsmPushAttri();
168
169   if (myRetainMode)
170   {
171     myIsTransientOpen = Standard_True;
172   }
173
174   if (theToUseDepthTest)
175   {
176     glEnable (GL_DEPTH_TEST);
177   }
178   else
179   {
180     glDisable (GL_DEPTH_TEST);
181   }
182
183   return Standard_True;
184 }
185
186 /*----------------------------------------------------------------------*/
187
188 //call_togl_end_immediat_mode
189 void OpenGl_Workspace::EndImmediatMode()
190 {
191   if (NamedStatus & OPENGL_NS_IMMEDIATE)
192   {
193     if (myIsTransientOpen)
194     {
195       myIsTransientOpen = Standard_False;
196     }
197     if (myTransientDrawToFront)
198     {
199       MakeBackBufCurrent();
200     }
201
202     // Clear immediate mode flag
203     NamedStatus &= ~OPENGL_NS_IMMEDIATE;
204   }
205
206   if (myTransientDrawToFront)
207   {
208     // Ajout CAL : pour voir quelque chose avant le prochain begin_immediat_mode
209     glFinish();
210   }
211   else
212   {
213     GetGlContext()->SwapBuffers();
214   }
215
216   //TsmPopAttri();
217 }
218
219 //call_togl_draw_structure
220 void OpenGl_Workspace::DrawStructure (const OpenGl_Structure* theStructure)
221 {
222   if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
223   {
224     Handle(OpenGl_Workspace) aWS (this);
225     theStructure->Render (aWS);
226
227     if (myIsTransientOpen && myRetainMode)
228     {
229       myTransientList.Append (theStructure);
230     }
231   }
232 }