1 // File: OpenGl_Display.cxx
2 // Created: 20 September 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
6 #include <OpenGl_Display.hxx>
8 #include <OSD_Environment.hxx>
9 #include <TCollection_AsciiString.hxx>
10 #include <Aspect_GraphicDeviceDefinitionError.hxx>
12 #include <OpenGl_tgl_all.hxx>
15 #include <OpenGl_Light.hxx>
17 IMPLEMENT_STANDARD_HANDLE(OpenGl_Display,MMgt_TShared)
18 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Display,MMgt_TShared)
20 Handle(OpenGl_Display) openglDisplay;
24 #if (defined(_WIN32) || defined(__WIN32__))
25 static char* TheDummyDisplay = "DISPLAY";
28 static const OpenGl_Facilities myDefaultFacilities = { 1, 1, 1, 1, OpenGLMaxLights, 10000 };
31 /*----------------------------------------------------------------------*/
33 OpenGl_Display::OpenGl_Display (const Standard_CString theDisplay)
35 myFacilities(myDefaultFacilities),
36 myDBuffer(Standard_True),
37 myDither(Standard_True),
38 myBackDither(Standard_False),
39 myWalkthrough(Standard_False),
40 mySymPerspective(Standard_False),
43 myAntiAliasingMode(3),
50 #if (defined(_WIN32) || defined(__WIN32__))
51 myDisplay = TheDummyDisplay;
53 if (theDisplay != NULL && *theDisplay != '\0')
55 OSD_Environment aDispEnv ("DISPLAY", theDisplay);
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);
69 /*----------------------------------------------------------------------*/
71 OpenGl_Display::OpenGl_Display (const Aspect_Display theDisplay)
73 myFacilities(myDefaultFacilities),
74 myDBuffer(Standard_True),
75 myDither(Standard_True),
76 myBackDither(Standard_False),
77 myWalkthrough(Standard_False),
78 mySymPerspective(Standard_False),
81 myAntiAliasingMode(3),
88 #if (defined(_WIN32) || defined(__WIN32__))
89 myDisplay = TheDummyDisplay;
91 myDisplay = theDisplay;
97 /*----------------------------------------------------------------------*/
99 OpenGl_Display::~OpenGl_Display ()
101 // Delete line styles
104 glDeleteLists((GLuint)myLinestyleBase,5);
107 // Delete surface patterns
110 glDeleteLists((GLuint)myPatternBase,TEL_HS_USER_DEF_START);
116 glDeleteLists((GLuint)myMarkerBase,60);
119 // Delete user markers
120 OpenGl_MapOfUserMarker::Iterator itm(myMapOfUM);
121 for (; itm.More(); itm.Next())
123 const OPENGL_MARKER_DATA &aData = itm.Value();
126 delete[] aData.Array;
128 else if (aData.ListId != 0)
130 glDeleteLists ( aData.ListId, 1 );
136 /*----------------------------------------------------------------------*/
138 Handle(OpenGl_Window) OpenGl_Display::GetWindow (const Aspect_Drawable AParent) const
140 Handle(OpenGl_Window) aWindow;
141 if ( myMapOfWindows.IsBound( AParent ) )
143 aWindow = myMapOfWindows.Find( AParent );
148 /*----------------------------------------------------------------------*/
150 void OpenGl_Display::SetWindow (const Aspect_Drawable AParent, const Handle(OpenGl_Window) &AWindow)
152 if ( !myMapOfWindows.IsBound( AParent ) )
154 myMapOfWindows.Bind( AParent, AWindow );
158 /*----------------------------------------------------------------------*/
160 //GenerateMarkerBitmap
161 void OpenGl_Display::AddUserMarker (const Standard_Integer AIndex,
162 const Standard_Integer AMarkWidth,
163 const Standard_Integer AMarkHeight,
164 const Handle(TColStd_HArray1OfByte)& ATexture)
166 if (!myMapOfUM.IsBound(AIndex))
168 const OPENGL_MARKER_DATA anEmptyData = { 0, 0, 0, NULL };
169 myMapOfUM.Bind(AIndex,anEmptyData);
172 OPENGL_MARKER_DATA &aData = myMapOfUM.ChangeFind(AIndex);
176 delete[] aData.Array;
180 unsigned char *anArray = new unsigned char[ATexture->Length()];
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 );
188 aData.Width = AMarkWidth;
189 aData.Height = AMarkHeight;
190 aData.Array = anArray;
193 /*----------------------------------------------------------------------*/
195 void OpenGl_Display::UpdateUserMarkers ()
197 OpenGl_MapOfUserMarker::Iterator itm(myMapOfUM);
198 for (; itm.More(); itm.Next())
200 OPENGL_MARKER_DATA &aData = itm.ChangeValue();
203 if (aData.ListId == 0)
204 aData.ListId = glGenLists(1);
206 glNewList( (GLuint)aData.ListId, GL_COMPILE );
208 GLint w = ( GLsizei ) aData.Width;
209 GLint h = ( GLsizei ) aData.Height;
211 0.5F * ( float )aData.Width, 0.5F * ( float )aData.Height,
212 ( float )30.0, ( float )30.0,
213 ( GLubyte* )aData.Array );
217 delete[] aData.Array;
223 /*----------------------------------------------------------------------*/
225 Standard_Integer OpenGl_Display::GetUserMarkerListIndex (const Standard_Integer AIndex) const
227 if (myMapOfUM.IsBound(AIndex))
229 const OPENGL_MARKER_DATA &aData = myMapOfUM.Find(AIndex);
236 /*----------------------------------------------------------------------*/
238 void OpenGl_Display::Init()
240 if (myDisplay != NULL)
242 #if (!defined(_WIN32) && !defined(__WIN32__))
243 XSynchronize ((Display* )myDisplay, (getenv("CALL_SYNCHRO_X") != NULL) ? 1 : 0);
245 if (getenv("CSF_GraphicSync") != NULL)
246 XSynchronize ((Display* )myDisplay, 1);
248 // does the server know about OpenGL & GLX?
250 if (!XQueryExtension ((Display* )myDisplay, "GLX", &aDummy, &aDummy, &aDummy))
253 std::cerr << "This system doesn't appear to support OpenGL\n";
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);
265 Aspect_GraphicDeviceDefinitionError::Raise(msg.ToCString());
268 if (getenv("CALL_OPENGL_NO_DBF") != NULL)
269 myDBuffer = Standard_False;
271 if (getenv("CALL_OPENGL_NO_DITHER") != NULL)
272 myDither = Standard_False;
274 if (getenv("CALL_OPENGL_NO_BACKDITHER") != NULL)
275 myBackDither = Standard_False;
277 if (getenv("CSF_WALKTHROUGH") != NULL)
278 myWalkthrough = Standard_True;
280 /* OCC18942: Test if symmetric perspective projection should be turned on */
281 if (getenv("CSF_SYM_PERSPECTIVE") != NULL)
282 mySymPerspective = Standard_True;
284 const char* pvalue = getenv("CALL_OPENGL_POLYGON_OFFSET");
288 const int n = sscanf(pvalue, "%f %f", &v1, &v2);
289 if (n > 0) myOffsetFactor = v1;
290 if (n > 1) myOffsetUnits = v2;
293 pvalue = getenv("CALL_OPENGL_ANTIALIASING_MODE");
297 if ( sscanf(pvalue,"%d",&v) > 0 ) myAntiAliasingMode = v;