0023243: Adapt OpenGL viewer for using in Cocoa applications on Mac OS X
[occt.git] / src / OpenGl / OpenGl_Display.cxx
CommitLineData
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
35IMPLEMENT_STANDARD_HANDLE(OpenGl_Display,MMgt_TShared)
36IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Display,MMgt_TShared)
37
38Handle(OpenGl_Display) openglDisplay;
39
40namespace
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
51OpenGl_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{
4fe56619 68#if (defined(_WIN32) || defined(__WIN32__)) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
2166f0fa
SK
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
89OpenGl_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
117OpenGl_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
156Handle(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
168void 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
179void 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
213void 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
243Standard_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
256void OpenGl_Display::Init()
257{
258 if (myDisplay != NULL)
259 {
4fe56619 260 #if (!defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)))
2166f0fa
SK
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");
4fe56619 279 #if (!defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)))
2166f0fa
SK
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}