1 // File: OpenGl_Workspace_2.cxx
2 // Created: 20 September 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
6 #include <OpenGl_GlCore11.hxx>
8 #include <OpenGl_FrameBuffer.hxx>
9 #include <TColStd_Array2OfReal.hxx>
10 #include <OpenGl_telem_util.hxx>
13 #include <NCollection_Handle.hxx>
14 #include <FreeImagePlus.h>
16 #pragma comment( lib, "FreeImage.lib" )
17 #pragma comment( lib, "FreeImagePlus.lib" )
19 typedef NCollection_Handle<fipImage> FipHandle;
22 #include <OpenGl_PrinterContext.hxx>
23 #include <OpenGl_Workspace.hxx>
24 #include <OpenGl_View.hxx>
25 #include <OpenGl_Display.hxx>
27 #include <GL/glu.h> // gluOrtho2D()
29 //10-05-96 : CAL ; Ajout d'un nouveau delta dans les copies de pixels (voir CALL_DEF_DELTA)
30 #define CALL_DEF_DELTA 10
32 // ---------------------------------------------------------------
33 // Function: getNearestPowOfTwo
34 // Purpose: get the nearest power of two for theNumber
35 // ---------------------------------------------------------------
36 static GLsizei getNearestPowOfTwo (const GLsizei theNumber)
39 for (GLsizei p2 = 1; p2 <= theNumber; aLast = p2, p2 <<= 1);
43 // ---------------------------------------------------------------
44 // Function: getMaxFrameSize
45 // Purpose: get the maximum possible frame size
46 // ---------------------------------------------------------------
47 static void getMaxFrameSize(Standard_Integer& theWidth,
48 Standard_Integer& theHeight)
53 glGetIntegerv (GL_MAX_VIEWPORT_DIMS, (GLint*) &aVpDim);
54 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &aTexDim);
55 (aVpDim[0] >= aTexDim) ? aMaxX = (GLsizei) aTexDim :
56 aMaxX = getNearestPowOfTwo((GLsizei)aVpDim[0]);
57 (aVpDim[1] >= aTexDim) ? aMaxY = (GLsizei) aTexDim :
58 aMaxY = getNearestPowOfTwo((GLsizei)aVpDim[1]);
60 theWidth = (Standard_Integer)aMaxX;
61 theHeight = (Standard_Integer)aMaxY;
64 // ---------------------------------------------------------------
65 // Function: fitDimensionsRatio
66 // Purpose: calculate correct width/height ratio for theWidth and
67 // theHeight parameters
68 // ---------------------------------------------------------------
69 static void fitDimensionsRatio (Standard_Integer& theWidth,
70 Standard_Integer& theHeight,
71 const Standard_Real theViewRatio)
73 // set dimensions in accordance with the viewratio
74 if (theHeight < theWidth/theViewRatio)
75 theWidth = (Standard_Integer)(theHeight*theViewRatio);
77 if (theWidth < theHeight*theViewRatio)
78 theHeight = (Standard_Integer)(theWidth/theViewRatio);
81 // ---------------------------------------------------------------
82 // Function: getDimensionsTiling
83 // Purpose: calculate maximum possible dimensions for framebuffer
84 // in tiling mode according to the view size
85 // ---------------------------------------------------------------
86 static void getDimensionsTiling (Standard_Integer& theFrameWidth,
87 Standard_Integer& theFrameHeight,
88 const int theViewWidth,
89 const int theViewHeight)
91 // fit the maximum dimensions into the printing area
92 if (theFrameWidth > theViewWidth)
93 theFrameWidth = theViewWidth;
95 if (theFrameHeight > theViewHeight)
96 theFrameHeight = theViewHeight;
99 // ---------------------------------------------------------------
100 // Function: initBufferStretch
101 // Purpose: calculate initialization sizes for frame buffer
102 // when the stretch algorithm is selected
103 // ---------------------------------------------------------------
104 static void initBufferStretch (Standard_Integer& theFrameWidth,
105 Standard_Integer& theFrameHeight,
106 const int theViewWidth,
107 const int theViewHeight)
110 // Calculate correct width/height for framebuffer
111 Standard_Real aViewRatio = (Standard_Real)theViewWidth/theViewHeight;
112 fitDimensionsRatio (theFrameWidth, theFrameHeight, aViewRatio);
114 // downscale the framebuffer if it is too large
115 Standard_Real aWidthRate = (Standard_Real)theFrameWidth /theViewWidth;
116 Standard_Real aHeightRate = (Standard_Real)theFrameHeight/theViewHeight;
118 if ((aWidthRate > 1 && aHeightRate > 1 && aWidthRate >= aHeightRate) ||
119 (aWidthRate > 1 && aHeightRate <= 1))
121 theFrameWidth = (Standard_Integer)(theFrameWidth /aWidthRate);
122 theFrameHeight = (Standard_Integer)(theFrameHeight/aWidthRate);
124 else if ((aWidthRate > 1 && aHeightRate > 1 && aWidthRate < aHeightRate) ||
125 (aWidthRate <= 1 && aHeightRate > 1))
127 theFrameWidth = (Standard_Integer)(theFrameWidth /aHeightRate);
128 theFrameHeight = (Standard_Integer)(theFrameHeight/aHeightRate);
133 // ---------------------------------------------------------------
134 // Function: initBufferTiling
135 // Purpose: calculate initialization sizes for frame buffer
136 // when the tile algorithm is selected
137 // ---------------------------------------------------------------
138 static void initBufferTiling (Standard_Integer& theFrameWidth,
139 Standard_Integer &theFrameHeight,
140 const int theViewWidth,
141 const int theViewHeight)
143 // fit framebuffer into the printing area
144 if (theFrameWidth > theViewWidth)
145 theFrameWidth = theViewWidth;
147 if (theFrameHeight > theViewHeight)
148 theFrameHeight = theViewHeight;
151 // ---------------------------------------------------------------
152 // Function: initBitmapBuffer
153 // Purpose: init device independent bitmap to hold printing data
154 // ---------------------------------------------------------------
156 #ifndef HAVE_FREEIMAGE
157 static void initBitmapBuffer (const HDC theMemoryDC,
158 HBITMAP &theMemoryBmp,
159 const Standard_Integer theBmpWidth,
160 const Standard_Integer theBmpHeight,
163 // define compatible bitmap
164 BITMAPINFO aBitmapData;
165 memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
166 aBitmapData.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
167 aBitmapData.bmiHeader.biWidth = theBmpWidth;
168 aBitmapData.bmiHeader.biHeight = theBmpHeight;
169 aBitmapData.bmiHeader.biPlanes = 1;
170 aBitmapData.bmiHeader.biBitCount = 24;
171 aBitmapData.bmiHeader.biXPelsPerMeter = 0;
172 aBitmapData.bmiHeader.biYPelsPerMeter = 0;
173 aBitmapData.bmiHeader.biClrUsed = 0;
174 aBitmapData.bmiHeader.biClrImportant = 0;
175 aBitmapData.bmiHeader.biCompression = BI_RGB;
176 aBitmapData.bmiHeader.biSizeImage = 0;
178 // Create Device Independent Bitmap
179 theMemoryBmp = CreateDIBSection (theMemoryDC, &aBitmapData, DIB_RGB_COLORS,
180 &theBufferPtr, NULL, 0);
183 // ---------------------------------------------------------------
184 // Function: imagePasteDC
185 // Purpose: copy the data from image buffer to the device context
186 // ---------------------------------------------------------------
187 static bool imagePasteDC(HDC theDstDC, FipHandle theImage, int theOffsetX,
188 int theOffsetY, int theWidth, int theHeight,
189 int theLeft = 0, int theTop = 0)
191 // get image parameters
192 BITMAPINFO* aBitmapData = theImage->getInfo ();
193 SetStretchBltMode (theDstDC, STRETCH_HALFTONE);
195 // organize blocks data passing if memory isn't enough to pass all the data
197 int aLinesComplete = 0, aMaxBlockWidth = theHeight, aBlockWidth = 0,
198 aPassed = 0, aInverseLine = 0, aScan = 0;
200 while (aMaxBlockWidth >= 1 && aLinesComplete < theHeight)
202 // how much lines still to pass
203 aBlockWidth = theHeight - aLinesComplete;
205 // normalize count of lines to pass to maximum lines count at one pass.
206 if (aBlockWidth > aMaxBlockWidth)
207 aBlockWidth = aMaxBlockWidth;
209 // access image data at the start scan line, we need to calculate scan from
210 // the bottom of image (image is bottom-left, the src coord is top-left)
211 aInverseLine = theTop + aBlockWidth + aLinesComplete;
212 aScan = theImage->getHeight() - aInverseLine;
213 aDataPtr = theImage->getScanLine (aScan);
217 // try to pass block to the device
220 // instead of banded output we provide blocked as it isn't always passed
221 // to printer as it is expected
222 aPassed = SetDIBitsToDevice (theDstDC, theOffsetX,
223 theOffsetY + aLinesComplete,
224 theWidth, aBlockWidth, theLeft, 0,
226 aDataPtr, aBitmapData, DIB_RGB_COLORS);
228 // if result is bad, try to decrease band width
229 if (aPassed != aBlockWidth)
231 aMaxBlockWidth = aMaxBlockWidth >> 1;
235 aLinesComplete += aBlockWidth;
239 // check for total failure
240 if (aMaxBlockWidth < 1)
246 // ---------------------------------------------------------------
247 // Function: imageStretchDC
248 // Purpose: copy pixels from image to dc by stretching them
249 // ---------------------------------------------------------------
250 static bool imageStretchDC(HDC theDstDC, FipHandle theImage, int theOffsetX,
251 int theOffsetY, int theWidth, int theHeight)
253 // access to raw image data
254 BYTE *aDataPtr = theImage->accessPixels ();
258 // get image parameters
259 unsigned int widthPx = theImage->getWidth ();
260 unsigned int heightPx = theImage->getHeight ();
261 BITMAPINFO* aBitmapData = theImage->getInfo ();
262 SetStretchBltMode (theDstDC, STRETCH_HALFTONE);
264 // pass lines and check if operation is succesfull
266 aPassed = StretchDIBits (theDstDC, theOffsetX, theOffsetY, theWidth,
267 theHeight, 0, 0, widthPx, heightPx, aDataPtr,
268 aBitmapData, DIB_RGB_COLORS, SRCCOPY);
270 if (aPassed != heightPx)
278 // ---------------------------------------------------------------
279 // ---------------------------------------------------------------
282 Standard_Boolean OpenGl_Workspace::Print
283 (const Graphic3d_CView& ACView,
284 const Aspect_CLayer2d& ACUnderLayer,
285 const Aspect_CLayer2d& ACOverLayer,
286 const Aspect_Handle hPrintDC,// const Aspect_Drawable hPrintDC,
287 const Standard_Boolean showBackground,
288 const Standard_CString filename,
289 const Aspect_PrintAlgo printAlgorithm,
290 const Standard_Real theScaleFactor)
296 //MessageBox (NULL, "Print failed: can't setup the view for printing.",
297 // "The operation couldn't be completed.", MB_OK);
298 return Standard_False;
301 // printer page dimensions
302 HDC hPrnDC = (HDC) hPrintDC;
303 int devWidth = GetDeviceCaps (hPrnDC, HORZRES);
304 int devHeight = GetDeviceCaps (hPrnDC, VERTRES);
306 // if context is actually a memory dc, try to retrieve bitmap dimensions
307 // (memory dc could be used for testing purposes)
308 if (GetObjectType (hPrnDC) == OBJ_MEMDC)
310 // memory dc dimensions
312 HBITMAP aMemoryBitmap = (HBITMAP) GetCurrentObject (hPrnDC, OBJ_BITMAP);
314 if (GetObject (aMemoryBitmap, sizeof (BITMAP), &aBitmapInfo))
316 devWidth = aBitmapInfo.bmWidth;
317 devHeight = aBitmapInfo.bmHeight;
321 Standard_Integer tempWidth = (Standard_Integer) devWidth;
322 Standard_Integer tempHeight = (Standard_Integer) devHeight;
325 int viewWidth = myWidth;
326 int viewHeight = myHeight;
327 if (viewWidth == 0 || viewHeight == 0)
329 //MessageBox (NULL, "Print failed: can't setup the view for printing.",
330 // "The operation couldn't be completed.", MB_OK);
331 return Standard_False;
334 // calculate correct width/height ratio
335 Standard_Real viewRatio = (Standard_Real)viewWidth/viewHeight;
336 fitDimensionsRatio(tempWidth, tempHeight, viewRatio);
338 // width and height for printing area
339 int width = (int) (tempWidth * theScaleFactor);
340 int height = (int) (tempHeight * theScaleFactor);
342 // device independent bitmap for the whole view
343 #ifdef HAVE_FREEIMAGE
344 FipHandle aViewImage = NULL;
345 BYTE* aViewBuffer = NULL;
347 HDC hMemDC = CreateCompatibleDC (hPrnDC);
348 HBITMAP hViewBitmap = NULL;
349 HGDIOBJ hViewBitmapOld = NULL;
350 VOID* aViewBuffer = NULL;
353 // Frame buffer initialization
354 OpenGl_FrameBuffer* aFrameBuffer = NULL;
355 OpenGl_FrameBuffer* aPrevBuffer = (OpenGl_FrameBuffer*) ACView.ptrFBO;
356 Standard_Integer aFrameWidth (0), aFrameHeight (0),
357 aPrevBufferX (0), aPrevBufferY (0);
359 bool IsTiling = (printAlgorithm == 1);
361 // try to use existing frame buffer
364 GLsizei aPrevWidth = aPrevBuffer->GetSizeX();
365 GLsizei aPrevHeight = aPrevBuffer->GetSizeY();
366 bool isUsable = false;
368 // check if its possible to use previous frame buffer
369 if (!IsTiling && aPrevWidth >= width && aPrevHeight >= height)
371 aFrameWidth = (Standard_Integer) width;
372 aFrameHeight = (Standard_Integer) height;
377 getDimensionsTiling (aFrameWidth, aFrameHeight, width, height);
378 if (aPrevWidth >= aFrameWidth && aPrevHeight >= aFrameHeight)
382 // if it is enough memory for image paste dc operation
385 #ifdef HAVE_FREEIMAGE
386 // try to allocate fipImage and necessary resources
387 fipImage* anImagePtr = new fipImage (FIT_BITMAP, aFrameWidth,
390 // if allocated succesfully
391 if (anImagePtr->isValid())
393 aViewImage = anImagePtr;
394 aViewBuffer = aViewImage->accessPixels ();
406 // try to allocate compatible bitmap and necessary resources
407 initBitmapBuffer (hMemDC, hViewBitmap,
408 aFrameWidth, aFrameHeight, aViewBuffer);
413 DeleteObject (hViewBitmap);
417 hViewBitmapOld = SelectObject (hMemDC, hViewBitmap);
421 // use previous frame buffer
424 aPrevBufferX = aPrevWidth;
425 aPrevBufferY = aPrevHeight;
426 aFrameBuffer = aPrevBuffer;
427 aFrameBuffer->ChangeViewport (aFrameWidth, aFrameHeight);
431 // if previous buffer cannot be used, try to init a new one
434 aFrameBuffer = new OpenGl_FrameBuffer();
436 // try to create the framebuffer with the best possible size
437 Standard_Integer aMaxWidth(0), aMaxHeight(0);
438 getMaxFrameSize (aMaxWidth, aMaxHeight);
439 while (aMaxWidth > 1 && aMaxHeight > 1)
441 aFrameWidth = aMaxWidth;
442 aFrameHeight = aMaxHeight;
444 // calculate dimensions for different printing algorithms
446 initBufferStretch (aFrameWidth, aFrameHeight, width, height);
448 initBufferTiling (aFrameWidth, aFrameHeight, width, height);
450 // try to initialize framebuffer
451 if (aFrameBuffer->Init (GetGlContext(), aFrameWidth, aFrameHeight))
453 #ifdef HAVE_FREEIMAGE
454 // try to allocate fipImage and necessary resources
455 fipImage* anImagePtr = new fipImage (FIT_BITMAP, aFrameWidth,
458 // if allocated succesfully
459 if (anImagePtr->isValid())
461 aViewImage = anImagePtr;
462 aViewBuffer = aViewImage->accessPixels ();
469 aFrameBuffer->Release (GetGlContext());
476 // try to allocate compatible bitmap and necessary resources
477 initBitmapBuffer (hMemDC, hViewBitmap,
478 aFrameWidth, aFrameHeight, aViewBuffer);
482 DeleteObject (hViewBitmap);
483 aFrameBuffer->Release (GetGlContext());
488 hViewBitmapOld = SelectObject (hMemDC, hViewBitmap);
494 // not initialized, decrease dimensions
495 aMaxWidth = aMaxWidth >> 1;
496 aMaxHeight = aMaxHeight >> 1;
499 // check if there are proper dimensions
500 if (aMaxWidth <= 1 || aMaxHeight <= 1)
502 MessageBox (NULL, "Print failed: can't allocate buffer for printing.",
503 "The operation couldn't be completed.", MB_OK);
507 #ifndef HAVE_FREEIMAGE
512 return Standard_False;
516 // setup printing context and viewport
517 GLint aViewPortBack[4];
518 GLint anAlignBack = 1;
520 OpenGl_PrinterContext aPrinterContext (myGContext);
521 aPrinterContext.SetLayerViewport ((GLsizei)aFrameWidth,
522 (GLsizei)aFrameHeight);
523 glGetIntegerv (GL_VIEWPORT, aViewPortBack);
524 glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack);
525 glPixelStorei (GL_PACK_ALIGNMENT, 4);
527 // start document if the printer context is not actually a memory dc
528 // (memory dc could be used for testing purposes)
530 if (GetObjectType (hPrnDC) == OBJ_DC)
532 // Initalize printing procedure
533 di.cbSize = sizeof(DOCINFO);
534 di.lpszDocName = "Open Cascade Document - print v3d view";
535 di.lpszOutput = filename;
537 // if can't print the document
538 if (StartDoc (hPrnDC, &di) <= 0 || StartPage (hPrnDC) <= 0)
540 MessageBox (NULL, "Print failed: printer can't start operation.",
541 "The operation couldn't be completed.", MB_OK);
542 #ifndef HAVE_FREEIMAGE
545 SelectObject (hMemDC, hViewBitmapOld);
546 DeleteObject (hViewBitmap);
551 return Standard_False;
555 // activate the offscreen buffer
556 aFrameBuffer->BindBuffer (GetGlContext());
558 // calculate offset for centered printing
559 int aDevOffx = (int)(devWidth - width) /2;
560 int aDevOffy = (int)(devHeight - height)/2;
562 // operation complete flag
565 // Set up status for printing
567 NamedStatus |= OPENGL_NS_WHITEBACK;
571 aPrinterContext.SetScale ((GLfloat)aFrameWidth /viewWidth,
572 (GLfloat)aFrameHeight/viewHeight);
573 aFrameBuffer->SetupViewport ();
574 Redraw1(ACView, ACUnderLayer, ACOverLayer, 0);
575 RedrawImmediatMode();
576 glReadPixels (0, 0, aFrameWidth, aFrameHeight,
577 GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
579 // copy result to the printer device and check for errors
580 #ifdef HAVE_FREEIMAGE
581 if (!aViewImage->rescale(width, height, FILTER_BICUBIC) ||
582 !imagePasteDC (hPrnDC, aViewImage, aDevOffx, aDevOffy, width, height))
583 isDone = imageStretchDC (hPrnDC, aViewImage, aDevOffx, aDevOffy,
586 if (width > aFrameWidth && height > aFrameHeight)
588 SetStretchBltMode (hPrnDC, STRETCH_HALFTONE);
589 isDone = StretchBlt (hPrnDC, aDevOffx, aDevOffy, width, height,
590 hMemDC, 0, 0, aFrameWidth, aFrameHeight, SRCCOPY);
594 isDone = BitBlt (hPrnDC, aDevOffx, aDevOffy, width, height,
595 hMemDC, 0, 0, SRCCOPY);
601 // calculate total count of frames and cropping size
602 Standard_Integer aPxCropx = 0;
603 Standard_Integer aPxCropy = 0;
604 Standard_Integer aTotalx =
605 (Standard_Integer)floor ((float)width /aFrameWidth);
606 Standard_Integer aTotaly =
607 (Standard_Integer)floor ((float)height/aFrameHeight);
608 if (width %aFrameWidth != 0)
610 aPxCropx = (aFrameWidth - width%aFrameWidth)/2;
613 if (height%aFrameHeight != 0)
615 aPxCropy = (aFrameHeight - height%aFrameHeight)/2;
619 int anOddPixelx = (width %aFrameWidth) %2;
620 int anOddPixely = (height%aFrameHeight)%2;
622 // calculate scale factor for full frames
623 Standard_Real aScalex = (Standard_Real)width /aFrameWidth;
624 Standard_Real aScaley = (Standard_Real)height/aFrameHeight;
626 // calculate and set the text scaling factor for printing context
627 GLfloat aScaleRatex = (GLfloat)aFrameWidth /viewWidth;
628 GLfloat aScaleRatey = (GLfloat)aFrameHeight/viewHeight;
629 aPrinterContext.SetScale (aScaleRatex*(GLfloat)aScalex,
630 aScaleRatey*(GLfloat)aScaley);
632 // initialize projection matrix for printer context
633 TColStd_Array2OfReal aProj (0, 3, 0, 3);
634 Standard_Real aDef = 0;
639 // projection matrix offsets for printer context
640 // offsets are even numbers
641 Standard_Real aOffsetx(0), aOffsety(0);
642 aOffsetx = -(aTotalx-1);
643 aOffsety = -(aTotaly-1);
645 // rect of frame image that will be copied
646 // and coordinates in view image where to put it
647 Standard_Integer aLeft = 0, aRight = 0, aBottom = 0, aTop = 0;
648 Standard_Integer aSubLeft = (Standard_Integer)aDevOffx;
649 Standard_Integer aSubTop = (Standard_Integer)aDevOffy;
651 // draw sequence of full frames
652 for (int i = 0; i < aTotalx; i++)
654 // offsets are even numbers
655 aOffsety = -(aTotaly-1);
656 aSubTop = (Standard_Integer)aDevOffy;
658 // calculate cropped frame rect
659 aLeft = (i == 0) ? aPxCropx : 0;
660 aRight = (i == aTotalx-1) ? aFrameWidth-(aPxCropx+anOddPixelx) :
663 for (int j = 0; j < aTotaly; j++)
665 // no offset for single frames
666 aProj(3,0) = (aTotalx == 1) ? 0 : -aOffsetx;
667 aProj(3,1) = (aTotaly == 1) ? 0 : aOffsety;
669 // set projection matrix
670 aProj(0,0) = aScalex;
671 aProj(1,1) = aScaley;
672 aPrinterContext.SetProjTransformation (aProj);
674 // calculate cropped frame rect
675 aTop = (j == 0) ? aPxCropy : 0;
676 aBottom = (j == aTotaly-1) ? aFrameHeight-(aPxCropy+anOddPixely) :
679 // draw to the offscreen buffer and capture the result
680 aFrameBuffer->SetupViewport ();
681 Redraw1(ACView, ACUnderLayer, ACOverLayer, 0);
682 RedrawImmediatMode();
683 glReadPixels (0, 0, aFrameWidth, aFrameHeight,
684 GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
685 #ifdef HAVE_FREEIMAGE
686 // cut out pixels that are out of printing area
687 isDone = imagePasteDC (hPrnDC, aViewImage, aSubLeft, aSubTop,
688 aRight-aLeft, aBottom-aTop, aLeft, aTop);
690 isDone = BitBlt (hPrnDC, aSubLeft, aSubTop, aRight-aLeft, aBottom-aTop,
691 hMemDC, aLeft, aTop, SRCCOPY);
694 // stop operation if errors
698 // calculate new view offset for y-coordinate
700 aSubTop += aBottom-aTop;
703 // stop operation if errors
707 // calculate new view offset for x-coordinate
709 aSubLeft += aRight-aLeft;
713 // complete printing or indicate an error
714 if (GetObjectType (hPrnDC) == OBJ_DC && isDone == true)
719 else if (isDone == false)
721 MessageBox (NULL, "Print failed: insufficient memory or spool error.\nPlease use smaller printer resolution.",
722 "The opeartion couldn't be completed.", MB_OK);
723 if (GetObjectType (hPrnDC) == OBJ_DC)
727 // return OpenGl to the previous state
728 aPrinterContext.Deactivate ();
729 glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack);
730 aFrameBuffer->UnbindBuffer (GetGlContext());
731 glViewport (aViewPortBack[0], aViewPortBack[1],
732 aViewPortBack[2], aViewPortBack[3]);
735 aPrevBuffer->ChangeViewport (aPrevBufferX, aPrevBufferY);
739 aFrameBuffer->Release (GetGlContext ());
744 #ifndef HAVE_FREEIMAGE
747 SelectObject (hMemDC, hViewBitmapOld);
748 DeleteObject (hViewBitmap);
753 // Reset status after printing
754 NamedStatus &= ~OPENGL_NS_WHITEBACK;
756 return (Standard_Boolean) isDone;
759 return Standard_False;
763 /*----------------------------------------------------------------------*/
766 void OpenGl_Workspace::Redraw1 (const Graphic3d_CView& ACView,
767 const Aspect_CLayer2d& ACUnderLayer,
768 const Aspect_CLayer2d& ACOverLayer,
771 if (myDisplay.IsNull() || myView.IsNull())
774 myDisplay->UpdateUserMarkers();
776 // Request reset of material
777 NamedStatus |= OPENGL_NS_RESMAT;
779 /* GL_DITHER on/off pour le background */
781 glEnable (GL_DITHER);
783 glDisable (GL_DITHER);
785 GLbitfield toClear = GL_COLOR_BUFFER_BIT;
788 glDepthFunc(GL_LEQUAL);
789 glDepthMask(GL_TRUE);
791 // SAV checking if depth test was deprecated somewhere outside
792 if ( myUseDepthTest )
793 glEnable(GL_DEPTH_TEST);
795 glDisable(GL_DEPTH_TEST);
798 toClear |= GL_DEPTH_BUFFER_BIT;
802 glDisable(GL_DEPTH_TEST);
805 if ( NamedStatus & OPENGL_NS_WHITEBACK )
807 // Set background to white
808 glClearColor (1.F, 1.F, 1.F, 1.F);
809 toClear |= GL_DEPTH_BUFFER_BIT;
813 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.F);
817 Handle(OpenGl_Workspace) aWS(this);
818 myView->Render(aWS,ACView,ACUnderLayer,ACOverLayer);
824 glXSwapBuffers ((Display*)myDisplay->GetDisplay (), myWindow );
826 SwapBuffers ( wglGetCurrentDC () );
829 myBackBufferRestored = Standard_False;
834 myIsUpdated = Standard_True;
837 /*----------------------------------------------------------------------*/
840 void OpenGl_Workspace::CopyBuffers (Tint vid, int FrontToBack, Tfloat xm, Tfloat ym, Tfloat zm, Tfloat XM, Tfloat YM, Tfloat ZM, Tint flag)
842 if (FrontToBack) myBackBufferRestored = Standard_False;
844 glMatrixMode (GL_PROJECTION);
847 gluOrtho2D ((GLdouble) 0., (GLdouble) myWidth, 0., (GLdouble) myHeight);
848 glMatrixMode (GL_MODELVIEW);
854 GLsizei width = myWidth+1, height = myHeight+1;
855 Tfloat xmr = 0, ymr = 0;
859 if (!myView.IsNull()) //szvgl: use vid here!
861 // Calculate bounding box and store the projected rectangle
863 // Project bounding box
864 if (myView->ProjectObjectToRaster (myWidth, myHeight, xm, ym, zm, xr[0], yr[0]) &&
865 myView->ProjectObjectToRaster (myWidth, myHeight, xm, YM, zm, xr[1], yr[1]) &&
866 myView->ProjectObjectToRaster (myWidth, myHeight, XM, YM, zm, xr[2], yr[2]) &&
867 myView->ProjectObjectToRaster (myWidth, myHeight, XM, ym, zm, xr[3], yr[3]) &&
868 myView->ProjectObjectToRaster (myWidth, myHeight, xm, ym, ZM, xr[4], yr[4]) &&
869 myView->ProjectObjectToRaster (myWidth, myHeight, xm, YM, ZM, xr[5], yr[5]) &&
870 myView->ProjectObjectToRaster (myWidth, myHeight, XM, YM, ZM, xr[6], yr[6]) &&
871 myView->ProjectObjectToRaster (myWidth, myHeight, XM, ym, ZM, xr[7], yr[7]))
874 xmr = ymr = (float ) shortreallast ();
875 XMR = YMR = (float ) shortrealfirst ();
877 * Recherche du rectangle projete
880 for (i=0; i<8; i++) {
881 if (xmr > xr[i]) xmr = xr[i];
882 if (ymr > yr[i]) ymr = yr[i];
883 if (XMR < xr[i]) XMR = xr[i];
884 if (YMR < yr[i]) YMR = yr[i];
886 /* pour eviter les bavures de pixels ! */
891 * Ajout CAL : 10/05/96
892 * Si les MinMax viennent d'un ensemble de markers
893 * on ne tient pas compte du scale factor de ceux-ci
894 * dans les valeurs de MinMax. En effet, ce facteur
895 * est dans l'espace pixel et les MinMax dans l'espace
896 * du modele. Donc ajout d'un delta de pixels
897 * en esperant que les applis n'utilisent pas des
898 * markers tres gros !
900 xmr -= CALL_DEF_DELTA; ymr -= CALL_DEF_DELTA;
901 XMR += CALL_DEF_DELTA; YMR += CALL_DEF_DELTA;
904 * Le rectangle projete peut-etre clippe
906 width = (GLsizei) (XMR-xmr+1);
907 height = (GLsizei) (YMR-ymr+1);
909 * (xmr,ymr) coin inferieur gauche
910 * (XMR,YMR) coin superieur droit
912 /* cas ou 1 coin est en dehors de la fenetre */
913 if (xmr < 0) { width = (GLsizei) (XMR+1); xmr = 0; }
914 if (ymr < 0) { height = (GLsizei) (YMR+1); ymr = 0; }
915 if (XMR > myWidth) { width = (GLsizei) (myWidth-xmr+1); }
916 if (YMR > myHeight) { height = (GLsizei) (myHeight-ymr+1); }
918 /* cas ou les 2 coins sont en dehors de la fenetre */
919 if (XMR < 0) { xmr = 0; width = height = 1; }
920 if (YMR < 0) { ymr = 0; width = height = 1; }
921 if (xmr > myWidth) { xmr = 0; width = height = 1; }
922 if (ymr > myHeight) { ymr = 0; width = height = 1; }
927 glDrawBuffer (FrontToBack? GL_BACK : GL_FRONT);
928 glReadBuffer (FrontToBack? GL_FRONT : GL_BACK);
930 glRasterPos2i ((GLint) xmr, (GLint) ymr);
931 glCopyPixels ((GLint) xmr, (GLint) ymr, width, height, GL_COLOR);
935 glMatrixMode (GL_PROJECTION);
937 glMatrixMode (GL_MODELVIEW);
940 glDrawBuffer (GL_BACK);
943 /*----------------------------------------------------------------------*/
945 //call_subr_displayCB
946 void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& ACView, int reason)
948 if( ACView.GDisplayCB )
950 Aspect_GraphicCallbackStruct callData;
951 callData.reason = reason;
952 callData.display = (DISPLAY*)myDisplay->GetDisplay();
953 callData.window = (WINDOW)myWindow;
954 callData.wsID = ACView.WsId;
955 callData.viewID = ACView.ViewId;
956 callData.gcontext = myGContext;
958 int status = (*ACView.GDisplayCB)( ACView.DefWindow.XWindow, ACView.GClientData, &callData );
962 /*----------------------------------------------------------------------*/