1 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
4 #if defined(_DEBUG) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
15 namespace gfx::drivers;
19 // ********** GL PLATFORMS INCLUDES **********
21 #if defined(__unix__) || defined(__APPLE__)
24 #if defined(__ANDROID__) || defined(__ODROID__)
27 #if defined(__ANDROID__)
28 #include <android/native_activity.h>
29 #include <android/log.h>
30 #define printf(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "ecere-app", __VA_ARGS__))
34 #elif defined(__EMSCRIPTEN__)
35 #define property _property
38 #include <emscripten/emscripten.h>
39 #include <emscripten/html5.h>
45 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
46 #define pointer _pointer
47 #define GL_GLEXT_PROTOTYPES
49 #define property _property
53 #define Window X11Window
54 #define Cursor X11Cursor
56 #define Display X11Display
58 #define KeyCode X11KeyCode
59 #define Picture X11Picture
60 #define Glyph X11Glyph
64 #include <X11/Xutil.h>
66 #include <X11/extensions/XShm.h>
69 #include <X11/extensions/Xrender.h>
70 #include <X11/extensions/shape.h>
86 #if !defined(__APPLE__)
87 default GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
88 default GLAPI void APIENTRY glUnlockArraysEXT (void);
93 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
99 #elif defined(__APPLE__)
100 #include <OpenGl/gl.h>
103 #elif defined(__WIN32__)
104 //#define WIN32_LEAN_AND_MEAN
106 #define _WIN32_WINNT 0x0502
107 #define String Sting_
114 #if defined(__WIN32__)
115 #elif !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
120 /* OpenGL Versions Features Quick Reference
122 | OpenGL 1.1 | OpenGL 1.5 | GL ES 1.1 | OpenGL 2 | GL 3 (Compat) | GL 3 (Core) | GL ES 2 | WebGL 1 | GL ES 3 | WebGL 2
123 =======================================================================================================================================================================
124 glBegin() | X | X | - | X | X | - | - | - | - | -
125 glLoadMatrix() | X | X | - | X | X | - | - | - | - | -
126 glLineWidth() | X | X | - | X | X | - | - | - | - | -
127 glPointSize() | X | X | - | X | X | - | - | - | - | -
128 glLineStipple() | X | X | - | X | X | - | - | - | - | -
129 glPolygonStipple() | X | X | - | X | X | - | - | - | - | -
130 glColorMaterial() | X | X | - | X | X | - | - | - | - | -
131 GL_QUADS | X | X | - | X | X | - | - | - | - | -
132 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
133 GL_INT / GL_DOUBLE | X | X | - | X | X | X | - | - | - | -
134 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
135 GL_SELECT | X | X | - | (Slow) | (Slow) | (Slow) | - | - | - | -
136 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
137 Non ² Textures | - | - | - | X | X | X | - | - | - | -
138 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
139 glVertexPointer() (PTR) | X | X | X | X | X | - | - | - | - | -
140 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
141 glVertexPointer() (VBO) | - | X | X | X | X | - | - | - | - | -
142 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
143 glBufferData() | - | X | X | X | X | X | X | X | X | X
144 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
145 glMapBuffer() | - | X | OES x | X | X | X | OES x | - | OES x | -
146 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
147 glBindFramebuffer() | - | - | OES x | - | X | X | X | X | X | X
148 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
149 glVertexAttribPointer() (PTR) | - | - | - | X | X | X | X | - | X | -
150 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
151 glVertexAttribPointer() (VBO) | - | - | - | X | X | X | X | X | X | X
152 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
153 GLSL Version | - | - | - | 1.10 | 1.30 | 1.30 | 1.00 | 1.00 | 3.00 | 3.00
154 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
155 bool legacy :1; // | X | X | - | X | X | - | - | - | - | -
156 bool shaders :1; // | - | - | - | X | X | X | X | X | X | X
157 bool nonPow2Textures :1; // | - | - | - | X | X | X | - | - | - | -
158 bool vertexBuffer :1; // | - | X | X | X | X | X | X | X | X | X
159 bool frameBuffer :1; // | - | - | ~ | - | X | X | X | X | X | X
160 // bool mapBuffer :1; // | - | X | ~ | X | X | X | ~ | - | ~ | -
164 // Capabilities Global set to capabilities of Display being rendered to
165 GLCapabilities glCaps;
166 // Requiring Graphics Reload:
167 bool glCaps_nonPow2Textures, glCaps_vertexBuffer, glCaps_quads, glCaps_intAndDouble, glCaps_legacyFormats, glCaps_compatible, glCaps_vertexPointer;
168 // Might toggle without Reload:
169 bool glCaps_core, glCaps_shaders, glCaps_fixedFunction, glCaps_immediate, glCaps_legacy, glCaps_pointSize, glCaps_frameBuffer, glCaps_vao, glCaps_select;
174 // ********** Errors and Debugging **********
179 while((e = glGetError()) && nCount++ < 10)
180 printf("GL error %d!\n", e);
187 static void APIENTRY openglCallbackFunction(GLenum source,
192 const GLchar* message,
193 const void* userParam)
195 if(severity == GL_DEBUG_SEVERITY_NOTIFICATION)
197 PrintLn("---------------------opengl-callback-start------------");
198 PrintLn("message: ", message);
202 case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
203 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
204 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
205 case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
206 case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
207 case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
214 case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
215 case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
216 case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
217 default: PrintLn("(other)");
219 PrintLn("---------------------opengl-callback-end--------------");
222 static void setupDebugging()
224 if(glDebugMessageCallback)
226 GLuint unusedIds = 0;
228 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
230 glDebugMessageCallback(openglCallbackFunction, null);
231 glDebugMessageControl(GL_DONT_CARE,
242 static GLuint stippleTexture;
243 static bool stippleEnabled;
245 public void glsupLineStipple( int i, uint16 j )
249 for(x = 0; x < 16; x++)
251 bool v = (j & (1 << x)) != 0;
252 texture[x] = v ? 0xFFFFFFFF : 0;
255 glGenTextures(1, &stippleTexture);
256 glBindTexture(GL_TEXTURE_2D, stippleTexture);
257 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
259 // TOOD: Special shading code for stippling?
260 GLSetupTexturing(true);
261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
265 GLMatrixMode(GL_TEXTURE);
267 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
268 GLScaled(i/16.0, 1, 1.0f);
269 GLTranslated(0.5, 0.5, 0);
270 GLMatrixMode(MatrixMode::projection);
273 // Exported to build _GLES version...
274 public void glsupLightModeli( unsigned int pname, int param )
277 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
278 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
283 void glFogi( unsigned int pname, int param ) { }
284 void glPolygonMode( unsigned int i, unsigned int j ) { }
285 void glBlendFuncSeparate(int a, int b, int c, int d)
292 #if defined(_GLES) || defined(_GLES2)
293 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
296 #if !ENABLE_GL_SELECT
298 // *** Picking won't be supported for now ***
299 void glPushName( unsigned int i ) { }
300 void glLoadName( unsigned int i ) { }
305 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
306 static inline uint getPrimitiveType(RenderPrimitiveType type)
308 static int primitiveTypes[RenderPrimitiveType] =
310 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN,
312 GLIMTKMode::quadStrip,
315 // NOTE: This will only work for single quads
316 return (type == quads && !glCaps_quads) ? GL_TRIANGLE_FAN : primitiveTypes[type];
319 public void GLSetupTexturing(bool enable)
321 #if ENABLE_GL_SHADERS
323 shader_texturing(enable);
328 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
332 public void GLSetupFog(bool enable)
334 #if ENABLE_GL_SHADERS
341 (enable ? glEnable : glDisable)(GL_FOG);
345 bool lightingEnabled;
347 public void GLSetupLighting(bool enable)
349 lightingEnabled = enable;
350 #if ENABLE_GL_SHADERS
352 shader_lighting(enable);
357 (enable ? glEnable : glDisable)(GL_LIGHTING);
362 /*static */GLuint lastBlitTex;
364 static int displayWidth, displayHeight;
366 #define GL_CLAMP_TO_EDGE 0x812F
368 static bool useSingleGLContext = false;
369 class OGLDisplay : struct
371 #if defined(__WIN32__)
382 byte * pboMemory1, * pboMemory2;
384 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
385 GLXContext glContext;
388 XShmSegmentInfo shminfo;
390 XShmSegmentInfo shminfoShape;
395 X11Picture windowPicture;
396 X11Picture pixmapPicture;
398 X11Picture shapePicture;
401 GLCapabilities capabilities, originalCapabilities;
405 ColorAlpha * flippingBuffer;
406 int flipBufH, flipBufW;
412 class OGLSystem : struct
416 #if ENABLE_GL_SHADERS
421 #if defined(__WIN32__)
422 PIXELFORMATDESCRIPTOR pfd;
427 #elif defined(__EMSCRIPTEN__)
428 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
429 #elif !defined(__ANDROID__) && !defined(__ODROID__)
430 XVisualInfo * visualInfo;
431 GLXContext glContext;
432 GLXDrawable glxDrawable;
434 GLCapabilities capabilities;
439 uint16 *shortBDBuffer;
443 class OGLSurface : struct
451 float foreground[4], background[4], bitmapMult[4];
454 class OGLMesh : struct
463 class OGLIndices : struct
473 #if defined(__WIN32__)
474 static HGLRC winCreateContext(HDC hdc, int * contextVersion, bool * isCompatible, bool compatible)
477 if(wglCreateContextAttribsARB)
479 int versions[12][2] =
481 { 4, 5 }, { 4, 4 }, { 4, 3 }, { 4, 2 }, { 4, 1 }, { 4, 0 },
482 { 3, 3 }, { 3, 2 }, { 3, 1 }, { 3, 0 },
486 bool tryingCompat = compatible;
490 for(v = 0; !result && v < sizeof(versions) / sizeof(versions[0]); v++)
492 int v0 = versions[v][0], v1 = versions[v][1];
493 if(!tryingCompat || v0 >= 3)
495 bool coreNotion = v0 > 3 || (v0 == 3 && v1 >= 3);
498 WGL_CONTEXT_MAJOR_VERSION_ARB, v0, WGL_CONTEXT_MINOR_VERSION_ARB, v1,
500 WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
502 coreNotion ? WGL_CONTEXT_PROFILE_MASK_ARB : 0, coreNotion ? (tryingCompat ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB) : 0,
505 result = wglCreateContextAttribsARB(hdc, null, attribs);
508 if(contextVersion) *contextVersion = v0;
509 if(isCompatible) *isCompatible = tryingCompat || !coreNotion;
514 tryingCompat = false;
521 if(contextVersion) *contextVersion = 1;
522 if(isCompatible) *isCompatible = true;
523 result = wglCreateContext(hdc);
529 class OpenGLDisplayDriver : DisplayDriver
531 class_property(name) = "OpenGL";
533 bool LockSystem(DisplaySystem displaySystem)
535 #if defined(__EMSCRIPTEN__)
536 OGLSystem oglSystem = displaySystem.driverData;
537 emscripten_webgl_make_context_current(oglSystem.glc);
538 #elif !defined(__ANDROID__) && !defined(__ODROID__)
539 OGLSystem oglSystem = displaySystem.driverData;
540 if(useSingleGLContext) return true;
541 #if defined(__WIN32__)
542 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
543 #elif defined(__unix__) || defined(__APPLE__)
544 //if(previous) return true;
545 // printf("Making SYSTEM current\n");
546 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
547 //previous = oglSystem.glContext;
550 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
551 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
555 void UnlockSystem(DisplaySystem displaySystem)
557 if(useSingleGLContext) return;
558 #if defined(__WIN32__)
559 wglMakeCurrent(null, null);
560 #elif defined(__unix__) || defined(__APPLE__)
561 // printf("Making NULL current\n");
562 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
564 glXMakeCurrent(xGlobalDisplay, None, null);
570 bool Lock(Display display)
572 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
573 OGLDisplay oglDisplay = display.driverData;
574 if(useSingleGLContext) return true;
575 #if defined(__WIN32__)
576 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
577 #elif defined(__unix__) || defined(__APPLE__)
578 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
579 // printf(" Making DISPLAY current\n");
580 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
583 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
584 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
588 void Unlock(Display display)
590 if(useSingleGLContext) return;
591 //printf(" Making NULL current\n");
592 //glXMakeCurrent(xGlobalDisplay, None, null);
594 LockSystem(display.displaySystem);
597 void DestroyDisplay(Display display)
599 OGLDisplay oglDisplay = display.driverData;
603 #if defined(__WIN32__)
604 wglMakeCurrent( null, null );
607 wglDeleteContext(oglDisplay.glrc);
609 if(oglDisplay.hdc && oglDisplay.pBuffer)
610 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
612 if(oglDisplay.pBuffer)
613 wglDestroyPbufferARB(oglDisplay.pBuffer);
616 ReleaseDC(display.window, oglDisplay.hdc);
618 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
619 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
621 #elif defined(__unix__) || defined(__APPLE__)
622 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
624 if(oglDisplay.shapePixmap)
625 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
626 if(oglDisplay.pixmap)
627 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
630 if(oglDisplay.shminfoShape.shmid != -1)
632 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
633 if(oglDisplay.shminfo.shmaddr != (void *)-1)
634 shmdt(oglDisplay.shminfo.shmaddr);
635 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
638 if(oglDisplay.shapeImage)
640 if(oglDisplay.shminfoShape.shmid != -1)
642 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
643 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
644 shmdt(oglDisplay.shminfoShape.shmaddr);
645 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
647 XDestroyImage(oglDisplay.shapeImage);
648 oglDisplay.shapeImage = None;
651 glXMakeCurrent(xGlobalDisplay, None, null);
653 if(oglDisplay.glContext)
654 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
657 delete oglDisplay.flippingBuffer;
659 display.driverData = null;
663 #if !defined(__EMSCRIPTEN__)
664 void ::CheckCapabilities(OGLSystem oglSystem, OGLDisplay oglDisplay)
666 GLCapabilities capabilities;
668 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
671 printf("extensions: %s\n", extensions);
674 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
677 capabilities = { fixedFunction = true, vertexPointer = true, vertexBuffer = true, pointSize = true, legacyFormats = true, frameBuffer = extensions && strstr(extensions, "GL_OES_framebuffer_object") };
678 #elif defined(_GLES2)
679 capabilities = { glCaps_shaders = true, vertexBuffer = true, pointSize = true, frameBuffer = true, legacyFormats = true };
683 nonPow2Textures = extensions && strstr(extensions, "GL_ARB_texture_non_power_of_two");
688 compatible = oglDisplay.compat;
689 pointSize = oglDisplay.compat;
691 legacy = glBegin != null && oglDisplay.compat;
692 legacyFormats = glBegin != null && oglDisplay.compat;
693 immediate = glBegin != null && oglDisplay.compat;
694 fixedFunction = glBegin != null && oglDisplay.compat;
695 quads = glBegin != null && oglDisplay.compat;
696 select = glSelectBuffer != null && oglDisplay.compat;
698 #if ENABLE_GL_SHADERS
699 shaders = glCreateProgram != null;
701 #if ENABLE_GL_POINTER
702 vertexPointer = oglDisplay.compat;
705 vao = glBindVertexArray != null && !oglDisplay.compat;
708 shaders = glBindFramebuffer != null;
710 vertexBuffer = glBindBuffer != null;
711 // mapBuffer = glMapBuffer != null;
716 PrintLn("max texture size: ", oglSystem.maxTextureSize);
718 if(oglDisplay) oglDisplay.capabilities = capabilities;
719 if(oglSystem) oglSystem.capabilities = capabilities;
723 bool CreateDisplaySystem(DisplaySystem displaySystem)
726 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
729 oglSystem.capabilities = { fixedFunction = true, vertexBuffer = true, frameBuffer = true, pointSize = true };
730 #elif defined(_GLES2)
731 oglSystem.capabilities = { shaders = true, vertexBuffer = true, frameBuffer = true, pointSize = true };
733 oglSystem.capabilities = { compatible = glCaps_compatible, shaders = true, fixedFunction = true, immediate = true, legacy = true, pointSize = true, quads = true, intAndDouble = true, vertexBuffer = true, frameBuffer = true, vao = true, nonPow2Textures = true };
737 PrintLn("OpenGL driver's CreateDisplaySystem()");
741 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
743 oglSystem.hdc = GetDC(oglSystem.hwnd);
747 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
748 oglSystem.pfd.nVersion = 1;
749 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
750 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
751 oglSystem.pfd.cColorBits = 24;
752 oglSystem.pfd.cAlphaBits = 8;
753 oglSystem.pfd.cDepthBits = 24;
754 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
756 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
757 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
759 if(oglSystem.pfd.cColorBits > 8)
761 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
762 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
765 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
767 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
768 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
769 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
770 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
771 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
772 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
773 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
774 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
775 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
776 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
777 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
779 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
780 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
782 // eSystem_LoggingMode(LOG_MSGBOX, null);
784 if(wglChoosePixelFormatARB)
789 float fAttributes[] = {0,0};
792 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
793 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
794 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
795 WGL_COLOR_BITS_ARB,24,
796 WGL_ALPHA_BITS_ARB,8,
797 WGL_DEPTH_BITS_ARB,16,
798 WGL_STENCIL_BITS_ARB,0,
799 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
800 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
801 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
805 //Log("Found wglChoosePixelFormatARB\n");
807 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
808 if(!valid || !numFormats)
810 //Log("Can't find 4x multi sampling\n");
812 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
813 if(!valid || !numFormats)
815 // Log("Can't find 2x multi sampling\n");
818 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
821 if(valid && numFormats)
823 oglSystem.format = pixelFormat;
824 wglMakeCurrent(null, null);
825 wglDeleteContext(oglSystem.glrc);
827 // *** DescribePixelFormat does not support WGL pixel formats! ***
828 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
829 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
830 //Log("Successfully set pixel format\n");
833 PrintLn("winCreateContext()");
835 oglSystem.glrc = winCreateContext(oglSystem.hdc, &oglSystem.version, &oglSystem.compat, displaySystem.glCapabilities.compatible);
837 PrintLn("wglMakeCurrent()");
840 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
844 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
848 wglMakeCurrent(null, null);
850 //eSystem_DumpErrors(true);
854 #elif defined(__unix__) || defined(__APPLE__)
855 #if defined(__ANDROID__) || defined(__ODROID__)
856 #if defined(__ANDROID__)
857 egl_init_display(guiApp.desktop.windowHandle);
858 #elif defined(__ODROID__)
859 egl_init_display((uint)displaySystem.window);
861 CheckCapabilities(oglSystem, null);
863 // TODO: Clean this up? Needed here?
864 GLEnableClientState(VERTICES);
866 // Initialize GL state.
867 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
868 glEnable(GL_CULL_FACE);
869 glShadeModel(GL_SMOOTH);
870 glDisable(GL_DEPTH_TEST);
872 glDisable(GL_CULL_FACE);
873 glDisable(GL_DEPTH_TEST);
875 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
878 matrixStack[0][0].Identity();
879 matrixStack[1][0].Identity();
880 matrixStack[2][0].Identity();
882 GLMatrixMode(GL_MODELVIEW);
883 GLScaled(1.0, 1.0, -1.0);
884 GLMatrixMode(GL_PROJECTION);
885 glShadeModel(GL_FLAT);
889 GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
891 glFogi(GL_FOG_MODE, GL_EXP);
892 glFogf(GL_FOG_DENSITY, 0);
893 glEnable(GL_NORMALIZE);
894 glDepthFunc(GL_LESS);
896 glDisable(GL_MULTISAMPLE);
898 glViewport(0,0,eglWidth,eglHeight);
900 GLOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
902 glabCurArrayBuffer = 0;
903 glabCurElementBuffer = 0;
906 #elif defined(__EMSCRIPTEN__)
908 EmscriptenWebGLContextAttributes attribs = { 0 };
910 attribs.antialias = 1;
917 EM_BOOL premultipliedAlpha;
918 EM_BOOL preserveDrawingBuffer;
919 EM_BOOL preferLowPowerToHighPerformance;
920 EM_BOOL failIfMajorPerformanceCaveat;
923 EM_BOOL enableExtensionsByDefault;
926 emscripten_webgl_init_context_attributes(&attribs);
927 oglSystem.maxTextureSize = 16384;
928 oglSystem.glc = emscripten_webgl_create_context("canvas", &attribs);
929 if(emscripten_webgl_make_context_current(oglSystem.glc) == EMSCRIPTEN_RESULT_SUCCESS)
932 /*glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
933 glEnable(GL_BLEND);*/
937 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
938 XSetWindowAttributes attr;
943 #ifndef ECERE_MINIGLX
944 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
947 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
951 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
952 attr.background_pixel = 0;
953 attr.border_pixel = 0;
954 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
955 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
956 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
958 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
959 oglSystem.visualInfo->visual, mask, &attr );
961 if(oglSystem.visualInfo)
963 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
964 if(oglSystem.glContext)
966 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
967 glXMakeCurrent(xGlobalDisplay, None, null);
974 displaySystem.flags.alpha = true;
975 displaySystem.flags.flipping = true;
976 displaySystem.pixelFormat = pixelFormat888;
980 void DestroyDisplaySystem(DisplaySystem displaySystem)
982 OGLSystem oglSystem = displaySystem.driverData;
985 glDeleteTextures(1, &stippleTexture);
989 #if ENABLE_GL_SHADERS
990 if(oglSystem.shadingProgram)
991 glDeleteProgram(oglSystem.shadingProgram);
992 if(oglSystem.fragmentShader)
993 glDeleteShader(oglSystem.fragmentShader);
994 if(oglSystem.vertexShader)
995 glDeleteShader(oglSystem.vertexShader);
998 delete oglSystem.shortBDBuffer;
1001 #if defined(__WIN32__)
1002 wglMakeCurrent( null, null );
1005 wglDeleteContext(oglSystem.glrc);
1008 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1009 DestroyWindow(oglSystem.hwnd);
1011 #elif defined(__unix__) || defined(__APPLE__)
1012 #if defined(__ANDROID__) || defined(__ODROID__)
1014 #elif defined(__EMSCRIPTEN__)
1015 emscripten_webgl_destroy_context(oglSystem.glc);
1017 if(oglSystem.visualInfo)
1019 #ifdef ECERE_MINIGLX
1020 __miniglx_XFree(oglSystem.visualInfo);
1022 XFree(oglSystem.visualInfo);
1026 if(oglSystem.glxDrawable)
1028 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1029 oglSystem.glxDrawable = 0;
1036 /*static */bool ::initialDisplaySetup(Display display)
1038 OGLDisplay oglDisplay = display.driverData;
1039 OGLSystem oglSystem = display.displaySystem.driverData;
1042 oglSystem.capabilities = oglDisplay.capabilities;
1043 SETCAPS(oglDisplay.capabilities);
1045 #if ENABLE_GL_SHADERS
1048 #if ENABLE_GL_LEGACY
1049 if(oglDisplay.compat)
1051 glDisableClientState(GL_VERTEX_ARRAY);
1052 glDisableClientState(GL_NORMAL_ARRAY);
1053 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1054 glDisableClientState(GL_COLOR_ARRAY);
1057 loadShaders(display.displaySystem, "<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1059 #if ENABLE_GL_LEGACY
1062 glDisableVertexAttribArray(GLBufferContents::color);
1063 glDisableVertexAttribArray(GLBufferContents::normal);
1064 glDisableVertexAttribArray(GLBufferContents::texCoord);
1065 glDisableVertexAttribArray(GLBufferContents::vertex);
1066 glBindVertexArray(0);
1075 glBindVertexArray(oglDisplay.vao);
1078 GLEnableClientState(VERTICES);
1080 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1081 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1083 #if defined(__WIN32__)
1084 if(glBlendFuncSeparate)
1085 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1087 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1089 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1093 GLMatrixMode(MatrixMode::texture);
1096 GLMatrixMode(MatrixMode::modelView);
1097 GLLoadIdentity(); // For setting up GLES stack
1098 GLScaled(1.0, 1.0, -1.0);
1099 // glTranslatef(0.375f, 0.375f, 0.0f);
1100 // glTranslatef(-0.625f, -0.625f, 0.0f);
1101 GLMatrixMode(MatrixMode::projection);
1103 if(display.width && display.height)
1104 GLOrtho(0,display.width,display.height,0,0.0,1.0);
1109 glShadeModel(GL_FLAT);
1111 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1112 GLLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1115 GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1117 glFogi(GL_FOG_MODE, GL_EXP);
1118 glFogf(GL_FOG_DENSITY, 0);
1119 glEnable(GL_NORMALIZE);
1122 glDepthFunc(GL_LESS);
1124 #if !defined(__EMSCRIPTEN__)
1125 glDisable(GL_MULTISAMPLE);
1128 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1129 display.ambient = Color { 50,50,50 };
1134 bool CreateDisplay(Display display)
1136 bool result = false;
1137 OGLDisplay oglDisplay = display.driverData;
1138 OGLSystem oglSystem = display.displaySystem.driverData;
1141 oglDisplay = display.driverData = OGLDisplay { };
1142 oglDisplay.capabilities = oglSystem.capabilities;
1144 #if defined(__WIN32__) || defined(USEPBUFFER)
1145 if(!display.alphaBlend)
1148 #if defined(__WIN32__)
1149 oglDisplay.hdc = GetDC(display.window);
1150 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1151 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, &oglDisplay.version, &oglDisplay.compat, (*&display.glCapabilities).compatible)))
1153 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1154 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1158 ReleaseDC(display.window, oglDisplay.hdc);
1159 #elif defined(__unix__) || defined(__APPLE__)
1160 # if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1163 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1165 #if defined(__APPLE__)
1166 XVisualInfo template = { 0 };
1167 XWindowAttributes winAttr;
1169 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1170 template.visualid = XVisualIDFromVisual(winAttr.visual);
1171 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1173 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1174 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1175 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1176 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1178 // visualInfo = oglSystem.visualInfo;
1181 #if !defined(__APPLE__)
1182 oglDisplay.compat = true;
1183 oglDisplay.version = 4;
1188 //printf("visualInfo is not null\n");
1189 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1190 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1191 //XFree(visualInfo);
1194 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1195 if(oglDisplay.glContext)
1197 //printf("CreateDisplay Got a Context\n");
1198 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1204 #if defined(__WIN32__) || defined(USEPBUFFER)
1208 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1213 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1216 PrintLn("Calling ogl_LoadFunctions() in CreateDisplay()");
1218 if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
1219 PrintLn("ogl_LoadFunctions() failed!");
1222 PrintLn("CheckCapabilities()");
1224 CheckCapabilities(oglSystem, oglDisplay);
1227 PrintLn("vboAvailable is: ", vboAvailable);
1230 # ifdef GL_DEBUGGING
1231 if(oglDisplay.capabilities.debug)
1234 oglDisplay.capabilities.debug = false;
1239 #if defined(__EMSCRIPTEN__)
1240 emscripten_webgl_make_context_current(oglSystem.glc);
1245 GLCapabilities capabilities = *&display.glCapabilities;
1246 // PrintLn("Available OpenGL Capabilities: ", oglDisplay.capabilities);
1247 // PrintLn("Desired OpenGL Capabilities: ", capabilities);
1249 oglDisplay.originalCapabilities = oglDisplay.capabilities;
1251 // Re-enable glCaps_shaders if no fixed function support
1252 if(!oglDisplay.capabilities.fixedFunction)
1253 capabilities.shaders = true;
1254 // Re-enable fixed function if no glCaps_shaders support
1255 if(!oglDisplay.capabilities.shaders)
1257 capabilities.fixedFunction = true;
1258 capabilities.shaders = false;
1261 // Disable things that don't work with glCaps_shaders
1262 if(capabilities.shaders)
1264 capabilities.fixedFunction = false;
1265 capabilities.legacy = false;
1266 capabilities.immediate = false;
1269 #if !ENABLE_GL_POINTER
1270 // Re-enable vertex buffer if no pointer support
1271 capabilities.vertexBuffer = true;
1274 oglDisplay.capabilities &= capabilities;
1276 // PrintLn("Selected OpenGL Capabilities: ", oglDisplay.capabilities);
1277 oglSystem.capabilities = oglDisplay.capabilities;
1281 if(oglDisplay.capabilities.vao)
1283 glGenVertexArrays(1, &oglDisplay.vao);
1284 glBindVertexArray(oglDisplay.vao);
1288 initialDisplaySetup(display);
1291 if(!useSingleGLContext)
1293 #if defined(__WIN32__)
1294 wglMakeCurrent(null, null);
1295 #elif defined(__unix__) || defined(__APPLE__)
1296 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1299 glXMakeCurrent(xGlobalDisplay, None, null);
1305 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1312 bool DisplaySize(Display display, int width, int height)
1314 OGLDisplay oglDisplay = display.driverData;
1315 bool result = false;
1317 #if defined(__WIN32__) || defined(USEPBUFFER)
1318 OGLSystem oglSystem = display.displaySystem.driverData;
1319 if(display.alphaBlend)
1321 #if defined(__WIN32__)
1322 const int attributes[]=
1324 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1325 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1327 int pixelFormat = 0;
1328 if(wglChoosePixelFormatARB)
1332 float fAttributes[] = {0,0};
1335 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1336 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1337 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1338 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1339 WGL_COLOR_BITS_ARB,24,
1340 WGL_ALPHA_BITS_ARB,8,
1341 WGL_DEPTH_BITS_ARB,16,
1342 WGL_STENCIL_BITS_ARB,0,
1343 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1344 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1345 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1349 //Log("Found wglChoosePixelFormatARB\n");
1351 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1352 if(!valid || !numFormats)
1354 //Log("Can't find 4x multi sampling\n");
1355 iAttributes[19] = 2;
1356 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1357 if(!valid || !numFormats)
1359 // Log("Can't find 2x multi sampling\n");
1360 iAttributes[16] = 0;
1361 iAttributes[17] = 0;
1362 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1363 if(!valid || !numFormats)
1367 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1368 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1369 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1370 WGL_COLOR_BITS_ARB,24,
1371 WGL_ALPHA_BITS_ARB,8,
1372 WGL_DEPTH_BITS_ARB,16,
1375 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1379 if(valid && numFormats)
1381 wglMakeCurrent(null, null);
1385 wglMakeCurrent( null, null );
1386 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1387 if(oglDisplay.hdc && oglDisplay.pBuffer)
1388 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1390 wglDestroyPbufferARB(oglDisplay.pBuffer);
1392 if(!useSingleGLContext)
1393 wglMakeCurrent( null, null );
1396 wglDeleteContext(oglDisplay.glrc);
1398 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1399 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1400 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, null, null, oglDisplay.capabilities.compatible)))
1403 HDC hdc = GetDC(display.window);
1405 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1406 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1408 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1409 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1411 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1413 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1417 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1418 oglDisplay.memDC = CreateCompatibleDC(hdc);
1419 SetMapMode(oglDisplay.memDC, MM_TEXT);
1420 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1421 info->bmiHeader.biPlanes = 1;
1422 info->bmiHeader.biCompression = BI_RGB;
1423 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1424 info->bmiHeader.biWidth = width;
1425 info->bmiHeader.biHeight = height;
1426 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1429 SelectObject(oglDisplay.memDC, newBitmap);
1430 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1433 PIXELFORMATDESCRIPTOR pfd = { 0 };
1434 pfd.nSize = (short)sizeof(pfd);
1436 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1437 pfd.iPixelType = PFD_TYPE_RGBA;
1438 pfd.cColorBits = 32;
1439 //pfd.cAlphaBits = 8;
1440 pfd.cDepthBits = 24;
1441 pfd.iLayerType = PFD_MAIN_PLANE;
1443 oglDisplay.hdc = oglDisplay.memDC;
1445 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1446 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1447 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1449 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1450 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1451 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1456 const int imageSize = width * height * 4;
1458 glGenBuffersARB(2, oglDisplay.imageBuffers);
1460 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1461 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1462 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1463 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1466 oglDisplay.memBitmap = newBitmap;
1467 oglDisplay.stride = width;
1473 ReleaseDC(display.window, hdc);
1475 #elif defined(__unix__) || defined(__APPLE__)
1476 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1481 GLX_DOUBLEBUFFER, True,
1487 GLX_STENCIL_SIZE, 1,
1488 //GLX_DEPTH_SIZE, 24,
1489 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1490 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1496 GLX_PBUFFER_WIDTH, width,
1497 GLX_PBUFFER_HEIGHT, height,
1498 GLX_LARGEST_PBUFFER, False,
1502 // choose a pixel format that meets our minimum requirements
1505 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1508 if(oglDisplay.pixmap)
1510 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1511 oglDisplay.pixmap = None;
1513 if(oglDisplay.shapePixmap)
1515 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1516 oglDisplay.shapePixmap = None;
1519 // Free Shared Memory Pixmap
1520 if(oglDisplay.image)
1522 if(oglDisplay.shminfoShape.shmid != -1)
1524 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1525 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1526 shmdt(oglDisplay.shminfo.shmaddr);
1527 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1529 XDestroyImage(oglDisplay.image);
1530 oglDisplay.image = None;
1532 if(oglDisplay.shapeImage)
1534 if(oglDisplay.shminfoShape.shmid != -1)
1536 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1537 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1538 shmdt(oglDisplay.shminfoShape.shmaddr);
1539 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1541 XDestroyImage(oglDisplay.shapeImage);
1542 oglDisplay.shapeImage = None;
1545 if(oglDisplay.windowPicture)
1546 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1547 if(oglDisplay.pixmapPicture)
1548 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1550 if(oglDisplay.pixmap)
1551 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1553 if(oglDisplay.glContext)
1554 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1555 if(oglDisplay.pBuffer)
1556 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1558 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1559 if(oglDisplay.pBuffer)
1561 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1562 if(oglDisplay.glContext)
1564 glXMakeCurrent(xGlobalDisplay, None, null);
1565 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1567 // Initialize Shared Memory Pixmap
1568 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1569 ZPixmap, null, &oglDisplay.shminfo, width, height);
1570 if(oglDisplay.image)
1572 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1573 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1574 if(oglDisplay.shminfo.shmid != -1)
1576 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1577 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1579 oglDisplay.shminfo.readOnly = False;
1580 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1582 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1583 &oglDisplay.shminfo, width, height, 32);
1585 // Initialize Shared Memory Shape Pixmap
1586 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1587 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1588 if(oglDisplay.shapeImage)
1590 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1591 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1592 if(oglDisplay.shminfoShape.shmid != -1)
1594 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1595 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1597 oglDisplay.shminfoShape.readOnly = False;
1598 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1600 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1601 &oglDisplay.shminfoShape, width, height, 1);
1602 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1605 XRenderPictureAttributes attributes = { 0 };
1606 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1607 #if !defined(__APPLE__)
1608 attributes.repeat = RepeatNormal;
1610 attributes.repeat = 1;
1612 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1613 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1614 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1615 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1618 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1619 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1636 CreateDisplay(display);
1637 #if defined(__WIN32__)
1638 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1639 #elif defined(__unix__) || defined(__APPLE__)
1640 #if defined(__ANDROID__) || defined(__ODROID__)
1643 #elif defined(__EMSCRIPTEN__)
1644 emscripten_webgl_make_context_current(oglSystem.glc);
1646 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1654 SETCAPS(oglDisplay.capabilities);
1656 if(display.alphaBlend && result)
1657 initialDisplaySetup(display);
1659 if(!result && display.alphaBlend)
1661 printf("Alpha blending windows not supported on this display\n");
1668 glViewport(0,0,width,height);
1669 GLMatrixMode(MatrixMode::projection);
1671 GLOrtho(0,width,height,0,0.0,1.0);
1672 displayWidth = display.width = width;
1673 displayHeight = display.height = height;
1675 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1677 oglDisplay.flipBufW = width;
1678 oglDisplay.flipBufH = height;
1679 #if defined(_GLES) || defined(_GLES2)
1682 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1685 if(oglDisplay.flippingBuffer || !width || !height)
1691 void DisplayPosition(Display display, int x, int y)
1693 OGLDisplay oglDisplay = display.driverData;
1699 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1703 void RestorePalette(Display display)
1707 void StartUpdate(Display display)
1712 OGLDisplay oglDisplay = display.driverData;
1713 glBindVertexArray(oglDisplay.vao);
1716 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1717 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1720 void EndUpdate(Display display)
1724 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1728 void Update(Display display, Box updateBox)
1730 #if defined(__WIN32__) || defined(USEPBUFFER)
1731 OGLDisplay oglDisplay = display.driverData;
1734 #if !defined(__ANDROID__)
1739 #if defined(__WIN32__) || defined(USEPBUFFER)
1740 if(display.alphaBlend)
1742 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1743 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1744 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1745 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1746 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1749 #if defined(__WIN32__)
1751 POINT point = { oglDisplay.x, oglDisplay.y};
1752 POINT srcPoint = { 0, 0 };
1753 BLENDFUNCTION blend = { 0 };
1755 size.cx = display.width;
1756 size.cy = display.height;
1757 blend.BlendOp = AC_SRC_OVER;
1758 blend.BlendFlags = 0;
1759 blend.SourceConstantAlpha = 255;
1760 blend.AlphaFormat = AC_SRC_ALPHA;
1763 // Process partial images. Mapping the buffer waits for
1764 // outstanding DMA transfers into the buffer to finish.
1765 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1766 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1768 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1769 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1772 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1773 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1776 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1779 // Unmap the image buffers
1780 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1781 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1783 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1784 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1786 // Bind two different buffer objects and start the glReadPixels
1787 // asynchronously. Each call will return directly after
1788 // starting the DMA transfer.
1789 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1790 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1792 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1793 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1797 #elif defined(__unix__) || defined(__APPLE__)
1798 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1800 XTransform transform =
1803 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1804 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1805 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1808 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1809 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1810 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1811 #if !defined(__APPLE__)
1812 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1814 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1816 XFlush(xGlobalDisplay);
1824 #if defined(__WIN32__)
1825 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1826 SwapBuffers(oglDisplay.hdc);
1827 //ecere::sys::Sleep(0.1);
1828 #elif defined(__unix__) || defined(__APPLE__)
1829 #if defined(__ANDROID__) || defined(__ODROID__)
1831 #elif defined(__EMSCRIPTEN__)
1833 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1839 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1841 if(bitmap.driverData)
1843 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1844 glDeleteTextures(1, &tex);
1845 bitmap.driverData = 0;
1847 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1850 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1852 OGLSystem oglSystem = displaySystem.driverData;
1853 GLCapabilities capabilities = oglSystem.capabilities;
1854 bool result = false;
1856 GLuint glBitmap = 0;
1858 uint w = width, h = height;
1859 if(!capabilities.nonPow2Textures)
1864 w = Min(w, oglSystem.maxTextureSize);
1865 h = Min(h, oglSystem.maxTextureSize);
1867 glGenTextures(1, &glBitmap);
1868 glBindTexture(GL_TEXTURE_2D, glBitmap);
1870 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1872 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1873 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1875 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1876 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1879 if(!capabilities.shaders)
1880 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1883 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1885 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1886 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1890 bitmap.driverData = (void *)(uintptr)glBitmap;
1891 bitmap.driver = displaySystem.driver;
1899 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1901 bool result = false;
1902 OGLSystem oglSystem = displaySystem.driverData;
1903 GLCapabilities capabilities = oglSystem.capabilities;
1904 Bitmap convBitmap = bitmap;
1908 convBitmap.Copy(bitmap);
1911 // Pre process the bitmap... First make it 32 bit
1912 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1915 uint w = bitmap.width, h = bitmap.height;
1916 GLuint glBitmap = 0;
1917 if(!capabilities.nonPow2Textures)
1922 w = Min(w, oglSystem.maxTextureSize);
1923 h = Min(h, oglSystem.maxTextureSize);
1927 while(w * 2 < h) w *= 2;
1928 while(h * 2 < w) h *= 2;
1931 // Switch ARGB to RGBA
1932 //if(bitmap.format != pixelFormatRGBA)
1934 for(c=0; c<bitmap.size; c++)
1936 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1938 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1939 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1942 // convBitmap.pixelFormat = pixelFormat888;
1945 glGenTextures(1, &glBitmap);
1948 //int error = glGetError();
1952 glBindTexture(GL_TEXTURE_2D, glBitmap);
1953 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1955 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1956 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1958 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1960 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1961 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1963 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1964 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1965 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1966 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1970 if(!capabilities.shaders)
1971 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1976 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1981 if(bitmap.width != w || bitmap.height != h)
1983 mipMap = Bitmap { };
1984 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1986 Surface mipSurface = mipMap.GetSurface(0,0,null);
1987 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1997 mipMap = convBitmap;
2004 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2005 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2006 //printf("Calling glTexImage2D\n");
2007 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2008 //printf("width = %d (Should be %d, %d)\n", width, w, h);
2009 if((error = glGetError()))
2011 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2012 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2016 if(mipMap != convBitmap)
2021 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2022 bitmap.driverData = (void *)(uintptr)glBitmap;
2023 bitmap.driver = displaySystem.driver;
2028 FreeBitmap(displaySystem, bitmap);
2029 else if(oglSystem.loadingFont)
2031 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2032 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2033 oglSystem.loadingFont = false;
2039 void ReleaseSurface(Display display, Surface surface)
2041 glDisable(GL_SCISSOR_TEST);
2042 delete surface.driverData;
2043 surface.driverData = null;
2046 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2051 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2053 bool result = false;
2054 OGLDisplay oglDisplay = display.driverData;
2055 OGLSurface oglSurface = surface.driverData = OGLSurface { };
2058 SETCAPS(oglDisplay.capabilities);
2059 if(displayWidth != display.width || displayHeight != display.height)
2061 displayWidth = display.width;
2062 displayHeight = display.height;
2064 glViewport(0,0,display.width,display.height);
2066 GLOrtho(0,display.width,display.height,0,0.0,1.0);
2069 surface.offset.x = x;
2070 surface.offset.y = y;
2071 surface.unclippedBox = surface.box = clip;
2072 oglSurface.bitmapMult[0] = 1;
2073 oglSurface.bitmapMult[1] = 1;
2074 oglSurface.bitmapMult[2] = 1;
2075 oglSurface.bitmapMult[3] = 1;
2077 glEnable(GL_SCISSOR_TEST);
2080 (display.height) -(y+clip.bottom)-1,
2081 clip.right-clip.left+1,
2082 clip.bottom-clip.top+1);
2088 void Clip(Display display, Surface surface, Box clip)
2095 box.Clip(surface.unclippedBox);
2099 box = surface.box = surface.unclippedBox;
2100 box.left += surface.offset.x;
2101 box.top += surface.offset.y;
2102 box.right+= surface.offset.x;
2103 box.bottom += surface.offset.y;
2106 box.left,display.height - box.bottom - 1,
2107 box.right-box.left+1, box.bottom-box.top+1);
2110 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2112 bool result = false;
2113 OGLDisplay oglDisplay = display.driverData;
2114 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2116 if(oglDisplay.flippingBuffer)
2118 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2121 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2127 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2128 #if ENABLE_GL_LEGACY
2129 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2130 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2131 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2133 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2136 for(row = 0; row<h; row++)
2137 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2144 void SetForeground(Display display, Surface surface, ColorAlpha color)
2146 OGLSurface oglSurface = surface.driverData;
2148 oglSurface.foreground[0] = color.color.r/255.0f;
2149 oglSurface.foreground[1] = color.color.g/255.0f;
2150 oglSurface.foreground[2] = color.color.b/255.0f;
2151 //oglSurface.foreground[3] = 1.0f;
2152 oglSurface.foreground[3] = color.a/255.0f;
2154 //if(!oglSurface.foreground[3])printf("bug");
2157 void SetBackground(Display display, Surface surface, ColorAlpha color)
2159 OGLSurface oglSurface = surface.driverData;
2161 oglSurface.background[0] = color.color.r/255.0f;
2162 oglSurface.background[1] = color.color.g/255.0f;
2163 oglSurface.background[2] = color.color.b/255.0f;
2164 //oglSurface.background[3] = 1.0;
2165 oglSurface.background[3] = color.a/255.0f;
2168 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2170 OGLSurface oglSurface = surface.driverData;
2172 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2173 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2174 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2175 oglSurface.bitmapMult[3] = color.a/255.0f;
2178 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2183 void PutPixel(Display display, Surface surface,int x,int y)
2185 OGLSurface oglSurface = surface.driverData;
2186 GLColor4fv(oglSurface.foreground);
2188 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2189 GLVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2193 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2195 OGLSurface oglSurface = surface.driverData;
2196 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2211 x1 += surface.offset.x;
2212 y1 += surface.offset.y;
2213 x2 += surface.offset.x;
2214 y2 += surface.offset.y;
2216 GLColor4fv(oglSurface.foreground);
2220 GLTexCoord2f(0.5f, 0);
2221 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2222 GLTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2223 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2231 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2232 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2238 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2240 OGLSurface oglSurface = surface.driverData;
2241 x1 += surface.offset.x;
2242 y1 += surface.offset.y;
2243 x2 += surface.offset.x;
2244 y2 += surface.offset.y;
2246 GLColor4fv(oglSurface.foreground);
2251 GLTexCoord2f(0.5f, 0);
2252 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2253 GLTexCoord2f(y2-y1 + 0.5f, 0);
2254 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2256 GLTexCoord2f(0.5f, 0);
2257 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2258 GLTexCoord2f(x2 - x1 + 0.5f, 0);
2259 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2261 GLTexCoord2f(0.5f, 0);
2262 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2263 GLTexCoord2f(y1 - y2 + 0.5f, 0);
2264 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2266 GLTexCoord2f(0.5f, 0);
2267 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2268 GLTexCoord2f(x1 - x2 + 0.5f, 0);
2269 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2273 GLBegin(GL_LINE_LOOP);
2280 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2281 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2282 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2283 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2288 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2290 OGLSurface oglSurface = surface.driverData;
2292 GLColor4fv(oglSurface.background);
2294 GLRecti(x1+surface.offset.x, y1+surface.offset.y,
2295 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2297 GLRectf(x1+surface.offset.x, y1+surface.offset.y,
2298 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2302 void Clear(Display display, Surface surface, ClearType type)
2304 OGLDisplay oglDisplay = display.driverData;
2305 OGLSurface oglSurface = surface.driverData;
2308 if(type != depthBuffer)
2309 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2310 if(type != colorBuffer && !oglDisplay.depthWrite)
2312 glDepthMask((byte)bool::true);
2314 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2315 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2316 if(type != colorBuffer && !oglDisplay.depthWrite)
2318 glDepthMask((byte)bool::false);
2322 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2327 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2329 OGLSurface oglSurface = surface.driverData;
2330 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
2333 if(!oglSurface.writingText)
2335 // glTranslatef(-0.375f, -0.375f, 0.0f);
2336 GLSetupTexturing(true);
2337 GLColor4fv(oglSurface.bitmapMult);
2338 glBindTexture(GL_TEXTURE_2D, tex);
2339 GLBegin(GLIMTKMode::quads);
2341 else if(lastBlitTex != tex)
2345 glBindTexture(GL_TEXTURE_2D, tex);
2346 GLBegin(GLIMTKMode::quads);
2352 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2353 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2354 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2355 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2356 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2357 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2358 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2359 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2364 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2365 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2366 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2367 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2368 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2369 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2370 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2371 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2374 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2375 GLVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2376 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2377 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2378 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2379 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2380 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2381 GLVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2383 if(!oglSurface.writingText)
2386 GLSetupTexturing(false);
2387 //glTranslate(0.375, 0.375, 0.0);
2391 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2393 OGLSurface oglSurface = surface.driverData;
2395 //glTranslate(-0.375, -0.375, 0.0);
2397 GLSetupTexturing(true);
2398 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2400 GLColor4fv(oglSurface.bitmapMult);
2402 GLBegin(GLIMTKMode::quads);
2406 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2407 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2409 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2410 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2412 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2413 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2415 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2416 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2420 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2421 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2423 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2424 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2426 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2427 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2429 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2430 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2435 GLSetupTexturing(false);
2437 //glTranslate(0.375, 0.375, 0.0);
2440 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2442 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2445 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2447 float s2dw,s2dh,d2sw,d2sh;
2448 //bool flipX = false, flipY = false;
2450 if(Sgn(w) != Sgn(sw))
2456 if(Sgn(h) != Sgn(sh))
2468 //Clip against the edges of the source
2471 dx+=(int)((0-sx) * s2dw);
2472 w-=(int)((0-sx) * s2dw);
2478 dy+=(int)((0-sy) * s2dh);
2479 h-=(int)((0-sy) * s2dh);
2484 if(sx+sw>bitmap.width-1)
2486 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2487 sw-=sx+sw-(bitmap.width-1)-1;
2489 if(sy+sh>(bitmap.height-1))
2491 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2492 sh-=sy+sh-(bitmap.height-1)-1;
2494 //Clip against the edges of the surfaceination
2495 if(dx<surface.box.left)
2498 sx+=(int)((surface.box.left-dx)*d2sw);
2499 sw-=(int)((surface.box.left-dx)*d2sw);
2500 w-=surface.box.left-dx;
2501 dx=surface.box.left;
2503 if(dy<surface.box.top)
2505 sy+=(int)((surface.box.top-dy)*d2sh);
2506 sh-=(int)((surface.box.top-dy)*d2sh);
2507 h-=surface.box.top-dy;
2510 if(dx+w>surface.box.right)
2512 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2513 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2514 w-=dx+w-surface.box.right-1;
2516 if(dy+h>surface.box.bottom)
2518 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2519 h-=dy+h-surface.box.bottom-1;
2521 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2523 dx += surface.offset.x;
2524 dy += surface.offset.y;
2526 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2528 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2529 #if ENABLE_GL_LEGACY
2532 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2533 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2534 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2535 glRasterPos2d(dx,dy);
2536 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2537 glPixelZoom(s2dw, -s2dh);
2538 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2539 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2540 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2541 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2544 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2548 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2550 //Clip against the edges of the source
2563 if(sx+w>bitmap.width-1)
2564 w-=sx+w-(bitmap.width-1)-1;
2565 if(sy+h>bitmap.height-1)
2566 h-=sy+h-(bitmap.height-1)-1;
2567 //Clip against the edges of the surfaceination
2568 if(dx<surface.box.left)
2571 sx+=surface.box.left-dx;
2572 w-=surface.box.left-dx;
2573 dx=surface.box.left;
2575 if(dy<surface.box.top)
2577 sy+=surface.box.top-dy;
2578 h-=surface.box.top-dy;
2581 if(dx+w>surface.box.right)
2583 //if(flip) sx+=dx+w-surface.box.right-1;
2584 w-=dx+w-surface.box.right-1;
2586 if(dy+h>surface.box.bottom)
2587 h-=dy+h-surface.box.bottom-1;
2591 dx += surface.offset.x;
2592 dy += surface.offset.y;
2594 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2596 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2597 #if ENABLE_GL_LEGACY
2600 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2601 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2602 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2603 glRasterPos2d(dx,dy);
2605 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2606 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2607 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2608 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2611 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2615 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2617 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2620 void UnloadFont(DisplaySystem displaySystem, Font font)
2622 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2625 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2628 OGLSystem oglSystem = displaySystem.driverData;
2629 oglSystem.loadingFont = true;
2630 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2634 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2636 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2639 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2643 OGLSurface oglSurface = surface.driverData;
2644 OGLSystem oglSystem = display.displaySystem.driverData;
2645 oglSystem.loadingFont = true;
2647 //glTranslated(-0.375, -0.375, 0.0);
2649 if(surface.textOpacity)
2651 int w = 0, h, adv = 0;
2652 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2654 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2657 oglSurface.writingText = true;
2659 GLSetupTexturing(true);
2661 if(surface.font.outlineSize)
2663 ColorAlpha outlineColor = surface.outlineColor;
2664 GLColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2665 oglSurface.writingOutline = true;
2667 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2668 if(lastBlitTex) GLEnd();
2669 oglSurface.writingOutline = false;
2671 GLColor4fv(oglSurface.foreground);
2674 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2675 if(lastBlitTex) GLEnd();
2678 oglSurface.writingText = false;
2679 oglSystem.loadingFont = false;
2681 GLSetupTexturing(false);
2683 //glTranslated(0.375, 0.375, 0.0);
2687 void TextFont(Display display, Surface surface, Font font)
2689 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2692 void TextOpacity(Display display, Surface surface, bool opaque)
2694 OGLSurface oglSurface = surface.driverData;
2695 oglSurface.opaqueText = opaque;
2698 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2700 OGLSurface oglSurface = surface.driverData;
2701 OGLSystem oglSystem = display.displaySystem.driverData;
2702 oglSystem.loadingFont = true;
2703 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2704 oglSystem.loadingFont = false;
2707 void DrawingChar(Display display, Surface surface, char character)
2712 void LineStipple(Display display, Surface surface, uint32 stipple)
2716 #if ENABLE_GL_LEGACY
2719 glLineStipple(1, (uint16)stipple);
2720 glEnable(GL_LINE_STIPPLE);
2725 stippleEnabled = true;
2726 glsupLineStipple(1, (uint16)stipple);
2731 #if ENABLE_GL_LEGACY
2733 glDisable(GL_LINE_STIPPLE);
2737 stippleEnabled = false;
2738 GLMatrixMode(GL_TEXTURE);
2740 GLMatrixMode(MatrixMode::projection);
2741 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2746 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2747 void SetRenderState(Display display, RenderState state, uint value)
2749 OGLDisplay oglDisplay = display.driverData;
2753 #ifndef __EMSCRIPTEN__
2755 glEnable(GL_MULTISAMPLE);
2757 glDisable(GL_MULTISAMPLE);
2761 #if ENABLE_GL_LEGACY
2763 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2767 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2770 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2771 oglDisplay.depthWrite = (bool)value;
2775 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2776 #if ENABLE_GL_SHADERS
2778 shader_fogColor(color[0], color[1], color[2]);
2783 glFogfv(GL_FOG_COLOR, (float *)&color);
2788 #if ENABLE_GL_SHADERS
2790 shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2795 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2799 //#if !defined(__EMSCRIPTEN__)
2800 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2805 #if ENABLE_GL_SHADERS
2807 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2813 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2814 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2821 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2826 #if defined(__WIN32__)
2827 if(wglSwapIntervalEXT)
2828 wglSwapIntervalEXT(value ? 1 : 0);
2835 void SetLight(Display display, int id, Light light)
2837 #if ENABLE_GL_SHADERS
2839 shader_setLight(display, id, light);
2847 Object lightObject = light.lightObject;
2848 float position[4] = { 0, 0, 0, 0 };
2849 float color[4] = { 0, 0, 0, 1 };
2851 glEnable(GL_LIGHT0 + id);
2853 if(!light.multiplier) light.multiplier = 1.0f;
2855 color[0] = light.diffuse.r * light.multiplier;
2856 color[1] = light.diffuse.g * light.multiplier;
2857 color[2] = light.diffuse.b * light.multiplier;
2858 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2860 color[0] = light.ambient.r * light.multiplier;
2861 color[1] = light.ambient.g * light.multiplier;
2862 color[2] = light.ambient.b * light.multiplier;
2863 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2864 color[0] = light.specular.r * light.multiplier;
2865 color[1] = light.specular.g * light.multiplier;
2866 color[2] = light.specular.b * light.multiplier;
2867 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2871 Vector3D positionVector;
2872 if(light.flags.spot)
2874 if(lightObject.flags.root || !lightObject.parent)
2876 positionVector = lightObject.transform.position;
2877 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2881 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2882 if(display.display3D.camera)
2883 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2889 if(!light.direction.x && !light.direction.y && !light.direction.z)
2891 Vector3Df vector { 0,0,-1 };
2893 mat.RotationQuaternion(light.orientation);
2894 positionVector.MultMatrixf(vector, mat);
2898 positionVector = light.direction;
2903 position[0] = (float)positionVector.x;
2904 position[1] = (float)positionVector.y;
2905 position[2] = (float)positionVector.z;
2907 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2910 // Display Light Position
2911 glDisable(GL_LIGHTING);
2912 glDisable(GL_DEPTH_TEST);
2916 glVertex3fv(position);
2918 glEnable(GL_DEPTH_TEST);
2919 glEnable(GL_LIGHTING);
2923 if(lightObject.flags.root || !lightObject.parent)
2925 positionVector = light.target.transform.position;
2926 positionVector.Subtract(positionVector, display.camera.cPosition);
2930 positionVector.MultMatrix(light.target.transform.position,
2931 lightObject.light.target.parent.matrix);
2932 positionVector.Subtract(positionVector, display.camera.cPosition);
2935 position[0] = positionVector.x;
2936 position[1] = positionVector.y;
2937 position[2] = positionVector.z;
2939 glDisable(GL_LIGHTING);
2940 glDisable(GL_DEPTH_TEST);
2944 glVertex3fv(position);
2946 glEnable(GL_DEPTH_TEST);
2947 glEnable(GL_LIGHTING);
2950 if(light.flags.attenuation)
2952 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2953 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2954 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2957 if(light.flags.spot)
2960 #define MAXLIGHT 0.9
2961 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2962 // Figure out exponent out of the hot spot
2963 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2965 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2966 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2967 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2972 Vector3Df vector { 0,0,-1 };
2973 Vector3Df direction;
2976 mat.RotationQuaternion(light.orientation);
2977 direction.MultMatrix(vector, mat);
2979 position[0] = direction.x;
2980 position[1] = direction.y;
2981 position[2] = direction.z;
2983 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2987 glDisable(GL_LIGHT0 + id);
2992 void SetCamera(Display display, Surface surface, Camera camera)
2994 OGLDisplay oglDisplay = display.driverData;
2996 if(surface && camera)
2998 int left = surface.box.left + surface.offset.x;
2999 int top = surface.box.top + surface.offset.y;
3000 int right = surface.box.right + surface.offset.x;
3001 int bottom = surface.box.bottom + surface.offset.y;
3002 float origX = surface.offset.x + camera.origin.x;
3003 float origY = surface.offset.y + camera.origin.y;
3005 int y = display.height - bottom - 1;
3006 int w = right - left + 1;
3007 int h = bottom - top + 1;
3010 glViewport(x, y, w, h);
3012 // *** Projection Matrix ***
3013 GLMatrixMode(MatrixMode::projection);
3014 if(!display.display3D.camera)
3017 if(display.display3D.collectingHits)
3019 float pickX = display.display3D.pickX + surface.offset.x;
3020 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3024 w / display.display3D.pickWidth, 0, 0, 0,
3025 0, h / display.display3D.pickHeight, 0, 0,
3027 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3028 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3031 GLLoadMatrixd(pickMatrix.array);
3036 (left - origX) * camera.zMin / camera.focalX,
3037 (right - origX) * camera.zMin / camera.focalX,
3038 (bottom - origY) * camera.zMin / camera.focalY,
3039 (top - origY) * camera.zMin / camera.focalY,
3040 camera.zMin, camera.zMax);
3042 glDisable(GL_BLEND);
3044 // *** Z Inverted Identity Matrix ***
3045 GLMatrixMode(MatrixMode::modelView);
3046 if(!display.display3D.camera)
3051 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3053 // *** View Matrix ***
3054 GLMultMatrixd(camera.viewMatrix.array);
3059 glEnable(GL_DEPTH_TEST);
3061 GLSetupLighting(true);
3064 glShadeModel(GL_SMOOTH);
3066 glDepthMask((byte)bool::true);
3067 oglDisplay.depthWrite = true;
3069 #ifndef __EMSCRIPTEN__
3070 glEnable(GL_MULTISAMPLE);
3073 else if(surface && display.display3D.camera)
3076 oglDisplay.depthWrite = false;
3077 glViewport(0,0,display.width,display.height);
3079 glDisable(GL_CULL_FACE);
3080 glDisable(GL_DEPTH_TEST);
3082 GLSetupTexturing(false);
3083 GLSetupLighting(false);
3086 GLDisableClientState(COLORS);
3088 #if ENABLE_GL_SHADERS
3090 shader_setPerVertexColor(false);
3095 glShadeModel(GL_FLAT);
3098 #if !defined(__EMSCRIPTEN__)
3099 glDisable(GL_MULTISAMPLE);
3102 // *** Restore 2D MODELVIEW Matrix ***
3105 // *** Restore 2D PROJECTION Matrix ***
3106 GLMatrixMode(MatrixMode::projection);
3112 void ApplyMaterial(Display display, Material material, Mesh mesh)
3115 if(material.flags.doubleSided)
3119 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3121 glDisable(GL_CULL_FACE);
3127 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3129 glEnable(GL_CULL_FACE);
3133 GLSetupFog(!material.flags.noFog);
3136 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3138 Bitmap map = material.baseMap;
3139 GLSetupTexturing(true);
3140 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3142 GLMatrixMode(GL_TEXTURE);
3144 if(material.uScale && material.vScale)
3145 GLScalef(material.uScale, material.vScale, 1);
3146 GLMatrixMode(MatrixMode::modelView);
3148 if(material.flags.tile)
3150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3155 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3156 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3160 GLSetupTexturing(false);
3162 #if ENABLE_GL_SHADERS
3164 shader_setMaterial(material, mesh.flags.colors);
3170 if(mesh.flags.colors)
3172 GLColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3173 glEnable(GL_COLOR_MATERIAL);
3177 glDisable(GL_COLOR_MATERIAL);
3179 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3180 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3183 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3184 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3188 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3189 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3192 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3193 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3196 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3201 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3203 OGLMesh oglMesh = mesh.data;
3206 OGLSystem oglSystem = displaySystem.driverData;
3207 SETCAPS(oglSystem.capabilities);
3208 if(!mesh.flags.vertices)
3210 oglMesh.vertices.free(glCaps_vertexBuffer);
3211 delete mesh.vertices;
3213 if(!mesh.flags.normals)
3215 oglMesh.normals.free(glCaps_vertexBuffer);
3216 delete mesh.normals;
3218 if(!mesh.flags.texCoords1)
3220 oglMesh.texCoords.free(glCaps_vertexBuffer);
3221 delete mesh.texCoords;
3223 if(!mesh.flags.texCoords2)
3225 oglMesh.texCoords2.free(glCaps_vertexBuffer);
3226 // delete mesh.texCoords2;
3228 if(!mesh.flags.colors)
3230 oglMesh.colors.free(glCaps_vertexBuffer);
3241 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3243 bool result = false;
3246 mesh.data = OGLMesh { };
3249 if(mesh.nVertices == nVertices)
3251 // Same number of vertices, adding features (Leaves the other features pointers alone)
3252 if(mesh.flags != flags)
3254 if(!mesh.flags.vertices && flags.vertices)
3256 if(flags.doubleVertices)
3258 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3261 mesh.vertices = new Vector3Df[nVertices];
3263 if(!mesh.flags.normals && flags.normals)
3265 if(flags.doubleNormals)
3267 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3270 mesh.normals = new Vector3Df[nVertices];
3272 if(!mesh.flags.texCoords1 && flags.texCoords1)
3274 mesh.texCoords = new Pointf[nVertices];
3276 if(!mesh.flags.colors && flags.colors)
3278 mesh.colors = new ColorRGBAf[nVertices];
3284 // New number of vertices, reallocate all current and new features
3285 flags |= mesh.flags;
3288 if(flags.doubleVertices)
3290 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3293 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3297 if(flags.doubleNormals)
3299 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3302 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3304 if(flags.texCoords1)
3306 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3310 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3318 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3320 OGLSystem oglSystem = displaySystem.driverData;
3321 SETCAPS(oglSystem.capabilities);
3322 if(glCaps_vertexBuffer)
3324 OGLMesh oglMesh = mesh.data;
3325 if(!flags) flags = mesh.flags;
3327 oglMesh.vertices.allocate(
3328 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, staticDraw);
3331 oglMesh.normals.allocate(
3332 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, staticDraw);
3334 if(flags.texCoords1)
3335 oglMesh.texCoords.allocate(
3336 mesh.nVertices * sizeof(Pointf), mesh.texCoords, staticDraw);
3339 oglMesh.colors.allocate(
3340 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, staticDraw);
3344 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3351 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3353 OGLSystem oglSystem = displaySystem.driverData;
3354 SETCAPS(oglSystem.capabilities);
3357 oglIndices.buffer.free(glCaps_vertexBuffer);
3358 delete oglIndices.indices;
3363 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3365 OGLIndices oglIndices = OGLIndices { };
3368 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3369 oglIndices.nIndices = nIndices;
3374 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3376 OGLSystem oglSystem = displaySystem.driverData;
3377 SETCAPS(oglSystem.capabilities);
3378 if(glCaps_vertexBuffer)
3380 if(!glCaps_intAndDouble && indices32bit)
3382 if(!oglIndices.buffer.buffer)
3383 glGenBuffers(1, &oglIndices.buffer.buffer);
3384 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3385 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3388 uint * pointer = (uint *)oglIndices.indices;
3391 if(nIndices > oglSystem.shortBDSize)
3393 oglSystem.shortBDSize = nIndices;
3394 oglSystem.shortBDBuffer = renew oglSystem.shortBDBuffer uint16[oglSystem.shortBDSize];
3396 b = oglSystem.shortBDBuffer;
3397 for(i = 0; i < nIndices; i++)
3398 b[i] = (uint16)pointer[i];
3400 glBufferData(GL_ELEMENT_ARRAY_BUFFER, nIndices * sizeof(uint16), b, GL_STATIC_DRAW);
3404 oglIndices.buffer.allocate(
3405 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3406 oglIndices.indices, staticDraw);
3410 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3413 return oglIndices.indices;
3416 void SelectMesh(Display display, Mesh mesh)
3418 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3419 #if defined(__WIN32__)
3420 if(glUnlockArraysEXT)
3422 if(!glCaps_vertexBuffer && display.display3D.mesh)
3423 glUnlockArraysEXT();
3427 OGLMesh oglMesh = mesh.data;
3429 // *** Vertex Stream ***
3430 GLEnableClientState(VERTICES);
3431 if(!display.display3D.collectingHits && oglMesh)
3433 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3435 // *** Normals Stream ***
3436 if(mesh.normals || mesh.flags.normals)
3438 GLEnableClientState(NORMALS);
3439 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3442 GLDisableClientState(NORMALS);
3444 // *** Texture Coordinates Stream ***
3445 if(mesh.texCoords || mesh.flags.texCoords1)
3447 GLEnableClientState(TEXCOORDS);
3448 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3451 GLDisableClientState(TEXCOORDS);
3453 // *** Color Stream ***
3454 if(mesh.colors || mesh.flags.colors)
3456 GLEnableClientState(COLORS);
3457 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3460 GLDisableClientState(COLORS);
3464 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3465 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3467 GLEnableClientState(NORMALS);
3468 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3471 GLDisableClientState(NORMALS);
3472 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3474 GLEnableClientState(TEXCOORDS);
3475 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3478 GLDisableClientState(TEXCOORDS);
3479 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3481 GLEnableClientState(COLORS);
3482 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3485 GLDisableClientState(COLORS);
3488 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3490 #if defined(__WIN32__)
3493 if(!glCaps_vertexBuffer)
3494 glLockArraysEXT(0, mesh.nVertices);
3499 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3501 if(primitive->type.vertexRange)
3504 glDrawArrays(getPrimitiveType(primitive->type.primitiveType), primitive->first, primitive->nVertices);
3508 OGLIndices oglIndices = primitive->data;
3509 GLEAB eab = ((!display.display3D.collectingHits && oglIndices && glCaps_vertexBuffer) ? oglIndices.buffer : noEAB);
3510 if(!glCaps_intAndDouble && !glCaps_vertexBuffer && primitive->type.indices32bit)
3512 uint16 * temp = new uint16[primitive->nIndices];
3513 uint32 * src = (uint32 *)(oglIndices ? oglIndices.indices : primitive->indices);
3515 for(i = 0; i < primitive->nIndices; i++)
3516 temp[i] = (uint16)src[i];
3517 eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices, GL_UNSIGNED_SHORT, temp);
3521 eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices,
3522 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3523 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3524 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3528 void PushMatrix(Display display)
3533 void PopMatrix(Display display, bool setMatrix)
3538 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3540 Matrix matrix = transMatrix;
3541 Camera camera = useCamera ? display.display3D.camera : null;
3546 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3551 matrix.m[3][0] - camera.cPosition.x,
3552 matrix.m[3][1] - camera.cPosition.y,
3553 matrix.m[3][2] - camera.cPosition.z);
3565 GLMultMatrixd(matrix.array);
3570 public void UseSingleGLContext(bool useSingle)
3572 useSingleGLContext = useSingle;
3575 default dllexport void *
3576 #if defined(__WIN32__)
3577 __attribute__((stdcall))
3579 IS_GLGetContext(DisplaySystem displaySystem)
3583 #if defined(__WIN32__)
3584 OGLSystem system = displaySystem.driverData;
3586 #elif defined(__ANDROID__) || defined(__ODROID__)
3588 #elif defined(__EMSCRIPTEN__)
3589 OGLSystem system = displaySystem.driverData;
3590 return (void *)system.glc;
3592 OGLSystem system = displaySystem.driverData;
3593 return system.glContext;