1 // Copyright (C) 2005 OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
19 // Author : OPEN CASCADE
22 // File: GLViewer_Drawer.cxx
23 // Created: November, 2004
25 //#include <GLViewerAfx.h>
26 #include "GLViewer_Drawer.h"
27 #include "GLViewer_Object.h"
28 #include "GLViewer_Text.h"
29 #include "GLViewer_ViewFrame.h"
30 #include "GLViewer_ViewPort2d.h"
36 #include <gp_Pnt2d.hxx>
42 // Two texture components for texmapped fonts: luminance and alpha
44 // A font is split into rows each containing 32 characters
45 #define TEX_ROW_LEN 32
46 // Gap in pixels between two character rows in a font texture
49 GLfloat modelMatrix[16];
51 //================================================================
52 // Class : GLViewer_TexFont
54 //================================================================
55 //! code of first font symbol
56 static int FirstSymbolNumber = 32;
57 //! code of last font symbol
58 static int LastSymbolNumber = 127;
60 QMap<GLViewer_TexFindId,GLViewer_TexIdStored> GLViewer_TexFont::TexFontBase;
61 QMap<GLViewer_TexFindId,GLuint> GLViewer_TexFont::BitmapFontCache;
63 //=======================================================================
64 // Function: clearTextBases
66 //=======================================================================
67 void GLViewer_TexFont::clearTextBases()
69 //cout << "Clear font map" << endl;
71 BitmapFontCache.clear();
74 //======================================================================
75 // Function: GLViewer_TexFont
77 //=======================================================================
78 GLViewer_TexFont::GLViewer_TexFont()
79 : myMaxRowWidth( 0 ), myFontHeight( 0 )
81 myQFont = QFont::defaultFont();
83 myIsResizeable = false;
84 myMinMagFilter = GL_LINEAR;
89 //======================================================================
90 // Function: GLViewer_TexFont
92 //=======================================================================
93 GLViewer_TexFont::GLViewer_TexFont( QFont* theFont, int theSeparator, bool theIsResizeable, GLuint theMinMagFilter )
94 : myMaxRowWidth( 0 ), myFontHeight( 0 )
97 mySeparator = theSeparator;
98 myIsResizeable = theIsResizeable;
99 myMinMagFilter = theMinMagFilter;
104 //======================================================================
105 // Function: ~GLViewer_TexFont
107 //=======================================================================
108 GLViewer_TexFont::~GLViewer_TexFont()
111 delete[] myPositions;
114 //======================================================================
117 //=======================================================================
118 void GLViewer_TexFont::init()
120 myNbSymbols = LastSymbolNumber - FirstSymbolNumber + 1;
122 // It is unsafe to draw all characters in a single row -
123 // this leads to problems on some graphic cards with small GL_MAX_TEXTURE_SIZE.
124 // So splitting the characters into rows each containing 32 characters (or less).
125 // Assuming contant height of each row (64 pixels) to simplify texture mapping.
126 // However, this can be improved if necessary.
127 QFontMetrics aFM( myQFont );
128 myFontHeight = aFM.height();
130 myWidths = new int[myNbSymbols];
131 myPositions = new int[myNbSymbols];
133 for( int i = 0, k = FirstSymbolNumber, aWidth = 0; i < myNbSymbols; i++, k++ )
135 // is it time to start a new row?
136 if ( !( i % TEX_ROW_LEN ) )
138 if( aWidth > myMaxRowWidth )
139 myMaxRowWidth = aWidth;
142 myWidths[i] = aFM.width( k );
143 myPositions[i] = aWidth;
144 aWidth += myWidths[i] + 2;
151 //======================================================================
152 // Function: generateTexture
154 //=======================================================================
155 bool GLViewer_TexFont::generateTexture()
157 GLViewer_TexFindId aFindFont;
158 aFindFont.myFontFamily = myQFont.family();//myQFont.toString();
159 aFindFont.myIsBold = myQFont.bold();
160 aFindFont.myIsItal = myQFont.italic();
161 aFindFont.myIsUndl = myQFont.underline();
162 aFindFont.myPointSize = myQFont.pointSize();
163 aFindFont.myViewPortId = (int)QGLContext::currentContext();
165 if( TexFontBase.contains( aFindFont ) )
167 GLViewer_TexIdStored aTexture = TexFontBase[ aFindFont ];
168 myTexFont = aTexture.myTexFontId;
169 myTexFontWidth = aTexture.myTexFontWidth;
170 myTexFontHeight = aTexture.myTexFontHeight;
174 // Adding some pixels to have a gap between rows
175 int aRowPixelHeight = myFontHeight + TEX_ROW_GAP;
176 int aDescent = QFontMetrics( myQFont ).descent();
178 int aNumRows = myNbSymbols / TEX_ROW_LEN;
179 if ( myNbSymbols % TEX_ROW_LEN )
181 int pixelsHight = aNumRows * aRowPixelHeight;
184 myTexFontHeight = 64;
186 while( myTexFontWidth < myMaxRowWidth )
187 myTexFontWidth <<= 1;
188 while( myTexFontHeight < pixelsHight )
189 myTexFontHeight <<= 1;
191 // Checking whether the texture dimensions for the requested font
192 // do not exceed the maximum size supported by the OpenGL implementation
194 glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxSize );
195 if ( myTexFontWidth > maxSize || myTexFontHeight > maxSize )
198 QPixmap aPixmap( myTexFontWidth, myTexFontHeight );
199 aPixmap.fill( QColor( 0, 0, 0) );
200 QPainter aPainter( &aPixmap );
201 aPainter.setFont( myQFont );
203 for( int l = 0; l < myNbSymbols; l++ )
205 row = l / TEX_ROW_LEN;
207 aLetter += (char)(FirstSymbolNumber + l);
208 aPainter.setPen( QColor( 255,255,255) );
209 aPainter.drawText( myPositions[l], ( row + 1 ) * aRowPixelHeight - aDescent, aLetter );
212 QImage aImage = aPixmap.convertToImage();
216 // aImage.save("w:\\work\\CATHARE\\texture.png", "PNG");
218 char* pixels = new char[myTexFontWidth * myTexFontHeight * NB_TEX_COMP];
220 for( int i = 0; i < myTexFontHeight; i++ )
222 for( int j = 0; j < myTexFontWidth; j++ )
224 int aRed = qRed( aImage.pixel( j, myTexFontHeight - i - 1 ) );
225 int aGreen = qGreen( aImage.pixel( j, myTexFontHeight - i - 1 ) );
226 int aBlue = qBlue( aImage.pixel( j, myTexFontHeight - i - 1 ) );
228 if( aRed != 0 || aGreen != 0 || aBlue != 0 )
230 pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP] = (GLubyte)( (aRed + aGreen + aBlue)/3 );
231 pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP + 1]= (GLubyte) 255;
235 pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP] = (GLubyte) 0;
236 pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP + 1]= (GLubyte) 0;
241 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
242 glGenTextures(1, &myTexFont);
243 glBindTexture(GL_TEXTURE_2D, myTexFont);
244 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myMinMagFilter);
245 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myMinMagFilter);
246 glTexImage2D(GL_TEXTURE_2D,
258 GLViewer_TexIdStored aTexture;
259 aTexture.myTexFontId = myTexFont;
260 aTexture.myTexFontWidth = myTexFontWidth;
261 aTexture.myTexFontHeight = myTexFontHeight;
263 TexFontBase.insert( aFindFont, aTexture );
268 //======================================================================
269 // Function: drawString
271 //=======================================================================
272 void GLViewer_TexFont::drawString( QString theStr, GLdouble theX , GLdouble theY, GLfloat theScale )
274 // Adding some pixels to have a gap between rows
275 int aRowPixelHeight = myFontHeight + TEX_ROW_GAP;
277 float aXScale = 1.f, aYScale = 1.f;
278 if ( !myIsResizeable )
280 glGetFloatv (GL_MODELVIEW_MATRIX, modelMatrix);
281 aXScale = modelMatrix[0];
282 aYScale = modelMatrix[5];
284 else if ( theScale > 0.f )
286 aXScale = aXScale / theScale;
287 aYScale = aYScale / theScale;
291 glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
293 glEnable(GL_TEXTURE_2D);
294 glPixelTransferi(GL_MAP_COLOR, 0);
296 glAlphaFunc(GL_GEQUAL, 0.05F);
297 glEnable(GL_ALPHA_TEST);
300 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
302 glBindTexture(GL_TEXTURE_2D, myTexFont);
303 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
307 float aLettBeginS, aLettEndS, aLettBeginT, aLettEndT;
308 float aDY = ( aRowPixelHeight - 1 ) / aYScale, aDX;
311 for( int i = 0; i < theStr.length(); i++ )
313 aLetter = theStr.data()[i];
314 aLettIndex = (int)aLetter - FirstSymbolNumber;
315 row = aLettIndex / TEX_ROW_LEN;
317 aLettBeginS = (float)myPositions[aLettIndex] / ( (float)myTexFontWidth - 1.f );
318 aLettEndS = aLettBeginS + ( (float)myWidths[aLettIndex] - 1.f ) / ( (float)myTexFontWidth - 1.f );
319 aLettBeginT = ( myTexFontHeight - ( row + 1 ) * aRowPixelHeight ) / ( (float)myTexFontHeight - 1.f );
320 aLettEndT = aLettBeginT + ( (float)aRowPixelHeight - 1.f ) / ( (float)myTexFontHeight - 1.f );
322 aDX = ( (float)myWidths[aLettIndex] - 1.f ) / aXScale;
324 glTexCoord2f( aLettBeginS, aLettBeginT ); glVertex3f( theX, theY, 1.f );
325 glTexCoord2f( aLettBeginS, aLettEndT ); glVertex3f( theX, theY + aDY, 1.f );
326 glTexCoord2f( aLettEndS, aLettEndT ); glVertex3f( theX + aDX, theY + aDY, 1.f );
327 glTexCoord2f( aLettEndS, aLettBeginT ); glVertex3f( theX + aDX, theY, 1.f );
329 theX += aDX + mySeparator / aXScale;
333 // restore attributes
337 //======================================================================
338 // Function: getStringWidth
340 //=======================================================================
341 int GLViewer_TexFont::getStringWidth( QString theStr )
344 for( int i = 0; i < theStr.length(); i ++ )
346 char aLetter = theStr.data()[i];
347 int aLettIndex = (int)aLetter - FirstSymbolNumber;
348 aWidth += myWidths[aLettIndex] + mySeparator;
354 //======================================================================
355 // Function: getStringHeight
357 //=======================================================================
358 int GLViewer_TexFont::getStringHeight()
360 QFontMetrics aFM( myQFont );
364 //! function for generation list base for bitmap fonts
365 static GLuint displayListBase( QFont* theFont )
370 //static QMap<GLViewer_TexFindId, GLuint> fontCache;
371 GLViewer_TexFindId aFindFont;
372 aFindFont.myFontFamily = theFont->family();//theFont->toString();
373 aFindFont.myIsBold = theFont->bold();
374 aFindFont.myIsItal = theFont->italic();
375 aFindFont.myIsUndl = theFont->underline();
376 aFindFont.myPointSize = theFont->pointSize();
379 HGLRC ctx = ::wglGetCurrentContext();
383 aFindFont.myViewPortId = (int)ctx;
385 if ( GLViewer_TexFont::BitmapFontCache.contains( aFindFont ) )
386 aList = GLViewer_TexFont::BitmapFontCache[aFindFont];
390 QMap<GLViewer_TexFindId, GLuint>::iterator it = GLViewer_TexFont::BitmapFontCache.begin();
391 for ( ; it != GLViewer_TexFont::BitmapFontCache.end(); ++it )
393 if ( it.key().myViewPortId == (int)ctx && it.data() > listBase )
394 listBase = it.data();
398 HDC glHdc = ::wglGetCurrentDC();
399 ::SelectObject( glHdc, theFont->handle() );
400 if ( !::wglUseFontBitmaps( glHdc, 0, 256, listBase ) )
403 GLViewer_TexFont::BitmapFontCache[aFindFont] = aList;
406 Display* aDisp = glXGetCurrentDisplay();
410 printf( "Can't find current dislay\n" );
415 GLXContext aCont = glXGetCurrentContext();
419 printf( "Can't find current context\n" );
424 aFindFont.myViewPortId = (int)aCont;
426 if ( GLViewer_TexFont::BitmapFontCache.contains( aFindFont ) )
427 aList = GLViewer_TexFont::BitmapFontCache[aFindFont];
431 QMap<GLViewer_TexFindId, GLuint>::iterator it = GLViewer_TexFont::BitmapFontCache.begin();
432 for ( ; it != GLViewer_TexFont::BitmapFontCache.end(); ++it )
434 if ( it.key().myViewPortId == (int)aCont && it.data() > listBase )
435 listBase = it.data();
439 //glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase );
441 QString aFontDef = theFont->toString();
442 char** xFontList = XListFonts( aDisp, aFontDef.latin1()/*aFindFont.myFontString.data()*/, 1, &aFontCont );
443 if( !theFont->handle() )
446 printf( "Can't load font %s. loading default font....\n", aFontDef.latin1()/*aFindFont.myFontString.data()*/ );
448 QString aFontMask ("-*-*-*-r-*-*-");
449 aFontMask += aFontDef/*aFindFont.myFontString*/.section( ',', 1, 1 );
451 printf( "Height of Default font: %s\n", aFontDef/*aFindFont.myFontString*/.section( ',', 1, 1 ).data() );
453 aFontMask += "-*-*-*-m-*-*-*";
454 xFontList = XListFonts( aDisp, aFontMask.data()/*"-*-*-*-r-*-*-12-*-*-*-m-*-*-*"*/, 1, &aFontCont );
458 printf( "Can't load default font\n" );
462 glXUseXFont( (Font)(XLoadFont( aDisp,xFontList[0] )), 0, 256, listBase );
465 glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase );
468 GLViewer_TexFont::BitmapFontCache[aFindFont] = aList;
476 /***************************************************************************
477 ** Class: GLViewer_Drawer
478 ** Descr: Drawer for GLViewer_Object
480 ** Created: UI team, 01.10.01
481 ****************************************************************************/
482 //======================================================================
483 // Function: GLViewer_Drawer
485 //=======================================================================
486 GLViewer_Drawer::GLViewer_Drawer()
487 : myFont( "Helvetica", 10, QFont::Bold )
489 myXScale = myYScale = 0.0;
491 myTextList = 0/*-1*/;
492 myObjectType = "GLViewer_Object";
494 myTextFormat = DTF_BITMAP;
498 //======================================================================
499 // Function: ~GLViewer_Drawer
501 //=======================================================================
502 GLViewer_Drawer::~GLViewer_Drawer()
505 glDeleteLists( myTextList, 1 );
508 //======================================================================
509 // Function: destroyAllTextures
511 //=======================================================================
512 void GLViewer_Drawer::destroyAllTextures()
514 QMap<GLViewer_TexFindId,GLViewer_TexIdStored>::Iterator anIt= GLViewer_TexFont::TexFontBase.begin();
515 QMap<GLViewer_TexFindId,GLViewer_TexIdStored>::Iterator anEndIt= GLViewer_TexFont::TexFontBase.end();
517 for( ; anIt != anEndIt; anIt++ )
518 glDeleteTextures( 1, &(anIt.data().myTexFontId) );
521 //=======================================================================
522 // Function: setAntialiasing
523 // Purpose : The function enables and disables antialiasing in Open GL (for points, lines and polygons).
524 //=======================================================================
525 void GLViewer_Drawer::setAntialiasing(const bool on)
529 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
530 glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
532 glEnable(GL_POINT_SMOOTH);
533 glEnable(GL_LINE_SMOOTH);
534 glEnable(GL_POLYGON_SMOOTH);
535 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
540 glDisable(GL_POINT_SMOOTH);
541 glDisable(GL_LINE_SMOOTH);
542 glDisable(GL_POLYGON_SMOOTH);
543 glBlendFunc (GL_ONE, GL_ZERO);
544 glDisable (GL_BLEND);
548 //======================================================================
549 // Function: loadTexture
551 //=======================================================================
552 GLuint GLViewer_Drawer::loadTexture( const QString& fileName,
558 if ( fileName.isEmpty() || !buf.load( fileName ) )
562 int h = buf.height();
565 while( size < w || size < h )
569 GLubyte* pixels = new GLubyte[ size * size * 4 ];
571 for( int i = 0; i < size; i++ )
573 for( int j = 0; j < size; j++ )
578 QRgb pixel = buf.pixel( j, h - i - 1 );
579 r = (GLubyte)qRed( pixel );
580 g = (GLubyte)qGreen( pixel );
581 b = (GLubyte)qBlue( pixel );
582 a = (GLubyte)qAlpha( pixel );
592 int index = 4 * ( i * size + j );
594 pixels[ index + 1 ] = g;
595 pixels[ index + 2 ] = b;
596 pixels[ index + 3 ] = a;
601 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
602 glGenTextures( 1, &texture );
603 glBindTexture( GL_TEXTURE_2D, texture );
604 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
605 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
606 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0,
607 GL_RGBA, GL_UNSIGNED_BYTE, pixels );
623 //======================================================================
624 // Function: drawTexture
626 //=======================================================================
627 void GLViewer_Drawer::drawTexture( GLuint texture, GLint size, GLfloat x, GLfloat y )
629 /*float xScale = myXScale;
630 float yScale = myYScale;
632 glColor4f( 1.0, 1.0, 1.0, 1.0 );
634 glEnable( GL_TEXTURE_2D );
635 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
636 glAlphaFunc( GL_GREATER, 0.95F );
637 glEnable( GL_ALPHA_TEST );
639 glBindTexture( GL_TEXTURE_2D, texture );
642 glTexCoord2f( 0.0, 0.0 );
643 glVertex3f( x-size/2./xScale, y-size/2./yScale, 0.0 );
645 glTexCoord2f( 0.0, 1.0 );
646 glVertex3f( x-size/2./xScale, y+size/2./yScale, 0.0 );
648 glTexCoord2f( 1.0, 1.0 );
649 glVertex3f( x+size/2./xScale, y+size/2./yScale, 0.0 );
651 glTexCoord2f( 1.0, 0.0 );
652 glVertex3f( x+size/2./xScale, y-size/2./yScale, 0.0 );
657 glDisable( GL_ALPHA_TEST );
658 glDisable( GL_TEXTURE_2D );*/
660 drawTexture( texture, size, size, x, y );
663 //======================================================================
664 // Function: drawTexture
666 //=======================================================================
667 void GLViewer_Drawer::drawTexture( GLuint texture, GLint x_size, GLint y_size, GLfloat x, GLfloat y )
669 /*float xScale = myXScale;
670 float yScale = myYScale;
672 glColor4f( 1.0, 1.0, 1.0, 1.0 );
674 glEnable( GL_TEXTURE_2D );
675 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
676 glAlphaFunc( GL_GREATER, 0.95F );
677 glEnable( GL_ALPHA_TEST );
679 glBindTexture( GL_TEXTURE_2D, texture );
682 glTexCoord2f( 0.0, 0.0 );
683 glVertex3f( x-x_size/2./xScale, y-y_size/2./yScale, 0.0 );
685 glTexCoord2f( 0.0, 1.0 );
686 glVertex3f( x-x_size/2./xScale, y+y_size/2./yScale, 0.0 );
688 glTexCoord2f( 1.0, 1.0 );
689 glVertex3f( x+x_size/2./xScale, y+y_size/2./yScale, 0.0 );
691 glTexCoord2f( 1.0, 0.0 );
692 glVertex3f( x+x_size/2./xScale, y-y_size/2./yScale, 0.0 );
697 glDisable( GL_ALPHA_TEST );
698 glDisable( GL_TEXTURE_2D );*/
699 drawTexturePart( texture, 1.0, 1.0, x_size, y_size, x, y );
702 //======================================================================
703 // Function: drawTexture
705 //=======================================================================
706 void GLViewer_Drawer::drawTexturePart( GLuint texture,
718 float xScale = scale > 0. ? 1./scale : myXScale;
719 float yScale = scale > 0. ? 1./scale : myYScale;
721 glColor4f( 1.0, 1.0, 1.0, 1.0 );
724 glEnable( GL_TEXTURE_2D );
725 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
726 bool hasAlpha = glIsEnabled( GL_ALPHA_TEST );
727 glDisable( GL_ALPHA_TEST );
729 glBindTexture( GL_TEXTURE_2D, texture );
732 glTexCoord2f( 0.0, 0.0 );
733 glVertex3f( x-x_size/2./xScale, y-y_size/2./yScale, 0.0 );
735 glTexCoord2f( 0.0, y_ratio );
736 glVertex3f( x-x_size/2./xScale, y+y_size/2./yScale, 0.0 );
738 glTexCoord2f( x_ratio, y_ratio );
739 glVertex3f( x+x_size/2./xScale, y+y_size/2./yScale, 0.0 );
741 glTexCoord2f( x_ratio, 0.0 );
742 glVertex3f( x+x_size/2./xScale, y-y_size/2./yScale, 0.0 );
748 glEnable( GL_ALPHA_TEST );
750 glDisable( GL_TEXTURE_2D );
753 //======================================================================
754 // Function: drawText
756 //=======================================================================
757 void GLViewer_Drawer::drawText( const QString& text, GLfloat xPos, GLfloat yPos,
758 const QColor& color, QFont* theFont, int theSeparator, DisplayTextFormat theFormat )
760 glColor3f( ( GLfloat )color.red() / 255,
761 ( GLfloat )color.green() / 255,
762 ( GLfloat )color.blue() / 255 );
764 if( theFormat != DTF_BITMAP )
766 GLViewer_TexFont aTexFont( theFont, theSeparator, theFormat == DTF_TEXTURE_SCALABLE, GL_LINEAR );
767 // Font texture was not found or generated --> cannot draw text
768 if ( !aTexFont.generateTexture() )
771 if ( theFormat == DTF_TEXTURE_SCALABLE )
772 aTexFont.drawString( text, xPos, yPos, textScale() );
774 aTexFont.drawString( text, xPos, yPos );
778 glRasterPos2f( xPos, yPos );
779 glListBase( displayListBase( theFont ) );
780 glCallLists( text.length(), GL_UNSIGNED_BYTE, text.local8Bit().data() );
784 //======================================================================
785 // Function: drawText
787 //=======================================================================
788 void GLViewer_Drawer::drawText( GLViewer_Object* theObject )
793 GLViewer_Text* aText = theObject->getGLText();
797 GLfloat aPosX, aPosY;
798 aText->getPosition( aPosX, aPosY );
799 // get temporary copy of font
800 QFont aTmpVarFont = aText->getFont();
801 drawText( aText->getText(), aPosX, aPosY, aText->getColor(), &aTmpVarFont, aText->getSeparator(), aText->getDisplayTextFormat() );
804 //======================================================================
805 // Function: drawGLText
807 //=======================================================================
808 void GLViewer_Drawer::drawGLText( QString text, float x, float y,
809 int hPosition, int vPosition, QColor color, bool smallFont )
811 QFont aFont( myFont );
813 aFont.setPointSize( aFont.pointSize() * 0.8 );
815 GLfloat scale = textScale() > 0. ? textScale() : 1.;
817 QFontMetrics aFontMetrics( aFont );
818 float width = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.width( text ) * scale : aFontMetrics.width( text ) / myXScale;
819 float height = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.height() * scale : aFontMetrics.height() / myYScale;
820 float gap = 5 / myXScale;
824 case GLText_Left : x -= ( gap + width ); break;
825 case GLText_Center : x -= width / 2; break;
826 case GLText_Right : x += gap; break;
832 case GLText_Top : y += height * 0.5; break;
833 case GLText_Center : y -= height * 0.5; break;
834 case GLText_Bottom : y -= height * 1.5; break;
838 drawText( text, x, y, color, &aFont, 2, myTextFormat );
841 //======================================================================
842 // Function: textRect
844 //=======================================================================
845 GLViewer_Rect GLViewer_Drawer::textRect( const QString& text ) const
847 GLfloat scale = textScale() > 0. ? textScale() : 1.;
849 QFontMetrics aFontMetrics( myFont );
850 float width = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.width( text ) * scale : aFontMetrics.width( text );
851 float height = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.height() * scale : aFontMetrics.height();
853 return GLViewer_Rect( 0, width, height, 0 );
856 //======================================================================
857 // Function: drawRectangle
859 //=======================================================================
860 void GLViewer_Drawer::drawRectangle( GLViewer_Rect* rect, QColor color )
865 float x1 = rect->left();
866 float x2 = rect->right();
867 float y1 = rect->bottom();
868 float y2 = rect->top();
870 glColor3f( ( GLfloat )color.red() / 255,
871 ( GLfloat )color.green() / 255,
872 ( GLfloat )color.blue() / 255 );
875 glBegin( GL_LINE_LOOP );
876 glVertex2f( x1, y1 );
877 glVertex2f( x1, y2 );
878 glVertex2f( x2, y2 );
879 glVertex2f( x2, y1 );
883 //======================================================================
884 // Function: translateToHPGL
886 //=======================================================================
887 bool GLViewer_Drawer::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
890 for( int i=0, n=myObjects.count(); i<n; i++ )
891 result &= myObjects[i]->translateToHPGL( hFile, aViewerCS, aHPGLCS );
895 //======================================================================
896 // Function: translateToPS
898 //=======================================================================
899 bool GLViewer_Drawer::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
902 for( int i=0, n=myObjects.count(); i<n; i++ )
903 result &= myObjects[i]->translateToPS( hFile, aViewerCS, aPSCS );
908 //======================================================================
909 // Function: translateToEMF
911 //=======================================================================
912 bool GLViewer_Drawer::translateToEMF( HDC hDC, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
915 for( int i=0, n=myObjects.count(); i<n; i++ )
916 result &= myObjects[i]->translateToEMF( hDC, aViewerCS, aEMFCS );
921 //======================================================================
922 // Function: drawRectangle
924 //=======================================================================
925 void GLViewer_Drawer::drawRectangle( GLViewer_Rect* rect, GLfloat lineWidth, GLfloat gap,
926 QColor color, bool filled, QColor fillingColor )
931 float x1 = rect->left() - gap;
932 float x2 = rect->right() + gap;
933 float y1 = rect->bottom() - gap;
934 float y2 = rect->top() + gap;
938 glColor3f( ( GLfloat )fillingColor.red() / 255,
939 ( GLfloat )fillingColor.green() / 255,
940 ( GLfloat )fillingColor.blue() / 255 );
941 glBegin( GL_POLYGON );
942 glVertex2f( x1, y1 );
943 glVertex2f( x1, y2 );
944 glVertex2f( x2, y2 );
945 glVertex2f( x2, y1 );
949 glColor3f( ( GLfloat )color.red() / 255,
950 ( GLfloat )color.green() / 255,
951 ( GLfloat )color.blue() / 255 );
952 glLineWidth( lineWidth );
954 glBegin( GL_LINE_LOOP );
955 glVertex2f( x1, y1 );
956 glVertex2f( x1, y2 );
957 glVertex2f( x2, y2 );
958 glVertex2f( x2, y1 );
962 //======================================================================
963 // Function: drawContour
965 //=======================================================================
966 void GLViewer_Drawer::drawContour( const GLViewer_PntList& pntList, QColor color, GLfloat lineWidth )
968 glColor3f( ( GLfloat )color.red() / 255,
969 ( GLfloat )color.green() / 255,
970 ( GLfloat )color.blue() / 255 );
971 glLineWidth( lineWidth );
974 QValueList<GLViewer_Pnt>::const_iterator it = pntList.begin();
975 for( ; it != pntList.end(); ++it )
976 glVertex2f( (*it).x(), (*it).y() );
980 //======================================================================
981 // Function: drawContour
983 //=======================================================================
984 void GLViewer_Drawer::drawContour( GLViewer_Rect* rect, QColor color, GLfloat lineWidth,
985 GLushort pattern, bool isStripe )
987 float x1 = rect->left();
988 float x2 = rect->right();
989 float y1 = rect->bottom();
990 float y2 = rect->top();
992 glColor3f( ( GLfloat )color.red() / 255,
993 ( GLfloat )color.green() / 255,
994 ( GLfloat )color.blue() / 255 );
995 glLineWidth( lineWidth );
999 glEnable( GL_LINE_STIPPLE );
1000 glLineStipple( 1, pattern );
1003 glBegin( GL_LINE_LOOP );
1005 glVertex2f( x1, y1 );
1006 glVertex2f( x1, y2 );
1007 glVertex2f( x2, y2 );
1008 glVertex2f( x2, y1 );
1011 glDisable( GL_LINE_STIPPLE );
1014 //======================================================================
1015 // Function: drawPolygon
1017 //=======================================================================
1018 void GLViewer_Drawer::drawPolygon( const GLViewer_PntList& pntList, QColor color )
1020 glColor3f( ( GLfloat )color.red() / 255,
1021 ( GLfloat )color.green() / 255,
1022 ( GLfloat )color.blue() / 255 );
1023 glBegin( GL_POLYGON );
1024 QValueList<GLViewer_Pnt>::const_iterator it = pntList.begin();
1025 for( ; it != pntList.end(); ++it )
1026 glVertex2f( (*it).x(), (*it).y() );
1030 //======================================================================
1031 // Function: drawPolygon
1033 //=======================================================================
1034 void GLViewer_Drawer::drawPolygon( GLViewer_Rect* rect, QColor color,
1035 GLushort pattern, bool isStripe )
1037 float x1 = rect->left();
1038 float x2 = rect->right();
1039 float y1 = rect->bottom();
1040 float y2 = rect->top();
1041 glColor3f( ( GLfloat )color.red() / 255,
1042 ( GLfloat )color.green() / 255,
1043 ( GLfloat )color.blue() / 255 );
1047 glEnable( GL_LINE_STIPPLE );
1048 glLineStipple( 1, pattern );
1050 glBegin( GL_POLYGON );
1052 glVertex2f( x1, y1 );
1053 glVertex2f( x1, y2 );
1054 glVertex2f( x2, y2 );
1055 glVertex2f( x2, y1 );
1058 glDisable( GL_LINE_STIPPLE );
1061 //======================================================================
1062 // Function: drawVertex
1064 //=======================================================================
1065 GLubyte rasterVertex[5] = { 0x70, 0xf8, 0xf8, 0xf8, 0x70 };
1066 void GLViewer_Drawer::drawVertex( GLfloat x, GLfloat y, QColor color )
1068 glColor3f( ( GLfloat )color.red() / 255, ( GLfloat )color.green() / 255, ( GLfloat )color.blue() / 255 );
1069 glRasterPos2f( x, y );
1070 glBitmap( 5, 5, 2, 2, 0, 0, rasterVertex );
1073 //======================================================================
1074 // Function: drawCross
1076 //=======================================================================
1077 GLubyte rasterCross[7] = { 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82 };
1078 void GLViewer_Drawer::drawCross( GLfloat x, GLfloat y, QColor color )
1080 glColor3f( ( GLfloat )color.red() / 255, ( GLfloat )color.green() / 255, ( GLfloat )color.blue() / 255 );
1081 glRasterPos2f( x, y );
1082 glBitmap( 7, 7, 3, 3, 0, 0, rasterCross );
1085 //======================================================================
1086 // Function: drawArrow
1088 //=======================================================================
1089 void GLViewer_Drawer::drawArrow( const GLfloat red, const GLfloat green, const GLfloat blue,
1091 GLfloat staff, GLfloat length, GLfloat width,
1092 GLfloat x, GLfloat y, GLfloat angle, GLboolean filled )
1095 GLfloat vy1 = y + staff + length;
1096 GLfloat vx2 = vx1 - width / 2;
1097 GLfloat vy2 = vy1 - length;
1098 GLfloat vx3 = vx1 + width / 2;
1099 GLfloat vy3 = vy1 - length;
1101 gp_Pnt2d p0( x, y );
1102 gp_Pnt2d p1( vx1, vy1 );
1103 gp_Pnt2d p2( vx2, vy2 );
1104 gp_Pnt2d p3( vx3, vy3 );
1106 p1.Rotate( p0, angle );
1107 p2.Rotate( p0, angle );
1108 p3.Rotate( p0, angle );
1110 vx1 = p1.X(); vy1 = p1.Y();
1111 vx2 = p2.X(); vy2 = p2.Y();
1112 vx3 = p3.X(); vy3 = p3.Y();
1114 glColor3f( red, green, blue );
1115 glLineWidth( lineWidth );
1117 glBegin( GL_LINES );
1119 glVertex2f( vx1, vy1 );
1125 glBegin( GL_LINES );
1126 glVertex2f( vx1, vy1 );
1127 glVertex2f( vx2, vy2 );
1128 glVertex2f( vx1, vy1 );
1129 glVertex2f( vx3, vy3 );
1134 glBegin( GL_POLYGON );
1135 glVertex2f( vx1, vy1 );
1136 glVertex2f( vx2, vy2 );
1137 glVertex2f( vx3, vy3 );