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