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