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