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