ecere/gfx/drivers/OpenGL: Disabling flippingBuffer on GL ES
[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    Matrix m;
858    Quaternion q;
859    q.RotationAxis({(float)b,(float)-c,(float)d}, a );
860    m.RotationQuaternion(q);
861    matrixStack[curStack][matrixIndex[curStack]].Rotate(q);
862    LoadCurMatrix();
863 }
864 void glesScaled( double a, double b, double c )
865 {
866    Matrix m, r;
867
868    m.Identity();
869    m.Scale(a,b,c);
870    r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
871    matrixStack[curStack][matrixIndex[curStack]] = r;
872    LoadCurMatrix();
873 }
874
875 void glesTranslated( double a, double b, double c )
876 {
877    Matrix m, r;
878
879    m.Identity();
880    m.Translate(a,b,c);
881    r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
882    matrixStack[curStack][matrixIndex[curStack]] = r;
883    LoadCurMatrix();
884 }
885
886 void glesMultMatrixd( double * i )
887 {
888    Matrix r;
889    r.Multiply((Matrix *)i, matrixStack[curStack][matrixIndex[curStack]]);
890    matrixStack[curStack][matrixIndex[curStack]] = r;
891    LoadCurMatrix();
892 }
893
894 void glesMatrixMode(int mode)
895 {
896    curStack = mode == GL_MODELVIEW ? 0 : mode == GL_PROJECTION ? 1 : 2;
897    glMatrixMode(mode);
898 }
899
900 #define glPushMatrix          glesPushMatrix
901 #define glPopMatrix           glesPopMatrix
902 #define glLoadIdentity        glesLoadIdentity
903 #define glMatrixMode          glesMatrixMode
904
905 /* Using the built-in matrix stack
906 void glesLoadMatrixd( double * i )
907 {
908    float m[16] =
909    {
910       (float)i[0],(float)i[1],(float)i[2],(float)i[3],
911       (float)i[4],(float)i[5],(float)i[6],(float)i[7],
912       (float)i[8],(float)i[9],(float)i[10],(float)i[11],
913       (float)i[12],(float)i[13],(float)i[14],(float)i[15]
914    };
915    glLoadMatrixf(m);
916 }
917
918 void glesOrtho( double l, double r, double b, double t, double n, double f )
919 {
920    float matrix[4][4] =
921    {
922       { (float)(2 / (r - l)), 0, 0, 0 },
923       { 0, (float)(2 / (t - b)), 0, 0 },
924       { 0, 0, (float)(-2 / (f - n)), 0 },
925       { (float)(-(r + l) / (r - l)), (float)(-(t + b) / (t - b)), (float)(-(f + n) / (f - n)), 1 }
926    };
927    glMultMatrixf((float *)matrix);
928 }
929
930 void glesFrustum( double l, double r, double b, double t, double n, double f )
931 {
932    float A = (float)((r + l) / (r - l));
933    float B = (float)((t + b) / (t - b));
934    float C = (float)(-(f + n) / (f - n));
935    float D = (float)(-2*f*n/(f-n));
936    float matrix[4][4] =
937    {
938       { (float)(2*n / (r - l)), 0, 0, 0 },
939       { 0, (float)(2*n / (t - b)), 0, 0 },
940       { A, B,             C,-1 },
941       { 0, 0,             D, 0 }
942    };
943    glMultMatrixf((float *)matrix);
944 }
945
946 void glesRotated( double a, double b, double c, double d ) { glRotatef((float)a, (float)b, (float)c, (float)d); }
947 void glesScaled( double a, double b, double c ) { glScalef((float)a, (float)b, (float)c); }
948 void glesTranslated( double a, double b, double c ) { glTranslatef((float)a, (float)b, (float)c); }
949
950 void glesMultMatrixd( double * i )
951 {
952    float m[16] =
953    {
954       (float)i[0], (float)i[1], (float)i[2], (float)i[3],
955       (float)i[4], (float)i[5], (float)i[6], (float)i[7],
956       (float)i[8], (float)i[9], (float)i[10], (float)i[11],
957       (float)i[12], (float)i[13], (float)i[14], (float)i[15]
958    };
959    glMultMatrixf(m);
960 }
961 */
962
963 // Need to do these...
964 void glesVertex3f( float x, float y, float z )
965 {
966    numVertexCoords = 3;
967    if(vertexCount + 4 > beginBufferSize)
968    {
969       beginBufferSize = beginBufferSize + beginBufferSize/2;
970       vertexPointer = renew vertexPointer float[beginBufferSize * 5];
971    }
972
973    vertexPointer[vertexCount*5+2] = x;
974    vertexPointer[vertexCount*5+3] = y;
975    vertexPointer[vertexCount*5+4] = z;
976    vertexCount++;
977
978    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
979    {
980       vertexPointer[vertexCount*5+2] = vertexPointer[(vertexCount-4)*5+2];
981       vertexPointer[vertexCount*5+3] = vertexPointer[(vertexCount-4)*5+3];
982       vertexPointer[vertexCount*5+4] = vertexPointer[(vertexCount-4)*5+4];
983       vertexCount++;
984       vertexPointer[vertexCount*5+2] = vertexPointer[(vertexCount-3)*5+2];
985       vertexPointer[vertexCount*5+3] = vertexPointer[(vertexCount-3)*5+3];
986       vertexPointer[vertexCount*5+4] = vertexPointer[(vertexCount-3)*5+4];
987       vertexCount++;
988    }
989    beginCount++;
990 }
991
992 void glesVertex3d( double x, double y, double z )  { glesVertex3f((float)x, (float)y, (float)z); }
993 void glesVertex3fv( float* coords )                { glesVertex3f(coords[0], coords[1], coords[2]); }
994
995 void glesNormal3f(float x, float y, float z)
996 {
997    normalCount = vertexCount;
998    if(vertexCount + 4 > normalBufferSize)
999    {
1000       normalBufferSize = normalBufferSize + normalBufferSize/2;
1001       normalPointer = renew normalPointer float[normalBufferSize * 2];
1002    }
1003
1004    normalPointer[normalCount*3+0] = x;
1005    normalPointer[normalCount*3+1] = y;
1006    normalPointer[normalCount*3+2] = z;
1007    normalCount++;
1008
1009    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
1010    {
1011       normalPointer[normalCount*3+0] = normalPointer[(normalCount-4)*3+0];
1012       normalPointer[normalCount*3+1] = normalPointer[(normalCount-4)*3+1];
1013       normalPointer[normalCount*3+2] = normalPointer[(normalCount-4)*3+2];
1014       normalCount++;
1015       normalPointer[normalCount*3+0] = normalPointer[(normalCount-3)*3+0];
1016       normalPointer[normalCount*3+1] = normalPointer[(normalCount-3)*3+1];
1017       normalPointer[normalCount*3+2] = normalPointer[(normalCount-3)*3+2];
1018       normalCount++;
1019    }
1020 }
1021 void glesNormal3fd(double x, double y, double z)         { glesNormal3f((float)x, (float)y, (float)z); }
1022 void glesNormal3fv(float * coords)                       { glesNormal3f(coords[0], coords[1], coords[2]); }
1023
1024 void glesColorMaterial(int a, int b)
1025 {
1026    PrintLn("glColorMaterial stub");
1027 }
1028
1029 void glesTerminate()
1030 {
1031    delete vertexPointer;
1032    beginBufferSize = 0;
1033
1034    delete floatVPBuffer;
1035    shortVPSize = 0;
1036
1037    delete shortVPBuffer;
1038    floatVPSize = 0;
1039
1040    delete shortBDBuffer;
1041    shortBDSize = 0;
1042 }
1043
1044 static GLuint stippleTexture;
1045 static bool stippleEnabled;
1046
1047 void glesLineStipple( int i, unsigned short j )
1048 {
1049    uint texture[1*16];
1050    int x;
1051    for(x = 0; x < 16; x++)
1052    {
1053       bool v = (j & (1 << x)) != 0;
1054       texture[x] = v ? 0xFFFFFFFF : 0;
1055    }
1056    if(!stippleTexture)
1057       glGenTextures(1, &stippleTexture);
1058    glBindTexture(GL_TEXTURE_2D, stippleTexture);
1059    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
1060    glEnable(GL_TEXTURE_2D);
1061    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1062    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1063    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1064    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1065    glMatrixMode(GL_TEXTURE);
1066    glLoadIdentity();
1067    //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
1068    glScaled(i/16.0, 1, 1.0f);
1069    glTranslated(0.5, 0.5, 0);
1070    glMatrixMode(GL_PROJECTION);
1071 }
1072
1073 void glesLightModeli( unsigned int pname, int param )
1074 {
1075    if(pname == GL_LIGHT_MODEL_TWO_SIDE)
1076       glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
1077 }
1078
1079 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
1080 void glFogi( unsigned int pname, int param ) { }
1081 void glPolygonMode( unsigned int i, unsigned int j ) { }
1082
1083
1084 // *** Picking won't be supported for now ***
1085 void glPushName( unsigned int i ) { }
1086 void glLoadName( unsigned int i ) { }
1087 void glPopName() { }
1088
1089 // Probably replace by regular glBlendFunc ...
1090 void glBlendFuncSeparate(int a, int b, int c, int d)
1091 {
1092    glBlendFunc(a, b);
1093 }
1094
1095 // For direct pixel blitting...
1096 void glRasterPos2d(double a, double b) { }
1097 void glPixelZoom(float a, float b) { }
1098 void glDrawPixels(int a, int b, int c, int d, void * e) { }
1099
1100 #else
1101
1102 /* Non OpenGL ES friendly stuff
1103 #undef GL_UNSIGNED_INT
1104 #undef GL_DOUBLE
1105 #undef GL_INT
1106 //#undef GL_POLYGON
1107 //#undef GL_QUADS
1108 #undef GL_QUAD_STRIP
1109 #undef GL_POLYGON_STIPPLE
1110 #undef GL_LINE_STIPPLE
1111 #undef GL_LINE
1112 #undef GL_FILL
1113 #undef GL_ALL_ATTRIB_BITS
1114 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
1115 */
1116
1117 #endif
1118
1119 #if !defined(__APPLE__)
1120 void (APIENTRY * glBindBufferARB) (GLenum target, GLuint buffer);
1121 void (APIENTRY * glGenBuffersARB) (GLsizei n, GLuint *buffers);
1122 void (APIENTRY * glDeleteBuffersARB) (GLsizei n, const GLuint *buffers);
1123 void (APIENTRY * glBufferDataARB) (GLenum target, int size, const GLvoid *data, GLenum usage);
1124 #endif
1125
1126 #endif
1127
1128 static int currentVertexBuffer;
1129
1130 bool GLSelectVBO(uint vbo)
1131 {
1132    if(currentVertexBuffer != vbo)
1133    {
1134       GLBindBuffer(GL_ARRAY_BUFFER, vbo);
1135       currentVertexBuffer = vbo;
1136       return true;
1137    }
1138    return false;
1139 }
1140
1141 void GLGenBuffers(int count, uint * buffer)
1142 {
1143 #ifdef __ANDROID__
1144    glGenBuffers(count, buffer);
1145 #else
1146 #if defined(__WIN32__)
1147    if(glGenBuffersARB)
1148 #endif
1149       glGenBuffersARB(count, buffer);
1150 #endif
1151 }
1152
1153 void GLDeleteBuffers(int count, GLuint * buffer)
1154 {
1155 #ifdef __ANDROID__
1156    glDeleteBuffers(count, buffer);
1157 #else
1158 #if defined(__WIN32__)
1159    if(glDeleteBuffersARB)
1160 #endif
1161       glDeleteBuffersARB(count, buffer);
1162 #endif
1163 }
1164
1165 void GLBindBuffer(int target, uint buffer)
1166 {
1167 #ifdef __ANDROID__
1168    glBindBuffer(target, buffer);
1169 #else
1170 #if defined(__WIN32__)
1171    if(glBindBufferARB)
1172 #endif
1173       glBindBufferARB(target, buffer);
1174 #endif
1175 }
1176
1177 void GLBufferData(int type, GLenum target, int size, const GLvoid *data, GLenum usage)
1178 {
1179 #ifdef __ANDROID__
1180    if(type == GL_DOUBLE)
1181       glesBufferDatad(target, size, (void *)data, usage);
1182    else if(type == GL_UNSIGNED_INT)
1183       glesBufferDatai(target, size, (void *)data, usage);
1184    else
1185       glBufferData(target, size, data, usage);
1186 #else
1187
1188 #if defined(__WIN32__)
1189    if(glBufferDataARB)
1190 #endif
1191       glBufferDataARB(target, size, data, usage);
1192
1193 #endif
1194 }
1195
1196 static int displayWidth, displayHeight;
1197
1198 #define GL_CLAMP_TO_EDGE 0x812F
1199
1200 static bool vboAvailable;
1201
1202 static bool useSingleGLContext = false;
1203 class OGLDisplay : struct
1204 {
1205 #if defined(__WIN32__)
1206    HDC hdc;
1207    HGLRC glrc;
1208
1209    HBITMAP memBitmap;
1210    HDC memDC;
1211    byte * picture;
1212    uint stride;
1213    void * pBuffer;
1214    /*
1215    int imageBuffers[2];
1216    byte * pboMemory1, * pboMemory2;
1217    */
1218 #elif !defined(__ANDROID__)
1219    GLXContext glContext;
1220
1221    Pixmap pixmap;
1222    XShmSegmentInfo shminfo;
1223    XImage * image;
1224    XShmSegmentInfo shminfoShape;
1225    XImage * shapeImage;
1226    byte * picture;
1227    uint stride;
1228    GLXPbuffer pBuffer;
1229    X11Picture windowPicture;
1230    X11Picture pixmapPicture;
1231    Pixmap shapePixmap;
1232    X11Picture shapePicture;
1233 #endif
1234
1235    ColorAlpha * flippingBuffer;
1236    int flipBufH, flipBufW;
1237    bool depthWrite;
1238    int x, y;
1239 };
1240
1241 class OGLSystem : struct
1242 {
1243    int maxTextureSize;
1244    bool loadingFont;
1245    bool pow2textures;
1246 #if defined(__WIN32__)
1247    PIXELFORMATDESCRIPTOR pfd;
1248    int format;
1249    HDC hdc;
1250    HGLRC glrc;
1251    HWND hwnd;
1252 #elif !defined(__ANDROID__)
1253    XVisualInfo * visualInfo;
1254    GLXContext glContext;
1255    GLXDrawable glxDrawable;
1256 #endif
1257 };
1258
1259 class OGLSurface : struct
1260 {
1261    Font font;
1262    bool opaqueText;
1263    int xOffset;
1264    bool writingText;
1265
1266    float foreground[4], background[4], bitmapMult[4];
1267 } OGLSurface;
1268
1269 class OGLMesh : struct
1270 {
1271    uint vertices;
1272    uint normals;
1273    uint texCoords;
1274    uint texCoords2;
1275    uint colors;
1276 };
1277
1278 class OGLIndices : struct
1279 {
1280    uint16 * indices;
1281    uint buffer;
1282    uint nIndices;
1283 };
1284
1285 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1286 static int primitiveTypes[RenderPrimitiveType] =
1287 {
1288    GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, GL_LINE_STRIP
1289 };
1290 #endif
1291
1292 int current;
1293 void * previous;
1294
1295 class OpenGLDisplayDriver : DisplayDriver
1296 {
1297    class_property(name) = "OpenGL";
1298
1299    bool LockSystem(DisplaySystem displaySystem)
1300    {
1301 #if !defined(__ANDROID__)
1302       OGLSystem oglSystem = displaySystem.driverData;
1303       if(useSingleGLContext) return true;
1304    #if defined(__WIN32__)
1305       wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1306    #elif defined(__unix__) || defined(__APPLE__)
1307       //if(previous) return true;
1308       // printf("Making SYSTEM current\n");
1309       glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
1310       //previous = oglSystem.glContext;
1311    #endif
1312 #endif
1313       return true;
1314    }
1315
1316    void UnlockSystem(DisplaySystem displaySystem)
1317    {
1318       if(useSingleGLContext) return;
1319    #if defined(__WIN32__)
1320       wglMakeCurrent(null, null);
1321    #elif defined(__unix__) || defined(__APPLE__)
1322       // printf("Making NULL current\n");
1323       #if defined(__ANDROID__)
1324       #else
1325       glXMakeCurrent(xGlobalDisplay, None, null);
1326       #endif
1327       // previous = null;
1328    #endif
1329    }
1330
1331    bool Lock(Display display)
1332    {
1333 #if !defined(__ANDROID__)
1334       OGLDisplay oglDisplay = display.driverData;
1335       if(useSingleGLContext) return true;
1336    #if defined(__WIN32__)
1337       wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1338    #elif defined(__unix__) || defined(__APPLE__)
1339       // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
1340       // printf("   Making DISPLAY current\n");
1341       glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1342    #endif
1343 #endif
1344       return true;
1345    }
1346
1347    void Unlock(Display display)
1348    {
1349       if(useSingleGLContext) return;
1350       //printf("   Making NULL current\n");
1351       //glXMakeCurrent(xGlobalDisplay, None, null);
1352       // if(previous)
1353          LockSystem(display.displaySystem);
1354    }
1355
1356    void DestroyDisplay(Display display)
1357    {
1358       OGLDisplay oglDisplay = display.driverData;
1359
1360       if(oglDisplay)
1361       {
1362    #if defined(__WIN32__)
1363          wglMakeCurrent( null, null );
1364
1365          if(oglDisplay.glrc)
1366             wglDeleteContext(oglDisplay.glrc);
1367
1368          if(oglDisplay.hdc && oglDisplay.pBuffer)
1369             wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1370
1371          if(oglDisplay.pBuffer)
1372             wglDestroyPbufferARB(oglDisplay.pBuffer);
1373
1374          if(oglDisplay.hdc)
1375             ReleaseDC(display.window, oglDisplay.hdc);
1376
1377          if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1378          if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1379
1380    #elif defined(__unix__) || defined(__APPLE__)
1381       #if defined(__ANDROID__)
1382       #else
1383          if(oglDisplay.shapePixmap)
1384             XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1385          if(oglDisplay.pixmap)
1386             XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1387          if(oglDisplay.image)
1388          {
1389             if(oglDisplay.shminfoShape.shmid != -1)
1390             {
1391                XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1392                if(oglDisplay.shminfo.shmaddr != (void *)-1)
1393                   shmdt(oglDisplay.shminfo.shmaddr);
1394                shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1395             }
1396          }
1397          if(oglDisplay.shapeImage)
1398          {
1399             if(oglDisplay.shminfoShape.shmid != -1)
1400             {
1401                XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1402                if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1403                   shmdt(oglDisplay.shminfoShape.shmaddr);
1404                shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1405             }
1406             XDestroyImage(oglDisplay.shapeImage);
1407             oglDisplay.shapeImage = None;
1408          }
1409
1410          glXMakeCurrent(xGlobalDisplay, None, null);
1411
1412          if(oglDisplay.glContext)
1413             glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1414       #endif
1415    #endif
1416          delete oglDisplay.flippingBuffer;
1417          delete oglDisplay;
1418          display.driverData = null;
1419       }
1420    }
1421
1422    void ::CheckExtensions(OGLSystem oglSystem)
1423    {
1424       const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
1425       if(extensions)
1426          oglSystem.pow2textures = strstr(extensions, "GL_ARB_texture_non_power_of_two") ? false : true;
1427       glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
1428    }
1429
1430    bool CreateDisplaySystem(DisplaySystem displaySystem)
1431    {
1432       bool result = false;
1433       OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
1434
1435    #ifdef __WIN32__
1436       oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
1437
1438       oglSystem.hdc = GetDC(oglSystem.hwnd);
1439       if(oglSystem.hdc)
1440       {
1441
1442          oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
1443          oglSystem.pfd.nVersion = 1;
1444          oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
1445          oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
1446          oglSystem.pfd.cColorBits = 24;
1447          oglSystem.pfd.cAlphaBits = 8;
1448          oglSystem.pfd.cDepthBits = 24;
1449          oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
1450
1451          oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
1452          DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1453
1454          if(oglSystem.pfd.cColorBits > 8)
1455          {
1456             SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1457             oglSystem.glrc = wglCreateContext(oglSystem.hdc);
1458             if(oglSystem.glrc)
1459             {
1460                wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1461
1462                  // Get Pointers To The GL Functions
1463                glActiveTextureARB = (void *) wglGetProcAddress("glActiveTextureARB");
1464                glMultiTexCoord2fARB = (void *) wglGetProcAddress("glMultiTexCoord2fARB");
1465                glClientActiveTextureARB = (void *) wglGetProcAddress("glClientActiveTextureARB");
1466                glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
1467                glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
1468                  glGenBuffersARB = (void *) wglGetProcAddress("glGenBuffersARB");
1469                  glBindBufferARB = (void *) wglGetProcAddress("glBindBufferARB");
1470                  glBufferDataARB = (void *) wglGetProcAddress("glBufferDataARB");
1471                glMapBufferARB  = (void *) wglGetProcAddress("glMapBufferARB");
1472                glUnmapBufferARB  = (void *) wglGetProcAddress("glUnmapBufferARB");
1473                  glDeleteBuffersARB = (void *) wglGetProcAddress("glDeleteBuffersARB");
1474                glBlendFuncSeparate = (void *) wglGetProcAddress("glBlendFuncSeparate");
1475
1476                wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
1477                wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
1478                wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
1479                wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
1480                wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
1481                wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
1482                wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
1483                wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
1484                wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
1485
1486                wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
1487
1488                vboAvailable = glBindBufferARB != null;
1489
1490                // eSystem_LoggingMode(LOG_MSGBOX, null);
1491
1492                if(wglChoosePixelFormatARB)
1493                {
1494                     int pixelFormat;
1495                     int valid;
1496                     int numFormats;
1497                     float fAttributes[] = {0,0};
1498                     int iAttributes[] =
1499                   {
1500                      WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
1501                             WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1502                             WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1503                             WGL_COLOR_BITS_ARB,24,
1504                             WGL_ALPHA_BITS_ARB,8,
1505                             WGL_DEPTH_BITS_ARB,16,
1506                             WGL_STENCIL_BITS_ARB,0,
1507                             WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
1508                             WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1509                             WGL_SAMPLES_ARB, 4,                                         // Check For 4x Multisampling
1510                             0,0
1511                   };
1512
1513                   //Log("Found wglChoosePixelFormatARB\n");
1514
1515                     valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1516                     if(!valid || !numFormats)
1517                     {
1518                      //Log("Can't find 4x multi sampling\n");
1519                        iAttributes[19] = 2;
1520                        valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1521                      if(!valid || !numFormats)
1522                      {
1523                         // Log("Can't find 2x multi sampling\n");
1524                         iAttributes[16] = 0;
1525                         iAttributes[17] = 0;
1526                         valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1527                      }
1528                     }
1529                   if(valid && numFormats)
1530                   {
1531                      oglSystem.format = pixelFormat;
1532                      wglMakeCurrent(null, null);
1533                      wglDeleteContext(oglSystem.glrc);
1534
1535                      // *** DescribePixelFormat does not support WGL pixel formats! ***
1536                      //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1537                      SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1538                      //Log("Successfully set pixel format\n");
1539
1540                      oglSystem.glrc = wglCreateContext(oglSystem.hdc);
1541                      wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1542                   }
1543                }
1544                /*else
1545                   eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
1546
1547                result = true;
1548
1549                CheckExtensions(oglSystem);
1550
1551                wglMakeCurrent(null, null);
1552
1553                //eSystem_DumpErrors(true);
1554             }
1555          }
1556       }
1557    #elif defined(__unix__) || defined(__APPLE__)
1558       vboAvailable = true;
1559       #if defined(__ANDROID__)
1560          egl_init_display(guiApp.desktop.windowHandle);
1561          CheckExtensions(oglSystem);
1562          result = true;
1563       #else
1564       {
1565          X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1566          XSetWindowAttributes attr;
1567          unsigned long mask;
1568
1569          int attrList[] =
1570          {
1571       #ifndef ECERE_MINIGLX
1572             GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1573       #endif
1574             GLX_RGBA,
1575             GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1576             GLX_DOUBLEBUFFER,
1577             None
1578          };
1579          oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay,  DefaultScreen( xGlobalDisplay ), attrList );
1580          attr.background_pixel = 0;
1581          attr.border_pixel = 0;
1582          attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1583          attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1584          mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1585
1586          oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1587             oglSystem.visualInfo->visual, mask, &attr );
1588       }
1589       if(oglSystem.visualInfo)
1590       {
1591          oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1592          if(oglSystem.glContext)
1593          {
1594             glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1595             // Setup Extensions
1596             CheckExtensions(oglSystem);
1597             glXMakeCurrent(xGlobalDisplay, None, null);
1598             result = true;
1599          }
1600       }
1601       #endif
1602    #endif
1603
1604       displaySystem.flags.alpha = true;
1605       displaySystem.flags.flipping = true;
1606       displaySystem.pixelFormat = pixelFormat888;
1607       return result;
1608    }
1609
1610    void DestroyDisplaySystem(DisplaySystem displaySystem)
1611    {
1612       OGLSystem oglSystem = displaySystem.driverData;
1613
1614    #if defined(__WIN32__)
1615       wglMakeCurrent( null, null );
1616
1617       if(oglSystem.glrc)
1618          wglDeleteContext(oglSystem.glrc);
1619
1620       if(oglSystem.hdc)
1621          ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1622       DestroyWindow(oglSystem.hwnd);
1623
1624    #elif defined(__unix__) || defined(__APPLE__)
1625       #if defined(__ANDROID__)
1626          egl_term_display();
1627       #else
1628       if(oglSystem.visualInfo)
1629       {
1630    #ifdef   ECERE_MINIGLX
1631          __miniglx_XFree(oglSystem.visualInfo);
1632    #else
1633          XFree(oglSystem.visualInfo);
1634    #endif
1635       }
1636
1637       if(oglSystem.glxDrawable)
1638       {
1639          XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1640          oglSystem.glxDrawable = 0;
1641       }
1642       #endif
1643    #endif
1644       delete oglSystem;
1645    }
1646
1647    bool CreateDisplay(Display display)
1648    {
1649       bool result = false;
1650       OGLDisplay oglDisplay = display.driverData;
1651 #if !defined(__ANDROID__)
1652       OGLSystem oglSystem = display.displaySystem.driverData;
1653 #endif
1654       if(!oglDisplay)
1655          oglDisplay = display.driverData = OGLDisplay { };
1656       //printf("Inside CreateDisplay\n");
1657
1658 #if defined(__WIN32__) || defined(USEPBUFFER)
1659       if(!display.alphaBlend)
1660 #endif
1661       {
1662    #if defined(__WIN32__)
1663          oglDisplay.hdc = GetDC(display.window);
1664          SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1665          if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
1666          {
1667             wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1668             wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1669             result = true;
1670          }
1671          else
1672             ReleaseDC(display.window, oglDisplay.hdc);
1673    #elif defined(__unix__) || defined(__APPLE__)
1674       #if defined(__ANDROID__)
1675       #else
1676          XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1677          /*
1678 #if defined(__APPLE__)
1679          XVisualInfo template = { 0 };
1680          XWindowAttributes winAttr;
1681          int n;
1682          XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1683          template.visualid = XVisualIDFromVisual(winAttr.visual);
1684          visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1685 #ifdef _DEBUG
1686          printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1687          printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1688          printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1689          printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1690 #endif
1691          // visualInfo = oglSystem.visualInfo;
1692 //#endif
1693          */
1694          if(visualInfo)
1695          {
1696             //printf("visualInfo is not null\n");
1697             // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1698             oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1699             //XFree(visualInfo);
1700          }
1701
1702          // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1703          if(oglDisplay.glContext)
1704          {
1705             //printf("CreateDisplay Got a Context\n");
1706             glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1707             result = true;
1708          }
1709       #endif
1710    #endif
1711       }
1712 #if defined(__WIN32__) || defined(USEPBUFFER)
1713       else
1714          result = true;
1715 #endif
1716       if(result)
1717       {
1718 #if defined(__WIN32__)
1719          if(glBlendFuncSeparate)
1720             glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1721          else
1722             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1723 #else
1724 #if !defined(__OLDX__)
1725           glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1726 #else
1727          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1728 #endif
1729 #endif
1730          glEnable(GL_BLEND);
1731
1732          glMatrixMode(GL_MODELVIEW);
1733          glScaled(1.0, 1.0, -1.0);
1734          // glTranslatef(0.375f, 0.375f, 0.0f);
1735          // glTranslatef(-0.625f, -0.625f, 0.0f);
1736          glMatrixMode(GL_PROJECTION);
1737          glShadeModel(GL_FLAT);
1738
1739          // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, true);
1740          glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1741          glFogi(GL_FOG_MODE, GL_EXP);
1742          glFogf(GL_FOG_DENSITY, 0);
1743          glEnable(GL_NORMALIZE);
1744          glDepthFunc(GL_LESS);
1745          glClearDepth(1.0);
1746          glDisable(GL_MULTISAMPLE_ARB);
1747       }
1748 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1749       display.ambient = Color { 50,50,50 };
1750 #endif
1751
1752       if(!useSingleGLContext)
1753       {
1754    #if defined(__WIN32__)
1755          wglMakeCurrent(null, null);
1756    #elif defined(__unix__) || defined(__APPLE__)
1757       #if defined(__ANDROID__)
1758          result = true;
1759       #else
1760          glXMakeCurrent(xGlobalDisplay, None, null);
1761       #endif
1762    #endif
1763       }
1764
1765       return result;
1766    }
1767
1768    bool DisplaySize(Display display, int width, int height)
1769    {
1770       OGLDisplay oglDisplay = display.driverData;
1771
1772       bool result = false;
1773
1774       //printf("Inside DisplaySize\n");
1775 #if defined(__WIN32__) || defined(USEPBUFFER)
1776       OGLSystem oglSystem = display.displaySystem.driverData;
1777       if(display.alphaBlend)
1778       {
1779 #if defined(__WIN32__)
1780          const int attributes[]=
1781          {
1782             /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1783             WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1784          };
1785          int pixelFormat = 0;
1786          if(wglChoosePixelFormatARB)
1787          {
1788             int valid;
1789             int numFormats;
1790             float fAttributes[] = {0,0};
1791             int iAttributes[] =
1792             {
1793                //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1794                WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1795                     WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1796                     WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1797                     WGL_COLOR_BITS_ARB,24,
1798                     WGL_ALPHA_BITS_ARB,8,
1799                     WGL_DEPTH_BITS_ARB,16,
1800                     WGL_STENCIL_BITS_ARB,0,
1801                     WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1802                     WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1803                     WGL_SAMPLES_ARB, 4,                                         // Check For 4x Multisampling
1804                     0,0
1805             };
1806
1807             //Log("Found wglChoosePixelFormatARB\n");
1808
1809             valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1810             if(!valid || !numFormats)
1811             {
1812                //Log("Can't find 4x multi sampling\n");
1813                iAttributes[19] = 2;
1814                valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1815                if(!valid || !numFormats)
1816                {
1817                   // Log("Can't find 2x multi sampling\n");
1818                   iAttributes[16] = 0;
1819                   iAttributes[17] = 0;
1820                   valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1821                   if(!valid || !numFormats)
1822                   {
1823                      int iAttributes[] =
1824                      {
1825                         WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1826                         //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1827                         WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1828                         WGL_COLOR_BITS_ARB,24,
1829                         WGL_ALPHA_BITS_ARB,8,
1830                         WGL_DEPTH_BITS_ARB,16,
1831                         0,0
1832                      };
1833                      valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1834                   }
1835                }
1836             }
1837             if(valid && numFormats)
1838             {
1839                wglMakeCurrent(null, null);
1840             }
1841          }
1842
1843          wglMakeCurrent( null, null );
1844          wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1845          if(oglDisplay.hdc && oglDisplay.pBuffer)
1846             wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1847
1848          wglDestroyPbufferARB(oglDisplay.pBuffer);
1849
1850          if(!useSingleGLContext)
1851             wglMakeCurrent( null, null );
1852
1853          if(oglDisplay.glrc)
1854             wglDeleteContext(oglDisplay.glrc);
1855
1856          oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1857          oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1858          if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
1859          {
1860             BITMAPINFO * info;
1861             HDC hdc = GetDC(display.window);
1862
1863             wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1864             wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1865
1866             //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1867             //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1868
1869             // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1870
1871             if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1872             {
1873                HBITMAP newBitmap;
1874
1875                if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1876                oglDisplay.memDC = CreateCompatibleDC(hdc);
1877                SetMapMode(oglDisplay.memDC, MM_TEXT);
1878                info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1879                info->bmiHeader.biPlanes = 1;
1880                info->bmiHeader.biCompression = BI_RGB;
1881                info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1882                info->bmiHeader.biWidth = width;
1883                info->bmiHeader.biHeight = height;
1884                newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1885                if(newBitmap)
1886                {
1887                   SelectObject(oglDisplay.memDC, newBitmap);
1888                   if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1889                   /*
1890                   {
1891                      PIXELFORMATDESCRIPTOR pfd = { 0 };
1892                      pfd.nSize = (short)sizeof(pfd);
1893                      pfd.nVersion = 1;
1894                      pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1895                      pfd.iPixelType = PFD_TYPE_RGBA;
1896                      pfd.cColorBits = 32;
1897                      //pfd.cAlphaBits = 8;
1898                      pfd.cDepthBits = 24;
1899                      pfd.iLayerType = PFD_MAIN_PLANE;
1900
1901                      oglDisplay.hdc = oglDisplay.memDC;
1902
1903                      pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1904                      DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1905                      SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1906
1907                      oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1908                      wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1909                      wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1910                   }
1911                   */
1912                   /*
1913                   {
1914                      const int imageSize = width * height * 4;
1915
1916                      glGenBuffersARB(2, oglDisplay.imageBuffers);
1917
1918                      glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1919                      glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1920                      // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1921                      // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1922                   }
1923                   */
1924                   oglDisplay.memBitmap = newBitmap;
1925                   oglDisplay.stride = width;
1926
1927                   result = true;
1928                }
1929                delete info;
1930             }
1931             ReleaseDC(display.window, hdc);
1932          }
1933 #elif defined(__unix__) || defined(__APPLE__)
1934       #if defined(__ANDROID__)
1935          result = true;
1936       #else
1937         int attrib[] =
1938         {
1939                 GLX_DOUBLEBUFFER,  True,
1940             GLX_DEPTH_SIZE,    1,
1941                 GLX_RED_SIZE,      8,
1942                 GLX_GREEN_SIZE,    8,
1943                 GLX_BLUE_SIZE,     8,
1944                 GLX_ALPHA_SIZE,    8,
1945                 GLX_STENCIL_SIZE,  1,
1946                 //GLX_DEPTH_SIZE,    24,
1947                 GLX_RENDER_TYPE,   GLX_RGBA_BIT,
1948                 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1949                 None
1950         };
1951
1952         int PBattrib[] =
1953         {
1954                 GLX_PBUFFER_WIDTH,   width,
1955                 GLX_PBUFFER_HEIGHT,  height,
1956                 GLX_LARGEST_PBUFFER, False,
1957             None
1958         };
1959
1960         // choose a pixel format that meets our minimum requirements
1961         int count = 0;
1962
1963         GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1964          if(config)
1965          {
1966             if(oglDisplay.pixmap)
1967             {
1968                XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1969                oglDisplay.pixmap = None;
1970             }
1971             if(oglDisplay.shapePixmap)
1972             {
1973                XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1974                oglDisplay.shapePixmap = None;
1975             }
1976
1977             // Free Shared Memory Pixmap
1978             if(oglDisplay.image)
1979             {
1980                if(oglDisplay.shminfoShape.shmid != -1)
1981                {
1982                   XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1983                   if(oglDisplay.shminfo.shmaddr != (void *)-1)
1984                      shmdt(oglDisplay.shminfo.shmaddr);
1985                   shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1986                }
1987                XDestroyImage(oglDisplay.image);
1988                oglDisplay.image = None;
1989             }
1990             if(oglDisplay.shapeImage)
1991             {
1992                if(oglDisplay.shminfoShape.shmid != -1)
1993                {
1994                   XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1995                   if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1996                      shmdt(oglDisplay.shminfoShape.shmaddr);
1997                   shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1998                }
1999                XDestroyImage(oglDisplay.shapeImage);
2000                oglDisplay.shapeImage = None;
2001             }
2002
2003             if(oglDisplay.windowPicture)
2004                XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
2005             if(oglDisplay.pixmapPicture)
2006                XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
2007
2008             if(oglDisplay.pixmap)
2009                XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
2010
2011             if(oglDisplay.glContext)
2012                   glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
2013             if(oglDisplay.pBuffer)
2014                glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
2015
2016                 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
2017             if(oglDisplay.pBuffer)
2018             {
2019                    oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
2020                if(oglDisplay.glContext)
2021                {
2022                   glXMakeCurrent(xGlobalDisplay, None, null);
2023                   glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
2024
2025                   // Initialize Shared Memory Pixmap
2026                   oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
2027                      ZPixmap, null, &oglDisplay.shminfo, width, height);
2028                   if(oglDisplay.image)
2029                   {
2030                      oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
2031                         oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
2032                      if(oglDisplay.shminfo.shmid != -1)
2033                      {
2034                         oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
2035                         if(oglDisplay.shminfo.shmaddr != (void *)-1)
2036                         {
2037                            oglDisplay.shminfo.readOnly = False;
2038                            if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
2039                            {
2040                               oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
2041                                  &oglDisplay.shminfo, width, height, 32);
2042
2043                               // Initialize Shared Memory Shape Pixmap
2044                               oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
2045                                  ZPixmap, null, &oglDisplay.shminfoShape, width, height);
2046                               if(oglDisplay.shapeImage)
2047                               {
2048                                  oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
2049                                     oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
2050                                  if(oglDisplay.shminfoShape.shmid != -1)
2051                                  {
2052                                     oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
2053                                     if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
2054                                     {
2055                                        oglDisplay.shminfoShape.readOnly = False;
2056                                        if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
2057                                        {
2058                                           oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
2059                                              &oglDisplay.shminfoShape, width, height, 1);
2060                                           //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
2061
2062                                           {
2063                                              XRenderPictureAttributes attributes = { 0 };
2064                                              XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
2065                                              #if !defined(__APPLE__) && !defined(__OLDX__)
2066                                              attributes.repeat = RepeatNormal;
2067                                              #else
2068                                              attributes.repeat = 1;
2069                                              #endif
2070                                              oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
2071                                              oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
2072                                              oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
2073                                                 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
2074                                           }
2075
2076                                           oglDisplay.picture = oglDisplay.shminfo.shmaddr;
2077                                           oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
2078
2079                                           result = true;
2080                                        }
2081                                     }
2082                                  }
2083                               }
2084                            }
2085                         }
2086                      }
2087                   }
2088                }
2089             }
2090             XFree(config);
2091          }
2092      #endif
2093 #endif
2094          CreateDisplay(display);
2095 #if defined(__WIN32__)
2096          wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
2097 #elif defined(__unix__) || defined(__APPLE__)
2098       #if defined(__ANDROID__)
2099          width = eglWidth;
2100          height = eglHeight;
2101       #else
2102          glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
2103       #endif
2104 #endif
2105       }
2106       else
2107 #endif
2108          result = true;
2109       if(!result && display.alphaBlend)
2110       {
2111          printf("Alpha blending windows not supported on this display\n");
2112       }
2113       if(!result)
2114          return false;
2115
2116       result = false;
2117
2118       glViewport(0,0,width,height);
2119       glLoadIdentity();
2120       glOrtho(0,width,height,0,0.0,1.0);
2121       displayWidth = display.width = width;
2122       displayHeight = display.height = height;
2123
2124       if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
2125       {
2126          oglDisplay.flipBufW = width;
2127          oglDisplay.flipBufH = height;
2128 #ifdef _GLES
2129          result = true;
2130 #else
2131          oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
2132 #endif
2133       }
2134       if(oglDisplay.flippingBuffer || !width || !height)
2135          result = true;
2136
2137       return result;
2138    }
2139
2140    void DisplayPosition(Display display, int x, int y)
2141    {
2142       OGLDisplay oglDisplay = display.driverData;
2143
2144       oglDisplay.x = x;
2145       oglDisplay.y = y;
2146    }
2147
2148    void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
2149    {
2150    }
2151
2152    void RestorePalette(Display display)
2153    {
2154    }
2155
2156    void StartUpdate(Display display)
2157    {
2158    }
2159
2160    void EndUpdate(Display display)
2161    {
2162    }
2163
2164    void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
2165    {
2166    }
2167
2168    void Update(Display display, Box updateBox)
2169    {
2170 #if defined(__WIN32__) || defined(USEPBUFFER)
2171       OGLDisplay oglDisplay = display.driverData;
2172 #endif
2173       //Logf("DisplayScreen\n");
2174
2175       glFlush();
2176       glFinish();
2177 #if defined(__WIN32__) || defined(USEPBUFFER)
2178       if(display.alphaBlend)
2179       {
2180          glPixelStorei(GL_PACK_ALIGNMENT, 4);
2181          glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
2182          glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2183          glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2184          glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
2185
2186          {
2187 #if defined(__WIN32__)
2188             HDC hdc = GetDC(0);
2189             POINT point = { oglDisplay.x, oglDisplay.y};
2190             POINT srcPoint = { 0, 0 };
2191             BLENDFUNCTION blend = { 0 };
2192             SIZE size;
2193             size.cx = display.width;
2194             size.cy = display.height;
2195             blend.BlendOp = AC_SRC_OVER;
2196             blend.BlendFlags = 0;
2197             blend.SourceConstantAlpha = 255;
2198             blend.AlphaFormat = AC_SRC_ALPHA;
2199
2200             /*
2201             // Process partial images.  Mapping the buffer waits for
2202             // outstanding DMA transfers into the buffer to finish.
2203             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2204             oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
2205
2206             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2207             // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
2208
2209
2210             memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
2211             //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
2212             */
2213
2214             UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
2215             /*
2216
2217             // Unmap the image buffers
2218             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2219             glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
2220
2221             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2222             // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
2223
2224             // Bind two different buffer objects and start the glReadPixels
2225             // asynchronously. Each call will return directly after
2226             // starting the DMA transfer.
2227             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2228             glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
2229
2230             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2231             // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
2232             */
2233
2234             ReleaseDC(0, hdc);
2235 #elif defined(__unix__) || defined(__APPLE__)
2236       #if defined(__ANDROID__)
2237       #else
2238             XTransform transform =
2239             {
2240                {
2241                   { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)),  (int)(0 * (1 << 16)) },
2242                   { (int)(0.0f),           (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
2243                   { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)),  (int)(1.0f * (1<<16)) }
2244                }
2245             };
2246             XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
2247             XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
2248             XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
2249             #if !defined(__APPLE__) && !defined(__OLDX__)
2250             XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
2251             #else
2252             XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
2253             #endif
2254             XFlush(xGlobalDisplay);
2255      #endif
2256 #endif
2257          }
2258       }
2259       else
2260 #endif
2261       {
2262 #if defined(__WIN32__)
2263          //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
2264          SwapBuffers(oglDisplay.hdc);
2265 #elif defined(__unix__) || defined(__APPLE__)
2266       #if defined(__ANDROID__)
2267          eglSwapBuffers(eglDisplay, eglSurface);
2268       #else
2269          glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
2270       #endif
2271 #endif
2272       }
2273       //Logf("Out of DisplayScreen\n");
2274    }
2275
2276    void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
2277    {
2278       if(bitmap.driverData)
2279       {
2280          GLuint tex = (GLuint)(uintptr)bitmap.driverData;
2281          glDeleteTextures(1, &tex);
2282          bitmap.driverData = 0;
2283       }
2284       bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
2285    }
2286
2287    bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
2288    {
2289       OGLSystem oglSystem = displaySystem.driverData;
2290       bool result = false;
2291       Bitmap mipMap { };
2292       GLuint glBitmap = 0;
2293
2294       uint w = width, h = height;
2295       if(oglSystem.pow2textures)
2296       {
2297          w = pow2i(w);
2298          h = pow2i(h);
2299       }
2300       w = Min(w, oglSystem.maxTextureSize);
2301       h = Min(h, oglSystem.maxTextureSize);
2302
2303       glGenTextures(1, &glBitmap);
2304       glBindTexture(GL_TEXTURE_2D, glBitmap);
2305
2306       glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2307
2308       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2309       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2310
2311       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2312       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2313
2314       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2315
2316       mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
2317
2318       // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2319       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2320
2321       delete mipMap;
2322
2323       bitmap.driverData = (void *)(uintptr)glBitmap;
2324       bitmap.driver = displaySystem.driver;
2325       bitmap.width = w;
2326       bitmap.height = h;
2327
2328       result = true;
2329       return result;
2330    }
2331
2332    bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
2333    {
2334       bool result = false;
2335       OGLSystem oglSystem = displaySystem.driverData;
2336
2337       // Pre process the bitmap... First make it 32 bit
2338       if(/*bitmap.pixelFormat == pixelFormatRGBA || */bitmap.Convert(null, pixelFormat888, null))
2339       {
2340          int c, level;
2341          uint w = bitmap.width, h = bitmap.height;
2342          GLuint glBitmap = 0;
2343          if(oglSystem.pow2textures)
2344          {
2345             w = pow2i(w);
2346             h = pow2i(h);
2347          }
2348          w = Min(w, oglSystem.maxTextureSize);
2349          h = Min(h, oglSystem.maxTextureSize);
2350
2351          if(mipMaps)
2352          {
2353             while(w * 2 < h) w *= 2;
2354             while(h * 2 < w) h *= 2;
2355          }
2356
2357          // Switch ARGB to RGBA
2358          //if(bitmap.format != pixelFormatRGBA)
2359          {
2360             for(c=0; c<bitmap.size; c++)
2361             {
2362                // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
2363                // TODO:
2364                ColorAlpha color = ((ColorAlpha *)bitmap.picture)[c];
2365                ((ColorRGBA *)bitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
2366             }
2367          }
2368          bitmap.pixelFormat = pixelFormat888;
2369
2370          glGetError();
2371          glGenTextures(1, &glBitmap);
2372          if(glBitmap == 0)
2373          {
2374             //int error = glGetError();
2375             return false;
2376          }
2377
2378          glBindTexture(GL_TEXTURE_2D, glBitmap);
2379          glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2380
2381          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2382          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
2383          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2384
2385          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
2386          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
2387
2388          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2389          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2390
2391          glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2392
2393          result = true;
2394
2395          for(level = 0; result && (w > 1 || h > 1); level++, w >>= 1, h >>= 1)
2396          {
2397             Bitmap mipMap;
2398             if(bitmap.width != w || bitmap.height != h)
2399             {
2400                mipMap = Bitmap { };
2401                if(mipMap.Allocate(null, w, h, w, bitmap.pixelFormat, false))
2402                {
2403                   Surface mipSurface = mipMap.GetSurface(0,0,null);
2404                   mipSurface.Filter(bitmap, 0,0,0,0, w, h, bitmap.width, bitmap.height);
2405                   delete mipSurface;
2406                }
2407                else
2408                {
2409                   result = false;
2410                   delete mipMap;
2411                }
2412             }
2413             else
2414                mipMap = bitmap;
2415
2416             if(result)
2417             {
2418                int error;
2419                //int width = 0;
2420                glGetError();
2421                // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2422                glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2423                //printf("Calling glTexImage2D\n");
2424                //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2425                //printf("width = %d (Should be %d, %d)\n", width, w, h);
2426                if((error = glGetError()))
2427                {
2428                   //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2429                   //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2430                   result = false;
2431                }
2432             }
2433             if(mipMap != bitmap)
2434                delete mipMap;
2435             if(!mipMaps) break;
2436          }
2437
2438          if(!bitmap.keepData)
2439             bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
2440          bitmap.driverData = (void *)(uintptr)glBitmap;
2441          bitmap.driver = displaySystem.driver;
2442
2443          if(!result)
2444             FreeBitmap(displaySystem, bitmap);
2445          else if(oglSystem.loadingFont)
2446          {
2447             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2448             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2449             oglSystem.loadingFont = false;
2450          }
2451       }
2452       return result;
2453    }
2454
2455    void ReleaseSurface(Display display, Surface surface)
2456    {
2457       glDisable(GL_SCISSOR_TEST);
2458       delete surface.driverData;
2459       surface.driverData = null;
2460    }
2461
2462    bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2463    {
2464       return false;
2465    }
2466
2467    bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2468    {
2469       bool result = false;
2470       OGLSurface oglSurface = surface.driverData = OGLSurface { };
2471
2472       //Logf("GetSurface\n");
2473
2474       if(oglSurface)
2475       {
2476          if(displayWidth != display.width || displayHeight != display.height)
2477          {
2478             displayWidth = display.width;
2479             displayHeight = display.height;
2480
2481             glViewport(0,0,display.width,display.height);
2482             glLoadIdentity();
2483             glOrtho(0,display.width,display.height,0,0.0,1.0);
2484          }
2485
2486          surface.offset.x = x;
2487          surface.offset.y = y;
2488          surface.unclippedBox = surface.box = clip;
2489          oglSurface.bitmapMult[0] = 1;
2490          oglSurface.bitmapMult[1] = 1;
2491          oglSurface.bitmapMult[2] = 1;
2492          oglSurface.bitmapMult[3] = 1;
2493
2494          glEnable(GL_SCISSOR_TEST);
2495          glScissor(
2496             x+clip.left,
2497             (display.height) -(y+clip.bottom)-1,
2498             clip.right-clip.left+1,
2499             clip.bottom-clip.top+1);
2500          result = true;
2501       }
2502       return result;
2503    }
2504
2505    void Clip(Display display, Surface surface, Box clip)
2506    {
2507       Box box;
2508
2509       //Logf("Clip\n");
2510
2511       if(clip != null)
2512       {
2513          box = clip;
2514          box.Clip(surface.unclippedBox);
2515          surface.box = box;
2516       }
2517       else
2518          box = surface.box = surface.unclippedBox;
2519       box.left += surface.offset.x;
2520       box.top  += surface.offset.y;
2521       box.right+= surface.offset.x;
2522       box.bottom += surface.offset.y;
2523
2524       glScissor(
2525          box.left,display.height - box.bottom - 1,
2526          box.right-box.left+1, box.bottom-box.top+1);
2527    }
2528
2529    bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2530    {
2531       bool result = false;
2532       OGLDisplay oglDisplay = display.driverData;
2533       ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2534
2535       if(oglDisplay.flippingBuffer)
2536       {
2537          if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2538          {
2539             bitmap.Free();
2540             bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2541          }
2542          if(bitmap)
2543          {
2544             uint row;
2545
2546             glPixelStorei(GL_PACK_ALIGNMENT, 4);
2547             glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2548             glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2549             glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2550             glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2551
2552             // Need a flip...
2553             for(row = 0; row<h; row++)
2554                CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2555             result = true;
2556          }
2557       }
2558       return result;
2559    }
2560
2561    void SetForeground(Display display, Surface surface, ColorAlpha color)
2562    {
2563       OGLSurface oglSurface = surface.driverData;
2564
2565       //Logf("SetForeground\n");
2566
2567       oglSurface.foreground[0] = color.color.r/255.0f;
2568       oglSurface.foreground[1] = color.color.g/255.0f;
2569       oglSurface.foreground[2] = color.color.b/255.0f;
2570       //oglSurface.foreground[3] = 1.0f;
2571       oglSurface.foreground[3] = color.a/255.0f;
2572
2573       //if(!oglSurface.foreground[3])printf("bug");
2574    }
2575
2576    void SetBackground(Display display, Surface surface, ColorAlpha color)
2577    {
2578       OGLSurface oglSurface = surface.driverData;
2579
2580       //Logf("SetBackground\n");
2581
2582       oglSurface.background[0] = color.color.r/255.0f;
2583       oglSurface.background[1] = color.color.g/255.0f;
2584       oglSurface.background[2] = color.color.b/255.0f;
2585       //oglSurface.background[3] = 1.0;
2586       oglSurface.background[3] = color.a/255.0f;
2587    }
2588
2589    void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2590    {
2591       OGLSurface oglSurface = surface.driverData;
2592
2593       oglSurface.bitmapMult[0] = color.color.r/255.0f;
2594       oglSurface.bitmapMult[1] = color.color.g/255.0f;
2595       oglSurface.bitmapMult[2] = color.color.b/255.0f;
2596       oglSurface.bitmapMult[3] = color.a/255.0f;
2597    }
2598
2599    ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2600    {
2601       return 0;
2602    }
2603
2604    void PutPixel(Display display, Surface surface,int x,int y)
2605    {
2606       OGLSurface oglSurface = surface.driverData;
2607
2608       //Logf("PutPixel\n");
2609
2610       glColor4fv(oglSurface.foreground);
2611       glBegin(GL_POINTS);
2612       // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2613       glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2614
2615       glEnd();
2616    }
2617
2618    void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2619    {
2620       OGLSurface oglSurface = surface.driverData;
2621       float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2622       if(_x1 == _x2)
2623       {
2624          if(_y2 >= _y1)
2625             y2 += 1;
2626          else
2627             y1 += 1;
2628       }
2629       else if(_y1 == _y2)
2630       {
2631          if(_x2 >= _x1)
2632             x2 += 1;
2633          else
2634             x1 += 1;
2635       }
2636       x1 += surface.offset.x;
2637       y1 += surface.offset.y;
2638       x2 += surface.offset.x;
2639       y2 += surface.offset.y;
2640
2641       //Logf("Line\n");
2642
2643       glColor4fv(oglSurface.foreground);
2644       glBegin(GL_LINES);
2645 #ifdef __ANDROID__
2646       if(stippleEnabled)
2647       {
2648          glTexCoord2f(0.5f, 0);
2649          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2650          glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2651          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2652       }
2653       else
2654 #endif
2655       {
2656          /*
2657          glVertex2i(x1, y1);
2658          glVertex2i(x2, y2);
2659          */
2660          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2661          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2662       }
2663
2664       glEnd();
2665    }
2666
2667    void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2668    {
2669       OGLSurface oglSurface = surface.driverData;
2670       x1 += surface.offset.x;
2671       y1 += surface.offset.y;
2672       x2 += surface.offset.x;
2673       y2 += surface.offset.y;
2674
2675       //Logf("Rectangle\n");
2676
2677       glColor4fv(oglSurface.foreground);
2678 #ifdef __ANDROID__
2679       if(stippleEnabled)
2680       {
2681          glBegin(GL_LINES);
2682
2683          glTexCoord2f(0.5f, 0);
2684          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2685          glTexCoord2f(y2-y1 + 0.5f, 0);
2686          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2687
2688          glTexCoord2f(0.5f, 0);
2689          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2690          glTexCoord2f(x2 - x1 + 0.5f, 0);
2691          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2692
2693          glTexCoord2f(0.5f, 0);
2694          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2695          glTexCoord2f(y1 - y2 + 0.5f, 0);
2696          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2697
2698          glTexCoord2f(0.5f, 0);
2699          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2700          glTexCoord2f(x1 - x2 + 0.5f, 0);
2701          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2702       }
2703       else
2704 #endif
2705       {
2706          glBegin(GL_LINE_LOOP);
2707          /*
2708          glVertex2i(x1, y1);
2709          glVertex2i(x1, y2);
2710          glVertex2i(x2, y2);
2711          glVertex2i(x2, y1);
2712          */
2713          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2714          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2715          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2716          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2717       }
2718       glEnd();
2719    }
2720
2721    void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2722    {
2723       OGLSurface oglSurface = surface.driverData;
2724       //Logf("Area\n");
2725
2726       glColor4fv(oglSurface.background);
2727       glRecti(x1+surface.offset.x, y1+surface.offset.y,
2728               x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2729
2730       /*
2731       glRectf(x1+surface.offset.x, y1+surface.offset.y,
2732               x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2733       */
2734    }
2735
2736    void Clear(Display display, Surface surface, ClearType type)
2737    {
2738       OGLDisplay oglDisplay = display.driverData;
2739       OGLSurface oglSurface = surface.driverData;
2740
2741       //Logf("Clear\n");
2742       if(type != depthBuffer)
2743          glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2744       if(type != colorBuffer && !oglDisplay.depthWrite)
2745       {
2746          glDepthMask((byte)bool::true);
2747       }
2748       glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2749               ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2750       if(type != colorBuffer && !oglDisplay.depthWrite)
2751       {
2752          glDepthMask((byte)bool::false);
2753       }
2754    }
2755
2756    bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2757    {
2758       return true;
2759    }
2760
2761    void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2762    {
2763       OGLSurface oglSurface = surface.driverData;
2764
2765 #if !defined(__OLDX__)
2766          // WHY DO WE HAVE GL_ONE HERE ?
2767          /*if(glBlendFuncSeparate && !oglSurface.writingText)
2768             glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2769 #endif
2770
2771       if(!oglSurface.writingText)
2772       {
2773          // glTranslatef(-0.375f, -0.375f, 0.0f);
2774          glEnable(GL_TEXTURE_2D);
2775          glColor4fv(oglSurface.bitmapMult);
2776       }
2777       else if(oglSurface.xOffset)
2778          glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2779
2780       glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2781       glBegin(GL_QUADS);
2782
2783       if(h < 0)
2784       {
2785          glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2786          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2787          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2788          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2789          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2790          glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2791          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2792          glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2793       }
2794       else
2795       {
2796          /*
2797          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2798          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2799          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2800          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2801          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2802          glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2803          glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2804          glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2805          */
2806
2807          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2808          glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2809          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2810          glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2811          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2812          glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2813          glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2814          glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2815       }
2816       glEnd();
2817
2818       if(!oglSurface.writingText)
2819       {
2820          glDisable(GL_TEXTURE_2D);
2821
2822          //glTranslate(0.375, 0.375, 0.0);
2823       }
2824       else if(oglSurface.xOffset)
2825          glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2826
2827 #if !defined(__OLDX__)
2828          /*if(glBlendFuncSeparate && !oglSurface.writingText)
2829             glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2830 #endif
2831    }
2832
2833    void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2834    {
2835       OGLSurface oglSurface = surface.driverData;
2836
2837       //glTranslate(-0.375, -0.375, 0.0);
2838
2839       //Logf("Stretch\n");
2840
2841 #if !defined(__OLDX__)
2842       /*if(glBlendFuncSeparate)
2843          glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2844 #endif
2845
2846       glEnable(GL_TEXTURE_2D);
2847       glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2848
2849       glColor4fv(oglSurface.bitmapMult);
2850
2851       glBegin(GL_QUADS);
2852
2853       if(h < 0)
2854       {
2855          glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2856          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2857
2858          glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2859          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2860
2861          glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2862          glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2863
2864          glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2865          glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2866       }
2867       else
2868       {
2869          glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2870          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2871
2872          glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2873          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2874
2875          glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2876          glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2877
2878          glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2879          glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2880       }
2881
2882       glEnd();
2883
2884       glDisable(GL_TEXTURE_2D);
2885
2886       //glTranslate(0.375, 0.375, 0.0);
2887 #if !defined(__OLDX__)
2888       /*if(glBlendFuncSeparate)
2889          glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2890 #endif
2891
2892    }
2893
2894    void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2895    {
2896       Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2897    }
2898
2899    void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2900    {
2901       float s2dw,s2dh,d2sw,d2sh;
2902       //bool flipX = false, flipY = false;
2903
2904       //Logf("StretchDI\n");
2905
2906       if(Sgn(w) != Sgn(sw))
2907       {
2908          w = Abs(w);
2909          sw = Abs(sw);
2910          //flipX = true;
2911       }
2912       if(Sgn(h) != Sgn(sh))
2913       {
2914          h = Abs(h);
2915          sh = Abs(sh);
2916          //flipY = true;
2917       }
2918
2919       s2dw=(float)w / sw;
2920       s2dh=(float)h / sh;
2921       d2sw=(float)sw / w;
2922       d2sh=(float)sh / h;
2923
2924       //Clip against the edges of the source
2925       if(sx<0)
2926       {
2927          dx+=(int)((0-sx) * s2dw);
2928          w-=(int)((0-sx) * s2dw);
2929          sw-=0-sx;
2930          sx=0;
2931       }
2932       if(sy<0)
2933       {
2934          dy+=(int)((0-sy) * s2dh);
2935          h-=(int)((0-sy) * s2dh);
2936
2937          sh-=0-sy;
2938          sy=0;
2939       }
2940       if(sx+sw>bitmap.width-1)
2941       {
2942          w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2943          sw-=sx+sw-(bitmap.width-1)-1;
2944       }
2945       if(sy+sh>(bitmap.height-1))
2946       {
2947          h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2948          sh-=sy+sh-(bitmap.height-1)-1;
2949       }
2950       //Clip against the edges of the surfaceination
2951       if(dx<surface.box.left)
2952       {
2953          //if(!flip)
2954          sx+=(int)((surface.box.left-dx)*d2sw);
2955          sw-=(int)((surface.box.left-dx)*d2sw);
2956          w-=surface.box.left-dx;
2957          dx=surface.box.left;
2958       }
2959       if(dy<surface.box.top)
2960       {
2961          sy+=(int)((surface.box.top-dy)*d2sh);
2962          sh-=(int)((surface.box.top-dy)*d2sh);
2963          h-=surface.box.top-dy;
2964          dy=surface.box.top;
2965       }
2966       if(dx+w>surface.box.right)
2967       {
2968          //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2969          sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2970          w-=dx+w-surface.box.right-1;
2971       }
2972       if(dy+h>surface.box.bottom)
2973       {
2974          sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2975          h-=dy+h-surface.box.bottom-1;
2976       }
2977       if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2978
2979       dx += surface.offset.x;
2980       dy += surface.offset.y;
2981
2982       if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2983       {
2984          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2985          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2986          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2987          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2988          glRasterPos2d(dx,dy);
2989          //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2990          glPixelZoom(s2dw, -s2dh);
2991          glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2992          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2993          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2994          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2995          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2996       }
2997    }
2998
2999    void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
3000    {
3001       //Logf("BlitDI\n");
3002
3003       //Clip against the edges of the source
3004       if(sx<0)
3005       {
3006          dx+=-sx;
3007          w-=-sx;
3008          sx=0;
3009       }
3010       if(sy<0)
3011       {
3012          dy+=0-sy;
3013          h-=0-sy;
3014          sy=0;
3015       }
3016       if(sx+w>bitmap.width-1)
3017          w-=sx+w-(bitmap.width-1)-1;
3018       if(sy+h>bitmap.height-1)
3019          h-=sy+h-(bitmap.height-1)-1;
3020       //Clip against the edges of the surfaceination
3021       if(dx<surface.box.left)
3022       {
3023          //if(!flip)
3024          sx+=surface.box.left-dx;
3025          w-=surface.box.left-dx;
3026          dx=surface.box.left;
3027       }
3028       if(dy<surface.box.top)
3029       {
3030          sy+=surface.box.top-dy;
3031          h-=surface.box.top-dy;
3032          dy=surface.box.top;
3033       }
3034       if(dx+w>surface.box.right)
3035       {
3036          //if(flip) sx+=dx+w-surface.box.right-1;
3037          w-=dx+w-surface.box.right-1;
3038       }
3039       if(dy+h>surface.box.bottom)
3040          h-=dy+h-surface.box.bottom-1;
3041       if((w<=0)||(h<=0))
3042          return;
3043
3044       dx += surface.offset.x;
3045       dy += surface.offset.y;
3046
3047       if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
3048       {
3049          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3050          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
3051          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
3052          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
3053          glRasterPos2d(dx,dy);
3054          glPixelZoom(1,-1);
3055          glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
3056          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3057          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3058          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3059          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3060       }
3061    }
3062
3063    void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3064    {
3065       StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
3066    }
3067
3068    void UnloadFont(DisplaySystem displaySystem, Font font)
3069    {
3070       ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
3071    }
3072
3073    Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
3074    {
3075       Font font;
3076       OGLSystem oglSystem = displaySystem.driverData;
3077       oglSystem.loadingFont = true;
3078       font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
3079       return font;
3080    }
3081
3082    void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
3083    {
3084       ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
3085    }
3086
3087    void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
3088    {
3089       OGLSurface oglSurface = surface.driverData;
3090       OGLSystem oglSystem = display.displaySystem.driverData;
3091       oglSystem.loadingFont = true;
3092
3093       //glTranslated(-0.375, -0.375, 0.0);
3094
3095       //Logf("Blit\n");
3096
3097       if(surface.textOpacity)
3098       {
3099          int w, h;
3100          FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
3101          display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
3102       }
3103
3104       oglSurface.writingText = true;
3105
3106       glEnable(GL_TEXTURE_2D);
3107       glColor4fv(oglSurface.foreground);
3108
3109       ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
3110       oglSurface.writingText = false;
3111       oglSystem.loadingFont = false;
3112
3113       glDisable(GL_TEXTURE_2D);
3114
3115       //glTranslated(0.375, 0.375, 0.0);
3116    }
3117
3118    void TextFont(Display display, Surface surface, Font font)
3119    {
3120       ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
3121    }
3122
3123    void TextOpacity(Display display, Surface surface, bool opaque)
3124    {
3125       OGLSurface oglSurface = surface.driverData;
3126       oglSurface.opaqueText = opaque;
3127    }
3128
3129    void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
3130    {
3131       OGLSurface oglSurface = surface.driverData;
3132       OGLSystem oglSystem = display.displaySystem.driverData;
3133       oglSystem.loadingFont = true;
3134       FontExtent(display.displaySystem, oglSurface.font, text, len, width, height);
3135       oglSystem.loadingFont = false;
3136    }
3137
3138    void DrawingChar(Display display, Surface surface, char character)
3139    {
3140
3141    }
3142
3143    void LineStipple(Display display, Surface surface, uint32 stipple)
3144    {
3145       //Logf("Stipple\n");
3146
3147       if(stipple)
3148       {
3149 #if defined(__ANDROID__)
3150          stippleEnabled = true;
3151          glesLineStipple(1, (uint16)stipple);
3152 #else
3153          glLineStipple(1, (uint16)stipple);
3154          glEnable(GL_LINE_STIPPLE);
3155 #endif
3156       }
3157       else
3158       {
3159 #if defined(__ANDROID__)
3160          stippleEnabled = false;
3161          glMatrixMode(GL_TEXTURE);
3162          glLoadIdentity();
3163          glMatrixMode(GL_PROJECTION);
3164          glDisable(GL_TEXTURE_2D);
3165 #else
3166          glDisable(GL_LINE_STIPPLE);
3167 #endif
3168       }
3169    }
3170 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
3171    void SetRenderState(Display display, RenderState state, uint value)
3172    {
3173       OGLDisplay oglDisplay = display.driverData;
3174       //Logf("RenderState\n");
3175
3176       switch(state)
3177       {
3178          case antiAlias:
3179             if(value)
3180                glEnable(GL_MULTISAMPLE_ARB);
3181             else
3182                glDisable(GL_MULTISAMPLE_ARB);
3183             break;
3184          case fillMode:
3185             glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
3186             break;
3187          case depthTest:
3188             if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
3189             break;
3190          case depthWrite:
3191             if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
3192             oglDisplay.depthWrite = (bool)value;
3193             break;
3194          case fogColor:
3195          {
3196             float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3197             glFogfv(GL_FOG_COLOR, (float *)&color);
3198             break;
3199          }
3200          case fogDensity:
3201             glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
3202             break;
3203          case blend:
3204             if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
3205             break;
3206          case ambient:
3207          {
3208             float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3209             glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
3210             break;
3211          }
3212          case alphaWrite:
3213          {
3214             if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
3215             break;
3216          }
3217          case vSync:
3218          {
3219 #if defined(__WIN32__)
3220             wglSwapIntervalEXT(value ? 1 : 0);
3221 #endif
3222             break;
3223          }
3224       }
3225    }
3226
3227    void SetLight(Display display, int id, Light light)
3228    {
3229       //Logf("SetLight\n");
3230
3231       if(light != null)
3232       {
3233          Object lightObject = light.lightObject;
3234          float position[4] = { 0, 0, 0, 0 };
3235          float color[4] = { 0, 0, 0, 1 };
3236
3237          glEnable(GL_LIGHT0 + id);
3238          /*
3239          glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
3240          glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
3241          glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
3242          */
3243
3244          if(!light.multiplier) light.multiplier = 1.0f;
3245
3246          color[0] = light.diffuse.r * light.multiplier;
3247          color[1] = light.diffuse.g * light.multiplier;
3248          color[2] = light.diffuse.b * light.multiplier;
3249          glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
3250
3251          color[0] = light.ambient.r * light.multiplier;
3252          color[1] = light.ambient.g * light.multiplier;
3253          color[2] = light.ambient.b * light.multiplier;
3254          glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
3255          color[0] = light.specular.r * light.multiplier;
3256          color[1] = light.specular.g * light.multiplier;
3257          color[2] = light.specular.b * light.multiplier;
3258          glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
3259
3260          if(lightObject)
3261          {
3262             Vector3D positionVector;
3263             if(light.flags.spot)
3264             {
3265                if(lightObject.flags.root || !lightObject.parent)
3266                {
3267                   positionVector = lightObject.transform.position;
3268                   positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3269                }
3270                else
3271                {
3272                   positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
3273                   if(display.display3D.camera)
3274                      positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3275                }
3276                position[3] = 1;
3277             }
3278             else
3279             {
3280                if(!light.direction.x && !light.direction.y && !light.direction.z)
3281                {
3282                   Vector3Df vector { 0,0,-1 };
3283                   Matrix mat;
3284                   mat.RotationQuaternion(light.orientation);
3285                   positionVector.MultMatrixf(vector, mat);
3286                }
3287                else
3288                {
3289                   positionVector = light.direction;
3290                   position[3] = 1;
3291                }
3292             }
3293
3294             position[0] = (float)positionVector.x;
3295             position[1] = (float)positionVector.y;
3296             position[2] = (float)positionVector.z;
3297
3298             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3299
3300             /*
3301             // Display Light Position
3302             glDisable(GL_LIGHTING);
3303             glDisable(GL_DEPTH_TEST);
3304             glColor3f(1,1,1);
3305             glPointSize(10);
3306             glBegin(GL_POINTS);
3307             glVertex3fv(position);
3308             glEnd();
3309             glEnable(GL_DEPTH_TEST);
3310             glEnable(GL_LIGHTING);
3311
3312
3313             // Display Target
3314             if(lightObject.flags.root || !lightObject.parent)
3315             {
3316                positionVector = light.target.transform.position;
3317                positionVector.Subtract(positionVector, display.camera.cPosition);
3318             }
3319             else
3320             {
3321                positionVector.MultMatrix(light.target.transform.position,
3322                   lightObject.light.target.parent.matrix);
3323                positionVector.Subtract(positionVector, display.camera.cPosition);
3324             }
3325
3326             position[0] = positionVector.x;
3327             position[1] = positionVector.y;
3328             position[2] = positionVector.z;
3329
3330             glDisable(GL_LIGHTING);
3331             glDisable(GL_DEPTH_TEST);
3332             glColor3f(1,1,0);
3333             glPointSize(10);
3334             glBegin(GL_POINTS);
3335             glVertex3fv(position);
3336             glEnd();
3337             glEnable(GL_DEPTH_TEST);
3338             glEnable(GL_LIGHTING);
3339             */
3340
3341             if(light.flags.attenuation)
3342             {
3343                glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
3344                glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
3345                glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
3346             }
3347
3348             if(light.flags.spot)
3349             {
3350                float exponent = 0;
3351                #define MAXLIGHT  0.9
3352                float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
3353                // Figure out exponent out of the hot spot
3354                exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
3355
3356                glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
3357                glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
3358                glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
3359             }
3360          }
3361          else
3362          {
3363
3364             Vector3Df vector { 0,0,-1 };
3365             Vector3Df direction;
3366             Matrix mat;
3367
3368             mat.RotationQuaternion(light.orientation);
3369             direction.MultMatrix(vector, mat);
3370
3371             position[0] = direction.x;
3372             position[1] = direction.y;
3373             position[2] = direction.z;
3374
3375             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3376          }
3377       }
3378       else
3379          glDisable(GL_LIGHT0 + id);
3380    }
3381
3382    void SetCamera(Display display, Surface surface, Camera camera)
3383    {
3384       OGLDisplay oglDisplay = display.driverData;
3385       //Logf("SetCamera\n");
3386
3387       if(camera)
3388       {
3389          int left = surface.box.left + surface.offset.x;
3390          int top = surface.box.top  + surface.offset.y;
3391          int right = surface.box.right + surface.offset.x;
3392          int bottom = surface.box.bottom + surface.offset.y;
3393          float origX = surface.offset.x + camera.origin.x;
3394          float origY = surface.offset.y + camera.origin.y;
3395          int x = left;
3396          int y = display.height - bottom - 1;
3397          int w = right - left + 1;
3398          int h = bottom - top + 1;
3399
3400          // *** ViewPort ***
3401          glViewport(x, y, w, h);
3402
3403          // *** Projection Matrix ***
3404          if(!display.display3D.camera)
3405             glPushMatrix();
3406          else
3407             glMatrixMode(GL_PROJECTION);
3408          if(display.display3D.collectingHits)
3409          {
3410             float pickX = display.display3D.pickX + surface.offset.x;
3411             float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3412             Matrix pickMatrix
3413             {
3414                {
3415                   w / display.display3D.pickWidth, 0, 0, 0,
3416                   0, h / display.display3D.pickHeight, 0, 0,
3417                   0, 0, 1, 0,
3418                   (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3419                   (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3420                }
3421             };
3422             glLoadMatrixd(pickMatrix.array);
3423          }
3424          else
3425             glLoadIdentity();
3426          glFrustum(
3427             (left   - origX) * camera.zMin / camera.focalX,
3428             (right  - origX) * camera.zMin / camera.focalX,
3429             (bottom - origY) * camera.zMin / camera.focalY,
3430             (top    - origY) * camera.zMin / camera.focalY,
3431             camera.zMin, camera.zMax);
3432
3433          glDisable(GL_BLEND);
3434
3435          // *** Z Inverted Identity Matrix ***
3436          glMatrixMode(GL_MODELVIEW);
3437          if(!display.display3D.camera)
3438             glPushMatrix();
3439
3440          glLoadIdentity();
3441
3442          glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3443
3444          // *** View Matrix ***
3445          glMultMatrixd(camera.viewMatrix.array);
3446
3447          // *** Lights ***
3448          // ...
3449
3450          glEnable(GL_DEPTH_TEST);
3451          glEnable(GL_LIGHTING);
3452          glShadeModel(GL_SMOOTH);
3453          glDepthMask((byte)bool::true);
3454          oglDisplay.depthWrite = true;
3455
3456          glEnable(GL_MULTISAMPLE_ARB);
3457       }
3458       else if(display.display3D.camera)
3459       {
3460          oglDisplay.depthWrite = false;
3461          glViewport(0,0,display.width,display.height);
3462
3463          glDisable(GL_CULL_FACE);
3464          glDisable(GL_DEPTH_TEST);
3465          glDisable(GL_LIGHTING);
3466          glDisable(GL_FOG);
3467          glDisable(GL_TEXTURE_2D);
3468          glShadeModel(GL_FLAT);
3469          glEnable(GL_BLEND);
3470          glDisable(GL_MULTISAMPLE_ARB);
3471
3472          // *** Restore 2D MODELVIEW Matrix ***
3473          glPopMatrix();
3474
3475          // *** Restore 2D PROJECTION Matrix ***
3476          glMatrixMode(GL_PROJECTION);
3477          glPopMatrix();
3478       }
3479
3480       GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
3481    }
3482
3483    void ApplyMaterial(Display display, Material material, Mesh mesh)
3484    {
3485       //Logf("ApplyMaterial\n");
3486
3487       // Basic Properties
3488       if(material.flags.doubleSided)
3489       {
3490          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3491          glDisable(GL_CULL_FACE);
3492       }
3493       else
3494       {
3495          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3496          glEnable(GL_CULL_FACE);
3497       }
3498
3499       // Fog
3500       if(material.flags.noFog)
3501          glDisable(GL_FOG);
3502       else
3503          glEnable(GL_FOG);
3504
3505       // Maps
3506       if(material.baseMap && mesh.texCoords)
3507       {
3508          Bitmap map = material.baseMap;
3509          glEnable(GL_TEXTURE_2D);
3510          glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3511
3512          glMatrixMode(GL_TEXTURE);
3513          glLoadIdentity();
3514          if(material.uScale && material.vScale)
3515             glScalef(material.uScale, material.vScale, 1);
3516          glMatrixMode(GL_MODELVIEW);
3517
3518          if(material.flags.tile)
3519          {
3520             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3521             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3522          }
3523          else
3524          {
3525             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3526             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3527          }
3528       }
3529       else
3530          glDisable(GL_TEXTURE_2D);
3531
3532       if(mesh.flags.colors)
3533       {
3534          glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3535          glEnable(GL_COLOR_MATERIAL);
3536       }
3537       else
3538       {
3539          glDisable(GL_COLOR_MATERIAL);
3540          {
3541             float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3542             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3543          }
3544          {
3545             float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3546             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3547          }
3548       }
3549       {
3550          float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3551          glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3552       }
3553       {
3554          float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3555          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3556       }
3557
3558       glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3559    }
3560
3561    void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3562    {
3563       OGLMesh oglMesh = mesh.data;
3564       if(oglMesh)
3565       {
3566          if(!mesh.flags.vertices)
3567          {
3568             if(oglMesh.vertices)
3569             {
3570                GLDeleteBuffers(1, &oglMesh.vertices);
3571                oglMesh.vertices = 0;
3572             }
3573             delete mesh.vertices;
3574          }
3575          if(!mesh.flags.normals)
3576          {
3577             if(oglMesh.normals)
3578             {
3579                GLDeleteBuffers(1, &oglMesh.normals);
3580                oglMesh.normals = 0;
3581             }
3582             delete mesh.normals;
3583          }
3584          if(!mesh.flags.texCoords1)
3585          {
3586             if(oglMesh.texCoords)
3587             {
3588                GLDeleteBuffers(1, &oglMesh.texCoords);
3589                oglMesh.texCoords = 0;
3590             }
3591             delete mesh.texCoords;
3592          }
3593          if(!mesh.flags.texCoords2)
3594          {
3595             if(oglMesh.texCoords2)
3596             {
3597                GLDeleteBuffers(1, &oglMesh.texCoords2);
3598                oglMesh.texCoords2 = 0;
3599             }
3600             /*
3601             delete mesh.texCoords2;
3602             */
3603          }
3604          if(!mesh.flags.colors)
3605          {
3606             if(oglMesh.colors)
3607             {
3608                GLDeleteBuffers(1, &oglMesh.colors);
3609                oglMesh.colors = 0;
3610             }
3611          }
3612          if(!mesh.flags)
3613          {
3614             delete oglMesh;
3615             mesh.data = null;
3616          }
3617       }
3618    }
3619
3620    bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3621    {
3622       bool result = false;
3623
3624       if(!mesh.data)
3625          mesh.data = OGLMesh { };
3626       if(mesh.data)
3627       {
3628          OGLMesh oglMesh = mesh.data;
3629          if(mesh.nVertices == nVertices)
3630          {
3631             // Same number of vertices, adding features (Leaves the other features pointers alone)
3632             if(mesh.flags != flags)
3633             {
3634                if(!mesh.flags.vertices && flags.vertices)
3635                {
3636                   if(flags.doubleVertices)
3637                   {
3638                      mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3639                   }
3640                   else
3641                      mesh.vertices = new Vector3Df[nVertices];
3642                   if(!oglMesh.vertices)
3643                      GLGenBuffers(1, &oglMesh.vertices);
3644                }
3645                if(!mesh.flags.normals && flags.normals)
3646                {
3647                   if(flags.doubleNormals)
3648                   {
3649                      mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3650                   }
3651                   else
3652                      mesh.normals = new Vector3Df[nVertices];
3653                   if(!oglMesh.normals)
3654                      GLGenBuffers( 1, &oglMesh.normals);
3655                }
3656                if(!mesh.flags.texCoords1 && flags.texCoords1)
3657                {
3658                   mesh.texCoords = new Pointf[nVertices];
3659                   if(!oglMesh.texCoords)
3660                      GLGenBuffers( 1, &oglMesh.texCoords);
3661                }
3662                if(!mesh.flags.colors && flags.colors)
3663                {
3664                   mesh.colors = new ColorRGBAf[nVertices];
3665                   if(!oglMesh.colors)
3666                      GLGenBuffers( 1, &oglMesh.colors);
3667                }
3668             }
3669          }
3670          else
3671          {
3672             // New number of vertices, reallocate all current and new features
3673             flags |= mesh.flags;
3674             if(flags.vertices)
3675             {
3676                if(flags.doubleVertices)
3677                {
3678                   mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3679                }
3680                else
3681                   mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3682                if(!oglMesh.vertices)
3683                   GLGenBuffers(1, &oglMesh.vertices);
3684             }
3685             if(flags.normals)
3686             {
3687                if(flags.doubleNormals)
3688                {
3689                   mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3690                }
3691                else
3692                   mesh.normals = renew mesh.normals Vector3Df[nVertices];
3693                if(!oglMesh.normals)
3694                   GLGenBuffers( 1, &oglMesh.normals);
3695             }
3696             if(flags.texCoords1)
3697             {
3698                mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3699                if(!oglMesh.texCoords)
3700                   GLGenBuffers( 1, &oglMesh.texCoords);
3701             }
3702             if(flags.colors)
3703             {
3704                mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3705                if(!oglMesh.colors)
3706                   GLGenBuffers( 1, &oglMesh.colors);
3707             }
3708          }
3709          result = true;
3710       }
3711       return result;
3712    }
3713
3714    void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3715    {
3716       OGLMesh oglMesh = mesh.data;
3717       if(!flags) flags = mesh.flags;
3718
3719       if(vboAvailable)
3720       {
3721          if(flags.vertices && oglMesh.vertices)
3722          {
3723             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices);
3724             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 );
3725          }
3726
3727          if(flags.normals && oglMesh.normals)
3728          {
3729             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
3730             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 );
3731          }
3732
3733          if(flags.texCoords1 && oglMesh.texCoords)
3734          {
3735             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
3736             GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(Pointf), mesh.texCoords, GL_STATIC_DRAW_ARB );
3737          }
3738
3739          if(flags.colors && oglMesh.colors)
3740          {
3741             GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
3742             GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, GL_STATIC_DRAW_ARB );
3743          }
3744
3745          GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
3746       }
3747    }
3748
3749    bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3750    {
3751       bool result = true;
3752
3753         return result;
3754    }
3755
3756    void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3757    {
3758       if(oglIndices)
3759       {
3760          if(oglIndices.buffer)
3761             GLDeleteBuffers(1, &oglIndices.buffer);
3762          delete oglIndices.indices;
3763          delete oglIndices;
3764       }
3765    }
3766
3767    void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3768    {
3769       OGLIndices oglIndices = OGLIndices { };
3770       if(oglIndices)
3771       {
3772          oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3773          GLGenBuffers( 1, &oglIndices.buffer);
3774          oglIndices.nIndices = nIndices;
3775       }
3776       return oglIndices;
3777    }
3778
3779    void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3780    {
3781       if(vboAvailable)
3782       {
3783          GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
3784          GLBufferData( indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, GL_ELEMENT_ARRAY_BUFFER_ARB, nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3785             oglIndices.indices, GL_STATIC_DRAW_ARB);
3786          GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3787       }
3788    }
3789
3790    uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3791    {
3792
3793       return oglIndices.indices;
3794    }
3795
3796    void SelectMesh(Display display, Mesh mesh)
3797    {
3798       //Logf("SelectMesh\n");
3799
3800 #if !defined( __ANDROID__) && !defined(__APPLE__)
3801
3802 #if defined(__WIN32__)
3803       if(glUnlockArraysEXT)
3804 #endif
3805          if(!vboAvailable && display.display3D.mesh)
3806             glUnlockArraysEXT();
3807
3808 #endif
3809       if(mesh)
3810       {
3811          OGLMesh oglMesh = mesh.data;
3812
3813          // *** Vertex Stream ***
3814          glEnableClientState(GL_VERTEX_ARRAY);
3815          if(!display.display3D.collectingHits && oglMesh)
3816          {
3817             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices );
3818             glVertexPointer(3, mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT, 0, vboAvailable ? null : mesh.vertices);
3819
3820             // *** Normals Stream ***
3821             if(mesh.normals)
3822             {
3823                glEnableClientState(GL_NORMAL_ARRAY);
3824                GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
3825                glNormalPointer(mesh.flags.doubleNormals ? GL_DOUBLE : GL_FLOAT, 0, vboAvailable ? null : mesh.normals);
3826             }
3827             else
3828                glDisableClientState(GL_NORMAL_ARRAY);
3829
3830             // *** Texture Coordinates Stream ***
3831             if(mesh.texCoords)
3832             {
3833                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3834                GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
3835                glTexCoordPointer(2, GL_FLOAT, 0, vboAvailable ? null : mesh.texCoords);
3836             }
3837             else
3838                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3839
3840             // *** Color Stream ***
3841             if(mesh.colors)
3842             {
3843                glEnableClientState(GL_COLOR_ARRAY);
3844                GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
3845                glColorPointer(4, GL_FLOAT, 0, vboAvailable ? null : mesh.colors);
3846             }
3847             else
3848                glDisableClientState(GL_COLOR_ARRAY);
3849
3850          }
3851          else
3852          {
3853             GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
3854             glVertexPointer(3,mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT,0,mesh.vertices);
3855             if(mesh.normals && !display.display3D.collectingHits)
3856             {
3857                glEnableClientState(GL_NORMAL_ARRAY);
3858                glNormalPointer(mesh.flags.doubleNormals ? GL_DOUBLE : GL_FLOAT, 0, mesh.normals);
3859             }
3860             else
3861                glDisableClientState(GL_NORMAL_ARRAY);
3862             if(mesh.texCoords && !display.display3D.collectingHits)
3863             {
3864                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3865                glTexCoordPointer(2, GL_FLOAT, 0, mesh.texCoords);
3866             }
3867             else
3868                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3869             if(mesh.colors && !display.display3D.collectingHits)
3870             {
3871                glEnableClientState(GL_COLOR_ARRAY);
3872                glColorPointer(4, GL_FLOAT, 0, mesh.colors);
3873             }
3874             else
3875                glDisableClientState(GL_COLOR_ARRAY);
3876          }
3877
3878 #if !defined(__ANDROID__) && !defined(__APPLE__)
3879
3880 #if defined(__WIN32__)
3881          if(glLockArraysEXT)
3882 #endif
3883             if(!vboAvailable)
3884                glLockArraysEXT(0, mesh.nVertices);
3885
3886 #endif
3887       }
3888       else
3889          GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
3890    }
3891
3892    void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3893    {
3894       //Logf("DrawPrimitives\n");
3895
3896       if(primitive->type.vertexRange)
3897          glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3898       else
3899       {
3900          //    *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3901          // HACK TO SPEED THINGS UP...
3902 #ifndef __ANDROID__
3903          GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3904          if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3905          {
3906             int c;
3907             glBegin(primitiveTypes[primitive->type.primitiveType]);
3908             if(primitive->data)
3909             {
3910                OGLIndices oglIndices = primitive->data;
3911                MeshFeatures flags = mesh.flags;
3912                for(c = 0; c<primitive->nIndices; c++)
3913                {
3914                   uint16 index = ((uint16 *) oglIndices.indices)[c];
3915                   if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3916                   if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3917                   if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3918                   glVertex3fv((float *)&mesh.vertices[index]);
3919                }
3920             }
3921             glEnd();
3922          }
3923          else
3924 #endif
3925          {
3926             OGLIndices oglIndices = primitive->data;
3927
3928             if(!display.display3D.collectingHits && vboAvailable && oglIndices)
3929             {
3930                GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
3931                glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3932                   primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
3933                GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3934             }
3935             else
3936                glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3937                   primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, oglIndices ? oglIndices.indices : primitive->indices);
3938          }
3939       }
3940    }
3941
3942    void PushMatrix(Display display)
3943    {
3944       glPushMatrix();
3945    }
3946
3947    void PopMatrix(Display display, bool setMatrix)
3948    {
3949       glPopMatrix();
3950    }
3951
3952    void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3953    {
3954       Matrix matrix = transMatrix;
3955       Camera camera = useCamera ? display.display3D.camera : null;
3956
3957       if(viewSpace)
3958       {
3959          glLoadIdentity();
3960          glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3961       }
3962       else if(camera)
3963       {
3964          glTranslated(
3965             matrix.m[3][0] - camera.cPosition.x,
3966             matrix.m[3][1] - camera.cPosition.y,
3967             matrix.m[3][2] - camera.cPosition.z);
3968       }
3969       else
3970          glTranslated(
3971             matrix.m[3][0],
3972             matrix.m[3][1],
3973             matrix.m[3][2]);
3974
3975       matrix.m[3][0] = 0;
3976       matrix.m[3][1] = 0;
3977       matrix.m[3][2] = 0;
3978
3979       glMultMatrixd(matrix.array);
3980    }
3981 #endif
3982 }
3983
3984 public void UseSingleGLContext(bool useSingle)
3985 {
3986    useSingleGLContext = useSingle;
3987 }
3988
3989 default dllexport void *
3990 #if defined(__WIN32__)
3991 __attribute__((stdcall))
3992 #endif
3993 IS_GLGetContext(DisplaySystem displaySystem)
3994 {
3995    if(displaySystem)
3996    {
3997 #if defined(__WIN32__)
3998       OGLSystem system = displaySystem.driverData;
3999       return system.glrc;
4000 #elif !defined(__ANDROID__)
4001       OGLSystem system = displaySystem.driverData;
4002       return system.glContext;
4003 #else
4004       return eglContext;
4005 #endif
4006    }
4007    return null;
4008 }
4009
4010 #endif