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