ecere: Fixed strict aliasing warnings
[sdk] / ecere / src / gfx / drivers / OpenGLDisplayDriver.ec
1 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
2 // #define USEPBUFFER
3
4 namespace gfx::drivers;
5
6 // OpenGL Extensions
7 #if defined(__unix__) || defined(__APPLE__)
8
9 #if !defined(__MINGW32__)
10 #define GL_GLEXT_PROTOTYPES
11 #endif
12
13 #ifdef ECERE_MINIGLX
14
15 //#include <GL/miniglx.h>
16
17 #else
18
19 #if defined(__ANDROID__)
20
21 #else
22
23 #define property _property
24 #define new _new
25 #define class _class
26
27 #define Window    X11Window
28 #define Cursor    X11Cursor
29 #define Font      X11Font
30 #define Display   X11Display
31 #define Time      X11Time
32 #define KeyCode   X11KeyCode
33 #define Picture   X11Picture
34 #define uint _uint
35
36 #include <X11/Xlib.h>
37 #include <X11/Xutil.h>
38 #include <GL/glx.h>
39 #include <X11/extensions/XShm.h>
40 #include <sys/ipc.h>
41 #include <sys/shm.h>
42 #include <X11/extensions/Xrender.h>
43 #include <X11/extensions/shape.h>
44
45 #undef Window
46 #undef Cursor
47 #undef Font
48 #undef Display
49 #undef Time
50 #undef KeyCode
51 #undef Picture
52 #undef uint
53 #undef new
54 #undef property
55 #undef class
56
57 #endif
58
59 #endif
60
61 #endif
62
63 #if defined(__APPLE__)
64 #include <OpenGl/gl.h>
65 #endif
66
67 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
68
69 #if defined(__WIN32__)
70 #define WIN32_LEAN_AND_MEAN
71 #undef _WIN32_WINNT
72 #define _WIN32_WINNT 0x0500
73 #define String Sting_
74 #include <windows.h>
75 #undef String
76 #endif
77
78 #if defined(__ANDROID__)
79
80 #include <GLES/gl.h>
81 #include <EGL/egl.h>
82
83 #else
84
85 #include <GL/gl.h>
86 #include <GL/glext.h>
87
88 #endif
89
90 import "Display"
91
92 #if defined(__unix__) || defined(__APPLE__)
93
94 #ifndef __ANDROID__
95 import "XInterface"
96 #endif
97
98 #endif
99
100 static double nearPlane = 1;
101
102 #define glLoadMatrix glLoadMatrixd
103 #define glMultMatrix glMultMatrixd
104 #define glGetMatrix  glGetDoublev
105 #define glTranslate glTranslated
106 #define glScale glScaled
107
108 /*
109 #define glVertex3v glVertex3dv
110 #define glNormal3v glNormal3dv
111 */
112
113 /*
114 //#ifdef VERTEX_FORMAT_DOUBLE
115
116 #define glLoadMatrix glLoadMatrixd
117 #define glMultMatrix glMultMatrixd
118 #define glGetMatrix  glGetDoublev
119 #define glVertex3v glVertex3dv
120 #define glNormal3v glNormal3dv
121 #define glTranslate glTranslated
122 #define glScale glScaled
123 //#define GL_VERTEX_FORMAT   GL_DOUBLE
124
125 #else
126
127 #define glLoadMatrix glLoadMatrixf
128 #define glMultMatrix glMultMatrixf
129 #define glGetMatrix  glGetFloatv
130 #define glVertex3v glVertex3fv
131 #define glNormal3v glNormal3fv
132 #define glTranslate glTranslatef
133 #define glScale glScalef
134 //#define GL_VERTEX_FORMAT   GL_FLOAT
135
136 #endif
137 */
138
139 #define GL_ARRAY_BUFFER_ARB            0x8892
140 #define GL_ELEMENT_ARRAY_BUFFER_ARB    0x8893
141 #define GL_STATIC_DRAW_ARB             0x88E4
142 #define GL_LIGHT_MODEL_COLOR_CONTROL   0x81F8
143 #define GL_SEPARATE_SPECULAR_COLOR     0x81FA
144
145 #define GL_MULTISAMPLE_ARB             0x809D
146
147 #if defined(__WIN32__)
148
149 #define WGL_SAMPLE_BUFFERS_ARB              0x2041
150 #define WGL_SAMPLES_ARB                     0x2042
151
152 #define  WGL_WGLEXT_VERSION   1
153 #define  WGL_FRONT_COLOR_BUFFER_BIT_ARB   0x00000001
154 #define  WGL_BACK_COLOR_BUFFER_BIT_ARB   0x00000002
155 #define  WGL_DEPTH_BUFFER_BIT_ARB   0x00000004
156 #define  WGL_STENCIL_BUFFER_BIT_ARB   0x00000008
157 #define  WGL_NUMBER_PIXEL_FORMATS_ARB   0x2000
158 #define  WGL_DRAW_TO_WINDOW_ARB   0x2001
159 #define  WGL_DRAW_TO_BITMAP_ARB   0x2002
160 #define  WGL_ACCELERATION_ARB   0x2003
161 #define  WGL_NEED_PALETTE_ARB   0x2004
162 #define  WGL_NEED_SYSTEM_PALETTE_ARB   0x2005
163 #define  WGL_SWAP_LAYER_BUFFERS_ARB   0x2006
164 #define  WGL_SWAP_METHOD_ARB   0x2007
165 #define  WGL_NUMBER_OVERLAYS_ARB   0x2008
166 #define  WGL_NUMBER_UNDERLAYS_ARB   0x2009
167 #define  WGL_TRANSPARENT_ARB   0x200A
168 #define  WGL_TRANSPARENT_RED_VALUE_ARB   0x2037
169 #define  WGL_TRANSPARENT_GREEN_VALUE_ARB   0x2038
170 #define  WGL_TRANSPARENT_BLUE_VALUE_ARB   0x2039
171 #define  WGL_TRANSPARENT_ALPHA_VALUE_ARB   0x203A
172 #define  WGL_TRANSPARENT_INDEX_VALUE_ARB   0x203B
173 #define  WGL_SHARE_DEPTH_ARB   0x200C
174 #define  WGL_SHARE_STENCIL_ARB   0x200D
175 #define  WGL_SHARE_ACCUM_ARB   0x200E
176 #define  WGL_SUPPORT_GDI_ARB   0x200F
177 #define  WGL_SUPPORT_OPENGL_ARB   0x2010
178 #define  WGL_DOUBLE_BUFFER_ARB   0x2011
179 #define  WGL_STEREO_ARB   0x2012
180 #define  WGL_PIXEL_TYPE_ARB   0x2013
181 #define  WGL_COLOR_BITS_ARB   0x2014
182 #define  WGL_RED_BITS_ARB   0x2015
183 #define  WGL_RED_SHIFT_ARB   0x2016
184 #define  WGL_GREEN_BITS_ARB   0x2017
185 #define  WGL_GREEN_SHIFT_ARB   0x2018
186 #define  WGL_BLUE_BITS_ARB   0x2019
187 #define  WGL_BLUE_SHIFT_ARB   0x201A
188 #define  WGL_ALPHA_BITS_ARB   0x201B
189 #define  WGL_ALPHA_SHIFT_ARB   0x201C
190 #define  WGL_ACCUM_BITS_ARB   0x201D
191 #define  WGL_ACCUM_RED_BITS_ARB   0x201E
192 #define  WGL_ACCUM_GREEN_BITS_ARB   0x201F
193 #define  WGL_ACCUM_BLUE_BITS_ARB   0x2020
194 #define  WGL_ACCUM_ALPHA_BITS_ARB   0x2021
195 #define  WGL_DEPTH_BITS_ARB   0x2022
196 #define  WGL_STENCIL_BITS_ARB   0x2023
197 #define  WGL_AUX_BUFFERS_ARB   0x2024
198 #define  WGL_NO_ACCELERATION_ARB   0x2025
199 #define  WGL_GENERIC_ACCELERATION_ARB   0x2026
200 #define  WGL_FULL_ACCELERATION_ARB   0x2027
201 #define  WGL_SWAP_EXCHANGE_ARB   0x2028
202 #define  WGL_SWAP_COPY_ARB   0x2029
203 #define  WGL_SWAP_UNDEFINED_ARB   0x202A
204 #define  WGL_TYPE_RGBA_ARB   0x202B
205 #define  WGL_TYPE_COLORINDEX_ARB   0x202C
206 #define  ERROR_INVALID_PIXEL_TYPE_ARB   0x2043
207 #define  ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB   0x2054
208 #define  WGL_DRAW_TO_PBUFFER_ARB   0x202D
209 #define  WGL_MAX_PBUFFER_PIXELS_ARB   0x202E
210 #define  WGL_MAX_PBUFFER_WIDTH_ARB   0x202F
211 #define  WGL_MAX_PBUFFER_HEIGHT_ARB   0x2030
212 #define  WGL_PBUFFER_LARGEST_ARB   0x2033
213 #define  WGL_PBUFFER_WIDTH_ARB   0x2034
214 #define  WGL_PBUFFER_HEIGHT_ARB   0x2035
215 #define  WGL_PBUFFER_LOST_ARB   0x2036
216 #define  ERROR_INVALID_PIXEL_TYPE_EXT   0x2043
217 #define  WGL_NUMBER_PIXEL_FORMATS_EXT   0x2000
218 #define  WGL_DRAW_TO_WINDOW_EXT   0x2001
219 #define  WGL_DRAW_TO_BITMAP_EXT   0x2002
220 #define  WGL_ACCELERATION_EXT   0x2003
221 #define  WGL_NEED_PALETTE_EXT   0x2004
222 #define  WGL_NEED_SYSTEM_PALETTE_EXT   0x2005
223 #define  WGL_SWAP_LAYER_BUFFERS_EXT   0x2006
224 #define  WGL_SWAP_METHOD_EXT   0x2007
225 #define  WGL_NUMBER_OVERLAYS_EXT   0x2008
226 #define  WGL_NUMBER_UNDERLAYS_EXT   0x2009
227 #define  WGL_TRANSPARENT_EXT   0x200A
228 #define  WGL_TRANSPARENT_VALUE_EXT   0x200B
229 #define  WGL_SHARE_DEPTH_EXT   0x200C
230 #define  WGL_SHARE_STENCIL_EXT   0x200D
231 #define  WGL_SHARE_ACCUM_EXT   0x200E
232 #define  WGL_SUPPORT_GDI_EXT   0x200F
233 #define  WGL_SUPPORT_OPENGL_EXT   0x2010
234 #define  WGL_DOUBLE_BUFFER_EXT   0x2011
235 #define  WGL_STEREO_EXT   0x2012
236 #define  WGL_PIXEL_TYPE_EXT   0x2013
237 #define  WGL_COLOR_BITS_EXT   0x2014
238 #define  WGL_RED_BITS_EXT   0x2015
239 #define  WGL_RED_SHIFT_EXT   0x2016
240 #define  WGL_GREEN_BITS_EXT   0x2017
241 #define  WGL_GREEN_SHIFT_EXT   0x2018
242 #define  WGL_BLUE_BITS_EXT   0x2019
243 #define  WGL_BLUE_SHIFT_EXT   0x201A
244 #define  WGL_ALPHA_BITS_EXT   0x201B
245 #define  WGL_ALPHA_SHIFT_EXT   0x201C
246 #define  WGL_ACCUM_BITS_EXT   0x201D
247 #define  WGL_ACCUM_RED_BITS_EXT   0x201E
248 #define  WGL_ACCUM_GREEN_BITS_EXT   0x201F
249 #define  WGL_ACCUM_BLUE_BITS_EXT   0x2020
250 #define  WGL_ACCUM_ALPHA_BITS_EXT   0x2021
251 #define  WGL_DEPTH_BITS_EXT   0x2022
252 #define  WGL_STENCIL_BITS_EXT   0x2023
253 #define  WGL_AUX_BUFFERS_EXT   0x2024
254 #define  WGL_NO_ACCELERATION_EXT   0x2025
255 #define  WGL_GENERIC_ACCELERATION_EXT   0x2026
256 #define  WGL_FULL_ACCELERATION_EXT   0x2027
257 #define  WGL_SWAP_EXCHANGE_EXT   0x2028
258 #define  WGL_SWAP_COPY_EXT   0x2029
259 #define  WGL_SWAP_UNDEFINED_EXT   0x202A
260 #define  WGL_TYPE_RGBA_EXT   0x202B
261 #define  WGL_TYPE_COLORINDEX_EXT   0x202C
262 #define  WGL_DRAW_TO_PBUFFER_EXT   0x202D
263 #define  WGL_MAX_PBUFFER_PIXELS_EXT   0x202E
264 #define  WGL_MAX_PBUFFER_WIDTH_EXT   0x202F
265 #define  WGL_MAX_PBUFFER_HEIGHT_EXT   0x2030
266 #define  WGL_OPTIMAL_PBUFFER_WIDTH_EXT   0x2031
267 #define  WGL_OPTIMAL_PBUFFER_HEIGHT_EXT   0x2032
268 #define  WGL_PBUFFER_LARGEST_EXT   0x2033
269 #define  WGL_PBUFFER_WIDTH_EXT   0x2034
270 #define  WGL_PBUFFER_HEIGHT_EXT   0x2035
271 #define  WGL_DEPTH_FLOAT_EXT   0x2040
272 #define  WGL_SAMPLE_BUFFERS_3DFX   0x2060
273 #define  WGL_SAMPLES_3DFX   0x2061
274 #define  WGL_SAMPLE_BUFFERS_EXT   0x2041
275 #define  WGL_SAMPLES_EXT   0x2042
276 #define  WGL_GENLOCK_SOURCE_MULTIVIEW_I3D   0x2044
277 #define  WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D   0x2045
278 #define  WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D   0x2046
279 #define  WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D   0x2047
280 #define  WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D   0x2048
281 #define  WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D   0x2049
282 #define  WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D   0x204A
283 #define  WGL_GENLOCK_SOURCE_EDGE_RISING_I3D   0x204B
284 #define  WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D   0x204C
285 #define  WGL_GAMMA_TABLE_SIZE_I3D   0x204E
286 #define  WGL_GAMMA_EXCLUDE_DESKTOP_I3D   0x204F
287 #define  WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D   0x2050
288 #define  WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D   0x2051
289 #define  WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D   0x2052
290 #define  WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D   0x2053
291 #define  WGL_ARB_buffer_region   1
292 #define  WGL_ARB_extensions_string   1
293 #define  WGL_ARB_pixel_format   1
294 #define  WGL_ARB_make_current_read   1
295 #define  WGL_ARB_pbuffer   1
296 #define  WGL_EXT_display_color_table   1
297 #define  WGL_EXT_extensions_string   1
298 #define  WGL_EXT_make_current_read   1
299 #define  WGL_EXT_pbuffer   1
300 #define  WGL_EXT_pixel_format   1
301 #define  WGL_EXT_swap_control   1
302 #define  WGL_WGL_EXT_depth_float   1
303 #define  WGL_WGL_3DFX_multisample   1
304 #define  WGL_WGL_EXT_multisample   1
305 #define  WGL_NV_allocate_memory   1
306
307 /*
308 typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum target);
309 typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
310 typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum target);
311 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
312 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
313 */
314
315 /*
316 typedef int (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
317 typedef int (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
318 typedef int (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
319 typedef int (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
320 */
321 typedef int (APIENTRY * PFNWGLCHOOSEPIXELFORMATARBPROC) ();
322 typedef void * (APIENTRY * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
323 typedef HDC (APIENTRY * PFNWGLGETPBUFFERDCARBPROC) (void * hPbuffer);
324 typedef int (APIENTRY * PFNWGLRELEASEPBUFFERDCARBPROC) (void * hPbuffer, HDC hDC);
325 typedef BOOL (APIENTRY * PFNWGLDESTROYPBUFFERARBPROC) (void * hPbuffer);
326 typedef BOOL (APIENTRY * PFNWGLQUERYPBUFFERARBPROC) (void * hPbuffer, int iAttribute, int *piValue);
327
328 static PFNGLMAPBUFFERARBPROC glMapBufferARB = null;
329 static PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = null;
330 static PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = null;
331 static PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = null;
332 static PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = null;
333 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
334 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
335 static PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate = null;
336
337 static PFNGLGENBUFFERSARBPROC glGenBuffersARB = null;
338 static PFNGLBINDBUFFERARBPROC glBindBufferARB = null;
339 static PFNGLBUFFERDATAARBPROC glBufferDataARB = null;
340 static PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = null;
341 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
342 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
343 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
344 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
345 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
346 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
347 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
348 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
349 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
350
351 #ifdef WGL_WGLEXT_PROTOTYPES
352 extern BOOL WINAPI wglSwapIntervalEXT (int);
353 extern int WINAPI wglGetSwapIntervalEXT (void);
354 #endif /* WGL_WGLEXT_PROTOTYPES */
355 typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
356 typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
357
358 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
359
360 #else
361
362 #if defined(__ANDROID__)
363
364 // Our own matrix stack
365 static Matrix matrixStack[3][32];
366 static int matrixIndex[3];
367 static int curStack = 0;
368
369 // OpenGL ES Porting Kit
370
371 #define glBindFramebuffer        glBindFramebufferOES
372 #define glBindRenderbuffer       glBindRenderbufferOES
373 #define GL_FRAMEBUFFER           GL_FRAMEBUFFER_OES
374 #define GL_RENDERBUFFER          GL_RENDERBUFFER_OES
375 #define glFramebufferTexture2D   glFramebufferTexture2DOES
376 #define GL_COLOR_ATTACHMENT0     GL_COLOR_ATTACHMENT0_OES
377 #define glGenFramebuffers        glGenFramebuffersOES
378 #define glGenRenderbuffers       glGenRenderbuffersOES
379 #define glDeleteFramebuffers     glDeleteFramebuffersOES
380 #define glDeleteRenderbuffers    glDeleteRenderbuffersOES
381
382 #define GL_POLYGON_STIPPLE 0xFFFF
383 #define GL_LINE_STIPPLE 0xFFFF
384 #define GL_LINE 0xFFFF
385 #define GL_FILL 0xFFFF
386 #define GL_ALL_ATTRIB_BITS 0xFFFF
387 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
388 #define glDrawElementsi(type, count, start)  glDrawElements(type, count, GL_UNSIGNED_SHORT, start)
389
390 #define GL_UNSIGNED_INT                         0x1405
391 #define GL_DOUBLE                               0x140A
392
393 #define GL_POLYGON      9
394 #define GL_QUADS        7
395
396 #define glBufferDatai         glesBufferDatai
397 #define glBufferDatad         glesBufferDatad
398 #define glVertexPointeri      glesVertexPointeri
399 #define glVertexPointerd      glesVertexPointerd
400
401 #define glRecti               glesRecti
402 #define glBegin               glesBegin
403 #define glTexCoord2i          glesTexCoord2i
404 #define glVertex2i            glesVertex2i
405 #define glTexCoord2d          glesTexCoord2d
406 #define glVertex2d            glesVertex2d
407 #define glTexCoord2f          glesTexCoord2f
408 #define glVertex2f            glesVertex2f
409 #define glEnd                 glesEnd
410 #define glColor3f             glesColor3f
411 #define glColor4ub            glesColor4ub
412 #define glColor4fv            glesColor4fv
413 #define glLineStipple         glesLineStipple
414 #define glNormal3fv           glesNormal3fv
415 #define glTexCoord2fv         glesTexCoord2fv
416 #define glColorMaterial       glesColorMaterial
417
418 #define glLoadMatrixd         glesLoadMatrixd
419 #define glMultMatrixd         glesMultMatrixd
420 #define glFrustum             glesFrustum
421 #define glOrtho               glesOrtho
422 #define glScaled              glesScaled
423 #define glTranslated          glesTranslated
424 #define glRotated             glesRotated
425 #define glVertex3d            glesVertex3d
426 #define glVertex3f            glesVertex3f
427 #define glVertex3fv           glesVertex3fv
428 #define glLightModeli         glesLightModeli
429
430 #define APIENTRY
431 //#define GL_QUADS              0
432 #define GL_QUAD_STRIP         0
433 //#define GL_DOUBLE             0
434 //#define GL_UNSIGNED_INT       0
435 //#define GL_FILL               0
436 //#define GL_LINE               0
437 //#define GL_LINE_STIPPLE       0
438 #define GL_BGRA_EXT           0
439 #define GL_UNPACK_ROW_LENGTH  0
440 #define GL_UNPACK_SKIP_PIXELS 0
441 #define GL_UNPACK_SKIP_ROWS   0
442 #define GL_RGBA8              0
443 #define GL_PACK_ROW_LENGTH    0
444 #define GL_PACK_SKIP_ROWS     0
445 #define GL_PACK_SKIP_PIXELS   0
446
447 static EGLDisplay eglDisplay;
448 static EGLSurface eglSurface;
449 static EGLContext eglContext;
450 static int eglWidth, eglHeight;
451
452 static bool egl_init_display(ANativeWindow* window)
453 {
454    const EGLint attribs[] =
455    {
456       EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
457       EGL_BLUE_SIZE, 8,
458       EGL_GREEN_SIZE, 8,
459       EGL_RED_SIZE, 8,
460       EGL_DEPTH_SIZE, 24,
461       /*EGL_SAMPLE_BUFFERS, 1,
462       EGL_SAMPLES, 0, //2,*/
463       EGL_NONE
464    };
465    EGLint w, h, dummy, format;
466    EGLint numConfigs;
467    EGLConfig config;
468    EGLSurface surface;
469    EGLContext context;
470
471    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
472    eglInitialize(display, 0, 0);
473    eglChooseConfig(display, attribs, &config, 1, &numConfigs);
474    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
475
476    surface = eglCreateWindowSurface(display, config, window, null);
477    context = eglCreateContext(display, config, null, null);
478
479    if(!eglMakeCurrent(display, surface, surface, context))
480       return false;
481
482    eglQuerySurface(display, surface, EGL_WIDTH, &w);
483    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
484
485    eglDisplay = display;
486    eglContext = context;
487    eglSurface = surface;
488    eglWidth = w;
489    eglHeight = h;
490
491    glEnableClientState(GL_VERTEX_ARRAY);
492    /*
493    // Initialize GL state.
494    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
495    glEnable(GL_CULL_FACE);
496    glShadeModel(GL_SMOOTH);
497    glDisable(GL_DEPTH_TEST);
498    */
499    glDisable(GL_CULL_FACE);
500    glDisable(GL_DEPTH_TEST);
501
502    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
503    glEnable(GL_BLEND);
504
505    matrixStack[0][0].Identity();
506    matrixStack[1][0].Identity();
507    matrixStack[2][0].Identity();
508
509    glesMatrixMode(GL_MODELVIEW);
510    glScaled(1.0, 1.0, -1.0);
511    glesMatrixMode(GL_PROJECTION);
512    glShadeModel(GL_FLAT);
513
514    glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
515    glFogi(GL_FOG_MODE, GL_EXP);
516    glFogf(GL_FOG_DENSITY, 0);
517    glEnable(GL_NORMALIZE);
518    glDepthFunc(GL_LESS);
519    glClearDepth(1.0);
520    glDisable(GL_MULTISAMPLE_ARB);
521
522    glViewport(0,0,w,h);
523    glesLoadIdentity();
524    glOrtho(0,w,h,0,0.0,1.0);
525
526    currentVertexBuffer = 0;
527    return true;
528 }
529
530 static void egl_term_display()
531 {
532    if(stippleTexture)
533    {
534       glDeleteTextures(1, &stippleTexture);
535       stippleTexture = 0;
536    }
537    if(eglDisplay != EGL_NO_DISPLAY)
538    {
539       eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
540       if(eglContext != EGL_NO_CONTEXT)
541          eglDestroyContext(eglDisplay, eglContext);
542       if(eglSurface != EGL_NO_SURFACE)
543          eglDestroySurface(eglDisplay, eglSurface);
544       eglTerminate(eglDisplay);
545    }
546    eglDisplay = EGL_NO_DISPLAY;
547    eglContext = EGL_NO_CONTEXT;
548    eglSurface = EGL_NO_SURFACE;
549 }
550
551 // OpenGL Immediate Mode Porting Kit
552 static int beginCount;
553 static int vertexCount;
554 static int normalCount;
555 static float *vertexPointer;
556 static float *normalPointer;
557 static GLenum beginMode;
558 static unsigned int beginBufferSize, normalBufferSize;
559 static int numVertexCoords = 2;
560
561 void glesRecti(int a, int b, int c, int d)
562 {
563    glBegin(GL_QUADS);
564    glVertex2i(a, b);
565    glVertex2i(a, d);
566    glVertex2i(c, d);
567    glVertex2i(c, b);
568    glEnd();
569 }
570
571 void glesBegin(GLenum mode)
572 {
573    beginMode = mode;
574    beginCount = 0;
575    vertexCount = 0;
576    if(!vertexPointer)
577    {
578       normalBufferSize = beginBufferSize = 1024;  // default number of vertices
579       vertexPointer = new float[beginBufferSize * 5];
580       normalPointer = new float[normalBufferSize * 3];
581    }
582 }
583
584 void glesTexCoord2f(float x, float y)
585 {
586    int count = vertexCount;
587
588    if(vertexCount + numVertexCoords > beginBufferSize)
589    {
590       beginBufferSize = beginBufferSize + beginBufferSize/2;
591       vertexPointer = renew vertexPointer float[beginBufferSize * 5];
592    }
593
594    vertexPointer[count*(2+numVertexCoords)  ] = x;
595    vertexPointer[count*(2+numVertexCoords)+1] = y;
596    count++;
597
598    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
599    {
600       vertexPointer[count*(2+numVertexCoords)  ] = vertexPointer[(count-4)*(2+numVertexCoords)];
601       vertexPointer[count*(2+numVertexCoords)+1] = vertexPointer[(count-4)*(2+numVertexCoords)+1];
602       count++;
603       vertexPointer[count*(2+numVertexCoords)  ] = vertexPointer[(count-3)*(2+numVertexCoords)];
604       vertexPointer[count*(2+numVertexCoords)+1] = vertexPointer[(count-3)*(2+numVertexCoords)+1];
605       count++;
606    }
607 }
608 void glesTexCoord2i(int x, int y)       { glesTexCoord2f((float)x, (float)y); }
609 void glesTexCoord2d(double x, double y) { glesTexCoord2f((float)x, (float)y); }
610 void glesTexCoord2fv(float * a)         { glesTexCoord2f(a[0], a[1]); }
611
612 void glesVertex2f(float x, float y)
613 {
614    numVertexCoords = 2;
615    if(vertexCount + 4 > beginBufferSize)
616    {
617       beginBufferSize = beginBufferSize + beginBufferSize/2;
618       vertexPointer = renew vertexPointer float[beginBufferSize * 5];
619    }
620
621    vertexPointer[vertexCount*4+2] = x;
622    vertexPointer[vertexCount*4+3] = y;
623    vertexCount++;
624
625    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
626    {
627       vertexPointer[vertexCount*4+2] = vertexPointer[(vertexCount-4)*4+2];
628       vertexPointer[vertexCount*4+3] = vertexPointer[(vertexCount-4)*4+3];
629       vertexCount++;
630       vertexPointer[vertexCount*4+2] = vertexPointer[(vertexCount-3)*4+2];
631       vertexPointer[vertexCount*4+3] = vertexPointer[(vertexCount-3)*4+3];
632       vertexCount++;
633    }
634    beginCount++;
635 }
636 void glesVertex2i(int x, int y)         { glesVertex2f((float)x, (float)y); }
637 void glesVertex2d(double x, double y)   { glesVertex2f((float)x, (float)y); }
638
639 void glesEnd(void)
640 {
641    int mode = beginMode;
642    if(mode == GL_QUADS)        mode = GL_TRIANGLES;
643    else if(mode == GL_POLYGON) mode = GL_TRIANGLE_FAN;
644    GLSelectVBO(0);
645    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
646    glTexCoordPointer(numVertexCoords, GL_FLOAT, (numVertexCoords+2)*sizeof(float),vertexPointer);
647    glVertexPointer  (numVertexCoords, GL_FLOAT, (numVertexCoords+2)*sizeof(float),vertexPointer+2);
648    if(normalCount && normalCount == vertexCount)
649    {
650       glEnableClientState(GL_NORMAL_ARRAY);
651       glNormalPointer  (GL_FLOAT, 3*sizeof(float),normalPointer);
652    }
653
654    glDrawArrays(mode, 0, vertexCount);
655    if(normalCount)
656       glDisableClientState(GL_NORMAL_ARRAY);
657    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
658    normalCount = 0;
659 }
660
661 // Vertex Pointer
662 static float *floatVPBuffer = null;
663 static short *shortVPBuffer = null;
664 static unsigned int shortVPSize = 0, floatVPSize = 0;
665
666 // Buffer Data
667 //static float *floatVPBuffer = null;  // For floats we reuse floatVPBuffer
668 static unsigned short *shortBDBuffer = null;
669 static unsigned int shortBDSize = 0/*, floatVPSize = 0*/;
670
671 void glesVertexPointeri(int numCoords, int stride, int *pointer, int numVertices)
672 {
673    if(pointer)
674    {
675       int i;
676       if(numVertices*numCoords > shortVPSize)
677       {
678          shortVPSize = numVertices*numCoords;
679          shortVPBuffer = renew shortVPBuffer short[shortVPSize];
680       }
681       for(i = 0; i < numVertices*numCoords; i++)
682          shortVPBuffer[i] = (short)pointer[i];
683       glVertexPointer(numCoords, GL_SHORT, stride, shortVPBuffer);
684    }
685    else
686       glVertexPointer(numCoords, GL_SHORT, stride, 0);
687 }
688
689 void glesVertexPointerd(int numCoords, int stride, double *pointer, int numVertices)
690 {
691    if(pointer)
692    {
693       int i;
694       if(numVertices*numCoords > floatVPSize)
695       {
696          floatVPSize = numVertices*numCoords;
697          floatVPBuffer = renew floatVPBuffer float[floatVPSize];
698       }
699       for(i = 0; i < numVertices*numCoords; i++)
700          floatVPBuffer[i] = (float)pointer[i];
701       glVertexPointer(numCoords, GL_FLOAT, stride, floatVPBuffer);
702    }
703    else
704       glVertexPointer(numCoords, GL_FLOAT, stride, 0);
705 }
706
707 void glesTexReuseIntVP(int numCoords)
708 {
709    glTexCoordPointer(numCoords, GL_SHORT, 0, floatVPBuffer);
710 }
711
712 void glesTexReuseDoubleVP(int numCoords)
713 {
714    glTexCoordPointer(numCoords, GL_FLOAT, 0, floatVPBuffer);
715 }
716
717 void glesColor3f( float r, float g, float b )
718 {
719    glColor4f(r, g, b, 1.0f);
720 }
721
722 void glesColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
723 {
724    glColor4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f);
725 }
726
727 void glesColor4fv(float * a)
728 {
729    glColor4f(a[0], a[1], a[2], a[3]);
730 }
731
732 void glesBufferDatad(int target, int size, void * data, int usage)
733 {
734    int numElems = size/sizeof(double);
735    double * dblPtr = (double *)data;
736    int i;
737    if (numElems > floatVPSize)
738    {
739       floatVPSize = numElems;
740       floatVPBuffer = renew floatVPBuffer float[floatVPSize];
741    }
742    for (i=0; i< numElems; i++)
743       floatVPBuffer[i] = (float)dblPtr[i];
744
745    glBufferData(target, numElems*sizeof(float), floatVPBuffer, usage);
746 }
747
748 void glesBufferDatai(int target, int size, void * data, int usage)
749 {
750    int numElems = size/sizeof(unsigned int);
751    unsigned int * pointer = (unsigned int *)data;
752    int i;
753    if (numElems > shortBDSize)
754    {
755       shortBDSize = numElems;
756       shortBDBuffer = renew shortBDBuffer uint16[shortBDSize];
757    }
758    for (i=0; i< numElems; i++)
759       shortBDBuffer[i] = (unsigned short)pointer[i];
760
761    glBufferData(target, numElems*sizeof(unsigned short), shortBDBuffer, usage);
762 }
763
764 // *** Our Custom Matrix Stack ***
765
766 static void LoadCurMatrix()
767 {
768    double * i = matrixStack[curStack][matrixIndex[curStack]].array;
769    float m[16] =
770    {
771       (float)i[0],(float)i[1],(float)i[2],(float)i[3],
772       (float)i[4],(float)i[5],(float)i[6],(float)i[7],
773       (float)i[8],(float)i[9],(float)i[10],(float)i[11],
774       (float)i[12],(float)i[13],(float)i[14],(float)i[15]
775    };
776    glLoadMatrixf(m);
777 }
778
779 void glesLoadIdentity()
780 {
781    matrixStack[curStack][matrixIndex[curStack]].Identity();
782    LoadCurMatrix();
783 }
784
785 void glesPushMatrix()
786 {
787    if(matrixIndex[curStack] + 1 < sizeof(matrixStack[0]) / sizeof(Matrix))
788    {
789       matrixIndex[curStack]++;
790       memcpy(matrixStack[curStack][matrixIndex[curStack]].array, matrixStack[curStack][matrixIndex[curStack]-1].array, sizeof(Matrix));
791    }
792 }
793
794 void glesPopMatrix()
795 {
796    if(matrixIndex[curStack] > 0)
797    {
798       matrixIndex[curStack]--;
799       LoadCurMatrix();
800    }
801 }
802
803 void glesLoadMatrixd(double * i)
804 {
805    memcpy(matrixStack[curStack][matrixIndex[curStack]].array, i, sizeof(Matrix));
806    LoadCurMatrix();
807 }
808
809 void glesOrtho( double l, double r, double b, double t, double n, double f )
810 {
811    Matrix m =
812    { {
813       (2 / (r - l)), 0, 0, 0,
814       0, (2 / (t - b)), 0, 0,
815       0, 0, (-2 / (f - n)), 0,
816       (-(r + l) / (r - l)), (-(t + b) / (t - b)), (-(f + n) / (f - n)), 1
817    } }, res;
818    res.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
819    matrixStack[curStack][matrixIndex[curStack]] = res;
820    LoadCurMatrix();
821 }
822
823 void glesFrustum( double l, double r, double b, double t, double n, double f )
824 {
825    nearPlane = n;
826    n = 1;
827    l /= nearPlane;
828    r /= nearPlane;
829    b /= nearPlane;
830    t /= nearPlane;
831    f /= nearPlane;
832    {
833       double A = ((r + l) / (r - l));
834       double B = ((t + b) / (t - b));
835       double C = (-(f + n) / (f - n));
836       double D = (-2*f*n/(f-n));
837       Matrix m =
838       { {
839          (2.0*n / (r - l)), 0, 0, 0,
840          0, (2.0*n / (t - b)), 0, 0,
841          A, B,             C,-1,
842          0, 0,             D, 0
843       } }, res;
844       res.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
845       matrixStack[curStack][matrixIndex[curStack]] = res;
846       LoadCurMatrix();
847    }
848 }
849
850 void glesRotated( double a, double b, double c, double d )
851 {
852    Matrix m;
853    Quaternion q;
854    q.RotationAxis({(float)b,(float)-c,(float)d}, a );
855    m.RotationQuaternion(q);
856    matrixStack[curStack][matrixIndex[curStack]].Rotate(q);
857    LoadCurMatrix();
858 }
859 void glesScaled( double a, double b, double c )
860 {
861    Matrix m, r;
862
863    m.Identity();
864    m.Scale(a,b,c);
865    r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
866    matrixStack[curStack][matrixIndex[curStack]] = r;
867    LoadCurMatrix();
868 }
869
870 void glesTranslated( double a, double b, double c )
871 {
872    Matrix m, r;
873
874    m.Identity();
875    m.Translate(a,b,c);
876    r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
877    matrixStack[curStack][matrixIndex[curStack]] = r;
878    LoadCurMatrix();
879 }
880
881 void glesMultMatrixd( double * i )
882 {
883    Matrix r;
884    r.Multiply((Matrix *)i, matrixStack[curStack][matrixIndex[curStack]]);
885    matrixStack[curStack][matrixIndex[curStack]] = r;
886    LoadCurMatrix();
887 }
888
889 void glesMatrixMode(int mode)
890 {
891    curStack = mode == GL_MODELVIEW ? 0 : mode == GL_PROJECTION ? 1 : 2;
892    glMatrixMode(mode);
893 }
894
895 #define glPushMatrix          glesPushMatrix
896 #define glPopMatrix           glesPopMatrix
897 #define glLoadIdentity        glesLoadIdentity
898 #define glMatrixMode          glesMatrixMode
899
900 /* Using the built-in matrix stack
901 void glesLoadMatrixd( double * i )
902 {
903    float m[16] =
904    {
905       (float)i[0],(float)i[1],(float)i[2],(float)i[3],
906       (float)i[4],(float)i[5],(float)i[6],(float)i[7],
907       (float)i[8],(float)i[9],(float)i[10],(float)i[11],
908       (float)i[12],(float)i[13],(float)i[14],(float)i[15]
909    };
910    glLoadMatrixf(m);
911 }
912
913 void glesOrtho( double l, double r, double b, double t, double n, double f )
914 {
915    float matrix[4][4] =
916    {
917       { (float)(2 / (r - l)), 0, 0, 0 },
918       { 0, (float)(2 / (t - b)), 0, 0 },
919       { 0, 0, (float)(-2 / (f - n)), 0 },
920       { (float)(-(r + l) / (r - l)), (float)(-(t + b) / (t - b)), (float)(-(f + n) / (f - n)), 1 }
921    };
922    glMultMatrixf((float *)matrix);
923 }
924
925 void glesFrustum( double l, double r, double b, double t, double n, double f )
926 {
927    float A = (float)((r + l) / (r - l));
928    float B = (float)((t + b) / (t - b));
929    float C = (float)(-(f + n) / (f - n));
930    float D = (float)(-2*f*n/(f-n));
931    float matrix[4][4] =
932    {
933       { (float)(2*n / (r - l)), 0, 0, 0 },
934       { 0, (float)(2*n / (t - b)), 0, 0 },
935       { A, B,             C,-1 },
936       { 0, 0,             D, 0 }
937    };
938    glMultMatrixf((float *)matrix);
939 }
940
941 void glesRotated( double a, double b, double c, double d ) { glRotatef((float)a, (float)b, (float)c, (float)d); }
942 void glesScaled( double a, double b, double c ) { glScalef((float)a, (float)b, (float)c); }
943 void glesTranslated( double a, double b, double c ) { glTranslatef((float)a, (float)b, (float)c); }
944
945 void glesMultMatrixd( double * i )
946 {
947    float m[16] =
948    {
949       (float)i[0], (float)i[1], (float)i[2], (float)i[3],
950       (float)i[4], (float)i[5], (float)i[6], (float)i[7],
951       (float)i[8], (float)i[9], (float)i[10], (float)i[11],
952       (float)i[12], (float)i[13], (float)i[14], (float)i[15]
953    };
954    glMultMatrixf(m);
955 }
956 */
957
958 // Need to do these...
959 void glesVertex3f( float x, float y, float z )
960 {
961    numVertexCoords = 3;
962    if(vertexCount + 4 > beginBufferSize)
963    {
964       beginBufferSize = beginBufferSize + beginBufferSize/2;
965       vertexPointer = renew vertexPointer float[beginBufferSize * 5];
966    }
967
968    vertexPointer[vertexCount*5+2] = x;
969    vertexPointer[vertexCount*5+3] = y;
970    vertexPointer[vertexCount*5+4] = z;
971    vertexCount++;
972
973    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
974    {
975       vertexPointer[vertexCount*5+2] = vertexPointer[(vertexCount-4)*5+2];
976       vertexPointer[vertexCount*5+3] = vertexPointer[(vertexCount-4)*5+3];
977       vertexPointer[vertexCount*5+4] = vertexPointer[(vertexCount-4)*5+4];
978       vertexCount++;
979       vertexPointer[vertexCount*5+2] = vertexPointer[(vertexCount-3)*5+2];
980       vertexPointer[vertexCount*5+3] = vertexPointer[(vertexCount-3)*5+3];
981       vertexPointer[vertexCount*5+4] = vertexPointer[(vertexCount-3)*5+4];
982       vertexCount++;
983    }
984    beginCount++;
985 }
986
987 void glesVertex3d( double x, double y, double z )  { glesVertex3f((float)x, (float)y, (float)z); }
988 void glesVertex3fv( float* coords )                { glesVertex3f(coords[0], coords[1], coords[2]); }
989
990 void glesNormal3f(float x, float y, float z)
991 {
992    normalCount = vertexCount;
993    if(vertexCount + 4 > normalBufferSize)
994    {
995       normalBufferSize = normalBufferSize + normalBufferSize/2;
996       normalPointer = renew normalPointer float[normalBufferSize * 2];
997    }
998
999    normalPointer[normalCount*3+0] = x;
1000    normalPointer[normalCount*3+1] = y;
1001    normalPointer[normalCount*3+2] = z;
1002    normalCount++;
1003
1004    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
1005    {
1006       normalPointer[normalCount*3+0] = normalPointer[(normalCount-4)*3+0];
1007       normalPointer[normalCount*3+1] = normalPointer[(normalCount-4)*3+1];
1008       normalPointer[normalCount*3+2] = normalPointer[(normalCount-4)*3+2];
1009       normalCount++;
1010       normalPointer[normalCount*3+0] = normalPointer[(normalCount-3)*3+0];
1011       normalPointer[normalCount*3+1] = normalPointer[(normalCount-3)*3+1];
1012       normalPointer[normalCount*3+2] = normalPointer[(normalCount-3)*3+2];
1013       normalCount++;
1014    }
1015 }
1016 void glesNormal3fd(double x, double y, double z)         { glesNormal3f((float)x, (float)y, (float)z); }
1017 void glesNormal3fv(float * coords)                       { glesNormal3f(coords[0], coords[1], coords[2]); }
1018
1019 void glesColorMaterial(int a, int b)
1020 {
1021    PrintLn("glColorMaterial stub");
1022 }
1023
1024 void glesTerminate()
1025 {
1026    delete vertexPointer;
1027    beginBufferSize = 0;
1028
1029    delete floatVPBuffer;
1030    shortVPSize = 0;
1031
1032    delete shortVPBuffer;
1033    floatVPSize = 0;
1034
1035    delete shortBDBuffer;
1036    shortBDSize = 0;
1037 }
1038
1039 static GLuint stippleTexture;
1040 static bool stippleEnabled;
1041
1042 void glesLineStipple( int i, unsigned short j )
1043 {
1044    uint texture[1*16];
1045    int c;
1046    int x;
1047    for(x = 0; x < 16; x++)
1048    {
1049       bool v = (j & (1 << x)) != 0;
1050       texture[x] = v ? 0xFFFFFFFF : 0;
1051    }
1052    if(!stippleTexture)
1053       glGenTextures(1, &stippleTexture);
1054    glBindTexture(GL_TEXTURE_2D, stippleTexture);
1055    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
1056    glEnable(GL_TEXTURE_2D);
1057    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1058    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1059    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1060    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1061    glMatrixMode(GL_TEXTURE);
1062    glLoadIdentity();
1063    //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
1064    glScaled(i/16.0, 1, 1.0f);
1065    glTranslated(0.5, 0.5, 0);
1066    glMatrixMode(GL_PROJECTION);
1067 }
1068
1069 void glesLightModeli( unsigned int pname, int param )
1070 {
1071    if(pname == GL_LIGHT_MODEL_TWO_SIDE)
1072       glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
1073 }
1074
1075 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
1076 void glFogi( unsigned int pname, int param ) { }
1077 void glPolygonMode( unsigned int i, unsigned int j ) { }
1078
1079
1080 // *** Picking won't be supported for now ***
1081 void glPushName( unsigned int i ) { }
1082 void glLoadName( unsigned int i ) { }
1083 void glPopName() { }
1084
1085 // Probably replace by regular glBlendFunc ...
1086 void glBlendFuncSeparate(int a, int b, int c, int d)
1087 {
1088    glBlendFunc(a, b);
1089 }
1090
1091 // For direct pixel blitting...
1092 void glRasterPos2d(double a, double b) { }
1093 void glPixelZoom(float a, float b) { }
1094 void glDrawPixels(int a, int b, int c, int d, void * e) { }
1095
1096 #else
1097
1098 /* Non OpenGL ES friendly stuff
1099 #undef GL_UNSIGNED_INT
1100 #undef GL_DOUBLE
1101 #undef GL_INT
1102 //#undef GL_POLYGON
1103 //#undef GL_QUADS
1104 #undef GL_QUAD_STRIP
1105 #undef GL_POLYGON_STIPPLE
1106 #undef GL_LINE_STIPPLE
1107 #undef GL_LINE
1108 #undef GL_FILL
1109 #undef GL_ALL_ATTRIB_BITS
1110 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
1111 */
1112
1113 #endif
1114
1115 #if !defined(__APPLE__)
1116 void (APIENTRY * glBindBufferARB) (GLenum target, GLuint buffer);
1117 void (APIENTRY * glGenBuffersARB) (GLsizei n, GLuint *buffers);
1118 void (APIENTRY * glDeleteBuffersARB) (GLsizei n, const GLuint *buffers);
1119 void (APIENTRY * glBufferDataARB) (GLenum target, int size, const GLvoid *data, GLenum usage);
1120 #endif
1121
1122 #endif
1123
1124 static int currentVertexBuffer;
1125
1126 bool GLSelectVBO(uint vbo)
1127 {
1128    if(currentVertexBuffer != vbo)
1129    {
1130       GLBindBuffer(GL_ARRAY_BUFFER, vbo);
1131       currentVertexBuffer = vbo;
1132       return true;
1133    }
1134    return false;
1135 }
1136
1137 void GLGenBuffers(int count, uint * buffer)
1138 {
1139 #ifdef __ANDROID__
1140    glGenBuffers(count, buffer);
1141 #else
1142 #if defined(__WIN32__)
1143    if(glGenBuffersARB)
1144 #endif
1145       glGenBuffersARB(count, buffer);
1146 #endif
1147 }
1148
1149 void GLDeleteBuffers(int count, GLuint * buffer)
1150 {
1151 #ifdef __ANDROID__
1152    glDeleteBuffers(count, buffer);
1153 #else
1154 #if defined(__WIN32__)
1155    if(glDeleteBuffersARB)
1156 #endif
1157       glDeleteBuffersARB(count, buffer);
1158 #endif
1159 }
1160
1161 void GLBindBuffer(int target, uint buffer)
1162 {
1163 #ifdef __ANDROID__
1164    glBindBuffer(target, buffer);
1165 #else
1166 #if defined(__WIN32__)
1167    if(glBindBufferARB)
1168 #endif
1169       glBindBufferARB(target, buffer);
1170 #endif
1171 }
1172
1173 void GLBufferData(int type, GLenum target, int size, const GLvoid *data, GLenum usage)
1174 {
1175 #ifdef __ANDROID__
1176    if(type == GL_DOUBLE)
1177       glesBufferDatad(target, size, data, usage);
1178    else if(type == GL_UNSIGNED_INT)
1179       glesBufferDatai(target, size, data, usage);
1180    else
1181       glBufferData(target, size, data, usage);
1182 #else
1183
1184 #if defined(__WIN32__)
1185    if(glBufferDataARB)
1186 #endif
1187       glBufferDataARB(target, size, data, usage);
1188
1189 #endif
1190 }
1191
1192 static int displayWidth, displayHeight;
1193
1194 #define GL_CLAMP_TO_EDGE 0x812F
1195
1196 static bool vboAvailable;
1197
1198 static bool useSingleGLContext = false;
1199 class OGLDisplay : struct
1200 {
1201 #if defined(__WIN32__)
1202    HDC hdc;
1203    HGLRC glrc;
1204
1205    HBITMAP memBitmap;
1206    HDC memDC;
1207    byte * picture;
1208    uint stride;
1209    void * pBuffer;
1210    /*
1211    int imageBuffers[2];
1212    byte * pboMemory1, * pboMemory2;
1213    */
1214 #else
1215    GLXContext glContext;
1216
1217    Pixmap pixmap;
1218    XShmSegmentInfo shminfo;
1219    XImage * image;
1220    XShmSegmentInfo shminfoShape;
1221    XImage * shapeImage;
1222    byte * picture;
1223    uint stride;
1224    GLXPbuffer pBuffer;
1225    X11Picture windowPicture;
1226    X11Picture pixmapPicture;
1227    Pixmap shapePixmap;
1228    X11Picture shapePicture;
1229 #endif
1230
1231    ColorAlpha * flippingBuffer;
1232    int flipBufH, flipBufW;
1233    bool depthWrite;
1234    int x, y;
1235 };
1236
1237 class OGLSystem : struct
1238 {
1239    int maxTextureSize;
1240    bool loadingFont;
1241    bool pow2textures;
1242 #if defined(__WIN32__)
1243    PIXELFORMATDESCRIPTOR pfd;
1244    int format;
1245    HDC hdc;
1246    HGLRC glrc;
1247    HWND hwnd;
1248 #else
1249    XVisualInfo * visualInfo;
1250    GLXContext glContext;
1251    GLXDrawable glxDrawable;
1252 #endif
1253 };
1254
1255 class OGLSurface : struct
1256 {
1257    Font font;
1258    bool opaqueText;
1259    int xOffset;
1260    bool writingText;
1261
1262    float foreground[4], background[4], bitmapMult[4];
1263 } OGLSurface;
1264
1265 class OGLMesh : struct
1266 {
1267    uint vertices;
1268    uint normals;
1269    uint texCoords;
1270    uint texCoords2;
1271    uint colors;
1272 };
1273
1274 class OGLIndices : struct
1275 {
1276    uint16 * indices;
1277    uint buffer;
1278    uint nIndices;
1279 };
1280
1281 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1282 static int primitiveTypes[RenderPrimitiveType] =
1283 {
1284    GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, GL_LINE_STRIP
1285 };
1286 #endif
1287
1288 int current;
1289 void * previous;
1290
1291 class OpenGLDisplayDriver : DisplayDriver
1292 {
1293    class_property(name) = "OpenGL";
1294
1295    bool LockSystem(DisplaySystem displaySystem)
1296    {
1297       OGLSystem oglSystem = displaySystem.driverData;
1298       if(useSingleGLContext) return true;
1299    #if defined(__WIN32__)
1300       wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1301    #elif defined(__unix__) || defined(__APPLE__)
1302       //if(previous) return true;
1303       // printf("Making SYSTEM current\n");
1304 #if !defined(__ANDROID__)
1305       glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
1306 #endif
1307       //previous = oglSystem.glContext;
1308    #endif
1309       return true;
1310    }
1311
1312    void UnlockSystem(DisplaySystem displaySystem)
1313    {
1314       if(useSingleGLContext) return;
1315    #if defined(__WIN32__)
1316       wglMakeCurrent(null, null);
1317    #elif defined(__unix__) || defined(__APPLE__)
1318       // printf("Making NULL current\n");
1319       #if defined(__ANDROID__)
1320       #else
1321       glXMakeCurrent(xGlobalDisplay, None, null);
1322       #endif
1323       // previous = null;
1324    #endif
1325    }
1326
1327    bool Lock(Display display)
1328    {
1329       OGLDisplay oglDisplay = display.driverData;
1330
1331       if(useSingleGLContext) return true;
1332    #if defined(__WIN32__)
1333       wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1334    #elif defined(__unix__) || defined(__APPLE__)
1335       // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
1336       // printf("   Making DISPLAY current\n");
1337       #if defined(__ANDROID__)
1338       #else
1339       glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1340       #endif
1341    #endif
1342       return true;
1343    }
1344
1345    void Unlock(Display display)
1346    {
1347       if(useSingleGLContext) return;
1348       //printf("   Making NULL current\n");
1349       //glXMakeCurrent(xGlobalDisplay, None, null);
1350       // if(previous)
1351          LockSystem(display.displaySystem);
1352    }
1353
1354    void DestroyDisplay(Display display)
1355    {
1356       OGLDisplay oglDisplay = display.driverData;
1357
1358       if(oglDisplay)
1359       {
1360    #if defined(__WIN32__)
1361          wglMakeCurrent( null, null );
1362
1363          if(oglDisplay.glrc)
1364             wglDeleteContext(oglDisplay.glrc);
1365
1366          if(oglDisplay.hdc && oglDisplay.pBuffer)
1367             wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1368
1369          if(oglDisplay.pBuffer)
1370             wglDestroyPbufferARB(oglDisplay.pBuffer);
1371
1372          if(oglDisplay.hdc)
1373             ReleaseDC(display.window, oglDisplay.hdc);
1374
1375          if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1376          if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1377
1378    #elif defined(__unix__) || defined(__APPLE__)
1379       #if defined(__ANDROID__)
1380       #else
1381          if(oglDisplay.shapePixmap)
1382             XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1383          if(oglDisplay.pixmap)
1384             XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1385          if(oglDisplay.image)
1386          {
1387             if(oglDisplay.shminfoShape.shmid != -1)
1388             {
1389                XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1390                if(oglDisplay.shminfo.shmaddr != (void *)-1)
1391                   shmdt(oglDisplay.shminfo.shmaddr);
1392                shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1393             }
1394          }
1395          if(oglDisplay.shapeImage)
1396          {
1397             if(oglDisplay.shminfoShape.shmid != -1)
1398             {
1399                XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1400                if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1401                   shmdt(oglDisplay.shminfoShape.shmaddr);
1402                shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1403             }
1404             XDestroyImage(oglDisplay.shapeImage);
1405             oglDisplay.shapeImage = None;
1406          }
1407
1408          glXMakeCurrent(xGlobalDisplay, None, null);
1409
1410          if(oglDisplay.glContext)
1411             glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1412       #endif
1413    #endif
1414          delete oglDisplay.flippingBuffer;
1415          delete oglDisplay;
1416          display.driverData = null;
1417       }
1418    }
1419
1420    void ::CheckExtensions(OGLSystem oglSystem)
1421    {
1422       const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
1423       if(extensions)
1424          oglSystem.pow2textures = strstr(extensions, "GL_ARB_texture_non_power_of_two") ? false : true;
1425       glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
1426    }
1427
1428    bool CreateDisplaySystem(DisplaySystem displaySystem)
1429    {
1430       bool result = false;
1431       OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
1432
1433    #ifdef __WIN32__
1434       oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
1435
1436       oglSystem.hdc = GetDC(oglSystem.hwnd);
1437       if(oglSystem.hdc)
1438       {
1439
1440          oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
1441          oglSystem.pfd.nVersion = 1;
1442          oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
1443          oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
1444          oglSystem.pfd.cColorBits = 24;
1445          oglSystem.pfd.cAlphaBits = 8;
1446          oglSystem.pfd.cDepthBits = 24;
1447          oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
1448
1449          oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
1450          DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1451
1452          if(oglSystem.pfd.cColorBits > 8)
1453          {
1454             SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1455             oglSystem.glrc = wglCreateContext(oglSystem.hdc);
1456             if(oglSystem.glrc)
1457             {
1458                wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1459
1460                  // Get Pointers To The GL Functions
1461                glActiveTextureARB = (void *) wglGetProcAddress("glActiveTextureARB");
1462                glMultiTexCoord2fARB = (void *) wglGetProcAddress("glMultiTexCoord2fARB");
1463                glClientActiveTextureARB = (void *) wglGetProcAddress("glClientActiveTextureARB");
1464                glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
1465                glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
1466                  glGenBuffersARB = (void *) wglGetProcAddress("glGenBuffersARB");
1467                  glBindBufferARB = (void *) wglGetProcAddress("glBindBufferARB");
1468                  glBufferDataARB = (void *) wglGetProcAddress("glBufferDataARB");
1469                glMapBufferARB  = (void *) wglGetProcAddress("glMapBufferARB");
1470                glUnmapBufferARB  = (void *) wglGetProcAddress("glUnmapBufferARB");
1471                  glDeleteBuffersARB = (void *) wglGetProcAddress("glDeleteBuffersARB");
1472                glBlendFuncSeparate = (void *) wglGetProcAddress("glBlendFuncSeparate");
1473
1474                wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
1475                wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
1476                wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
1477                wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
1478                wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
1479                wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
1480                wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
1481                wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
1482                wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
1483
1484                wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
1485
1486                vboAvailable = glBindBufferARB != null;
1487
1488                // eSystem_LoggingMode(LOG_MSGBOX, null);
1489
1490                if(wglChoosePixelFormatARB)
1491                {
1492                     int pixelFormat;
1493                     int valid;
1494                     int numFormats;
1495                     float fAttributes[] = {0,0};
1496                     int iAttributes[] =
1497                   {
1498                      WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
1499                             WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1500                             WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1501                             WGL_COLOR_BITS_ARB,24,
1502                             WGL_ALPHA_BITS_ARB,8,
1503                             WGL_DEPTH_BITS_ARB,16,
1504                             WGL_STENCIL_BITS_ARB,0,
1505                             WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
1506                             WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1507                             WGL_SAMPLES_ARB, 4,                                         // Check For 4x Multisampling
1508                             0,0
1509                   };
1510
1511                   //Log("Found wglChoosePixelFormatARB\n");
1512
1513                     valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1514                     if(!valid || !numFormats)
1515                     {
1516                      //Log("Can't find 4x multi sampling\n");
1517                        iAttributes[19] = 2;
1518                        valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1519                      if(!valid || !numFormats)
1520                      {
1521                         // Log("Can't find 2x multi sampling\n");
1522                         iAttributes[16] = 0;
1523                         iAttributes[17] = 0;
1524                         valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1525                      }
1526                     }
1527                   if(valid && numFormats)
1528                   {
1529                      oglSystem.format = pixelFormat;
1530                      wglMakeCurrent(null, null);
1531                      wglDeleteContext(oglSystem.glrc);
1532
1533                      // *** DescribePixelFormat does not support WGL pixel formats! ***
1534                      //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1535                      SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1536                      //Log("Successfully set pixel format\n");
1537
1538                      oglSystem.glrc = wglCreateContext(oglSystem.hdc);
1539                      wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1540                   }
1541                }
1542                /*else
1543                   eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
1544
1545                result = true;
1546
1547                CheckExtensions(oglSystem);
1548
1549                wglMakeCurrent(null, null);
1550
1551                //eSystem_DumpErrors(true);
1552             }
1553          }
1554       }
1555    #elif defined(__unix__) || defined(__APPLE__)
1556       vboAvailable = true;
1557       #if defined(__ANDROID__)
1558          egl_init_display(guiApp.desktop.windowHandle);
1559          CheckExtensions(oglSystem);
1560          result = true;
1561       #else
1562       {
1563          X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1564          XSetWindowAttributes attr;
1565          unsigned long mask;
1566
1567          int attrList[] =
1568          {
1569       #ifndef ECERE_MINIGLX
1570             GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1571       #endif
1572             GLX_RGBA,
1573             GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1574             GLX_DOUBLEBUFFER,
1575             None
1576          };
1577          oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay,  DefaultScreen( xGlobalDisplay ), attrList );
1578          attr.background_pixel = 0;
1579          attr.border_pixel = 0;
1580          attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1581          attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1582          mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1583
1584          oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1585             oglSystem.visualInfo->visual, mask, &attr );
1586       }
1587       if(oglSystem.visualInfo)
1588       {
1589          oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1590          if(oglSystem.glContext)
1591          {
1592             glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1593             // Setup Extensions
1594             CheckExtensions(oglSystem);
1595             glXMakeCurrent(xGlobalDisplay, None, null);
1596             result = true;
1597          }
1598       }
1599       #endif
1600    #endif
1601
1602       displaySystem.flags.alpha = true;
1603       displaySystem.flags.flipping = true;
1604       displaySystem.pixelFormat = pixelFormat888;
1605       return result;
1606    }
1607
1608    void DestroyDisplaySystem(DisplaySystem displaySystem)
1609    {
1610       OGLSystem oglSystem = displaySystem.driverData;
1611
1612    #if defined(__WIN32__)
1613       wglMakeCurrent( null, null );
1614
1615       if(oglSystem.glrc)
1616          wglDeleteContext(oglSystem.glrc);
1617
1618       if(oglSystem.hdc)
1619          ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1620       DestroyWindow(oglSystem.hwnd);
1621
1622    #elif defined(__unix__) || defined(__APPLE__)
1623       #if defined(__ANDROID__)
1624          egl_term_display();
1625       #else
1626       if(oglSystem.visualInfo)
1627       {
1628    #ifdef   ECERE_MINIGLX
1629          __miniglx_XFree(oglSystem.visualInfo);
1630    #else
1631          XFree(oglSystem.visualInfo);
1632    #endif
1633       }
1634
1635       if(oglSystem.glxDrawable)
1636       {
1637          XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1638          oglSystem.glxDrawable = 0;
1639       }
1640       #endif
1641    #endif
1642       delete oglSystem;
1643    }
1644
1645    bool CreateDisplay(Display display)
1646    {
1647       bool result = false;
1648       OGLDisplay oglDisplay = display.driverData;
1649       OGLSystem oglSystem = display.displaySystem.driverData;
1650       if(!oglDisplay)
1651          oglDisplay = display.driverData = OGLDisplay { };
1652       //printf("Inside CreateDisplay\n");
1653
1654 #if defined(__WIN32__) || defined(USEPBUFFER)
1655       if(!display.alphaBlend)
1656 #endif
1657       {
1658    #if defined(__WIN32__)
1659          oglDisplay.hdc = GetDC(display.window);
1660          SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1661          if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
1662          {
1663             wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1664             wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1665             result = true;
1666          }
1667          else
1668             ReleaseDC(display.window, oglDisplay.hdc);
1669    #elif defined(__unix__) || defined(__APPLE__)
1670       #if defined(__ANDROID__)
1671       #else
1672          XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1673          /*
1674 #if defined(__APPLE__)
1675          XVisualInfo template = { 0 };
1676          XWindowAttributes winAttr;
1677          int n;
1678          XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1679          template.visualid = XVisualIDFromVisual(winAttr.visual);
1680          visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1681 #ifdef _DEBUG
1682          printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1683          printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1684          printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1685          printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1686 #endif
1687          // visualInfo = oglSystem.visualInfo;
1688 //#endif
1689          */
1690          if(visualInfo)
1691          {
1692             //printf("visualInfo is not null\n");
1693             // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1694             oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1695             //XFree(visualInfo);
1696          }
1697
1698          // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1699          if(oglDisplay.glContext)
1700          {
1701             //printf("CreateDisplay Got a Context\n");
1702             glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1703             result = true;
1704          }
1705       #endif
1706    #endif
1707       }
1708 #if defined(__WIN32__) || defined(USEPBUFFER)
1709       else
1710          result = true;
1711 #endif
1712       if(result)
1713       {
1714 #if defined(__WIN32__)
1715          if(glBlendFuncSeparate)
1716             glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1717          else
1718             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1719 #else
1720 #if !defined(__OLDX__)
1721           glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1722 #else
1723          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1724 #endif
1725 #endif
1726          glEnable(GL_BLEND);
1727
1728          glMatrixMode(GL_MODELVIEW);
1729          glScaled(1.0, 1.0, -1.0);
1730          // glTranslatef(0.375f, 0.375f, 0.0f);
1731          // glTranslatef(-0.625f, -0.625f, 0.0f);
1732          glMatrixMode(GL_PROJECTION);
1733          glShadeModel(GL_FLAT);
1734
1735          // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, true);
1736          glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1737          glFogi(GL_FOG_MODE, GL_EXP);
1738          glFogf(GL_FOG_DENSITY, 0);
1739          glEnable(GL_NORMALIZE);
1740          glDepthFunc(GL_LESS);
1741          glClearDepth(1.0);
1742          glDisable(GL_MULTISAMPLE_ARB);
1743       }
1744 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1745       display.ambient = Color { 50,50,50 };
1746 #endif
1747
1748       if(!useSingleGLContext)
1749       {
1750    #if defined(__WIN32__)
1751          wglMakeCurrent(null, null);
1752    #elif defined(__unix__) || defined(__APPLE__)
1753       #if defined(__ANDROID__)
1754          result = true;
1755       #else
1756          glXMakeCurrent(xGlobalDisplay, None, null);
1757       #endif
1758    #endif
1759       }
1760
1761       return result;
1762    }
1763
1764    bool DisplaySize(Display display, int width, int height)
1765    {
1766       OGLDisplay oglDisplay = display.driverData;
1767
1768       bool result = false;
1769
1770       //printf("Inside DisplaySize\n");
1771 #if defined(__WIN32__) || defined(USEPBUFFER)
1772       OGLSystem oglSystem = display.displaySystem.driverData;
1773       if(display.alphaBlend)
1774       {
1775 #if defined(__WIN32__)
1776          const int attributes[]=
1777          {
1778             /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1779             WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1780          };
1781          int pixelFormat = 0;
1782          if(wglChoosePixelFormatARB)
1783          {
1784             int valid;
1785             int numFormats;
1786             float fAttributes[] = {0,0};
1787             int iAttributes[] =
1788             {
1789                //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1790                WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1791                     WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1792                     WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1793                     WGL_COLOR_BITS_ARB,24,
1794                     WGL_ALPHA_BITS_ARB,8,
1795                     WGL_DEPTH_BITS_ARB,16,
1796                     WGL_STENCIL_BITS_ARB,0,
1797                     WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1798                     WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1799                     WGL_SAMPLES_ARB, 4,                                         // Check For 4x Multisampling
1800                     0,0
1801             };
1802
1803             //Log("Found wglChoosePixelFormatARB\n");
1804
1805             valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1806             if(!valid || !numFormats)
1807             {
1808                //Log("Can't find 4x multi sampling\n");
1809                iAttributes[19] = 2;
1810                valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1811                if(!valid || !numFormats)
1812                {
1813                   // Log("Can't find 2x multi sampling\n");
1814                   iAttributes[16] = 0;
1815                   iAttributes[17] = 0;
1816                   valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1817                   if(!valid || !numFormats)
1818                   {
1819                      int iAttributes[] =
1820                      {
1821                         WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1822                         //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1823                         WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1824                         WGL_COLOR_BITS_ARB,24,
1825                         WGL_ALPHA_BITS_ARB,8,
1826                         WGL_DEPTH_BITS_ARB,16,
1827                         0,0
1828                      };
1829                      valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1830                   }
1831                }
1832             }
1833             if(valid && numFormats)
1834             {
1835                wglMakeCurrent(null, null);
1836             }
1837          }
1838
1839          wglMakeCurrent( null, null );
1840          wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1841          if(oglDisplay.hdc && oglDisplay.pBuffer)
1842             wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1843
1844          wglDestroyPbufferARB(oglDisplay.pBuffer);
1845
1846          if(!useSingleGLContext)
1847             wglMakeCurrent( null, null );
1848
1849          if(oglDisplay.glrc)
1850             wglDeleteContext(oglDisplay.glrc);
1851
1852          oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1853          oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1854          if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
1855          {
1856             BITMAPINFO * info;
1857             HDC hdc = GetDC(display.window);
1858
1859             wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1860             wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1861
1862             //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1863             //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1864
1865             // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1866
1867             if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1868             {
1869                HBITMAP newBitmap;
1870
1871                if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1872                oglDisplay.memDC = CreateCompatibleDC(hdc);
1873                SetMapMode(oglDisplay.memDC, MM_TEXT);
1874                info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1875                info->bmiHeader.biPlanes = 1;
1876                info->bmiHeader.biCompression = BI_RGB;
1877                info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1878                info->bmiHeader.biWidth = width;
1879                info->bmiHeader.biHeight = height;
1880                newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1881                if(newBitmap)
1882                {
1883                   SelectObject(oglDisplay.memDC, newBitmap);
1884                   if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1885                   /*
1886                   {
1887                      PIXELFORMATDESCRIPTOR pfd = { 0 };
1888                      pfd.nSize = (short)sizeof(pfd);
1889                      pfd.nVersion = 1;
1890                      pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1891                      pfd.iPixelType = PFD_TYPE_RGBA;
1892                      pfd.cColorBits = 32;
1893                      //pfd.cAlphaBits = 8;
1894                      pfd.cDepthBits = 24;
1895                      pfd.iLayerType = PFD_MAIN_PLANE;
1896
1897                      oglDisplay.hdc = oglDisplay.memDC;
1898
1899                      pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1900                      DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1901                      SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1902
1903                      oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1904                      wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1905                      wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1906                   }
1907                   */
1908                   /*
1909                   {
1910                      const int imageSize = width * height * 4;
1911
1912                      glGenBuffersARB(2, oglDisplay.imageBuffers);
1913
1914                      glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1915                      glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1916                      // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1917                      // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1918                   }
1919                   */
1920                   oglDisplay.memBitmap = newBitmap;
1921                   oglDisplay.stride = width;
1922
1923                   result = true;
1924                }
1925                delete info;
1926             }
1927             ReleaseDC(display.window, hdc);
1928          }
1929 #elif defined(__unix__) || defined(__APPLE__)
1930       #if defined(__ANDROID__)
1931          result = true;
1932       #else
1933         int attrib[] =
1934         {
1935                 GLX_DOUBLEBUFFER,  True,
1936             GLX_DEPTH_SIZE,    1,
1937                 GLX_RED_SIZE,      8,
1938                 GLX_GREEN_SIZE,    8,
1939                 GLX_BLUE_SIZE,     8,
1940                 GLX_ALPHA_SIZE,    8,
1941                 GLX_STENCIL_SIZE,  1,
1942                 //GLX_DEPTH_SIZE,    24,
1943                 GLX_RENDER_TYPE,   GLX_RGBA_BIT,
1944                 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1945                 None
1946         };
1947
1948         int PBattrib[] =
1949         {
1950                 GLX_PBUFFER_WIDTH,   width,
1951                 GLX_PBUFFER_HEIGHT,  height,
1952                 GLX_LARGEST_PBUFFER, False,
1953             None
1954         };
1955
1956         // choose a pixel format that meets our minimum requirements
1957         int count = 0;
1958
1959         GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1960          if(config)
1961          {
1962             if(oglDisplay.pixmap)
1963             {
1964                XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1965                oglDisplay.pixmap = None;
1966             }
1967             if(oglDisplay.shapePixmap)
1968             {
1969                XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1970                oglDisplay.shapePixmap = None;
1971             }
1972
1973             // Free Shared Memory Pixmap
1974             if(oglDisplay.image)
1975             {
1976                if(oglDisplay.shminfoShape.shmid != -1)
1977                {
1978                   XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1979                   if(oglDisplay.shminfo.shmaddr != (void *)-1)
1980                      shmdt(oglDisplay.shminfo.shmaddr);
1981                   shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1982                }
1983                XDestroyImage(oglDisplay.image);
1984                oglDisplay.image = None;
1985             }
1986             if(oglDisplay.shapeImage)
1987             {
1988                if(oglDisplay.shminfoShape.shmid != -1)
1989                {
1990                   XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1991                   if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1992                      shmdt(oglDisplay.shminfoShape.shmaddr);
1993                   shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1994                }
1995                XDestroyImage(oglDisplay.shapeImage);
1996                oglDisplay.shapeImage = None;
1997             }
1998
1999             if(oglDisplay.windowPicture)
2000                XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
2001             if(oglDisplay.pixmapPicture)
2002                XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
2003
2004             if(oglDisplay.pixmap)
2005                XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
2006
2007             if(oglDisplay.glContext)
2008                   glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
2009             if(oglDisplay.pBuffer)
2010                glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
2011
2012                 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
2013             if(oglDisplay.pBuffer)
2014             {
2015                    oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
2016                if(oglDisplay.glContext)
2017                {
2018                   glXMakeCurrent(xGlobalDisplay, None, null);
2019                   glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
2020
2021                   // Initialize Shared Memory Pixmap
2022                   oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
2023                      ZPixmap, null, &oglDisplay.shminfo, width, height);
2024                   if(oglDisplay.image)
2025                   {
2026                      oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
2027                         oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
2028                      if(oglDisplay.shminfo.shmid != -1)
2029                      {
2030                         oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
2031                         if(oglDisplay.shminfo.shmaddr != (void *)-1)
2032                         {
2033                            oglDisplay.shminfo.readOnly = False;
2034                            if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
2035                            {
2036                               oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
2037                                  &oglDisplay.shminfo, width, height, 32);
2038
2039                               // Initialize Shared Memory Shape Pixmap
2040                               oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
2041                                  ZPixmap, null, &oglDisplay.shminfoShape, width, height);
2042                               if(oglDisplay.shapeImage)
2043                               {
2044                                  oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
2045                                     oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
2046                                  if(oglDisplay.shminfoShape.shmid != -1)
2047                                  {
2048                                     oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
2049                                     if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
2050                                     {
2051                                        oglDisplay.shminfoShape.readOnly = False;
2052                                        if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
2053                                        {
2054                                           oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
2055                                              &oglDisplay.shminfoShape, width, height, 1);
2056                                           //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
2057
2058                                           {
2059                                              XRenderPictureAttributes attributes = { 0 };
2060                                              XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
2061                                              #if !defined(__APPLE__) && !defined(__OLDX__)
2062                                              attributes.repeat = RepeatNormal;
2063                                              #else
2064                                              attributes.repeat = 1;
2065                                              #endif
2066                                              oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
2067                                              oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
2068                                              oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
2069                                                 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
2070                                           }
2071
2072                                           oglDisplay.picture = oglDisplay.shminfo.shmaddr;
2073                                           oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
2074
2075                                           result = true;
2076                                        }
2077                                     }
2078                                  }
2079                               }
2080                            }
2081                         }
2082                      }
2083                   }
2084                }
2085             }
2086             XFree(config);
2087          }
2088      #endif
2089 #endif
2090          CreateDisplay(display);
2091 #if defined(__WIN32__)
2092          wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
2093 #elif defined(__unix__) || defined(__APPLE__)
2094       #if defined(__ANDROID__)
2095          width = eglWidth;
2096          height = eglHeight;
2097       #else
2098          glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
2099       #endif
2100 #endif
2101       }
2102       else
2103 #endif
2104          result = true;
2105       if(!result && display.alphaBlend)
2106       {
2107          printf("Alpha blending windows not supported on this display\n");
2108       }
2109       if(!result)
2110          return false;
2111
2112       result = false;
2113
2114       glViewport(0,0,width,height);
2115       glLoadIdentity();
2116       glOrtho(0,width,height,0,0.0,1.0);
2117       displayWidth = display.width = width;
2118       displayHeight = display.height = height;
2119
2120       if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
2121       {
2122          oglDisplay.flipBufW = width;
2123          oglDisplay.flipBufH = height;
2124          oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
2125       }
2126       if(oglDisplay.flippingBuffer || !width || !height)
2127          result = true;
2128
2129       return result;
2130    }
2131
2132    void DisplayPosition(Display display, int x, int y)
2133    {
2134       OGLDisplay oglDisplay = display.driverData;
2135
2136       oglDisplay.x = x;
2137       oglDisplay.y = y;
2138    }
2139
2140    void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
2141    {
2142    }
2143
2144    void RestorePalette(Display display)
2145    {
2146    }
2147
2148    void StartUpdate(Display display)
2149    {
2150    }
2151
2152    void EndUpdate(Display display)
2153    {
2154    }
2155
2156    void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
2157    {
2158    }
2159
2160    void Update(Display display, Box updateBox)
2161    {
2162 #if defined(__WIN32__) || defined(USEPBUFFER)
2163       OGLDisplay oglDisplay = display.driverData;
2164 #endif
2165       //Logf("DisplayScreen\n");
2166
2167       glFlush();
2168       glFinish();
2169 #if defined(__WIN32__) || defined(USEPBUFFER)
2170       if(display.alphaBlend)
2171       {
2172          glPixelStorei(GL_PACK_ALIGNMENT, 4);
2173          glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
2174          glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2175          glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2176          glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
2177
2178          {
2179 #if defined(__WIN32__)
2180             HDC hdc = GetDC(0);
2181             POINT point = { oglDisplay.x, oglDisplay.y};
2182             POINT srcPoint = { 0, 0 };
2183             BLENDFUNCTION blend = { 0 };
2184             SIZE size;
2185             size.cx = display.width;
2186             size.cy = display.height;
2187             blend.BlendOp = AC_SRC_OVER;
2188             blend.BlendFlags = 0;
2189             blend.SourceConstantAlpha = 255;
2190             blend.AlphaFormat = AC_SRC_ALPHA;
2191
2192             /*
2193             // Process partial images.  Mapping the buffer waits for
2194             // outstanding DMA transfers into the buffer to finish.
2195             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2196             oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
2197
2198             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2199             // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
2200
2201
2202             memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
2203             //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
2204             */
2205
2206             UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
2207             /*
2208
2209             // Unmap the image buffers
2210             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2211             glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
2212
2213             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2214             // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
2215
2216             // Bind two different buffer objects and start the glReadPixels
2217             // asynchronously. Each call will return directly after
2218             // starting the DMA transfer.
2219             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2220             glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
2221
2222             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2223             // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
2224             */
2225
2226             ReleaseDC(0, hdc);
2227 #elif defined(__unix__) || defined(__APPLE__)
2228       #if defined(__ANDROID__)
2229       #else
2230             XTransform transform =
2231             {
2232                {
2233                   { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)),  (int)(0 * (1 << 16)) },
2234                   { (int)(0.0f),           (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
2235                   { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)),  (int)(1.0f * (1<<16)) }
2236                }
2237             };
2238             XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
2239             XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
2240             XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
2241             #if !defined(__APPLE__) && !defined(__OLDX__)
2242             XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
2243             #else
2244             XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
2245             #endif
2246             XFlush(xGlobalDisplay);
2247      #endif
2248 #endif
2249          }
2250       }
2251       else
2252 #endif
2253       {
2254 #if defined(__WIN32__)
2255          //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
2256          SwapBuffers(oglDisplay.hdc);
2257 #elif defined(__unix__) || defined(__APPLE__)
2258       #if defined(__ANDROID__)
2259          eglSwapBuffers(eglDisplay, eglSurface);
2260       #else
2261          glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
2262       #endif
2263 #endif
2264       }
2265       //Logf("Out of DisplayScreen\n");
2266    }
2267
2268    void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
2269    {
2270       if(bitmap.driverData)
2271       {
2272          GLuint tex = (GLuint)(uintptr)bitmap.driverData;
2273          glDeleteTextures(1, &tex);
2274          bitmap.driverData = 0;
2275       }
2276       bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
2277    }
2278
2279    bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
2280    {
2281       OGLSystem oglSystem = displaySystem.driverData;
2282       bool result = false;
2283       Bitmap mipMap { };
2284       GLuint glBitmap = 0;
2285
2286       uint w = width, h = height;
2287       if(oglSystem.pow2textures)
2288       {
2289          w = pow2i(w);
2290          h = pow2i(h);
2291       }
2292       w = Min(w, oglSystem.maxTextureSize);
2293       h = Min(h, oglSystem.maxTextureSize);
2294
2295       glGenTextures(1, &glBitmap);
2296       glBindTexture(GL_TEXTURE_2D, glBitmap);
2297
2298       glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2299
2300       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2301       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2302
2303       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2304       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2305
2306       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2307
2308       mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
2309
2310       // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2311       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2312
2313       delete mipMap;
2314
2315       bitmap.driverData = (void *)(uintptr)glBitmap;
2316       bitmap.driver = displaySystem.driver;
2317       bitmap.width = w;
2318       bitmap.height = h;
2319
2320       result = true;
2321       return result;
2322    }
2323
2324    bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
2325    {
2326       bool result = false;
2327       OGLSystem oglSystem = displaySystem.driverData;
2328
2329       // Pre process the bitmap... First make it 32 bit
2330       if(/*bitmap.pixelFormat == pixelFormatRGBA || */bitmap.Convert(null, pixelFormat888, null))
2331       {
2332          int c, level;
2333          uint w = bitmap.width, h = bitmap.height;
2334          GLuint glBitmap = 0;
2335          if(oglSystem.pow2textures)
2336          {
2337             w = pow2i(w);
2338             h = pow2i(h);
2339          }
2340          w = Min(w, oglSystem.maxTextureSize);
2341          h = Min(h, oglSystem.maxTextureSize);
2342
2343          if(mipMaps)
2344          {
2345             while(w * 2 < h) w *= 2;
2346             while(h * 2 < w) h *= 2;
2347          }
2348
2349          // Switch ARGB to RGBA
2350          //if(bitmap.format != pixelFormatRGBA)
2351          {
2352             for(c=0; c<bitmap.size; c++)
2353             {
2354                // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
2355                // TODO:
2356                ColorAlpha color = ((ColorAlpha *)bitmap.picture)[c];
2357                ((ColorRGBA *)bitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
2358             }
2359          }
2360          bitmap.pixelFormat = pixelFormat888;
2361
2362          glGetError();
2363          glGenTextures(1, &glBitmap);
2364          if(glBitmap == 0)
2365          {
2366             //int error = glGetError();
2367             return false;
2368          }
2369
2370          glBindTexture(GL_TEXTURE_2D, glBitmap);
2371          glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2372
2373          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2374          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
2375          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2376
2377          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
2378          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
2379
2380          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2381          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2382
2383          glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2384
2385          result = true;
2386
2387          for(level = 0; result && (w > 1 || h > 1); level++, w >>= 1, h >>= 1)
2388          {
2389             Bitmap mipMap;
2390             if(bitmap.width != w || bitmap.height != h)
2391             {
2392                mipMap = Bitmap { };
2393                if(mipMap.Allocate(null, w, h, w, bitmap.pixelFormat, false))
2394                {
2395                   Surface mipSurface = mipMap.GetSurface(0,0,null);
2396                   mipSurface.Filter(bitmap, 0,0,0,0, w, h, bitmap.width, bitmap.height);
2397                   delete mipSurface;
2398                }
2399                else
2400                {
2401                   result = false;
2402                   delete mipMap;
2403                }
2404             }
2405             else
2406                mipMap = bitmap;
2407
2408             if(result)
2409             {
2410                int error;
2411                //int width = 0;
2412                glGetError();
2413                // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2414                glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2415                //printf("Calling glTexImage2D\n");
2416                //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2417                //printf("width = %d (Should be %d, %d)\n", width, w, h);
2418                if((error = glGetError()))
2419                {
2420                   //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2421                   //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2422                   result = false;
2423                }
2424             }
2425             if(mipMap != bitmap)
2426                delete mipMap;
2427             if(!mipMaps) break;
2428          }
2429
2430          if(!bitmap.keepData)
2431             bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
2432          bitmap.driverData = (void *)(uintptr)glBitmap;
2433          bitmap.driver = displaySystem.driver;
2434
2435          if(!result)
2436             FreeBitmap(displaySystem, bitmap);
2437          else if(oglSystem.loadingFont)
2438          {
2439             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2440             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2441             oglSystem.loadingFont = false;
2442          }
2443       }
2444       return result;
2445    }
2446
2447    void ReleaseSurface(Display display, Surface surface)
2448    {
2449       glDisable(GL_SCISSOR_TEST);
2450       delete surface.driverData;
2451       surface.driverData = null;
2452    }
2453
2454    bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2455    {
2456       return false;
2457    }
2458
2459    bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2460    {
2461       bool result = false;
2462       OGLSurface oglSurface = surface.driverData = OGLSurface { };
2463
2464       //Logf("GetSurface\n");
2465
2466       if(oglSurface)
2467       {
2468          if(displayWidth != display.width || displayHeight != display.height)
2469          {
2470             displayWidth = display.width;
2471             displayHeight = display.height;
2472
2473             glViewport(0,0,display.width,display.height);
2474             glLoadIdentity();
2475             glOrtho(0,display.width,display.height,0,0.0,1.0);
2476          }
2477
2478          surface.offset.x = x;
2479          surface.offset.y = y;
2480          surface.unclippedBox = surface.box = clip;
2481          oglSurface.bitmapMult[0] = 1;
2482          oglSurface.bitmapMult[1] = 1;
2483          oglSurface.bitmapMult[2] = 1;
2484          oglSurface.bitmapMult[3] = 1;
2485
2486          glEnable(GL_SCISSOR_TEST);
2487          glScissor(
2488             x+clip.left,
2489             (display.height) -(y+clip.bottom)-1,
2490             clip.right-clip.left+1,
2491             clip.bottom-clip.top+1);
2492          result = true;
2493       }
2494       return result;
2495    }
2496
2497    void Clip(Display display, Surface surface, Box clip)
2498    {
2499       Box box;
2500
2501       //Logf("Clip\n");
2502
2503       if(clip != null)
2504       {
2505          box = clip;
2506          box.Clip(surface.unclippedBox);
2507          surface.box = box;
2508       }
2509       else
2510          box = surface.box = surface.unclippedBox;
2511       box.left += surface.offset.x;
2512       box.top  += surface.offset.y;
2513       box.right+= surface.offset.x;
2514       box.bottom += surface.offset.y;
2515
2516       glScissor(
2517          box.left,display.height - box.bottom - 1,
2518          box.right-box.left+1, box.bottom-box.top+1);
2519    }
2520
2521    bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2522    {
2523       bool result = false;
2524       OGLDisplay oglDisplay = display.driverData;
2525       ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2526
2527       if(oglDisplay.flippingBuffer)
2528       {
2529          if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2530          {
2531             bitmap.Free();
2532             bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2533          }
2534          if(bitmap)
2535          {
2536             uint row;
2537
2538             glPixelStorei(GL_PACK_ALIGNMENT, 4);
2539             glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2540             glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2541             glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2542             glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2543
2544             // Need a flip...
2545             for(row = 0; row<h; row++)
2546                CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2547             result = true;
2548          }
2549       }
2550       return result;
2551    }
2552
2553    void SetForeground(Display display, Surface surface, ColorAlpha color)
2554    {
2555       OGLSurface oglSurface = surface.driverData;
2556
2557       //Logf("SetForeground\n");
2558
2559       oglSurface.foreground[0] = color.color.r/255.0f;
2560       oglSurface.foreground[1] = color.color.g/255.0f;
2561       oglSurface.foreground[2] = color.color.b/255.0f;
2562       //oglSurface.foreground[3] = 1.0f;
2563       oglSurface.foreground[3] = color.a/255.0f;
2564
2565       //if(!oglSurface.foreground[3])printf("bug");
2566    }
2567
2568    void SetBackground(Display display, Surface surface, ColorAlpha color)
2569    {
2570       OGLSurface oglSurface = surface.driverData;
2571
2572       //Logf("SetBackground\n");
2573
2574       oglSurface.background[0] = color.color.r/255.0f;
2575       oglSurface.background[1] = color.color.g/255.0f;
2576       oglSurface.background[2] = color.color.b/255.0f;
2577       //oglSurface.background[3] = 1.0;
2578       oglSurface.background[3] = color.a/255.0f;
2579    }
2580
2581    void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2582    {
2583       OGLSurface oglSurface = surface.driverData;
2584
2585       oglSurface.bitmapMult[0] = color.color.r/255.0f;
2586       oglSurface.bitmapMult[1] = color.color.g/255.0f;
2587       oglSurface.bitmapMult[2] = color.color.b/255.0f;
2588       oglSurface.bitmapMult[3] = color.a/255.0f;
2589    }
2590
2591    ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2592    {
2593       return 0;
2594    }
2595
2596    void PutPixel(Display display, Surface surface,int x,int y)
2597    {
2598       OGLSurface oglSurface = surface.driverData;
2599
2600       //Logf("PutPixel\n");
2601
2602       glColor4fv(oglSurface.foreground);
2603       glBegin(GL_POINTS);
2604       // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2605       glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2606
2607       glEnd();
2608    }
2609
2610    void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2611    {
2612       OGLSurface oglSurface = surface.driverData;
2613       float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2614       if(_x1 == _x2)
2615       {
2616          if(_y2 >= _y1)
2617             y2 += 1;
2618          else
2619             y1 += 1;
2620       }
2621       else if(_y1 == _y2)
2622       {
2623          if(_x2 >= _x1)
2624             x2 += 1;
2625          else
2626             x1 += 1;
2627       }
2628       x1 += surface.offset.x;
2629       y1 += surface.offset.y;
2630       x2 += surface.offset.x;
2631       y2 += surface.offset.y;
2632
2633       //Logf("Line\n");
2634
2635       glColor4fv(oglSurface.foreground);
2636       glBegin(GL_LINES);
2637 #ifdef __ANDROID__
2638       if(stippleEnabled)
2639       {
2640          glTexCoord2f(0.5f, 0);
2641          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2642          glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2643          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2644       }
2645       else
2646 #endif
2647       {
2648          /*
2649          glVertex2i(x1, y1);
2650          glVertex2i(x2, y2);
2651          */
2652          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2653          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2654       }
2655
2656       glEnd();
2657    }
2658
2659    void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2660    {
2661       OGLSurface oglSurface = surface.driverData;
2662       x1 += surface.offset.x;
2663       y1 += surface.offset.y;
2664       x2 += surface.offset.x;
2665       y2 += surface.offset.y;
2666
2667       //Logf("Rectangle\n");
2668
2669       glColor4fv(oglSurface.foreground);
2670 #ifdef __ANDROID__
2671       if(stippleEnabled)
2672       {
2673          glBegin(GL_LINES);
2674
2675          glTexCoord2f(0.5f, 0);
2676          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2677          glTexCoord2f(y2-y1 + 0.5f, 0);
2678          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2679
2680          glTexCoord2f(0.5f, 0);
2681          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2682          glTexCoord2f(x2 - x1 + 0.5f, 0);
2683          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2684
2685          glTexCoord2f(0.5f, 0);
2686          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2687          glTexCoord2f(y1 - y2 + 0.5f, 0);
2688          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2689
2690          glTexCoord2f(0.5f, 0);
2691          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2692          glTexCoord2f(x1 - x2 + 0.5f, 0);
2693          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2694       }
2695       else
2696 #endif
2697       {
2698          glBegin(GL_LINE_LOOP);
2699          /*
2700          glVertex2i(x1, y1);
2701          glVertex2i(x1, y2);
2702          glVertex2i(x2, y2);
2703          glVertex2i(x2, y1);
2704          */
2705          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2706          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2707          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2708          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2709       }
2710       glEnd();
2711    }
2712
2713    void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2714    {
2715       OGLSurface oglSurface = surface.driverData;
2716       //Logf("Area\n");
2717
2718       glColor4fv(oglSurface.background);
2719       glRecti(x1+surface.offset.x, y1+surface.offset.y,
2720               x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2721
2722       /*
2723       glRectf(x1+surface.offset.x, y1+surface.offset.y,
2724               x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2725       */
2726    }
2727
2728    void Clear(Display display, Surface surface, ClearType type)
2729    {
2730       OGLDisplay oglDisplay = display.driverData;
2731       OGLSurface oglSurface = surface.driverData;
2732
2733       //Logf("Clear\n");
2734       if(type != depthBuffer)
2735          glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2736       if(type != colorBuffer && !oglDisplay.depthWrite)
2737       {
2738          glDepthMask((byte)bool::true);
2739       }
2740       glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2741               ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2742       if(type != colorBuffer && !oglDisplay.depthWrite)
2743       {
2744          glDepthMask((byte)bool::false);
2745       }
2746    }
2747
2748    bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2749    {
2750       return true;
2751    }
2752
2753    void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2754    {
2755       OGLSurface oglSurface = surface.driverData;
2756
2757 #if !defined(__OLDX__)
2758          // WHY DO WE HAVE GL_ONE HERE ?
2759          /*if(glBlendFuncSeparate && !oglSurface.writingText)
2760             glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2761 #endif
2762
2763       if(!oglSurface.writingText)
2764       {
2765          // glTranslatef(-0.375f, -0.375f, 0.0f);
2766          glEnable(GL_TEXTURE_2D);
2767          glColor4fv(oglSurface.bitmapMult);
2768       }
2769       else if(oglSurface.xOffset)
2770          glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2771
2772       glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2773       glBegin(GL_QUADS);
2774
2775       if(h < 0)
2776       {
2777          glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2778          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2779          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2780          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2781          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2782          glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2783          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2784          glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2785       }
2786       else
2787       {
2788          /*
2789          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2790          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2791          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2792          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2793          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2794          glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2795          glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2796          glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2797          */
2798
2799          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2800          glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2801          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2802          glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2803          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2804          glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2805          glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2806          glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2807       }
2808       glEnd();
2809
2810       if(!oglSurface.writingText)
2811       {
2812          glDisable(GL_TEXTURE_2D);
2813
2814          //glTranslate(0.375, 0.375, 0.0);
2815       }
2816       else if(oglSurface.xOffset)
2817          glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2818
2819 #if !defined(__OLDX__)
2820          /*if(glBlendFuncSeparate && !oglSurface.writingText)
2821             glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2822 #endif
2823    }
2824
2825    void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2826    {
2827       OGLSurface oglSurface = surface.driverData;
2828
2829       //glTranslate(-0.375, -0.375, 0.0);
2830
2831       //Logf("Stretch\n");
2832
2833 #if !defined(__OLDX__)
2834       /*if(glBlendFuncSeparate)
2835          glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2836 #endif
2837
2838       glEnable(GL_TEXTURE_2D);
2839       glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2840
2841       glColor4fv(oglSurface.bitmapMult);
2842
2843       glBegin(GL_QUADS);
2844
2845       if(h < 0)
2846       {
2847          glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2848          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2849
2850          glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2851          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2852
2853          glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2854          glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2855
2856          glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2857          glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2858       }
2859       else
2860       {
2861          glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2862          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2863
2864          glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2865          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2866
2867          glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2868          glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2869
2870          glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2871          glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2872       }
2873
2874       glEnd();
2875
2876       glDisable(GL_TEXTURE_2D);
2877
2878       //glTranslate(0.375, 0.375, 0.0);
2879 #if !defined(__OLDX__)
2880       /*if(glBlendFuncSeparate)
2881          glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2882 #endif
2883
2884    }
2885
2886    void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2887    {
2888       Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2889    }
2890
2891    void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2892    {
2893       float s2dw,s2dh,d2sw,d2sh;
2894       //bool flipX = false, flipY = false;
2895
2896       //Logf("StretchDI\n");
2897
2898       if(Sgn(w) != Sgn(sw))
2899       {
2900          w = Abs(w);
2901          sw = Abs(sw);
2902          //flipX = true;
2903       }
2904       if(Sgn(h) != Sgn(sh))
2905       {
2906          h = Abs(h);
2907          sh = Abs(sh);
2908          //flipY = true;
2909       }
2910
2911       s2dw=(float)w / sw;
2912       s2dh=(float)h / sh;
2913       d2sw=(float)sw / w;
2914       d2sh=(float)sh / h;
2915
2916       //Clip against the edges of the source
2917       if(sx<0)
2918       {
2919          dx+=(int)((0-sx) * s2dw);
2920          w-=(int)((0-sx) * s2dw);
2921          sw-=0-sx;
2922          sx=0;
2923       }
2924       if(sy<0)
2925       {
2926          dy+=(int)((0-sy) * s2dh);
2927          h-=(int)((0-sy) * s2dh);
2928
2929          sh-=0-sy;
2930          sy=0;
2931       }
2932       if(sx+sw>bitmap.width-1)
2933       {
2934          w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2935          sw-=sx+sw-(bitmap.width-1)-1;
2936       }
2937       if(sy+sh>(bitmap.height-1))
2938       {
2939          h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2940          sh-=sy+sh-(bitmap.height-1)-1;
2941       }
2942       //Clip against the edges of the surfaceination
2943       if(dx<surface.box.left)
2944       {
2945          //if(!flip)
2946          sx+=(int)((surface.box.left-dx)*d2sw);
2947          sw-=(int)((surface.box.left-dx)*d2sw);
2948          w-=surface.box.left-dx;
2949          dx=surface.box.left;
2950       }
2951       if(dy<surface.box.top)
2952       {
2953          sy+=(int)((surface.box.top-dy)*d2sh);
2954          sh-=(int)((surface.box.top-dy)*d2sh);
2955          h-=surface.box.top-dy;
2956          dy=surface.box.top;
2957       }
2958       if(dx+w>surface.box.right)
2959       {
2960          //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2961          sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2962          w-=dx+w-surface.box.right-1;
2963       }
2964       if(dy+h>surface.box.bottom)
2965       {
2966          sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2967          h-=dy+h-surface.box.bottom-1;
2968       }
2969       if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2970
2971       dx += surface.offset.x;
2972       dy += surface.offset.y;
2973
2974       if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2975       {
2976          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2977          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2978          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2979          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2980          glRasterPos2d(dx,dy);
2981          //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2982          glPixelZoom(s2dw, -s2dh);
2983          glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2984          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2985          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2986          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2987          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2988       }
2989    }
2990
2991    void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2992    {
2993       //Logf("BlitDI\n");
2994
2995       //Clip against the edges of the source
2996       if(sx<0)
2997       {
2998          dx+=-sx;
2999          w-=-sx;
3000          sx=0;
3001       }
3002       if(sy<0)
3003       {
3004          dy+=0-sy;
3005          h-=0-sy;
3006          sy=0;
3007       }
3008       if(sx+w>bitmap.width-1)
3009          w-=sx+w-(bitmap.width-1)-1;
3010       if(sy+h>bitmap.height-1)
3011          h-=sy+h-(bitmap.height-1)-1;
3012       //Clip against the edges of the surfaceination
3013       if(dx<surface.box.left)
3014       {
3015          //if(!flip)
3016          sx+=surface.box.left-dx;
3017          w-=surface.box.left-dx;
3018          dx=surface.box.left;
3019       }
3020       if(dy<surface.box.top)
3021       {
3022          sy+=surface.box.top-dy;
3023          h-=surface.box.top-dy;
3024          dy=surface.box.top;
3025       }
3026       if(dx+w>surface.box.right)
3027       {
3028          //if(flip) sx+=dx+w-surface.box.right-1;
3029          w-=dx+w-surface.box.right-1;
3030       }
3031       if(dy+h>surface.box.bottom)
3032          h-=dy+h-surface.box.bottom-1;
3033       if((w<=0)||(h<=0))
3034          return;
3035
3036       dx += surface.offset.x;
3037       dy += surface.offset.y;
3038
3039       if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
3040       {
3041          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3042          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
3043          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
3044          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
3045          glRasterPos2d(dx,dy);
3046          glPixelZoom(1,-1);
3047          glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
3048          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3049          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3050          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3051          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3052       }
3053    }
3054
3055    void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3056    {
3057       StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
3058    }
3059
3060    void UnloadFont(DisplaySystem displaySystem, Font font)
3061    {
3062       ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
3063    }
3064
3065    Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
3066    {
3067       Font font;
3068       OGLSystem oglSystem = displaySystem.driverData;
3069       oglSystem.loadingFont = true;
3070       font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
3071       return font;
3072    }
3073
3074    void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
3075    {
3076       ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
3077    }
3078
3079    void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
3080    {
3081       OGLSurface oglSurface = surface.driverData;
3082       OGLSystem oglSystem = display.displaySystem.driverData;
3083       oglSystem.loadingFont = true;
3084
3085       //glTranslated(-0.375, -0.375, 0.0);
3086
3087       //Logf("Blit\n");
3088
3089       if(surface.textOpacity)
3090       {
3091          int w, h;
3092          FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
3093          display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
3094       }
3095
3096       oglSurface.writingText = true;
3097
3098       glEnable(GL_TEXTURE_2D);
3099       glColor4fv(oglSurface.foreground);
3100
3101       ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
3102       oglSurface.writingText = false;
3103       oglSystem.loadingFont = false;
3104
3105       glDisable(GL_TEXTURE_2D);
3106
3107       //glTranslated(0.375, 0.375, 0.0);
3108    }
3109
3110    void TextFont(Display display, Surface surface, Font font)
3111    {
3112       ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
3113    }
3114
3115    void TextOpacity(Display display, Surface surface, bool opaque)
3116    {
3117       OGLSurface oglSurface = surface.driverData;
3118       oglSurface.opaqueText = opaque;
3119    }
3120
3121    void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
3122    {
3123       OGLSurface oglSurface = surface.driverData;
3124       OGLSystem oglSystem = display.displaySystem.driverData;
3125       oglSystem.loadingFont = true;
3126       FontExtent(display.displaySystem, oglSurface.font, text, len, width, height);
3127       oglSystem.loadingFont = false;
3128    }
3129
3130    void DrawingChar(Display display, Surface surface, char character)
3131    {
3132
3133    }
3134
3135    void LineStipple(Display display, Surface surface, uint32 stipple)
3136    {
3137       //Logf("Stipple\n");
3138
3139       if(stipple)
3140       {
3141 #if defined(__ANDROID__)
3142          stippleEnabled = true;
3143          glesLineStipple(1, (uint16)stipple);
3144 #else
3145          glLineStipple(1, (uint16)stipple);
3146          glEnable(GL_LINE_STIPPLE);
3147 #endif
3148       }
3149       else
3150       {
3151 #if defined(__ANDROID__)
3152          stippleEnabled = false;
3153          glMatrixMode(GL_TEXTURE);
3154          glLoadIdentity();
3155          glMatrixMode(GL_PROJECTION);
3156          glDisable(GL_TEXTURE_2D);
3157 #else
3158          glDisable(GL_LINE_STIPPLE);
3159 #endif
3160       }
3161    }
3162 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
3163    void SetRenderState(Display display, RenderState state, uint value)
3164    {
3165       OGLDisplay oglDisplay = display.driverData;
3166       //Logf("RenderState\n");
3167
3168       switch(state)
3169       {
3170          case antiAlias:
3171             if(value)
3172                glEnable(GL_MULTISAMPLE_ARB);
3173             else
3174                glDisable(GL_MULTISAMPLE_ARB);
3175             break;
3176          case fillMode:
3177             glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
3178             break;
3179          case depthTest:
3180             if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
3181             break;
3182          case depthWrite:
3183             if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
3184             oglDisplay.depthWrite = (bool)value;
3185             break;
3186          case fogColor:
3187          {
3188             float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3189             glFogfv(GL_FOG_COLOR, (float *)&color);
3190             break;
3191          }
3192          case fogDensity:
3193             glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { value }.f * nearPlane));
3194             break;
3195          case blend:
3196             if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
3197             break;
3198          case ambient:
3199          {
3200             float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3201             glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
3202             break;
3203          }
3204          case alphaWrite:
3205          {
3206             if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
3207             break;
3208          }
3209          case vSync:
3210          {
3211 #if defined(__WIN32__)
3212             wglSwapIntervalEXT(value ? 1 : 0);
3213 #endif
3214             break;
3215          }
3216       }
3217    }
3218
3219    void SetLight(Display display, int id, Light light)
3220    {
3221       //Logf("SetLight\n");
3222
3223       if(light != null)
3224       {
3225          Object lightObject = light.lightObject;
3226          float position[4] = { 0, 0, 0, 0 };
3227          float color[4] = { 0, 0, 0, 1 };
3228
3229          glEnable(GL_LIGHT0 + id);
3230          /*
3231          glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
3232          glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
3233          glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
3234          */
3235
3236          if(!light.multiplier) light.multiplier = 1.0f;
3237
3238          color[0] = light.diffuse.r * light.multiplier;
3239          color[1] = light.diffuse.g * light.multiplier;
3240          color[2] = light.diffuse.b * light.multiplier;
3241          glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
3242
3243          color[0] = light.ambient.r * light.multiplier;
3244          color[1] = light.ambient.g * light.multiplier;
3245          color[2] = light.ambient.b * light.multiplier;
3246          glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
3247          color[0] = light.specular.r * light.multiplier;
3248          color[1] = light.specular.g * light.multiplier;
3249          color[2] = light.specular.b * light.multiplier;
3250          glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
3251
3252          if(lightObject)
3253          {
3254             Vector3D positionVector;
3255             if(light.flags.spot)
3256             {
3257                if(lightObject.flags.root || !lightObject.parent)
3258                {
3259                   positionVector = lightObject.transform.position;
3260                   positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3261                }
3262                else
3263                {
3264                   positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
3265                   if(display.display3D.camera)
3266                      positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3267                }
3268                position[3] = 1;
3269             }
3270             else
3271             {
3272                if(!light.direction.x && !light.direction.y && !light.direction.z)
3273                {
3274                   Vector3Df vector { 0,0,-1 };
3275                   Matrix mat;
3276                   mat.RotationQuaternion(light.orientation);
3277                   positionVector.MultMatrixf(vector, mat);
3278                }
3279                else
3280                {
3281                   positionVector = light.direction;
3282                   position[3] = 1;
3283                }
3284             }
3285
3286             position[0] = (float)positionVector.x;
3287             position[1] = (float)positionVector.y;
3288             position[2] = (float)positionVector.z;
3289
3290             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3291
3292             /*
3293             // Display Light Position
3294             glDisable(GL_LIGHTING);
3295             glDisable(GL_DEPTH_TEST);
3296             glColor3f(1,1,1);
3297             glPointSize(10);
3298             glBegin(GL_POINTS);
3299             glVertex3fv(position);
3300             glEnd();
3301             glEnable(GL_DEPTH_TEST);
3302             glEnable(GL_LIGHTING);
3303
3304
3305             // Display Target
3306             if(lightObject.flags.root || !lightObject.parent)
3307             {
3308                positionVector = light.target.transform.position;
3309                positionVector.Subtract(positionVector, display.camera.cPosition);
3310             }
3311             else
3312             {
3313                positionVector.MultMatrix(light.target.transform.position,
3314                   lightObject.light.target.parent.matrix);
3315                positionVector.Subtract(positionVector, display.camera.cPosition);
3316             }
3317
3318             position[0] = positionVector.x;
3319             position[1] = positionVector.y;
3320             position[2] = positionVector.z;
3321
3322             glDisable(GL_LIGHTING);
3323             glDisable(GL_DEPTH_TEST);
3324             glColor3f(1,1,0);
3325             glPointSize(10);
3326             glBegin(GL_POINTS);
3327             glVertex3fv(position);
3328             glEnd();
3329             glEnable(GL_DEPTH_TEST);
3330             glEnable(GL_LIGHTING);
3331             */
3332
3333             if(light.flags.attenuation)
3334             {
3335                glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
3336                glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
3337                glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
3338             }
3339
3340             if(light.flags.spot)
3341             {
3342                float exponent = 0;
3343                #define MAXLIGHT  0.9
3344                float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
3345                // Figure out exponent out of the hot spot
3346                exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
3347
3348                glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
3349                glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
3350                glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
3351             }
3352          }
3353          else
3354          {
3355
3356             Vector3Df vector { 0,0,-1 };
3357             Vector3Df direction;
3358             Matrix mat;
3359
3360             mat.RotationQuaternion(light.orientation);
3361             direction.MultMatrix(vector, mat);
3362
3363             position[0] = direction.x;
3364             position[1] = direction.y;
3365             position[2] = direction.z;
3366
3367             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3368          }
3369       }
3370       else
3371          glDisable(GL_LIGHT0 + id);
3372    }
3373
3374    void SetCamera(Display display, Surface surface, Camera camera)
3375    {
3376       OGLDisplay oglDisplay = display.driverData;
3377       //Logf("SetCamera\n");
3378
3379       if(camera)
3380       {
3381          int left = surface.box.left + surface.offset.x;
3382          int top = surface.box.top  + surface.offset.y;
3383          int right = surface.box.right + surface.offset.x;
3384          int bottom = surface.box.bottom + surface.offset.y;
3385          float origX = surface.offset.x + camera.origin.x;
3386          float origY = surface.offset.y + camera.origin.y;
3387          int x = left;
3388          int y = display.height - bottom - 1;
3389          int w = right - left + 1;
3390          int h = bottom - top + 1;
3391
3392          // *** ViewPort ***
3393          glViewport(x, y, w, h);
3394
3395          // *** Projection Matrix ***
3396          if(!display.display3D.camera)
3397             glPushMatrix();
3398          else
3399             glMatrixMode(GL_PROJECTION);
3400          if(display.display3D.collectingHits)
3401          {
3402             float pickX = display.display3D.pickX + surface.offset.x;
3403             float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3404             Matrix pickMatrix
3405             {
3406                {
3407                   w / display.display3D.pickWidth, 0, 0, 0,
3408                   0, h / display.display3D.pickHeight, 0, 0,
3409                   0, 0, 1, 0,
3410                   (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3411                   (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3412                }
3413             };
3414             glLoadMatrixd(pickMatrix.array);
3415          }
3416          else
3417             glLoadIdentity();
3418          glFrustum(
3419             (left   - origX) * camera.zMin / camera.focalX,
3420             (right  - origX) * camera.zMin / camera.focalX,
3421             (bottom - origY) * camera.zMin / camera.focalY,
3422             (top    - origY) * camera.zMin / camera.focalY,
3423             camera.zMin, camera.zMax);
3424
3425          glDisable(GL_BLEND);
3426
3427          // *** Z Inverted Identity Matrix ***
3428          glMatrixMode(GL_MODELVIEW);
3429          if(!display.display3D.camera)
3430             glPushMatrix();
3431
3432          glLoadIdentity();
3433
3434          glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3435
3436          // *** View Matrix ***
3437          glMultMatrixd(camera.viewMatrix.array);
3438
3439          // *** Lights ***
3440          // ...
3441
3442          glEnable(GL_DEPTH_TEST);
3443          glEnable(GL_LIGHTING);
3444          glShadeModel(GL_SMOOTH);
3445          glDepthMask((byte)bool::true);
3446          oglDisplay.depthWrite = true;
3447
3448          glEnable(GL_MULTISAMPLE_ARB);
3449       }
3450       else if(display.display3D.camera)
3451       {
3452          oglDisplay.depthWrite = false;
3453          glViewport(0,0,display.width,display.height);
3454
3455          glDisable(GL_CULL_FACE);
3456          glDisable(GL_DEPTH_TEST);
3457          glDisable(GL_LIGHTING);
3458          glDisable(GL_FOG);
3459          glDisable(GL_TEXTURE_2D);
3460          glShadeModel(GL_FLAT);
3461          glEnable(GL_BLEND);
3462          glDisable(GL_MULTISAMPLE_ARB);
3463
3464          // *** Restore 2D MODELVIEW Matrix ***
3465          glPopMatrix();
3466
3467          // *** Restore 2D PROJECTION Matrix ***
3468          glMatrixMode(GL_PROJECTION);
3469          glPopMatrix();
3470       }
3471
3472       GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
3473    }
3474
3475    void ApplyMaterial(Display display, Material material, Mesh mesh)
3476    {
3477       //Logf("ApplyMaterial\n");
3478
3479       // Basic Properties
3480       if(material.flags.doubleSided)
3481       {
3482          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3483          glDisable(GL_CULL_FACE);
3484       }
3485       else
3486       {
3487          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3488          glEnable(GL_CULL_FACE);
3489       }
3490
3491       // Fog
3492       if(material.flags.noFog)
3493          glDisable(GL_FOG);
3494       else
3495          glEnable(GL_FOG);
3496
3497       // Maps
3498       if(material.baseMap && mesh.texCoords)
3499       {
3500          Bitmap map = material.baseMap;
3501          glEnable(GL_TEXTURE_2D);
3502          glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3503
3504          glMatrixMode(GL_TEXTURE);
3505          glLoadIdentity();
3506          if(material.uScale && material.vScale)
3507             glScalef(material.uScale, material.vScale, 1);
3508          glMatrixMode(GL_MODELVIEW);
3509
3510          if(material.flags.tile)
3511          {
3512             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3513             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3514          }
3515          else
3516          {
3517             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3518             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3519          }
3520       }
3521       else
3522          glDisable(GL_TEXTURE_2D);
3523
3524       if(mesh.flags.colors)
3525       {
3526          glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3527          glEnable(GL_COLOR_MATERIAL);
3528       }
3529       else
3530       {
3531          glDisable(GL_COLOR_MATERIAL);
3532          {
3533             float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3534             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3535          }
3536          {
3537             float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3538             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3539          }
3540       }
3541       {
3542          float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3543          glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3544       }
3545       {
3546          float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3547          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3548       }
3549
3550       glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3551    }
3552
3553    void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3554    {
3555       OGLMesh oglMesh = mesh.data;
3556       if(oglMesh)
3557       {
3558          if(!mesh.flags.vertices)
3559          {
3560             if(oglMesh.vertices)
3561             {
3562                GLDeleteBuffers(1, &oglMesh.vertices);
3563                oglMesh.vertices = 0;
3564             }
3565             delete mesh.vertices;
3566          }
3567          if(!mesh.flags.normals)
3568          {
3569             if(oglMesh.normals)
3570             {
3571                GLDeleteBuffers(1, &oglMesh.normals);
3572                oglMesh.normals = 0;
3573             }
3574             delete mesh.normals;
3575          }
3576          if(!mesh.flags.texCoords1)
3577          {
3578             if(oglMesh.texCoords)
3579             {
3580                GLDeleteBuffers(1, &oglMesh.texCoords);
3581                oglMesh.texCoords = 0;
3582             }
3583             delete mesh.texCoords;
3584          }
3585          if(!mesh.flags.texCoords2)
3586          {
3587             if(oglMesh.texCoords2)
3588             {
3589                GLDeleteBuffers(1, &oglMesh.texCoords2);
3590                oglMesh.texCoords2 = 0;
3591             }
3592             /*
3593             delete mesh.texCoords2;
3594             */
3595          }
3596          if(!mesh.flags.colors)
3597          {
3598             if(oglMesh.colors)
3599             {
3600                GLDeleteBuffers(1, &oglMesh.colors);
3601                oglMesh.colors = 0;
3602             }
3603          }
3604          if(!mesh.flags)
3605          {
3606             delete oglMesh;
3607             mesh.data = null;
3608          }
3609       }
3610    }
3611
3612    bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh)
3613    {
3614       bool result = false;
3615
3616       if(!mesh.data)
3617          mesh.data = OGLMesh { };
3618       if(mesh.data)
3619       {
3620          OGLMesh oglMesh = mesh.data;
3621
3622          if(mesh.flags.vertices && !oglMesh.vertices && !mesh.vertices)
3623          {
3624             mesh.vertices = mesh.flags.doubleVertices ? (Vector3Df *)new Vector3D[mesh.nVertices] : new Vector3Df[mesh.nVertices];
3625             GLGenBuffers(1, &oglMesh.vertices);
3626          }
3627          if(mesh.flags.normals && !oglMesh.normals && !mesh.normals)
3628          {
3629             GLGenBuffers( 1, &oglMesh.normals);
3630             mesh.normals = mesh.flags.doubleNormals ? (Vector3Df *)new Vector3D[mesh.nVertices] : new Vector3Df[mesh.nVertices];
3631          }
3632          if(mesh.flags.texCoords1 && !oglMesh.texCoords && !mesh.texCoords)
3633          {
3634             GLGenBuffers( 1, &oglMesh.texCoords);
3635             mesh.texCoords = new Pointf[mesh.nVertices];
3636          }
3637          if(mesh.flags.colors && !oglMesh.colors && !mesh.colors)
3638          {
3639             GLGenBuffers( 1, &oglMesh.colors);
3640             mesh.colors = new ColorRGBAf[mesh.nVertices];
3641          }
3642          result = true;
3643       }
3644       return result;
3645    }
3646
3647    void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3648    {
3649       OGLMesh oglMesh = mesh.data;
3650       if(!flags) flags = mesh.flags;
3651
3652       if(vboAvailable)
3653       {
3654          if(!(flags.vertices) || oglMesh.vertices)
3655          {
3656             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices);
3657             GLBufferData( mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, GL_STATIC_DRAW_ARB );
3658          }
3659
3660          if(!(flags.normals) || oglMesh.normals)
3661          {
3662             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
3663             GLBufferData( mesh.flags.doubleNormals ? GL_DOUBLE : GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, GL_STATIC_DRAW_ARB );
3664          }
3665
3666          if(!(flags.texCoords1) || oglMesh.texCoords)
3667          {
3668             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
3669             GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(Pointf), mesh.texCoords, GL_STATIC_DRAW_ARB );
3670          }
3671
3672          if(!(flags.colors) || oglMesh.colors)
3673          {
3674             GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
3675             GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, GL_STATIC_DRAW_ARB );
3676          }
3677
3678          GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
3679       }
3680    }
3681
3682    bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3683    {
3684       bool result = true;
3685
3686         return result;
3687    }
3688
3689    void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3690    {
3691       if(oglIndices)
3692       {
3693          if(oglIndices.buffer)
3694             GLDeleteBuffers(1, &oglIndices.buffer);
3695          delete oglIndices.indices;
3696          delete oglIndices;
3697       }
3698    }
3699
3700    void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3701    {
3702       OGLIndices oglIndices = OGLIndices { };
3703       if(oglIndices)
3704       {
3705          oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3706          GLGenBuffers( 1, &oglIndices.buffer);
3707          oglIndices.nIndices = nIndices;
3708       }
3709       return oglIndices;
3710    }
3711
3712    void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3713    {
3714       if(vboAvailable)
3715       {
3716          GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
3717          GLBufferData( indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, GL_ELEMENT_ARRAY_BUFFER_ARB, nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3718             oglIndices.indices, GL_STATIC_DRAW_ARB);
3719          GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3720       }
3721    }
3722
3723    uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3724    {
3725
3726       return oglIndices.indices;
3727    }
3728
3729    void SelectMesh(Display display, Mesh mesh)
3730    {
3731       //Logf("SelectMesh\n");
3732
3733 #if !defined( __ANDROID__) && !defined(__APPLE__)
3734 #if defined(__WIN32__)
3735       if(glUnlockArraysEXT)
3736 #endif
3737          if(display.display3D.mesh)
3738             glUnlockArraysEXT();
3739 #endif
3740       if(mesh)
3741       {
3742          OGLMesh oglMesh = mesh.data;
3743
3744          // *** Vertex Stream ***
3745          glEnableClientState(GL_VERTEX_ARRAY);
3746          if(!display.display3D.collectingHits && oglMesh)
3747          {
3748             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices );
3749             glVertexPointer(3, mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT, 0, vboAvailable ? null : mesh.vertices);
3750
3751             // *** Normals Stream ***
3752             if(mesh.normals)
3753             {
3754                glEnableClientState(GL_NORMAL_ARRAY);
3755                GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
3756                glNormalPointer(mesh.flags.doubleNormals ? GL_DOUBLE : GL_FLOAT, 0, vboAvailable ? null : mesh.normals);
3757             }
3758             else
3759                glDisableClientState(GL_NORMAL_ARRAY);
3760
3761             // *** Texture Coordinates Stream ***
3762             if(mesh.texCoords)
3763             {
3764                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3765                GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
3766                glTexCoordPointer(2, GL_FLOAT, 0, vboAvailable ? null : mesh.texCoords);
3767             }
3768             else
3769                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3770
3771             // *** Color Stream ***
3772             if(mesh.colors)
3773             {
3774                glEnableClientState(GL_COLOR_ARRAY);
3775                GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
3776                glColorPointer(4, GL_FLOAT, 0, vboAvailable ? null : mesh.colors);
3777             }
3778             else
3779                glDisableClientState(GL_COLOR_ARRAY);
3780
3781          }
3782          else
3783          {
3784             GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
3785             glVertexPointer(3,mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT,0,mesh.vertices);
3786             if(mesh.normals && !display.display3D.collectingHits)
3787             {
3788                glEnableClientState(GL_NORMAL_ARRAY);
3789                glNormalPointer(mesh.flags.doubleNormals ? GL_DOUBLE : GL_FLOAT, 0, mesh.normals);
3790             }
3791             else
3792                glDisableClientState(GL_NORMAL_ARRAY);
3793             if(mesh.texCoords && !display.display3D.collectingHits)
3794             {
3795                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3796                glTexCoordPointer(2, GL_FLOAT, 0, mesh.texCoords);
3797             }
3798             else
3799                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3800             if(mesh.colors && !display.display3D.collectingHits)
3801             {
3802                glEnableClientState(GL_COLOR_ARRAY);
3803                glColorPointer(4, GL_FLOAT, 0, mesh.colors);
3804             }
3805             else
3806                glDisableClientState(GL_COLOR_ARRAY);
3807          }
3808
3809 #if !defined(__ANDROID__) && !defined(__APPLE__)
3810
3811 #if defined(__WIN32__)
3812          if(glLockArraysEXT)
3813 #endif
3814             glLockArraysEXT(0, mesh.nVertices);
3815 #endif
3816       }
3817       else
3818          GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
3819    }
3820
3821    void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3822    {
3823       //Logf("DrawPrimitives\n");
3824
3825       if(primitive->type.vertexRange)
3826          glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3827       else
3828       {
3829          //    *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3830          // HACK TO SPEED THINGS UP...
3831 #ifndef __ANDROID__
3832          GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3833          if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3834          {
3835             int c;
3836             glBegin(primitiveTypes[primitive->type.primitiveType]);
3837             if(primitive->data)
3838             {
3839                OGLIndices oglIndices = primitive->data;
3840                MeshFeatures flags = mesh.flags;
3841                for(c = 0; c<primitive->nIndices; c++)
3842                {
3843                   uint16 index = ((uint16 *) oglIndices.indices)[c];
3844                   if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3845                   if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3846                   if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3847                   glVertex3fv((float *)&mesh.vertices[index]);
3848                }
3849             }
3850             glEnd();
3851          }
3852          else
3853 #endif
3854          {
3855             OGLIndices oglIndices = primitive->data;
3856
3857             if(!display.display3D.collectingHits && vboAvailable && oglIndices)
3858             {
3859                GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
3860                glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3861                   primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
3862                GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3863             }
3864             else
3865                glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3866                   primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, oglIndices ? oglIndices.indices : primitive->indices);
3867          }
3868       }
3869    }
3870
3871    void PushMatrix(Display display)
3872    {
3873       glPushMatrix();
3874    }
3875
3876    void PopMatrix(Display display, bool setMatrix)
3877    {
3878       glPopMatrix();
3879    }
3880
3881    void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3882    {
3883       Matrix matrix = transMatrix;
3884       Camera camera = useCamera ? display.display3D.camera : null;
3885
3886       if(viewSpace)
3887       {
3888          glLoadIdentity();
3889          glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3890       }
3891       else if(camera)
3892       {
3893          glTranslated(
3894             matrix.m[3][0] - camera.cPosition.x,
3895             matrix.m[3][1] - camera.cPosition.y,
3896             matrix.m[3][2] - camera.cPosition.z);
3897       }
3898       else
3899          glTranslated(
3900             matrix.m[3][0],
3901             matrix.m[3][1],
3902             matrix.m[3][2]);
3903
3904       matrix.m[3][0] = 0;
3905       matrix.m[3][1] = 0;
3906       matrix.m[3][2] = 0;
3907
3908       glMultMatrixd(matrix.array);
3909    }
3910 #endif
3911 }
3912
3913 public void UseSingleGLContext(bool useSingle)
3914 {
3915    useSingleGLContext = useSingle;
3916 }
3917
3918 default dllexport void *
3919 #if defined(__WIN32__)
3920 __attribute__((stdcall))
3921 #endif
3922 IS_GLGetContext(DisplaySystem displaySystem)
3923 {
3924    if(displaySystem)
3925    {
3926       OGLSystem system = displaySystem.driverData;
3927 #if defined(__WIN32__)
3928       return system.glrc;
3929 #else
3930       return system.glContext;
3931 #endif
3932    }
3933    return null;
3934 }
3935
3936 #endif