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