ecere/gfx/drivers/OpenGL: Added GLLoadMatrix()
[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       currentVertexBuffer = 0;
557       return true;
558    }
559
560    static void egl_term_display()
561    {
562       if(stippleTexture)
563       {
564          glDeleteTextures(1, &stippleTexture);
565          stippleTexture = 0;
566       }
567       if(eglDisplay != EGL_NO_DISPLAY)
568       {
569          eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
570          if(eglContext != EGL_NO_CONTEXT)
571             eglDestroyContext(eglDisplay, eglContext);
572          if(eglSurface != EGL_NO_SURFACE)
573             eglDestroySurface(eglDisplay, eglSurface);
574          eglTerminate(eglDisplay);
575       }
576       eglDisplay = EGL_NO_DISPLAY;
577       eglContext = EGL_NO_CONTEXT;
578       eglSurface = EGL_NO_SURFACE;
579    }
580
581 #endif
582
583 // OpenGL Immediate Mode Porting Kit
584 static int beginCount;
585 static int vertexCount;
586 static int normalCount;
587 static float *vertexPointer;
588 static float *normalPointer;
589 static GLenum beginMode = -1;
590 static uint beginBufferSize, normalBufferSize;
591 static int numVertexCoords = 2;
592 static bool vertexColorValues = false;
593 static int vertexStride = 4;
594 static int vertexOffset = 2;
595
596 public void glesRecti(int a, int b, int c, int d)
597 {
598    glBegin(GL_QUADS);
599    glVertex2i(a, b);
600    glVertex2i(a, d);
601    glVertex2i(c, d);
602    glVertex2i(c, b);
603    glEnd();
604 }
605
606 public void glesBegin(GLenum mode)
607 {
608    beginMode = mode;
609    beginCount = 0;
610    vertexCount = 0;
611    vertexColorValues = false;
612    vertexOffset = 2;
613    vertexStride = 4;
614    numVertexCoords = 2;
615
616    if(!vertexPointer)
617    {
618       normalBufferSize = beginBufferSize = 1024;  // default number of vertices
619       vertexPointer = new float[beginBufferSize * vertexStride];
620       normalPointer = new float[normalBufferSize * 3];
621    }
622 }
623
624 public void glesTexCoord2f(float x, float y)
625 {
626    int count = vertexCount;
627
628    if(vertexCount + numVertexCoords > beginBufferSize)
629    {
630       beginBufferSize = beginBufferSize + beginBufferSize/2;
631       vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
632    }
633
634    vertexPointer[count*vertexStride  ] = x;
635    vertexPointer[count*vertexStride+1] = y;
636    count++;
637
638    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
639    {
640       vertexPointer[count*vertexStride  ] = vertexPointer[(count-4)*vertexStride];
641       vertexPointer[count*vertexStride+1] = vertexPointer[(count-4)*vertexStride+1];
642       count++;
643       vertexPointer[count*vertexStride  ] = vertexPointer[(count-3)*vertexStride];
644       vertexPointer[count*vertexStride+1] = vertexPointer[(count-3)*vertexStride+1];
645       count++;
646    }
647 }
648 public void glesTexCoord2i(int x, int y)       { glesTexCoord2f((float)x, (float)y); }
649 public void glesTexCoord2d(double x, double y) { glesTexCoord2f((float)x, (float)y); }
650 public void glesTexCoord2fv(float * a)         { glesTexCoord2f(a[0], a[1]); }
651
652 public void glesVertex2f(float x, float y)
653 {
654    numVertexCoords = 2;
655    vertexStride = vertexOffset + numVertexCoords;
656
657    if(vertexCount + 4 > beginBufferSize)
658    {
659       beginBufferSize = beginBufferSize + beginBufferSize/2;
660       vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
661    }
662
663    vertexPointer[vertexCount*vertexStride+vertexOffset] = x;
664    vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = y;
665    vertexCount++;
666
667    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
668    {
669       vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset];
670       vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset + 1];
671       vertexCount++;
672       vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset];
673       vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset + 1];
674       vertexCount++;
675    }
676    beginCount++;
677 }
678 public void glesVertex2i(int x, int y)         { glesVertex2f((float)x, (float)y); }
679 public void glesVertex2d(double x, double y)   { glesVertex2f((float)x, (float)y); }
680
681 public void glesEnd(void)
682 {
683    int mode = beginMode;
684    if(mode == GL_QUADS)        mode = GL_TRIANGLES;
685    else if(mode == GL_POLYGON) mode = GL_TRIANGLE_FAN;
686
687    GLSelectVBO(0);
688    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
689    glTexCoordPointer(2, GL_FLOAT,  vertexStride * sizeof(float), vertexPointer);
690    if(vertexColorValues)
691    {
692       glEnableClientState(GL_COLOR_ARRAY);
693       glColorPointer(4, GL_FLOAT, vertexStride * sizeof(float), vertexPointer + 2);
694    }
695    glVertexPointer  (numVertexCoords, GL_FLOAT, (vertexStride)*sizeof(float),vertexPointer+vertexOffset);
696    if(normalCount && normalCount == vertexCount)
697    {
698       glEnableClientState(GL_NORMAL_ARRAY);
699       glNormalPointer  (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 static int currentVertexBuffer;
1213
1214 public void GLLoadMatrix(Matrix matrix)
1215 {
1216    float m[16] =
1217    {
1218       (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
1219       (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
1220       (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
1221       (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
1222    };
1223    glLoadMatrixf(m);
1224 }
1225
1226 bool GLSelectVBO(uint vbo)
1227 {
1228    if(currentVertexBuffer != vbo)
1229    {
1230       GLBindBuffer(GL_ARRAY_BUFFER, vbo);
1231       currentVertexBuffer = vbo;
1232       return true;
1233    }
1234    return false;
1235 }
1236
1237 void GLGenBuffers(int count, uint * buffer)
1238 {
1239 #ifdef __ANDROID__
1240    glGenBuffers(count, buffer);
1241 #else
1242 #if defined(__WIN32__)
1243    if(glGenBuffersARB)
1244 #endif
1245       glGenBuffersARB(count, buffer);
1246 #endif
1247 }
1248
1249 void GLDeleteBuffers(int count, GLuint * buffer)
1250 {
1251 #ifdef __ANDROID__
1252    glDeleteBuffers(count, buffer);
1253 #else
1254 #if defined(__WIN32__)
1255    if(glDeleteBuffersARB)
1256 #endif
1257       glDeleteBuffersARB(count, buffer);
1258 #endif
1259 }
1260
1261 void GLBindBuffer(int target, uint buffer)
1262 {
1263 #ifdef __ANDROID__
1264    glBindBuffer(target, buffer);
1265 #else
1266 #if defined(__WIN32__)
1267    if(glBindBufferARB)
1268 #endif
1269       glBindBufferARB(target, buffer);
1270 #endif
1271    currentVertexBuffer = buffer;
1272 }
1273
1274 public void GLVertexPointer(int numCoords, int glType, int stride, void *ptr, int numVertices)
1275 {
1276 #ifdef _GLES
1277    if(glType == GL_DOUBLE)
1278       glesVertexPointerd(numCoords, stride, ptr, numVertices);
1279    else if(glType == GL_INT)
1280       glesVertexPointeri(numCoords, stride, ptr, numVertices);
1281    else
1282 #endif
1283       glVertexPointer(numCoords, glType, stride, ptr);
1284 }
1285
1286 public void GLBufferData(int type, GLenum target, int size, const GLvoid *data, GLenum usage)
1287 {
1288 #ifdef _GLES
1289    if(type == GL_DOUBLE)
1290       glesBufferDatad(target, size, (void *)data, usage);
1291    else if(type == GL_UNSIGNED_INT)
1292       glesBufferDatai(target, size, (void *)data, usage);
1293    else
1294 #endif
1295
1296 #ifdef __ANDROID__
1297       glBufferData(target, size, data, usage);
1298 #else
1299
1300 #if defined(__WIN32__)
1301    if(glBufferDataARB)
1302 #endif
1303       glBufferDataARB(target, size, data, usage);
1304 #endif
1305 }
1306
1307 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1308 static int primitiveTypes[RenderPrimitiveType] =
1309 {
1310    GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, GL_LINE_STRIP
1311 };
1312 #endif
1313
1314
1315 // Non OpenGL ES friendly stuff
1316
1317 #if defined(_GLES)
1318
1319 //#undef GL_UNSIGNED_INT
1320 //#undef GL_DOUBLE
1321 #undef GL_INT
1322 //#undef GL_POLYGON
1323 //#undef GL_QUADS
1324 #undef GL_QUAD_STRIP
1325 #undef GL_POLYGON_STIPPLE
1326 #undef GL_LINE_STIPPLE
1327 #undef GL_LINE
1328 #undef GL_FILL
1329 #undef GL_ALL_ATTRIB_BITS
1330 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
1331
1332 #endif
1333
1334 static int displayWidth, displayHeight;
1335
1336 #define GL_CLAMP_TO_EDGE 0x812F
1337
1338 static bool vboAvailable;
1339
1340 static bool useSingleGLContext = false;
1341 class OGLDisplay : struct
1342 {
1343 #if defined(__WIN32__)
1344    HDC hdc;
1345    HGLRC glrc;
1346
1347    HBITMAP memBitmap;
1348    HDC memDC;
1349    byte * picture;
1350    uint stride;
1351    void * pBuffer;
1352    /*
1353    int imageBuffers[2];
1354    byte * pboMemory1, * pboMemory2;
1355    */
1356 #elif !defined(__ANDROID__)
1357    GLXContext glContext;
1358
1359    Pixmap pixmap;
1360    XShmSegmentInfo shminfo;
1361    XImage * image;
1362    XShmSegmentInfo shminfoShape;
1363    XImage * shapeImage;
1364    byte * picture;
1365    uint stride;
1366    GLXPbuffer pBuffer;
1367    X11Picture windowPicture;
1368    X11Picture pixmapPicture;
1369    Pixmap shapePixmap;
1370    X11Picture shapePicture;
1371 #endif
1372
1373    ColorAlpha * flippingBuffer;
1374    int flipBufH, flipBufW;
1375    bool depthWrite;
1376    int x, y;
1377 };
1378
1379 class OGLSystem : struct
1380 {
1381    int maxTextureSize;
1382    bool loadingFont;
1383    bool pow2textures;
1384 #if defined(__WIN32__)
1385    PIXELFORMATDESCRIPTOR pfd;
1386    int format;
1387    HDC hdc;
1388    HGLRC glrc;
1389    HWND hwnd;
1390 #elif !defined(__ANDROID__)
1391    XVisualInfo * visualInfo;
1392    GLXContext glContext;
1393    GLXDrawable glxDrawable;
1394 #endif
1395 };
1396
1397 class OGLSurface : struct
1398 {
1399    Font font;
1400    bool opaqueText;
1401    int xOffset;
1402    bool writingText;
1403
1404    float foreground[4], background[4], bitmapMult[4];
1405 } OGLSurface;
1406
1407 class OGLMesh : struct
1408 {
1409    uint vertices;
1410    uint normals;
1411    uint texCoords;
1412    uint texCoords2;
1413    uint colors;
1414 };
1415
1416 class OGLIndices : struct
1417 {
1418    uint16 * indices;
1419    uint buffer;
1420    uint nIndices;
1421 };
1422
1423 int current;
1424 void * previous;
1425
1426 class OpenGLDisplayDriver : DisplayDriver
1427 {
1428    class_property(name) = "OpenGL";
1429
1430    bool LockSystem(DisplaySystem displaySystem)
1431    {
1432 #if !defined(__ANDROID__)
1433       OGLSystem oglSystem = displaySystem.driverData;
1434       if(useSingleGLContext) return true;
1435    #if defined(__WIN32__)
1436       wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1437    #elif defined(__unix__) || defined(__APPLE__)
1438       //if(previous) return true;
1439       // printf("Making SYSTEM current\n");
1440       glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
1441       //previous = oglSystem.glContext;
1442    #endif
1443 #endif
1444       return true;
1445    }
1446
1447    void UnlockSystem(DisplaySystem displaySystem)
1448    {
1449       if(useSingleGLContext) return;
1450    #if defined(__WIN32__)
1451       wglMakeCurrent(null, null);
1452    #elif defined(__unix__) || defined(__APPLE__)
1453       // printf("Making NULL current\n");
1454       #if defined(__ANDROID__)
1455       #else
1456       glXMakeCurrent(xGlobalDisplay, None, null);
1457       #endif
1458       // previous = null;
1459    #endif
1460    }
1461
1462    bool Lock(Display display)
1463    {
1464 #if !defined(__ANDROID__)
1465       OGLDisplay oglDisplay = display.driverData;
1466       if(useSingleGLContext) return true;
1467    #if defined(__WIN32__)
1468       wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1469    #elif defined(__unix__) || defined(__APPLE__)
1470       // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
1471       // printf("   Making DISPLAY current\n");
1472       glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1473    #endif
1474 #endif
1475       return true;
1476    }
1477
1478    void Unlock(Display display)
1479    {
1480       if(useSingleGLContext) return;
1481       //printf("   Making NULL current\n");
1482       //glXMakeCurrent(xGlobalDisplay, None, null);
1483       // if(previous)
1484          LockSystem(display.displaySystem);
1485    }
1486
1487    void DestroyDisplay(Display display)
1488    {
1489       OGLDisplay oglDisplay = display.driverData;
1490
1491       if(oglDisplay)
1492       {
1493    #if defined(__WIN32__)
1494          wglMakeCurrent( null, null );
1495
1496          if(oglDisplay.glrc)
1497             wglDeleteContext(oglDisplay.glrc);
1498
1499          if(oglDisplay.hdc && oglDisplay.pBuffer)
1500             wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1501
1502          if(oglDisplay.pBuffer)
1503             wglDestroyPbufferARB(oglDisplay.pBuffer);
1504
1505          if(oglDisplay.hdc)
1506             ReleaseDC(display.window, oglDisplay.hdc);
1507
1508          if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1509          if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1510
1511    #elif defined(__unix__) || defined(__APPLE__)
1512       #if defined(__ANDROID__)
1513       #else
1514          if(oglDisplay.shapePixmap)
1515             XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1516          if(oglDisplay.pixmap)
1517             XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1518          if(oglDisplay.image)
1519          {
1520             if(oglDisplay.shminfoShape.shmid != -1)
1521             {
1522                XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1523                if(oglDisplay.shminfo.shmaddr != (void *)-1)
1524                   shmdt(oglDisplay.shminfo.shmaddr);
1525                shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1526             }
1527          }
1528          if(oglDisplay.shapeImage)
1529          {
1530             if(oglDisplay.shminfoShape.shmid != -1)
1531             {
1532                XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1533                if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1534                   shmdt(oglDisplay.shminfoShape.shmaddr);
1535                shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1536             }
1537             XDestroyImage(oglDisplay.shapeImage);
1538             oglDisplay.shapeImage = None;
1539          }
1540
1541          glXMakeCurrent(xGlobalDisplay, None, null);
1542
1543          if(oglDisplay.glContext)
1544             glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1545       #endif
1546    #endif
1547          delete oglDisplay.flippingBuffer;
1548          delete oglDisplay;
1549          display.driverData = null;
1550       }
1551    }
1552
1553    void ::CheckExtensions(OGLSystem oglSystem)
1554    {
1555       const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
1556       if(extensions)
1557          oglSystem.pow2textures = strstr(extensions, "GL_ARB_texture_non_power_of_two") ? false : true;
1558       glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
1559    }
1560
1561    bool CreateDisplaySystem(DisplaySystem displaySystem)
1562    {
1563       bool result = false;
1564       OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
1565
1566    #ifdef __WIN32__
1567       oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
1568
1569       oglSystem.hdc = GetDC(oglSystem.hwnd);
1570       if(oglSystem.hdc)
1571       {
1572
1573          oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
1574          oglSystem.pfd.nVersion = 1;
1575          oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
1576          oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
1577          oglSystem.pfd.cColorBits = 24;
1578          oglSystem.pfd.cAlphaBits = 8;
1579          oglSystem.pfd.cDepthBits = 24;
1580          oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
1581
1582          oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
1583          DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1584
1585          if(oglSystem.pfd.cColorBits > 8)
1586          {
1587             SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1588             oglSystem.glrc = wglCreateContext(oglSystem.hdc);
1589             if(oglSystem.glrc)
1590             {
1591                wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1592
1593                  // Get Pointers To The GL Functions
1594                glActiveTextureARB = (void *) wglGetProcAddress("glActiveTextureARB");
1595                glMultiTexCoord2fARB = (void *) wglGetProcAddress("glMultiTexCoord2fARB");
1596                glClientActiveTextureARB = (void *) wglGetProcAddress("glClientActiveTextureARB");
1597                glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
1598                glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
1599                  glGenBuffersARB = (void *) wglGetProcAddress("glGenBuffersARB");
1600                  glBindBufferARB = (void *) wglGetProcAddress("glBindBufferARB");
1601                  glBufferDataARB = (void *) wglGetProcAddress("glBufferDataARB");
1602                glMapBufferARB  = (void *) wglGetProcAddress("glMapBufferARB");
1603                glUnmapBufferARB  = (void *) wglGetProcAddress("glUnmapBufferARB");
1604                  glDeleteBuffersARB = (void *) wglGetProcAddress("glDeleteBuffersARB");
1605                glBlendFuncSeparate = (void *) wglGetProcAddress("glBlendFuncSeparate");
1606
1607                wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
1608                wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
1609                wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
1610                wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
1611                wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
1612                wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
1613                wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
1614                wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
1615                wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
1616
1617                wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
1618
1619                vboAvailable = glBindBufferARB != null;
1620
1621                // eSystem_LoggingMode(LOG_MSGBOX, null);
1622
1623                if(wglChoosePixelFormatARB)
1624                {
1625                     int pixelFormat;
1626                     int valid;
1627                     int numFormats;
1628                     float fAttributes[] = {0,0};
1629                     int iAttributes[] =
1630                   {
1631                      WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
1632                             WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1633                             WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1634                             WGL_COLOR_BITS_ARB,24,
1635                             WGL_ALPHA_BITS_ARB,8,
1636                             WGL_DEPTH_BITS_ARB,16,
1637                             WGL_STENCIL_BITS_ARB,0,
1638                             WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
1639                             WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1640                             WGL_SAMPLES_ARB, 4,                                         // Check For 4x Multisampling
1641                             0,0
1642                   };
1643
1644                   //Log("Found wglChoosePixelFormatARB\n");
1645
1646                     valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1647                     if(!valid || !numFormats)
1648                     {
1649                      //Log("Can't find 4x multi sampling\n");
1650                        iAttributes[19] = 2;
1651                        valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1652                      if(!valid || !numFormats)
1653                      {
1654                         // Log("Can't find 2x multi sampling\n");
1655                         iAttributes[16] = 0;
1656                         iAttributes[17] = 0;
1657                         valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1658                      }
1659                     }
1660                   if(valid && numFormats)
1661                   {
1662                      oglSystem.format = pixelFormat;
1663                      wglMakeCurrent(null, null);
1664                      wglDeleteContext(oglSystem.glrc);
1665
1666                      // *** DescribePixelFormat does not support WGL pixel formats! ***
1667                      //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1668                      SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1669                      //Log("Successfully set pixel format\n");
1670
1671                      oglSystem.glrc = wglCreateContext(oglSystem.hdc);
1672                      wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1673                   }
1674                }
1675                /*else
1676                   eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
1677
1678                result = true;
1679
1680                CheckExtensions(oglSystem);
1681
1682                wglMakeCurrent(null, null);
1683
1684                //eSystem_DumpErrors(true);
1685             }
1686          }
1687       }
1688    #elif defined(__unix__) || defined(__APPLE__)
1689       vboAvailable = true;
1690       #if defined(__ANDROID__)
1691          egl_init_display(guiApp.desktop.windowHandle);
1692          CheckExtensions(oglSystem);
1693          result = true;
1694       #else
1695       {
1696          X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1697          XSetWindowAttributes attr;
1698          unsigned long mask;
1699
1700          int attrList[] =
1701          {
1702       #ifndef ECERE_MINIGLX
1703             GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1704       #endif
1705             GLX_RGBA,
1706             GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1707             GLX_DOUBLEBUFFER,
1708             None
1709          };
1710          oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay,  DefaultScreen( xGlobalDisplay ), attrList );
1711          attr.background_pixel = 0;
1712          attr.border_pixel = 0;
1713          attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1714          attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1715          mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1716
1717          oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1718             oglSystem.visualInfo->visual, mask, &attr );
1719       }
1720       if(oglSystem.visualInfo)
1721       {
1722          oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1723          if(oglSystem.glContext)
1724          {
1725             glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1726             // Setup Extensions
1727             CheckExtensions(oglSystem);
1728             glXMakeCurrent(xGlobalDisplay, None, null);
1729             result = true;
1730          }
1731       }
1732       #endif
1733    #endif
1734
1735       displaySystem.flags.alpha = true;
1736       displaySystem.flags.flipping = true;
1737       displaySystem.pixelFormat = pixelFormat888;
1738       return result;
1739    }
1740
1741    void DestroyDisplaySystem(DisplaySystem displaySystem)
1742    {
1743       OGLSystem oglSystem = displaySystem.driverData;
1744
1745    #if defined(__WIN32__)
1746       wglMakeCurrent( null, null );
1747
1748       if(oglSystem.glrc)
1749          wglDeleteContext(oglSystem.glrc);
1750
1751       if(oglSystem.hdc)
1752          ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1753       DestroyWindow(oglSystem.hwnd);
1754
1755    #elif defined(__unix__) || defined(__APPLE__)
1756       #if defined(__ANDROID__)
1757          egl_term_display();
1758       #else
1759       if(oglSystem.visualInfo)
1760       {
1761    #ifdef   ECERE_MINIGLX
1762          __miniglx_XFree(oglSystem.visualInfo);
1763    #else
1764          XFree(oglSystem.visualInfo);
1765    #endif
1766       }
1767
1768       if(oglSystem.glxDrawable)
1769       {
1770          XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1771          oglSystem.glxDrawable = 0;
1772       }
1773       #endif
1774    #endif
1775       delete oglSystem;
1776    }
1777
1778    bool CreateDisplay(Display display)
1779    {
1780       bool result = false;
1781       OGLDisplay oglDisplay = display.driverData;
1782 #if !defined(__ANDROID__)
1783       OGLSystem oglSystem = display.displaySystem.driverData;
1784 #endif
1785       if(!oglDisplay)
1786          oglDisplay = display.driverData = OGLDisplay { };
1787       //printf("Inside CreateDisplay\n");
1788
1789 #if defined(__WIN32__) || defined(USEPBUFFER)
1790       if(!display.alphaBlend)
1791 #endif
1792       {
1793    #if defined(__WIN32__)
1794          oglDisplay.hdc = GetDC(display.window);
1795          SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1796          if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
1797          {
1798             wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1799             wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1800             result = true;
1801          }
1802          else
1803             ReleaseDC(display.window, oglDisplay.hdc);
1804    #elif defined(__unix__) || defined(__APPLE__)
1805       #if defined(__ANDROID__)
1806       #else
1807          XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1808          /*
1809 #if defined(__APPLE__)
1810          XVisualInfo template = { 0 };
1811          XWindowAttributes winAttr;
1812          int n;
1813          XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1814          template.visualid = XVisualIDFromVisual(winAttr.visual);
1815          visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1816 #ifdef _DEBUG
1817          printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1818          printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1819          printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1820          printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1821 #endif
1822          // visualInfo = oglSystem.visualInfo;
1823 //#endif
1824          */
1825          if(visualInfo)
1826          {
1827             //printf("visualInfo is not null\n");
1828             // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1829             oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1830             //XFree(visualInfo);
1831          }
1832
1833          // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1834          if(oglDisplay.glContext)
1835          {
1836             //printf("CreateDisplay Got a Context\n");
1837             glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1838             result = true;
1839          }
1840       #endif
1841    #endif
1842       }
1843 #if defined(__WIN32__) || defined(USEPBUFFER)
1844       else
1845          result = true;
1846 #endif
1847       if(result)
1848       {
1849 #if defined(__WIN32__)
1850          if(glBlendFuncSeparate)
1851             glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1852          else
1853             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1854 #else
1855 #if !defined(__OLDX__)
1856           glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1857 #else
1858          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1859 #endif
1860 #endif
1861          glEnable(GL_BLEND);
1862
1863          glMatrixMode(GL_MODELVIEW);
1864          glScaled(1.0, 1.0, -1.0);
1865          // glTranslatef(0.375f, 0.375f, 0.0f);
1866          // glTranslatef(-0.625f, -0.625f, 0.0f);
1867          glMatrixMode(GL_PROJECTION);
1868          glShadeModel(GL_FLAT);
1869
1870          // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, true);
1871          glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1872          glFogi(GL_FOG_MODE, GL_EXP);
1873          glFogf(GL_FOG_DENSITY, 0);
1874          glEnable(GL_NORMALIZE);
1875          glDepthFunc(GL_LESS);
1876          glClearDepth(1.0);
1877          glDisable(GL_MULTISAMPLE_ARB);
1878       }
1879 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1880       display.ambient = Color { 50,50,50 };
1881 #endif
1882
1883       if(!useSingleGLContext)
1884       {
1885    #if defined(__WIN32__)
1886          wglMakeCurrent(null, null);
1887    #elif defined(__unix__) || defined(__APPLE__)
1888       #if defined(__ANDROID__)
1889          result = true;
1890       #else
1891          glXMakeCurrent(xGlobalDisplay, None, null);
1892       #endif
1893    #endif
1894       }
1895
1896       return result;
1897    }
1898
1899    bool DisplaySize(Display display, int width, int height)
1900    {
1901       OGLDisplay oglDisplay = display.driverData;
1902
1903       bool result = false;
1904
1905       //printf("Inside DisplaySize\n");
1906 #if defined(__WIN32__) || defined(USEPBUFFER)
1907       OGLSystem oglSystem = display.displaySystem.driverData;
1908       if(display.alphaBlend)
1909       {
1910 #if defined(__WIN32__)
1911          const int attributes[]=
1912          {
1913             /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1914             WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1915          };
1916          int pixelFormat = 0;
1917          if(wglChoosePixelFormatARB)
1918          {
1919             int valid;
1920             int numFormats;
1921             float fAttributes[] = {0,0};
1922             int iAttributes[] =
1923             {
1924                //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1925                WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1926                     WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1927                     WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1928                     WGL_COLOR_BITS_ARB,24,
1929                     WGL_ALPHA_BITS_ARB,8,
1930                     WGL_DEPTH_BITS_ARB,16,
1931                     WGL_STENCIL_BITS_ARB,0,
1932                     WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1933                     WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1934                     WGL_SAMPLES_ARB, 4,                                         // Check For 4x Multisampling
1935                     0,0
1936             };
1937
1938             //Log("Found wglChoosePixelFormatARB\n");
1939
1940             valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1941             if(!valid || !numFormats)
1942             {
1943                //Log("Can't find 4x multi sampling\n");
1944                iAttributes[19] = 2;
1945                valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1946                if(!valid || !numFormats)
1947                {
1948                   // Log("Can't find 2x multi sampling\n");
1949                   iAttributes[16] = 0;
1950                   iAttributes[17] = 0;
1951                   valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1952                   if(!valid || !numFormats)
1953                   {
1954                      int iAttributes[] =
1955                      {
1956                         WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1957                         //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1958                         WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1959                         WGL_COLOR_BITS_ARB,24,
1960                         WGL_ALPHA_BITS_ARB,8,
1961                         WGL_DEPTH_BITS_ARB,16,
1962                         0,0
1963                      };
1964                      valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1965                   }
1966                }
1967             }
1968             if(valid && numFormats)
1969             {
1970                wglMakeCurrent(null, null);
1971             }
1972          }
1973
1974          wglMakeCurrent( null, null );
1975          wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1976          if(oglDisplay.hdc && oglDisplay.pBuffer)
1977             wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1978
1979          wglDestroyPbufferARB(oglDisplay.pBuffer);
1980
1981          if(!useSingleGLContext)
1982             wglMakeCurrent( null, null );
1983
1984          if(oglDisplay.glrc)
1985             wglDeleteContext(oglDisplay.glrc);
1986
1987          oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1988          oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1989          if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
1990          {
1991             BITMAPINFO * info;
1992             HDC hdc = GetDC(display.window);
1993
1994             wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1995             wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1996
1997             //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1998             //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1999
2000             // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
2001
2002             if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
2003             {
2004                HBITMAP newBitmap;
2005
2006                if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
2007                oglDisplay.memDC = CreateCompatibleDC(hdc);
2008                SetMapMode(oglDisplay.memDC, MM_TEXT);
2009                info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2010                info->bmiHeader.biPlanes = 1;
2011                info->bmiHeader.biCompression = BI_RGB;
2012                info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
2013                info->bmiHeader.biWidth = width;
2014                info->bmiHeader.biHeight = height;
2015                newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
2016                if(newBitmap)
2017                {
2018                   SelectObject(oglDisplay.memDC, newBitmap);
2019                   if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
2020                   /*
2021                   {
2022                      PIXELFORMATDESCRIPTOR pfd = { 0 };
2023                      pfd.nSize = (short)sizeof(pfd);
2024                      pfd.nVersion = 1;
2025                      pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
2026                      pfd.iPixelType = PFD_TYPE_RGBA;
2027                      pfd.cColorBits = 32;
2028                      //pfd.cAlphaBits = 8;
2029                      pfd.cDepthBits = 24;
2030                      pfd.iLayerType = PFD_MAIN_PLANE;
2031
2032                      oglDisplay.hdc = oglDisplay.memDC;
2033
2034                      pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
2035                      DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
2036                      SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
2037
2038                      oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
2039                      wglShareLists(oglSystem.glrc, oglDisplay.glrc);
2040                      wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
2041                   }
2042                   */
2043                   /*
2044                   {
2045                      const int imageSize = width * height * 4;
2046
2047                      glGenBuffersARB(2, oglDisplay.imageBuffers);
2048
2049                      glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2050                      glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
2051                      // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2052                      // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
2053                   }
2054                   */
2055                   oglDisplay.memBitmap = newBitmap;
2056                   oglDisplay.stride = width;
2057
2058                   result = true;
2059                }
2060                delete info;
2061             }
2062             ReleaseDC(display.window, hdc);
2063          }
2064 #elif defined(__unix__) || defined(__APPLE__)
2065       #if defined(__ANDROID__)
2066          result = true;
2067       #else
2068         int attrib[] =
2069         {
2070                 GLX_DOUBLEBUFFER,  True,
2071             GLX_DEPTH_SIZE,    1,
2072                 GLX_RED_SIZE,      8,
2073                 GLX_GREEN_SIZE,    8,
2074                 GLX_BLUE_SIZE,     8,
2075                 GLX_ALPHA_SIZE,    8,
2076                 GLX_STENCIL_SIZE,  1,
2077                 //GLX_DEPTH_SIZE,    24,
2078                 GLX_RENDER_TYPE,   GLX_RGBA_BIT,
2079                 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
2080                 None
2081         };
2082
2083         int PBattrib[] =
2084         {
2085                 GLX_PBUFFER_WIDTH,   width,
2086                 GLX_PBUFFER_HEIGHT,  height,
2087                 GLX_LARGEST_PBUFFER, False,
2088             None
2089         };
2090
2091         // choose a pixel format that meets our minimum requirements
2092         int count = 0;
2093
2094         GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
2095          if(config)
2096          {
2097             if(oglDisplay.pixmap)
2098             {
2099                XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
2100                oglDisplay.pixmap = None;
2101             }
2102             if(oglDisplay.shapePixmap)
2103             {
2104                XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
2105                oglDisplay.shapePixmap = None;
2106             }
2107
2108             // Free Shared Memory Pixmap
2109             if(oglDisplay.image)
2110             {
2111                if(oglDisplay.shminfoShape.shmid != -1)
2112                {
2113                   XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
2114                   if(oglDisplay.shminfo.shmaddr != (void *)-1)
2115                      shmdt(oglDisplay.shminfo.shmaddr);
2116                   shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
2117                }
2118                XDestroyImage(oglDisplay.image);
2119                oglDisplay.image = None;
2120             }
2121             if(oglDisplay.shapeImage)
2122             {
2123                if(oglDisplay.shminfoShape.shmid != -1)
2124                {
2125                   XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
2126                   if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
2127                      shmdt(oglDisplay.shminfoShape.shmaddr);
2128                   shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
2129                }
2130                XDestroyImage(oglDisplay.shapeImage);
2131                oglDisplay.shapeImage = None;
2132             }
2133
2134             if(oglDisplay.windowPicture)
2135                XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
2136             if(oglDisplay.pixmapPicture)
2137                XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
2138
2139             if(oglDisplay.pixmap)
2140                XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
2141
2142             if(oglDisplay.glContext)
2143                   glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
2144             if(oglDisplay.pBuffer)
2145                glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
2146
2147                 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
2148             if(oglDisplay.pBuffer)
2149             {
2150                    oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
2151                if(oglDisplay.glContext)
2152                {
2153                   glXMakeCurrent(xGlobalDisplay, None, null);
2154                   glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
2155
2156                   // Initialize Shared Memory Pixmap
2157                   oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
2158                      ZPixmap, null, &oglDisplay.shminfo, width, height);
2159                   if(oglDisplay.image)
2160                   {
2161                      oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
2162                         oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
2163                      if(oglDisplay.shminfo.shmid != -1)
2164                      {
2165                         oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
2166                         if(oglDisplay.shminfo.shmaddr != (void *)-1)
2167                         {
2168                            oglDisplay.shminfo.readOnly = False;
2169                            if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
2170                            {
2171                               oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
2172                                  &oglDisplay.shminfo, width, height, 32);
2173
2174                               // Initialize Shared Memory Shape Pixmap
2175                               oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
2176                                  ZPixmap, null, &oglDisplay.shminfoShape, width, height);
2177                               if(oglDisplay.shapeImage)
2178                               {
2179                                  oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
2180                                     oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
2181                                  if(oglDisplay.shminfoShape.shmid != -1)
2182                                  {
2183                                     oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
2184                                     if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
2185                                     {
2186                                        oglDisplay.shminfoShape.readOnly = False;
2187                                        if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
2188                                        {
2189                                           oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
2190                                              &oglDisplay.shminfoShape, width, height, 1);
2191                                           //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
2192
2193                                           {
2194                                              XRenderPictureAttributes attributes = { 0 };
2195                                              XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
2196                                              #if !defined(__APPLE__) && !defined(__OLDX__)
2197                                              attributes.repeat = RepeatNormal;
2198                                              #else
2199                                              attributes.repeat = 1;
2200                                              #endif
2201                                              oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
2202                                              oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
2203                                              oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
2204                                                 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
2205                                           }
2206
2207                                           oglDisplay.picture = oglDisplay.shminfo.shmaddr;
2208                                           oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
2209
2210                                           result = true;
2211                                        }
2212                                     }
2213                                  }
2214                               }
2215                            }
2216                         }
2217                      }
2218                   }
2219                }
2220             }
2221             XFree(config);
2222          }
2223      #endif
2224 #endif
2225          CreateDisplay(display);
2226 #if defined(__WIN32__)
2227          wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
2228 #elif defined(__unix__) || defined(__APPLE__)
2229       #if defined(__ANDROID__)
2230          width = eglWidth;
2231          height = eglHeight;
2232       #else
2233          glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
2234       #endif
2235 #endif
2236       }
2237       else
2238 #endif
2239          result = true;
2240       if(!result && display.alphaBlend)
2241       {
2242          printf("Alpha blending windows not supported on this display\n");
2243       }
2244       if(!result)
2245          return false;
2246
2247       result = false;
2248
2249       glViewport(0,0,width,height);
2250       glLoadIdentity();
2251       glOrtho(0,width,height,0,0.0,1.0);
2252       displayWidth = display.width = width;
2253       displayHeight = display.height = height;
2254
2255       if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
2256       {
2257          oglDisplay.flipBufW = width;
2258          oglDisplay.flipBufH = height;
2259 #ifdef _GLES
2260          result = true;
2261 #else
2262          oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
2263 #endif
2264       }
2265       if(oglDisplay.flippingBuffer || !width || !height)
2266          result = true;
2267
2268       return result;
2269    }
2270
2271    void DisplayPosition(Display display, int x, int y)
2272    {
2273       OGLDisplay oglDisplay = display.driverData;
2274
2275       oglDisplay.x = x;
2276       oglDisplay.y = y;
2277    }
2278
2279    void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
2280    {
2281    }
2282
2283    void RestorePalette(Display display)
2284    {
2285    }
2286
2287    void StartUpdate(Display display)
2288    {
2289    }
2290
2291    void EndUpdate(Display display)
2292    {
2293    }
2294
2295    void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
2296    {
2297    }
2298
2299    void Update(Display display, Box updateBox)
2300    {
2301 #if defined(__WIN32__) || defined(USEPBUFFER)
2302       OGLDisplay oglDisplay = display.driverData;
2303 #endif
2304       //Logf("DisplayScreen\n");
2305
2306       glFlush();
2307       glFinish();
2308 #if defined(__WIN32__) || defined(USEPBUFFER)
2309       if(display.alphaBlend)
2310       {
2311          glPixelStorei(GL_PACK_ALIGNMENT, 4);
2312          glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
2313          glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2314          glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2315          glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
2316
2317          {
2318 #if defined(__WIN32__)
2319             HDC hdc = GetDC(0);
2320             POINT point = { oglDisplay.x, oglDisplay.y};
2321             POINT srcPoint = { 0, 0 };
2322             BLENDFUNCTION blend = { 0 };
2323             SIZE size;
2324             size.cx = display.width;
2325             size.cy = display.height;
2326             blend.BlendOp = AC_SRC_OVER;
2327             blend.BlendFlags = 0;
2328             blend.SourceConstantAlpha = 255;
2329             blend.AlphaFormat = AC_SRC_ALPHA;
2330
2331             /*
2332             // Process partial images.  Mapping the buffer waits for
2333             // outstanding DMA transfers into the buffer to finish.
2334             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2335             oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
2336
2337             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2338             // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
2339
2340
2341             memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
2342             //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
2343             */
2344
2345             UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
2346             /*
2347
2348             // Unmap the image buffers
2349             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2350             glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
2351
2352             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2353             // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
2354
2355             // Bind two different buffer objects and start the glReadPixels
2356             // asynchronously. Each call will return directly after
2357             // starting the DMA transfer.
2358             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2359             glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
2360
2361             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2362             // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
2363             */
2364
2365             ReleaseDC(0, hdc);
2366 #elif defined(__unix__) || defined(__APPLE__)
2367       #if defined(__ANDROID__)
2368       #else
2369             XTransform transform =
2370             {
2371                {
2372                   { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)),  (int)(0 * (1 << 16)) },
2373                   { (int)(0.0f),           (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
2374                   { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)),  (int)(1.0f * (1<<16)) }
2375                }
2376             };
2377             XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
2378             XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
2379             XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
2380             #if !defined(__APPLE__) && !defined(__OLDX__)
2381             XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
2382             #else
2383             XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
2384             #endif
2385             XFlush(xGlobalDisplay);
2386      #endif
2387 #endif
2388          }
2389       }
2390       else
2391 #endif
2392       {
2393 #if defined(__WIN32__)
2394          //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
2395          SwapBuffers(oglDisplay.hdc);
2396 #elif defined(__unix__) || defined(__APPLE__)
2397       #if defined(__ANDROID__)
2398          eglSwapBuffers(eglDisplay, eglSurface);
2399       #else
2400          glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
2401       #endif
2402 #endif
2403       }
2404       //Logf("Out of DisplayScreen\n");
2405    }
2406
2407    void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
2408    {
2409       if(bitmap.driverData)
2410       {
2411          GLuint tex = (GLuint)(uintptr)bitmap.driverData;
2412          glDeleteTextures(1, &tex);
2413          bitmap.driverData = 0;
2414       }
2415       bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
2416    }
2417
2418    bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
2419    {
2420       OGLSystem oglSystem = displaySystem.driverData;
2421       bool result = false;
2422       Bitmap mipMap { };
2423       GLuint glBitmap = 0;
2424
2425       uint w = width, h = height;
2426       if(oglSystem.pow2textures)
2427       {
2428          w = pow2i(w);
2429          h = pow2i(h);
2430       }
2431       w = Min(w, oglSystem.maxTextureSize);
2432       h = Min(h, oglSystem.maxTextureSize);
2433
2434       glGenTextures(1, &glBitmap);
2435       glBindTexture(GL_TEXTURE_2D, glBitmap);
2436
2437       glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2438
2439       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2440       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2441
2442       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2443       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2444
2445       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2446
2447       mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
2448
2449       // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2450       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2451
2452       delete mipMap;
2453
2454       bitmap.driverData = (void *)(uintptr)glBitmap;
2455       bitmap.driver = displaySystem.driver;
2456       bitmap.width = w;
2457       bitmap.height = h;
2458
2459       result = true;
2460       return result;
2461    }
2462
2463    bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
2464    {
2465       bool result = false;
2466       OGLSystem oglSystem = displaySystem.driverData;
2467
2468       // Pre process the bitmap... First make it 32 bit
2469       if(/*bitmap.pixelFormat == pixelFormatRGBA || */bitmap.Convert(null, pixelFormat888, null))
2470       {
2471          int c, level;
2472          uint w = bitmap.width, h = bitmap.height;
2473          GLuint glBitmap = 0;
2474          if(oglSystem.pow2textures)
2475          {
2476             w = pow2i(w);
2477             h = pow2i(h);
2478          }
2479          w = Min(w, oglSystem.maxTextureSize);
2480          h = Min(h, oglSystem.maxTextureSize);
2481
2482          if(mipMaps)
2483          {
2484             while(w * 2 < h) w *= 2;
2485             while(h * 2 < w) h *= 2;
2486          }
2487
2488          // Switch ARGB to RGBA
2489          //if(bitmap.format != pixelFormatRGBA)
2490          {
2491             for(c=0; c<bitmap.size; c++)
2492             {
2493                // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
2494                // TODO:
2495                ColorAlpha color = ((ColorAlpha *)bitmap.picture)[c];
2496                ((ColorRGBA *)bitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
2497             }
2498          }
2499          bitmap.pixelFormat = pixelFormat888;
2500
2501          glGetError();
2502          glGenTextures(1, &glBitmap);
2503          if(glBitmap == 0)
2504          {
2505             //int error = glGetError();
2506             return false;
2507          }
2508
2509          glBindTexture(GL_TEXTURE_2D, glBitmap);
2510          glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2511
2512          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
2513          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2514
2515          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2516
2517          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
2518          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
2519
2520          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2521          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2522
2523          glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2524
2525          result = true;
2526
2527          for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
2528          {
2529             Bitmap mipMap;
2530             if(!w) w = 1;
2531             if(!h) h = 1;
2532             if(bitmap.width != w || bitmap.height != h)
2533             {
2534                mipMap = Bitmap { };
2535                if(mipMap.Allocate(null, w, h, w, bitmap.pixelFormat, false))
2536                {
2537                   Surface mipSurface = mipMap.GetSurface(0,0,null);
2538                   mipSurface.Filter(bitmap, 0,0,0,0, w, h, bitmap.width, bitmap.height);
2539                   delete mipSurface;
2540                }
2541                else
2542                {
2543                   result = false;
2544                   delete mipMap;
2545                }
2546             }
2547             else
2548                mipMap = bitmap;
2549
2550             if(result)
2551             {
2552                int error;
2553                //int width = 0;
2554                glGetError();
2555                // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2556                glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2557                //printf("Calling glTexImage2D\n");
2558                //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2559                //printf("width = %d (Should be %d, %d)\n", width, w, h);
2560                if((error = glGetError()))
2561                {
2562                   //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2563                   //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2564                   result = false;
2565                }
2566             }
2567             if(mipMap != bitmap)
2568                delete mipMap;
2569             if(!mipMaps) break;
2570          }
2571
2572          if(!bitmap.keepData)
2573             bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
2574          bitmap.driverData = (void *)(uintptr)glBitmap;
2575          bitmap.driver = displaySystem.driver;
2576
2577          if(!result)
2578             FreeBitmap(displaySystem, bitmap);
2579          else if(oglSystem.loadingFont)
2580          {
2581             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2582             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2583             oglSystem.loadingFont = false;
2584          }
2585       }
2586       return result;
2587    }
2588
2589    void ReleaseSurface(Display display, Surface surface)
2590    {
2591       glDisable(GL_SCISSOR_TEST);
2592       delete surface.driverData;
2593       surface.driverData = null;
2594    }
2595
2596    bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2597    {
2598       return false;
2599    }
2600
2601    bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2602    {
2603       bool result = false;
2604       OGLSurface oglSurface = surface.driverData = OGLSurface { };
2605
2606       //Logf("GetSurface\n");
2607
2608       if(oglSurface)
2609       {
2610          if(displayWidth != display.width || displayHeight != display.height)
2611          {
2612             displayWidth = display.width;
2613             displayHeight = display.height;
2614
2615             glViewport(0,0,display.width,display.height);
2616             glLoadIdentity();
2617             glOrtho(0,display.width,display.height,0,0.0,1.0);
2618          }
2619
2620          surface.offset.x = x;
2621          surface.offset.y = y;
2622          surface.unclippedBox = surface.box = clip;
2623          oglSurface.bitmapMult[0] = 1;
2624          oglSurface.bitmapMult[1] = 1;
2625          oglSurface.bitmapMult[2] = 1;
2626          oglSurface.bitmapMult[3] = 1;
2627
2628          glEnable(GL_SCISSOR_TEST);
2629          glScissor(
2630             x+clip.left,
2631             (display.height) -(y+clip.bottom)-1,
2632             clip.right-clip.left+1,
2633             clip.bottom-clip.top+1);
2634          result = true;
2635       }
2636       return result;
2637    }
2638
2639    void Clip(Display display, Surface surface, Box clip)
2640    {
2641       Box box;
2642
2643       //Logf("Clip\n");
2644
2645       if(clip != null)
2646       {
2647          box = clip;
2648          box.Clip(surface.unclippedBox);
2649          surface.box = box;
2650       }
2651       else
2652          box = surface.box = surface.unclippedBox;
2653       box.left += surface.offset.x;
2654       box.top  += surface.offset.y;
2655       box.right+= surface.offset.x;
2656       box.bottom += surface.offset.y;
2657
2658       glScissor(
2659          box.left,display.height - box.bottom - 1,
2660          box.right-box.left+1, box.bottom-box.top+1);
2661    }
2662
2663    bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2664    {
2665       bool result = false;
2666       OGLDisplay oglDisplay = display.driverData;
2667       ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2668
2669       if(oglDisplay.flippingBuffer)
2670       {
2671          if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2672          {
2673             bitmap.Free();
2674             bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2675          }
2676          if(bitmap)
2677          {
2678             uint row;
2679
2680             glPixelStorei(GL_PACK_ALIGNMENT, 4);
2681             glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2682             glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2683             glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2684             glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2685
2686             // Need a flip...
2687             for(row = 0; row<h; row++)
2688                CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2689             result = true;
2690          }
2691       }
2692       return result;
2693    }
2694
2695    void SetForeground(Display display, Surface surface, ColorAlpha color)
2696    {
2697       OGLSurface oglSurface = surface.driverData;
2698
2699       //Logf("SetForeground\n");
2700
2701       oglSurface.foreground[0] = color.color.r/255.0f;
2702       oglSurface.foreground[1] = color.color.g/255.0f;
2703       oglSurface.foreground[2] = color.color.b/255.0f;
2704       //oglSurface.foreground[3] = 1.0f;
2705       oglSurface.foreground[3] = color.a/255.0f;
2706
2707       //if(!oglSurface.foreground[3])printf("bug");
2708    }
2709
2710    void SetBackground(Display display, Surface surface, ColorAlpha color)
2711    {
2712       OGLSurface oglSurface = surface.driverData;
2713
2714       //Logf("SetBackground\n");
2715
2716       oglSurface.background[0] = color.color.r/255.0f;
2717       oglSurface.background[1] = color.color.g/255.0f;
2718       oglSurface.background[2] = color.color.b/255.0f;
2719       //oglSurface.background[3] = 1.0;
2720       oglSurface.background[3] = color.a/255.0f;
2721    }
2722
2723    void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2724    {
2725       OGLSurface oglSurface = surface.driverData;
2726
2727       oglSurface.bitmapMult[0] = color.color.r/255.0f;
2728       oglSurface.bitmapMult[1] = color.color.g/255.0f;
2729       oglSurface.bitmapMult[2] = color.color.b/255.0f;
2730       oglSurface.bitmapMult[3] = color.a/255.0f;
2731    }
2732
2733    ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2734    {
2735       return 0;
2736    }
2737
2738    void PutPixel(Display display, Surface surface,int x,int y)
2739    {
2740       OGLSurface oglSurface = surface.driverData;
2741
2742       //Logf("PutPixel\n");
2743
2744       glColor4fv(oglSurface.foreground);
2745       glBegin(GL_POINTS);
2746       // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2747       glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2748
2749       glEnd();
2750    }
2751
2752    void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2753    {
2754       OGLSurface oglSurface = surface.driverData;
2755       float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2756       if(_x1 == _x2)
2757       {
2758          if(_y2 >= _y1)
2759             y2 += 1;
2760          else
2761             y1 += 1;
2762       }
2763       else if(_y1 == _y2)
2764       {
2765          if(_x2 >= _x1)
2766             x2 += 1;
2767          else
2768             x1 += 1;
2769       }
2770       x1 += surface.offset.x;
2771       y1 += surface.offset.y;
2772       x2 += surface.offset.x;
2773       y2 += surface.offset.y;
2774
2775       //Logf("Line\n");
2776
2777       glColor4fv(oglSurface.foreground);
2778       glBegin(GL_LINES);
2779 #ifdef _GLES
2780       if(stippleEnabled)
2781       {
2782          glTexCoord2f(0.5f, 0);
2783          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2784          glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2785          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2786       }
2787       else
2788 #endif
2789       {
2790          /*
2791          glVertex2i(x1, y1);
2792          glVertex2i(x2, y2);
2793          */
2794          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2795          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2796       }
2797
2798       glEnd();
2799    }
2800
2801    void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2802    {
2803       OGLSurface oglSurface = surface.driverData;
2804       x1 += surface.offset.x;
2805       y1 += surface.offset.y;
2806       x2 += surface.offset.x;
2807       y2 += surface.offset.y;
2808
2809       //Logf("Rectangle\n");
2810
2811       glColor4fv(oglSurface.foreground);
2812 #ifdef _GLES
2813       if(stippleEnabled)
2814       {
2815          glBegin(GL_LINES);
2816
2817          glTexCoord2f(0.5f, 0);
2818          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2819          glTexCoord2f(y2-y1 + 0.5f, 0);
2820          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2821
2822          glTexCoord2f(0.5f, 0);
2823          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2824          glTexCoord2f(x2 - x1 + 0.5f, 0);
2825          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2826
2827          glTexCoord2f(0.5f, 0);
2828          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2829          glTexCoord2f(y1 - y2 + 0.5f, 0);
2830          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2831
2832          glTexCoord2f(0.5f, 0);
2833          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2834          glTexCoord2f(x1 - x2 + 0.5f, 0);
2835          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2836       }
2837       else
2838 #endif
2839       {
2840          glBegin(GL_LINE_LOOP);
2841          /*
2842          glVertex2i(x1, y1);
2843          glVertex2i(x1, y2);
2844          glVertex2i(x2, y2);
2845          glVertex2i(x2, y1);
2846          */
2847          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2848          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2849          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2850          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2851       }
2852       glEnd();
2853    }
2854
2855    void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2856    {
2857       OGLSurface oglSurface = surface.driverData;
2858       //Logf("Area\n");
2859
2860       glColor4fv(oglSurface.background);
2861       glRecti(x1+surface.offset.x, y1+surface.offset.y,
2862               x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2863
2864       /*
2865       glRectf(x1+surface.offset.x, y1+surface.offset.y,
2866               x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2867       */
2868    }
2869
2870    void Clear(Display display, Surface surface, ClearType type)
2871    {
2872       OGLDisplay oglDisplay = display.driverData;
2873       OGLSurface oglSurface = surface.driverData;
2874
2875       //Logf("Clear\n");
2876       if(type != depthBuffer)
2877          glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2878       if(type != colorBuffer && !oglDisplay.depthWrite)
2879       {
2880          glDepthMask((byte)bool::true);
2881       }
2882       glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2883               ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2884       if(type != colorBuffer && !oglDisplay.depthWrite)
2885       {
2886          glDepthMask((byte)bool::false);
2887       }
2888    }
2889
2890    bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2891    {
2892       return true;
2893    }
2894
2895    void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2896    {
2897       OGLSurface oglSurface = surface.driverData;
2898
2899 #if !defined(__OLDX__)
2900          // WHY DO WE HAVE GL_ONE HERE ?
2901          /*if(glBlendFuncSeparate && !oglSurface.writingText)
2902             glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2903 #endif
2904
2905       if(!oglSurface.writingText)
2906       {
2907          // glTranslatef(-0.375f, -0.375f, 0.0f);
2908          glEnable(GL_TEXTURE_2D);
2909          glColor4fv(oglSurface.bitmapMult);
2910       }
2911       else if(oglSurface.xOffset)
2912          glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2913
2914       glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2915       glBegin(GL_QUADS);
2916
2917       if(h < 0)
2918       {
2919          glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2920          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2921          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2922          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2923          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2924          glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2925          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2926          glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2927       }
2928       else
2929       {
2930          /*
2931          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2932          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2933          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2934          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2935          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2936          glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2937          glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2938          glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2939          */
2940
2941          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2942          glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2943          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2944          glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2945          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2946          glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2947          glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2948          glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2949       }
2950       glEnd();
2951
2952       if(!oglSurface.writingText)
2953       {
2954          glDisable(GL_TEXTURE_2D);
2955
2956          //glTranslate(0.375, 0.375, 0.0);
2957       }
2958       else if(oglSurface.xOffset)
2959          glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2960
2961 #if !defined(__OLDX__)
2962          /*if(glBlendFuncSeparate && !oglSurface.writingText)
2963             glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2964 #endif
2965    }
2966
2967    void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2968    {
2969       OGLSurface oglSurface = surface.driverData;
2970
2971       //glTranslate(-0.375, -0.375, 0.0);
2972
2973       //Logf("Stretch\n");
2974
2975 #if !defined(__OLDX__)
2976       /*if(glBlendFuncSeparate)
2977          glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2978 #endif
2979
2980       glEnable(GL_TEXTURE_2D);
2981       glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2982
2983       glColor4fv(oglSurface.bitmapMult);
2984
2985       glBegin(GL_QUADS);
2986
2987       if(h < 0)
2988       {
2989          glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2990          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2991
2992          glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2993          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2994
2995          glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2996          glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2997
2998          glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2999          glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
3000       }
3001       else
3002       {
3003          glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
3004          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
3005
3006          glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
3007          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
3008
3009          glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
3010          glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
3011
3012          glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
3013          glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
3014       }
3015
3016       glEnd();
3017
3018       glDisable(GL_TEXTURE_2D);
3019
3020       //glTranslate(0.375, 0.375, 0.0);
3021 #if !defined(__OLDX__)
3022       /*if(glBlendFuncSeparate)
3023          glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
3024 #endif
3025
3026    }
3027
3028    void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3029    {
3030       Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
3031    }
3032
3033    void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3034    {
3035       float s2dw,s2dh,d2sw,d2sh;
3036       //bool flipX = false, flipY = false;
3037
3038       //Logf("StretchDI\n");
3039
3040       if(Sgn(w) != Sgn(sw))
3041       {
3042          w = Abs(w);
3043          sw = Abs(sw);
3044          //flipX = true;
3045       }
3046       if(Sgn(h) != Sgn(sh))
3047       {
3048          h = Abs(h);
3049          sh = Abs(sh);
3050          //flipY = true;
3051       }
3052
3053       s2dw=(float)w / sw;
3054       s2dh=(float)h / sh;
3055       d2sw=(float)sw / w;
3056       d2sh=(float)sh / h;
3057
3058       //Clip against the edges of the source
3059       if(sx<0)
3060       {
3061          dx+=(int)((0-sx) * s2dw);
3062          w-=(int)((0-sx) * s2dw);
3063          sw-=0-sx;
3064          sx=0;
3065       }
3066       if(sy<0)
3067       {
3068          dy+=(int)((0-sy) * s2dh);
3069          h-=(int)((0-sy) * s2dh);
3070
3071          sh-=0-sy;
3072          sy=0;
3073       }
3074       if(sx+sw>bitmap.width-1)
3075       {
3076          w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
3077          sw-=sx+sw-(bitmap.width-1)-1;
3078       }
3079       if(sy+sh>(bitmap.height-1))
3080       {
3081          h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
3082          sh-=sy+sh-(bitmap.height-1)-1;
3083       }
3084       //Clip against the edges of the surfaceination
3085       if(dx<surface.box.left)
3086       {
3087          //if(!flip)
3088          sx+=(int)((surface.box.left-dx)*d2sw);
3089          sw-=(int)((surface.box.left-dx)*d2sw);
3090          w-=surface.box.left-dx;
3091          dx=surface.box.left;
3092       }
3093       if(dy<surface.box.top)
3094       {
3095          sy+=(int)((surface.box.top-dy)*d2sh);
3096          sh-=(int)((surface.box.top-dy)*d2sh);
3097          h-=surface.box.top-dy;
3098          dy=surface.box.top;
3099       }
3100       if(dx+w>surface.box.right)
3101       {
3102          //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
3103          sw-=(int)((dx+w-surface.box.right-1)*d2sw);
3104          w-=dx+w-surface.box.right-1;
3105       }
3106       if(dy+h>surface.box.bottom)
3107       {
3108          sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
3109          h-=dy+h-surface.box.bottom-1;
3110       }
3111       if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
3112
3113       dx += surface.offset.x;
3114       dy += surface.offset.y;
3115
3116       if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
3117       {
3118          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3119          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
3120          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
3121          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
3122          glRasterPos2d(dx,dy);
3123          //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
3124          glPixelZoom(s2dw, -s2dh);
3125          glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
3126          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3127          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3128          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3129          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3130       }
3131    }
3132
3133    void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
3134    {
3135       //Logf("BlitDI\n");
3136
3137       //Clip against the edges of the source
3138       if(sx<0)
3139       {
3140          dx+=-sx;
3141          w-=-sx;
3142          sx=0;
3143       }
3144       if(sy<0)
3145       {
3146          dy+=0-sy;
3147          h-=0-sy;
3148          sy=0;
3149       }
3150       if(sx+w>bitmap.width-1)
3151          w-=sx+w-(bitmap.width-1)-1;
3152       if(sy+h>bitmap.height-1)
3153          h-=sy+h-(bitmap.height-1)-1;
3154       //Clip against the edges of the surfaceination
3155       if(dx<surface.box.left)
3156       {
3157          //if(!flip)
3158          sx+=surface.box.left-dx;
3159          w-=surface.box.left-dx;
3160          dx=surface.box.left;
3161       }
3162       if(dy<surface.box.top)
3163       {
3164          sy+=surface.box.top-dy;
3165          h-=surface.box.top-dy;
3166          dy=surface.box.top;
3167       }
3168       if(dx+w>surface.box.right)
3169       {
3170          //if(flip) sx+=dx+w-surface.box.right-1;
3171          w-=dx+w-surface.box.right-1;
3172       }
3173       if(dy+h>surface.box.bottom)
3174          h-=dy+h-surface.box.bottom-1;
3175       if((w<=0)||(h<=0))
3176          return;
3177
3178       dx += surface.offset.x;
3179       dy += surface.offset.y;
3180
3181       if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
3182       {
3183          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3184          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
3185          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
3186          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
3187          glRasterPos2d(dx,dy);
3188          glPixelZoom(1,-1);
3189          glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
3190          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3191          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3192          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3193          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3194       }
3195    }
3196
3197    void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3198    {
3199       StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
3200    }
3201
3202    void UnloadFont(DisplaySystem displaySystem, Font font)
3203    {
3204       ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
3205    }
3206
3207    Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
3208    {
3209       Font font;
3210       OGLSystem oglSystem = displaySystem.driverData;
3211       oglSystem.loadingFont = true;
3212       font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
3213       return font;
3214    }
3215
3216    void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
3217    {
3218       ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
3219    }
3220
3221    void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
3222    {
3223       OGLSurface oglSurface = surface.driverData;
3224       OGLSystem oglSystem = display.displaySystem.driverData;
3225       oglSystem.loadingFont = true;
3226
3227       //glTranslated(-0.375, -0.375, 0.0);
3228
3229       //Logf("Blit\n");
3230
3231       if(surface.textOpacity)
3232       {
3233          int w, h;
3234          FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
3235          display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
3236       }
3237
3238       oglSurface.writingText = true;
3239
3240       glEnable(GL_TEXTURE_2D);
3241       glColor4fv(oglSurface.foreground);
3242
3243       ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
3244       oglSurface.writingText = false;
3245       oglSystem.loadingFont = false;
3246
3247       glDisable(GL_TEXTURE_2D);
3248
3249       //glTranslated(0.375, 0.375, 0.0);
3250    }
3251
3252    void TextFont(Display display, Surface surface, Font font)
3253    {
3254       ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
3255    }
3256
3257    void TextOpacity(Display display, Surface surface, bool opaque)
3258    {
3259       OGLSurface oglSurface = surface.driverData;
3260       oglSurface.opaqueText = opaque;
3261    }
3262
3263    void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
3264    {
3265       OGLSurface oglSurface = surface.driverData;
3266       OGLSystem oglSystem = display.displaySystem.driverData;
3267       oglSystem.loadingFont = true;
3268       FontExtent(display.displaySystem, oglSurface.font, text, len, width, height);
3269       oglSystem.loadingFont = false;
3270    }
3271
3272    void DrawingChar(Display display, Surface surface, char character)
3273    {
3274
3275    }
3276
3277    void LineStipple(Display display, Surface surface, uint32 stipple)
3278    {
3279       //Logf("Stipple\n");
3280
3281       if(stipple)
3282       {
3283 #if defined(_GLES)
3284          stippleEnabled = true;
3285          glesLineStipple(1, (uint16)stipple);
3286 #else
3287          glLineStipple(1, (uint16)stipple);
3288          glEnable(GL_LINE_STIPPLE);
3289 #endif
3290       }
3291       else
3292       {
3293 #if defined(_GLES)
3294          stippleEnabled = false;
3295          glMatrixMode(GL_TEXTURE);
3296          glLoadIdentity();
3297          glMatrixMode(GL_PROJECTION);
3298          glDisable(GL_TEXTURE_2D);
3299 #else
3300          glDisable(GL_LINE_STIPPLE);
3301 #endif
3302       }
3303    }
3304 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
3305    void SetRenderState(Display display, RenderState state, uint value)
3306    {
3307       OGLDisplay oglDisplay = display.driverData;
3308       //Logf("RenderState\n");
3309
3310       switch(state)
3311       {
3312          case antiAlias:
3313             if(value)
3314                glEnable(GL_MULTISAMPLE_ARB);
3315             else
3316                glDisable(GL_MULTISAMPLE_ARB);
3317             break;
3318          case fillMode:
3319 #if !defined(_GLES)
3320             glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
3321 #endif
3322             break;
3323          case depthTest:
3324             if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
3325             break;
3326          case depthWrite:
3327             if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
3328             oglDisplay.depthWrite = (bool)value;
3329             break;
3330          case fogColor:
3331          {
3332             float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3333             glFogfv(GL_FOG_COLOR, (float *)&color);
3334             break;
3335          }
3336          case fogDensity:
3337             glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
3338             break;
3339          case blend:
3340             if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
3341             break;
3342          case ambient:
3343          {
3344             float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3345             glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
3346             break;
3347          }
3348          case alphaWrite:
3349          {
3350             if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
3351             break;
3352          }
3353          case vSync:
3354          {
3355 #if defined(__WIN32__)
3356             wglSwapIntervalEXT(value ? 1 : 0);
3357 #endif
3358             break;
3359          }
3360       }
3361    }
3362
3363    void SetLight(Display display, int id, Light light)
3364    {
3365       //Logf("SetLight\n");
3366
3367       if(light != null)
3368       {
3369          Object lightObject = light.lightObject;
3370          float position[4] = { 0, 0, 0, 0 };
3371          float color[4] = { 0, 0, 0, 1 };
3372
3373          glEnable(GL_LIGHT0 + id);
3374          /*
3375          glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
3376          glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
3377          glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
3378          */
3379
3380          if(!light.multiplier) light.multiplier = 1.0f;
3381
3382          color[0] = light.diffuse.r * light.multiplier;
3383          color[1] = light.diffuse.g * light.multiplier;
3384          color[2] = light.diffuse.b * light.multiplier;
3385          glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
3386
3387          color[0] = light.ambient.r * light.multiplier;
3388          color[1] = light.ambient.g * light.multiplier;
3389          color[2] = light.ambient.b * light.multiplier;
3390          glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
3391          color[0] = light.specular.r * light.multiplier;
3392          color[1] = light.specular.g * light.multiplier;
3393          color[2] = light.specular.b * light.multiplier;
3394          glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
3395
3396          if(lightObject)
3397          {
3398             Vector3D positionVector;
3399             if(light.flags.spot)
3400             {
3401                if(lightObject.flags.root || !lightObject.parent)
3402                {
3403                   positionVector = lightObject.transform.position;
3404                   positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3405                }
3406                else
3407                {
3408                   positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
3409                   if(display.display3D.camera)
3410                      positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3411                }
3412                position[3] = 1;
3413             }
3414             else
3415             {
3416                if(!light.direction.x && !light.direction.y && !light.direction.z)
3417                {
3418                   Vector3Df vector { 0,0,-1 };
3419                   Matrix mat;
3420                   mat.RotationQuaternion(light.orientation);
3421                   positionVector.MultMatrixf(vector, mat);
3422                }
3423                else
3424                {
3425                   positionVector = light.direction;
3426                   position[3] = 1;
3427                }
3428             }
3429
3430             position[0] = (float)positionVector.x;
3431             position[1] = (float)positionVector.y;
3432             position[2] = (float)positionVector.z;
3433
3434             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3435
3436             /*
3437             // Display Light Position
3438             glDisable(GL_LIGHTING);
3439             glDisable(GL_DEPTH_TEST);
3440             glColor3f(1,1,1);
3441             glPointSize(10);
3442             glBegin(GL_POINTS);
3443             glVertex3fv(position);
3444             glEnd();
3445             glEnable(GL_DEPTH_TEST);
3446             glEnable(GL_LIGHTING);
3447
3448
3449             // Display Target
3450             if(lightObject.flags.root || !lightObject.parent)
3451             {
3452                positionVector = light.target.transform.position;
3453                positionVector.Subtract(positionVector, display.camera.cPosition);
3454             }
3455             else
3456             {
3457                positionVector.MultMatrix(light.target.transform.position,
3458                   lightObject.light.target.parent.matrix);
3459                positionVector.Subtract(positionVector, display.camera.cPosition);
3460             }
3461
3462             position[0] = positionVector.x;
3463             position[1] = positionVector.y;
3464             position[2] = positionVector.z;
3465
3466             glDisable(GL_LIGHTING);
3467             glDisable(GL_DEPTH_TEST);
3468             glColor3f(1,1,0);
3469             glPointSize(10);
3470             glBegin(GL_POINTS);
3471             glVertex3fv(position);
3472             glEnd();
3473             glEnable(GL_DEPTH_TEST);
3474             glEnable(GL_LIGHTING);
3475             */
3476
3477             if(light.flags.attenuation)
3478             {
3479                glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
3480                glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
3481                glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
3482             }
3483
3484             if(light.flags.spot)
3485             {
3486                float exponent = 0;
3487                #define MAXLIGHT  0.9
3488                float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
3489                // Figure out exponent out of the hot spot
3490                exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
3491
3492                glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
3493                glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
3494                glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
3495             }
3496          }
3497          else
3498          {
3499
3500             Vector3Df vector { 0,0,-1 };
3501             Vector3Df direction;
3502             Matrix mat;
3503
3504             mat.RotationQuaternion(light.orientation);
3505             direction.MultMatrix(vector, mat);
3506
3507             position[0] = direction.x;
3508             position[1] = direction.y;
3509             position[2] = direction.z;
3510
3511             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3512          }
3513       }
3514       else
3515          glDisable(GL_LIGHT0 + id);
3516    }
3517
3518    void SetCamera(Display display, Surface surface, Camera camera)
3519    {
3520       OGLDisplay oglDisplay = display.driverData;
3521       //Logf("SetCamera\n");
3522
3523       if(camera)
3524       {
3525          int left = surface.box.left + surface.offset.x;
3526          int top = surface.box.top  + surface.offset.y;
3527          int right = surface.box.right + surface.offset.x;
3528          int bottom = surface.box.bottom + surface.offset.y;
3529          float origX = surface.offset.x + camera.origin.x;
3530          float origY = surface.offset.y + camera.origin.y;
3531          int x = left;
3532          int y = display.height - bottom - 1;
3533          int w = right - left + 1;
3534          int h = bottom - top + 1;
3535
3536          // *** ViewPort ***
3537          glViewport(x, y, w, h);
3538
3539          // *** Projection Matrix ***
3540          if(!display.display3D.camera)
3541             glPushMatrix();
3542          else
3543             glMatrixMode(GL_PROJECTION);
3544          if(display.display3D.collectingHits)
3545          {
3546             float pickX = display.display3D.pickX + surface.offset.x;
3547             float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3548             Matrix pickMatrix
3549             {
3550                {
3551                   w / display.display3D.pickWidth, 0, 0, 0,
3552                   0, h / display.display3D.pickHeight, 0, 0,
3553                   0, 0, 1, 0,
3554                   (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3555                   (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3556                }
3557             };
3558             glLoadMatrixd(pickMatrix.array);
3559          }
3560          else
3561             glLoadIdentity();
3562          glFrustum(
3563             (left   - origX) * camera.zMin / camera.focalX,
3564             (right  - origX) * camera.zMin / camera.focalX,
3565             (bottom - origY) * camera.zMin / camera.focalY,
3566             (top    - origY) * camera.zMin / camera.focalY,
3567             camera.zMin, camera.zMax);
3568
3569          glDisable(GL_BLEND);
3570
3571          // *** Z Inverted Identity Matrix ***
3572          glMatrixMode(GL_MODELVIEW);
3573          if(!display.display3D.camera)
3574             glPushMatrix();
3575
3576          glLoadIdentity();
3577
3578          glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3579
3580          // *** View Matrix ***
3581          glMultMatrixd(camera.viewMatrix.array);
3582
3583          // *** Lights ***
3584          // ...
3585
3586          glEnable(GL_DEPTH_TEST);
3587          glEnable(GL_LIGHTING);
3588          glShadeModel(GL_SMOOTH);
3589          glDepthMask((byte)bool::true);
3590          oglDisplay.depthWrite = true;
3591
3592          glEnable(GL_MULTISAMPLE_ARB);
3593       }
3594       else if(display.display3D.camera)
3595       {
3596          oglDisplay.depthWrite = false;
3597          glViewport(0,0,display.width,display.height);
3598
3599          glDisable(GL_CULL_FACE);
3600          glDisable(GL_DEPTH_TEST);
3601          glDisable(GL_LIGHTING);
3602          glDisable(GL_FOG);
3603          glDisable(GL_TEXTURE_2D);
3604          glShadeModel(GL_FLAT);
3605          glEnable(GL_BLEND);
3606          glDisable(GL_MULTISAMPLE_ARB);
3607
3608          // *** Restore 2D MODELVIEW Matrix ***
3609          glPopMatrix();
3610
3611          // *** Restore 2D PROJECTION Matrix ***
3612          glMatrixMode(GL_PROJECTION);
3613          glPopMatrix();
3614       }
3615
3616       GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
3617    }
3618
3619    void ApplyMaterial(Display display, Material material, Mesh mesh)
3620    {
3621       //Logf("ApplyMaterial\n");
3622
3623       // Basic Properties
3624       if(material.flags.doubleSided)
3625       {
3626          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3627          glDisable(GL_CULL_FACE);
3628       }
3629       else
3630       {
3631          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3632          glEnable(GL_CULL_FACE);
3633       }
3634
3635       // Fog
3636       if(material.flags.noFog)
3637          glDisable(GL_FOG);
3638       else
3639          glEnable(GL_FOG);
3640
3641       // Maps
3642       if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3643       {
3644          Bitmap map = material.baseMap;
3645          glEnable(GL_TEXTURE_2D);
3646          glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3647
3648          glMatrixMode(GL_TEXTURE);
3649          glLoadIdentity();
3650          if(material.uScale && material.vScale)
3651             glScalef(material.uScale, material.vScale, 1);
3652          glMatrixMode(GL_MODELVIEW);
3653
3654          if(material.flags.tile)
3655          {
3656             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3657             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3658          }
3659          else
3660          {
3661             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3662             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3663          }
3664       }
3665       else
3666          glDisable(GL_TEXTURE_2D);
3667
3668       if(mesh.flags.colors)
3669       {
3670          glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3671          glEnable(GL_COLOR_MATERIAL);
3672       }
3673       else
3674       {
3675          glDisable(GL_COLOR_MATERIAL);
3676          {
3677             float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3678             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3679          }
3680          {
3681             float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3682             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3683          }
3684       }
3685       {
3686          float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3687          glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3688       }
3689       {
3690          float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3691          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3692       }
3693
3694       glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3695    }
3696
3697    void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3698    {
3699       OGLMesh oglMesh = mesh.data;
3700       if(oglMesh)
3701       {
3702          if(!mesh.flags.vertices)
3703          {
3704             if(oglMesh.vertices)
3705             {
3706                GLDeleteBuffers(1, &oglMesh.vertices);
3707                oglMesh.vertices = 0;
3708             }
3709             delete mesh.vertices;
3710          }
3711          if(!mesh.flags.normals)
3712          {
3713             if(oglMesh.normals)
3714             {
3715                GLDeleteBuffers(1, &oglMesh.normals);
3716                oglMesh.normals = 0;
3717             }
3718             delete mesh.normals;
3719          }
3720          if(!mesh.flags.texCoords1)
3721          {
3722             if(oglMesh.texCoords)
3723             {
3724                GLDeleteBuffers(1, &oglMesh.texCoords);
3725                oglMesh.texCoords = 0;
3726             }
3727             delete mesh.texCoords;
3728          }
3729          if(!mesh.flags.texCoords2)
3730          {
3731             if(oglMesh.texCoords2)
3732             {
3733                GLDeleteBuffers(1, &oglMesh.texCoords2);
3734                oglMesh.texCoords2 = 0;
3735             }
3736             /*
3737             delete mesh.texCoords2;
3738             */
3739          }
3740          if(!mesh.flags.colors)
3741          {
3742             if(oglMesh.colors)
3743             {
3744                GLDeleteBuffers(1, &oglMesh.colors);
3745                oglMesh.colors = 0;
3746             }
3747          }
3748          if(!mesh.flags)
3749          {
3750             delete oglMesh;
3751             mesh.data = null;
3752          }
3753       }
3754    }
3755
3756    bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3757    {
3758       bool result = false;
3759
3760       if(!mesh.data)
3761          mesh.data = OGLMesh { };
3762       if(mesh.data)
3763       {
3764          if(mesh.nVertices == nVertices)
3765          {
3766             // Same number of vertices, adding features (Leaves the other features pointers alone)
3767             if(mesh.flags != flags)
3768             {
3769                if(!mesh.flags.vertices && flags.vertices)
3770                {
3771                   if(flags.doubleVertices)
3772                   {
3773                      mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3774                   }
3775                   else
3776                      mesh.vertices = new Vector3Df[nVertices];
3777                }
3778                if(!mesh.flags.normals && flags.normals)
3779                {
3780                   if(flags.doubleNormals)
3781                   {
3782                      mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3783                   }
3784                   else
3785                      mesh.normals = new Vector3Df[nVertices];
3786                }
3787                if(!mesh.flags.texCoords1 && flags.texCoords1)
3788                {
3789                   mesh.texCoords = new Pointf[nVertices];
3790                }
3791                if(!mesh.flags.colors && flags.colors)
3792                {
3793                   mesh.colors = new ColorRGBAf[nVertices];
3794                }
3795             }
3796          }
3797          else
3798          {
3799             // New number of vertices, reallocate all current and new features
3800             flags |= mesh.flags;
3801             if(flags.vertices)
3802             {
3803                if(flags.doubleVertices)
3804                {
3805                   mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3806                }
3807                else
3808                   mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3809             }
3810             if(flags.normals)
3811             {
3812                if(flags.doubleNormals)
3813                {
3814                   mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3815                }
3816                else
3817                   mesh.normals = renew mesh.normals Vector3Df[nVertices];
3818             }
3819             if(flags.texCoords1)
3820             {
3821                mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3822             }
3823             if(flags.colors)
3824             {
3825                mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3826             }
3827          }
3828          result = true;
3829       }
3830       return result;
3831    }
3832
3833    void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3834    {
3835       OGLMesh oglMesh = mesh.data;
3836       if(!flags) flags = mesh.flags;
3837
3838       if(vboAvailable)
3839       {
3840          if(flags.vertices)
3841          {
3842             if(!oglMesh.vertices)
3843                GLGenBuffers(1, &oglMesh.vertices);
3844             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices);
3845             GLBufferData( mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, GL_STATIC_DRAW_ARB );
3846          }
3847
3848          if(flags.normals)
3849          {
3850             if(!oglMesh.normals)
3851                GLGenBuffers(1, &oglMesh.normals);
3852             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
3853             GLBufferData( mesh.flags.doubleNormals ? GL_DOUBLE : GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, GL_STATIC_DRAW_ARB );
3854          }
3855
3856          if(flags.texCoords1)
3857          {
3858             if(!oglMesh.texCoords)
3859                GLGenBuffers(1, &oglMesh.texCoords);
3860             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
3861             GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(Pointf), mesh.texCoords, GL_STATIC_DRAW_ARB );
3862          }
3863
3864          if(flags.colors)
3865          {
3866             if(!oglMesh.colors)
3867                GLGenBuffers( 1, &oglMesh.colors);
3868             GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
3869             GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, GL_STATIC_DRAW_ARB );
3870          }
3871
3872          GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
3873       }
3874    }
3875
3876    bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3877    {
3878       bool result = true;
3879
3880         return result;
3881    }
3882
3883    void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3884    {
3885       if(oglIndices)
3886       {
3887          if(oglIndices.buffer)
3888             GLDeleteBuffers(1, &oglIndices.buffer);
3889          delete oglIndices.indices;
3890          delete oglIndices;
3891       }
3892    }
3893
3894    void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3895    {
3896       OGLIndices oglIndices = OGLIndices { };
3897       if(oglIndices)
3898       {
3899          oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3900          GLGenBuffers( 1, &oglIndices.buffer);
3901          oglIndices.nIndices = nIndices;
3902       }
3903       return oglIndices;
3904    }
3905
3906    void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3907    {
3908       if(vboAvailable)
3909       {
3910          GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
3911          GLBufferData( indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, GL_ELEMENT_ARRAY_BUFFER_ARB, nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3912             oglIndices.indices, GL_STATIC_DRAW_ARB);
3913          GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3914       }
3915    }
3916
3917    uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3918    {
3919
3920       return oglIndices.indices;
3921    }
3922
3923    void SelectMesh(Display display, Mesh mesh)
3924    {
3925       //Logf("SelectMesh\n");
3926
3927 #if !defined( __ANDROID__) && !defined(__APPLE__)
3928
3929 #if defined(__WIN32__)
3930       if(glUnlockArraysEXT)
3931 #endif
3932          if(!vboAvailable && display.display3D.mesh)
3933             glUnlockArraysEXT();
3934
3935 #endif
3936       if(mesh)
3937       {
3938          OGLMesh oglMesh = mesh.data;
3939
3940          // *** Vertex Stream ***
3941          glEnableClientState(GL_VERTEX_ARRAY);
3942          if(!display.display3D.collectingHits && oglMesh)
3943          {
3944             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices );
3945             if(mesh.flags.doubleVertices)
3946                glVertexPointerd(3, 0, oglMesh.vertices ? null : (double *)mesh.vertices, mesh.nVertices);
3947             else
3948                glVertexPointer(3, GL_FLOAT, 0, oglMesh.vertices ? null : mesh.vertices);
3949
3950             // *** Normals Stream ***
3951             if(mesh.normals || mesh.flags.normals)
3952             {
3953                glEnableClientState(GL_NORMAL_ARRAY);
3954                GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
3955                glNormalPointer(/*mesh.flags.doubleNormals ? GL_DOUBLE : */GL_FLOAT, 0, oglMesh.normals ? null : mesh.normals);
3956             }
3957             else
3958                glDisableClientState(GL_NORMAL_ARRAY);
3959
3960             // *** Texture Coordinates Stream ***
3961             if(mesh.texCoords || mesh.flags.texCoords1)
3962             {
3963                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3964                GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
3965                glTexCoordPointer(2, GL_FLOAT, 0, oglMesh.texCoords ? null : mesh.texCoords);
3966             }
3967             else
3968                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3969
3970             // *** Color Stream ***
3971             if(mesh.colors || mesh.flags.colors)
3972             {
3973                glEnableClientState(GL_COLOR_ARRAY);
3974                GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
3975                glColorPointer(4, GL_FLOAT, 0, oglMesh.colors ? null : mesh.colors);
3976             }
3977             else
3978                glDisableClientState(GL_COLOR_ARRAY);
3979          }
3980          else
3981          {
3982             GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
3983             if(mesh.flags.doubleVertices)
3984                glVertexPointerd(3, 0, (double *)mesh.vertices, mesh.nVertices);
3985             else
3986                glVertexPointer(3, GL_FLOAT, 0, mesh.vertices);
3987             if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3988             {
3989                glEnableClientState(GL_NORMAL_ARRAY);
3990                glNormalPointer(/*mesh.flags.doubleNormals ? GL_DOUBLE : */GL_FLOAT, 0, mesh.normals);
3991             }
3992             else
3993                glDisableClientState(GL_NORMAL_ARRAY);
3994             if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3995             {
3996                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3997                glTexCoordPointer(2, GL_FLOAT, 0, mesh.texCoords);
3998             }
3999             else
4000                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4001             if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
4002             {
4003                glEnableClientState(GL_COLOR_ARRAY);
4004                glColorPointer(4, GL_FLOAT, 0, mesh.colors);
4005             }
4006             else
4007                glDisableClientState(GL_COLOR_ARRAY);
4008          }
4009
4010 #if !defined(__ANDROID__) && !defined(__APPLE__)
4011
4012 #if defined(__WIN32__)
4013          if(glLockArraysEXT)
4014 #endif
4015             if(!vboAvailable)
4016                glLockArraysEXT(0, mesh.nVertices);
4017
4018 #endif
4019       }
4020       else
4021          GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
4022    }
4023
4024    void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
4025    {
4026       //Logf("DrawPrimitives\n");
4027
4028       if(primitive->type.vertexRange)
4029          glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
4030       else
4031       {
4032          //    *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
4033          // HACK TO SPEED THINGS UP...
4034 #ifndef __ANDROID__
4035          /*GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
4036          if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
4037          {
4038             int c;
4039             glBegin(primitiveTypes[primitive->type.primitiveType]);
4040             if(primitive->data)
4041             {
4042                OGLIndices oglIndices = primitive->data;
4043                MeshFeatures flags = mesh.flags;
4044                for(c = 0; c<primitive->nIndices; c++)
4045                {
4046                   uint16 index = ((uint16 *) oglIndices.indices)[c];
4047                   if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
4048                   if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
4049                   if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
4050                   glVertex3fv((float *)&mesh.vertices[index]);
4051                }
4052             }
4053             glEnd();
4054          }
4055          else*/
4056 #endif
4057          {
4058             OGLIndices oglIndices = primitive->data;
4059
4060             if(!display.display3D.collectingHits && vboAvailable && oglIndices)
4061             {
4062                GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
4063                if(primitive->type.indices32bit)
4064                   glDrawElementsi(primitiveTypes[primitive->type.primitiveType], primitive->nIndices, 0);
4065                else
4066                   glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices, GL_UNSIGNED_SHORT, 0);
4067                GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
4068             }
4069             else
4070             {
4071                if(primitive->type.indices32bit)
4072                   glDrawElementsi(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
4073                      oglIndices ? oglIndices.indices : primitive->indices);
4074                else
4075                   glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
4076                      GL_UNSIGNED_SHORT, oglIndices ? oglIndices.indices : primitive->indices);
4077             }
4078          }
4079       }
4080    }
4081
4082    void PushMatrix(Display display)
4083    {
4084       glPushMatrix();
4085    }
4086
4087    void PopMatrix(Display display, bool setMatrix)
4088    {
4089       glPopMatrix();
4090    }
4091
4092    void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
4093    {
4094       Matrix matrix = transMatrix;
4095       Camera camera = useCamera ? display.display3D.camera : null;
4096
4097       if(viewSpace)
4098       {
4099          glLoadIdentity();
4100          glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
4101       }
4102       else if(camera)
4103       {
4104          glTranslated(
4105             matrix.m[3][0] - camera.cPosition.x,
4106             matrix.m[3][1] - camera.cPosition.y,
4107             matrix.m[3][2] - camera.cPosition.z);
4108       }
4109       else
4110          glTranslated(
4111             matrix.m[3][0],
4112             matrix.m[3][1],
4113             matrix.m[3][2]);
4114
4115       matrix.m[3][0] = 0;
4116       matrix.m[3][1] = 0;
4117       matrix.m[3][2] = 0;
4118
4119       glMultMatrixd(matrix.array);
4120    }
4121 #endif
4122 }
4123
4124 public void UseSingleGLContext(bool useSingle)
4125 {
4126    useSingleGLContext = useSingle;
4127 }
4128
4129 default dllexport void *
4130 #if defined(__WIN32__)
4131 __attribute__((stdcall))
4132 #endif
4133 IS_GLGetContext(DisplaySystem displaySystem)
4134 {
4135    if(displaySystem)
4136    {
4137 #if defined(__WIN32__)
4138       OGLSystem system = displaySystem.driverData;
4139       return system.glrc;
4140 #elif !defined(__ANDROID__)
4141       OGLSystem system = displaySystem.driverData;
4142       return system.glContext;
4143 #else
4144       return eglContext;
4145 #endif
4146    }
4147    return null;
4148 }
4149
4150 #endif