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