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