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