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