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