0022819: Redesign of OpenGl driver
[occt.git] / src / OpenGl / OpenGl_Text.cxx
1 // File:      OpenGl_Text.cxx
2 // Created:   13 July 2011
3 // Author:    Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
5
6 #include <OpenGl_Text.hxx>
7
8 #if (!defined(_WIN32) && !defined(__WIN32__))
9   #include <X11/Xlib.h>
10 #endif
11
12 #include <OpenGl_tgl_all.hxx>
13 #include <GL/gl.h>
14
15 #include <OpenGl_Memory.hxx>
16
17 #include <OpenGl_AspectText.hxx>
18 #include <OpenGl_Structure.hxx>
19
20 /*----------------------------------------------------------------------*/
21
22 OpenGl_Text::OpenGl_Text (const TCollection_ExtendedString& AText,
23                         const Graphic3d_Vertex& APoint,
24                         const Standard_Real AHeight,
25                         const Graphic3d_HorizontalTextAlignment AHta,
26                         const Graphic3d_VerticalTextAlignment AVta)
27 : myString(NULL)
28 {
29   const Techar *str = (const Techar *) AText.ToExtString();
30
31   //szv: instead of strlen + 1
32   int i = 0; while (str[i++]);
33
34   wchar_t *wstr = new wchar_t[i];
35
36   //szv: instead of memcpy
37   i = 0; while (wstr[i++] = (wchar_t)(*str++));
38   if (myString) delete[] myString;
39   myString = wstr;
40
41   Standard_Real X, Y, Z;
42   APoint.Coord(X, Y, Z);
43   myAttachPnt.xyz[0] = float (X);
44   myAttachPnt.xyz[1] = float (Y);
45   myAttachPnt.xyz[2] = float (Z);
46
47   myParam.Height = int (AHeight);
48
49   myParam.HAlign = AHta;
50   myParam.VAlign = AVta;
51 }
52
53 /*----------------------------------------------------------------------*/
54
55 OpenGl_Text::~OpenGl_Text ()
56 {
57   if (myString)
58     delete[] myString;
59 }
60
61 /*----------------------------------------------------------------------*/
62
63 void OpenGl_Text::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
64 {
65   if ( AWorkspace->DegenerateModel > 0 && AWorkspace->SkipRatio >= 1.f )
66     return;
67
68   const OpenGl_AspectText *aspect_text = AWorkspace->AspectText( Standard_True );
69
70   const TEL_COLOUR *tcolor, *scolor;
71
72   // Use highlight colours
73   if( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
74   {                         
75     tcolor = scolor = AWorkspace->HighlightColor;
76   }
77   else
78   {
79     tcolor = &aspect_text->Color();
80     scolor = &aspect_text->SubtitleColor();
81   }
82
83   // Handle annotation style
84   GLboolean flag_zbuffer = GL_FALSE;
85   if (aspect_text->StyleType() == Aspect_TOST_ANNOTATION)
86   {
87     flag_zbuffer = glIsEnabled(GL_DEPTH_TEST);
88     if (flag_zbuffer) glDisable(GL_DEPTH_TEST);
89   }
90
91   AWorkspace->SetTextParam(&myParam);
92
93   GLboolean       blend_state = GL_FALSE; 
94   GLdouble        modelMatrix[16], projMatrix[16];
95   GLint           viewport[4];
96   GLdouble        objrefX, objrefY, objrefZ;
97   GLdouble        objX, objY, objZ;
98   GLdouble        obj1X, obj1Y, obj1Z;
99   GLdouble        obj2X, obj2Y, obj2Z;
100   GLdouble        obj3X, obj3Y, obj3Z;
101   GLdouble        winx1, winy1, winz1;
102   GLdouble        winx, winy, winz;
103   GLint           status;
104
105   /* display type of text */
106   if (aspect_text->DisplayType() != Aspect_TODT_NORMAL)
107   {
108     /* Optimisation: il faudrait ne faire le Get qu'une fois par Redraw */
109     glGetIntegerv (GL_VIEWPORT, viewport);
110     glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
111     glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
112
113     switch (aspect_text->DisplayType())
114     {
115     case Aspect_TODT_BLEND:
116       blend_state = glIsEnabled(GL_BLEND);
117       if (!blend_state) glEnable(GL_BLEND);
118       glEnable(GL_COLOR_LOGIC_OP);
119       glLogicOp(GL_XOR);
120       break;
121     case Aspect_TODT_SUBTITLE:
122     {
123       int sWidth, sAscent, sDescent;
124       AWorkspace->StringSize(myString, sWidth, sAscent, sDescent);
125
126       objrefX = (float)myAttachPnt.xyz[0];   
127       objrefY = (float)myAttachPnt.xyz[1];   
128       objrefZ = (float)myAttachPnt.xyz[2];
129       status = gluProject (objrefX, objrefY, objrefZ, modelMatrix, projMatrix, viewport,
130         &winx1, &winy1, &winz1);
131
132       winx = winx1;
133       winy = winy1-sDescent;
134       winz = winz1+0.00001;     
135       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
136         &objX, &objY, &objZ);
137
138       winx = winx1 + sWidth;
139       winy = winy1-sDescent;
140       winz = winz1+0.00001; /* il vaut mieux F+B / 1000000 ? */     
141       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
142         &obj1X, &obj1Y, &obj1Z);
143
144       winx = winx1 + sWidth;
145       winy = winy1 + sAscent;
146       winz = winz1+0.00001;     
147       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
148         &obj2X, &obj2Y, &obj2Z);
149
150       winx = winx1;
151       winy = winy1+ sAscent;
152       winz = winz1+0.00001;   
153       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
154         &obj3X, &obj3Y, &obj3Z);
155
156       glColor3fv( scolor->rgb );
157       glBegin(GL_POLYGON);
158       glVertex3d(objX, objY, objZ);
159       glVertex3d(obj1X, obj1Y, obj1Z);
160       glVertex3d(obj2X, obj2Y, obj2Z);
161       glVertex3d(obj3X, obj3Y, obj3Z);
162       glEnd();
163       break;
164     }
165
166     case Aspect_TODT_DEKALE:
167       objrefX = (float)myAttachPnt.xyz[0];   
168       objrefY = (float)myAttachPnt.xyz[1];   
169       objrefZ = (float)myAttachPnt.xyz[2];
170       status = gluProject (objrefX, objrefY, objrefZ, modelMatrix, projMatrix, viewport,
171         &winx1, &winy1, &winz1);
172
173       winx = winx1+1;
174       winy = winy1+1;
175       winz = winz1+0.00001;     
176       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
177         &objX, &objY, &objZ);
178
179       glColor3fv( scolor->rgb );
180       AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
181       winx = winx1-1;
182       winy = winy1-1;
183       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
184         &objX, &objY, &objZ);
185
186       AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
187       winx = winx1-1;
188       winy = winy1+1;
189       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
190         &objX, &objY, &objZ); 
191
192       AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
193       winx = winx1+1;
194       winy = winy1-1;
195       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
196         &objX, &objY, &objZ);
197       AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
198       break;
199     }
200   }
201
202   glColor3fv( tcolor->rgb );
203   AWorkspace->RenderText( myString, 0, (float)myAttachPnt.xyz[0], (float)myAttachPnt.xyz[1],(float)myAttachPnt.xyz[2] );
204   /* maj attributs */
205   if (flag_zbuffer) glEnable(GL_DEPTH_TEST);
206   if (aspect_text->DisplayType() == Aspect_TODT_BLEND)
207   {
208     if (!blend_state) glDisable(GL_BLEND);
209     glDisable(GL_COLOR_LOGIC_OP);
210   }
211 }
212
213 /*----------------------------------------------------------------------*/