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