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