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>
29 /*----------------------------------------------------------------------*/
31 void OpenGl_GraphicDriver::ActivateView (const Graphic3d_CView& ACView)
33 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
35 aCView->WS->SetActiveView(aCView->View);
38 void OpenGl_GraphicDriver::AntiAliasing (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
40 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
42 aCView->View->SetAntiAliasing(AFlag);
45 void OpenGl_GraphicDriver::Background (const Graphic3d_CView& ACView)
47 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
50 aCView->WS->SetBackgroundColor(ACView.DefWindow.Background.r,ACView.DefWindow.Background.g,ACView.DefWindow.Background.b);
51 aCView->WS->Invalidate();
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);
64 aCView->WS->Invalidate();
68 void OpenGl_GraphicDriver::Blink (const Graphic3d_CStructure &, const Standard_Boolean)
73 void OpenGl_GraphicDriver::BoundaryBox (const Graphic3d_CStructure& ACStructure, const Standard_Boolean Create)
75 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
80 astructure->SetHighlightBox(ACStructure.BoundBox);
82 astructure->ClearHighlightBox();
85 void OpenGl_GraphicDriver::HighlightColor (const Graphic3d_CStructure& ACStructure, const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B, const Standard_Boolean Create)
87 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
92 astructure->SetHighlightColor(R,G,B);
94 astructure->ClearHighlightColor();
97 void OpenGl_GraphicDriver::NameSetStructure (const Graphic3d_CStructure& ACStructure)
99 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
102 Standard_Integer aStatus = 0;
103 if (ACStructure.highlight) aStatus |= OPENGL_NS_HIGHLIGHT;
104 if (!ACStructure.visible) aStatus |= OPENGL_NS_HIDE;
105 astructure->SetNamedStatus( aStatus );
109 void OpenGl_GraphicDriver::ClipLimit (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
111 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
114 aCView->View->SetClipLimit(ACView);
117 aCView->WS->Resize(ACView.DefWindow);
118 aCView->WS->Invalidate();
123 void OpenGl_GraphicDriver::DeactivateView (const Graphic3d_CView& ACView)
125 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
128 const Handle(OpenGl_View) aDummyView;
129 aCView->WS->SetActiveView(aDummyView);
133 void OpenGl_GraphicDriver::DepthCueing (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
135 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
137 aCView->View->SetFog(ACView, AFlag);
140 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)
142 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
144 return Standard_False;
146 Standard_Integer aWidth = aCView->WS->Width();
147 Standard_Integer aHeight = aCView->WS->Height();
148 Standard_ShortReal xr, yr;
149 if (aCView->View->ProjectObjectToRaster(aWidth, aHeight, AX, AY, AZ, xr, yr))
151 AU = (Standard_Integer) xr;
152 AV = aHeight - (Standard_Integer) yr;
153 return Standard_True;
156 return Standard_False;
159 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)
161 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
163 return Standard_False;
165 const Standard_Integer aWidth = aCView->WS->Width();
166 const Standard_Integer aHeight = aCView->WS->Height();
169 Patched by P.Dolbey: the window pixel height decreased by one
170 in order for yr to remain within valid coordinate range [0; Ym -1]
171 where Ym means window pixel height.
173 return aCView->View->ProjectRasterToObject( aWidth, aHeight, AU, (AYM-1)-Aym-AV, Ax, Ay, Az );
176 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)
178 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
180 return Standard_False;
182 const Standard_Integer aWidth = aCView->WS->Width();
183 const Standard_Integer aHeight = aCView->WS->Height();
185 return aCView->View->ProjectRasterToObjectWithRay( aWidth, aHeight, AU, AYM-Aym-AV, Ax, Ay, Az, Dx, Dy, Dz );
188 void OpenGl_GraphicDriver::RatioWindow (const Graphic3d_CView& theCView)
190 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
192 aCView->WS->Resize (theCView.DefWindow);
195 void OpenGl_GraphicDriver::Redraw (const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACUnderLayer, const Aspect_CLayer2d& ACOverLayer, const Standard_Integer x, const Standard_Integer y, const Standard_Integer width, const Standard_Integer height)
197 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
200 /*if( width <= 0 || height <= 0 )
201 aCView->WS->Redraw(ACView, ACUnderLayer, ACOverLayer);
203 aCView->WS->RedrawArea(ACView, ACUnderLayer, ACOverLayer, x, y, width, height);*/
204 // Always do full redraw
205 aCView->WS->Redraw(ACView, ACUnderLayer, ACOverLayer);
209 Graphic3d_PtrFrameBuffer OpenGl_GraphicDriver::FBOCreate (const Graphic3d_CView& ACView, const Standard_Integer theWidth, const Standard_Integer theHeight)
211 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
213 return aCView->WS->FBOCreate(theWidth, theHeight);
214 return (Graphic3d_PtrFrameBuffer)NULL;
217 Graphic3d_PtrFrameBuffer OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth, const Standard_Integer theHeight)
219 // activate OpenGL context
224 OpenGl_FrameBuffer* aFrameBuffer = new OpenGl_FrameBuffer();
225 if (!aFrameBuffer->Init (GetGlContext(), theWidth, theHeight))
230 return (Graphic3d_PtrFrameBuffer )aFrameBuffer;
233 void OpenGl_GraphicDriver::FBORelease (const Graphic3d_CView& ACView, Graphic3d_PtrFrameBuffer& theFBOPtr)
235 if (theFBOPtr == NULL)
237 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
240 aCView->WS->FBORelease(theFBOPtr);
245 void OpenGl_Workspace::FBORelease (Graphic3d_PtrFrameBuffer theFBOPtr)
247 // activate OpenGL context
251 // release the object
252 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer*)theFBOPtr;
253 aFrameBuffer->Release (GetGlContext());
257 void OpenGl_GraphicDriver::FBOGetDimensions (const Graphic3d_CView& ,
258 const Graphic3d_PtrFrameBuffer theFBOPtr,
259 Standard_Integer& theWidth, Standard_Integer& theHeight,
260 Standard_Integer& theWidthMax, Standard_Integer& theHeightMax)
262 if (theFBOPtr == NULL)
266 const OpenGl_FrameBuffer* aFrameBuffer = (const OpenGl_FrameBuffer* )theFBOPtr;
267 theWidth = aFrameBuffer->GetVPSizeX(); // current viewport size
268 theHeight = aFrameBuffer->GetVPSizeY();
269 theWidthMax = aFrameBuffer->GetSizeX(); // texture size
270 theHeightMax = aFrameBuffer->GetSizeY();
273 void OpenGl_GraphicDriver::FBOChangeViewport (const Graphic3d_CView& ,
274 Graphic3d_PtrFrameBuffer& theFBOPtr,
275 const Standard_Integer theWidth, const Standard_Integer theHeight)
277 if (theFBOPtr == NULL)
281 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theFBOPtr;
282 aFrameBuffer->ChangeViewport (theWidth, theHeight);
287 #define GL_BGR 0x80E0
290 #define GL_BGRA 0x80E1
293 static inline GLenum TFormatToGLEnum (const TRawBufferDataFormat theTFormat)
297 case TRGB: return GL_RGB;
298 case TBGR: return GL_BGR;
299 case TRGBA: return GL_RGBA;
300 case TBGRA: return GL_BGRA;
301 case TDepthComponent: return GL_DEPTH_COMPONENT;
302 case TRed: return GL_RED;
303 case TGreen: return GL_GREEN;
304 case TBlue: return GL_BLUE;
305 case TAlpha: return GL_ALPHA;
310 static inline GLenum TTypeToGLEnum (const TRawBufferDataType theTType)
314 case TUByte: return GL_UNSIGNED_BYTE;
315 case TFloat: return GL_FLOAT;
320 Standard_Boolean OpenGl_GraphicDriver::BufferDump (const Graphic3d_CView& ACView, Image_CRawBufferData& theBuffer)
322 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
324 return aCView->WS->BufferDump((OpenGl_FrameBuffer *)ACView.ptrFBO,theBuffer);
325 return Standard_False;
328 Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer *theFBOPtr, Image_CRawBufferData& theBuffer)
330 GLenum aFormat = TFormatToGLEnum (theBuffer.format);
331 GLenum aType = TTypeToGLEnum (theBuffer.type);
334 if (aFormat == 0 || aType == 0 ||
335 theBuffer.widthPx == 0 || theBuffer.heightPx == 0 ||
336 theBuffer.dataPtr == NULL)
338 return Standard_False;
341 // activate OpenGL context
343 return Standard_False;
346 OpenGl_FrameBuffer* aFrameBuffer = theFBOPtr;
347 GLint aReadBufferPrev = GL_BACK;
348 if (aFrameBuffer != NULL && aFrameBuffer->IsValid())
350 aFrameBuffer->BindBuffer (GetGlContext());
354 glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
355 GLint aDrawBufferPrev = GL_BACK;
356 glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
357 glReadBuffer (aDrawBufferPrev);
360 GLint anAlignBack = 1;
361 glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack);
362 if (theBuffer.rowAligmentBytes == 0)
364 theBuffer.rowAligmentBytes = 1;
366 glPixelStorei (GL_PACK_ALIGNMENT, theBuffer.rowAligmentBytes);
369 glReadPixels (0, 0, theBuffer.widthPx, theBuffer.heightPx, aFormat, aType, (GLvoid* )theBuffer.dataPtr);
370 glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack);
372 if (aFrameBuffer != NULL && aFrameBuffer->IsValid())
374 aFrameBuffer->UnbindBuffer (GetGlContext());
378 glReadBuffer (aReadBufferPrev);
380 return Standard_True;
383 void OpenGl_GraphicDriver::RemoveView (const Graphic3d_CView& ACView)
385 if (GetMapOfViews().IsBound (ACView.ViewId))
386 GetMapOfViews().UnBind (ACView.ViewId);
388 if (GetMapOfWorkspaces().IsBound (ACView.WsId))
389 GetMapOfWorkspaces().UnBind (ACView.WsId);
391 OpenGl_CView *aCView = (OpenGl_CView *)ACView.ptrView;
393 ((Graphic3d_CView *)&ACView)->ptrView = NULL;
396 void OpenGl_GraphicDriver::SetLight (const Graphic3d_CView& ACView)
398 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
400 aCView->View->SetLights(ACView.Context);
403 void OpenGl_GraphicDriver::SetPlane (const Graphic3d_CView& ACView)
405 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
407 aCView->View->SetClippingPlanes(ACView.Context);
410 void OpenGl_GraphicDriver::SetVisualisation (const Graphic3d_CView& ACView)
412 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
415 aCView->View->SetVisualisation(ACView.Context);
416 aCView->WS->UseZBuffer() = ( ACView.Context.Visualization == 0? (ACView.Context.ZBufferActivity == 1) : (ACView.Context.ZBufferActivity != 0) );
420 void OpenGl_GraphicDriver::TransformStructure (const Graphic3d_CStructure& ACStructure)
422 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
424 astructure->SetTransformation(&(ACStructure.Transformation[0][0]));
427 void OpenGl_GraphicDriver::DegenerateStructure (const Graphic3d_CStructure& ACStructure)
429 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
431 astructure->SetDegenerateModel( ACStructure.ContextFillArea.DegenerationMode, ACStructure.ContextFillArea.SkipRatio );
434 void OpenGl_GraphicDriver::Transparency (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
436 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
438 aCView->WS->UseTransparency(AFlag);
441 void OpenGl_GraphicDriver::Update (const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACUnderLayer, const Aspect_CLayer2d& ACOverLayer)
443 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
445 aCView->WS->Update(ACView,ACUnderLayer,ACOverLayer);
448 Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& ACView)
450 if (openglDisplay.IsNull())
451 return Standard_False;
453 if (GetMapOfViews().IsBound (ACView.ViewId))
454 GetMapOfViews().UnBind (ACView.ViewId);
456 if (GetMapOfWorkspaces().IsBound (ACView.WsId))
457 GetMapOfWorkspaces().UnBind (ACView.WsId);
459 Handle(OpenGl_Workspace) aWS = Handle(OpenGl_Workspace)::DownCast(openglDisplay->GetWindow( ACView.DefWindow.XWindow ));
462 aWS = new OpenGl_Workspace( openglDisplay, ACView.DefWindow, ACView.GContext );
463 openglDisplay->SetWindow( ACView.DefWindow.XWindow, aWS );
466 GetMapOfWorkspaces().Bind (ACView.WsId, aWS);
468 Handle(OpenGl_View) aView = new OpenGl_View( ACView.Context );
469 GetMapOfViews().Bind (ACView.ViewId, aView);
471 OpenGl_CView *aCView = new OpenGl_CView;
472 aCView->View = aView;
474 ACView.ptrView = aCView;
476 return Standard_True;
479 void OpenGl_GraphicDriver::ViewMapping (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
481 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
484 aCView->View->SetMapping(ACView);
487 aCView->WS->Resize(ACView.DefWindow);
488 aCView->WS->Invalidate();
493 void OpenGl_GraphicDriver::ViewOrientation (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
495 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
498 aCView->View->SetOrientation(ACView);
501 aCView->WS->Resize(ACView.DefWindow);
502 aCView->WS->Invalidate();
507 void OpenGl_GraphicDriver::SetBackFacingModel (const Graphic3d_CView& ACView)
509 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
511 aCView->View->SetBackfacing(ACView.Backfacing);
514 //=======================================================================
515 //function : AddZLayer
517 //=======================================================================
519 void OpenGl_GraphicDriver::AddZLayer (const Graphic3d_CView& theCView,
520 const Standard_Integer theLayerId)
522 const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
524 aCView->View->AddZLayer (theLayerId);
527 //=======================================================================
528 //function : RemoveZLayer
530 //=======================================================================
532 void OpenGl_GraphicDriver::RemoveZLayer (const Graphic3d_CView& theCView,
533 const Standard_Integer theLayerId)
535 const OpenGl_CView* aCView = (const OpenGl_CView *)theCView.ptrView;
537 aCView->View->RemoveZLayer (theLayerId);