Salome HOME
Transaction management in operations modifed.
[modules/gui.git] / src / GLViewer / GLViewer_Drawer.cxx
1 //  Copyright (C) 2005 OPEN CASCADE
2 //
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.
7 //
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.
12 //
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
16 //
17 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
18 //
19 //  Author : OPEN CASCADE
20 //
21
22 // File:      GLViewer_Drawer.cxx
23 // Created:   November, 2004
24
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"
31
32 #ifndef WIN32
33 #include <GL/glx.h>
34 #endif
35
36 #include <qimage.h>
37 #include <qpainter.h>
38
39 #define TEXT_GAP    5
40
41 GLboolean          TFLoaded = GL_FALSE;
42
43 GLdouble           modelMatrix[16], projMatrix[16];
44 GLint              viewport[4];
45 GLdouble           winx, winy, winz;
46 GLint              status;
47
48 GLViewer_TexFont*  staticGlFont;
49
50 //================================================================
51 // Class       : GLViewer_TexFont
52 // Description : 
53 //================================================================
54 //! code of first font symbol
55 static int FirstSymbolNumber = 32;
56 //! code of last font symbol
57 static int LastSymbolNumber = 127;
58
59 QMap<GLViewer_TexFindId,GLViewer_TexIdStored> GLViewer_TexFont::TexFontBase;
60 QMap<GLViewer_TexFindId,GLuint>               GLViewer_TexFont::BitmapFontCache; 
61
62 //=======================================================================
63 // Function: clearTextBases
64 // Purpose :
65 //=======================================================================
66 void GLViewer_TexFont::clearTextBases()
67 {
68   //cout << "Clear font map" << endl;
69   TexFontBase.clear();
70   BitmapFontCache.clear();
71 }
72
73 //======================================================================
74 // Function: GLViewer_TexFont
75 // Purpose :
76 //=======================================================================
77 GLViewer_TexFont::GLViewer_TexFont()
78 {
79     myQFont = QFont::defaultFont();
80     QFontMetrics aFM( myQFont );        
81     myWidths = new int[LastSymbolNumber - FirstSymbolNumber+1];
82     myPositions = new int[LastSymbolNumber - FirstSymbolNumber+1];
83     mySeparator = 2;
84     for( int k = FirstSymbolNumber, aWidth = 0; k <= LastSymbolNumber; k++ )
85     {
86         myWidths[ k - FirstSymbolNumber ] = aFM.width( k );
87         myPositions[ k - FirstSymbolNumber ] = aWidth;
88         aWidth += myWidths[ k - FirstSymbolNumber ] + 2;//mySeparator;
89     }
90
91     myTexFontWidth = 0;
92     myTexFontHeight = 0; 
93     myIsResizeable = false;
94     //myMinMagFilter = GL_NEAREST;
95     myMinMagFilter = GL_LINEAR_ATTENUATION ;
96 }
97
98 //======================================================================
99 // Function: GLViewer_TexFont
100 // Purpose :
101 //=======================================================================
102 GLViewer_TexFont::GLViewer_TexFont( QFont* theFont, int theSeparator, bool theIsResizeable, GLuint theMinMagFilter )
103 {
104     myQFont = *theFont;
105     QFontMetrics aFM( myQFont );        
106     myWidths = new int[LastSymbolNumber - FirstSymbolNumber+1];
107     myPositions = new int[LastSymbolNumber - FirstSymbolNumber+1];
108     mySeparator = theSeparator;
109     for( int k = FirstSymbolNumber, aWidth = 0; k <= LastSymbolNumber; k++ )
110     {
111         myWidths[ k - FirstSymbolNumber ] = aFM.width( k );
112         myPositions[ k - FirstSymbolNumber ] = aWidth;
113         aWidth += myWidths[ k - FirstSymbolNumber ] + 2;//mySeparator;
114     }
115
116     myTexFontWidth = 0;
117     myTexFontHeight = 0;
118     myIsResizeable = theIsResizeable;
119     myMinMagFilter = theMinMagFilter;
120     
121 }
122
123 //======================================================================
124 // Function: ~GLViewer_TexFont
125 // Purpose :
126 //=======================================================================
127 GLViewer_TexFont::~GLViewer_TexFont()
128 {
129     delete[] myWidths;
130     delete[] myPositions;
131
132   
133 //======================================================================
134 // Function: generateTexture
135 // Purpose :
136 //=======================================================================
137 void GLViewer_TexFont::generateTexture()
138 {
139     QFontMetrics aFM( myQFont );
140
141     GLViewer_TexFindId aFindFont;
142     aFindFont.myFontString = myQFont.toString();
143     aFindFont.myViewPortId = (int)QGLContext::currentContext();
144         
145     if( TexFontBase.contains( aFindFont ) )
146     {
147         GLViewer_TexIdStored aTexture = TexFontBase[ aFindFont ];
148         myTexFont = aTexture.myTexFontId;
149         myTexFontWidth = aTexture.myTexFontWidth;
150         myTexFontHeight = aTexture.myTexFontHeight;
151     }    
152     else    
153     {
154         QString aStr;
155         int pixelsWidth = 0;
156         int pixelsHight = aFM.height();
157         myTexFontWidth = 64;
158         myTexFontHeight = 64;
159     
160         pixelsWidth = myWidths[LastSymbolNumber - FirstSymbolNumber] + 
161                       myPositions[LastSymbolNumber - FirstSymbolNumber];
162
163         while( myTexFontWidth < pixelsWidth )
164             myTexFontWidth = myTexFontWidth * 2;
165         while( myTexFontHeight < pixelsHight )
166             myTexFontHeight = myTexFontHeight * 2;
167
168         QPixmap aPixmap( myTexFontWidth, myTexFontHeight );
169         aPixmap.fill( QColor( 0, 0, 0) );
170         QPainter aPainter( &aPixmap );
171         aPainter.setFont( myQFont );
172         for( int l = 0/*, gap = 0*/; l < LastSymbolNumber - FirstSymbolNumber; l++  )
173         {
174             QString aLetter;
175             aLetter += (char)(FirstSymbolNumber + l);
176             aPainter.setPen( QColor( 255,255,255) );
177             aPainter.drawText ( myPositions[l], pixelsHight, aLetter );
178         }
179     
180         QImage aImage = aPixmap.convertToImage();
181         char* pixels = new char[myTexFontWidth * myTexFontHeight * 2];
182
183         for( int i = 0; i < myTexFontHeight; i++ )
184         {            
185             for( int j = 0; j < myTexFontWidth;  j++ )
186             {
187                 int aRed = qRed( aImage.pixel( j, myTexFontHeight - i - 1 ) );
188                 int aGreen = qGreen( aImage.pixel( j, myTexFontHeight - i - 1 ) );
189                 int aBlue = qBlue( aImage.pixel( j, myTexFontHeight - i - 1 ) );
190           
191                 if( aRed != 0 || aGreen != 0 || aBlue != 0 )
192                 {
193                     pixels[i * myTexFontWidth * 2 + j * 2] = (GLubyte)( (aRed + aGreen + aBlue)/3 );
194                     pixels[i * myTexFontWidth * 2 + j * 2 + 1]= (GLubyte) 255;
195                 }
196                 else
197                 {
198                     pixels[i * myTexFontWidth * 2 + j * 2] = (GLubyte) 0;
199                     pixels[i * myTexFontWidth * 2 + j * 2 + 1]= (GLubyte) 0;
200                 }                
201             }
202         }
203
204         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
205         glGenTextures(1, &myTexFont);
206         glBindTexture(GL_TEXTURE_2D, myTexFont);  
207         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
208         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
209         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myMinMagFilter);
210         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myMinMagFilter);
211         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
212         glTexImage2D(GL_TEXTURE_2D, 
213                      0, 
214                      GL_INTENSITY, 
215                      myTexFontWidth,
216                      myTexFontHeight, 
217                      0, 
218                      GL_LUMINANCE_ALPHA, 
219                      GL_UNSIGNED_BYTE, 
220                      pixels);
221     
222         delete[] pixels;
223         
224         GLViewer_TexIdStored aTexture;
225         aTexture.myTexFontId = myTexFont;
226         aTexture.myTexFontWidth = myTexFontWidth;
227         aTexture.myTexFontHeight = myTexFontHeight;
228
229         TexFontBase.insert( aFindFont, aTexture );
230     }
231 }
232
233 //======================================================================
234 // Function: drawString
235 // Purpose :
236 //=======================================================================
237 void GLViewer_TexFont::drawString( QString theStr, GLdouble theX , GLdouble theY )
238 {
239     double aXScale = 1., aYScale = 1.;
240     // store attributes
241     glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
242
243     if ( !myIsResizeable )
244     {
245       glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
246       aXScale = modelMatrix[0];
247       aYScale = modelMatrix[5];
248     }
249
250     glEnable(GL_TEXTURE_2D);
251
252     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
253     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
254     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
255     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myMinMagFilter);
256     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myMinMagFilter);
257
258     glPixelTransferi(GL_MAP_COLOR, 0);
259
260     glAlphaFunc(GL_GEQUAL, 0.05F);
261     glEnable(GL_ALPHA_TEST);
262
263     glEnable(GL_BLEND);
264     glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
265
266     glBindTexture(GL_TEXTURE_2D, myTexFont);
267     glBegin(GL_QUADS);
268
269     theY = theY - ( myTexFontHeight - QFontMetrics( myQFont ).height() ) / aYScale;
270
271     double aLettBegin, aLettEnd, aDY = ( myTexFontHeight - 1 ) / aYScale, aDX;
272     char aLetter;
273     int aLettIndex;
274     for( int i = 0; i < theStr.length(); i++ )
275     {
276         aLetter    = theStr.data()[i];
277         aLettIndex = (int)aLetter - FirstSymbolNumber;
278
279         aLettBegin = (double)myPositions[aLettIndex] / ( (double)myTexFontWidth - 1. );
280         aLettEnd   = aLettBegin + ( (double)myWidths[aLettIndex] - 1. ) / ( (double)myTexFontWidth - 1. );
281
282         aDX = ( (double)myWidths[aLettIndex] - 1. ) / aXScale;
283
284         glTexCoord2d( aLettBegin, 0.0 ); glVertex3d( theX,       theY,       1.0 );
285         glTexCoord2d( aLettBegin, 1.0 ); glVertex3d( theX,       theY + aDY, 1.0 );
286         glTexCoord2d( aLettEnd,   1.0 ); glVertex3d( theX + aDX, theY + aDY, 1.0 );
287         glTexCoord2d( aLettEnd,   0.0 ); glVertex3d( theX + aDX, theY,       1.0 );
288
289         theX += aDX + mySeparator / aXScale;
290     }
291
292     glEnd();
293     // restore attributes
294     glPopAttrib();
295 }
296
297 //======================================================================
298 // Function: getStringWidth
299 // Purpose :
300 //=======================================================================
301 int GLViewer_TexFont::getStringWidth( QString theStr )
302 {
303     int aWidth = 0;
304     for( int i = 0; i < theStr.length(); i ++ )
305     {
306         char aLetter = theStr.data()[i];
307         int aLettIndex = (int)aLetter - FirstSymbolNumber;
308         aWidth += myWidths[aLettIndex] + mySeparator;
309     }
310
311     return aWidth;
312 }
313
314 //======================================================================
315 // Function: getStringHeight
316 // Purpose :
317 //=======================================================================
318 int GLViewer_TexFont::getStringHeight()
319 {
320     QFontMetrics aFM( myQFont );
321     return aFM.height();
322 }
323
324 //! function for generation list base for bitmap fonts
325 static GLuint displayListBase( QFont* theFont )
326 {
327   GLuint aList = 0;
328   //static QMap<GLViewer_TexFindId, GLuint> fontCache;
329   GLViewer_TexFindId aFindFont;
330   aFindFont.myFontString = theFont->toString();
331
332 #ifdef WIN32
333   HGLRC ctx = ::wglGetCurrentContext();
334   if ( !ctx )
335     return aList;  
336   
337   aFindFont.myViewPortId = (int)ctx;
338
339   if ( GLViewer_TexFont::BitmapFontCache.contains( aFindFont ) )
340     aList = GLViewer_TexFont::BitmapFontCache[aFindFont];
341   else
342   {
343     GLuint listBase = 0;
344     QMap<GLViewer_TexFindId, GLuint>::iterator it = GLViewer_TexFont::BitmapFontCache.begin();
345     for ( ; it != GLViewer_TexFont::BitmapFontCache.end(); ++it )
346     {
347       if ( it.key().myViewPortId == (int)ctx && it.data() > listBase )
348         listBase = it.data();
349     }
350     listBase += 256;
351
352     HDC glHdc = ::wglGetCurrentDC();
353     ::SelectObject( glHdc, theFont->handle() );
354     if ( !::wglUseFontBitmaps( glHdc, 0, 256, listBase ) )
355       listBase = 0;
356     aList = listBase;
357     GLViewer_TexFont::BitmapFontCache[aFindFont] = aList;
358   }
359 #else //X Window
360   Display* aDisp = glXGetCurrentDisplay();
361   if( !aDisp )
362   {
363 #ifdef _DEBUG_
364     printf( "Can't find current dislay\n" );
365 #endif
366     return aList;
367   }
368   
369   GLXContext aCont = glXGetCurrentContext();
370   if( !aCont )
371   {
372 #ifdef _DEBUG_
373     printf( "Can't find current context\n" );
374 #endif
375     return aList;
376   }
377
378   aFindFont.myViewPortId = (int)aCont;
379
380   if ( GLViewer_TexFont::BitmapFontCache.contains( aFindFont ) )
381     aList = GLViewer_TexFont::BitmapFontCache[aFindFont];
382   else
383   {
384     GLuint listBase = 0;
385     QMap<GLViewer_TexFindId, GLuint>::iterator it = GLViewer_TexFont::BitmapFontCache.begin();
386     for ( ; it != GLViewer_TexFont::BitmapFontCache.end(); ++it )
387     {
388       if ( it.key().myViewPortId == (int)aCont && it.data() > listBase )
389         listBase = it.data();
390     }
391     listBase += 256;
392     
393     //glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase );
394     int aFontCont = 0;
395     char** xFontList = XListFonts( aDisp, aFindFont.myFontString.data(), 1, &aFontCont  );
396     if( !theFont->handle() )
397     {       
398 #ifdef _DEBUG_
399       printf( "Can't load font %s. loading default font....\n", aFindFont.myFontString.data() );
400 #endif
401       QString aFontMask ("-*-*-*-r-*-*-");
402       aFontMask += aFindFont.myFontString.section( ',', 1, 1 );
403 #ifdef _DEBUG_
404       printf( "Height of Default font: %s\n", aFindFont.myFontString.section( ',', 1, 1 ).data() );
405 #endif
406       aFontMask += "-*-*-*-m-*-*-*";
407       xFontList = XListFonts( aDisp, aFontMask.data()/*"-*-*-*-r-*-*-12-*-*-*-m-*-*-*"*/, 1, &aFontCont  );
408       if( aFontCont == 0 )
409       {      
410 #ifdef _DEBUG_
411         printf( "Can't load default font\n" );
412 #endif
413         return 0;
414       }
415       glXUseXFont( (Font)(XLoadFont( aDisp,xFontList[0] )), 0, 256, listBase );
416     }
417     else
418       glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase );
419     
420     aList = listBase;
421     GLViewer_TexFont::BitmapFontCache[aFindFont] = aList;
422   }
423
424 #endif
425
426   return aList;
427 }
428
429 /***************************************************************************
430 **  Class:   GLViewer_Drawer
431 **  Descr:   Drawer for GLViewer_Object
432 **  Module:  GLViewer
433 **  Created: UI team, 01.10.01
434 ****************************************************************************/
435 //======================================================================
436 // Function: GLViewer_Drawer
437 // Purpose :
438 //=======================================================================
439 GLViewer_Drawer::GLViewer_Drawer()
440 : myFont( "Helvetica", 10, QFont::Bold )
441 {
442   myXScale = myYScale = 0.0;
443   myObjects.clear();
444   myTextList = 0/*-1*/;
445   myObjectType = "GLViewer_Object";
446   myPriority = 0;
447   myTextFormat = DTF_BITMAP;
448 }
449
450 //======================================================================
451 // Function: ~GLViewer_Drawer
452 // Purpose :
453 //=======================================================================
454 GLViewer_Drawer::~GLViewer_Drawer()
455 {
456   myObjects.clear();
457   glDeleteLists( myTextList, 1 );
458 }
459
460 //======================================================================
461 // Function: destroyAllTextures
462 // Purpose :
463 //=======================================================================
464 void GLViewer_Drawer::destroyAllTextures()
465 {
466     QMap<GLViewer_TexFindId,GLViewer_TexIdStored>::Iterator anIt= GLViewer_TexFont::TexFontBase.begin();
467     QMap<GLViewer_TexFindId,GLViewer_TexIdStored>::Iterator anEndIt= GLViewer_TexFont::TexFontBase.end();
468
469     for( ; anIt != anEndIt; anIt++ )
470         glDeleteTextures( 1, &(anIt.data().myTexFontId) );
471 }
472
473 //=======================================================================
474 // Function: setAntialiasing
475 // Purpose : The function enables and disables antialiasing in Open GL (for points, lines and polygons).
476 //=======================================================================
477 void GLViewer_Drawer::setAntialiasing(const bool on)
478 {
479         if (on)
480         {
481     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
482     glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
483
484                 glEnable(GL_POINT_SMOOTH);
485                 glEnable(GL_LINE_SMOOTH);
486                 glEnable(GL_POLYGON_SMOOTH);
487                 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
488                 glEnable (GL_BLEND);
489         }
490         else
491         {
492                 glDisable(GL_POINT_SMOOTH);
493                 glDisable(GL_LINE_SMOOTH);
494                 glDisable(GL_POLYGON_SMOOTH);
495                 glBlendFunc (GL_ONE, GL_ZERO);
496                 glDisable (GL_BLEND);
497         }
498 }
499
500 //======================================================================
501 // Function: loadTexture
502 // Purpose :
503 //=======================================================================
504 GLuint GLViewer_Drawer::loadTexture( const QString& fileName,
505                                      GLint* x_size,
506                                      GLint* y_size,
507                                      GLint* t_size )
508 {
509     QImage buf;
510     if ( fileName.isEmpty() || !buf.load( fileName ) )
511         return 0;
512
513     int w = buf.width();
514     int h = buf.height();
515
516     int size = 16;
517     while( size < w || size < h )
518         size = size * 2;
519
520     GLuint texture;
521     GLubyte* pixels = new GLubyte[ size * size * 4 ];
522
523     for( int i = 0; i < size; i++ )
524     {            
525         for( int j = 0; j < size; j++ )
526         {
527             GLubyte r, g, b, a;
528             if( j < w && i < h )
529             {
530                 QRgb pixel = buf.pixel( j, h - i - 1 );
531                 r = (GLubyte)qRed( pixel );
532                 g = (GLubyte)qGreen( pixel );
533                 b = (GLubyte)qBlue( pixel );
534                 a = (GLubyte)qAlpha( pixel );
535             }
536             else
537             {
538                 r = (GLubyte)255;
539                 g = (GLubyte)255;
540                 b = (GLubyte)255;
541                 a = (GLubyte)255;
542             }
543
544             int index = 4 * ( i * size + j );
545             pixels[ index ] = r;
546             pixels[ index + 1 ] = g;
547             pixels[ index + 2 ] = b;
548             pixels[ index + 3 ] = a;
549         }
550     }
551
552     //initialize texture
553     glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
554     glGenTextures( 1, &texture );
555     glBindTexture( GL_TEXTURE_2D, texture );
556     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
557     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
558     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0,
559                   GL_RGBA, GL_UNSIGNED_BYTE, pixels );
560
561     delete[] pixels;
562
563     if ( x_size )
564       *(x_size) = w;
565
566     if ( y_size )
567       *(y_size) = h;
568
569     if ( t_size )
570       *(t_size) = size;
571
572     return texture;
573 }
574
575 //======================================================================
576 // Function: drawTexture
577 // Purpose :
578 //=======================================================================
579 void GLViewer_Drawer::drawTexture( GLuint texture, GLint size, GLfloat x, GLfloat y )
580 {
581     /*float xScale = myXScale;
582     float yScale = myYScale;
583
584     glColor4f( 1.0, 1.0, 1.0, 1.0 );
585
586     glEnable( GL_TEXTURE_2D );
587     glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
588     glAlphaFunc( GL_GREATER, 0.95F );
589     glEnable( GL_ALPHA_TEST );
590     
591     glBindTexture( GL_TEXTURE_2D, texture );
592     glBegin( GL_QUADS );
593
594     glTexCoord2f( 0.0, 0.0 );
595     glVertex3f( x-size/2./xScale, y-size/2./yScale, 0.0 );
596
597     glTexCoord2f( 0.0, 1.0 );
598     glVertex3f( x-size/2./xScale, y+size/2./yScale, 0.0 );
599
600     glTexCoord2f( 1.0, 1.0 );
601     glVertex3f( x+size/2./xScale, y+size/2./yScale, 0.0 );
602
603     glTexCoord2f( 1.0, 0.0 );
604     glVertex3f( x+size/2./xScale, y-size/2./yScale, 0.0 );
605     
606     glEnd();
607     glFlush();
608
609     glDisable( GL_ALPHA_TEST );
610     glDisable( GL_TEXTURE_2D );*/
611
612   drawTexture( texture, size, size, x, y );
613 }
614
615 //======================================================================
616 // Function: drawTexture
617 // Purpose :
618 //=======================================================================
619 void GLViewer_Drawer::drawTexture( GLuint texture, GLint x_size, GLint y_size, GLfloat x, GLfloat y )
620 {
621     /*float xScale = myXScale;
622     float yScale = myYScale;
623
624     glColor4f( 1.0, 1.0, 1.0, 1.0 );
625
626     glEnable( GL_TEXTURE_2D );
627     glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
628     glAlphaFunc( GL_GREATER, 0.95F );
629     glEnable( GL_ALPHA_TEST );
630     
631     glBindTexture( GL_TEXTURE_2D, texture );
632     glBegin( GL_QUADS );
633
634     glTexCoord2f( 0.0, 0.0 );
635     glVertex3f( x-x_size/2./xScale, y-y_size/2./yScale, 0.0 );
636
637     glTexCoord2f( 0.0, 1.0 );
638     glVertex3f( x-x_size/2./xScale, y+y_size/2./yScale, 0.0 );
639
640     glTexCoord2f( 1.0, 1.0 );
641     glVertex3f( x+x_size/2./xScale, y+y_size/2./yScale, 0.0 );
642
643     glTexCoord2f( 1.0, 0.0 );
644     glVertex3f( x+x_size/2./xScale, y-y_size/2./yScale, 0.0 );
645     
646     glEnd();
647     glFlush();
648
649     glDisable( GL_ALPHA_TEST );
650     glDisable( GL_TEXTURE_2D );*/
651   drawTexturePart( texture, 1.0, 1.0, x_size, y_size, x, y );
652 }
653
654 //======================================================================
655 // Function: drawTexture
656 // Purpose :
657 //=======================================================================
658 void GLViewer_Drawer::drawTexturePart( GLuint texture,
659                                        GLfloat x_ratio,
660                                        GLfloat y_ratio,
661                                        GLint x_size,
662                                        GLint y_size,
663                                        GLfloat x,
664                                        GLfloat y,
665                                        GLfloat scale )
666 {
667   float xScale = scale > 0. ? 1./scale : myXScale;
668   float yScale = scale > 0. ? 1./scale : myYScale;
669
670   glColor4f( 1.0, 1.0, 1.0, 1.0 );
671
672   glEnable( GL_TEXTURE_2D );
673   glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
674   glAlphaFunc( GL_GREATER, 0.95F );
675   glEnable( GL_ALPHA_TEST );
676   
677   glBindTexture( GL_TEXTURE_2D, texture );
678   glBegin( GL_QUADS );
679
680   glTexCoord2f( 0.0, 0.0 );
681   glVertex3f( x-x_size/2./xScale, y-y_size/2./yScale, 0.0 );
682
683   glTexCoord2f( 0.0, y_ratio );
684   glVertex3f( x-x_size/2./xScale, y+y_size/2./yScale, 0.0 );
685
686   glTexCoord2f( x_ratio, y_ratio );
687   glVertex3f( x+x_size/2./xScale, y+y_size/2./yScale, 0.0 );
688
689   glTexCoord2f( x_ratio, 0.0 );
690   glVertex3f( x+x_size/2./xScale, y-y_size/2./yScale, 0.0 );
691   
692   glEnd();
693   glFlush();
694
695   glDisable( GL_ALPHA_TEST );
696   glDisable( GL_TEXTURE_2D );
697 }
698
699 //======================================================================
700 // Function: drawText
701 // Purpose :
702 //=======================================================================
703 void GLViewer_Drawer::drawText( const QString& text, GLfloat xPos, GLfloat yPos,
704                                 const QColor& color, QFont* theFont, int theSeparator, DisplayTextFormat theFormat )
705 {
706   glColor3f( ( GLfloat )color.red() / 255, 
707              ( GLfloat )color.green() / 255, 
708              ( GLfloat )color.blue() / 255 );
709
710   if( theFormat != DTF_BITMAP )
711   {
712     GLViewer_TexFont aTexFont( theFont, theSeparator, theFormat == DTF_TEXTURE_SCALABLE, GL_LINEAR );
713     aTexFont.generateTexture();
714     aTexFont.drawString( text, xPos, yPos );
715   }
716   else
717   {
718     glRasterPos2f( xPos, yPos );
719     glListBase( displayListBase( theFont ) );
720     glCallLists( text.length(), GL_UNSIGNED_BYTE, text.local8Bit().data() );
721   }
722 }
723
724 //======================================================================
725 // Function: drawText
726 // Purpose :
727 //=======================================================================
728 void GLViewer_Drawer::drawText( GLViewer_Object* theObject )
729 {
730   if( !theObject )
731     return;
732
733   GLViewer_Text* aText = theObject->getGLText();
734   if( !aText )
735     return;
736
737   GLfloat aPosX, aPosY;
738   aText->getPosition( aPosX, aPosY );
739   // get temporary copy of font
740   QFont aTmpVarFont = aText->getFont();
741   drawText( aText->getText(), aPosX, aPosY, aText->getColor(), &aTmpVarFont, aText->getSeparator(), aText->getDisplayTextFormat() );
742 }
743
744 //======================================================================
745 // Function: drawGLText
746 // Purpose :
747 //=======================================================================
748 void GLViewer_Drawer::drawGLText( QString text, float x, float y,
749                                   int hPosition, int vPosition, QColor color, bool smallFont )
750 {
751   QFont aFont( myFont );
752   if( smallFont )
753     aFont.setPointSize( aFont.pointSize() * 0.8 );
754
755   QFontMetrics aFontMetrics( aFont );
756   float width  = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.width( text ) : aFontMetrics.width( text ) / myXScale;
757   float height = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.height() : aFontMetrics.height() / myYScale;
758   float gap = 5 / myXScale;
759
760   switch( hPosition )
761   {
762       case GLText_Left   : x -= ( gap + width ); break;
763       case GLText_Center : x -= width / 2; break;
764       case GLText_Right  : x += gap; break;
765       default : break;
766   }
767
768   switch( vPosition )
769   {
770       case GLText_Top    : y += height * 0.5; break;
771       case GLText_Center : y -= height * 0.5; break;
772       case GLText_Bottom : y -= height * 1.5; break;
773       default : break;
774   }
775
776   drawText( text, x, y, color, &aFont, 2, myTextFormat );
777 }
778
779 //======================================================================
780 // Function: drawRectangle
781 // Purpose :
782 //=======================================================================
783 void GLViewer_Drawer::drawRectangle( GLViewer_Rect* rect, QColor color )
784 {
785   if( !rect )
786     return;
787
788   float x1 = rect->left();
789   float x2 = rect->right();
790   float y1 = rect->bottom();
791   float y2 = rect->top();
792   
793   glColor3f( ( GLfloat )color.red() / 255,
794     ( GLfloat )color.green() / 255,
795     ( GLfloat )color.blue() / 255 );
796   glLineWidth( 1.0 );
797   
798   glBegin( GL_LINE_LOOP );
799   glVertex2f( x1, y1 );
800   glVertex2f( x1, y2 );
801   glVertex2f( x2, y2 );
802   glVertex2f( x2, y1 );
803   glEnd();
804 }
805
806 //======================================================================
807 // Function: translateToHPGL
808 // Purpose :
809 //=======================================================================
810 bool GLViewer_Drawer::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
811 {
812     bool result = true;
813     for( int i=0, n=myObjects.count(); i<n; i++ ) 
814         result &= myObjects[i]->translateToHPGL( hFile, aViewerCS, aHPGLCS );
815     return result;
816 }
817
818 //======================================================================
819 // Function: translateToPS
820 // Purpose :
821 //=======================================================================
822 bool GLViewer_Drawer::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
823 {
824     bool result = true;
825     for( int i=0, n=myObjects.count(); i<n; i++ ) 
826         result &= myObjects[i]->translateToPS( hFile, aViewerCS, aPSCS );
827     return result;
828 }
829
830 #ifdef WIN32
831 //======================================================================
832 // Function: translateToEMF
833 // Purpose :
834 //=======================================================================
835 bool GLViewer_Drawer::translateToEMF( HDC hDC, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
836 {
837     bool result = true;
838     for( int i=0, n=myObjects.count(); i<n; i++ ) 
839         result &= myObjects[i]->translateToEMF( hDC, aViewerCS, aEMFCS );
840     return result;
841 }
842 #endif