0022627: Change OCCT memory management defaults
[occt.git] / src / OpenGl / OpenGl_Display.cxx
CommitLineData
2166f0fa
SK
1// File: OpenGl_Display.cxx
2// Created: 20 September 2011
3// Author: Sergey ZERCHANINOV
4// Copyright: OPEN CASCADE 2011
5
5f8b738e 6#include <OpenGl_GlCore11.hxx>
7
2166f0fa
SK
8#include <OpenGl_Display.hxx>
9
10#include <OSD_Environment.hxx>
11#include <TCollection_AsciiString.hxx>
12#include <Aspect_GraphicDeviceDefinitionError.hxx>
13
2166f0fa
SK
14#include <OpenGl_Light.hxx>
15
5f8b738e 16#if (!defined(_WIN32) && !defined(__WIN32__))
17 #include <X11/Xlib.h> // XOpenDisplay()
18#endif
19
2166f0fa
SK
20IMPLEMENT_STANDARD_HANDLE(OpenGl_Display,MMgt_TShared)
21IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Display,MMgt_TShared)
22
23Handle(OpenGl_Display) openglDisplay;
24
25namespace
26{
27 #if (defined(_WIN32) || defined(__WIN32__))
28 static char* TheDummyDisplay = "DISPLAY";
29 #endif
30
31 static const OpenGl_Facilities myDefaultFacilities = { 1, 1, 1, 1, OpenGLMaxLights, 10000 };
32};
33
34/*----------------------------------------------------------------------*/
35
36OpenGl_Display::OpenGl_Display (const Standard_CString theDisplay)
37: myDisplay(NULL),
38 myFacilities(myDefaultFacilities),
39 myDBuffer(Standard_True),
40 myDither(Standard_True),
41 myBackDither(Standard_False),
42 myWalkthrough(Standard_False),
43 mySymPerspective(Standard_False),
44 myOffsetFactor(1.F),
45 myOffsetUnits(0.F),
46 myAntiAliasingMode(3),
47 myLinestyleBase(0),
48 myPatternBase(0),
49 myMarkerBase(0),
50 myFont(-1),
51 myFontSize(-1)
52{
53#if (defined(_WIN32) || defined(__WIN32__))
54 myDisplay = TheDummyDisplay;
55#else
56 if (theDisplay != NULL && *theDisplay != '\0')
57 {
58 OSD_Environment aDispEnv ("DISPLAY", theDisplay);
59 aDispEnv.Build();
60 }
61
62 // Specifies the hardware display name, which determines the
63 // display and communications domain to be used.
64 // On a POSIX system, if the display_name is NULL, it defaults
65 // to the value of the DISPLAY environment variable.
66 myDisplay = XOpenDisplay (NULL);
67#endif
68
69 Init();
70}
71
72/*----------------------------------------------------------------------*/
73
74OpenGl_Display::OpenGl_Display (const Aspect_Display theDisplay)
75: myDisplay(NULL),
76 myFacilities(myDefaultFacilities),
77 myDBuffer(Standard_True),
78 myDither(Standard_True),
79 myBackDither(Standard_False),
80 myWalkthrough(Standard_False),
81 mySymPerspective(Standard_False),
82 myOffsetFactor(1.F),
83 myOffsetUnits(0.F),
84 myAntiAliasingMode(3),
85 myLinestyleBase(0),
86 myPatternBase(0),
87 myMarkerBase(0),
88 myFont(-1),
89 myFontSize(-1)
90{
91#if (defined(_WIN32) || defined(__WIN32__))
92 myDisplay = TheDummyDisplay;
93#else
94 myDisplay = theDisplay;
95#endif
96
97 Init();
98}
99
100/*----------------------------------------------------------------------*/
101
102OpenGl_Display::~OpenGl_Display ()
103{
104 // Delete line styles
105 if (myLinestyleBase)
106 {
107 glDeleteLists((GLuint)myLinestyleBase,5);
108 myLinestyleBase = 0;
109 }
110 // Delete surface patterns
111 if (myPatternBase)
112 {
113 glDeleteLists((GLuint)myPatternBase,TEL_HS_USER_DEF_START);
114 myPatternBase = 0;
115 }
116 // Delete markers
117 if (myMarkerBase)
118 {
119 glDeleteLists((GLuint)myMarkerBase,60);
120 myMarkerBase = 0;
121 }
122 // Delete user markers
123 OpenGl_MapOfUserMarker::Iterator itm(myMapOfUM);
124 for (; itm.More(); itm.Next())
125 {
126 const OPENGL_MARKER_DATA &aData = itm.Value();
127 if (aData.Array)
128 {
129 delete[] aData.Array;
130 }
131 else if (aData.ListId != 0)
132 {
133 glDeleteLists ( aData.ListId, 1 );
134 }
135 }
136 myDisplay = NULL;
137}
138
139/*----------------------------------------------------------------------*/
140
141Handle(OpenGl_Window) OpenGl_Display::GetWindow (const Aspect_Drawable AParent) const
142{
143 Handle(OpenGl_Window) aWindow;
144 if ( myMapOfWindows.IsBound( AParent ) )
145 {
146 aWindow = myMapOfWindows.Find( AParent );
147 }
148 return aWindow;
149}
150
151/*----------------------------------------------------------------------*/
152
153void OpenGl_Display::SetWindow (const Aspect_Drawable AParent, const Handle(OpenGl_Window) &AWindow)
154{
155 if ( !myMapOfWindows.IsBound( AParent ) )
156 {
157 myMapOfWindows.Bind( AParent, AWindow );
158 }
159}
160
161/*----------------------------------------------------------------------*/
162
163//GenerateMarkerBitmap
164void OpenGl_Display::AddUserMarker (const Standard_Integer AIndex,
165 const Standard_Integer AMarkWidth,
166 const Standard_Integer AMarkHeight,
167 const Handle(TColStd_HArray1OfByte)& ATexture)
168{
169 if (!myMapOfUM.IsBound(AIndex))
170 {
171 const OPENGL_MARKER_DATA anEmptyData = { 0, 0, 0, NULL };
172 myMapOfUM.Bind(AIndex,anEmptyData);
173 }
174
175 OPENGL_MARKER_DATA &aData = myMapOfUM.ChangeFind(AIndex);
176
177 if (aData.Array)
178 {
179 delete[] aData.Array;
180 aData.Array = NULL;
181 }
182
183 unsigned char *anArray = new unsigned char[ATexture->Length()];
184
185 const int aByteWidth = AMarkWidth / 8;
186 int i, anIndex = ATexture->Upper() - ATexture->Lower() - aByteWidth + 1;
187 for ( ; anIndex >= 0; anIndex -= aByteWidth )
188 for ( i = 0; i < aByteWidth; i++ )
189 anArray[ATexture->Upper() - ATexture->Lower() - aByteWidth + 1 - anIndex + i ] = ATexture->Value( anIndex + i + 1 );
190
191 aData.Width = AMarkWidth;
192 aData.Height = AMarkHeight;
193 aData.Array = anArray;
194}
195
196/*----------------------------------------------------------------------*/
197
198void OpenGl_Display::UpdateUserMarkers ()
199{
200 OpenGl_MapOfUserMarker::Iterator itm(myMapOfUM);
201 for (; itm.More(); itm.Next())
202 {
203 OPENGL_MARKER_DATA &aData = itm.ChangeValue();
204 if (aData.Array)
205 {
206 if (aData.ListId == 0)
207 aData.ListId = glGenLists(1);
208
209 glNewList( (GLuint)aData.ListId, GL_COMPILE );
210
211 GLint w = ( GLsizei ) aData.Width;
212 GLint h = ( GLsizei ) aData.Height;
213 glBitmap( w, h,
214 0.5F * ( float )aData.Width, 0.5F * ( float )aData.Height,
215 ( float )30.0, ( float )30.0,
216 ( GLubyte* )aData.Array );
217
218 glEndList();
219
220 delete[] aData.Array;
221 aData.Array = NULL;
222 }
223 }
224}
225
226/*----------------------------------------------------------------------*/
227
228Standard_Integer OpenGl_Display::GetUserMarkerListIndex (const Standard_Integer AIndex) const
229{
230 if (myMapOfUM.IsBound(AIndex))
231 {
232 const OPENGL_MARKER_DATA &aData = myMapOfUM.Find(AIndex);
233 if (!aData.Array)
234 return aData.ListId;
235 }
236 return -1;
237}
238
239/*----------------------------------------------------------------------*/
240
241void OpenGl_Display::Init()
242{
243 if (myDisplay != NULL)
244 {
245 #if (!defined(_WIN32) && !defined(__WIN32__))
246 XSynchronize ((Display* )myDisplay, (getenv("CALL_SYNCHRO_X") != NULL) ? 1 : 0);
247
248 if (getenv("CSF_GraphicSync") != NULL)
249 XSynchronize ((Display* )myDisplay, 1);
250
251 // does the server know about OpenGL & GLX?
252 int aDummy;
253 if (!XQueryExtension ((Display* )myDisplay, "GLX", &aDummy, &aDummy, &aDummy))
254 {
255 #ifdef DEBUG
256 std::cerr << "This system doesn't appear to support OpenGL\n";
257 #endif
258 }
259 #endif
260 }
261 else
262 {
263 TCollection_AsciiString msg("OpenGl_Display::Init");
264 #if (!defined(_WIN32) && !defined(__WIN32__))
265 msg += " : Cannot connect to X server ";
266 msg += XDisplayName ((char*) NULL);
267 #endif
268 Aspect_GraphicDeviceDefinitionError::Raise(msg.ToCString());
269 }
270
271 if (getenv("CALL_OPENGL_NO_DBF") != NULL)
272 myDBuffer = Standard_False;
273
274 if (getenv("CALL_OPENGL_NO_DITHER") != NULL)
275 myDither = Standard_False;
276
277 if (getenv("CALL_OPENGL_NO_BACKDITHER") != NULL)
278 myBackDither = Standard_False;
279
280 if (getenv("CSF_WALKTHROUGH") != NULL)
281 myWalkthrough = Standard_True;
282
283 /* OCC18942: Test if symmetric perspective projection should be turned on */
284 if (getenv("CSF_SYM_PERSPECTIVE") != NULL)
285 mySymPerspective = Standard_True;
286
287 const char* pvalue = getenv("CALL_OPENGL_POLYGON_OFFSET");
288 if (pvalue)
289 {
290 float v1, v2;
291 const int n = sscanf(pvalue, "%f %f", &v1, &v2);
292 if (n > 0) myOffsetFactor = v1;
293 if (n > 1) myOffsetUnits = v2;
294 }
295
296 pvalue = getenv("CALL_OPENGL_ANTIALIASING_MODE");
297 if (pvalue)
298 {
299 int v;
300 if ( sscanf(pvalue,"%d",&v) > 0 ) myAntiAliasingMode = v;
301 }
302}