1 // ---------------------------------------------------------------------------
2 //
3 // @file TwOpenGL.cpp
4 // @author Philippe Decaudin
5 // @license This file is part of the AntTweakBar library.
6 // For conditions of distribution and use, see License.txt
7 //
8 // ---------------------------------------------------------------------------
9
10
11 #include "TwPrecomp.h"
12 #include "LoadOGL.h"
13 #include "TwOpenGL.h"
14 #include "TwMgr.h"
15
16 using namespace std;
17
18 const char *g_ErrCantLoadOGL = "Cannot load OpenGL library dynamically";
19 const char *g_ErrCantUnloadOGL = "Cannot unload OpenGL library";
20
21 GLuint g_SmallFontTexID = 0;
22 GLuint g_NormalFontTexID = 0;
23 GLuint g_LargeFontTexID = 0;
24
25 // ---------------------------------------------------------------------------
26 // Extensions
27
28 typedef void (APIENTRY * PFNGLBindBufferARB)(GLenum target, GLuint buffer);
29 typedef void (APIENTRY * PFNGLBindProgramARB)(GLenum target, GLuint program);
30 typedef GLuint (APIENTRY * PFNGLGetHandleARB)(GLenum pname);
31 typedef void (APIENTRY * PFNGLUseProgramObjectARB)(GLuint programObj);
32 typedef void (APIENTRY * PFNGLTexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
33 typedef void (APIENTRY * PFNGLActiveTextureARB)(GLenum texture);
34 typedef void (APIENTRY * PFNGLClientActiveTextureARB)(GLenum texture);
35 typedef void (APIENTRY * PFNGLBlendEquation)(GLenum mode);
36 typedef void (APIENTRY * PFNGLBlendEquationSeparate)(GLenum srcMode, GLenum dstMode);
37 typedef void (APIENTRY * PFNGLBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
38 typedef void (APIENTRY * PFNGLBindVertexArray)(GLuint array);
39 typedef void (APIENTRY * PFNGLEnableVertexAttribArray) (GLuint index);
40 typedef void (APIENTRY * PFNGLDisableVertexAttribArray) (GLuint index);
41 typedef void (APIENTRY * PFNGLGetVertexAttribiv) (GLuint, GLenum, GLint*);
42 PFNGLBindBufferARB _glBindBufferARB = NULL;
43 PFNGLBindProgramARB _glBindProgramARB = NULL;
44 PFNGLGetHandleARB _glGetHandleARB = NULL;
45 PFNGLUseProgramObjectARB _glUseProgramObjectARB = NULL;
46 PFNGLTexImage3D _glTexImage3D = NULL;
47 PFNGLActiveTextureARB _glActiveTextureARB = NULL;
48 PFNGLClientActiveTextureARB _glClientActiveTextureARB = NULL;
49 PFNGLBlendEquation _glBlendEquation = NULL;
50 PFNGLBlendEquationSeparate _glBlendEquationSeparate = NULL;
51 PFNGLBlendFuncSeparate _glBlendFuncSeparate = NULL;
52 PFNGLBindVertexArray _glBindVertexArray = NULL;
53 PFNGLEnableVertexAttribArray _glEnableVertexAttribArray = NULL;
54 PFNGLDisableVertexAttribArray _glDisableVertexAttribArray = NULL;
55 PFNGLGetVertexAttribiv _glGetVertexAttribiv = NULL;
56 #ifndef GL_ARRAY_BUFFER_ARB
57 # define GL_ARRAY_BUFFER_ARB 0x8892
58 #endif
59 #ifndef GL_ELEMENT_ARRAY_BUFFER_ARB
60 # define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
61 #endif
62 #ifndef GL_ARRAY_BUFFER_BINDING_ARB
63 # define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
64 #endif
65 #ifndef GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB
66 # define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
67 #endif
68 #ifndef GL_VERTEX_PROGRAM_ARB
69 # define GL_VERTEX_PROGRAM_ARB 0x8620
70 #endif
71 #ifndef GL_FRAGMENT_PROGRAM_ARB
72 # define GL_FRAGMENT_PROGRAM_ARB 0x8804
73 #endif
74 #ifndef GL_PROGRAM_OBJECT_ARB
75 # define GL_PROGRAM_OBJECT_ARB 0x8B40
76 #endif
77 #ifndef GL_TEXTURE_3D
78 # define GL_TEXTURE_3D 0x806F
79 #endif
80 #ifndef GL_TEXTURE0_ARB
81 # define GL_TEXTURE0_ARB 0x84C0
82 #endif
83 #ifndef GL_ACTIVE_TEXTURE_ARB
84 # define GL_ACTIVE_TEXTURE_ARB 0x84E0
85 #endif
86 #ifndef GL_CLIENT_ACTIVE_TEXTURE_ARB
87 # define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
88 #endif
89 #ifndef GL_MAX_TEXTURE_UNITS_ARB
90 # define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
91 #endif
92 #ifndef GL_MAX_TEXTURE_COORDS
93 # define GL_MAX_TEXTURE_COORDS 0x8871
94 #endif
95 #ifndef GL_TEXTURE_RECTANGLE_ARB
96 # define GL_TEXTURE_RECTANGLE_ARB 0x84F5
97 #endif
98 #ifndef GL_FUNC_ADD
99 # define GL_FUNC_ADD 0x8006
100 #endif
101 #ifndef GL_BLEND_EQUATION
102 # define GL_BLEND_EQUATION 0x8009
103 #endif
104 #ifndef GL_BLEND_EQUATION_RGB
105 # define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
106 #endif
107 #ifndef GL_BLEND_EQUATION_ALPHA
108 # define GL_BLEND_EQUATION_ALPHA 0x883D
109 #endif
110 #ifndef GL_BLEND_SRC_RGB
111 # define GL_BLEND_SRC_RGB 0x80C9
112 #endif
113 #ifndef GL_BLEND_DST_RGB
114 # define GL_BLEND_DST_RGB 0x80C8
115 #endif
116 #ifndef GL_BLEND_SRC_ALPHA
117 # define GL_BLEND_SRC_ALPHA 0x80CB
118 #endif
119 #ifndef GL_BLEND_DST_ALPHA
120 # define GL_BLEND_DST_ALPHA 0x80CA
121 #endif
122 #ifndef GL_VERTEX_ARRAY_BINDING
123 # define GL_VERTEX_ARRAY_BINDING 0x85B5
124 #endif
125 #ifndef GL_MAX_VERTEX_ATTRIBS
126 # define GL_MAX_VERTEX_ATTRIBS 0x8869
127 #endif
128 #ifndef GL_VERTEX_ATTRIB_ARRAY_ENABLED
129 # define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
130 #endif
131
132 // ---------------------------------------------------------------------------
133
134 #ifdef _DEBUG
CheckGLError(const char * file,int line,const char * func)135 static void CheckGLError(const char *file, int line, const char *func)
136 {
137 int err=0;
138 char msg[256];
139 while( (err=_glGetError())!=0 )
140 {
141 sprintf(msg, "%s(%d) : [%s] GL_ERROR=0x%x\n", file, line, func, err);
142 #ifdef ANT_WINDOWS
143 OutputDebugString(msg);
144 #endif
145 fprintf(stderr, msg);
146 }
147 }
148 # ifdef __FUNCTION__
149 # define CHECK_GL_ERROR CheckGLError(__FILE__, __LINE__, __FUNCTION__)
150 # else
151 # define CHECK_GL_ERROR CheckGLError(__FILE__, __LINE__, "")
152 # endif
153 #else
154 # define CHECK_GL_ERROR ((void)(0))
155 #endif
156
157 // ---------------------------------------------------------------------------
158
BindFont(const CTexFont * _Font)159 static GLuint BindFont(const CTexFont *_Font)
160 {
161 GLuint TexID = 0;
162 _glGenTextures(1, &TexID);
163 _glBindTexture(GL_TEXTURE_2D, TexID);
164 _glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
165 _glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
166 _glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
167 _glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
168 _glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
169 _glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
170 _glPixelTransferf(GL_ALPHA_SCALE, 1);
171 _glPixelTransferf(GL_ALPHA_BIAS, 0);
172 _glPixelTransferf(GL_RED_BIAS, 1);
173 _glPixelTransferf(GL_GREEN_BIAS, 1);
174 _glPixelTransferf(GL_BLUE_BIAS, 1);
175 _glTexImage2D(GL_TEXTURE_2D, 0, 4, _Font->m_TexWidth, _Font->m_TexHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, _Font->m_TexBytes);
176 _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
177 _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
178 _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
179 _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
180 _glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
181 _glBindTexture(GL_TEXTURE_2D, 0);
182 _glPixelTransferf(GL_ALPHA_BIAS, 0);
183 _glPixelTransferf(GL_RED_BIAS, 0);
184 _glPixelTransferf(GL_GREEN_BIAS, 0);
185 _glPixelTransferf(GL_BLUE_BIAS, 0);
186
187 return TexID;
188 }
189
UnbindFont(GLuint _FontTexID)190 static void UnbindFont(GLuint _FontTexID)
191 {
192 if( _FontTexID>0 )
193 _glDeleteTextures(1, &_FontTexID);
194 }
195
196 // ---------------------------------------------------------------------------
197
Init()198 int CTwGraphOpenGL::Init()
199 {
200 m_Drawing = false;
201 m_FontTexID = 0;
202 m_FontTex = NULL;
203 m_MaxClipPlanes = -1;
204
205 if( LoadOpenGL()==0 )
206 {
207 g_TwMgr->SetLastError(g_ErrCantLoadOGL);
208 return 0;
209 }
210
211 // Get extensions
212 _glBindBufferARB = reinterpret_cast<PFNGLBindBufferARB>(_glGetProcAddress("glBindBufferARB"));
213 _glBindProgramARB = reinterpret_cast<PFNGLBindProgramARB>(_glGetProcAddress("glBindProgramARB"));
214 _glGetHandleARB = reinterpret_cast<PFNGLGetHandleARB>(_glGetProcAddress("glGetHandleARB"));
215 _glUseProgramObjectARB = reinterpret_cast<PFNGLUseProgramObjectARB>(_glGetProcAddress("glUseProgramObjectARB"));
216 _glTexImage3D = reinterpret_cast<PFNGLTexImage3D>(_glGetProcAddress("glTexImage3D"));
217 _glActiveTextureARB = reinterpret_cast<PFNGLActiveTextureARB>(_glGetProcAddress("glActiveTextureARB"));
218 _glClientActiveTextureARB = reinterpret_cast<PFNGLClientActiveTextureARB>(_glGetProcAddress("glClientActiveTextureARB"));
219 _glBlendEquation = reinterpret_cast<PFNGLBlendEquation>(_glGetProcAddress("glBlendEquation"));
220 _glBlendEquationSeparate = reinterpret_cast<PFNGLBlendEquationSeparate>(_glGetProcAddress("glBlendEquationSeparate"));
221 _glBlendFuncSeparate = reinterpret_cast<PFNGLBlendFuncSeparate>(_glGetProcAddress("glBlendFuncSeparate"));
222 _glBindVertexArray = reinterpret_cast<PFNGLBindVertexArray>(_glGetProcAddress("glBindVertexArray"));
223 _glEnableVertexAttribArray = reinterpret_cast<PFNGLEnableVertexAttribArray>(_glGetProcAddress("glEnableVertexAttribArray"));
224 _glDisableVertexAttribArray = reinterpret_cast<PFNGLDisableVertexAttribArray>(_glGetProcAddress("glDisableVertexAttribArray"));
225 _glGetVertexAttribiv = reinterpret_cast<PFNGLGetVertexAttribiv>(_glGetProcAddress("glGetVertexAttribiv"));
226
227 m_SupportTexRect = false; // updated in BeginDraw
228
229 return 1;
230 }
231
232 // ---------------------------------------------------------------------------
233
Shut()234 int CTwGraphOpenGL::Shut()
235 {
236 assert(m_Drawing==false);
237
238 UnbindFont(m_FontTexID);
239
240 int Res = 1;
241 if( UnloadOpenGL()==0 )
242 {
243 g_TwMgr->SetLastError(g_ErrCantUnloadOGL);
244 Res = 0;
245 }
246
247 return Res;
248 }
249
250 // ---------------------------------------------------------------------------
251
BeginDraw(int _WndWidth,int _WndHeight)252 void CTwGraphOpenGL::BeginDraw(int _WndWidth, int _WndHeight)
253 {
254 assert(m_Drawing==false && _WndWidth>0 && _WndHeight>0);
255 m_Drawing = true;
256 m_WndWidth = _WndWidth;
257 m_WndHeight = _WndHeight;
258
259 CHECK_GL_ERROR;
260
261 //#if !defined(ANT_OSX)
262 static bool s_SupportTexRectChecked = false;
263 if (!s_SupportTexRectChecked)
264 {
265 const char *ext = (const char *)_glGetString(GL_EXTENSIONS);
266 if( ext!=0 && strlen(ext)>0 )
267 m_SupportTexRect = (strstr(ext, "GL_ARB_texture_rectangle")!=NULL);
268 s_SupportTexRectChecked = true;
269 }
270 //#endif
271
272 _glPushAttrib(GL_ALL_ATTRIB_BITS);
273 _glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
274
275 if( _glActiveTextureARB )
276 {
277 _glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &m_PrevActiveTextureARB);
278 _glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE_ARB, &m_PrevClientActiveTextureARB);
279 GLint maxTexUnits = 1;
280 _glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxTexUnits); // was GL_MAX_TEXTURE_UNITS_ARB
281 if( maxTexUnits<1 )
282 maxTexUnits = 1;
283 else if( maxTexUnits > MAX_TEXTURES )
284 maxTexUnits = MAX_TEXTURES;
285 GLint i;
286 for( i=0; i<maxTexUnits; ++i )
287 {
288 _glActiveTextureARB(GL_TEXTURE0_ARB+i);
289 m_PrevActiveTexture1D[i] = _glIsEnabled(GL_TEXTURE_1D);
290 m_PrevActiveTexture2D[i] = _glIsEnabled(GL_TEXTURE_2D);
291 m_PrevActiveTexture3D[i] = _glIsEnabled(GL_TEXTURE_3D);
292 _glDisable(GL_TEXTURE_1D);
293 _glDisable(GL_TEXTURE_2D);
294 _glDisable(GL_TEXTURE_3D);
295 }
296 _glActiveTextureARB(GL_TEXTURE0_ARB);
297
298 for( i=0; i<maxTexUnits; i++ )
299 {
300 _glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
301 m_PrevClientTexCoordArray[i] = _glIsEnabled(GL_TEXTURE_COORD_ARRAY);
302 _glDisableClientState(GL_TEXTURE_COORD_ARRAY);
303 }
304 _glClientActiveTextureARB(GL_TEXTURE0_ARB);
305 }
306
307 _glMatrixMode(GL_TEXTURE);
308 _glPushMatrix();
309 _glLoadIdentity();
310 _glMatrixMode(GL_MODELVIEW);
311 _glPushMatrix();
312 _glLoadIdentity();
313 _glMatrixMode(GL_PROJECTION);
314 _glPushMatrix();
315 GLint Vp[4];
316 _glGetIntegerv(GL_VIEWPORT, Vp);
317 /*
318 if( _WndWidth>0 && _WndHeight>0 )
319 {
320 Vp[0] = 0;
321 Vp[1] = 0;
322 Vp[2] = _WndWidth;
323 Vp[3] = _WndHeight;
324 _glViewport(Vp[0], Vp[1], Vp[2], Vp[3]);
325 }
326 _glLoadIdentity();
327 //_glOrtho(Vp[0], Vp[0]+Vp[2]-1, Vp[1]+Vp[3]-1, Vp[1], -1, 1); // Doesn't work
328 _glOrtho(Vp[0], Vp[0]+Vp[2], Vp[1]+Vp[3], Vp[1], -1, 1);
329 */
330 if( _WndWidth>0 && _WndHeight>0 )
331 {
332 Vp[0] = 0;
333 Vp[1] = 0;
334 Vp[2] = _WndWidth-1;
335 Vp[3] = _WndHeight-1;
336 _glViewport(Vp[0], Vp[1], Vp[2], Vp[3]);
337 }
338 _glLoadIdentity();
339 _glOrtho(Vp[0], Vp[0]+Vp[2], Vp[1]+Vp[3], Vp[1], -1, 1);
340 _glGetIntegerv(GL_VIEWPORT, m_ViewportInit);
341 _glGetFloatv(GL_PROJECTION_MATRIX, m_ProjMatrixInit);
342
343 _glGetFloatv(GL_LINE_WIDTH, &m_PrevLineWidth);
344 _glDisable(GL_POLYGON_STIPPLE);
345 _glLineWidth(1);
346 _glDisable(GL_LINE_SMOOTH);
347 _glDisable(GL_LINE_STIPPLE);
348 _glDisable(GL_CULL_FACE);
349 _glDisable(GL_DEPTH_TEST);
350 _glDisable(GL_LIGHTING);
351 _glEnable(GL_BLEND);
352 _glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
353 _glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &m_PrevTexEnv);
354 _glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
355 _glGetIntegerv(GL_POLYGON_MODE, m_PrevPolygonMode);
356 _glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
357 _glDisable(GL_ALPHA_TEST);
358 //_glEnable(GL_ALPHA_TEST);
359 //_glAlphaFunc(GL_GREATER, 0);
360 _glDisable(GL_FOG);
361 _glDisable(GL_LOGIC_OP);
362 _glDisable(GL_SCISSOR_TEST);
363 if( m_MaxClipPlanes<0 )
364 {
365 _glGetIntegerv(GL_MAX_CLIP_PLANES, &m_MaxClipPlanes);
366 if( m_MaxClipPlanes<0 || m_MaxClipPlanes>255 )
367 m_MaxClipPlanes = 6;
368 }
369 for( GLint i=0; i<m_MaxClipPlanes; ++i )
370 _glDisable(GL_CLIP_PLANE0+i);
371 m_PrevTexture = 0;
372 _glGetIntegerv(GL_TEXTURE_BINDING_2D, &m_PrevTexture);
373
374 _glDisableClientState(GL_VERTEX_ARRAY);
375 _glDisableClientState(GL_NORMAL_ARRAY);
376 _glDisableClientState(GL_TEXTURE_COORD_ARRAY);
377 _glDisableClientState(GL_INDEX_ARRAY);
378 _glDisableClientState(GL_COLOR_ARRAY);
379 _glDisableClientState(GL_EDGE_FLAG_ARRAY);
380
381 if( _glBindVertexArray!=NULL )
382 {
383 m_PrevVertexArray = 0;
384 _glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&m_PrevVertexArray);
385 _glBindVertexArray(0);
386 }
387 if( _glBindBufferARB!=NULL )
388 {
389 m_PrevArrayBufferARB = m_PrevElementArrayBufferARB = 0;
390 _glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &m_PrevArrayBufferARB);
391 _glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &m_PrevElementArrayBufferARB);
392 _glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
393 _glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
394 }
395 if( _glBindProgramARB!=NULL )
396 {
397 m_PrevVertexProgramARB = _glIsEnabled(GL_VERTEX_PROGRAM_ARB);
398 m_PrevFragmentProgramARB = _glIsEnabled(GL_FRAGMENT_PROGRAM_ARB);
399 _glDisable(GL_VERTEX_PROGRAM_ARB);
400 _glDisable(GL_FRAGMENT_PROGRAM_ARB);
401 }
402 if( _glGetHandleARB!=NULL && _glUseProgramObjectARB!=NULL )
403 {
404 m_PrevProgramObjectARB = _glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
405 _glUseProgramObjectARB(0);
406 }
407 _glDisable(GL_TEXTURE_1D);
408 _glDisable(GL_TEXTURE_2D);
409 if( _glTexImage3D!=NULL )
410 {
411 m_PrevTexture3D = _glIsEnabled(GL_TEXTURE_3D);
412 _glDisable(GL_TEXTURE_3D);
413 }
414
415 if( m_SupportTexRect )
416 {
417 m_PrevTexRectARB = _glIsEnabled(GL_TEXTURE_RECTANGLE_ARB);
418 _glDisable(GL_TEXTURE_RECTANGLE_ARB);
419 }
420 if( _glBlendEquationSeparate!=NULL )
421 {
422 _glGetIntegerv(GL_BLEND_EQUATION_RGB, &m_PrevBlendEquationRGB);
423 _glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &m_PrevBlendEquationAlpha);
424 _glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
425 }
426 if( _glBlendFuncSeparate!=NULL )
427 {
428 _glGetIntegerv(GL_BLEND_SRC_RGB, &m_PrevBlendSrcRGB);
429 _glGetIntegerv(GL_BLEND_DST_RGB, &m_PrevBlendDstRGB);
430 _glGetIntegerv(GL_BLEND_SRC_ALPHA, &m_PrevBlendSrcAlpha);
431 _glGetIntegerv(GL_BLEND_DST_ALPHA, &m_PrevBlendDstAlpha);
432 _glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
433 }
434 if( _glBlendEquation!=NULL )
435 {
436 _glGetIntegerv(GL_BLEND_EQUATION, &m_PrevBlendEquation);
437 _glBlendEquation(GL_FUNC_ADD);
438 }
439 if( _glDisableVertexAttribArray!=NULL )
440 {
441 GLint maxVertexAttribs;
442 _glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
443 if(maxVertexAttribs>MAX_VERTEX_ATTRIBS)
444 maxVertexAttribs=MAX_VERTEX_ATTRIBS;
445
446 for(int i=0; i<maxVertexAttribs; i++)
447 {
448 _glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &m_PrevEnabledVertexAttrib[i]);
449 _glDisableVertexAttribArray(i);
450 }
451 }
452
453 CHECK_GL_ERROR;
454 }
455
456 // ---------------------------------------------------------------------------
457
EndDraw()458 void CTwGraphOpenGL::EndDraw()
459 {
460 assert(m_Drawing==true);
461 m_Drawing = false;
462
463 _glBindTexture(GL_TEXTURE_2D, m_PrevTexture);
464 if( _glBindVertexArray!=NULL )
465 _glBindVertexArray(m_PrevVertexArray);
466 if( _glBindBufferARB!=NULL )
467 {
468 _glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_PrevArrayBufferARB);
469 _glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_PrevElementArrayBufferARB);
470 }
471 if( _glBindProgramARB!=NULL )
472 {
473 if( m_PrevVertexProgramARB )
474 _glEnable(GL_VERTEX_PROGRAM_ARB);
475 if( m_PrevFragmentProgramARB )
476 _glEnable(GL_FRAGMENT_PROGRAM_ARB);
477 }
478 if( _glGetHandleARB!=NULL && _glUseProgramObjectARB!=NULL )
479 _glUseProgramObjectARB(m_PrevProgramObjectARB);
480 if( _glTexImage3D!=NULL && m_PrevTexture3D )
481 _glEnable(GL_TEXTURE_3D);
482 if( m_SupportTexRect && m_PrevTexRectARB )
483 _glEnable(GL_TEXTURE_RECTANGLE_ARB);
484 if( _glBlendEquation!=NULL )
485 _glBlendEquation(m_PrevBlendEquation);
486 if( _glBlendEquationSeparate!=NULL )
487 _glBlendEquationSeparate(m_PrevBlendEquationRGB, m_PrevBlendEquationAlpha);
488 if( _glBlendFuncSeparate!=NULL )
489 _glBlendFuncSeparate(m_PrevBlendSrcRGB, m_PrevBlendDstRGB, m_PrevBlendSrcAlpha, m_PrevBlendDstAlpha);
490
491 _glPolygonMode(GL_FRONT, m_PrevPolygonMode[0]);
492 _glPolygonMode(GL_BACK, m_PrevPolygonMode[1]);
493 _glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_PrevTexEnv);
494 _glLineWidth(m_PrevLineWidth);
495 _glMatrixMode(GL_PROJECTION);
496 _glPopMatrix();
497 _glMatrixMode(GL_MODELVIEW);
498 _glPopMatrix();
499 _glMatrixMode(GL_TEXTURE);
500 _glPopMatrix();
501 _glPopClientAttrib();
502 _glPopAttrib();
503
504 if( _glActiveTextureARB )
505 {
506 GLint maxTexUnits = 1;
507 _glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxTexUnits); // was GL_MAX_TEXTURE_UNITS_ARB
508 if( maxTexUnits<1 )
509 maxTexUnits = 1;
510 else if( maxTexUnits > MAX_TEXTURES )
511 maxTexUnits = MAX_TEXTURES;
512 GLint i;
513 for( i=0; i<maxTexUnits; ++i )
514 {
515 _glActiveTextureARB(GL_TEXTURE0_ARB+i);
516 if( m_PrevActiveTexture1D[i] )
517 _glEnable(GL_TEXTURE_1D);
518 if( m_PrevActiveTexture2D[i] )
519 _glEnable(GL_TEXTURE_2D);
520 if( m_PrevActiveTexture3D[i] )
521 _glEnable(GL_TEXTURE_3D);
522 }
523 _glActiveTextureARB(m_PrevActiveTextureARB);
524
525 for( i=0; i<maxTexUnits; ++i )
526 {
527 _glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
528 if( m_PrevClientTexCoordArray[i] )
529 _glEnableClientState(GL_TEXTURE_COORD_ARRAY);
530 }
531 _glClientActiveTextureARB(m_PrevClientActiveTextureARB);
532 }
533 if(_glEnableVertexAttribArray)
534 {
535 GLint maxVertexAttribs;
536 _glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
537 if(maxVertexAttribs>MAX_VERTEX_ATTRIBS)
538 maxVertexAttribs=MAX_VERTEX_ATTRIBS;
539
540 for(int i=0; i<maxVertexAttribs; i++)
541 {
542 if(m_PrevEnabledVertexAttrib[i]!=0)
543 _glEnableVertexAttribArray(i);
544 }
545 }
546
547 CHECK_GL_ERROR;
548 }
549
550 // ---------------------------------------------------------------------------
551
IsDrawing()552 bool CTwGraphOpenGL::IsDrawing()
553 {
554 return m_Drawing;
555 }
556
557 // ---------------------------------------------------------------------------
558
Restore()559 void CTwGraphOpenGL::Restore()
560 {
561 UnbindFont(m_FontTexID);
562 m_FontTexID = 0;
563 m_FontTex = NULL;
564 }
565
566
567 // ---------------------------------------------------------------------------
568
DrawLine(int _X0,int _Y0,int _X1,int _Y1,color32 _Color0,color32 _Color1,bool _AntiAliased)569 void CTwGraphOpenGL::DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased)
570 {
571 assert(m_Drawing==true);
572 /*
573 // border adjustment NO!!
574 if(_X0<_X1)
575 ++_X1;
576 else if(_X0>_X1)
577 ++_X0;
578 if(_Y0<_Y1)
579 ++_Y1;
580 else if(_Y0>_Y1)
581 ++_Y0;
582 */
583 //const GLfloat dx = +0.0f;
584 const GLfloat dx = +0.5f;
585 //GLfloat dy = -0.2f;
586 const GLfloat dy = -0.5f;
587 if( _AntiAliased )
588 _glEnable(GL_LINE_SMOOTH);
589 else
590 _glDisable(GL_LINE_SMOOTH);
591 _glDisable(GL_TEXTURE_2D);
592 _glMatrixMode(GL_MODELVIEW);
593 _glLoadIdentity();
594 _glBegin(GL_LINES);
595 _glColor4ub(GLubyte(_Color0>>16), GLubyte(_Color0>>8), GLubyte(_Color0), GLubyte(_Color0>>24));
596 _glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y0+dy);
597 _glColor4ub(GLubyte(_Color1>>16), GLubyte(_Color1>>8), GLubyte(_Color1), GLubyte(_Color1>>24));
598 _glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y1+dy);
599 //_glVertex2i(_X0, _Y0);
600 //_glVertex2i(_X1, _Y1);
601 _glEnd();
602 _glDisable(GL_LINE_SMOOTH);
603 }
604
605 // ---------------------------------------------------------------------------
606
DrawRect(int _X0,int _Y0,int _X1,int _Y1,color32 _Color00,color32 _Color10,color32 _Color01,color32 _Color11)607 void CTwGraphOpenGL::DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11)
608 {
609 assert(m_Drawing==true);
610
611 /*
612 // border adjustment
613 if(_X0<_X1)
614 ++_X1;
615 else if(_X0>_X1)
616 ++_X0;
617 if(_Y0<_Y1)
618 ++_Y1;
619 else if(_Y0>_Y1)
620 ++_Y0;
621 */
622 // border adjustment
623 if(_X0<_X1)
624 ++_X1;
625 else if(_X0>_X1)
626 ++_X0;
627 if(_Y0<_Y1)
628 --_Y0;
629 else if(_Y0>_Y1)
630 --_Y1;
631 const GLfloat dx = +0.0f;
632 const GLfloat dy = +0.0f;
633
634 _glDisable(GL_TEXTURE_2D);
635 _glMatrixMode(GL_MODELVIEW);
636 _glLoadIdentity();
637 //GLubyte r = GLubyte(_Color>>16);
638 //GLubyte g = GLubyte(_Color>>8);
639 //GLubyte b = GLubyte(_Color);
640 //GLubyte a = GLubyte(_Color>>24);
641 //_glColor4ub(GLubyte(_Color>>16), GLubyte(_Color>>8), GLubyte(_Color), GLubyte(_Color>>24));
642 //_glColor4ub(r, g, b, a);
643 _glBegin(GL_QUADS);
644 _glColor4ub(GLubyte(_Color00>>16), GLubyte(_Color00>>8), GLubyte(_Color00), GLubyte(_Color00>>24));
645 _glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y0+dy);
646 _glColor4ub(GLubyte(_Color10>>16), GLubyte(_Color10>>8), GLubyte(_Color10), GLubyte(_Color10>>24));
647 _glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y0+dy);
648 _glColor4ub(GLubyte(_Color11>>16), GLubyte(_Color11>>8), GLubyte(_Color11), GLubyte(_Color11>>24));
649 _glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y1+dy);
650 _glColor4ub(GLubyte(_Color01>>16), GLubyte(_Color01>>8), GLubyte(_Color01), GLubyte(_Color01>>24));
651 _glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y1+dy);
652 _glEnd();
653 }
654
655 // ---------------------------------------------------------------------------
656
NewTextObj()657 void *CTwGraphOpenGL::NewTextObj()
658 {
659 return new CTextObj;
660 }
661
662 // ---------------------------------------------------------------------------
663
DeleteTextObj(void * _TextObj)664 void CTwGraphOpenGL::DeleteTextObj(void *_TextObj)
665 {
666 assert(_TextObj!=NULL);
667 delete static_cast<CTextObj *>(_TextObj);
668 }
669
670 // ---------------------------------------------------------------------------
671
BuildText(void * _TextObj,const std::string * _TextLines,color32 * _LineColors,color32 * _LineBgColors,int _NbLines,const CTexFont * _Font,int _Sep,int _BgWidth)672 void CTwGraphOpenGL::BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth)
673 {
674 assert(m_Drawing==true);
675 assert(_TextObj!=NULL);
676 assert(_Font!=NULL);
677
678 if( _Font != m_FontTex )
679 {
680 UnbindFont(m_FontTexID);
681 m_FontTexID = BindFont(_Font);
682 m_FontTex = _Font;
683 }
684 CTextObj *TextObj = static_cast<CTextObj *>(_TextObj);
685 TextObj->m_TextVerts.resize(0);
686 TextObj->m_TextUVs.resize(0);
687 TextObj->m_BgVerts.resize(0);
688 TextObj->m_Colors.resize(0);
689 TextObj->m_BgColors.resize(0);
690
691 int x, x1, y, y1, i, Len;
692 unsigned char ch;
693 const unsigned char *Text;
694 color32 LineColor = COLOR32_RED;
695 for( int Line=0; Line<_NbLines; ++Line )
696 {
697 x = 0;
698 y = Line * (_Font->m_CharHeight+_Sep);
699 y1 = y+_Font->m_CharHeight;
700 Len = (int)_TextLines[Line].length();
701 Text = (const unsigned char *)(_TextLines[Line].c_str());
702 if( _LineColors!=NULL )
703 LineColor = (_LineColors[Line]&0xff00ff00) | GLubyte(_LineColors[Line]>>16) | (GLubyte(_LineColors[Line])<<16);
704
705 for( i=0; i<Len; ++i )
706 {
707 ch = Text[i];
708 x1 = x + _Font->m_CharWidth[ch];
709
710 TextObj->m_TextVerts.push_back(Vec2(x , y ));
711 TextObj->m_TextVerts.push_back(Vec2(x1, y ));
712 TextObj->m_TextVerts.push_back(Vec2(x , y1));
713 TextObj->m_TextVerts.push_back(Vec2(x1, y ));
714 TextObj->m_TextVerts.push_back(Vec2(x1, y1));
715 TextObj->m_TextVerts.push_back(Vec2(x , y1));
716
717 TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV0[ch]));
718 TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV0[ch]));
719 TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV1[ch]));
720 TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV0[ch]));
721 TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV1[ch]));
722 TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV1[ch]));
723
724 if( _LineColors!=NULL )
725 {
726 TextObj->m_Colors.push_back(LineColor);
727 TextObj->m_Colors.push_back(LineColor);
728 TextObj->m_Colors.push_back(LineColor);
729 TextObj->m_Colors.push_back(LineColor);
730 TextObj->m_Colors.push_back(LineColor);
731 TextObj->m_Colors.push_back(LineColor);
732 }
733
734 x = x1;
735 }
736 if( _BgWidth>0 )
737 {
738 TextObj->m_BgVerts.push_back(Vec2(-1 , y ));
739 TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y ));
740 TextObj->m_BgVerts.push_back(Vec2(-1 , y1));
741 TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y ));
742 TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y1));
743 TextObj->m_BgVerts.push_back(Vec2(-1 , y1));
744
745 if( _LineBgColors!=NULL )
746 {
747 color32 LineBgColor = (_LineBgColors[Line]&0xff00ff00) | GLubyte(_LineBgColors[Line]>>16) | (GLubyte(_LineBgColors[Line])<<16);
748 TextObj->m_BgColors.push_back(LineBgColor);
749 TextObj->m_BgColors.push_back(LineBgColor);
750 TextObj->m_BgColors.push_back(LineBgColor);
751 TextObj->m_BgColors.push_back(LineBgColor);
752 TextObj->m_BgColors.push_back(LineBgColor);
753 TextObj->m_BgColors.push_back(LineBgColor);
754 }
755 }
756 }
757 }
758
759 // ---------------------------------------------------------------------------
760
DrawText(void * _TextObj,int _X,int _Y,color32 _Color,color32 _BgColor)761 void CTwGraphOpenGL::DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor)
762 {
763 assert(m_Drawing==true);
764 assert(_TextObj!=NULL);
765 CTextObj *TextObj = static_cast<CTextObj *>(_TextObj);
766
767 if( TextObj->m_TextVerts.size()<4 && TextObj->m_BgVerts.size()<4 )
768 return; // nothing to draw
769
770 _glMatrixMode(GL_MODELVIEW);
771 _glLoadIdentity();
772 _glTranslatef((GLfloat)_X, (GLfloat)_Y, 0);
773 _glEnableClientState(GL_VERTEX_ARRAY);
774 if( (_BgColor!=0 || TextObj->m_BgColors.size()==TextObj->m_BgVerts.size()) && TextObj->m_BgVerts.size()>=4 )
775 {
776 _glDisable(GL_TEXTURE_2D);
777 _glVertexPointer(2, GL_FLOAT, 0, &(TextObj->m_BgVerts[0]));
778 if( TextObj->m_BgColors.size()==TextObj->m_BgVerts.size() && _BgColor==0 )
779 {
780 _glEnableClientState(GL_COLOR_ARRAY);
781 _glColorPointer(4, GL_UNSIGNED_BYTE, 0, &(TextObj->m_BgColors[0]));
782 }
783 else
784 {
785 _glDisableClientState(GL_COLOR_ARRAY);
786 _glColor4ub(GLubyte(_BgColor>>16), GLubyte(_BgColor>>8), GLubyte(_BgColor), GLubyte(_BgColor>>24));
787 }
788 _glDrawArrays(GL_TRIANGLES, 0, (int)TextObj->m_BgVerts.size());
789 }
790 _glEnable(GL_TEXTURE_2D);
791 _glBindTexture(GL_TEXTURE_2D, m_FontTexID);
792 _glEnableClientState(GL_TEXTURE_COORD_ARRAY);
793 if( TextObj->m_TextVerts.size()>=4 )
794 {
795 _glVertexPointer(2, GL_FLOAT, 0, &(TextObj->m_TextVerts[0]));
796 _glTexCoordPointer(2, GL_FLOAT, 0, &(TextObj->m_TextUVs[0]));
797 if( TextObj->m_Colors.size()==TextObj->m_TextVerts.size() && _Color==0 )
798 {
799 _glEnableClientState(GL_COLOR_ARRAY);
800 _glColorPointer(4, GL_UNSIGNED_BYTE, 0, &(TextObj->m_Colors[0]));
801 }
802 else
803 {
804 _glDisableClientState(GL_COLOR_ARRAY);
805 _glColor4ub(GLubyte(_Color>>16), GLubyte(_Color>>8), GLubyte(_Color), GLubyte(_Color>>24));
806 }
807
808 _glDrawArrays(GL_TRIANGLES, 0, (int)TextObj->m_TextVerts.size());
809 }
810
811 _glDisableClientState(GL_VERTEX_ARRAY);
812 _glDisableClientState(GL_TEXTURE_COORD_ARRAY);
813 _glDisableClientState(GL_COLOR_ARRAY);
814 }
815
816 // ---------------------------------------------------------------------------
817
ChangeViewport(int _X0,int _Y0,int _Width,int _Height,int _OffsetX,int _OffsetY)818 void CTwGraphOpenGL::ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY)
819 {
820 if( _Width>0 && _Height>0 )
821 {
822 GLint vp[4];
823 vp[0] = _X0;
824 vp[1] = _Y0;
825 vp[2] = _Width-1;
826 vp[3] = _Height-1;
827 _glViewport(vp[0], m_WndHeight-vp[1]-vp[3], vp[2], vp[3]);
828
829 GLint matrixMode = 0;
830 _glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
831 _glMatrixMode(GL_PROJECTION);
832 _glLoadIdentity();
833 _glOrtho(_OffsetX, _OffsetX+vp[2], vp[3]-_OffsetY, -_OffsetY, -1, 1);
834 _glMatrixMode(matrixMode);
835 }
836 }
837
838 // ---------------------------------------------------------------------------
839
RestoreViewport()840 void CTwGraphOpenGL::RestoreViewport()
841 {
842 _glViewport(m_ViewportInit[0], m_ViewportInit[1], m_ViewportInit[2], m_ViewportInit[3]);
843
844 GLint matrixMode = 0;
845 _glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
846 _glMatrixMode(GL_PROJECTION);
847 _glLoadMatrixf(m_ProjMatrixInit);
848 _glMatrixMode(matrixMode);
849 }
850
851 // ---------------------------------------------------------------------------
852
SetScissor(int _X0,int _Y0,int _Width,int _Height)853 void CTwGraphOpenGL::SetScissor(int _X0, int _Y0, int _Width, int _Height)
854 {
855 if( _Width>0 && _Height>0 )
856 {
857 _glScissor(_X0-1, m_WndHeight-_Y0-_Height, _Width-1, _Height);
858 _glEnable(GL_SCISSOR_TEST);
859 }
860 else
861 _glDisable(GL_SCISSOR_TEST);
862 }
863
864 // ---------------------------------------------------------------------------
865
DrawTriangles(int _NumTriangles,int * _Vertices,color32 * _Colors,Cull _CullMode)866 void CTwGraphOpenGL::DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode)
867 {
868 assert(m_Drawing==true);
869
870 const GLfloat dx = +0.0f;
871 const GLfloat dy = +0.0f;
872
873 GLint prevCullFaceMode, prevFrontFace;
874 _glGetIntegerv(GL_CULL_FACE_MODE, &prevCullFaceMode);
875 _glGetIntegerv(GL_FRONT_FACE, &prevFrontFace);
876 GLboolean prevCullEnable = _glIsEnabled(GL_CULL_FACE);
877 _glCullFace(GL_BACK);
878 _glEnable(GL_CULL_FACE);
879 if( _CullMode==CULL_CW )
880 _glFrontFace(GL_CCW);
881 else if( _CullMode==CULL_CCW )
882 _glFrontFace(GL_CW);
883 else
884 _glDisable(GL_CULL_FACE);
885
886 _glDisable(GL_TEXTURE_2D);
887 _glMatrixMode(GL_MODELVIEW);
888 _glLoadIdentity();
889 _glBegin(GL_TRIANGLES);
890 for(int i=0; i<3*_NumTriangles; ++i)
891 {
892 color32 col = _Colors[i];
893 _glColor4ub(GLubyte(col>>16), GLubyte(col>>8), GLubyte(col), GLubyte(col>>24));
894 _glVertex2f((GLfloat)_Vertices[2*i+0]+dx, (GLfloat)_Vertices[2*i+1]+dy);
895 }
896 _glEnd();
897
898 _glCullFace(prevCullFaceMode);
899 _glFrontFace(prevFrontFace);
900 if( prevCullEnable )
901 _glEnable(GL_CULL_FACE);
902 else
903 _glDisable(GL_CULL_FACE);
904 }
905
906 // ---------------------------------------------------------------------------
907