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