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