1 // Created on: 2011-09-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_GlCore11.hxx>
23 #include <OpenGl_FrameBuffer.hxx>
24 #include <TColStd_Array2OfReal.hxx>
25 #include <OpenGl_telem_util.hxx>
31 #if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_FREEIMAGE)
32 #include <NCollection_Handle.hxx>
33 #include <FreeImagePlus.h>
35 #pragma comment( lib, "FreeImage.lib" )
36 #pragma comment( lib, "FreeImagePlus.lib" )
38 typedef NCollection_Handle<fipImage> FipHandle;
41 #include <OpenGl_PrinterContext.hxx>
42 #include <OpenGl_Workspace.hxx>
43 #include <OpenGl_View.hxx>
44 #include <OpenGl_Display.hxx>
46 //10-05-96 : CAL ; Ajout d'un nouveau delta dans les copies de pixels (voir CALL_DEF_DELTA)
47 #define CALL_DEF_DELTA 10
49 // ---------------------------------------------------------------
50 // Function: getNearestPowOfTwo
51 // Purpose: get the nearest power of two for theNumber
52 // ---------------------------------------------------------------
53 static GLsizei getNearestPowOfTwo (const GLsizei theNumber)
56 for (GLsizei p2 = 1; p2 <= theNumber; aLast = p2, p2 <<= 1);
60 // ---------------------------------------------------------------
61 // Function: getMaxFrameSize
62 // Purpose: get the maximum possible frame size
63 // ---------------------------------------------------------------
64 static void getMaxFrameSize(Standard_Integer& theWidth,
65 Standard_Integer& theHeight)
70 glGetIntegerv (GL_MAX_VIEWPORT_DIMS, (GLint*) &aVpDim);
71 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &aTexDim);
72 (aVpDim[0] >= aTexDim) ? aMaxX = (GLsizei) aTexDim :
73 aMaxX = getNearestPowOfTwo((GLsizei)aVpDim[0]);
74 (aVpDim[1] >= aTexDim) ? aMaxY = (GLsizei) aTexDim :
75 aMaxY = getNearestPowOfTwo((GLsizei)aVpDim[1]);
77 theWidth = (Standard_Integer)aMaxX;
78 theHeight = (Standard_Integer)aMaxY;
81 // ---------------------------------------------------------------
82 // Function: fitDimensionsRatio
83 // Purpose: calculate correct width/height ratio for theWidth and
84 // theHeight parameters
85 // ---------------------------------------------------------------
86 static void fitDimensionsRatio (Standard_Integer& theWidth,
87 Standard_Integer& theHeight,
88 const Standard_Real theViewRatio)
90 // set dimensions in accordance with the viewratio
91 if (theHeight < theWidth/theViewRatio)
92 theWidth = (Standard_Integer)(theHeight*theViewRatio);
94 if (theWidth < theHeight*theViewRatio)
95 theHeight = (Standard_Integer)(theWidth/theViewRatio);
98 // ---------------------------------------------------------------
99 // Function: getDimensionsTiling
100 // Purpose: calculate maximum possible dimensions for framebuffer
101 // in tiling mode according to the view size
102 // ---------------------------------------------------------------
103 static void getDimensionsTiling (Standard_Integer& theFrameWidth,
104 Standard_Integer& theFrameHeight,
105 const int theViewWidth,
106 const int theViewHeight)
108 // fit the maximum dimensions into the printing area
109 if (theFrameWidth > theViewWidth)
110 theFrameWidth = theViewWidth;
112 if (theFrameHeight > theViewHeight)
113 theFrameHeight = theViewHeight;
116 // ---------------------------------------------------------------
117 // Function: initBufferStretch
118 // Purpose: calculate initialization sizes for frame buffer
119 // when the stretch algorithm is selected
120 // ---------------------------------------------------------------
121 static void initBufferStretch (Standard_Integer& theFrameWidth,
122 Standard_Integer& theFrameHeight,
123 const int theViewWidth,
124 const int theViewHeight)
127 // Calculate correct width/height for framebuffer
128 Standard_Real aViewRatio = (Standard_Real)theViewWidth/theViewHeight;
129 fitDimensionsRatio (theFrameWidth, theFrameHeight, aViewRatio);
131 // downscale the framebuffer if it is too large
132 Standard_Real aWidthRate = (Standard_Real)theFrameWidth /theViewWidth;
133 Standard_Real aHeightRate = (Standard_Real)theFrameHeight/theViewHeight;
135 if ((aWidthRate > 1 && aHeightRate > 1 && aWidthRate >= aHeightRate) ||
136 (aWidthRate > 1 && aHeightRate <= 1))
138 theFrameWidth = (Standard_Integer)(theFrameWidth /aWidthRate);
139 theFrameHeight = (Standard_Integer)(theFrameHeight/aWidthRate);
141 else if ((aWidthRate > 1 && aHeightRate > 1 && aWidthRate < aHeightRate) ||
142 (aWidthRate <= 1 && aHeightRate > 1))
144 theFrameWidth = (Standard_Integer)(theFrameWidth /aHeightRate);
145 theFrameHeight = (Standard_Integer)(theFrameHeight/aHeightRate);
150 // ---------------------------------------------------------------
151 // Function: initBufferTiling
152 // Purpose: calculate initialization sizes for frame buffer
153 // when the tile algorithm is selected
154 // ---------------------------------------------------------------
155 static void initBufferTiling (Standard_Integer& theFrameWidth,
156 Standard_Integer &theFrameHeight,
157 const int theViewWidth,
158 const int theViewHeight)
160 // fit framebuffer into the printing area
161 if (theFrameWidth > theViewWidth)
162 theFrameWidth = theViewWidth;
164 if (theFrameHeight > theViewHeight)
165 theFrameHeight = theViewHeight;
168 // ---------------------------------------------------------------
169 // Function: initBitmapBuffer
170 // Purpose: init device independent bitmap to hold printing data
171 // ---------------------------------------------------------------
173 #ifndef HAVE_FREEIMAGE
174 static void initBitmapBuffer (const HDC theMemoryDC,
175 HBITMAP &theMemoryBmp,
176 const Standard_Integer theBmpWidth,
177 const Standard_Integer theBmpHeight,
180 // define compatible bitmap
181 BITMAPINFO aBitmapData;
182 memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
183 aBitmapData.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
184 aBitmapData.bmiHeader.biWidth = theBmpWidth;
185 aBitmapData.bmiHeader.biHeight = theBmpHeight;
186 aBitmapData.bmiHeader.biPlanes = 1;
187 aBitmapData.bmiHeader.biBitCount = 24;
188 aBitmapData.bmiHeader.biXPelsPerMeter = 0;
189 aBitmapData.bmiHeader.biYPelsPerMeter = 0;
190 aBitmapData.bmiHeader.biClrUsed = 0;
191 aBitmapData.bmiHeader.biClrImportant = 0;
192 aBitmapData.bmiHeader.biCompression = BI_RGB;
193 aBitmapData.bmiHeader.biSizeImage = 0;
195 // Create Device Independent Bitmap
196 theMemoryBmp = CreateDIBSection (theMemoryDC, &aBitmapData, DIB_RGB_COLORS,
197 &theBufferPtr, NULL, 0);
200 // ---------------------------------------------------------------
201 // Function: imagePasteDC
202 // Purpose: copy the data from image buffer to the device context
203 // ---------------------------------------------------------------
204 static bool imagePasteDC(HDC theDstDC, FipHandle theImage, int theOffsetX,
205 int theOffsetY, int theWidth, int theHeight,
206 int theLeft = 0, int theTop = 0)
208 // get image parameters
209 BITMAPINFO* aBitmapData = theImage->getInfo ();
210 SetStretchBltMode (theDstDC, STRETCH_HALFTONE);
212 // organize blocks data passing if memory isn't enough to pass all the data
214 int aLinesComplete = 0, aMaxBlockWidth = theHeight, aBlockWidth = 0,
215 aPassed = 0, aInverseLine = 0, aScan = 0;
217 while (aMaxBlockWidth >= 1 && aLinesComplete < theHeight)
219 // how much lines still to pass
220 aBlockWidth = theHeight - aLinesComplete;
222 // normalize count of lines to pass to maximum lines count at one pass.
223 if (aBlockWidth > aMaxBlockWidth)
224 aBlockWidth = aMaxBlockWidth;
226 // access image data at the start scan line, we need to calculate scan from
227 // the bottom of image (image is bottom-left, the src coord is top-left)
228 aInverseLine = theTop + aBlockWidth + aLinesComplete;
229 aScan = theImage->getHeight() - aInverseLine;
230 aDataPtr = theImage->getScanLine (aScan);
234 // try to pass block to the device
237 // instead of banded output we provide blocked as it isn't always passed
238 // to printer as it is expected
239 aPassed = SetDIBitsToDevice (theDstDC, theOffsetX,
240 theOffsetY + aLinesComplete,
241 theWidth, aBlockWidth, theLeft, 0,
243 aDataPtr, aBitmapData, DIB_RGB_COLORS);
245 // if result is bad, try to decrease band width
246 if (aPassed != aBlockWidth)
248 aMaxBlockWidth = aMaxBlockWidth >> 1;
252 aLinesComplete += aBlockWidth;
256 // check for total failure
257 if (aMaxBlockWidth < 1)
263 // ---------------------------------------------------------------
264 // Function: imageStretchDC
265 // Purpose: copy pixels from image to dc by stretching them
266 // ---------------------------------------------------------------
267 static bool imageStretchDC(HDC theDstDC, FipHandle theImage, int theOffsetX,
268 int theOffsetY, int theWidth, int theHeight)
270 // access to raw image data
271 BYTE *aDataPtr = theImage->accessPixels ();
275 // get image parameters
276 unsigned int widthPx = theImage->getWidth ();
277 unsigned int heightPx = theImage->getHeight ();
278 BITMAPINFO* aBitmapData = theImage->getInfo ();
279 SetStretchBltMode (theDstDC, STRETCH_HALFTONE);
281 // pass lines and check if operation is succesfull
283 aPassed = StretchDIBits (theDstDC, theOffsetX, theOffsetY, theWidth,
284 theHeight, 0, 0, widthPx, heightPx, aDataPtr,
285 aBitmapData, DIB_RGB_COLORS, SRCCOPY);
287 if (aPassed != heightPx)
295 // ---------------------------------------------------------------
296 // ---------------------------------------------------------------
299 Standard_Boolean OpenGl_Workspace::Print
300 (const Graphic3d_CView& ACView,
301 const Aspect_CLayer2d& ACUnderLayer,
302 const Aspect_CLayer2d& ACOverLayer,
303 const Aspect_Handle hPrintDC,// const Aspect_Drawable hPrintDC,
304 const Standard_Boolean showBackground,
305 const Standard_CString filename,
306 const Aspect_PrintAlgo printAlgorithm,
307 const Standard_Real theScaleFactor)
313 //MessageBox (NULL, "Print failed: can't setup the view for printing.",
314 // "The operation couldn't be completed.", MB_OK);
315 return Standard_False;
318 // printer page dimensions
319 HDC hPrnDC = (HDC) hPrintDC;
320 int devWidth = GetDeviceCaps (hPrnDC, HORZRES);
321 int devHeight = GetDeviceCaps (hPrnDC, VERTRES);
323 // if context is actually a memory dc, try to retrieve bitmap dimensions
324 // (memory dc could be used for testing purposes)
325 if (GetObjectType (hPrnDC) == OBJ_MEMDC)
327 // memory dc dimensions
329 HBITMAP aMemoryBitmap = (HBITMAP) GetCurrentObject (hPrnDC, OBJ_BITMAP);
331 if (GetObject (aMemoryBitmap, sizeof (BITMAP), &aBitmapInfo))
333 devWidth = aBitmapInfo.bmWidth;
334 devHeight = aBitmapInfo.bmHeight;
338 Standard_Integer tempWidth = (Standard_Integer) devWidth;
339 Standard_Integer tempHeight = (Standard_Integer) devHeight;
342 int viewWidth = myWidth;
343 int viewHeight = myHeight;
344 if (viewWidth == 0 || viewHeight == 0)
346 //MessageBox (NULL, "Print failed: can't setup the view for printing.",
347 // "The operation couldn't be completed.", MB_OK);
348 return Standard_False;
351 // calculate correct width/height ratio
352 Standard_Real viewRatio = (Standard_Real)viewWidth/viewHeight;
353 fitDimensionsRatio(tempWidth, tempHeight, viewRatio);
355 // width and height for printing area
356 int width = (int) (tempWidth * theScaleFactor);
357 int height = (int) (tempHeight * theScaleFactor);
359 // device independent bitmap for the whole view
360 #ifdef HAVE_FREEIMAGE
361 FipHandle aViewImage = NULL;
362 BYTE* aViewBuffer = NULL;
364 HDC hMemDC = CreateCompatibleDC (hPrnDC);
365 HBITMAP hViewBitmap = NULL;
366 HGDIOBJ hViewBitmapOld = NULL;
367 VOID* aViewBuffer = NULL;
370 // Frame buffer initialization
371 OpenGl_FrameBuffer* aFrameBuffer = NULL;
372 OpenGl_FrameBuffer* aPrevBuffer = (OpenGl_FrameBuffer*) ACView.ptrFBO;
373 Standard_Integer aFrameWidth (0), aFrameHeight (0),
374 aPrevBufferX (0), aPrevBufferY (0);
376 bool IsTiling = (printAlgorithm == 1);
378 // try to use existing frame buffer
381 GLsizei aPrevWidth = aPrevBuffer->GetSizeX();
382 GLsizei aPrevHeight = aPrevBuffer->GetSizeY();
383 bool isUsable = false;
385 // check if its possible to use previous frame buffer
386 if (!IsTiling && aPrevWidth >= width && aPrevHeight >= height)
388 aFrameWidth = (Standard_Integer) width;
389 aFrameHeight = (Standard_Integer) height;
394 getDimensionsTiling (aFrameWidth, aFrameHeight, width, height);
395 if (aPrevWidth >= aFrameWidth && aPrevHeight >= aFrameHeight)
399 // if it is enough memory for image paste dc operation
402 #ifdef HAVE_FREEIMAGE
403 // try to allocate fipImage and necessary resources
404 fipImage* anImagePtr = new fipImage (FIT_BITMAP, aFrameWidth,
407 // if allocated succesfully
408 if (anImagePtr->isValid())
410 aViewImage = anImagePtr;
411 aViewBuffer = aViewImage->accessPixels ();
423 // try to allocate compatible bitmap and necessary resources
424 initBitmapBuffer (hMemDC, hViewBitmap,
425 aFrameWidth, aFrameHeight, aViewBuffer);
430 DeleteObject (hViewBitmap);
434 hViewBitmapOld = SelectObject (hMemDC, hViewBitmap);
438 // use previous frame buffer
441 aPrevBufferX = aPrevWidth;
442 aPrevBufferY = aPrevHeight;
443 aFrameBuffer = aPrevBuffer;
444 aFrameBuffer->ChangeViewport (aFrameWidth, aFrameHeight);
448 // if previous buffer cannot be used, try to init a new one
451 aFrameBuffer = new OpenGl_FrameBuffer();
453 // try to create the framebuffer with the best possible size
454 Standard_Integer aMaxWidth(0), aMaxHeight(0);
455 getMaxFrameSize (aMaxWidth, aMaxHeight);
456 while (aMaxWidth > 1 && aMaxHeight > 1)
458 aFrameWidth = aMaxWidth;
459 aFrameHeight = aMaxHeight;
461 // calculate dimensions for different printing algorithms
463 initBufferStretch (aFrameWidth, aFrameHeight, width, height);
465 initBufferTiling (aFrameWidth, aFrameHeight, width, height);
467 // try to initialize framebuffer
468 if (aFrameBuffer->Init (GetGlContext(), aFrameWidth, aFrameHeight))
470 #ifdef HAVE_FREEIMAGE
471 // try to allocate fipImage and necessary resources
472 fipImage* anImagePtr = new fipImage (FIT_BITMAP, aFrameWidth,
475 // if allocated succesfully
476 if (anImagePtr->isValid())
478 aViewImage = anImagePtr;
479 aViewBuffer = aViewImage->accessPixels ();
486 aFrameBuffer->Release (GetGlContext());
493 // try to allocate compatible bitmap and necessary resources
494 initBitmapBuffer (hMemDC, hViewBitmap,
495 aFrameWidth, aFrameHeight, aViewBuffer);
499 DeleteObject (hViewBitmap);
500 aFrameBuffer->Release (GetGlContext());
505 hViewBitmapOld = SelectObject (hMemDC, hViewBitmap);
511 // not initialized, decrease dimensions
512 aMaxWidth = aMaxWidth >> 1;
513 aMaxHeight = aMaxHeight >> 1;
516 // check if there are proper dimensions
517 if (aMaxWidth <= 1 || aMaxHeight <= 1)
519 MessageBox (NULL, "Print failed: can't allocate buffer for printing.",
520 "The operation couldn't be completed.", MB_OK);
524 #ifndef HAVE_FREEIMAGE
529 return Standard_False;
533 // setup printing context and viewport
534 GLint aViewPortBack[4];
535 GLint anAlignBack = 1;
537 OpenGl_PrinterContext aPrinterContext (GetGContext());
538 aPrinterContext.SetLayerViewport ((GLsizei)aFrameWidth,
539 (GLsizei)aFrameHeight);
540 glGetIntegerv (GL_VIEWPORT, aViewPortBack);
541 glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack);
542 glPixelStorei (GL_PACK_ALIGNMENT, 4);
544 // start document if the printer context is not actually a memory dc
545 // (memory dc could be used for testing purposes)
547 if (GetObjectType (hPrnDC) == OBJ_DC)
549 // Initalize printing procedure
550 di.cbSize = sizeof(DOCINFO);
551 di.lpszDocName = "Open Cascade Document - print v3d view";
552 di.lpszOutput = filename;
554 // if can't print the document
555 if (StartDoc (hPrnDC, &di) <= 0 || StartPage (hPrnDC) <= 0)
557 MessageBox (NULL, "Print failed: printer can't start operation.",
558 "The operation couldn't be completed.", MB_OK);
559 #ifndef HAVE_FREEIMAGE
562 SelectObject (hMemDC, hViewBitmapOld);
563 DeleteObject (hViewBitmap);
568 return Standard_False;
572 // activate the offscreen buffer
573 aFrameBuffer->BindBuffer (GetGlContext());
575 // calculate offset for centered printing
576 int aDevOffx = (int)(devWidth - width) /2;
577 int aDevOffy = (int)(devHeight - height)/2;
579 // operation complete flag
582 // Set up status for printing
584 NamedStatus |= OPENGL_NS_WHITEBACK;
588 aPrinterContext.SetScale ((GLfloat)aFrameWidth /viewWidth,
589 (GLfloat)aFrameHeight/viewHeight);
590 aFrameBuffer->SetupViewport ();
591 Redraw1(ACView, ACUnderLayer, ACOverLayer, 0);
592 if (!myTransientDrawToFront)
594 // render to FBO only if allowed to render to back buffer
595 RedrawImmediatMode();
597 glReadPixels (0, 0, aFrameWidth, aFrameHeight,
598 GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
600 // copy result to the printer device and check for errors
601 #ifdef HAVE_FREEIMAGE
602 if (!aViewImage->rescale(width, height, FILTER_BICUBIC) ||
603 !imagePasteDC (hPrnDC, aViewImage, aDevOffx, aDevOffy, width, height))
604 isDone = imageStretchDC (hPrnDC, aViewImage, aDevOffx, aDevOffy,
607 if (width > aFrameWidth && height > aFrameHeight)
609 SetStretchBltMode (hPrnDC, STRETCH_HALFTONE);
610 isDone = (StretchBlt (hPrnDC, aDevOffx, aDevOffy, width, height,
611 hMemDC, 0, 0, aFrameWidth, aFrameHeight, SRCCOPY) != 0); // to avoid warning C4800
615 isDone = (BitBlt (hPrnDC, aDevOffx, aDevOffy, width, height,
616 hMemDC, 0, 0, SRCCOPY) != 0); // to avoid warning C4800
622 // calculate total count of frames and cropping size
623 Standard_Integer aPxCropx = 0;
624 Standard_Integer aPxCropy = 0;
625 Standard_Integer aTotalx =
626 (Standard_Integer)floor ((float)width /aFrameWidth);
627 Standard_Integer aTotaly =
628 (Standard_Integer)floor ((float)height/aFrameHeight);
629 if (width %aFrameWidth != 0)
631 aPxCropx = (aFrameWidth - width%aFrameWidth)/2;
634 if (height%aFrameHeight != 0)
636 aPxCropy = (aFrameHeight - height%aFrameHeight)/2;
640 int anOddPixelx = (width %aFrameWidth) %2;
641 int anOddPixely = (height%aFrameHeight)%2;
643 // calculate scale factor for full frames
644 Standard_Real aScalex = (Standard_Real)width /aFrameWidth;
645 Standard_Real aScaley = (Standard_Real)height/aFrameHeight;
647 // calculate and set the text scaling factor for printing context
648 GLfloat aScaleRatex = (GLfloat)aFrameWidth /viewWidth;
649 GLfloat aScaleRatey = (GLfloat)aFrameHeight/viewHeight;
650 aPrinterContext.SetScale (aScaleRatex*(GLfloat)aScalex,
651 aScaleRatey*(GLfloat)aScaley);
653 // initialize projection matrix for printer context
654 TColStd_Array2OfReal aProj (0, 3, 0, 3);
655 Standard_Real aDef = 0;
660 // projection matrix offsets for printer context
661 // offsets are even numbers
662 Standard_Real aOffsetx(0), aOffsety(0);
663 aOffsetx = -(aTotalx-1);
664 aOffsety = -(aTotaly-1);
666 // rect of frame image that will be copied
667 // and coordinates in view image where to put it
668 Standard_Integer aLeft = 0, aRight = 0, aBottom = 0, aTop = 0;
669 Standard_Integer aSubLeft = (Standard_Integer)aDevOffx;
670 Standard_Integer aSubTop = (Standard_Integer)aDevOffy;
672 // draw sequence of full frames
673 for (int i = 0; i < aTotalx; i++)
675 // offsets are even numbers
676 aOffsety = -(aTotaly-1);
677 aSubTop = (Standard_Integer)aDevOffy;
679 // calculate cropped frame rect
680 aLeft = (i == 0) ? aPxCropx : 0;
681 aRight = (i == aTotalx-1) ? aFrameWidth-(aPxCropx+anOddPixelx) :
684 for (int j = 0; j < aTotaly; j++)
686 // no offset for single frames
687 aProj(3,0) = (aTotalx == 1) ? 0 : -aOffsetx;
688 aProj(3,1) = (aTotaly == 1) ? 0 : aOffsety;
690 // set projection matrix
691 aProj(0,0) = aScalex;
692 aProj(1,1) = aScaley;
693 aPrinterContext.SetProjTransformation (aProj);
695 // calculate cropped frame rect
696 aTop = (j == 0) ? aPxCropy : 0;
697 aBottom = (j == aTotaly-1) ? aFrameHeight-(aPxCropy+anOddPixely) :
700 // draw to the offscreen buffer and capture the result
701 aFrameBuffer->SetupViewport ();
702 Redraw1(ACView, ACUnderLayer, ACOverLayer, 0);
703 if (!myTransientDrawToFront)
705 // render to FBO only if forces to render to back buffer
706 RedrawImmediatMode();
708 glReadPixels (0, 0, aFrameWidth, aFrameHeight,
709 GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
710 #ifdef HAVE_FREEIMAGE
711 // cut out pixels that are out of printing area
712 isDone = imagePasteDC (hPrnDC, aViewImage, aSubLeft, aSubTop,
713 aRight-aLeft, aBottom-aTop, aLeft, aTop);
715 isDone = (BitBlt (hPrnDC, aSubLeft, aSubTop, aRight-aLeft, aBottom-aTop,
716 hMemDC, aLeft, aTop, SRCCOPY) != 0); // to avoid warning C4800
719 // stop operation if errors
723 // calculate new view offset for y-coordinate
725 aSubTop += aBottom-aTop;
728 // stop operation if errors
732 // calculate new view offset for x-coordinate
734 aSubLeft += aRight-aLeft;
738 // complete printing or indicate an error
739 if (GetObjectType (hPrnDC) == OBJ_DC && isDone == true)
744 else if (isDone == false)
746 MessageBox (NULL, "Print failed: insufficient memory or spool error.\nPlease use smaller printer resolution.",
747 "The opeartion couldn't be completed.", MB_OK);
748 if (GetObjectType (hPrnDC) == OBJ_DC)
752 // return OpenGl to the previous state
753 aPrinterContext.Deactivate ();
754 glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack);
755 aFrameBuffer->UnbindBuffer (GetGlContext());
756 glViewport (aViewPortBack[0], aViewPortBack[1],
757 aViewPortBack[2], aViewPortBack[3]);
760 aPrevBuffer->ChangeViewport (aPrevBufferX, aPrevBufferY);
764 aFrameBuffer->Release (GetGlContext ());
769 #ifndef HAVE_FREEIMAGE
772 SelectObject (hMemDC, hViewBitmapOld);
773 DeleteObject (hViewBitmap);
778 // Reset status after printing
779 NamedStatus &= ~OPENGL_NS_WHITEBACK;
781 return (Standard_Boolean) isDone;
784 return Standard_False;
788 /*----------------------------------------------------------------------*/
791 void OpenGl_Workspace::Redraw1 (const Graphic3d_CView& ACView,
792 const Aspect_CLayer2d& ACUnderLayer,
793 const Aspect_CLayer2d& ACOverLayer,
796 if (myDisplay.IsNull() || myView.IsNull())
799 myDisplay->UpdateUserMarkers();
801 // Request reset of material
802 NamedStatus |= OPENGL_NS_RESMAT;
804 /* GL_DITHER on/off pour le background */
806 glEnable (GL_DITHER);
808 glDisable (GL_DITHER);
810 GLbitfield toClear = GL_COLOR_BUFFER_BIT;
813 glDepthFunc(GL_LEQUAL);
814 glDepthMask(GL_TRUE);
816 // SAV checking if depth test was deprecated somewhere outside
817 if ( myUseDepthTest )
818 glEnable(GL_DEPTH_TEST);
820 glDisable(GL_DEPTH_TEST);
823 toClear |= GL_DEPTH_BUFFER_BIT;
827 glDisable(GL_DEPTH_TEST);
830 if ( NamedStatus & OPENGL_NS_WHITEBACK )
832 // Set background to white
833 glClearColor (1.F, 1.F, 1.F, 1.F);
834 toClear |= GL_DEPTH_BUFFER_BIT;
838 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.F);
842 Handle(OpenGl_Workspace) aWS(this);
843 myView->Render(aWS,ACView,ACUnderLayer,ACOverLayer);
848 GetGlContext()->SwapBuffers();
849 myBackBufferRestored = Standard_False;
855 /*----------------------------------------------------------------------*/
858 void OpenGl_Workspace::CopyBuffers (const Standard_Boolean theFrontToBack)
862 myBackBufferRestored = Standard_False;
865 glMatrixMode (GL_PROJECTION);
868 gluOrtho2D ((GLdouble) 0., (GLdouble) myWidth, 0., (GLdouble) myHeight);
869 glMatrixMode (GL_MODELVIEW);
875 glDrawBuffer (theFrontToBack ? GL_BACK : GL_FRONT);
876 glReadBuffer (theFrontToBack ? GL_FRONT : GL_BACK);
878 glRasterPos2i (0, 0);
879 glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR);
883 glMatrixMode (GL_PROJECTION);
885 glMatrixMode (GL_MODELVIEW);
888 glDrawBuffer (GL_BACK);
891 /*----------------------------------------------------------------------*/
893 //call_subr_displayCB
894 void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
897 if (theCView.GDisplayCB == NULL)
902 Aspect_GraphicCallbackStruct aCallData;
903 aCallData.reason = theReason;
904 aCallData.glContext = GetGlContext();
905 aCallData.wsID = theCView.WsId;
906 aCallData.viewID = theCView.ViewId;
907 theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
910 /*----------------------------------------------------------------------*/