1 // Created on: 2011-10-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_GraphicDriver.hxx>
18 #include <OpenGl_FrameBuffer.hxx>
20 #include <OpenGl_Structure.hxx>
21 #include <OpenGl_CView.hxx>
22 #include <OpenGl_Text.hxx>
24 /*----------------------------------------------------------------------*/
26 void OpenGl_GraphicDriver::ActivateView (const Graphic3d_CView& ACView)
28 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
30 aCView->WS->SetActiveView(aCView->View);
33 void OpenGl_GraphicDriver::AntiAliasing (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
35 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
37 aCView->View->SetAntiAliasing(AFlag);
40 void OpenGl_GraphicDriver::Background (const Graphic3d_CView& ACView)
42 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
45 aCView->WS->SetBackgroundColor(ACView.DefWindow.Background.r,ACView.DefWindow.Background.g,ACView.DefWindow.Background.b);
49 void OpenGl_GraphicDriver::GradientBackground (const Graphic3d_CView& ACView,
50 const Quantity_Color& AColor1,
51 const Quantity_Color& AColor2,
52 const Aspect_GradientFillMethod AType)
54 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
57 aCView->View->SetBackgroundGradient(AColor1,AColor2,AType);
61 void OpenGl_GraphicDriver::ClipLimit (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
63 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
66 aCView->View->SetClipLimit(ACView);
69 aCView->WS->Resize(ACView.DefWindow);
74 void OpenGl_GraphicDriver::DeactivateView (const Graphic3d_CView& ACView)
76 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
79 const Handle(OpenGl_View) aDummyView;
80 aCView->WS->SetActiveView(aDummyView);
84 void OpenGl_GraphicDriver::DepthCueing (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
86 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
88 aCView->View->SetFog(ACView, AFlag);
91 void OpenGl_GraphicDriver::RatioWindow (const Graphic3d_CView& theCView)
93 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
95 aCView->WS->Resize (theCView.DefWindow);
98 void OpenGl_GraphicDriver::Redraw (const Graphic3d_CView& ACView,
99 const Aspect_CLayer2d& ACUnderLayer,
100 const Aspect_CLayer2d& ACOverLayer,
101 const Standard_Integer /*x*/,
102 const Standard_Integer /*y*/,
103 const Standard_Integer /*width*/,
104 const Standard_Integer /*height*/)
106 if (!myCaps->vboDisable && ACView.IsRaytracing)
108 if (ACView.WasRedrawnGL)
110 myDeviceLostFlag = Standard_True;
113 myCaps->keepArrayData = Standard_True;
116 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
119 /*if( width <= 0 || height <= 0 )
120 aCView->WS->Redraw(ACView, ACUnderLayer, ACOverLayer);
122 aCView->WS->RedrawArea(ACView, ACUnderLayer, ACOverLayer, x, y, width, height);*/
123 // Always do full redraw
124 aCView->WS->Redraw(ACView, ACUnderLayer, ACOverLayer);
128 void OpenGl_GraphicDriver::RedrawImmediate (const Graphic3d_CView& theCView,
129 const Aspect_CLayer2d& theCUnderLayer,
130 const Aspect_CLayer2d& theCOverLayer)
132 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
135 aCView->WS->RedrawImmediate (theCView, theCUnderLayer, theCOverLayer);
139 void OpenGl_GraphicDriver::Invalidate (const Graphic3d_CView& theCView)
141 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
144 aCView->WS->Invalidate (theCView);
148 Graphic3d_PtrFrameBuffer OpenGl_GraphicDriver::FBOCreate (const Graphic3d_CView& ACView, const Standard_Integer theWidth, const Standard_Integer theHeight)
150 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
152 return aCView->WS->FBOCreate(theWidth, theHeight);
153 return (Graphic3d_PtrFrameBuffer)NULL;
156 Graphic3d_PtrFrameBuffer OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth,
157 const Standard_Integer theHeight)
159 // activate OpenGL context
164 const Handle(OpenGl_Context)& aCtx = GetGlContext();
165 OpenGl_FrameBuffer* aFrameBuffer = new OpenGl_FrameBuffer();
166 if (!aFrameBuffer->Init (aCtx, theWidth, theHeight))
168 aFrameBuffer->Release (aCtx.operator->());
172 return (Graphic3d_PtrFrameBuffer )aFrameBuffer;
175 void OpenGl_GraphicDriver::FBORelease (const Graphic3d_CView& ACView, Graphic3d_PtrFrameBuffer& theFBOPtr)
177 if (theFBOPtr == NULL)
179 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
182 aCView->WS->FBORelease(theFBOPtr);
187 void OpenGl_Workspace::FBORelease (Graphic3d_PtrFrameBuffer theFBOPtr)
189 // activate OpenGL context
191 || theFBOPtr == NULL)
196 // release the object
197 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer*)theFBOPtr;
198 if (aFrameBuffer != NULL)
200 aFrameBuffer->Release (GetGlContext().operator->());
205 void OpenGl_GraphicDriver::FBOGetDimensions (const Graphic3d_CView& ,
206 const Graphic3d_PtrFrameBuffer theFBOPtr,
207 Standard_Integer& theWidth, Standard_Integer& theHeight,
208 Standard_Integer& theWidthMax, Standard_Integer& theHeightMax)
210 if (theFBOPtr == NULL)
214 const OpenGl_FrameBuffer* aFrameBuffer = (const OpenGl_FrameBuffer* )theFBOPtr;
215 theWidth = aFrameBuffer->GetVPSizeX(); // current viewport size
216 theHeight = aFrameBuffer->GetVPSizeY();
217 theWidthMax = aFrameBuffer->GetSizeX(); // texture size
218 theHeightMax = aFrameBuffer->GetSizeY();
221 void OpenGl_GraphicDriver::FBOChangeViewport (const Graphic3d_CView& ,
222 Graphic3d_PtrFrameBuffer& theFBOPtr,
223 const Standard_Integer theWidth, const Standard_Integer theHeight)
225 if (theFBOPtr == NULL)
229 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theFBOPtr;
230 aFrameBuffer->ChangeViewport (theWidth, theHeight);
233 inline bool getDataFormat (const Image_PixMap& theData,
234 GLenum& thePixelFormat,
237 thePixelFormat = GL_RGB;
238 theDataType = GL_UNSIGNED_BYTE;
239 switch (theData.Format())
241 case Image_PixMap::ImgGray:
242 thePixelFormat = GL_DEPTH_COMPONENT;
243 theDataType = GL_UNSIGNED_BYTE;
245 case Image_PixMap::ImgRGB:
246 thePixelFormat = GL_RGB;
247 theDataType = GL_UNSIGNED_BYTE;
249 case Image_PixMap::ImgBGR:
250 thePixelFormat = GL_BGR;
251 theDataType = GL_UNSIGNED_BYTE;
253 case Image_PixMap::ImgRGBA:
254 case Image_PixMap::ImgRGB32:
255 thePixelFormat = GL_RGBA;
256 theDataType = GL_UNSIGNED_BYTE;
258 case Image_PixMap::ImgBGRA:
259 case Image_PixMap::ImgBGR32:
260 thePixelFormat = GL_BGRA;
261 theDataType = GL_UNSIGNED_BYTE;
263 case Image_PixMap::ImgGrayF:
264 thePixelFormat = GL_DEPTH_COMPONENT;
265 theDataType = GL_FLOAT;
267 case Image_PixMap::ImgRGBF:
268 thePixelFormat = GL_RGB;
269 theDataType = GL_FLOAT;
271 case Image_PixMap::ImgBGRF:
272 thePixelFormat = GL_BGR;
273 theDataType = GL_FLOAT;
275 case Image_PixMap::ImgRGBAF:
276 thePixelFormat = GL_RGBA;
277 theDataType = GL_FLOAT;
279 case Image_PixMap::ImgBGRAF:
280 thePixelFormat = GL_BGRA;
281 theDataType = GL_FLOAT;
288 Standard_Boolean OpenGl_GraphicDriver::BufferDump (const Graphic3d_CView& theCView,
289 Image_PixMap& theImage,
290 const Graphic3d_BufferType& theBufferType)
292 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
293 return (aCView != NULL) && aCView->WS->BufferDump ((OpenGl_FrameBuffer* )theCView.ptrFBO, theImage, theBufferType);
296 Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer* theFBOPtr,
297 Image_PixMap& theImage,
298 const Graphic3d_BufferType& theBufferType)
300 GLenum aFormat, aType;
301 if (theImage.IsEmpty()
302 || !getDataFormat (theImage, aFormat, aType)
303 || ((theBufferType == Graphic3d_BT_Depth) && (aFormat != GL_DEPTH_COMPONENT))
306 return Standard_False;
310 GLint aReadBufferPrev = GL_BACK;
311 if (theFBOPtr != NULL && theFBOPtr->IsValid())
313 theFBOPtr->BindBuffer (GetGlContext());
317 glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
318 GLint aDrawBufferPrev = GL_BACK;
319 glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
320 glReadBuffer (aDrawBufferPrev);
324 const GLint anExtraBytes = (GLint )theImage.RowExtraBytes();
325 const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
326 glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
328 const GLint aPixelsWidth = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
329 glPixelStorei (GL_PACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0);
331 if (theImage.IsTopDown())
334 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
336 // Image_PixMap rows indexation always starts from the upper corner
337 // while order in memory depends on the flag and processed by ChangeRow() method
338 glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
343 glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
346 glPixelStorei (GL_PACK_ALIGNMENT, 1);
347 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
349 if (theFBOPtr != NULL && theFBOPtr->IsValid())
351 theFBOPtr->UnbindBuffer (GetGlContext());
355 glReadBuffer (aReadBufferPrev);
357 return Standard_True;
360 void OpenGl_GraphicDriver::RemoveView (const Graphic3d_CView& theCView)
362 Handle(OpenGl_Context) aCtx = GetSharedContext();
363 Handle(OpenGl_View) aView;
364 Handle(OpenGl_Workspace) aWindow;
365 if (myMapOfWS.Find (theCView.WsId, aWindow))
367 myMapOfWS.UnBind (theCView.WsId);
369 if (!aWindow.IsNull())
371 if (aWindow->GetGlContext()->MakeCurrent())
373 aCtx = aWindow->GetGlContext();
377 // try to hijack another context if any
378 const Handle(OpenGl_Context)& anOtherCtx = GetSharedContext();
379 if (!anOtherCtx.IsNull()
380 && anOtherCtx != aWindow->GetGlContext())
387 if (myMapOfView.Find (theCView.ViewId, aView))
389 aView->ReleaseGlResources (aCtx);
390 myMapOfView.UnBind (theCView.ViewId);
393 if (myMapOfWS.IsEmpty())
395 // The last view removed but some objects still present.
396 // Release GL resources now without object destruction.
397 for (NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
398 aStructIt.More (); aStructIt.Next())
400 OpenGl_Structure* aStruct = aStructIt.ChangeValue();
401 aStruct->ReleaseGlResources (aCtx);
403 myTempText->Release (aCtx);
404 myDeviceLostFlag = !myMapOfStructure.IsEmpty();
407 OpenGl_CView* aCView = (OpenGl_CView* )theCView.ptrView;
409 ((Graphic3d_CView *)&theCView)->ptrView = NULL;
416 void OpenGl_GraphicDriver::SetLight (const Graphic3d_CView& ACView)
418 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
420 aCView->View->SetLights(ACView.Context);
423 void OpenGl_GraphicDriver::SetClipPlanes (const Graphic3d_CView& theCView)
425 const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
428 aCView->View->SetClipPlanes (theCView.Context.ClipPlanes);
432 //=======================================================================
433 //function : SetCamera
435 //=======================================================================
436 void OpenGl_GraphicDriver::SetCamera (const Graphic3d_CView& theCView)
438 const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
441 aCView->View->SetCamera (theCView.Context.Camera);
445 void OpenGl_GraphicDriver::SetVisualisation (const Graphic3d_CView& ACView)
447 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
450 aCView->View->SetVisualisation(ACView.Context);
451 aCView->WS->UseZBuffer() = ( ACView.Context.Visualization == 0? (ACView.Context.ZBufferActivity == 1) : (ACView.Context.ZBufferActivity != 0) );
455 void OpenGl_GraphicDriver::Transparency (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
457 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
459 aCView->WS->UseTransparency(AFlag);
462 Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& theCView)
464 if (myMapOfView.IsBound (theCView.ViewId)
465 || myMapOfWS .IsBound (theCView.WsId))
467 return Standard_False;
470 Handle(OpenGl_Context) aShareCtx = GetSharedContext();
471 Handle(OpenGl_Workspace) aWS = new OpenGl_Workspace (myDisplayConnection, theCView.DefWindow, theCView.GContext, myCaps, aShareCtx);
472 Handle(OpenGl_View) aView = new OpenGl_View (theCView.Context, &myStateCounter);
473 myMapOfWS .Bind (theCView.WsId, aWS);
474 myMapOfView.Bind (theCView.ViewId, aView);
476 OpenGl_CView* aCView = new OpenGl_CView();
477 aCView->View = aView;
479 theCView.ptrView = aCView;
481 return Standard_True;
484 void OpenGl_GraphicDriver::SetBackFacingModel (const Graphic3d_CView& ACView)
486 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
488 aCView->View->SetBackfacing(ACView.Backfacing);
491 //=======================================================================
492 //function : AddZLayer
494 //=======================================================================
496 void OpenGl_GraphicDriver::AddZLayer (const Graphic3d_CView& theCView,
497 const Standard_Integer theLayerId)
499 const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
501 aCView->View->AddZLayer (theLayerId);
504 //=======================================================================
505 //function : RemoveZLayer
507 //=======================================================================
508 void OpenGl_GraphicDriver::RemoveZLayer (const Graphic3d_CView& theCView,
509 const Standard_Integer theLayerId)
511 const OpenGl_CView* aCView = (const OpenGl_CView *)theCView.ptrView;
513 aCView->View->RemoveZLayer (theLayerId);
516 //=======================================================================
517 //function : SetZLayerSettings
519 //=======================================================================
520 Standard_EXPORT void OpenGl_GraphicDriver::SetZLayerSettings (const Graphic3d_CView& theCView,
521 const Standard_Integer theLayerId,
522 const Graphic3d_ZLayerSettings& theSettings)
524 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
526 aCView->View->SetZLayerSettings (theLayerId, theSettings);