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