Initialize libbullet git in 2.0_beta.
[platform/upstream/libbullet.git] / Extras / CDTestFramework / AntTweakBar / src / TwOpenGL.cpp
1 //      ---------------------------------------------------------------------------
2 //
3 //      @file           TwOpenGL.cpp
4 //      @author         Philippe Decaudin - http://www.antisphere.com
5 //  @license    This file is part of the AntTweakBar library.
6 //                              Copyright © 2005, 2006 Philippe Decaudin.
7 //              For conditions of distribution and use, see License.txt
8 //
9 //      note:           TAB=4
10 //
11 //      ---------------------------------------------------------------------------
12
13
14 #include "TwPrecomp.h"
15 #include "LoadOGL.h"
16 #include "TwOpenGL.h"
17 #include "TwMgr.h"
18
19 using namespace std;
20
21 const char *g_ErrCantLoadOGL    = "Cannot load OpenGL library dynamically";
22 const char *g_ErrCantUnloadOGL  = "Cannot unload OpenGL library";
23
24 GLuint g_SmallFontTexID = 0;
25 GLuint g_NormalFontTexID = 0;
26 GLuint g_LargeFontTexID = 0;
27
28 //      ---------------------------------------------------------------------------
29 //      Extensions
30
31 typedef void (APIENTRY * PFNGLBindBufferARB)(GLenum target, GLuint buffer);
32 typedef void (APIENTRY * PFNGLBindProgramARB)(GLenum target, GLuint program);
33 typedef GLuint (APIENTRY * PFNGLGetHandleARB)(GLenum pname);
34 typedef void (APIENTRY * PFNGLUseProgramObjectARB)(GLuint programObj);
35 PFNGLBindBufferARB _glBindBufferARB = NULL;\r
36 PFNGLBindProgramARB _glBindProgramARB = NULL;\r
37 PFNGLGetHandleARB _glGetHandleARB = NULL;\r
38 PFNGLUseProgramObjectARB _glUseProgramObjectARB = NULL;\r
39 #ifndef GL_ARRAY_BUFFER_ARB\r
40 #       define GL_ARRAY_BUFFER_ARB 0x8892
41 #endif
42 #ifndef GL_ELEMENT_ARRAY_BUFFER_ARB
43 #       define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
44 #endif
45 #ifndef GL_ARRAY_BUFFER_BINDING_ARB
46 #       define GL_ARRAY_BUFFER_BINDING_ARB 0x8894\r
47 #endif\r
48 #ifndef GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB\r
49 #       define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
50 #endif
51 #ifndef GL_VERTEX_PROGRAM_ARB
52 #       define GL_VERTEX_PROGRAM_ARB 0x8620
53 #endif
54 #ifndef GL_FRAGMENT_PROGRAM_ARB
55 #       define GL_FRAGMENT_PROGRAM_ARB 0x8804
56 #endif
57 #ifndef GL_PROGRAM_OBJECT_ARB
58 #       define GL_PROGRAM_OBJECT_ARB 0x8B40
59 #endif
60
61 //      ---------------------------------------------------------------------------
62
63 static GLuint BindFont(const CTexFont *_Font)
64 {
65         GLuint TexID = 0;
66         _glGenTextures(1, &TexID);
67         _glBindTexture(GL_TEXTURE_2D, TexID);
68         _glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
69         _glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
70         _glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
71         _glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
72         _glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
73         _glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
74         _glPixelTransferf(GL_ALPHA_SCALE, 1);
75         _glPixelTransferf(GL_ALPHA_BIAS, 0);
76         _glPixelTransferf(GL_RED_BIAS, 1);
77         _glPixelTransferf(GL_GREEN_BIAS, 1);
78         _glPixelTransferf(GL_BLUE_BIAS, 1);
79         _glTexImage2D(GL_TEXTURE_2D, 0, 4, _Font->m_TexWidth, _Font->m_TexHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, _Font->m_TexBytes);
80         _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
81     _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
82     _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
83     _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
84         _glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
85         _glBindTexture(GL_TEXTURE_2D, 0);
86         _glPixelTransferf(GL_ALPHA_BIAS, 0);
87         _glPixelTransferf(GL_RED_BIAS, 0);
88         _glPixelTransferf(GL_GREEN_BIAS, 0);
89         _glPixelTransferf(GL_BLUE_BIAS, 0);
90
91         return TexID;
92 }
93
94 static void UnbindFont(GLuint _FontTexID)
95 {
96         if( _FontTexID>0 )
97                 _glDeleteTextures(1, &_FontTexID);
98 }
99
100 //      ---------------------------------------------------------------------------
101
102 int CTwGraphOpenGL::Init()
103 {
104         if( LoadOpenGL()==0 )
105         {
106                 g_TwMgr->SetLastError(g_ErrCantLoadOGL);
107                 return 0;
108         }
109
110         m_Drawing = false;
111         m_FontTexID = 0;
112         m_FontTex = NULL;
113         m_MaxClipPlanes = -1;
114
115         // Get extensions
116         _glBindBufferARB = reinterpret_cast<PFNGLBindBufferARB>(_glGetProcAddress("glBindBufferARB"));\r
117         _glBindProgramARB = reinterpret_cast<PFNGLBindProgramARB>(_glGetProcAddress("glBindProgramARB"));\r
118         _glGetHandleARB = reinterpret_cast<PFNGLGetHandleARB>(_glGetProcAddress("glGetHandleARB"));\r
119         _glUseProgramObjectARB = reinterpret_cast<PFNGLUseProgramObjectARB>(_glGetProcAddress("glUseProgramObjectARB"));\r
120
121         return 1;
122 }
123
124 //      ---------------------------------------------------------------------------
125
126 int CTwGraphOpenGL::Shut()
127 {
128         assert(m_Drawing==false);
129
130         UnbindFont(m_FontTexID);
131
132         int Res = 1;
133         if( UnloadOpenGL()==0 )
134         {
135                 g_TwMgr->SetLastError(g_ErrCantUnloadOGL);
136                 Res = 0;
137         }
138
139         return Res;
140 }
141
142 //      ---------------------------------------------------------------------------
143
144 void CTwGraphOpenGL::BeginDraw(int _WndWidth, int _WndHeight)
145 {
146         assert(m_Drawing==false && _WndWidth>0 && _WndHeight>0);
147         m_Drawing = true;
148
149 #ifdef _DEBUG
150         { 
151                 int err=0;
152                 char msg[128];
153                 while( (err=_glGetError())!=0 )
154                 {
155                         sprintf(msg, "Before BeginDraw GL_ERROR=0x%x\n", err);
156                         #ifdef ANT_WINDOWS
157                                 OutputDebugString(msg);
158                         #endif
159                         fprintf(stderr, msg);
160                 }
161         }
162 #endif
163
164         _glPushAttrib(GL_ALL_ATTRIB_BITS);
165         _glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
166         _glMatrixMode(GL_TEXTURE);
167         _glPushMatrix();
168         _glLoadIdentity();
169         _glMatrixMode(GL_MODELVIEW);
170         _glPushMatrix();
171         _glLoadIdentity();
172         _glMatrixMode(GL_PROJECTION);
173         _glPushMatrix();
174         GLint Vp[4];
175         _glGetIntegerv(GL_VIEWPORT, Vp);
176         /*
177         if( _WndWidth>0 && _WndHeight>0 )
178         {
179                 Vp[0] = 0;
180                 Vp[1] = 0;
181                 Vp[2] = _WndWidth;
182                 Vp[3] = _WndHeight;
183                 _glViewport(Vp[0], Vp[1], Vp[2], Vp[3]);
184         }
185         _glLoadIdentity();
186         //_glOrtho(Vp[0], Vp[0]+Vp[2]-1, Vp[1]+Vp[3]-1, Vp[1], -1, 1); // Doesn't work
187         _glOrtho(Vp[0], Vp[0]+Vp[2], Vp[1]+Vp[3], Vp[1], -1, 1);
188         */
189         if( _WndWidth>0 && _WndHeight>0 )
190         {
191                 Vp[0] = 0;
192                 Vp[1] = 0;
193                 Vp[2] = _WndWidth-1;
194                 Vp[3] = _WndHeight-1;
195                 _glViewport(Vp[0], Vp[1], Vp[2], Vp[3]);
196         }
197         _glLoadIdentity();
198         _glOrtho(Vp[0], Vp[0]+Vp[2], Vp[1]+Vp[3], Vp[1], -1, 1);
199
200         _glGetFloatv(GL_LINE_WIDTH, &m_PrevLineWidth);
201         _glDisable(GL_POLYGON_STIPPLE);
202         _glLineWidth(1);
203         _glDisable(GL_LINE_SMOOTH);
204         _glDisable(GL_LINE_STIPPLE);
205         _glDisable(GL_CULL_FACE);
206         _glDisable(GL_DEPTH_TEST);
207         _glDisable(GL_LIGHTING);
208         _glEnable(GL_BLEND);
209         _glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
210         _glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &m_PrevTexEnv);
211         _glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
212         _glGetIntegerv(GL_POLYGON_MODE, m_PrevPolygonMode);
213         _glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
214         _glDisable(GL_ALPHA_TEST);
215         //_glEnable(GL_ALPHA_TEST);
216         //_glAlphaFunc(GL_GREATER, 0);
217         _glDisable(GL_FOG);
218         _glDisable(GL_LOGIC_OP);
219         _glDisable(GL_SCISSOR_TEST);
220         if( m_MaxClipPlanes<0 )
221         {
222                 _glGetIntegerv(GL_MAX_CLIP_PLANES, &m_MaxClipPlanes);
223                 if( m_MaxClipPlanes<0 || m_MaxClipPlanes>255 )
224                         m_MaxClipPlanes = 6;
225         }
226         for( int i=0; i<m_MaxClipPlanes; ++i )
227                 _glDisable(GL_CLIP_PLANE0+i);
228         m_PrevTexture = 0;
229         _glGetIntegerv(GL_TEXTURE_BINDING_2D, &m_PrevTexture);
230
231         _glDisableClientState(GL_VERTEX_ARRAY);
232         _glDisableClientState(GL_NORMAL_ARRAY);
233         _glDisableClientState(GL_TEXTURE_COORD_ARRAY);
234         _glDisableClientState(GL_INDEX_ARRAY);
235         _glDisableClientState(GL_COLOR_ARRAY);
236         _glDisableClientState(GL_EDGE_FLAG_ARRAY);
237
238         if( _glBindBufferARB!=NULL )
239         {
240                 m_PrevArrayBufferARB = m_PrevElementArrayBufferARB = 0;
241                 _glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &m_PrevArrayBufferARB);
242                 _glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &m_PrevElementArrayBufferARB);
243                 _glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
244                 _glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
245         }
246         if( _glBindProgramARB!=NULL )
247         {
248                 m_PrevVertexProgramARB = _glIsEnabled(GL_VERTEX_PROGRAM_ARB);
249                 m_PrevFragmentProgramARB = _glIsEnabled(GL_FRAGMENT_PROGRAM_ARB);
250                 _glDisable(GL_VERTEX_PROGRAM_ARB);
251                 _glDisable(GL_FRAGMENT_PROGRAM_ARB);
252         }
253         if( _glGetHandleARB!=NULL && _glUseProgramObjectARB!=NULL )
254         {
255                 m_PrevProgramObjectARB = _glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
256                 _glUseProgramObjectARB(0);
257         }
258 }
259
260 //      ---------------------------------------------------------------------------
261
262 void CTwGraphOpenGL::EndDraw()
263 {
264         assert(m_Drawing==true);
265         m_Drawing = false;
266
267         _glBindTexture(GL_TEXTURE_2D, m_PrevTexture);
268         if( _glBindBufferARB!=NULL )
269         {
270                 _glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_PrevArrayBufferARB);
271                 _glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_PrevElementArrayBufferARB);
272         }
273         if( _glBindProgramARB!=NULL )
274         {
275                 if( m_PrevVertexProgramARB )
276                         _glEnable(GL_VERTEX_PROGRAM_ARB);
277                 if( m_PrevFragmentProgramARB )
278                         _glEnable(GL_FRAGMENT_PROGRAM_ARB);
279         }
280         if( _glGetHandleARB!=NULL && _glUseProgramObjectARB!=NULL )
281                 _glUseProgramObjectARB(m_PrevProgramObjectARB);
282         
283         _glPolygonMode(GL_FRONT, m_PrevPolygonMode[0]);
284         _glPolygonMode(GL_BACK, m_PrevPolygonMode[1]);
285         _glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_PrevTexEnv);
286         _glLineWidth(m_PrevLineWidth);
287         _glMatrixMode(GL_PROJECTION);
288         _glPopMatrix();
289         _glMatrixMode(GL_MODELVIEW);
290         _glPopMatrix();
291         _glMatrixMode(GL_TEXTURE);
292         _glPopMatrix();
293         _glPopClientAttrib();
294         _glPopAttrib();
295
296 #ifdef _DEBUG
297         { 
298                 int err=0;
299                 char msg[128];
300                 while( (err=_glGetError())!=0 )
301                 {
302                         sprintf(msg, "After EndDraw GL_ERROR=0x%x\n", err);
303                         #ifdef ANT_WINDOWS
304                                 OutputDebugString(msg);
305                         #endif
306                         fprintf(stderr, msg);
307                 }
308         }
309 #endif
310 }
311
312 //      ---------------------------------------------------------------------------
313
314 bool CTwGraphOpenGL::IsDrawing()
315 {
316         return m_Drawing;
317 }
318
319 //      ---------------------------------------------------------------------------
320
321 void CTwGraphOpenGL::Restore()
322 {
323         UnbindFont(m_FontTexID);
324         m_FontTexID = 0;
325         m_FontTex = NULL;
326 }
327
328
329 //      ---------------------------------------------------------------------------
330
331 void CTwGraphOpenGL::DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased)
332 {
333         assert(m_Drawing==true);
334         /* 
335         // border adjustment NO!!
336         if(_X0<_X1)
337                 ++_X1;
338         else if(_X0>_X1)
339                 ++_X0;
340         if(_Y0<_Y1)
341                 ++_Y1;
342         else if(_Y0>_Y1)
343                 ++_Y0;
344         */
345         const GLfloat dx = +0.0f;
346         //GLfloat dy = -0.2f;
347         const GLfloat dy = -0.5f;
348         if( _AntiAliased )
349                 _glEnable(GL_LINE_SMOOTH);
350         else
351                 _glDisable(GL_LINE_SMOOTH);
352         _glDisable(GL_TEXTURE_2D);
353         _glMatrixMode(GL_MODELVIEW);
354         _glLoadIdentity();
355         _glBegin(GL_LINES);
356                 _glColor4ub(GLubyte(_Color0>>16), GLubyte(_Color0>>8), GLubyte(_Color0), GLubyte(_Color0>>24));
357                 _glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y0+dy);
358                 _glColor4ub(GLubyte(_Color1>>16), GLubyte(_Color1>>8), GLubyte(_Color1), GLubyte(_Color1>>24));
359                 _glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y1+dy);
360                 //_glVertex2i(_X0, _Y0);
361                 //_glVertex2i(_X1, _Y1);
362         _glEnd();
363         _glDisable(GL_LINE_SMOOTH);
364 }
365   
366 //      ---------------------------------------------------------------------------
367
368 void CTwGraphOpenGL::DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11)
369 {
370         assert(m_Drawing==true);
371
372         /*
373         // border adjustment
374         if(_X0<_X1)
375                 ++_X1;
376         else if(_X0>_X1)
377                 ++_X0;
378         if(_Y0<_Y1)
379                 ++_Y1;
380         else if(_Y0>_Y1)
381                 ++_Y0;
382         */
383         // border adjustment
384         if(_X0<_X1)
385                 ++_X1;
386         else if(_X0>_X1)
387                 ++_X0;
388         if(_Y0<_Y1)
389                 --_Y0;
390         else if(_Y0>_Y1)
391                 --_Y1;
392         const GLfloat dx = +0.0f;
393         const GLfloat dy = +0.0f;
394
395         _glDisable(GL_TEXTURE_2D);
396         _glMatrixMode(GL_MODELVIEW);
397         _glLoadIdentity();
398         //GLubyte r = GLubyte(_Color>>16);
399         //GLubyte g = GLubyte(_Color>>8);
400         //GLubyte b = GLubyte(_Color);
401         //GLubyte a = GLubyte(_Color>>24);
402         //_glColor4ub(GLubyte(_Color>>16), GLubyte(_Color>>8), GLubyte(_Color), GLubyte(_Color>>24));
403         //_glColor4ub(r, g, b, a);
404         _glBegin(GL_QUADS);
405                 _glColor4ub(GLubyte(_Color00>>16), GLubyte(_Color00>>8), GLubyte(_Color00), GLubyte(_Color00>>24));
406                 _glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y0+dy);
407                 _glColor4ub(GLubyte(_Color10>>16), GLubyte(_Color10>>8), GLubyte(_Color10), GLubyte(_Color10>>24));
408                 _glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y0+dy);
409                 _glColor4ub(GLubyte(_Color11>>16), GLubyte(_Color11>>8), GLubyte(_Color11), GLubyte(_Color11>>24));
410                 _glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y1+dy);
411                 _glColor4ub(GLubyte(_Color01>>16), GLubyte(_Color01>>8), GLubyte(_Color01), GLubyte(_Color01>>24));
412                 _glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y1+dy);
413         _glEnd();
414 }
415
416 //      ---------------------------------------------------------------------------
417
418 void *CTwGraphOpenGL::NewTextObj()
419 {
420         return new CTextObj;
421 }
422
423 //      ---------------------------------------------------------------------------
424
425 void CTwGraphOpenGL::DeleteTextObj(void *_TextObj)
426 {
427         assert(_TextObj!=NULL);
428         delete static_cast<CTextObj *>(_TextObj);
429 }
430
431 //      ---------------------------------------------------------------------------
432
433 void CTwGraphOpenGL::BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth)
434 {
435         assert(m_Drawing==true);
436         assert(_TextObj!=NULL);
437         assert(_Font!=NULL);
438
439         if( _Font != m_FontTex )
440         {
441                 UnbindFont(m_FontTexID);
442                 m_FontTexID = BindFont(_Font);
443                 m_FontTex = _Font;
444         }
445         CTextObj *TextObj = static_cast<CTextObj *>(_TextObj);
446         TextObj->m_TextVerts.resize(0);
447         TextObj->m_TextUVs.resize(0);
448         TextObj->m_BgVerts.resize(0);
449         TextObj->m_Colors.resize(0);
450         TextObj->m_BgColors.resize(0);
451
452         int x, x1, y, y1, i, Len;
453         unsigned char ch;
454         const unsigned char *Text;
455         color32 LineColor = COLOR32_RED;
456         for( int Line=0; Line<_NbLines; ++Line )
457         {
458                 x = 0;
459                 y = Line * (_Font->m_CharHeight+_Sep);
460                 y1 = y+_Font->m_CharHeight;
461                 Len = (int)_TextLines[Line].length();
462                 Text = (const unsigned char *)(_TextLines[Line].c_str());
463                 if( _LineColors!=NULL )
464                         LineColor = (_LineColors[Line]&0xff00ff00) | GLubyte(_LineColors[Line]>>16) | (GLubyte(_LineColors[Line])<<16);
465
466                 for( i=0; i<Len; ++i )
467                 {
468                         ch = Text[i];
469                         x1 = x + _Font->m_CharWidth[ch];
470
471                         TextObj->m_TextVerts.push_back(Vec2(x , y ));
472                         TextObj->m_TextVerts.push_back(Vec2(x1, y ));
473                         TextObj->m_TextVerts.push_back(Vec2(x , y1));
474                         TextObj->m_TextVerts.push_back(Vec2(x1, y ));
475                         TextObj->m_TextVerts.push_back(Vec2(x1, y1));
476                         TextObj->m_TextVerts.push_back(Vec2(x , y1));
477
478                         TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV0[ch]));
479                         TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV0[ch]));
480                         TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV1[ch]));
481                         TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV0[ch]));
482                         TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV1[ch]));
483                         TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV1[ch]));
484
485                         if( _LineColors!=NULL )
486                         {
487                                 TextObj->m_Colors.push_back(LineColor);
488                                 TextObj->m_Colors.push_back(LineColor);
489                                 TextObj->m_Colors.push_back(LineColor);
490                                 TextObj->m_Colors.push_back(LineColor);
491                                 TextObj->m_Colors.push_back(LineColor);
492                                 TextObj->m_Colors.push_back(LineColor);
493                         }
494
495                         x = x1;
496                 }
497                 if( _BgWidth>0 && Len>0 )
498                 {
499                         TextObj->m_BgVerts.push_back(Vec2(-1        , y ));
500                         TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y ));
501                         TextObj->m_BgVerts.push_back(Vec2(-1        , y1));
502                         TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y ));
503                         TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y1));
504                         TextObj->m_BgVerts.push_back(Vec2(-1        , y1));
505
506                         if( _LineBgColors!=NULL )
507                         {
508                                 color32 LineBgColor = (_LineBgColors[Line]&0xff00ff00) | GLubyte(_LineBgColors[Line]>>16) | (GLubyte(_LineBgColors[Line])<<16);
509                                 TextObj->m_BgColors.push_back(LineBgColor);
510                                 TextObj->m_BgColors.push_back(LineBgColor);
511                                 TextObj->m_BgColors.push_back(LineBgColor);
512                                 TextObj->m_BgColors.push_back(LineBgColor);
513                                 TextObj->m_BgColors.push_back(LineBgColor);
514                                 TextObj->m_BgColors.push_back(LineBgColor);
515                         }
516                 }
517         }
518 }
519
520 //      ---------------------------------------------------------------------------
521
522 void CTwGraphOpenGL::DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor)
523 {
524         assert(m_Drawing==true);
525         assert(_TextObj!=NULL);
526         CTextObj *TextObj = static_cast<CTextObj *>(_TextObj);
527
528         if( TextObj->m_TextVerts.size()<4 )
529                 return; // no character to draw
530
531         _glMatrixMode(GL_MODELVIEW);
532         _glLoadIdentity();
533         _glTranslatef((GLfloat)_X, (GLfloat)_Y, 0);
534         _glEnableClientState(GL_VERTEX_ARRAY);
535         if( (_BgColor!=0 || TextObj->m_BgColors.size()==TextObj->m_BgVerts.size()) && TextObj->m_BgVerts.size()>=4 )
536         {
537                 _glDisable(GL_TEXTURE_2D);
538                 _glVertexPointer(2, GL_FLOAT, 0, &(TextObj->m_BgVerts[0]));
539                 if( TextObj->m_BgColors.size()==TextObj->m_BgVerts.size() && _BgColor==0 )
540                 {
541                         _glEnableClientState(GL_COLOR_ARRAY);
542                         _glColorPointer(4, GL_UNSIGNED_BYTE, 0, &(TextObj->m_BgColors[0]));
543                 }
544                 else
545                 {
546                         _glDisableClientState(GL_COLOR_ARRAY);
547                         _glColor4ub(GLubyte(_BgColor>>16), GLubyte(_BgColor>>8), GLubyte(_BgColor), GLubyte(_BgColor>>24));
548                 }
549                 _glDrawArrays(GL_TRIANGLES, 0, (int)TextObj->m_BgVerts.size());
550         }
551         _glEnable(GL_TEXTURE_2D);
552         _glBindTexture(GL_TEXTURE_2D, m_FontTexID);
553         _glEnableClientState(GL_TEXTURE_COORD_ARRAY);
554         _glVertexPointer(2, GL_FLOAT, 0, &(TextObj->m_TextVerts[0]));
555         _glTexCoordPointer(2, GL_FLOAT, 0, &(TextObj->m_TextUVs[0]));
556         if( TextObj->m_Colors.size()==TextObj->m_TextVerts.size() && _Color==0 )
557         {
558                 _glEnableClientState(GL_COLOR_ARRAY);
559                 _glColorPointer(4, GL_UNSIGNED_BYTE, 0, &(TextObj->m_Colors[0]));
560         }
561         else
562         {
563                 _glDisableClientState(GL_COLOR_ARRAY);
564                 _glColor4ub(GLubyte(_Color>>16), GLubyte(_Color>>8), GLubyte(_Color), GLubyte(_Color>>24));
565         }
566
567         _glDrawArrays(GL_TRIANGLES, 0, (int)TextObj->m_TextVerts.size());
568         
569         _glDisableClientState(GL_VERTEX_ARRAY);
570         _glDisableClientState(GL_TEXTURE_COORD_ARRAY);
571         _glDisableClientState(GL_COLOR_ARRAY);
572 }
573
574 //      ---------------------------------------------------------------------------