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