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