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