1 // Created on: 2011-10-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
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.
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.
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.
21 #include <OpenGl_GraphicDriver.hxx>
23 #include <OpenGl_FrameBuffer.hxx>
25 #include <OpenGl_Structure.hxx>
26 #include <OpenGl_CView.hxx>
27 #include <OpenGl_Display.hxx>
28 #include <OpenGl_Text.hxx>
30 /*----------------------------------------------------------------------*/
32 void OpenGl_GraphicDriver::ActivateView (const Graphic3d_CView& ACView)
34 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
36 aCView->WS->SetActiveView(aCView->View);
39 void OpenGl_GraphicDriver::AntiAliasing (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
41 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
43 aCView->View->SetAntiAliasing(AFlag);
46 void OpenGl_GraphicDriver::Background (const Graphic3d_CView& ACView)
48 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
51 aCView->WS->SetBackgroundColor(ACView.DefWindow.Background.r,ACView.DefWindow.Background.g,ACView.DefWindow.Background.b);
55 void OpenGl_GraphicDriver::GradientBackground (const Graphic3d_CView& ACView,
56 const Quantity_Color& AColor1,
57 const Quantity_Color& AColor2,
58 const Aspect_GradientFillMethod AType)
60 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
63 aCView->View->SetBackgroundGradient(AColor1,AColor2,AType);
67 void OpenGl_GraphicDriver::Blink (const Graphic3d_CStructure &, const Standard_Boolean)
72 void OpenGl_GraphicDriver::BoundaryBox (const Graphic3d_CStructure& theCStructure,
73 const Standard_Boolean toCreate)
75 OpenGl_Structure* aStructure = (OpenGl_Structure* )theCStructure.ptrStructure;
76 if (aStructure == NULL)
80 aStructure->SetHighlightBox (GetSharedContext(), theCStructure.BoundBox);
82 aStructure->ClearHighlightBox (GetSharedContext());
85 void OpenGl_GraphicDriver::HighlightColor (const Graphic3d_CStructure& theCStructure,
86 const Standard_ShortReal R,
87 const Standard_ShortReal G,
88 const Standard_ShortReal B,
89 const Standard_Boolean toCreate)
91 OpenGl_Structure* aStructure = (OpenGl_Structure* )theCStructure.ptrStructure;
92 if (aStructure == NULL)
96 aStructure->SetHighlightColor (GetSharedContext(), R, G, B);
98 aStructure->ClearHighlightColor (GetSharedContext());
101 void OpenGl_GraphicDriver::NameSetStructure (const Graphic3d_CStructure& ACStructure)
103 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
106 Standard_Integer aStatus = 0;
107 if (ACStructure.highlight) aStatus |= OPENGL_NS_HIGHLIGHT;
108 if (!ACStructure.visible) aStatus |= OPENGL_NS_HIDE;
109 astructure->SetNamedStatus( aStatus );
113 void OpenGl_GraphicDriver::ClipLimit (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
115 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
118 aCView->View->SetClipLimit(ACView);
121 aCView->WS->Resize(ACView.DefWindow);
126 void OpenGl_GraphicDriver::DeactivateView (const Graphic3d_CView& ACView)
128 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
131 const Handle(OpenGl_View) aDummyView;
132 aCView->WS->SetActiveView(aDummyView);
136 void OpenGl_GraphicDriver::DepthCueing (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
138 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
140 aCView->View->SetFog(ACView, AFlag);
143 Standard_Boolean OpenGl_GraphicDriver::ProjectRaster (const Graphic3d_CView& ACView, const Standard_ShortReal AX, const Standard_ShortReal AY, const Standard_ShortReal AZ, Standard_Integer& AU, Standard_Integer& AV)
145 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
147 return Standard_False;
149 Standard_Integer aWidth = aCView->WS->Width();
150 Standard_Integer aHeight = aCView->WS->Height();
151 Standard_ShortReal xr, yr;
152 if (aCView->View->ProjectObjectToRaster(aWidth, aHeight, AX, AY, AZ, xr, yr))
154 AU = (Standard_Integer) xr;
155 AV = aHeight - (Standard_Integer) yr;
156 return Standard_True;
159 return Standard_False;
162 Standard_Boolean OpenGl_GraphicDriver::UnProjectRaster (const Graphic3d_CView& ACView, const Standard_Integer /*Axm*/, const Standard_Integer Aym, const Standard_Integer /*AXM*/, const Standard_Integer AYM, const Standard_Integer AU, const Standard_Integer AV, Standard_ShortReal& Ax, Standard_ShortReal& Ay, Standard_ShortReal& Az)
164 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
166 return Standard_False;
168 const Standard_Integer aWidth = aCView->WS->Width();
169 const Standard_Integer aHeight = aCView->WS->Height();
172 Patched by P.Dolbey: the window pixel height decreased by one
173 in order for yr to remain within valid coordinate range [0; Ym -1]
174 where Ym means window pixel height.
176 return aCView->View->ProjectRasterToObject( aWidth, aHeight, AU, (AYM-1)-Aym-AV, Ax, Ay, Az );
179 Standard_Boolean OpenGl_GraphicDriver::UnProjectRasterWithRay (const Graphic3d_CView& ACView, const Standard_Integer /*Axm*/, const Standard_Integer Aym, const Standard_Integer /*AXM*/, const Standard_Integer AYM, const Standard_Integer AU, const Standard_Integer AV, Standard_ShortReal& Ax, Standard_ShortReal& Ay, Standard_ShortReal& Az, Standard_ShortReal& Dx, Standard_ShortReal& Dy, Standard_ShortReal& Dz)
181 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
183 return Standard_False;
185 const Standard_Integer aWidth = aCView->WS->Width();
186 const Standard_Integer aHeight = aCView->WS->Height();
188 return aCView->View->ProjectRasterToObjectWithRay( aWidth, aHeight, AU, AYM-Aym-AV, Ax, Ay, Az, Dx, Dy, Dz );
191 void OpenGl_GraphicDriver::RatioWindow (const Graphic3d_CView& theCView)
193 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
195 aCView->WS->Resize (theCView.DefWindow);
198 void OpenGl_GraphicDriver::Redraw (const Graphic3d_CView& ACView,
199 const Aspect_CLayer2d& ACUnderLayer,
200 const Aspect_CLayer2d& ACOverLayer,
201 const Standard_Integer /*x*/,
202 const Standard_Integer /*y*/,
203 const Standard_Integer /*width*/,
204 const Standard_Integer /*height*/)
206 if (!myCaps->vboDisable && ACView.IsRaytracing)
208 if (ACView.WasRedrawnGL)
210 myDeviceLostFlag = Standard_True;
213 myCaps->keepArrayData = Standard_True;
216 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
219 /*if( width <= 0 || height <= 0 )
220 aCView->WS->Redraw(ACView, ACUnderLayer, ACOverLayer);
222 aCView->WS->RedrawArea(ACView, ACUnderLayer, ACOverLayer, x, y, width, height);*/
223 // Always do full redraw
224 aCView->WS->Redraw(ACView, ACUnderLayer, ACOverLayer);
228 Graphic3d_PtrFrameBuffer OpenGl_GraphicDriver::FBOCreate (const Graphic3d_CView& ACView, const Standard_Integer theWidth, const Standard_Integer theHeight)
230 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
232 return aCView->WS->FBOCreate(theWidth, theHeight);
233 return (Graphic3d_PtrFrameBuffer)NULL;
236 Graphic3d_PtrFrameBuffer OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth,
237 const Standard_Integer theHeight)
239 // activate OpenGL context
244 const Handle(OpenGl_Context)& aCtx = GetGlContext();
245 OpenGl_FrameBuffer* aFrameBuffer = new OpenGl_FrameBuffer();
246 if (!aFrameBuffer->Init (aCtx, theWidth, theHeight))
248 aFrameBuffer->Release (aCtx.operator->());
252 return (Graphic3d_PtrFrameBuffer )aFrameBuffer;
255 void OpenGl_GraphicDriver::FBORelease (const Graphic3d_CView& ACView, Graphic3d_PtrFrameBuffer& theFBOPtr)
257 if (theFBOPtr == NULL)
259 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
262 aCView->WS->FBORelease(theFBOPtr);
267 void OpenGl_Workspace::FBORelease (Graphic3d_PtrFrameBuffer theFBOPtr)
269 // activate OpenGL context
271 || theFBOPtr == NULL)
276 // release the object
277 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer*)theFBOPtr;
278 if (aFrameBuffer != NULL)
280 aFrameBuffer->Release (GetGlContext().operator->());
285 void OpenGl_GraphicDriver::FBOGetDimensions (const Graphic3d_CView& ,
286 const Graphic3d_PtrFrameBuffer theFBOPtr,
287 Standard_Integer& theWidth, Standard_Integer& theHeight,
288 Standard_Integer& theWidthMax, Standard_Integer& theHeightMax)
290 if (theFBOPtr == NULL)
294 const OpenGl_FrameBuffer* aFrameBuffer = (const OpenGl_FrameBuffer* )theFBOPtr;
295 theWidth = aFrameBuffer->GetVPSizeX(); // current viewport size
296 theHeight = aFrameBuffer->GetVPSizeY();
297 theWidthMax = aFrameBuffer->GetSizeX(); // texture size
298 theHeightMax = aFrameBuffer->GetSizeY();
301 void OpenGl_GraphicDriver::FBOChangeViewport (const Graphic3d_CView& ,
302 Graphic3d_PtrFrameBuffer& theFBOPtr,
303 const Standard_Integer theWidth, const Standard_Integer theHeight)
305 if (theFBOPtr == NULL)
309 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theFBOPtr;
310 aFrameBuffer->ChangeViewport (theWidth, theHeight);
313 inline bool getDataFormat (const Image_PixMap& theData,
314 GLenum& thePixelFormat,
317 thePixelFormat = GL_RGB;
318 theDataType = GL_UNSIGNED_BYTE;
319 switch (theData.Format())
321 case Image_PixMap::ImgGray:
322 thePixelFormat = GL_DEPTH_COMPONENT;
323 theDataType = GL_UNSIGNED_BYTE;
325 case Image_PixMap::ImgRGB:
326 thePixelFormat = GL_RGB;
327 theDataType = GL_UNSIGNED_BYTE;
329 case Image_PixMap::ImgBGR:
330 thePixelFormat = GL_BGR;
331 theDataType = GL_UNSIGNED_BYTE;
333 case Image_PixMap::ImgRGBA:
334 case Image_PixMap::ImgRGB32:
335 thePixelFormat = GL_RGBA;
336 theDataType = GL_UNSIGNED_BYTE;
338 case Image_PixMap::ImgBGRA:
339 case Image_PixMap::ImgBGR32:
340 thePixelFormat = GL_BGRA;
341 theDataType = GL_UNSIGNED_BYTE;
343 case Image_PixMap::ImgGrayF:
344 thePixelFormat = GL_DEPTH_COMPONENT;
345 theDataType = GL_FLOAT;
347 case Image_PixMap::ImgRGBF:
348 thePixelFormat = GL_RGB;
349 theDataType = GL_FLOAT;
351 case Image_PixMap::ImgBGRF:
352 thePixelFormat = GL_BGR;
353 theDataType = GL_FLOAT;
355 case Image_PixMap::ImgRGBAF:
356 thePixelFormat = GL_RGBA;
357 theDataType = GL_FLOAT;
359 case Image_PixMap::ImgBGRAF:
360 thePixelFormat = GL_BGRA;
361 theDataType = GL_FLOAT;
368 Standard_Boolean OpenGl_GraphicDriver::BufferDump (const Graphic3d_CView& theCView,
369 Image_PixMap& theImage,
370 const Graphic3d_BufferType& theBufferType)
372 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
373 return (aCView != NULL) && aCView->WS->BufferDump ((OpenGl_FrameBuffer* )theCView.ptrFBO, theImage, theBufferType);
376 Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer* theFBOPtr,
377 Image_PixMap& theImage,
378 const Graphic3d_BufferType& theBufferType)
380 GLenum aFormat, aType;
381 if (theImage.IsEmpty()
382 || !getDataFormat (theImage, aFormat, aType)
383 || ((theBufferType == Graphic3d_BT_Depth) && (aFormat != GL_DEPTH_COMPONENT))
386 return Standard_False;
390 GLint aReadBufferPrev = GL_BACK;
391 if (theFBOPtr != NULL && theFBOPtr->IsValid())
393 theFBOPtr->BindBuffer (GetGlContext());
397 glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
398 GLint aDrawBufferPrev = GL_BACK;
399 glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
400 glReadBuffer (aDrawBufferPrev);
403 GLint anAlignBack = 1;
404 glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack);
405 GLint anExtraBytes = (GLint )theImage.RowExtraBytes();
406 GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
407 glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
409 if (anExtraBytes >= anAligment)
412 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
414 glReadPixels (0, GLint(aRow), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
420 glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
421 theImage.SetTopDown (false); // image bottom-up in OpenGL
424 glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack);
426 if (theFBOPtr != NULL && theFBOPtr->IsValid())
428 theFBOPtr->UnbindBuffer (GetGlContext());
432 glReadBuffer (aReadBufferPrev);
434 return Standard_True;
437 void OpenGl_GraphicDriver::RemoveView (const Graphic3d_CView& theCView)
439 Handle(OpenGl_Context) aCtx = GetSharedContext();
440 Handle(OpenGl_View) aView;
441 Handle(OpenGl_Workspace) aWindow;
442 if (myMapOfWS.Find (theCView.WsId, aWindow))
444 myMapOfWS.UnBind (theCView.WsId);
446 if (!aWindow.IsNull())
448 if (aWindow->GetGlContext()->MakeCurrent())
450 aCtx = aWindow->GetGlContext();
454 // try to hijack another context if any
455 const Handle(OpenGl_Context)& anOtherCtx = GetSharedContext();
456 if (!anOtherCtx.IsNull()
457 && anOtherCtx != aWindow->GetGlContext())
464 if (myMapOfView.Find (theCView.ViewId, aView))
466 aView->ReleaseGlResources (aCtx);
467 myMapOfView.UnBind (theCView.ViewId);
470 if (myMapOfWS.IsEmpty())
472 // The last view removed but some objects still present.
473 // Release GL resources now without object destruction.
474 for (NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
475 aStructIt.More (); aStructIt.Next())
477 OpenGl_Structure* aStruct = aStructIt.ChangeValue();
478 aStruct->ReleaseGlResources (aCtx);
480 myTempText->Release (aCtx);
481 myGlDisplay->ReleaseAttributes (aCtx.operator->());
482 myDeviceLostFlag = !myMapOfStructure.IsEmpty();
485 OpenGl_CView* aCView = (OpenGl_CView* )theCView.ptrView;
487 ((Graphic3d_CView *)&theCView)->ptrView = NULL;
494 void OpenGl_GraphicDriver::SetLight (const Graphic3d_CView& ACView)
496 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
498 aCView->View->SetLights(ACView.Context);
501 void OpenGl_GraphicDriver::SetClipPlanes (const Graphic3d_CView& theCView)
503 const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
506 aCView->View->SetClipPlanes (theCView.Context.ClipPlanes);
510 void OpenGl_GraphicDriver::SetClipPlanes (const Graphic3d_CStructure& theCStructure)
512 OpenGl_Structure* aStructure = (OpenGl_Structure *)theCStructure.ptrStructure;
515 aStructure->SetClipPlanes (theCStructure.ClipPlanes);
519 void OpenGl_GraphicDriver::SetVisualisation (const Graphic3d_CView& ACView)
521 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
524 aCView->View->SetVisualisation(ACView.Context);
525 aCView->WS->UseZBuffer() = ( ACView.Context.Visualization == 0? (ACView.Context.ZBufferActivity == 1) : (ACView.Context.ZBufferActivity != 0) );
529 void OpenGl_GraphicDriver::TransformStructure (const Graphic3d_CStructure& ACStructure)
531 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
533 astructure->SetTransformation(&(ACStructure.Transformation[0][0]));
536 void OpenGl_GraphicDriver::Transparency (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
538 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
540 aCView->WS->UseTransparency(AFlag);
543 void OpenGl_GraphicDriver::Update (const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACUnderLayer, const Aspect_CLayer2d& ACOverLayer)
545 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
547 aCView->WS->Update(ACView,ACUnderLayer,ACOverLayer);
550 Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& theCView)
552 if (myGlDisplay.IsNull()
553 || myMapOfView.IsBound (theCView.ViewId)
554 || myMapOfWS .IsBound (theCView.WsId))
556 return Standard_False;
559 Handle(OpenGl_Context) aShareCtx = GetSharedContext();
560 Handle(OpenGl_Workspace) aWS = new OpenGl_Workspace (myGlDisplay, theCView.DefWindow, theCView.GContext, myCaps, aShareCtx);
561 Handle(OpenGl_View) aView = new OpenGl_View (theCView.Context, &myStateCounter);
562 myMapOfWS .Bind (theCView.WsId, aWS);
563 myMapOfView.Bind (theCView.ViewId, aView);
565 OpenGl_CView* aCView = new OpenGl_CView();
566 aCView->View = aView;
568 theCView.ptrView = aCView;
570 return Standard_True;
573 void OpenGl_GraphicDriver::ViewMapping (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
575 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
578 aCView->View->SetMapping (myGlDisplay, ACView);
581 aCView->WS->Resize(ACView.DefWindow);
586 void OpenGl_GraphicDriver::ViewOrientation (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
588 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
591 aCView->View->SetOrientation(ACView);
594 aCView->WS->Resize(ACView.DefWindow);
599 void OpenGl_GraphicDriver::SetBackFacingModel (const Graphic3d_CView& ACView)
601 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
603 aCView->View->SetBackfacing(ACView.Backfacing);
606 //=======================================================================
607 //function : AddZLayer
609 //=======================================================================
611 void OpenGl_GraphicDriver::AddZLayer (const Graphic3d_CView& theCView,
612 const Standard_Integer theLayerId)
614 const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
616 aCView->View->AddZLayer (theLayerId);
619 //=======================================================================
620 //function : RemoveZLayer
622 //=======================================================================
624 void OpenGl_GraphicDriver::RemoveZLayer (const Graphic3d_CView& theCView,
625 const Standard_Integer theLayerId)
627 const OpenGl_CView* aCView = (const OpenGl_CView *)theCView.ptrView;
629 aCView->View->RemoveZLayer (theLayerId);