1 // File: OpenGl_Display.cxx
2 // Created: 20 September 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
6 #include <OpenGl_GlCore11.hxx>
8 #include <OpenGl_Display.hxx>
10 #include <OSD_Environment.hxx>
11 #include <TCollection_AsciiString.hxx>
12 #include <Aspect_GraphicDeviceDefinitionError.hxx>
14 #include <OpenGl_Light.hxx>
16 #if (!defined(_WIN32) && !defined(__WIN32__))
17 #include <X11/Xlib.h> // XOpenDisplay()
20 IMPLEMENT_STANDARD_HANDLE(OpenGl_Display,MMgt_TShared)
21 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Display,MMgt_TShared)
23 Handle(OpenGl_Display) openglDisplay;
27 #if (defined(_WIN32) || defined(__WIN32__))
28 static char* TheDummyDisplay = "DISPLAY";
31 static const OpenGl_Facilities myDefaultFacilities = { 1, 1, 1, 1, OpenGLMaxLights, 10000 };
34 /*----------------------------------------------------------------------*/
36 OpenGl_Display::OpenGl_Display (const Standard_CString theDisplay)
38 myFacilities(myDefaultFacilities),
39 myDBuffer(Standard_True),
40 myDither(Standard_True),
41 myBackDither(Standard_False),
42 myWalkthrough(Standard_False),
43 mySymPerspective(Standard_False),
46 myAntiAliasingMode(3),
53 #if (defined(_WIN32) || defined(__WIN32__))
54 myDisplay = TheDummyDisplay;
56 if (theDisplay != NULL && *theDisplay != '\0')
58 OSD_Environment aDispEnv ("DISPLAY", theDisplay);
62 // Specifies the hardware display name, which determines the
63 // display and communications domain to be used.
64 // On a POSIX system, if the display_name is NULL, it defaults
65 // to the value of the DISPLAY environment variable.
66 myDisplay = XOpenDisplay (NULL);
72 /*----------------------------------------------------------------------*/
74 OpenGl_Display::OpenGl_Display (const Aspect_Display theDisplay)
76 myFacilities(myDefaultFacilities),
77 myDBuffer(Standard_True),
78 myDither(Standard_True),
79 myBackDither(Standard_False),
80 myWalkthrough(Standard_False),
81 mySymPerspective(Standard_False),
84 myAntiAliasingMode(3),
91 #if (defined(_WIN32) || defined(__WIN32__))
92 myDisplay = TheDummyDisplay;
94 myDisplay = theDisplay;
100 /*----------------------------------------------------------------------*/
102 OpenGl_Display::~OpenGl_Display ()
104 // Delete line styles
107 glDeleteLists((GLuint)myLinestyleBase,5);
110 // Delete surface patterns
113 glDeleteLists((GLuint)myPatternBase,TEL_HS_USER_DEF_START);
119 glDeleteLists((GLuint)myMarkerBase,60);
122 // Delete user markers
123 OpenGl_MapOfUserMarker::Iterator itm(myMapOfUM);
124 for (; itm.More(); itm.Next())
126 const OPENGL_MARKER_DATA &aData = itm.Value();
129 delete[] aData.Array;
131 else if (aData.ListId != 0)
133 glDeleteLists ( aData.ListId, 1 );
139 /*----------------------------------------------------------------------*/
141 Handle(OpenGl_Window) OpenGl_Display::GetWindow (const Aspect_Drawable AParent) const
143 Handle(OpenGl_Window) aWindow;
144 if ( myMapOfWindows.IsBound( AParent ) )
146 aWindow = myMapOfWindows.Find( AParent );
151 /*----------------------------------------------------------------------*/
153 void OpenGl_Display::SetWindow (const Aspect_Drawable AParent, const Handle(OpenGl_Window) &AWindow)
155 if ( !myMapOfWindows.IsBound( AParent ) )
157 myMapOfWindows.Bind( AParent, AWindow );
161 /*----------------------------------------------------------------------*/
163 //GenerateMarkerBitmap
164 void OpenGl_Display::AddUserMarker (const Standard_Integer AIndex,
165 const Standard_Integer AMarkWidth,
166 const Standard_Integer AMarkHeight,
167 const Handle(TColStd_HArray1OfByte)& ATexture)
169 if (!myMapOfUM.IsBound(AIndex))
171 const OPENGL_MARKER_DATA anEmptyData = { 0, 0, 0, NULL };
172 myMapOfUM.Bind(AIndex,anEmptyData);
175 OPENGL_MARKER_DATA &aData = myMapOfUM.ChangeFind(AIndex);
179 delete[] aData.Array;
183 unsigned char *anArray = new unsigned char[ATexture->Length()];
185 const int aByteWidth = AMarkWidth / 8;
186 int i, anIndex = ATexture->Upper() - ATexture->Lower() - aByteWidth + 1;
187 for ( ; anIndex >= 0; anIndex -= aByteWidth )
188 for ( i = 0; i < aByteWidth; i++ )
189 anArray[ATexture->Upper() - ATexture->Lower() - aByteWidth + 1 - anIndex + i ] = ATexture->Value( anIndex + i + 1 );
191 aData.Width = AMarkWidth;
192 aData.Height = AMarkHeight;
193 aData.Array = anArray;
196 /*----------------------------------------------------------------------*/
198 void OpenGl_Display::UpdateUserMarkers ()
200 OpenGl_MapOfUserMarker::Iterator itm(myMapOfUM);
201 for (; itm.More(); itm.Next())
203 OPENGL_MARKER_DATA &aData = itm.ChangeValue();
206 if (aData.ListId == 0)
207 aData.ListId = glGenLists(1);
209 glNewList( (GLuint)aData.ListId, GL_COMPILE );
211 GLint w = ( GLsizei ) aData.Width;
212 GLint h = ( GLsizei ) aData.Height;
214 0.5F * ( float )aData.Width, 0.5F * ( float )aData.Height,
215 ( float )30.0, ( float )30.0,
216 ( GLubyte* )aData.Array );
220 delete[] aData.Array;
226 /*----------------------------------------------------------------------*/
228 Standard_Integer OpenGl_Display::GetUserMarkerListIndex (const Standard_Integer AIndex) const
230 if (myMapOfUM.IsBound(AIndex))
232 const OPENGL_MARKER_DATA &aData = myMapOfUM.Find(AIndex);
239 /*----------------------------------------------------------------------*/
241 void OpenGl_Display::Init()
243 if (myDisplay != NULL)
245 #if (!defined(_WIN32) && !defined(__WIN32__))
246 XSynchronize ((Display* )myDisplay, (getenv("CALL_SYNCHRO_X") != NULL) ? 1 : 0);
248 if (getenv("CSF_GraphicSync") != NULL)
249 XSynchronize ((Display* )myDisplay, 1);
251 // does the server know about OpenGL & GLX?
253 if (!XQueryExtension ((Display* )myDisplay, "GLX", &aDummy, &aDummy, &aDummy))
256 std::cerr << "This system doesn't appear to support OpenGL\n";
263 TCollection_AsciiString msg("OpenGl_Display::Init");
264 #if (!defined(_WIN32) && !defined(__WIN32__))
265 msg += " : Cannot connect to X server ";
266 msg += XDisplayName ((char*) NULL);
268 Aspect_GraphicDeviceDefinitionError::Raise(msg.ToCString());
271 if (getenv("CALL_OPENGL_NO_DBF") != NULL)
272 myDBuffer = Standard_False;
274 if (getenv("CALL_OPENGL_NO_DITHER") != NULL)
275 myDither = Standard_False;
277 if (getenv("CALL_OPENGL_NO_BACKDITHER") != NULL)
278 myBackDither = Standard_False;
280 if (getenv("CSF_WALKTHROUGH") != NULL)
281 myWalkthrough = Standard_True;
283 /* OCC18942: Test if symmetric perspective projection should be turned on */
284 if (getenv("CSF_SYM_PERSPECTIVE") != NULL)
285 mySymPerspective = Standard_True;
287 const char* pvalue = getenv("CALL_OPENGL_POLYGON_OFFSET");
291 const int n = sscanf(pvalue, "%f %f", &v1, &v2);
292 if (n > 0) myOffsetFactor = v1;
293 if (n > 1) myOffsetUnits = v2;
296 pvalue = getenv("CALL_OPENGL_ANTIALIASING_MODE");
300 if ( sscanf(pvalue,"%d",&v) > 0 ) myAntiAliasingMode = v;