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