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