1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_GlCore11.hxx>
18 #include <OpenGl_FrameBuffer.hxx>
19 #include <TColStd_Array2OfReal.hxx>
20 #include <OpenGl_telem_util.hxx>
26 #if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_FREEIMAGE)
27 #include <NCollection_Handle.hxx>
28 #include <FreeImagePlus.h>
30 #pragma comment( lib, "FreeImage.lib" )
31 #pragma comment( lib, "FreeImagePlus.lib" )
33 typedef NCollection_Handle<fipImage> FipHandle;
36 #include <OpenGl_PrinterContext.hxx>
37 #include <OpenGl_Workspace.hxx>
38 #include <OpenGl_View.hxx>
39 #include <OpenGl_Display.hxx>
41 //10-05-96 : CAL ; Ajout d'un nouveau delta dans les copies de pixels (voir CALL_DEF_DELTA)
42 #define CALL_DEF_DELTA 10
44 // ---------------------------------------------------------------
45 // Function: getNearestPowOfTwo
46 // Purpose: get the nearest power of two for theNumber
47 // ---------------------------------------------------------------
48 static GLsizei getNearestPowOfTwo (const GLsizei theNumber)
51 for (GLsizei p2 = 1; p2 <= theNumber; aLast = p2, p2 <<= 1);
55 // ---------------------------------------------------------------
56 // Function: fitDimensionsRatio
57 // Purpose: calculate correct width/height ratio for theWidth and
58 // theHeight parameters
59 // ---------------------------------------------------------------
60 static void fitDimensionsRatio (Standard_Integer& theWidth,
61 Standard_Integer& theHeight,
62 const Standard_Real theViewRatio)
64 // set dimensions in accordance with the viewratio
65 if (theHeight < theWidth/theViewRatio)
66 theWidth = (Standard_Integer)(theHeight*theViewRatio);
68 if (theWidth < theHeight*theViewRatio)
69 theHeight = (Standard_Integer)(theWidth/theViewRatio);
72 // ---------------------------------------------------------------
73 // Function: initBitmapBuffer
74 // Purpose: init device independent bitmap to hold printing data
75 // ---------------------------------------------------------------
77 #ifndef HAVE_FREEIMAGE
78 static void initBitmapBuffer (const HDC theMemoryDC,
79 HBITMAP &theMemoryBmp,
80 const Standard_Integer theBmpWidth,
81 const Standard_Integer theBmpHeight,
84 // define compatible bitmap
85 BITMAPINFO aBitmapData;
86 memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
87 aBitmapData.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
88 aBitmapData.bmiHeader.biWidth = theBmpWidth;
89 aBitmapData.bmiHeader.biHeight = theBmpHeight;
90 aBitmapData.bmiHeader.biPlanes = 1;
91 aBitmapData.bmiHeader.biBitCount = 24;
92 aBitmapData.bmiHeader.biXPelsPerMeter = 0;
93 aBitmapData.bmiHeader.biYPelsPerMeter = 0;
94 aBitmapData.bmiHeader.biClrUsed = 0;
95 aBitmapData.bmiHeader.biClrImportant = 0;
96 aBitmapData.bmiHeader.biCompression = BI_RGB;
97 aBitmapData.bmiHeader.biSizeImage = 0;
99 // Create Device Independent Bitmap
100 theMemoryBmp = CreateDIBSection (theMemoryDC, &aBitmapData, DIB_RGB_COLORS,
101 &theBufferPtr, NULL, 0);
104 // ---------------------------------------------------------------
105 // Function: imagePasteDC
106 // Purpose: copy the data from image buffer to the device context
107 // ---------------------------------------------------------------
108 static bool imagePasteDC(HDC theDstDC, FipHandle theImage, int theOffsetX,
109 int theOffsetY, int theWidth, int theHeight,
110 int theLeft = 0, int theTop = 0)
112 // get image parameters
113 BITMAPINFO* aBitmapData = theImage->getInfo ();
114 SetStretchBltMode (theDstDC, STRETCH_HALFTONE);
116 // organize blocks data passing if memory isn't enough to pass all the data
118 int aLinesComplete = 0, aMaxBlockWidth = theHeight, aBlockWidth = 0,
119 aPassed = 0, aInverseLine = 0, aScan = 0;
121 while (aMaxBlockWidth >= 1 && aLinesComplete < theHeight)
123 // how much lines still to pass
124 aBlockWidth = theHeight - aLinesComplete;
126 // normalize count of lines to pass to maximum lines count at one pass.
127 if (aBlockWidth > aMaxBlockWidth)
128 aBlockWidth = aMaxBlockWidth;
130 // access image data at the start scan line, we need to calculate scan from
131 // the bottom of image (image is bottom-left, the src coord is top-left)
132 aInverseLine = theTop + aBlockWidth + aLinesComplete;
133 aScan = theImage->getHeight() - aInverseLine;
134 aDataPtr = theImage->getScanLine (aScan);
138 // try to pass block to the device
141 // instead of banded output we provide blocked as it isn't always passed
142 // to printer as it is expected
143 aPassed = SetDIBitsToDevice (theDstDC, theOffsetX,
144 theOffsetY + aLinesComplete,
145 theWidth, aBlockWidth, theLeft, 0,
147 aDataPtr, aBitmapData, DIB_RGB_COLORS);
149 // if result is bad, try to decrease band width
150 if (aPassed != aBlockWidth)
152 aMaxBlockWidth = aMaxBlockWidth >> 1;
156 aLinesComplete += aBlockWidth;
160 // check for total failure
161 if (aMaxBlockWidth < 1)
167 // ---------------------------------------------------------------
168 // Function: imageStretchDC
169 // Purpose: copy pixels from image to dc by stretching them
170 // ---------------------------------------------------------------
171 static bool imageStretchDC(HDC theDstDC, FipHandle theImage, int theOffsetX,
172 int theOffsetY, int theWidth, int theHeight)
174 // access to raw image data
175 BYTE *aDataPtr = theImage->accessPixels ();
179 // get image parameters
180 unsigned int widthPx = theImage->getWidth ();
181 unsigned int heightPx = theImage->getHeight ();
182 BITMAPINFO* aBitmapData = theImage->getInfo ();
183 SetStretchBltMode (theDstDC, STRETCH_HALFTONE);
185 // pass lines and check if operation is succesfull
187 aPassed = StretchDIBits (theDstDC, theOffsetX, theOffsetY, theWidth,
188 theHeight, 0, 0, widthPx, heightPx, aDataPtr,
189 aBitmapData, DIB_RGB_COLORS, SRCCOPY);
191 if ((unsigned)aPassed != heightPx)
198 // ---------------------------------------------------------------
199 // Function: getMaxFrameSize
200 // Purpose: get the maximum possible frame size
201 // ---------------------------------------------------------------
202 static void getMaxFrameSize(Standard_Integer& theWidth,
203 Standard_Integer& theHeight)
205 GLsizei aMaxX, aMaxY;
207 GLint aTexDim = 2048;
208 glGetIntegerv (GL_MAX_VIEWPORT_DIMS, (GLint*) &aVpDim);
209 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &aTexDim);
210 (aVpDim[0] >= aTexDim) ? aMaxX = (GLsizei) aTexDim :
211 aMaxX = getNearestPowOfTwo((GLsizei)aVpDim[0]);
212 (aVpDim[1] >= aTexDim) ? aMaxY = (GLsizei) aTexDim :
213 aMaxY = getNearestPowOfTwo((GLsizei)aVpDim[1]);
215 theWidth = (Standard_Integer)aMaxX;
216 theHeight = (Standard_Integer)aMaxY;
219 // ---------------------------------------------------------------
220 // Function: initBufferStretch
221 // Purpose: calculate initialization sizes for frame buffer
222 // when the stretch algorithm is selected
223 // ---------------------------------------------------------------
224 static void initBufferStretch (Standard_Integer& theFrameWidth,
225 Standard_Integer& theFrameHeight,
226 const int theViewWidth,
227 const int theViewHeight)
230 // Calculate correct width/height for framebuffer
231 Standard_Real aViewRatio = (Standard_Real)theViewWidth/theViewHeight;
232 fitDimensionsRatio (theFrameWidth, theFrameHeight, aViewRatio);
234 // downscale the framebuffer if it is too large
235 Standard_Real aWidthRate = (Standard_Real)theFrameWidth /theViewWidth;
236 Standard_Real aHeightRate = (Standard_Real)theFrameHeight/theViewHeight;
238 if ((aWidthRate > 1 && aHeightRate > 1 && aWidthRate >= aHeightRate) ||
239 (aWidthRate > 1 && aHeightRate <= 1))
241 theFrameWidth = (Standard_Integer)(theFrameWidth /aWidthRate);
242 theFrameHeight = (Standard_Integer)(theFrameHeight/aWidthRate);
244 else if ((aWidthRate > 1 && aHeightRate > 1 && aWidthRate < aHeightRate) ||
245 (aWidthRate <= 1 && aHeightRate > 1))
247 theFrameWidth = (Standard_Integer)(theFrameWidth /aHeightRate);
248 theFrameHeight = (Standard_Integer)(theFrameHeight/aHeightRate);
251 // ---------------------------------------------------------------
252 // Function: initBufferTiling
253 // Purpose: calculate initialization sizes for frame buffer
254 // when the tile algorithm is selected
255 // ---------------------------------------------------------------
256 static void initBufferTiling (Standard_Integer& theFrameWidth,
257 Standard_Integer &theFrameHeight,
258 const int theViewWidth,
259 const int theViewHeight)
261 // fit framebuffer into the printing area
262 if (theFrameWidth > theViewWidth)
263 theFrameWidth = theViewWidth;
265 if (theFrameHeight > theViewHeight)
266 theFrameHeight = theViewHeight;
270 // ---------------------------------------------------------------
271 // ---------------------------------------------------------------
275 Standard_Boolean OpenGl_Workspace::Print
276 (const Handle(OpenGl_PrinterContext)& thePrintContext,
277 const Graphic3d_CView& ACView,
278 const Aspect_CLayer2d& ACUnderLayer,
279 const Aspect_CLayer2d& ACOverLayer,
280 const Aspect_Handle hPrintDC,// const Aspect_Drawable hPrintDC,
281 const Standard_Boolean showBackground,
282 const Standard_CString filename,
283 const Aspect_PrintAlgo printAlgorithm,
284 const Standard_Real theScaleFactor)
286 if (thePrintContext.IsNull())
288 return Standard_False;
295 //MessageBox (NULL, "Print failed: can't setup the view for printing.",
296 // "The operation couldn't be completed.", MB_OK);
297 return Standard_False;
300 // printer page dimensions
301 HDC hPrnDC = (HDC) hPrintDC;
302 int devWidth = GetDeviceCaps (hPrnDC, HORZRES);
303 int devHeight = GetDeviceCaps (hPrnDC, VERTRES);
305 // if context is actually a memory dc, try to retrieve bitmap dimensions
306 // (memory dc could be used for testing purposes)
307 if (GetObjectType (hPrnDC) == OBJ_MEMDC)
309 // memory dc dimensions
311 HBITMAP aMemoryBitmap = (HBITMAP) GetCurrentObject (hPrnDC, OBJ_BITMAP);
313 if (GetObject (aMemoryBitmap, sizeof (BITMAP), &aBitmapInfo))
315 devWidth = aBitmapInfo.bmWidth;
316 devHeight = aBitmapInfo.bmHeight;
320 Standard_Integer tempWidth = (Standard_Integer) devWidth;
321 Standard_Integer tempHeight = (Standard_Integer) devHeight;
324 int viewWidth = myWidth;
325 int viewHeight = myHeight;
326 if (viewWidth == 0 || viewHeight == 0)
328 //MessageBox (NULL, "Print failed: can't setup the view for printing.",
329 // "The operation couldn't be completed.", MB_OK);
330 return Standard_False;
333 // calculate correct width/height ratio
334 Standard_Real viewRatio = (Standard_Real)viewWidth/viewHeight;
335 fitDimensionsRatio(tempWidth, tempHeight, viewRatio);
337 // width and height for printing area
338 int width = (int) (tempWidth * theScaleFactor);
339 int height = (int) (tempHeight * theScaleFactor);
341 // device independent bitmap for the whole view
342 #ifdef HAVE_FREEIMAGE
343 FipHandle aViewImage = NULL;
344 BYTE* aViewBuffer = NULL;
346 HDC hMemDC = CreateCompatibleDC (hPrnDC);
347 HBITMAP hViewBitmap = NULL;
348 HGDIOBJ hViewBitmapOld = NULL;
349 VOID* aViewBuffer = NULL;
352 // Frame buffer initialization
353 OpenGl_FrameBuffer* aFrameBuffer = NULL;
354 OpenGl_FrameBuffer* aPrevBuffer = (OpenGl_FrameBuffer*) ACView.ptrFBO;
355 Standard_Integer aFrameWidth (0), aFrameHeight (0),
356 aPrevBufferX (0), aPrevBufferY (0);
358 bool IsTiling = (printAlgorithm == 1);
360 // try to use existing frame buffer
363 GLsizei aPrevWidth = aPrevBuffer->GetSizeX();
364 GLsizei aPrevHeight = aPrevBuffer->GetSizeY();
365 bool isUsable = false;
367 // check if its possible to use previous frame buffer
368 if (!IsTiling && aPrevWidth >= width && aPrevHeight >= height)
370 aFrameWidth = (Standard_Integer) width;
371 aFrameHeight = (Standard_Integer) height;
376 // use previous frame buffer with its dimensions
377 aFrameWidth = aPrevWidth;
378 aFrameHeight = aPrevHeight;
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().operator->());
476 // try to allocate compatible bitmap and necessary resources
477 initBitmapBuffer (hMemDC, hViewBitmap,
478 aFrameWidth, aFrameHeight, aViewBuffer);
482 DeleteObject (hViewBitmap);
483 aFrameBuffer->Release (GetGlContext().operator->());
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 myPrintContext = thePrintContext;
518 GLint aViewPortBack[4];
519 GLint anAlignBack = 1;
520 myPrintContext->SetLayerViewport ((GLsizei )aFrameWidth,
521 (GLsizei )aFrameHeight);
522 glGetIntegerv (GL_VIEWPORT, aViewPortBack);
523 glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack);
524 glPixelStorei (GL_PACK_ALIGNMENT, 4);
526 // start document if the printer context is not actually a memory dc
527 // (memory dc could be used for testing purposes)
529 if (GetObjectType (hPrnDC) == OBJ_DC)
531 // Initalize printing procedure
532 di.cbSize = sizeof(DOCINFO);
533 di.lpszDocName = "Open Cascade Document - print v3d view";
534 di.lpszOutput = filename;
536 // if can't print the document
537 if (StartDoc (hPrnDC, &di) <= 0 || StartPage (hPrnDC) <= 0)
539 MessageBox (NULL, "Print failed: printer can't start operation.",
540 "The operation couldn't be completed.", MB_OK);
541 #ifndef HAVE_FREEIMAGE
544 SelectObject (hMemDC, hViewBitmapOld);
545 DeleteObject (hViewBitmap);
550 myPrintContext.Nullify();
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 myPrintContext->SetScale ((GLfloat )aFrameWidth /viewWidth,
572 (GLfloat )aFrameHeight/viewHeight);
573 aFrameBuffer->SetupViewport (GetGlContext());
574 Redraw1(ACView, ACUnderLayer, ACOverLayer, 0);
575 if (!myTransientDrawToFront)
577 // render to FBO only if allowed to render to back buffer
578 RedrawImmediatMode();
580 glReadPixels (0, 0, aFrameWidth, aFrameHeight,
581 GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
583 // copy result to the printer device and check for errors
584 #ifdef HAVE_FREEIMAGE
585 if (!aViewImage->rescale(width, height, FILTER_BICUBIC) ||
586 !imagePasteDC (hPrnDC, aViewImage, aDevOffx, aDevOffy, width, height))
587 isDone = imageStretchDC (hPrnDC, aViewImage, aDevOffx, aDevOffy,
590 if (width > aFrameWidth && height > aFrameHeight)
592 SetStretchBltMode (hPrnDC, STRETCH_HALFTONE);
593 isDone = (StretchBlt (hPrnDC, aDevOffx, aDevOffy, width, height,
594 hMemDC, 0, 0, aFrameWidth, aFrameHeight, SRCCOPY) != 0); // to avoid warning C4800
598 isDone = (BitBlt (hPrnDC, aDevOffx, aDevOffy, width, height,
599 hMemDC, 0, 0, SRCCOPY) != 0); // to avoid warning C4800
605 // calculate total count of frames and cropping size
606 Standard_Integer aPxCropx = 0;
607 Standard_Integer aPxCropy = 0;
608 Standard_Integer aTotalx =
609 (Standard_Integer)floor ((float)width /aFrameWidth);
610 Standard_Integer aTotaly =
611 (Standard_Integer)floor ((float)height/aFrameHeight);
612 if (width %aFrameWidth != 0)
614 aPxCropx = (aFrameWidth - width%aFrameWidth)/2;
617 if (height%aFrameHeight != 0)
619 aPxCropy = (aFrameHeight - height%aFrameHeight)/2;
623 int anOddPixelx = (width %aFrameWidth) %2;
624 int anOddPixely = (height%aFrameHeight)%2;
626 // calculate scale factor for full frames
627 Standard_Real aScalex = (Standard_Real)width /aFrameWidth;
628 Standard_Real aScaley = (Standard_Real)height/aFrameHeight;
630 // calculate and set the text scaling factor for printing context
631 GLfloat aScaleRatex = (GLfloat)aFrameWidth /viewWidth;
632 GLfloat aScaleRatey = (GLfloat)aFrameHeight/viewHeight;
633 myPrintContext->SetScale (aScaleRatex * (GLfloat )aScalex,
634 aScaleRatey * (GLfloat )aScaley);
636 // initialize projection matrix for printer context
637 TColStd_Array2OfReal aProj (0, 3, 0, 3);
638 Standard_Real aDef = 0;
643 // projection matrix offsets for printer context
644 // offsets are even numbers
645 Standard_Real aOffsetx(0), aOffsety(0);
646 aOffsetx = -(aTotalx-1);
647 aOffsety = -(aTotaly-1);
649 // rect of frame image that will be copied
650 // and coordinates in view image where to put it
651 Standard_Integer aLeft = 0, aRight = 0, aBottom = 0, aTop = 0;
652 Standard_Integer aSubLeft = (Standard_Integer)aDevOffx;
653 Standard_Integer aSubTop = (Standard_Integer)aDevOffy;
655 // draw sequence of full frames
656 for (int i = 0; i < aTotalx; i++)
658 // offsets are even numbers
659 aOffsety = -(aTotaly-1);
660 aSubTop = (Standard_Integer)aDevOffy;
662 // calculate cropped frame rect
663 aLeft = (i == 0) ? aPxCropx : 0;
664 aRight = (i == aTotalx-1) ? aFrameWidth-(aPxCropx+anOddPixelx) :
667 for (int j = 0; j < aTotaly; j++)
669 // no offset for single frames
670 aProj(3,0) = (aTotalx == 1) ? 0 : -aOffsetx;
671 aProj(3,1) = (aTotaly == 1) ? 0 : aOffsety;
673 // set projection matrix
674 aProj(0,0) = aScalex;
675 aProj(1,1) = aScaley;
676 myPrintContext->SetProjTransformation (aProj);
678 // calculate cropped frame rect
679 aTop = (j == 0) ? aPxCropy : 0;
680 aBottom = (j == aTotaly-1) ? aFrameHeight-(aPxCropy+anOddPixely) :
683 // draw to the offscreen buffer and capture the result
684 aFrameBuffer->SetupViewport (GetGlContext());
685 Redraw1(ACView, ACUnderLayer, ACOverLayer, 0);
686 if (!myTransientDrawToFront)
688 // render to FBO only if forces to render to back buffer
689 RedrawImmediatMode();
691 glReadPixels (0, 0, aFrameWidth, aFrameHeight,
692 GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
693 #ifdef HAVE_FREEIMAGE
694 // cut out pixels that are out of printing area
695 isDone = imagePasteDC (hPrnDC, aViewImage, aSubLeft, aSubTop,
696 aRight-aLeft, aBottom-aTop, aLeft, aTop);
698 isDone = (BitBlt (hPrnDC, aSubLeft, aSubTop, aRight-aLeft, aBottom-aTop,
699 hMemDC, aLeft, aTop, SRCCOPY) != 0); // to avoid warning C4800
702 // stop operation if errors
706 // calculate new view offset for y-coordinate
708 aSubTop += aBottom-aTop;
711 // stop operation if errors
715 // calculate new view offset for x-coordinate
717 aSubLeft += aRight-aLeft;
721 // complete printing or indicate an error
722 if (GetObjectType (hPrnDC) == OBJ_DC && isDone == true)
727 else if (isDone == false)
729 MessageBox (NULL, "Print failed: insufficient memory or spool error.\nPlease use smaller printer resolution.",
730 "The opeartion couldn't be completed.", MB_OK);
731 if (GetObjectType (hPrnDC) == OBJ_DC)
735 // return OpenGl to the previous state
736 glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack);
737 aFrameBuffer->UnbindBuffer (GetGlContext());
738 glViewport (aViewPortBack[0], aViewPortBack[1],
739 aViewPortBack[2], aViewPortBack[3]);
742 aPrevBuffer->ChangeViewport (aPrevBufferX, aPrevBufferY);
746 aFrameBuffer->Release (GetGlContext().operator->());
751 #ifndef HAVE_FREEIMAGE
754 SelectObject (hMemDC, hViewBitmapOld);
755 DeleteObject (hViewBitmap);
760 // Reset status after printing
761 NamedStatus &= ~OPENGL_NS_WHITEBACK;
763 myPrintContext.Nullify();
764 return (Standard_Boolean) isDone;
767 myPrintContext.Nullify();
768 return Standard_False;
772 /*----------------------------------------------------------------------*/
775 void OpenGl_Workspace::Redraw1 (const Graphic3d_CView& ACView,
776 const Aspect_CLayer2d& ACUnderLayer,
777 const Aspect_CLayer2d& ACOverLayer,
780 if (myDisplay.IsNull() || myView.IsNull())
783 // Request reset of material
784 NamedStatus |= OPENGL_NS_RESMAT;
786 /* GL_DITHER on/off pour le background */
788 glEnable (GL_DITHER);
790 glDisable (GL_DITHER);
792 GLbitfield toClear = GL_COLOR_BUFFER_BIT;
795 glDepthFunc(GL_LEQUAL);
796 glDepthMask(GL_TRUE);
798 // SAV checking if depth test was deprecated somewhere outside
799 if ( myUseDepthTest )
800 glEnable(GL_DEPTH_TEST);
802 glDisable(GL_DEPTH_TEST);
805 toClear |= GL_DEPTH_BUFFER_BIT;
809 glDisable(GL_DEPTH_TEST);
812 if ( NamedStatus & OPENGL_NS_WHITEBACK )
814 // Set background to white
815 glClearColor (1.F, 1.F, 1.F, 1.F);
816 toClear |= GL_DEPTH_BUFFER_BIT;
820 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.F);
824 Handle(OpenGl_Workspace) aWS(this);
825 myView->Render (myPrintContext, aWS, ACView, ACUnderLayer, ACOverLayer);
830 GetGlContext()->SwapBuffers();
831 myBackBufferRestored = Standard_False;
837 /*----------------------------------------------------------------------*/
840 void OpenGl_Workspace::CopyBuffers (const Standard_Boolean theFrontToBack)
844 myBackBufferRestored = Standard_False;
847 glMatrixMode (GL_PROJECTION);
850 gluOrtho2D ((GLdouble) 0., (GLdouble) myWidth, 0., (GLdouble) myHeight);
851 glMatrixMode (GL_MODELVIEW);
857 glDrawBuffer (theFrontToBack ? GL_BACK : GL_FRONT);
858 glReadBuffer (theFrontToBack ? GL_FRONT : GL_BACK);
860 glRasterPos2i (0, 0);
861 glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR);
865 glMatrixMode (GL_PROJECTION);
867 glMatrixMode (GL_MODELVIEW);
870 glDrawBuffer (GL_BACK);
873 /*----------------------------------------------------------------------*/
875 //call_subr_displayCB
876 void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
879 if (theCView.GDisplayCB == NULL)
884 Aspect_GraphicCallbackStruct aCallData;
885 aCallData.reason = theReason;
886 aCallData.glContext = GetGlContext();
887 aCallData.wsID = theCView.WsId;
888 aCallData.viewID = theCView.ViewId;
889 theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
892 /*----------------------------------------------------------------------*/