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