0023000: Improve the way the gradient and textured background is managed in 3d viewer
[occt.git] / src / OpenGl / OpenGl_GraphicDriver_7.cxx
CommitLineData
2166f0fa
SK
1// File: OpenGl_GraphicDriver_7.cxx
2// Created: 20 October 2011
3// Author: Sergey ZERCHANINOV
4// Copyright: OPEN CASCADE 2011
7fd59977 5
2166f0fa 6#include <OpenGl_GraphicDriver.hxx>
7fd59977 7
7fd59977 8#include <OpenGl_FrameBuffer.hxx>
9
2166f0fa
SK
10#include <OpenGl_Structure.hxx>
11#include <OpenGl_CView.hxx>
12#include <OpenGl_Display.hxx>
7fd59977 13
2166f0fa 14/*----------------------------------------------------------------------*/
7fd59977 15
2166f0fa
SK
16void OpenGl_GraphicDriver::ActivateView (const Graphic3d_CView& ACView)
17{
18 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
19 if (aCView)
20 aCView->WS->SetActiveView(aCView->View);
7fd59977 21}
22
2166f0fa
SK
23void OpenGl_GraphicDriver::AntiAliasing (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
24{
25 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
26 if (aCView)
27 aCView->View->SetAntiAliasing(AFlag);
7fd59977 28}
29
2166f0fa
SK
30void OpenGl_GraphicDriver::Background (const Graphic3d_CView& ACView)
31{
32 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
33 if (aCView)
34 {
35 aCView->WS->SetBackgroundColor(ACView.DefWindow.Background.r,ACView.DefWindow.Background.g,ACView.DefWindow.Background.b);
36 aCView->WS->Invalidate();
7fd59977 37 }
7fd59977 38}
39
2166f0fa 40void OpenGl_GraphicDriver::GradientBackground (const Graphic3d_CView& ACView,
7fd59977 41 const Quantity_Color& AColor1,
42 const Quantity_Color& AColor2,
2166f0fa
SK
43 const Aspect_GradientFillMethod AType)
44{
45 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
46 if (aCView)
47 {
48 aCView->View->SetBackgroundGradient(AColor1,AColor2,AType);
49 aCView->WS->Invalidate();
7fd59977 50 }
7fd59977 51}
52
2166f0fa
SK
53void OpenGl_GraphicDriver::Blink (const Graphic3d_CStructure &, const Standard_Boolean)
54{
55 // Do nothing
7fd59977 56}
57
2166f0fa
SK
58void OpenGl_GraphicDriver::BoundaryBox (const Graphic3d_CStructure& ACStructure, const Standard_Boolean Create)
59{
60 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
61 if (!astructure)
62 return;
7fd59977 63
2166f0fa
SK
64 if ( Create )
65 astructure->SetHighlightBox(ACStructure.BoundBox);
66 else
67 astructure->ClearHighlightBox();
7fd59977 68}
69
2166f0fa
SK
70void OpenGl_GraphicDriver::HighlightColor (const Graphic3d_CStructure& ACStructure, const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B, const Standard_Boolean Create)
71{
72 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
73 if (!astructure)
74 return;
7fd59977 75
2166f0fa
SK
76 if ( Create )
77 astructure->SetHighlightColor(R,G,B);
78 else
79 astructure->ClearHighlightColor();
7fd59977 80}
81
2166f0fa
SK
82void OpenGl_GraphicDriver::NameSetStructure (const Graphic3d_CStructure& ACStructure)
83{
84 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
85 if (astructure)
86 {
87 Standard_Integer aStatus = 0;
88 if (ACStructure.highlight) aStatus |= OPENGL_NS_HIGHLIGHT;
89 if (!ACStructure.visible) aStatus |= OPENGL_NS_HIDE;
90 if (ACStructure.pick) aStatus |= OPENGL_NS_PICK;
91 astructure->SetNamedStatus( aStatus );
7fd59977 92 }
7fd59977 93}
94
2166f0fa
SK
95void OpenGl_GraphicDriver::ClipLimit (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
96{
97 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
98 if (aCView)
99 {
100 aCView->View->SetClipLimit(ACView);
529afc1a 101 if (!AWait)
2166f0fa
SK
102 {
103 aCView->WS->Resize(ACView.DefWindow);
104 aCView->WS->Invalidate();
105 }
7fd59977 106 }
7fd59977 107}
108
2166f0fa
SK
109void OpenGl_GraphicDriver::DeactivateView (const Graphic3d_CView& ACView)
110{
111 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
112 if (aCView)
113 {
114 const Handle(OpenGl_View) aDummyView;
115 aCView->WS->SetActiveView(aDummyView);
7fd59977 116 }
7fd59977 117}
118
2166f0fa
SK
119void OpenGl_GraphicDriver::DepthCueing (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
120{
121 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
122 if (aCView)
123 aCView->View->SetFog(ACView, AFlag);
7fd59977 124}
125
2166f0fa
SK
126Standard_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)
127{
128 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
129 if (!aCView)
130 return Standard_False;
7fd59977 131
2166f0fa
SK
132 Standard_Integer aWidth = aCView->WS->Width();
133 Standard_Integer aHeight = aCView->WS->Height();
2166f0fa
SK
134 Standard_ShortReal xr, yr;
135 if (aCView->View->ProjectObjectToRaster(aWidth, aHeight, AX, AY, AZ, xr, yr))
136 {
137 AU = (Standard_Integer) xr;
138 AV = aHeight - (Standard_Integer) yr;
139 return Standard_True;
7fd59977 140 }
141
2166f0fa 142 return Standard_False;
7fd59977 143}
144
2166f0fa
SK
145Standard_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)
146{
147 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
148 if (!aCView)
149 return Standard_False;
7fd59977 150
2166f0fa
SK
151 const Standard_Integer aWidth = aCView->WS->Width();
152 const Standard_Integer aHeight = aCView->WS->Height();
7fd59977 153
2166f0fa
SK
154 /*
155 Patched by P.Dolbey: the window pixel height decreased by one
156 in order for yr to remain within valid coordinate range [0; Ym -1]
157 where Ym means window pixel height.
158 */
159 return aCView->View->ProjectRasterToObject( aWidth, aHeight, AU, (AYM-1)-Aym-AV, Ax, Ay, Az );
7fd59977 160}
161
2166f0fa
SK
162Standard_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)
163{
164 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
165 if (!aCView)
166 return Standard_False;
7fd59977 167
2166f0fa
SK
168 const Standard_Integer aWidth = aCView->WS->Width();
169 const Standard_Integer aHeight = aCView->WS->Height();
7fd59977 170
2166f0fa 171 return aCView->View->ProjectRasterToObjectWithRay( aWidth, aHeight, AU, AYM-Aym-AV, Ax, Ay, Az, Dx, Dy, Dz );
7fd59977 172}
173
529afc1a 174void OpenGl_GraphicDriver::RatioWindow (const Graphic3d_CView& theCView)
2166f0fa 175{
529afc1a
K
176 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
177 if (aCView != NULL)
178 aCView->WS->Resize (theCView.DefWindow);
2166f0fa 179}
7fd59977 180
2166f0fa
SK
181void 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)
182{
183 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
184 if (aCView)
185 {
186 /*if( width <= 0 || height <= 0 )
187 aCView->WS->Redraw(ACView, ACUnderLayer, ACOverLayer);
188 else
189 aCView->WS->RedrawArea(ACView, ACUnderLayer, ACOverLayer, x, y, width, height);*/
190 // Always do full redraw
191 aCView->WS->Redraw(ACView, ACUnderLayer, ACOverLayer);
7fd59977 192 }
7fd59977 193}
194
2166f0fa
SK
195Graphic3d_PtrFrameBuffer OpenGl_GraphicDriver::FBOCreate (const Graphic3d_CView& ACView, const Standard_Integer theWidth, const Standard_Integer theHeight)
196{
197 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
198 if (aCView)
199 return aCView->WS->FBOCreate(theWidth, theHeight);
200 return (Graphic3d_PtrFrameBuffer)NULL;
7fd59977 201}
202
2166f0fa
SK
203Graphic3d_PtrFrameBuffer OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth, const Standard_Integer theHeight)
204{
7fd59977 205 // activate OpenGL context
2166f0fa 206 if (!Activate())
7fd59977 207 return NULL;
2166f0fa 208
7fd59977 209 // create the FBO
210 OpenGl_FrameBuffer* aFrameBuffer = new OpenGl_FrameBuffer();
2166f0fa 211 if (!aFrameBuffer->Init (GetGlContext(), theWidth, theHeight))
7fd59977 212 {
213 delete aFrameBuffer;
214 return NULL;
215 }
216 return (Graphic3d_PtrFrameBuffer )aFrameBuffer;
217}
218
2166f0fa 219void OpenGl_GraphicDriver::FBORelease (const Graphic3d_CView& ACView, Graphic3d_PtrFrameBuffer& theFBOPtr)
7fd59977 220{
221 if (theFBOPtr == NULL)
7fd59977 222 return;
2166f0fa
SK
223 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
224 if (aCView)
225 {
226 aCView->WS->FBORelease(theFBOPtr);
227 theFBOPtr = NULL;
7fd59977 228 }
2166f0fa
SK
229}
230
231void OpenGl_Workspace::FBORelease (Graphic3d_PtrFrameBuffer theFBOPtr)
232{
7fd59977 233 // activate OpenGL context
2166f0fa 234 if (!Activate())
7fd59977 235 return;
2166f0fa 236
7fd59977 237 // release the object
2166f0fa
SK
238 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer*)theFBOPtr;
239 aFrameBuffer->Release (GetGlContext());
7fd59977 240 delete aFrameBuffer;
7fd59977 241}
242
243void OpenGl_GraphicDriver::FBOGetDimensions (const Graphic3d_CView& ,
244 const Graphic3d_PtrFrameBuffer theFBOPtr,
245 Standard_Integer& theWidth, Standard_Integer& theHeight,
246 Standard_Integer& theWidthMax, Standard_Integer& theHeightMax)
247{
248 if (theFBOPtr == NULL)
249 {
250 return;
251 }
252 const OpenGl_FrameBuffer* aFrameBuffer = (const OpenGl_FrameBuffer* )theFBOPtr;
253 theWidth = aFrameBuffer->GetVPSizeX(); // current viewport size
254 theHeight = aFrameBuffer->GetVPSizeY();
255 theWidthMax = aFrameBuffer->GetSizeX(); // texture size
256 theHeightMax = aFrameBuffer->GetSizeY();
257}
258
259void OpenGl_GraphicDriver::FBOChangeViewport (const Graphic3d_CView& ,
260 Graphic3d_PtrFrameBuffer& theFBOPtr,
261 const Standard_Integer theWidth, const Standard_Integer theHeight)
262{
263 if (theFBOPtr == NULL)
264 {
265 return;
266 }
267 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theFBOPtr;
268 aFrameBuffer->ChangeViewport (theWidth, theHeight);
269}
270
271// OpenGL 1.2 stuff
272#ifndef GL_BGR
273 #define GL_BGR 0x80E0
274#endif
275#ifndef GL_BGRA
276 #define GL_BGRA 0x80E1
277#endif
278
7fd59977 279static inline GLenum TFormatToGLEnum (const TRawBufferDataFormat theTFormat)
280{
281 switch (theTFormat)
282 {
283 case TRGB: return GL_RGB;
284 case TBGR: return GL_BGR;
285 case TRGBA: return GL_RGBA;
286 case TBGRA: return GL_BGRA;
287 case TDepthComponent: return GL_DEPTH_COMPONENT;
288 case TRed: return GL_RED;
289 case TGreen: return GL_GREEN;
290 case TBlue: return GL_BLUE;
291 case TAlpha: return GL_ALPHA;
292 default: return 0;
293 }
294}
295
296static inline GLenum TTypeToGLEnum (const TRawBufferDataType theTType)
297{
298 switch (theTType)
299 {
300 case TUByte: return GL_UNSIGNED_BYTE;
301 case TFloat: return GL_FLOAT;
302 default: return 0;
303 }
304}
305
2166f0fa
SK
306Standard_Boolean OpenGl_GraphicDriver::BufferDump (const Graphic3d_CView& ACView, Image_CRawBufferData& theBuffer)
307{
308 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
309 if (aCView)
310 return aCView->WS->BufferDump((OpenGl_FrameBuffer *)ACView.ptrFBO,theBuffer);
311 return Standard_False;
312}
313
314Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer *theFBOPtr, Image_CRawBufferData& theBuffer)
7fd59977 315{
316 GLenum aFormat = TFormatToGLEnum (theBuffer.format);
317 GLenum aType = TTypeToGLEnum (theBuffer.type);
318
319 // safe checks
320 if (aFormat == 0 || aType == 0 ||
321 theBuffer.widthPx == 0 || theBuffer.heightPx == 0 ||
322 theBuffer.dataPtr == NULL)
323 {
324 return Standard_False;
325 }
326
327 // activate OpenGL context
2166f0fa 328 if (!Activate())
7fd59977 329 return Standard_False;
7fd59977 330
331 // bind FBO if used
2166f0fa 332 OpenGl_FrameBuffer* aFrameBuffer = theFBOPtr;
7fd59977 333 GLint aReadBufferPrev = GL_BACK;
334 if (aFrameBuffer != NULL && aFrameBuffer->IsValid())
335 {
2166f0fa 336 aFrameBuffer->BindBuffer (GetGlContext());
7fd59977 337 }
338 else
339 {
340 glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
341 GLint aDrawBufferPrev = GL_BACK;
342 glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
343 glReadBuffer (aDrawBufferPrev);
344 }
345
346 GLint anAlignBack = 1;
347 glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack);
348 if (theBuffer.rowAligmentBytes == 0)
349 {
350 theBuffer.rowAligmentBytes = 1;
351 }
352 glPixelStorei (GL_PACK_ALIGNMENT, theBuffer.rowAligmentBytes);
353
354 // read pixels
355 glReadPixels (0, 0, theBuffer.widthPx, theBuffer.heightPx, aFormat, aType, (GLvoid* )theBuffer.dataPtr);
356 glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack);
357
358 if (aFrameBuffer != NULL && aFrameBuffer->IsValid())
359 {
2166f0fa 360 aFrameBuffer->UnbindBuffer (GetGlContext());
7fd59977 361 }
362 else
363 {
364 glReadBuffer (aReadBufferPrev);
365 }
366 return Standard_True;
367}
368
2166f0fa
SK
369void OpenGl_GraphicDriver::RemoveView (const Graphic3d_CView& ACView)
370{
371 if (GetMapOfViews().IsBound (ACView.ViewId))
372 GetMapOfViews().UnBind (ACView.ViewId);
7fd59977 373
2166f0fa
SK
374 if (GetMapOfWorkspaces().IsBound (ACView.WsId))
375 GetMapOfWorkspaces().UnBind (ACView.WsId);
7fd59977 376
2166f0fa
SK
377 OpenGl_CView *aCView = (OpenGl_CView *)ACView.ptrView;
378 delete aCView;
379 ((Graphic3d_CView *)&ACView)->ptrView = NULL;
7fd59977 380}
381
2166f0fa
SK
382void OpenGl_GraphicDriver::SetLight (const Graphic3d_CView& ACView)
383{
384 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
385 if (aCView)
386 aCView->View->SetLights(ACView.Context);
7fd59977 387}
388
2166f0fa
SK
389void OpenGl_GraphicDriver::SetPlane (const Graphic3d_CView& ACView)
390{
391 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
392 if (aCView)
393 aCView->View->SetClippingPlanes(ACView.Context);
7fd59977 394}
395
2166f0fa
SK
396void OpenGl_GraphicDriver::SetVisualisation (const Graphic3d_CView& ACView)
397{
398 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
399 if (aCView)
400 {
401 aCView->View->SetVisualisation(ACView.Context);
402 aCView->WS->UseZBuffer() = ( ACView.Context.Visualization == 0? (ACView.Context.ZBufferActivity == 1) : (ACView.Context.ZBufferActivity != 0) );
7fd59977 403 }
7fd59977 404}
405
2166f0fa
SK
406void OpenGl_GraphicDriver::TransformStructure (const Graphic3d_CStructure& ACStructure)
407{
408 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
409 if (astructure)
410 astructure->SetTransformation(&(ACStructure.Transformation[0][0]));
7fd59977 411}
412
2166f0fa
SK
413void OpenGl_GraphicDriver::DegenerateStructure (const Graphic3d_CStructure& ACStructure)
414{
415 OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
416 if (astructure)
417 astructure->SetDegenerateModel( ACStructure.ContextFillArea.DegenerationMode, ACStructure.ContextFillArea.SkipRatio );
418}
7fd59977 419
2166f0fa
SK
420void OpenGl_GraphicDriver::Transparency (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
421{
422 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
423 if (aCView)
424 aCView->WS->UseTransparency(AFlag);
425}
7fd59977 426
2166f0fa
SK
427void OpenGl_GraphicDriver::Update (const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACUnderLayer, const Aspect_CLayer2d& ACOverLayer)
428{
429 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
430 if (aCView)
431 aCView->WS->Update(ACView,ACUnderLayer,ACOverLayer);
432}
7fd59977 433
2166f0fa
SK
434Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& ACView)
435{
436 if (openglDisplay.IsNull())
437 return Standard_False;
7fd59977 438
2166f0fa
SK
439 if (GetMapOfViews().IsBound (ACView.ViewId))
440 GetMapOfViews().UnBind (ACView.ViewId);
7fd59977 441
2166f0fa
SK
442 if (GetMapOfWorkspaces().IsBound (ACView.WsId))
443 GetMapOfWorkspaces().UnBind (ACView.WsId);
7fd59977 444
2166f0fa
SK
445 Handle(OpenGl_Workspace) aWS = Handle(OpenGl_Workspace)::DownCast(openglDisplay->GetWindow( ACView.DefWindow.XWindow ));
446 if ( aWS.IsNull() )
447 {
448 aWS = new OpenGl_Workspace( openglDisplay, ACView.DefWindow, ACView.GContext );
449 openglDisplay->SetWindow( ACView.DefWindow.XWindow, aWS );
7fd59977 450 }
451
2166f0fa 452 GetMapOfWorkspaces().Bind (ACView.WsId, aWS);
7fd59977 453
2166f0fa
SK
454 Handle(OpenGl_View) aView = new OpenGl_View( ACView.Context );
455 GetMapOfViews().Bind (ACView.ViewId, aView);
7fd59977 456
2166f0fa
SK
457 OpenGl_CView *aCView = new OpenGl_CView;
458 aCView->View = aView;
459 aCView->WS = aWS;
460 ACView.ptrView = aCView;
7fd59977 461
2166f0fa
SK
462 return Standard_True;
463}
7fd59977 464
2166f0fa
SK
465void OpenGl_GraphicDriver::ViewMapping (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
466{
467 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
468 if (aCView)
469 {
470 aCView->View->SetMapping(ACView);
529afc1a 471 if (!AWait)
2166f0fa
SK
472 {
473 aCView->WS->Resize(ACView.DefWindow);
474 aCView->WS->Invalidate();
7fd59977 475 }
7fd59977 476 }
2166f0fa 477}
7fd59977 478
2166f0fa
SK
479void OpenGl_GraphicDriver::ViewOrientation (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
480{
481 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
482 if (aCView)
483 {
484 aCView->View->SetOrientation(ACView);
529afc1a 485 if (!AWait)
2166f0fa
SK
486 {
487 aCView->WS->Resize(ACView.DefWindow);
488 aCView->WS->Invalidate();
7fd59977 489 }
7fd59977 490 }
2166f0fa 491}
7fd59977 492
2166f0fa
SK
493void OpenGl_GraphicDriver::SetBackFacingModel (const Graphic3d_CView& ACView)
494{
495 const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
496 if (aCView)
497 aCView->View->SetBackfacing(ACView.Backfacing);
498}