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