ecere/gfx/drivers/OpenGL: Fixed LockArraysEXT warnings on Linux
[sdk] / ecere / src / gfx / drivers / OpenGLDisplayDriver.ec
1 // #define DIAGNOSTICS
2
3 namespace gfx::drivers;
4
5 #if defined(_GLES)
6    #define ES1_1
7 #else
8    #define SHADERS
9 #endif
10
11 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
12 #  if defined(SHADERS)
13 #     include "gl_core_3_3.h"
14 #  else
15 #     include "gl_compat_4_4.h"
16 #  endif
17 #endif
18
19 #if defined(__ANDROID__) || defined(__ODROID__)
20 import "egl"
21 #endif
22
23 import "glab"
24 import "immediate"
25 import "matrixStack"
26 import "shading"
27
28 #define GL_BGRA_EXT  0x80E1
29
30 #ifdef SHADERS
31
32 #undef glEnableClientState
33 #undef glDisableClientState
34 #undef GL_VERTEX_ARRAY
35 #undef GL_NORMAL_ARRAY
36 #undef GL_TEXTURE_COORD_ARRAY
37 #undef GL_COLOR_ARRAY
38
39 #define glEnableClientState      glEnableVertexAttribArray
40 #define glDisableClientState     glDisableVertexAttribArray
41 #define GL_VERTEX_ARRAY          GLBufferContents::vertex
42 #define GL_NORMAL_ARRAY          GLBufferContents::normal
43 #define GL_TEXTURE_COORD_ARRAY   GLBufferContents::texCoord
44 #define GL_COLOR_ARRAY           GLBufferContents::color
45
46 #endif
47
48 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
49 // #define USEPBUFFER
50 #if defined(__unix__) || defined(__APPLE__)
51
52    #if !defined(__MINGW32__)
53       #define GL_GLEXT_PROTOTYPES
54    #endif
55
56    #define pointer _pointer
57
58
59    #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
60
61       #define property _property
62       #define new _new
63       #define class _class
64
65       #define Window    X11Window
66       #define Cursor    X11Cursor
67       #define Font      X11Font
68       #define Display   X11Display
69       #define Time      X11Time
70       #define KeyCode   X11KeyCode
71       #define Picture   X11Picture
72       #define Glyph     X11Glyph
73       #define uint _uint
74
75       #include <X11/Xlib.h>
76       #include <X11/Xutil.h>
77       #include <GL/glx.h>
78       #include <X11/extensions/XShm.h>
79       #include <sys/ipc.h>
80       #include <sys/shm.h>
81       #include <X11/extensions/Xrender.h>
82       #include <X11/extensions/shape.h>
83
84       #undef Window
85       #undef Cursor
86       #undef Font
87       #undef Display
88       #undef Time
89       #undef KeyCode
90       #undef Picture
91       #undef Glyph
92       #undef uint
93       #undef new
94       #undef property
95       #undef class
96
97    #endif
98
99 #endif
100
101 #if defined(__APPLE__)
102    #include <OpenGl/gl.h>
103 #endif
104
105 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
106
107    #if defined(__WIN32__)
108       //#define WIN32_LEAN_AND_MEAN
109       #undef _WIN32_WINNT
110       #define _WIN32_WINNT 0x0502
111       #define String Sting_
112       #include <windows.h>
113       #undef String
114    #endif
115
116    #if defined(__ANDROID__) || defined(__ODROID__)
117       #if defined(__ODROID__) && !defined(ES1_1)
118          #define ES1_1
119       #endif
120
121       #define uint _uint
122       #define property _property
123       #define new _new
124       #define class _class
125       #define Window    X11Window
126       #define Cursor    X11Cursor
127       #define Font      X11Font
128       #define Display   X11Display
129       #define Time      X11Time
130       #define KeyCode   X11KeyCode
131       #define Picture   X11Picture
132       #define Bool      X11Bool
133
134       #include <GLES/gl.h>
135
136       #undef Bool
137       #undef Picture
138       #undef Window
139       #undef Cursor
140       #undef Font
141       #undef Display
142       #undef Time
143       #undef KeyCode
144       #undef uint
145       #undef new
146       #undef property
147       #undef class
148
149    #elif defined(__EMSCRIPTEN__)
150       #define ES2
151       // #define ES1_1
152
153       #define property _property
154       #define uint _uint
155
156       //#include <GL/gl.h>
157       //#include <GLES/gl.h>
158       #include <GLES2/gl2.h>
159
160       #include <emscripten/emscripten.h>
161       #include <emscripten/html5.h>
162
163       #undef property
164       #undef uint
165
166    #else
167       #include <GL/gl.h>
168    #endif
169
170    #undef pointer
171
172    import "Display"
173
174    #if defined(__unix__) || defined(__APPLE__)
175
176    #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
177    import "XInterface"
178    #endif
179
180    #endif
181
182    #define glLoadMatrix glLoadMatrixd
183    #define glMultMatrix glMultMatrixd
184    #define glGetMatrix  glGetDoublev
185    #define glTranslate glTranslated
186    #define glScale glScaled
187
188 /*
189 #define glVertex3v glVertex3dv
190 #define glNormal3v glNormal3dv
191 */
192
193 /*
194 //#ifdef VERTEX_FORMAT_DOUBLE
195
196 #define glLoadMatrix glLoadMatrixd
197 #define glMultMatrix glMultMatrixd
198 #define glGetMatrix  glGetDoublev
199 #define glVertex3v glVertex3dv
200 #define glNormal3v glNormal3dv
201 #define glTranslate glTranslated
202 #define glScale glScaled
203 //#define GL_VERTEX_FORMAT   GL_DOUBLE
204
205 #else
206
207 #define glLoadMatrix glLoadMatrixf
208 #define glMultMatrix glMultMatrixf
209 #define glGetMatrix  glGetFloatv
210 #define glVertex3v glVertex3fv
211 #define glNormal3v glNormal3fv
212 #define glTranslate glTranslatef
213 #define glScale glScalef
214 //#define GL_VERTEX_FORMAT   GL_FLOAT
215
216 #endif
217 */
218
219 #define GL_ARRAY_BUFFER_ARB            0x8892
220 #define GL_ELEMENT_ARRAY_BUFFER_ARB    0x8893
221 #define GL_STATIC_DRAW_ARB             0x88E4
222 #define GL_LIGHT_MODEL_COLOR_CONTROL   0x81F8
223 #define GL_SEPARATE_SPECULAR_COLOR     0x81FA
224
225 #define GL_MULTISAMPLE_ARB             0x809D
226
227 #if defined(__WIN32__)
228    #include "wglDefs.h"
229
230    typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
231    typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
232
233    static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
234    static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
235
236    static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
237    static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
238    static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
239    static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
240    static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
241    static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
242    static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
243    static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
244    static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
245    static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = null;
246    static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = null;
247
248 #else
249
250 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
251 default:
252    GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
253    GLAPI void APIENTRY glUnlockArraysEXT (void);
254 private:
255 #endif
256
257 #if defined(__ANDROID__) || defined(__ODROID__)
258    #define GL_FRAMEBUFFER           GL_FRAMEBUFFER_OES
259    #define GL_RENDERBUFFER          GL_RENDERBUFFER_OES
260    #define GL_COLOR_ATTACHMENT0     GL_COLOR_ATTACHMENT0_OES
261    #define GL_BGRA_EXT           0
262 #endif
263
264 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
265
266    #define GL_POLYGON_STIPPLE 0xFFFF
267    #define GL_LINE_STIPPLE 0xFFFF
268    #define GL_LINE 0xFFFF
269    #define GL_FILL 0xFFFF
270    #define GL_ALL_ATTRIB_BITS 0xFFFF
271    #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
272
273    #define GL_POLYGON      9
274    #define GL_QUADS        7
275
276    //#define GL_QUADS              0
277    #define GL_QUAD_STRIP         0
278    //#define GL_DOUBLE             0
279    //#define GL_UNSIGNED_INT       0
280    //#define GL_FILL               0
281    //#define GL_LINE               0
282    //#define GL_LINE_STIPPLE       0
283    #define GL_UNPACK_ROW_LENGTH  0
284    #define GL_UNPACK_SKIP_PIXELS 0
285    #define GL_UNPACK_SKIP_ROWS   0
286    #define GL_RGBA8              0
287    #define GL_PACK_ROW_LENGTH    0
288    #define GL_PACK_SKIP_ROWS     0
289    #define GL_PACK_SKIP_PIXELS   0
290 #endif
291
292 #endif
293
294
295 #if defined(__ANDROID__) || defined(__ODROID__)
296    #define glBindFramebuffer        glBindFramebufferOES
297    #define glBindRenderbuffer       glBindRenderbufferOES
298    #define glFramebufferTexture2D   glFramebufferTexture2DOES
299    #define glGenFramebuffers        glGenFramebuffersOES
300    #define glGenRenderbuffers       glGenRenderbuffersOES
301    #define glDeleteFramebuffers     glDeleteFramebuffersOES
302    #define glDeleteRenderbuffers    glDeleteRenderbuffersOES
303 #endif
304
305 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
306    #define GL_INT                                  0x1404
307    #define GL_UNSIGNED_INT                         0x1405
308    #define GL_DOUBLE                               0x140A
309    #define APIENTRY
310 #endif
311
312 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
313
314    #undef glRecti
315    #undef glBegin
316    #undef glTexCoord2i
317    #undef glVertex2i
318    #undef glTexCoord2d
319    #undef glVertex2d
320    #undef glTexCoord2f
321    #undef glVertex2f
322    #undef glEnd
323    #undef glColor3f
324    #undef glColor4ub
325    #undef glColor4fv
326    #undef glNormal3fv
327    #undef glNormal3f
328    #undef glTexCoord2fv
329    #undef glVertex3d
330    #undef glVertex3dv
331    #undef glVertex3f
332    #undef glVertex3fv
333
334    #undef glLoadMatrixd
335    #undef glMultMatrixd
336    #undef glFrustum
337    #undef glOrtho
338    #undef glScaled
339    #undef glScalef
340    #undef glTranslated
341    #undef glRotated
342    #undef glMatrixMode
343    #undef glLoadIdentity
344    #undef glPushMatrix
345    #undef glPopMatrix
346
347    #undef glLineStipple
348    #undef glColorMaterial
349    #undef glLightModeli
350
351    #define glRecti               glimtkRecti
352    #define glBegin               glimtkBegin
353    #define glTexCoord2i          glimtkTexCoord2i
354    #define glVertex2i            glimtkVertex2i
355    #define glTexCoord2d          glimtkTexCoord2d
356    #define glVertex2d            glimtkVertex2d
357    #define glTexCoord2f          glimtkTexCoord2f
358    #define glVertex2f            glimtkVertex2f
359    #define glEnd                 glimtkEnd
360    #define glColor3f             glimtkColor3f
361    #define glColor4ub            glimtkColor4ub
362    #define glColor4fv            glimtkColor4fv
363    #define glNormal3fv           glimtkNormal3fv
364    #define glNormal3f            glimtkNormal3f
365    #define glTexCoord2fv         glimtkTexCoord2fv
366    #define glVertex3d            glimtkVertex3d
367    #define glVertex3dv           glimtkVertex3dv
368    #define glVertex3f            glimtkVertex3f
369    #define glVertex3fv           glimtkVertex3fv
370
371    #define glLoadMatrixd         glmsLoadMatrixd
372    #define glMultMatrixd         glmsMultMatrixd
373    #define glFrustum             glmsFrustum
374    #define glOrtho               glmsOrtho
375    #define glScaled              glmsScaled
376    #define glScalef              glmsScaled
377    #define glTranslated          glmsTranslated
378    #define glRotated             glmsRotated
379    #define glMatrixMode          glmsMatrixMode
380    #define glLoadIdentity        glmsLoadIdentity
381    #define glPushMatrix          glmsPushMatrix
382    #define glPopMatrix           glmsPopMatrix
383
384    #define glLineStipple         glesLineStipple
385    #define glColorMaterial       glesColorMaterial
386    #define glLightModeli         glesLightModeli
387
388 #endif
389
390 public void glesColorMaterial(int a, int b)
391 {
392    PrintLn("glColorMaterial stub");
393 }
394
395 static GLuint stippleTexture;
396 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
397 static bool stippleEnabled;
398 #endif
399
400 public void glesLineStipple( int i, unsigned short j )
401 {
402    uint texture[1*16];
403    int x;
404    for(x = 0; x < 16; x++)
405    {
406       bool v = (j & (1 << x)) != 0;
407       texture[x] = v ? 0xFFFFFFFF : 0;
408    }
409    if(!stippleTexture)
410       glGenTextures(1, &stippleTexture);
411    glBindTexture(GL_TEXTURE_2D, stippleTexture);
412    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
413
414    // TOOD: Special shading code for stippling?
415    GLSetupTexturing(true);
416    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
417    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
418    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
419    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
420    glMatrixMode(GL_TEXTURE);
421    glLoadIdentity();
422    //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
423    glScaled(i/16.0, 1, 1.0f);
424    glTranslated(0.5, 0.5, 0);
425    glMatrixMode(MatrixMode::projection);
426 }
427
428 public void glesLightModeli( unsigned int pname, int param )
429 {
430 #if !defined(SHADERS)
431    if(pname == GL_LIGHT_MODEL_TWO_SIDE)
432       glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
433 #endif
434 }
435
436 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
437 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
438 #endif
439
440 #if defined(__ANDROID__) || defined(__ODROID__)
441 void glFogi( unsigned int pname, int param ) { }
442 void glPolygonMode( unsigned int i, unsigned int j ) { }
443
444
445 // *** Picking won't be supported for now ***
446 void glPushName( unsigned int i ) { }
447 void glLoadName( unsigned int i ) { }
448 void glPopName() { }
449
450 // Probably replace by regular glBlendFunc ...
451 void glBlendFuncSeparate(int a, int b, int c, int d)
452 {
453    glBlendFunc(a, b);
454 }
455
456 // For direct pixel blitting...
457 void glRasterPos2d(double a, double b) { }
458 void glPixelZoom(float a, float b) { }
459 void glDrawPixels(int a, int b, int c, int d, void * e) { }
460
461 #endif
462
463 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
464 static int primitiveTypes[RenderPrimitiveType] =
465 {
466    GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN,
467 #if defined(SHADERS) || defined(ES1_1) || defined(ES2)
468    GL_TRIANGLE_FAN,     // NOTE: This will only work for single quads
469 #else
470    GLIMTKMode::quads,
471 #endif
472    GLIMTKMode::quadStrip,
473    GL_LINE_STRIP
474 };
475 #endif
476
477 public void GLSetupTexturing(bool enable)
478 {
479 #ifdef SHADERS
480    shader_texturing(enable);
481 #else
482    (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
483 #endif
484 }
485
486 public void GLSetupFog(bool enable)
487 {
488 #ifdef SHADERS
489    shader_fog(enable);
490 #else
491    (enable ? glEnable : glDisable)(GL_FOG);
492 #endif
493 }
494
495 public void GLSetupLighting(bool enable)
496 {
497 #if defined(SHADERS)
498    shader_lighting(enable);
499 #else
500    (enable ? glEnable : glDisable)(GL_LIGHTING);
501 #endif
502 }
503
504 // Non OpenGL ES friendly stuff
505
506 #if defined(ES1_1) || defined(ES2)
507
508 //#undef GL_UNSIGNED_INT
509 //#undef GL_DOUBLE
510 #undef GL_INT
511 //#undef GL_POLYGON
512 //#undef GL_QUADS
513 #undef GL_QUAD_STRIP
514 #undef GL_POLYGON_STIPPLE
515 #undef GL_LINE_STIPPLE
516 #undef GL_LINE
517 #undef GL_FILL
518 #undef GL_ALL_ATTRIB_BITS
519 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
520
521 #endif
522
523 static int displayWidth, displayHeight;
524
525 #define GL_CLAMP_TO_EDGE 0x812F
526
527 static bool vboAvailable;
528
529 static bool useSingleGLContext = false;
530 class OGLDisplay : struct
531 {
532 #if defined(__WIN32__)
533    HDC hdc;
534    HGLRC glrc;
535
536    HBITMAP memBitmap;
537    HDC memDC;
538    byte * picture;
539    uint stride;
540    void * pBuffer;
541    /*
542    int imageBuffers[2];
543    byte * pboMemory1, * pboMemory2;
544    */
545 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
546    GLXContext glContext;
547
548    Pixmap pixmap;
549    XShmSegmentInfo shminfo;
550    XImage * image;
551    XShmSegmentInfo shminfoShape;
552    XImage * shapeImage;
553    byte * picture;
554    uint stride;
555    GLXPbuffer pBuffer;
556    X11Picture windowPicture;
557    X11Picture pixmapPicture;
558    Pixmap shapePixmap;
559    X11Picture shapePicture;
560 #endif
561
562    ColorAlpha * flippingBuffer;
563    int flipBufH, flipBufW;
564    bool depthWrite;
565    int x, y;
566 };
567
568 #ifdef _DEBUG
569 static void APIENTRY openglCallbackFunction(GLenum source,
570                                            GLenum type,
571                                            GLuint id,
572                                            GLenum severity,
573                                            GLsizei length,
574                                            const GLchar* message,
575                                            const void* userParam)
576 {
577    PrintLn("---------------------opengl-callback-start------------");
578    PrintLn("message: ", message);
579    PrintLn("type: ");
580    switch (type)
581    {
582       case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
583       case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
584       case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
585       case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
586       case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
587       case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
588    }
589
590    PrintLn("id: ", id);
591    Print("severity: ");
592    switch (severity)
593    {
594       case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
595       case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
596       case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
597    }
598    PrintLn("---------------------opengl-callback-end--------------");
599 }
600 #endif
601
602 class OGLSystem : struct
603 {
604    int maxTextureSize;
605    bool loadingFont;
606    bool pow2textures;
607 #if defined(__WIN32__)
608    PIXELFORMATDESCRIPTOR pfd;
609    int format;
610    HDC hdc;
611    HGLRC glrc;
612    HWND hwnd;
613 #elif defined(__EMSCRIPTEN__)
614    EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
615 #elif !defined(__ANDROID__) && !defined(__ODROID__)
616    XVisualInfo * visualInfo;
617    GLXContext glContext;
618    GLXDrawable glxDrawable;
619 #endif
620 };
621
622 class OGLSurface : struct
623 {
624    Font font;
625    bool opaqueText;
626    int xOffset;
627    bool writingText;
628    bool writingOutline;
629
630    float foreground[4], background[4], bitmapMult[4];
631 } OGLSurface;
632
633 class OGLMesh : struct
634 {
635    GLAB vertices;
636    GLAB normals;
637    GLAB texCoords;
638    GLAB texCoords2;
639    GLAB colors;
640 };
641
642 class OGLIndices : struct
643 {
644    uint16 * indices;
645    GLEAB buffer;
646    uint nIndices;
647 };
648
649 int current;
650 void * previous;
651
652 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
653 #ifdef _DEBUG
654 static void setupDebugging()
655 {
656    if(glDebugMessageCallback)
657    {
658       GLuint unusedIds = 0;
659
660       glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
661       /*
662       glDebugMessageCallback(openglCallbackFunction, null);
663       glDebugMessageControl(GL_DONT_CARE,
664           GL_DONT_CARE,
665           GL_DONT_CARE,
666           0,
667           &unusedIds,
668           GL_TRUE);
669       */
670    }
671 }
672 #endif
673 #endif
674
675 #if defined(__WIN32__)
676 static HGLRC winCreateContext(HDC hdc)
677 {
678    HGLRC result = 0;
679 #ifdef SHADERS
680    if(wglCreateContextAttribsARB)
681    {
682       int attribs[] =
683       {
684          WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
685          WGL_CONTEXT_MINOR_VERSION_ARB, 4,
686          WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | */WGL_CONTEXT_DEBUG_BIT_ARB,
687          WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB /*WGL_CONTEXT_CORE_PROFILE_BIT_ARB*/,
688          0,0
689       };
690       result = wglCreateContextAttribsARB(hdc, null, attribs);
691       if(!result)
692       {
693          attribs[1] = 2;
694          attribs[3] = 0;
695          attribs[7] = 0;
696          result = wglCreateContextAttribsARB(hdc, null, attribs);
697       }
698    }
699 #endif
700    if(!result)
701       result = wglCreateContext(hdc);
702    return result;
703 }
704 #endif
705
706 class OpenGLDisplayDriver : DisplayDriver
707 {
708    class_property(name) = "OpenGL";
709
710    bool LockSystem(DisplaySystem displaySystem)
711    {
712 #if defined(__EMSCRIPTEN__)
713       OGLSystem oglSystem = displaySystem.driverData;
714       emscripten_webgl_make_context_current(oglSystem.glc);
715 #elif !defined(__ANDROID__) && !defined(__ODROID__)
716       OGLSystem oglSystem = displaySystem.driverData;
717       if(useSingleGLContext) return true;
718    #if defined(__WIN32__)
719       wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
720    #elif defined(__unix__) || defined(__APPLE__)
721       //if(previous) return true;
722       // printf("Making SYSTEM current\n");
723       glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
724       //previous = oglSystem.glContext;
725    #endif
726 #endif
727       GLABBindBuffer(GL_ARRAY_BUFFER, 0);
728       GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
729       return true;
730    }
731
732    void UnlockSystem(DisplaySystem displaySystem)
733    {
734       if(useSingleGLContext) return;
735    #if defined(__WIN32__)
736       wglMakeCurrent(null, null);
737    #elif defined(__unix__) || defined(__APPLE__)
738       // printf("Making NULL current\n");
739       #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
740       #else
741       glXMakeCurrent(xGlobalDisplay, None, null);
742       #endif
743       // previous = null;
744    #endif
745    }
746
747    bool Lock(Display display)
748    {
749 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
750       OGLDisplay oglDisplay = display.driverData;
751       if(useSingleGLContext) return true;
752    #if defined(__WIN32__)
753       wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
754    #elif defined(__unix__) || defined(__APPLE__)
755       // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
756       // printf("   Making DISPLAY current\n");
757       glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
758    #endif
759 #endif
760       GLABBindBuffer(GL_ARRAY_BUFFER, 0);
761       GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
762       return true;
763    }
764
765    void Unlock(Display display)
766    {
767       if(useSingleGLContext) return;
768       //printf("   Making NULL current\n");
769       //glXMakeCurrent(xGlobalDisplay, None, null);
770       // if(previous)
771          LockSystem(display.displaySystem);
772    }
773
774    void DestroyDisplay(Display display)
775    {
776       OGLDisplay oglDisplay = display.driverData;
777
778       if(oglDisplay)
779       {
780    #if defined(__WIN32__)
781          wglMakeCurrent( null, null );
782
783          if(oglDisplay.glrc)
784             wglDeleteContext(oglDisplay.glrc);
785
786          if(oglDisplay.hdc && oglDisplay.pBuffer)
787             wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
788
789          if(oglDisplay.pBuffer)
790             wglDestroyPbufferARB(oglDisplay.pBuffer);
791
792          if(oglDisplay.hdc)
793             ReleaseDC(display.window, oglDisplay.hdc);
794
795          if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
796          if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
797
798    #elif defined(__unix__) || defined(__APPLE__)
799       #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
800       #else
801          if(oglDisplay.shapePixmap)
802             XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
803          if(oglDisplay.pixmap)
804             XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
805          if(oglDisplay.image)
806          {
807             if(oglDisplay.shminfoShape.shmid != -1)
808             {
809                XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
810                if(oglDisplay.shminfo.shmaddr != (void *)-1)
811                   shmdt(oglDisplay.shminfo.shmaddr);
812                shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
813             }
814          }
815          if(oglDisplay.shapeImage)
816          {
817             if(oglDisplay.shminfoShape.shmid != -1)
818             {
819                XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
820                if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
821                   shmdt(oglDisplay.shminfoShape.shmaddr);
822                shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
823             }
824             XDestroyImage(oglDisplay.shapeImage);
825             oglDisplay.shapeImage = None;
826          }
827
828          glXMakeCurrent(xGlobalDisplay, None, null);
829
830          if(oglDisplay.glContext)
831             glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
832       #endif
833    #endif
834          delete oglDisplay.flippingBuffer;
835          delete oglDisplay;
836          display.driverData = null;
837       }
838    }
839
840    void ::CheckExtensions(OGLSystem oglSystem)
841    {
842       const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
843 #ifdef DIAGNOSTICS
844       printf("extensions: %s\n", extensions);
845 #endif
846
847       oglSystem.pow2textures = (extensions && strstr(extensions, "GL_ARB_texture_non_power_of_two")) ? false : true;
848       glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
849    }
850
851    bool CreateDisplaySystem(DisplaySystem displaySystem)
852    {
853       bool result = false;
854       OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
855
856 #ifdef DIAGNOSTICS
857       PrintLn("OpenGL driver's CreateDisplaySystem()");
858 #endif
859
860    #ifdef __WIN32__
861       oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
862
863       oglSystem.hdc = GetDC(oglSystem.hwnd);
864       if(oglSystem.hdc)
865       {
866
867          oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
868          oglSystem.pfd.nVersion = 1;
869          oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
870          oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
871          oglSystem.pfd.cColorBits = 24;
872          oglSystem.pfd.cAlphaBits = 8;
873          oglSystem.pfd.cDepthBits = 24;
874          oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
875
876          oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
877          DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
878
879          if(oglSystem.pfd.cColorBits > 8)
880          {
881             SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
882             oglSystem.glrc = wglCreateContext(oglSystem.hdc);
883             if(oglSystem.glrc)
884             {
885                wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
886
887                wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
888                wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
889                wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
890                wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
891                wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
892                wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
893                wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
894                wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
895                wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
896                wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
897                wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
898
899                glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
900                glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
901
902                // eSystem_LoggingMode(LOG_MSGBOX, null);
903
904                if(wglChoosePixelFormatARB)
905                {
906                   int pixelFormat;
907                   int valid;
908                   int numFormats;
909                   float fAttributes[] = {0,0};
910                   int iAttributes[] =
911                   {
912                      WGL_DRAW_TO_WINDOW_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_TRUE,
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                      }
940                   }
941                   if(valid && numFormats)
942                   {
943                      oglSystem.format = pixelFormat;
944                      wglMakeCurrent(null, null);
945                      wglDeleteContext(oglSystem.glrc);
946
947                      // *** DescribePixelFormat does not support WGL pixel formats! ***
948                      //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
949                      SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
950                      //Log("Successfully set pixel format\n");
951
952 #ifdef DIAGNOSTICS
953                      PrintLn("winCreateContext()");
954 #endif
955                      oglSystem.glrc = winCreateContext(oglSystem.hdc);
956 #ifdef DIAGNOSTICS
957                      PrintLn("wglMakeCurrent()");
958 #endif
959                      wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
960                   }
961                }
962                /*else
963                   eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
964
965                result = true;
966
967                wglMakeCurrent(null, null);
968
969                //eSystem_DumpErrors(true);
970             }
971          }
972       }
973    #elif defined(__unix__) || defined(__APPLE__)
974       vboAvailable = true;
975       #if defined(__ANDROID__) || defined(__ODROID__)
976          #if defined(__ANDROID__)
977          egl_init_display(guiApp.desktop.windowHandle);
978          #elif defined(__ODROID__)
979          egl_init_display((uint)displaySystem.window);
980          CheckExtensions(oglSystem);
981          #endif
982
983          // TODO: Clean this up? Needed here?
984          glEnableClientState(GL_VERTEX_ARRAY);
985          /*
986          // Initialize GL state.
987          glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
988          glEnable(GL_CULL_FACE);
989          glShadeModel(GL_SMOOTH);
990          glDisable(GL_DEPTH_TEST);
991          */
992          glDisable(GL_CULL_FACE);
993          glDisable(GL_DEPTH_TEST);
994
995          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
996          glEnable(GL_BLEND);
997
998          matrixStack[0][0].Identity();
999          matrixStack[1][0].Identity();
1000          matrixStack[2][0].Identity();
1001
1002          glmsMatrixMode(GL_MODELVIEW);
1003          glScaled(1.0, 1.0, -1.0);
1004          glmsMatrixMode(GL_PROJECTION);
1005          glShadeModel(GL_FLAT);
1006
1007          glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1008          glFogi(GL_FOG_MODE, GL_EXP);
1009          glFogf(GL_FOG_DENSITY, 0);
1010          glEnable(GL_NORMALIZE);
1011          glDepthFunc(GL_LESS);
1012          glClearDepth(1.0);
1013          glDisable(GL_MULTISAMPLE_ARB);
1014
1015          glViewport(0,0,eglWidth,eglHeight);
1016          glmsLoadIdentity();
1017          glOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
1018
1019          glabCurArrayBuffer = 0;
1020          glabCurElementBuffer = 0;
1021
1022          result = true;
1023       #elif defined(__EMSCRIPTEN__)
1024          {
1025             EmscriptenWebGLContextAttributes attribs = { 0 };
1026             attribs.depth = 1;
1027             attribs.antialias = 1;
1028
1029             /*
1030               EM_BOOL alpha;
1031               EM_BOOL depth;
1032               EM_BOOL stencil;
1033               EM_BOOL antialias;
1034               EM_BOOL premultipliedAlpha;
1035               EM_BOOL preserveDrawingBuffer;
1036               EM_BOOL preferLowPowerToHighPerformance;
1037               EM_BOOL failIfMajorPerformanceCaveat;
1038               int majorVersion;
1039               int minorVersion;
1040               EM_BOOL enableExtensionsByDefault;
1041               */
1042
1043             emscripten_webgl_init_context_attributes(&attribs);
1044             oglSystem.pow2textures = true;
1045             oglSystem.maxTextureSize = 16384;
1046             oglSystem.glc = emscripten_webgl_create_context("canvas", &attribs);
1047             if(emscripten_webgl_make_context_current(oglSystem.glc) == EMSCRIPTEN_RESULT_SUCCESS)
1048                result = true;
1049
1050             /*glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1051             glEnable(GL_BLEND);*/
1052          }
1053       #else
1054       {
1055          X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1056          XSetWindowAttributes attr;
1057          unsigned long mask;
1058
1059          int attrList[] =
1060          {
1061       #ifndef ECERE_MINIGLX
1062             GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1063       #endif
1064             GLX_RGBA,
1065             GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1066             GLX_DOUBLEBUFFER,
1067             None
1068          };
1069          oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay,  DefaultScreen( xGlobalDisplay ), attrList );
1070          attr.background_pixel = 0;
1071          attr.border_pixel = 0;
1072          attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1073          attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1074          mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1075
1076          oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1077             oglSystem.visualInfo->visual, mask, &attr );
1078       }
1079       if(oglSystem.visualInfo)
1080       {
1081          oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1082          if(oglSystem.glContext)
1083          {
1084             glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1085             // Setup Extensions
1086             // CheckExtensions(oglSystem);
1087             glXMakeCurrent(xGlobalDisplay, None, null);
1088             result = true;
1089          }
1090       }
1091       #endif
1092    #endif
1093
1094       displaySystem.flags.alpha = true;
1095       displaySystem.flags.flipping = true;
1096       displaySystem.pixelFormat = pixelFormat888;
1097       return result;
1098    }
1099
1100    void DestroyDisplaySystem(DisplaySystem displaySystem)
1101    {
1102       OGLSystem oglSystem = displaySystem.driverData;
1103       if(stippleTexture)
1104       {
1105          glDeleteTextures(1, &stippleTexture);
1106          stippleTexture = 0;
1107       }
1108
1109       glimtkTerminate();
1110
1111    #if defined(__WIN32__)
1112       wglMakeCurrent( null, null );
1113
1114       if(oglSystem.glrc)
1115          wglDeleteContext(oglSystem.glrc);
1116
1117       if(oglSystem.hdc)
1118          ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1119       DestroyWindow(oglSystem.hwnd);
1120
1121    #elif defined(__unix__) || defined(__APPLE__)
1122       #if defined(__ANDROID__) || defined(__ODROID__)
1123          egl_term_display();
1124       #elif defined(__EMSCRIPTEN__)
1125          emscripten_webgl_destroy_context(oglSystem.glc);
1126       #else
1127       if(oglSystem.visualInfo)
1128       {
1129    #ifdef   ECERE_MINIGLX
1130          __miniglx_XFree(oglSystem.visualInfo);
1131    #else
1132          XFree(oglSystem.visualInfo);
1133    #endif
1134       }
1135
1136       if(oglSystem.glxDrawable)
1137       {
1138          XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1139          oglSystem.glxDrawable = 0;
1140       }
1141       #endif
1142    #endif
1143       delete oglSystem;
1144    }
1145
1146    static bool ::initialDisplaySetup(Display display)
1147    {
1148       bool result = true;
1149       #ifdef SHADERS
1150       loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1151       #endif
1152       glEnableClientState(GL_VERTEX_ARRAY);
1153
1154       GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1155       GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1156
1157 #if defined(__WIN32__)
1158       if(glBlendFuncSeparate)
1159          glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1160       else
1161          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1162 #else
1163       glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1164 #endif
1165       glEnable(GL_BLEND);
1166
1167       glMatrixMode(MatrixMode::modelView);
1168       glLoadIdentity(); // For setting up GLES stack
1169       glScaled(1.0, 1.0, -1.0);
1170       // glTranslatef(0.375f, 0.375f, 0.0f);
1171       // glTranslatef(-0.625f, -0.625f, 0.0f);
1172       glMatrixMode(MatrixMode::projection);
1173 #if !defined(EM_MODE) && !defined(SHADERS)
1174       glShadeModel(GL_FLAT);
1175
1176       // #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1177
1178       // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1179
1180       glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1181       glFogi(GL_FOG_MODE, GL_EXP);
1182       glFogf(GL_FOG_DENSITY, 0);
1183       glEnable(GL_NORMALIZE);
1184 #endif
1185       glDepthFunc(GL_LESS);
1186       glClearDepth(1.0);
1187       glDisable(GL_MULTISAMPLE_ARB);
1188 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1189       display.ambient = Color { 50,50,50 };
1190 #endif
1191       return result;
1192    }
1193
1194    bool CreateDisplay(Display display)
1195    {
1196       bool result = false;
1197       OGLDisplay oglDisplay = display.driverData;
1198 #if !defined(__ANDROID__) && !defined(__ODROID__)
1199       OGLSystem oglSystem = display.displaySystem.driverData;
1200 #endif
1201
1202       if(!oglDisplay)
1203          oglDisplay = display.driverData = OGLDisplay { };
1204       //printf("Inside CreateDisplay\n");
1205
1206 #if defined(__WIN32__) || defined(USEPBUFFER)
1207       if(!display.alphaBlend)
1208 #endif
1209       {
1210 #if defined(__WIN32__)
1211          oglDisplay.hdc = GetDC(display.window);
1212          SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1213          if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1214          {
1215             wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1216             wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1217             result = true;
1218          }
1219          else
1220             ReleaseDC(display.window, oglDisplay.hdc);
1221 #elif defined(__unix__) || defined(__APPLE__)
1222 #  if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1223          result = true;
1224 #  else
1225          XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1226          /*
1227 #if defined(__APPLE__)
1228          XVisualInfo template = { 0 };
1229          XWindowAttributes winAttr;
1230          int n;
1231          XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1232          template.visualid = XVisualIDFromVisual(winAttr.visual);
1233          visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1234 #ifdef _DEBUG
1235          printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1236          printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1237          printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1238          printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1239 #endif
1240          // visualInfo = oglSystem.visualInfo;
1241 //#endif
1242          */
1243          if(visualInfo)
1244          {
1245             //printf("visualInfo is not null\n");
1246             // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1247             oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1248             //XFree(visualInfo);
1249          }
1250
1251          // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1252          if(oglDisplay.glContext)
1253          {
1254             //printf("CreateDisplay Got a Context\n");
1255             glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1256             result = true;
1257          }
1258 #  endif
1259 #endif
1260       }
1261 #if defined(__WIN32__) || defined(USEPBUFFER)
1262       else
1263       {
1264          result = true;
1265          wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1266       }
1267 #endif
1268       if(result)
1269       {
1270 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1271
1272 #ifdef DIAGNOSTICS
1273          PrintLn("Calling ogl_LoadFunctions() in CreateDisplay()");
1274 #endif
1275          if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
1276             PrintLn("ogl_LoadFunctions() failed!");
1277
1278 #ifdef DIAGNOSTICS
1279          PrintLn("CheckExtensions()");
1280 #endif
1281          CheckExtensions(oglSystem);
1282          vboAvailable = glBindBuffer != null;
1283
1284 #ifdef DIAGNOSTICS
1285          PrintLn("vboAvailable is: ", vboAvailable);
1286 #endif
1287
1288 #  ifdef _DEBUG
1289          setupDebugging();
1290 #  endif
1291
1292 #endif
1293
1294 #if defined(__EMSCRIPTEN__)
1295          emscripten_webgl_make_context_current(oglSystem.glc);
1296 #endif
1297
1298          initialDisplaySetup(display);
1299       }
1300
1301       if(!useSingleGLContext)
1302       {
1303    #if defined(__WIN32__)
1304          wglMakeCurrent(null, null);
1305    #elif defined(__unix__) || defined(__APPLE__)
1306       #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1307          result = true;
1308       #else
1309          glXMakeCurrent(xGlobalDisplay, None, null);
1310       #endif
1311    #endif
1312       }
1313       else
1314       {
1315       #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1316          result = true;
1317       #endif
1318       }
1319
1320       return result;
1321    }
1322
1323    bool DisplaySize(Display display, int width, int height)
1324    {
1325       OGLDisplay oglDisplay = display.driverData;
1326
1327       bool result = false;
1328
1329       //printf("Inside DisplaySize\n");
1330 #if defined(__WIN32__) || defined(USEPBUFFER)
1331       OGLSystem oglSystem = display.displaySystem.driverData;
1332       if(display.alphaBlend)
1333       {
1334 #if defined(__WIN32__)
1335          const int attributes[]=
1336          {
1337             /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1338             WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1339          };
1340          int pixelFormat = 0;
1341          if(wglChoosePixelFormatARB)
1342          {
1343             int valid;
1344             int numFormats;
1345             float fAttributes[] = {0,0};
1346             int iAttributes[] =
1347             {
1348                //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1349                WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1350                WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1351                WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1352                WGL_COLOR_BITS_ARB,24,
1353                WGL_ALPHA_BITS_ARB,8,
1354                WGL_DEPTH_BITS_ARB,16,
1355                WGL_STENCIL_BITS_ARB,0,
1356                WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1357                WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1358                WGL_SAMPLES_ARB, 4,                  // Check For 4x Multisampling
1359                0,0
1360             };
1361
1362             //Log("Found wglChoosePixelFormatARB\n");
1363
1364             valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1365             if(!valid || !numFormats)
1366             {
1367                //Log("Can't find 4x multi sampling\n");
1368                iAttributes[19] = 2;
1369                valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1370                if(!valid || !numFormats)
1371                {
1372                   // Log("Can't find 2x multi sampling\n");
1373                   iAttributes[16] = 0;
1374                   iAttributes[17] = 0;
1375                   valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1376                   if(!valid || !numFormats)
1377                   {
1378                      int iAttributes[] =
1379                      {
1380                         WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1381                         //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1382                         WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1383                         WGL_COLOR_BITS_ARB,24,
1384                         WGL_ALPHA_BITS_ARB,8,
1385                         WGL_DEPTH_BITS_ARB,16,
1386                         0,0
1387                      };
1388                      valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1389                   }
1390                }
1391             }
1392             if(valid && numFormats)
1393             {
1394                wglMakeCurrent(null, null);
1395             }
1396          }
1397
1398          wglMakeCurrent( null, null );
1399          wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1400          if(oglDisplay.hdc && oglDisplay.pBuffer)
1401             wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1402
1403          wglDestroyPbufferARB(oglDisplay.pBuffer);
1404
1405          if(!useSingleGLContext)
1406             wglMakeCurrent( null, null );
1407
1408          if(oglDisplay.glrc)
1409             wglDeleteContext(oglDisplay.glrc);
1410
1411          oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1412          oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1413          if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1414          {
1415             BITMAPINFO * info;
1416             HDC hdc = GetDC(display.window);
1417
1418             wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1419             wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1420
1421             //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1422             //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1423
1424             // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1425
1426             if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1427             {
1428                HBITMAP newBitmap;
1429
1430                if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1431                oglDisplay.memDC = CreateCompatibleDC(hdc);
1432                SetMapMode(oglDisplay.memDC, MM_TEXT);
1433                info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1434                info->bmiHeader.biPlanes = 1;
1435                info->bmiHeader.biCompression = BI_RGB;
1436                info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1437                info->bmiHeader.biWidth = width;
1438                info->bmiHeader.biHeight = height;
1439                newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1440                if(newBitmap)
1441                {
1442                   SelectObject(oglDisplay.memDC, newBitmap);
1443                   if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1444                   /*
1445                   {
1446                      PIXELFORMATDESCRIPTOR pfd = { 0 };
1447                      pfd.nSize = (short)sizeof(pfd);
1448                      pfd.nVersion = 1;
1449                      pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1450                      pfd.iPixelType = PFD_TYPE_RGBA;
1451                      pfd.cColorBits = 32;
1452                      //pfd.cAlphaBits = 8;
1453                      pfd.cDepthBits = 24;
1454                      pfd.iLayerType = PFD_MAIN_PLANE;
1455
1456                      oglDisplay.hdc = oglDisplay.memDC;
1457
1458                      pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1459                      DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1460                      SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1461
1462                      oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1463                      wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1464                      wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1465                   }
1466                   */
1467                   /*
1468                   {
1469                      const int imageSize = width * height * 4;
1470
1471                      glGenBuffersARB(2, oglDisplay.imageBuffers);
1472
1473                      glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1474                      glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1475                      // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1476                      // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1477                   }
1478                   */
1479                   oglDisplay.memBitmap = newBitmap;
1480                   oglDisplay.stride = width;
1481
1482                   result = true;
1483                }
1484                delete info;
1485             }
1486             ReleaseDC(display.window, hdc);
1487          }
1488 #elif defined(__unix__) || defined(__APPLE__)
1489       #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1490          result = true;
1491       #else
1492          int attrib[] =
1493          {
1494             GLX_DOUBLEBUFFER,  True,
1495             GLX_DEPTH_SIZE,    1,
1496             GLX_RED_SIZE,      8,
1497             GLX_GREEN_SIZE,    8,
1498             GLX_BLUE_SIZE,     8,
1499             GLX_ALPHA_SIZE,    8,
1500             GLX_STENCIL_SIZE,  1,
1501             //GLX_DEPTH_SIZE,    24,
1502             GLX_RENDER_TYPE,   GLX_RGBA_BIT,
1503             GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1504             None
1505          };
1506
1507          int PBattrib[] =
1508          {
1509             GLX_PBUFFER_WIDTH,   width,
1510             GLX_PBUFFER_HEIGHT,  height,
1511             GLX_LARGEST_PBUFFER, False,
1512             None
1513          };
1514
1515          // choose a pixel format that meets our minimum requirements
1516          int count = 0;
1517
1518          GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1519          if(config)
1520          {
1521             if(oglDisplay.pixmap)
1522             {
1523                XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1524                oglDisplay.pixmap = None;
1525             }
1526             if(oglDisplay.shapePixmap)
1527             {
1528                XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1529                oglDisplay.shapePixmap = None;
1530             }
1531
1532             // Free Shared Memory Pixmap
1533             if(oglDisplay.image)
1534             {
1535                if(oglDisplay.shminfoShape.shmid != -1)
1536                {
1537                   XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1538                   if(oglDisplay.shminfo.shmaddr != (void *)-1)
1539                      shmdt(oglDisplay.shminfo.shmaddr);
1540                   shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1541                }
1542                XDestroyImage(oglDisplay.image);
1543                oglDisplay.image = None;
1544             }
1545             if(oglDisplay.shapeImage)
1546             {
1547                if(oglDisplay.shminfoShape.shmid != -1)
1548                {
1549                   XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1550                   if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1551                      shmdt(oglDisplay.shminfoShape.shmaddr);
1552                   shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1553                }
1554                XDestroyImage(oglDisplay.shapeImage);
1555                oglDisplay.shapeImage = None;
1556             }
1557
1558             if(oglDisplay.windowPicture)
1559                XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1560             if(oglDisplay.pixmapPicture)
1561                XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1562
1563             if(oglDisplay.pixmap)
1564                XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1565
1566             if(oglDisplay.glContext)
1567               glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1568             if(oglDisplay.pBuffer)
1569                glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1570
1571             oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1572             if(oglDisplay.pBuffer)
1573             {
1574                oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1575                if(oglDisplay.glContext)
1576                {
1577                   glXMakeCurrent(xGlobalDisplay, None, null);
1578                   glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1579
1580                   // Initialize Shared Memory Pixmap
1581                   oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1582                      ZPixmap, null, &oglDisplay.shminfo, width, height);
1583                   if(oglDisplay.image)
1584                   {
1585                      oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1586                         oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1587                      if(oglDisplay.shminfo.shmid != -1)
1588                      {
1589                         oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1590                         if(oglDisplay.shminfo.shmaddr != (void *)-1)
1591                         {
1592                            oglDisplay.shminfo.readOnly = False;
1593                            if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1594                            {
1595                               oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1596                                  &oglDisplay.shminfo, width, height, 32);
1597
1598                               // Initialize Shared Memory Shape Pixmap
1599                               oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1600                                  ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1601                               if(oglDisplay.shapeImage)
1602                               {
1603                                  oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1604                                     oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1605                                  if(oglDisplay.shminfoShape.shmid != -1)
1606                                  {
1607                                     oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1608                                     if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1609                                     {
1610                                        oglDisplay.shminfoShape.readOnly = False;
1611                                        if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1612                                        {
1613                                           oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1614                                              &oglDisplay.shminfoShape, width, height, 1);
1615                                           //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1616
1617                                           {
1618                                              XRenderPictureAttributes attributes = { 0 };
1619                                              XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1620                                              #if !defined(__APPLE__)
1621                                              attributes.repeat = RepeatNormal;
1622                                              #else
1623                                              attributes.repeat = 1;
1624                                              #endif
1625                                              oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1626                                              oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1627                                              oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1628                                                 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1629                                           }
1630
1631                                           oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1632                                           oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1633
1634                                           result = true;
1635                                        }
1636                                     }
1637                                  }
1638                               }
1639                            }
1640                         }
1641                      }
1642                   }
1643                }
1644             }
1645             XFree(config);
1646          }
1647      #endif
1648 #endif
1649          CreateDisplay(display);
1650 #if defined(__WIN32__)
1651          wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1652 #elif defined(__unix__) || defined(__APPLE__)
1653       #if defined(__ANDROID__) || defined(__ODROID__)
1654          width = eglWidth;
1655          height = eglHeight;
1656       #elif defined(__EMSCRIPTEN__)
1657          emscripten_webgl_make_context_current(oglSystem.glc);
1658       #else
1659          glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1660       #endif
1661 #endif
1662       }
1663       else
1664 #endif
1665          result = true;
1666
1667       if(display.alphaBlend && result)
1668          initialDisplaySetup(display);
1669
1670       if(!result && display.alphaBlend)
1671       {
1672          printf("Alpha blending windows not supported on this display\n");
1673       }
1674       if(!result)
1675          return false;
1676
1677       result = false;
1678
1679       glViewport(0,0,width,height);
1680       glMatrixMode(MatrixMode::projection);
1681       glLoadIdentity();
1682       glOrtho(0,width,height,0,0.0,1.0);
1683       displayWidth = display.width = width;
1684       displayHeight = display.height = height;
1685
1686       if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1687       {
1688          oglDisplay.flipBufW = width;
1689          oglDisplay.flipBufH = height;
1690 #if defined(ES1_1) || defined(ES2)
1691          result = true;
1692 #else
1693          oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1694 #endif
1695       }
1696       if(oglDisplay.flippingBuffer || !width || !height)
1697          result = true;
1698
1699       return result;
1700    }
1701
1702    void DisplayPosition(Display display, int x, int y)
1703    {
1704       OGLDisplay oglDisplay = display.driverData;
1705
1706       oglDisplay.x = x;
1707       oglDisplay.y = y;
1708    }
1709
1710    void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1711    {
1712    }
1713
1714    void RestorePalette(Display display)
1715    {
1716    }
1717
1718    void StartUpdate(Display display)
1719    {
1720    }
1721
1722    void EndUpdate(Display display)
1723    {
1724    }
1725
1726    void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1727    {
1728    }
1729
1730    void Update(Display display, Box updateBox)
1731    {
1732 #if defined(__WIN32__) || defined(USEPBUFFER)
1733       OGLDisplay oglDisplay = display.driverData;
1734 #endif
1735       //Logf("DisplayScreen\n");
1736
1737 #if !defined(__ANDROID__)
1738       /*glFlush();
1739       glFinish();*/
1740 #endif
1741
1742 #if defined(__WIN32__) || defined(USEPBUFFER)
1743       if(display.alphaBlend)
1744       {
1745          glPixelStorei(GL_PACK_ALIGNMENT, 4);
1746          glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1747          glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1748          glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1749          glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1750
1751          {
1752 #if defined(__WIN32__)
1753             HDC hdc = GetDC(0);
1754             POINT point = { oglDisplay.x, oglDisplay.y};
1755             POINT srcPoint = { 0, 0 };
1756             BLENDFUNCTION blend = { 0 };
1757             SIZE size;
1758             size.cx = display.width;
1759             size.cy = display.height;
1760             blend.BlendOp = AC_SRC_OVER;
1761             blend.BlendFlags = 0;
1762             blend.SourceConstantAlpha = 255;
1763             blend.AlphaFormat = AC_SRC_ALPHA;
1764
1765             /*
1766             // Process partial images.  Mapping the buffer waits for
1767             // outstanding DMA transfers into the buffer to finish.
1768             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1769             oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1770
1771             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1772             // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1773
1774
1775             memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1776             //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1777             */
1778
1779             UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1780             /*
1781
1782             // Unmap the image buffers
1783             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1784             glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1785
1786             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1787             // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1788
1789             // Bind two different buffer objects and start the glReadPixels
1790             // asynchronously. Each call will return directly after
1791             // starting the DMA transfer.
1792             glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1793             glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1794
1795             // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1796             // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1797             */
1798
1799             ReleaseDC(0, hdc);
1800 #elif defined(__unix__) || defined(__APPLE__)
1801       #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1802       #else
1803             XTransform transform =
1804             {
1805                {
1806                   { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)),  (int)(0 * (1 << 16)) },
1807                   { (int)(0.0f),           (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1808                   { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)),  (int)(1.0f * (1<<16)) }
1809                }
1810             };
1811             XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1812             XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1813             XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1814             #if !defined(__APPLE__)
1815             XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1816             #else
1817             XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1818             #endif
1819             XFlush(xGlobalDisplay);
1820      #endif
1821 #endif
1822          }
1823       }
1824       else
1825 #endif
1826       {
1827 #if defined(__WIN32__)
1828          //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1829          SwapBuffers(oglDisplay.hdc);
1830          //ecere::sys::Sleep(0.1);
1831 #elif defined(__unix__) || defined(__APPLE__)
1832       #if defined(__ANDROID__) || defined(__ODROID__)
1833          egl_swap_buffers();
1834       #elif defined(__EMSCRIPTEN__)
1835       #else
1836          glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1837       #endif
1838 #endif
1839       }
1840       //Logf("Out of DisplayScreen\n");
1841    }
1842
1843    void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1844    {
1845       if(bitmap.driverData)
1846       {
1847          GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1848          glDeleteTextures(1, &tex);
1849          bitmap.driverData = 0;
1850       }
1851       bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1852    }
1853
1854    bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1855    {
1856       OGLSystem oglSystem = displaySystem.driverData;
1857       bool result = false;
1858       Bitmap mipMap { };
1859       GLuint glBitmap = 0;
1860
1861       uint w = width, h = height;
1862       if(oglSystem.pow2textures)
1863       {
1864          w = pow2i(w);
1865          h = pow2i(h);
1866       }
1867       w = Min(w, oglSystem.maxTextureSize);
1868       h = Min(h, oglSystem.maxTextureSize);
1869
1870       glGenTextures(1, &glBitmap);
1871       glBindTexture(GL_TEXTURE_2D, glBitmap);
1872
1873       glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1874
1875       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1876       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1877
1878       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1879       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1880
1881 #if !defined(SHADERS)
1882       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1883 #endif
1884
1885       mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1886
1887       // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1888       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1889
1890       delete mipMap;
1891
1892       bitmap.driverData = (void *)(uintptr)glBitmap;
1893       bitmap.driver = displaySystem.driver;
1894       bitmap.width = w;
1895       bitmap.height = h;
1896
1897       result = true;
1898       return result;
1899    }
1900
1901    bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1902    {
1903       bool result = false;
1904       OGLSystem oglSystem = displaySystem.driverData;
1905       Bitmap convBitmap = bitmap;
1906       if(bitmap.keepData)
1907       {
1908          convBitmap = { };
1909          convBitmap.Copy(bitmap);
1910       }
1911
1912       // Pre process the bitmap... First make it 32 bit
1913       if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1914       {
1915          int c, level;
1916          uint w = bitmap.width, h = bitmap.height;
1917          GLuint glBitmap = 0;
1918          if(oglSystem.pow2textures)
1919          {
1920             w = pow2i(w);
1921             h = pow2i(h);
1922          }
1923          w = Min(w, oglSystem.maxTextureSize);
1924          h = Min(h, oglSystem.maxTextureSize);
1925
1926          if(mipMaps)
1927          {
1928             while(w * 2 < h) w *= 2;
1929             while(h * 2 < w) h *= 2;
1930          }
1931
1932          // Switch ARGB to RGBA
1933          //if(bitmap.format != pixelFormatRGBA)
1934          {
1935             for(c=0; c<bitmap.size; c++)
1936             {
1937                // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1938                // TODO:
1939                ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1940                ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1941             }
1942          }
1943          // convBitmap.pixelFormat = pixelFormat888;
1944
1945          glGetError();
1946          glGenTextures(1, &glBitmap);
1947          if(glBitmap == 0)
1948          {
1949             //int error = glGetError();
1950             return false;
1951          }
1952
1953          glBindTexture(GL_TEXTURE_2D, glBitmap);
1954          glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1955
1956          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1957          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1958
1959          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1960
1961          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1962          //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1963
1964          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1965          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1966 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1967          glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1968 #endif
1969
1970 #if !defined(SHADERS)
1971          glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1972 #endif
1973
1974          result = true;
1975
1976          for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1977          {
1978             Bitmap mipMap;
1979             if(!w) w = 1;
1980             if(!h) h = 1;
1981             if(bitmap.width != w || bitmap.height != h)
1982             {
1983                mipMap = Bitmap { };
1984                if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1985                {
1986                   Surface mipSurface = mipMap.GetSurface(0,0,null);
1987                   mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1988                   delete mipSurface;
1989                }
1990                else
1991                {
1992                   result = false;
1993                   delete mipMap;
1994                }
1995             }
1996             else
1997                mipMap = convBitmap;
1998
1999             if(result)
2000             {
2001                int error;
2002                //int width = 0;
2003                glGetError();
2004                // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2005                glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2006                //printf("Calling glTexImage2D\n");
2007                //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2008                //printf("width = %d (Should be %d, %d)\n", width, w, h);
2009                if((error = glGetError()))
2010                {
2011                   //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2012                   //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2013                   result = false;
2014                }
2015             }
2016             if(mipMap != convBitmap)
2017                delete mipMap;
2018             if(!mipMaps) break;
2019          }
2020
2021          convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2022          bitmap.driverData = (void *)(uintptr)glBitmap;
2023          bitmap.driver = displaySystem.driver;
2024          if(bitmap.keepData)
2025             delete convBitmap;
2026
2027          if(!result)
2028             FreeBitmap(displaySystem, bitmap);
2029          else if(oglSystem.loadingFont)
2030          {
2031             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2032             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2033             oglSystem.loadingFont = false;
2034          }
2035       }
2036       return result;
2037    }
2038
2039    void ReleaseSurface(Display display, Surface surface)
2040    {
2041       glDisable(GL_SCISSOR_TEST);
2042       delete surface.driverData;
2043       surface.driverData = null;
2044    }
2045
2046    bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2047    {
2048       return false;
2049    }
2050
2051    bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2052    {
2053       bool result = false;
2054       OGLSurface oglSurface = surface.driverData = OGLSurface { };
2055
2056       //Logf("GetSurface\n");
2057
2058       if(oglSurface)
2059       {
2060          if(displayWidth != display.width || displayHeight != display.height)
2061          {
2062             displayWidth = display.width;
2063             displayHeight = display.height;
2064
2065             glViewport(0,0,display.width,display.height);
2066             glLoadIdentity();
2067             glOrtho(0,display.width,display.height,0,0.0,1.0);
2068          }
2069
2070          surface.offset.x = x;
2071          surface.offset.y = y;
2072          surface.unclippedBox = surface.box = clip;
2073          oglSurface.bitmapMult[0] = 1;
2074          oglSurface.bitmapMult[1] = 1;
2075          oglSurface.bitmapMult[2] = 1;
2076          oglSurface.bitmapMult[3] = 1;
2077
2078          glEnable(GL_SCISSOR_TEST);
2079          glScissor(
2080             x+clip.left,
2081             (display.height) -(y+clip.bottom)-1,
2082             clip.right-clip.left+1,
2083             clip.bottom-clip.top+1);
2084          result = true;
2085       }
2086       return result;
2087    }
2088
2089    void Clip(Display display, Surface surface, Box clip)
2090    {
2091       Box box;
2092
2093       //Logf("Clip\n");
2094
2095       if(clip != null)
2096       {
2097          box = clip;
2098          box.Clip(surface.unclippedBox);
2099          surface.box = box;
2100       }
2101       else
2102          box = surface.box = surface.unclippedBox;
2103       box.left += surface.offset.x;
2104       box.top  += surface.offset.y;
2105       box.right+= surface.offset.x;
2106       box.bottom += surface.offset.y;
2107
2108       glScissor(
2109          box.left,display.height - box.bottom - 1,
2110          box.right-box.left+1, box.bottom-box.top+1);
2111    }
2112
2113    bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2114    {
2115       bool result = false;
2116       OGLDisplay oglDisplay = display.driverData;
2117       ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2118
2119       if(oglDisplay.flippingBuffer)
2120       {
2121          if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2122          {
2123             bitmap.Free();
2124             bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2125          }
2126          if(bitmap)
2127          {
2128             uint row;
2129
2130             glPixelStorei(GL_PACK_ALIGNMENT, 4);
2131             glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2132             glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2133             glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2134             glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2135
2136             // Need a flip...
2137             for(row = 0; row<h; row++)
2138                CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2139             result = true;
2140          }
2141       }
2142       return result;
2143    }
2144
2145    void SetForeground(Display display, Surface surface, ColorAlpha color)
2146    {
2147       OGLSurface oglSurface = surface.driverData;
2148
2149       //Logf("SetForeground\n");
2150
2151       oglSurface.foreground[0] = color.color.r/255.0f;
2152       oglSurface.foreground[1] = color.color.g/255.0f;
2153       oglSurface.foreground[2] = color.color.b/255.0f;
2154       //oglSurface.foreground[3] = 1.0f;
2155       oglSurface.foreground[3] = color.a/255.0f;
2156
2157       //if(!oglSurface.foreground[3])printf("bug");
2158    }
2159
2160    void SetBackground(Display display, Surface surface, ColorAlpha color)
2161    {
2162       OGLSurface oglSurface = surface.driverData;
2163
2164       //Logf("SetBackground\n");
2165
2166       oglSurface.background[0] = color.color.r/255.0f;
2167       oglSurface.background[1] = color.color.g/255.0f;
2168       oglSurface.background[2] = color.color.b/255.0f;
2169       //oglSurface.background[3] = 1.0;
2170       oglSurface.background[3] = color.a/255.0f;
2171    }
2172
2173    void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2174    {
2175       OGLSurface oglSurface = surface.driverData;
2176
2177       oglSurface.bitmapMult[0] = color.color.r/255.0f;
2178       oglSurface.bitmapMult[1] = color.color.g/255.0f;
2179       oglSurface.bitmapMult[2] = color.color.b/255.0f;
2180       oglSurface.bitmapMult[3] = color.a/255.0f;
2181    }
2182
2183    ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2184    {
2185       return 0;
2186    }
2187
2188    void PutPixel(Display display, Surface surface,int x,int y)
2189    {
2190       OGLSurface oglSurface = surface.driverData;
2191
2192       //Logf("PutPixel\n");
2193
2194       glColor4fv(oglSurface.foreground);
2195       glBegin(GL_POINTS);
2196       // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2197       glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2198
2199       glEnd();
2200    }
2201
2202    void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2203    {
2204       OGLSurface oglSurface = surface.driverData;
2205       float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2206       if(_x1 == _x2)
2207       {
2208          if(_y2 >= _y1)
2209             y2 += 1;
2210          else
2211             y1 += 1;
2212       }
2213       else if(_y1 == _y2)
2214       {
2215          if(_x2 >= _x1)
2216             x2 += 1;
2217          else
2218             x1 += 1;
2219       }
2220       x1 += surface.offset.x;
2221       y1 += surface.offset.y;
2222       x2 += surface.offset.x;
2223       y2 += surface.offset.y;
2224
2225       //Logf("Line\n");
2226
2227       glColor4fv(oglSurface.foreground);
2228       glBegin(GL_LINES);
2229 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2230       if(stippleEnabled)
2231       {
2232          glTexCoord2f(0.5f, 0);
2233          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2234          glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2235          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2236       }
2237       else
2238 #endif
2239       {
2240          /*
2241          glVertex2i(x1, y1);
2242          glVertex2i(x2, y2);
2243          */
2244          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2245          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2246       }
2247
2248       glEnd();
2249    }
2250
2251    void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2252    {
2253       OGLSurface oglSurface = surface.driverData;
2254       x1 += surface.offset.x;
2255       y1 += surface.offset.y;
2256       x2 += surface.offset.x;
2257       y2 += surface.offset.y;
2258
2259       //Logf("Rectangle\n");
2260
2261       glColor4fv(oglSurface.foreground);
2262 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2263       if(stippleEnabled)
2264       {
2265          glBegin(GL_LINES);
2266
2267          glTexCoord2f(0.5f, 0);
2268          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2269          glTexCoord2f(y2-y1 + 0.5f, 0);
2270          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2271
2272          glTexCoord2f(0.5f, 0);
2273          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2274          glTexCoord2f(x2 - x1 + 0.5f, 0);
2275          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2276
2277          glTexCoord2f(0.5f, 0);
2278          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2279          glTexCoord2f(y1 - y2 + 0.5f, 0);
2280          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2281
2282          glTexCoord2f(0.5f, 0);
2283          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2284          glTexCoord2f(x1 - x2 + 0.5f, 0);
2285          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2286       }
2287       else
2288 #endif
2289       {
2290          glBegin(GL_LINE_LOOP);
2291          /*
2292          glVertex2i(x1, y1);
2293          glVertex2i(x1, y2);
2294          glVertex2i(x2, y2);
2295          glVertex2i(x2, y1);
2296          */
2297          glVertex2f(x1 + 0.5f, y1 + 0.5f);
2298          glVertex2f(x1 + 0.5f, y2 + 0.5f);
2299          glVertex2f(x2 + 0.5f, y2 + 0.5f);
2300          glVertex2f(x2 + 0.5f, y1 + 0.5f);
2301       }
2302       glEnd();
2303    }
2304
2305    void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2306    {
2307       OGLSurface oglSurface = surface.driverData;
2308       //Logf("Area\n");
2309
2310       glColor4fv(oglSurface.background);
2311
2312       glRecti(x1+surface.offset.x, y1+surface.offset.y,
2313               x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2314       /*
2315       glRectf(x1+surface.offset.x, y1+surface.offset.y,
2316               x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2317       */
2318    }
2319
2320    void Clear(Display display, Surface surface, ClearType type)
2321    {
2322       OGLDisplay oglDisplay = display.driverData;
2323       OGLSurface oglSurface = surface.driverData;
2324
2325       //Logf("Clear\n");
2326       if(type != depthBuffer)
2327          glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2328       if(type != colorBuffer && !oglDisplay.depthWrite)
2329       {
2330          glDepthMask((byte)bool::true);
2331       }
2332       glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2333               ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2334       if(type != colorBuffer && !oglDisplay.depthWrite)
2335       {
2336          glDepthMask((byte)bool::false);
2337       }
2338    }
2339
2340    bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2341    {
2342       return true;
2343    }
2344
2345    void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2346    {
2347       OGLSurface oglSurface = surface.driverData;
2348
2349       if(!oglSurface.writingText)
2350       {
2351          // glTranslatef(-0.375f, -0.375f, 0.0f);
2352          GLSetupTexturing(true);
2353          glColor4fv(oglSurface.bitmapMult);
2354       }
2355       else if(oglSurface.xOffset)
2356          glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2357
2358       glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2359       glBegin(GLIMTKMode::quads);
2360
2361       if(h < 0)
2362       {
2363          glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2364          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2365          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2366          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2367          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2368          glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2369          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2370          glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2371       }
2372       else
2373       {
2374          /*
2375          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2376          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2377          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2378          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2379          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2380          glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2381          glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2382          glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2383          */
2384
2385          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2386          glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2387          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2388          glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2389          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2390          glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2391          glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2392          glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2393       }
2394       glEnd();
2395
2396       if(!oglSurface.writingText)
2397       {
2398          GLSetupTexturing(false);
2399
2400          //glTranslate(0.375, 0.375, 0.0);
2401       }
2402       else if(oglSurface.xOffset)
2403          glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2404    }
2405
2406    void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2407    {
2408       OGLSurface oglSurface = surface.driverData;
2409
2410       //glTranslate(-0.375, -0.375, 0.0);
2411
2412       GLSetupTexturing(true);
2413       glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2414
2415       glColor4fv(oglSurface.bitmapMult);
2416
2417       glBegin(GLIMTKMode::quads);
2418
2419       if(h < 0)
2420       {
2421          glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2422          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2423
2424          glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2425          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2426
2427          glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2428          glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2429
2430          glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2431          glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2432       }
2433       else
2434       {
2435          glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2436          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2437
2438          glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2439          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2440
2441          glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2442          glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2443
2444          glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2445          glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2446       }
2447
2448       glEnd();
2449
2450       GLSetupTexturing(false);
2451
2452       //glTranslate(0.375, 0.375, 0.0);
2453    }
2454
2455    void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2456    {
2457       Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2458    }
2459
2460    void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2461    {
2462       float s2dw,s2dh,d2sw,d2sh;
2463       //bool flipX = false, flipY = false;
2464
2465       //Logf("StretchDI\n");
2466
2467       if(Sgn(w) != Sgn(sw))
2468       {
2469          w = Abs(w);
2470          sw = Abs(sw);
2471          //flipX = true;
2472       }
2473       if(Sgn(h) != Sgn(sh))
2474       {
2475          h = Abs(h);
2476          sh = Abs(sh);
2477          //flipY = true;
2478       }
2479
2480       s2dw=(float)w / sw;
2481       s2dh=(float)h / sh;
2482       d2sw=(float)sw / w;
2483       d2sh=(float)sh / h;
2484
2485       //Clip against the edges of the source
2486       if(sx<0)
2487       {
2488          dx+=(int)((0-sx) * s2dw);
2489          w-=(int)((0-sx) * s2dw);
2490          sw-=0-sx;
2491          sx=0;
2492       }
2493       if(sy<0)
2494       {
2495          dy+=(int)((0-sy) * s2dh);
2496          h-=(int)((0-sy) * s2dh);
2497
2498          sh-=0-sy;
2499          sy=0;
2500       }
2501       if(sx+sw>bitmap.width-1)
2502       {
2503          w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2504          sw-=sx+sw-(bitmap.width-1)-1;
2505       }
2506       if(sy+sh>(bitmap.height-1))
2507       {
2508          h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2509          sh-=sy+sh-(bitmap.height-1)-1;
2510       }
2511       //Clip against the edges of the surfaceination
2512       if(dx<surface.box.left)
2513       {
2514          //if(!flip)
2515          sx+=(int)((surface.box.left-dx)*d2sw);
2516          sw-=(int)((surface.box.left-dx)*d2sw);
2517          w-=surface.box.left-dx;
2518          dx=surface.box.left;
2519       }
2520       if(dy<surface.box.top)
2521       {
2522          sy+=(int)((surface.box.top-dy)*d2sh);
2523          sh-=(int)((surface.box.top-dy)*d2sh);
2524          h-=surface.box.top-dy;
2525          dy=surface.box.top;
2526       }
2527       if(dx+w>surface.box.right)
2528       {
2529          //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2530          sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2531          w-=dx+w-surface.box.right-1;
2532       }
2533       if(dy+h>surface.box.bottom)
2534       {
2535          sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2536          h-=dy+h-surface.box.bottom-1;
2537       }
2538       if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2539
2540       dx += surface.offset.x;
2541       dy += surface.offset.y;
2542
2543       if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2544       {
2545          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2546          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2547          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2548          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2549 #if !defined(SHADERS)
2550          glRasterPos2d(dx,dy);
2551          //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2552          glPixelZoom(s2dw, -s2dh);
2553          glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2554 #endif
2555          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2556          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2557          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2558          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2559       }
2560    }
2561
2562    void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2563    {
2564       //Logf("BlitDI\n");
2565
2566       //Clip against the edges of the source
2567       if(sx<0)
2568       {
2569          dx+=-sx;
2570          w-=-sx;
2571          sx=0;
2572       }
2573       if(sy<0)
2574       {
2575          dy+=0-sy;
2576          h-=0-sy;
2577          sy=0;
2578       }
2579       if(sx+w>bitmap.width-1)
2580          w-=sx+w-(bitmap.width-1)-1;
2581       if(sy+h>bitmap.height-1)
2582          h-=sy+h-(bitmap.height-1)-1;
2583       //Clip against the edges of the surfaceination
2584       if(dx<surface.box.left)
2585       {
2586          //if(!flip)
2587          sx+=surface.box.left-dx;
2588          w-=surface.box.left-dx;
2589          dx=surface.box.left;
2590       }
2591       if(dy<surface.box.top)
2592       {
2593          sy+=surface.box.top-dy;
2594          h-=surface.box.top-dy;
2595          dy=surface.box.top;
2596       }
2597       if(dx+w>surface.box.right)
2598       {
2599          //if(flip) sx+=dx+w-surface.box.right-1;
2600          w-=dx+w-surface.box.right-1;
2601       }
2602       if(dy+h>surface.box.bottom)
2603          h-=dy+h-surface.box.bottom-1;
2604       if((w<=0)||(h<=0))
2605          return;
2606
2607       dx += surface.offset.x;
2608       dy += surface.offset.y;
2609
2610       if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2611       {
2612          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2613          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2614          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2615          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2616 #if !defined(SHADERS)
2617          glRasterPos2d(dx,dy);
2618          glPixelZoom(1,-1);
2619          glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2620 #endif
2621          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2622          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2623          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2624          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2625       }
2626    }
2627
2628    void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2629    {
2630       StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2631    }
2632
2633    void UnloadFont(DisplaySystem displaySystem, Font font)
2634    {
2635       ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2636    }
2637
2638    Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2639    {
2640       Font font;
2641       OGLSystem oglSystem = displaySystem.driverData;
2642       oglSystem.loadingFont = true;
2643       font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2644       return font;
2645    }
2646
2647    void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2648    {
2649       ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2650    }
2651
2652    void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2653    {
2654       OGLSurface oglSurface = surface.driverData;
2655       OGLSystem oglSystem = display.displaySystem.driverData;
2656       oglSystem.loadingFont = true;
2657
2658       //glTranslated(-0.375, -0.375, 0.0);
2659
2660       //Logf("Blit\n");
2661
2662       if(surface.textOpacity)
2663       {
2664          int w, h, adv;
2665          FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2666          w += adv;
2667          display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2668       }
2669
2670       oglSurface.writingText = true;
2671
2672       GLSetupTexturing(true);
2673
2674       if(surface.font.outlineSize)
2675       {
2676          ColorAlpha outlineColor = surface.outlineColor;
2677          glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2678          oglSurface.writingOutline = true;
2679          ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2680          oglSurface.writingOutline = false;
2681       }
2682       glColor4fv(oglSurface.foreground);
2683
2684       ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2685       oglSurface.writingText = false;
2686       oglSystem.loadingFont = false;
2687
2688       GLSetupTexturing(false);
2689
2690       //glTranslated(0.375, 0.375, 0.0);
2691    }
2692
2693    void TextFont(Display display, Surface surface, Font font)
2694    {
2695       ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2696    }
2697
2698    void TextOpacity(Display display, Surface surface, bool opaque)
2699    {
2700       OGLSurface oglSurface = surface.driverData;
2701       oglSurface.opaqueText = opaque;
2702    }
2703
2704    void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2705    {
2706       OGLSurface oglSurface = surface.driverData;
2707       OGLSystem oglSystem = display.displaySystem.driverData;
2708       oglSystem.loadingFont = true;
2709       FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2710       oglSystem.loadingFont = false;
2711    }
2712
2713    void DrawingChar(Display display, Surface surface, char character)
2714    {
2715
2716    }
2717
2718    void LineStipple(Display display, Surface surface, uint32 stipple)
2719    {
2720       //Logf("Stipple\n");
2721
2722       if(stipple)
2723       {
2724 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2725          stippleEnabled = true;
2726          glesLineStipple(1, (uint16)stipple);
2727 #else
2728          glLineStipple(1, (uint16)stipple);
2729          glEnable(GL_LINE_STIPPLE);
2730 #endif
2731       }
2732       else
2733       {
2734 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2735          stippleEnabled = false;
2736          glMatrixMode(GL_TEXTURE);
2737          glLoadIdentity();
2738          glMatrixMode(MatrixMode::projection);
2739          GLSetupTexturing(false);   // TODO: Special shading code for stipple?
2740 #else
2741          glDisable(GL_LINE_STIPPLE);
2742 #endif
2743       }
2744    }
2745
2746 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2747    void SetRenderState(Display display, RenderState state, uint value)
2748    {
2749       OGLDisplay oglDisplay = display.driverData;
2750       //Logf("RenderState\n");
2751
2752       switch(state)
2753       {
2754          case antiAlias:
2755 #ifndef __EMSCRIPTEN__
2756             if(value)
2757                glEnable(GL_MULTISAMPLE_ARB);
2758             else
2759                glDisable(GL_MULTISAMPLE_ARB);
2760 #endif
2761             break;
2762          case fillMode:
2763 #if !defined(ES1_1) && !defined(ES2)
2764             glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2765 #endif
2766             break;
2767          case depthTest:
2768             if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2769             break;
2770          case depthWrite:
2771             if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2772             oglDisplay.depthWrite = (bool)value;
2773             break;
2774          case fogColor:
2775          {
2776             float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2777 #if defined(SHADERS)
2778             shader_fogColor(color[0], color[1], color[2]);
2779 #else
2780             glFogfv(GL_FOG_COLOR, (float *)&color);
2781 #endif
2782             break;
2783          }
2784          case fogDensity:
2785 #if defined(SHADERS)
2786             shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2787 #else
2788             glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2789 #endif
2790             break;
2791          case blend:
2792 //#if !defined(__EMSCRIPTEN__)
2793             if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2794 //#endif
2795             break;
2796          case ambient:
2797          {
2798 #if defined(SHADERS)
2799             shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2800 #else
2801             float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2802             glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2803 #endif
2804             break;
2805          }
2806          case alphaWrite:
2807          {
2808             if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2809             break;
2810          }
2811          case vSync:
2812          {
2813 #if defined(__WIN32__)
2814             wglSwapIntervalEXT(value ? 1 : 0);
2815 #endif
2816             break;
2817          }
2818       }
2819    }
2820
2821    void SetLight(Display display, int id, Light light)
2822    {
2823 #if defined(SHADERS)
2824       shader_setLight(display, id, light);
2825 #else
2826       //Logf("SetLight\n");
2827
2828       if(light != null)
2829       {
2830          Object lightObject = light.lightObject;
2831          float position[4] = { 0, 0, 0, 0 };
2832          float color[4] = { 0, 0, 0, 1 };
2833
2834          glEnable(GL_LIGHT0 + id);
2835          /*
2836          glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
2837          glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
2838          glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
2839          */
2840
2841          if(!light.multiplier) light.multiplier = 1.0f;
2842
2843          color[0] = light.diffuse.r * light.multiplier;
2844          color[1] = light.diffuse.g * light.multiplier;
2845          color[2] = light.diffuse.b * light.multiplier;
2846          glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2847
2848          color[0] = light.ambient.r * light.multiplier;
2849          color[1] = light.ambient.g * light.multiplier;
2850          color[2] = light.ambient.b * light.multiplier;
2851          glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2852          color[0] = light.specular.r * light.multiplier;
2853          color[1] = light.specular.g * light.multiplier;
2854          color[2] = light.specular.b * light.multiplier;
2855          glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2856
2857          if(lightObject)
2858          {
2859             Vector3D positionVector;
2860             if(light.flags.spot)
2861             {
2862                if(lightObject.flags.root || !lightObject.parent)
2863                {
2864                   positionVector = lightObject.transform.position;
2865                   positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2866                }
2867                else
2868                {
2869                   positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2870                   if(display.display3D.camera)
2871                      positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2872                }
2873                position[3] = 1;
2874             }
2875             else
2876             {
2877                if(!light.direction.x && !light.direction.y && !light.direction.z)
2878                {
2879                   Vector3Df vector { 0,0,-1 };
2880                   Matrix mat;
2881                   mat.RotationQuaternion(light.orientation);
2882                   positionVector.MultMatrixf(vector, mat);
2883                }
2884                else
2885                {
2886                   positionVector = light.direction;
2887                   position[3] = 1;
2888                }
2889             }
2890
2891             position[0] = (float)positionVector.x;
2892             position[1] = (float)positionVector.y;
2893             position[2] = (float)positionVector.z;
2894
2895             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2896
2897             /*
2898             // Display Light Position
2899             glDisable(GL_LIGHTING);
2900             glDisable(GL_DEPTH_TEST);
2901             glColor3f(1,1,1);
2902             glPointSize(10);
2903             glBegin(GL_POINTS);
2904             glVertex3fv(position);
2905             glEnd();
2906             glEnable(GL_DEPTH_TEST);
2907             glEnable(GL_LIGHTING);
2908
2909
2910             // Display Target
2911             if(lightObject.flags.root || !lightObject.parent)
2912             {
2913                positionVector = light.target.transform.position;
2914                positionVector.Subtract(positionVector, display.camera.cPosition);
2915             }
2916             else
2917             {
2918                positionVector.MultMatrix(light.target.transform.position,
2919                   lightObject.light.target.parent.matrix);
2920                positionVector.Subtract(positionVector, display.camera.cPosition);
2921             }
2922
2923             position[0] = positionVector.x;
2924             position[1] = positionVector.y;
2925             position[2] = positionVector.z;
2926
2927             glDisable(GL_LIGHTING);
2928             glDisable(GL_DEPTH_TEST);
2929             glColor3f(1,1,0);
2930             glPointSize(10);
2931             glBegin(GL_POINTS);
2932             glVertex3fv(position);
2933             glEnd();
2934             glEnable(GL_DEPTH_TEST);
2935             glEnable(GL_LIGHTING);
2936             */
2937
2938             if(light.flags.attenuation)
2939             {
2940                glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2941                glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2942                glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2943             }
2944
2945             if(light.flags.spot)
2946             {
2947                float exponent = 0;
2948                #define MAXLIGHT  0.9
2949                float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2950                // Figure out exponent out of the hot spot
2951                exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2952
2953                glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2954                glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2955                glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2956             }
2957          }
2958          else
2959          {
2960             Vector3Df vector { 0,0,-1 };
2961             Vector3Df direction;
2962             Matrix mat;
2963
2964             mat.RotationQuaternion(light.orientation);
2965             direction.MultMatrix(vector, mat);
2966
2967             position[0] = direction.x;
2968             position[1] = direction.y;
2969             position[2] = direction.z;
2970
2971             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2972          }
2973       }
2974       else
2975          glDisable(GL_LIGHT0 + id);
2976 #endif
2977    }
2978
2979    void SetCamera(Display display, Surface surface, Camera camera)
2980    {
2981       OGLDisplay oglDisplay = display.driverData;
2982       //Logf("SetCamera\n");
2983
2984       if(surface && camera)
2985       {
2986          int left = surface.box.left + surface.offset.x;
2987          int top = surface.box.top  + surface.offset.y;
2988          int right = surface.box.right + surface.offset.x;
2989          int bottom = surface.box.bottom + surface.offset.y;
2990          float origX = surface.offset.x + camera.origin.x;
2991          float origY = surface.offset.y + camera.origin.y;
2992          int x = left;
2993          int y = display.height - bottom - 1;
2994          int w = right - left + 1;
2995          int h = bottom - top + 1;
2996
2997          // *** ViewPort ***
2998          glViewport(x, y, w, h);
2999
3000          // *** Projection Matrix ***
3001          glMatrixMode(MatrixMode::projection);
3002          if(!display.display3D.camera)
3003             glPushMatrix();
3004
3005          if(display.display3D.collectingHits)
3006          {
3007             float pickX = display.display3D.pickX + surface.offset.x;
3008             float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3009             Matrix pickMatrix
3010             {
3011                {
3012                   w / display.display3D.pickWidth, 0, 0, 0,
3013                   0, h / display.display3D.pickHeight, 0, 0,
3014                   0, 0, 1, 0,
3015                   (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3016                   (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3017                }
3018             };
3019             glLoadMatrixd(pickMatrix.array);
3020          }
3021          else
3022             glLoadIdentity();
3023          glFrustum(
3024             (left   - origX) * camera.zMin / camera.focalX,
3025             (right  - origX) * camera.zMin / camera.focalX,
3026             (bottom - origY) * camera.zMin / camera.focalY,
3027             (top    - origY) * camera.zMin / camera.focalY,
3028             camera.zMin, camera.zMax);
3029
3030          glDisable(GL_BLEND);
3031
3032          // *** Z Inverted Identity Matrix ***
3033          glMatrixMode(MatrixMode::modelView);
3034          if(!display.display3D.camera)
3035             glPushMatrix();
3036
3037          glLoadIdentity();
3038
3039          glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3040
3041          // *** View Matrix ***
3042          glMultMatrixd(camera.viewMatrix.array);
3043
3044          // *** Lights ***
3045          // ...
3046
3047          glEnable(GL_DEPTH_TEST);
3048
3049          GLSetupLighting(true);
3050 #if !defined(SHADERS)
3051          glShadeModel(GL_SMOOTH);
3052 #endif
3053          glDepthMask((byte)bool::true);
3054          oglDisplay.depthWrite = true;
3055
3056 #ifndef __EMSCRIPTEN__
3057          glEnable(GL_MULTISAMPLE_ARB);
3058 #endif
3059       }
3060       else if(surface && display.display3D.camera)
3061       {
3062          nearPlane = 1;
3063          oglDisplay.depthWrite = false;
3064          glViewport(0,0,display.width,display.height);
3065
3066          glDisable(GL_CULL_FACE);
3067          glDisable(GL_DEPTH_TEST);
3068
3069
3070          GLSetupTexturing(false);
3071          GLSetupLighting(false);
3072          GLSetupFog(false);
3073
3074          glDisableClientState(GL_COLOR_ARRAY);
3075
3076 #if defined(SHADERS)
3077          shader_setPerVertexColor(false);
3078 #else
3079          glShadeModel(GL_FLAT);
3080 #endif
3081          glEnable(GL_BLEND);
3082 #if !defined(__EMSCRIPTEN__)
3083          glDisable(GL_MULTISAMPLE_ARB);
3084 #endif
3085
3086          // *** Restore 2D MODELVIEW Matrix ***
3087          glPopMatrix();
3088
3089          // *** Restore 2D PROJECTION Matrix ***
3090          glMatrixMode(MatrixMode::projection);
3091          glPopMatrix();
3092       }
3093
3094    }
3095
3096    void ApplyMaterial(Display display, Material material, Mesh mesh)
3097    {
3098       //Logf("ApplyMaterial\n");
3099
3100       // Basic Properties
3101       if(material.flags.doubleSided)
3102       {
3103 #if !defined(SHADERS)
3104          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3105 #endif
3106          glDisable(GL_CULL_FACE);
3107       }
3108       else
3109       {
3110 #if !defined(SHADERS)
3111          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3112 #endif
3113          glEnable(GL_CULL_FACE);
3114       }
3115
3116       // Fog
3117       GLSetupFog(!material.flags.noFog);
3118
3119       // Maps
3120       if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3121       {
3122          Bitmap map = material.baseMap;
3123          GLSetupTexturing(true);
3124          glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3125
3126          glMatrixMode(GL_TEXTURE);
3127          glLoadIdentity();
3128          if(material.uScale && material.vScale)
3129             glScalef(material.uScale, material.vScale, 1);
3130          glMatrixMode(MatrixMode::modelView);
3131
3132          if(material.flags.tile)
3133          {
3134             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3135             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3136          }
3137          else
3138          {
3139             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3140             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3141          }
3142       }
3143       else
3144          GLSetupTexturing(false);
3145
3146 #if defined(SHADERS)
3147       shader_setMaterial(material, mesh.flags.colors);
3148 #else
3149       if(mesh.flags.colors)
3150       {
3151          glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3152          glEnable(GL_COLOR_MATERIAL);
3153       }
3154       else
3155       {
3156          glDisable(GL_COLOR_MATERIAL);
3157          {
3158             float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3159             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3160          }
3161          {
3162             float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3163             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3164          }
3165       }
3166       {
3167          float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3168          glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3169       }
3170       {
3171          float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3172          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3173       }
3174
3175       glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3176 #endif
3177    }
3178
3179    void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3180    {
3181       OGLMesh oglMesh = mesh.data;
3182       if(oglMesh)
3183       {
3184          if(!mesh.flags.vertices)
3185          {
3186             oglMesh.vertices.free();
3187             delete mesh.vertices;
3188          }
3189          if(!mesh.flags.normals)
3190          {
3191             oglMesh.normals.free();
3192             delete mesh.normals;
3193          }
3194          if(!mesh.flags.texCoords1)
3195          {
3196             oglMesh.texCoords.free();
3197             delete mesh.texCoords;
3198          }
3199          if(!mesh.flags.texCoords2)
3200          {
3201             oglMesh.texCoords2.free();
3202             // delete mesh.texCoords2;
3203          }
3204          if(!mesh.flags.colors)
3205          {
3206             oglMesh.colors.free();
3207             delete mesh.colors;
3208          }
3209          if(!mesh.flags)
3210          {
3211             delete oglMesh;
3212             mesh.data = null;
3213          }
3214       }
3215    }
3216
3217    bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3218    {
3219       bool result = false;
3220
3221       if(!mesh.data)
3222          mesh.data = OGLMesh { };
3223       if(mesh.data)
3224       {
3225          if(mesh.nVertices == nVertices)
3226          {
3227             // Same number of vertices, adding features (Leaves the other features pointers alone)
3228             if(mesh.flags != flags)
3229             {
3230                if(!mesh.flags.vertices && flags.vertices)
3231                {
3232                   if(flags.doubleVertices)
3233                   {
3234                      mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3235                   }
3236                   else
3237                      mesh.vertices = new Vector3Df[nVertices];
3238                }
3239                if(!mesh.flags.normals && flags.normals)
3240                {
3241                   if(flags.doubleNormals)
3242                   {
3243                      mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3244                   }
3245                   else
3246                      mesh.normals = new Vector3Df[nVertices];
3247                }
3248                if(!mesh.flags.texCoords1 && flags.texCoords1)
3249                {
3250                   mesh.texCoords = new Pointf[nVertices];
3251                }
3252                if(!mesh.flags.colors && flags.colors)
3253                {
3254                   mesh.colors = new ColorRGBAf[nVertices];
3255                }
3256             }
3257          }
3258          else
3259          {
3260             // New number of vertices, reallocate all current and new features
3261             flags |= mesh.flags;
3262             if(flags.vertices)
3263             {
3264                if(flags.doubleVertices)
3265                {
3266                   mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3267                }
3268                else
3269                   mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3270             }
3271             if(flags.normals)
3272             {
3273                if(flags.doubleNormals)
3274                {
3275                   mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3276                }
3277                else
3278                   mesh.normals = renew mesh.normals Vector3Df[nVertices];
3279             }
3280             if(flags.texCoords1)
3281             {
3282                mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3283             }
3284             if(flags.colors)
3285             {
3286                mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3287             }
3288          }
3289          result = true;
3290       }
3291       return result;
3292    }
3293
3294    void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3295    {
3296       OGLMesh oglMesh = mesh.data;
3297       if(!flags) flags = mesh.flags;
3298
3299       if(vboAvailable)
3300       {
3301          if(flags.vertices)
3302             oglMesh.vertices.upload(
3303                mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3304
3305          if(flags.normals)
3306             oglMesh.normals.upload(
3307                mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3308
3309          if(flags.texCoords1)
3310             oglMesh.texCoords.upload(
3311                mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3312
3313          if(flags.colors)
3314             oglMesh.colors.upload(
3315                mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3316       }
3317    }
3318
3319    bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3320    {
3321       bool result = true;
3322
3323       return result;
3324    }
3325
3326    void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3327    {
3328       if(oglIndices)
3329       {
3330          oglIndices.buffer.free();
3331          delete oglIndices.indices;
3332          delete oglIndices;
3333       }
3334    }
3335
3336    void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3337    {
3338       OGLIndices oglIndices = OGLIndices { };
3339       if(oglIndices)
3340       {
3341          oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3342          oglIndices.nIndices = nIndices;
3343       }
3344       return oglIndices;
3345    }
3346
3347    void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3348    {
3349       if(vboAvailable)
3350       {
3351 #if defined(ES1_1) || defined(ES2)
3352          if(indices32bit)
3353          {
3354             if(!oglIndices.buffer.buffer)
3355                glGenBuffers(1, &oglIndices.buffer.buffer);
3356             if(glabCurElementBuffer != oglIndices.buffer.buffer)
3357                GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3358             glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3359          }
3360          else
3361 #endif
3362          oglIndices.buffer.upload(
3363             nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3364             oglIndices.indices); //GL_STATIC_DRAW_ARB);
3365       }
3366    }
3367
3368    uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3369    {
3370
3371       return oglIndices.indices;
3372    }
3373
3374    void SelectMesh(Display display, Mesh mesh)
3375    {
3376       //Logf("SelectMesh\n");
3377
3378 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3379
3380 #if defined(__WIN32__)
3381       if(glUnlockArraysEXT)
3382 #endif
3383          if(!vboAvailable && display.display3D.mesh)
3384             glUnlockArraysEXT();
3385
3386 #endif
3387       if(mesh)
3388       {
3389          OGLMesh oglMesh = mesh.data;
3390
3391          // *** Vertex Stream ***
3392          glEnableClientState(GL_VERTEX_ARRAY);
3393          if(!display.display3D.collectingHits && oglMesh)
3394          {
3395             oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3396
3397             // *** Normals Stream ***
3398             if(mesh.normals || mesh.flags.normals)
3399             {
3400                glEnableClientState(GL_NORMAL_ARRAY);
3401                oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3402             }
3403             else
3404                glDisableClientState(GL_NORMAL_ARRAY);
3405
3406             // *** Texture Coordinates Stream ***
3407             if(mesh.texCoords || mesh.flags.texCoords1)
3408             {
3409                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3410                oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3411             }
3412             else
3413                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3414
3415             // *** Color Stream ***
3416             if(mesh.colors || mesh.flags.colors)
3417             {
3418                glEnableClientState(GL_COLOR_ARRAY);
3419                oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3420             }
3421             else
3422                glDisableClientState(GL_COLOR_ARRAY);
3423          }
3424          else
3425          {
3426             noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3427             if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3428             {
3429                glEnableClientState(GL_NORMAL_ARRAY);
3430                noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3431             }
3432             else
3433                glDisableClientState(GL_NORMAL_ARRAY);
3434             if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3435             {
3436                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3437                noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3438             }
3439             else
3440                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3441             if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3442             {
3443                glEnableClientState(GL_COLOR_ARRAY);
3444                noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3445             }
3446             else
3447                glDisableClientState(GL_COLOR_ARRAY);
3448          }
3449
3450 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3451
3452 #if defined(__WIN32__)
3453          if(glLockArraysEXT)
3454 #endif
3455             if(!vboAvailable)
3456                glLockArraysEXT(0, mesh.nVertices);
3457
3458 #endif
3459       }
3460    }
3461
3462    void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3463    {
3464       //Logf("DrawPrimitives\n");
3465
3466       if(primitive->type.vertexRange)
3467          glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3468       else
3469       {
3470          //    *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3471          // HACK TO SPEED THINGS UP...
3472 #ifndef __ANDROID__
3473          /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3474          if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3475          {
3476             int c;
3477             glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
3478             if(primitive->data)
3479             {
3480                OGLIndices oglIndices = primitive->data;
3481                MeshFeatures flags = mesh.flags;
3482                for(c = 0; c<primitive->nIndices; c++)
3483                {
3484                   uint16 index = ((uint16 *) oglIndices.indices)[c];
3485                   if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3486                   if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3487                   if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3488                   glVertex3fv((float *)&mesh.vertices[index]);
3489                }
3490             }
3491             glEnd();
3492          }
3493          else*/
3494 #endif
3495
3496          {
3497             OGLIndices oglIndices = primitive->data;
3498             GLEAB eab = ((!display.display3D.collectingHits && oglIndices) ? oglIndices.buffer : noEAB);
3499
3500             eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3501                primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3502                eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3503             GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3504          }
3505       }
3506    }
3507
3508    void PushMatrix(Display display)
3509    {
3510       glPushMatrix();
3511    }
3512
3513    void PopMatrix(Display display, bool setMatrix)
3514    {
3515       glPopMatrix();
3516    }
3517
3518    void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3519    {
3520       Matrix matrix = transMatrix;
3521       Camera camera = useCamera ? display.display3D.camera : null;
3522
3523       if(viewSpace)
3524       {
3525          glLoadIdentity();
3526          glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3527       }
3528       else if(camera)
3529       {
3530          glTranslated(
3531             matrix.m[3][0] - camera.cPosition.x,
3532             matrix.m[3][1] - camera.cPosition.y,
3533             matrix.m[3][2] - camera.cPosition.z);
3534       }
3535       else
3536          glTranslated(
3537             matrix.m[3][0],
3538             matrix.m[3][1],
3539             matrix.m[3][2]);
3540
3541       matrix.m[3][0] = 0;
3542       matrix.m[3][1] = 0;
3543       matrix.m[3][2] = 0;
3544
3545       glMultMatrixd(matrix.array);
3546    }
3547 #endif
3548 }
3549
3550 public void UseSingleGLContext(bool useSingle)
3551 {
3552    useSingleGLContext = useSingle;
3553 }
3554
3555 default dllexport void *
3556 #if defined(__WIN32__)
3557 __attribute__((stdcall))
3558 #endif
3559 IS_GLGetContext(DisplaySystem displaySystem)
3560 {
3561    if(displaySystem)
3562    {
3563 #if defined(__WIN32__)
3564       OGLSystem system = displaySystem.driverData;
3565       return system.glrc;
3566 #elif defined(__ANDROID__) || defined(__ODROID__)
3567       return eglContext;
3568 #elif defined(__EMSCRIPTEN__)
3569       OGLSystem system = displaySystem.driverData;
3570       return (void *)system.glc;
3571 #else
3572       OGLSystem system = displaySystem.driverData;
3573       return system.glContext;
3574 #endif
3575    }
3576    return null;
3577 }
3578
3579 #endif