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, bool canCheckExtensions)
666 GLCapabilities capabilities;
668 const char * extensions = (canCheckExtensions && oglDisplay.compat) ? (const char *)glGetString(GL_EXTENSIONS) : null;
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 = glGetStringi || (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, true);
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, bool canCheckExtensions, bool loadExtensions)
1038 OGLDisplay oglDisplay = display.driverData;
1039 OGLSystem oglSystem = display.displaySystem.driverData;
1042 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1043 if(loadExtensions && ogl_LoadFunctions() == ogl_LOAD_FAILED)
1044 PrintLn("ogl_LoadFunctions() failed!");
1045 CheckCapabilities(oglSystem, oglDisplay, canCheckExtensions);
1047 if(oglDisplay.capabilities.debug)
1050 oglDisplay.capabilities.debug = false;
1055 GLCapabilities capabilities = *&display.glCapabilities;
1056 // PrintLn("Available OpenGL Capabilities: ", oglDisplay.capabilities);
1057 // PrintLn("Desired OpenGL Capabilities: ", capabilities);
1059 oglDisplay.originalCapabilities = oglDisplay.capabilities;
1061 // Re-enable glCaps_shaders if no fixed function support
1062 if(!oglDisplay.capabilities.fixedFunction)
1063 capabilities.shaders = true;
1064 // Re-enable fixed function if no glCaps_shaders support
1065 if(!oglDisplay.capabilities.shaders)
1067 capabilities.fixedFunction = true;
1068 capabilities.shaders = false;
1071 if(!capabilities.shaders && !capabilities.fixedFunction)
1073 capabilities.fixedFunction = oglDisplay.capabilities.fixedFunction;
1074 capabilities.shaders = oglDisplay.capabilities.shaders;
1077 // Disable things that don't work with glCaps_shaders
1078 if(capabilities.shaders)
1080 capabilities.fixedFunction = false;
1081 capabilities.legacy = false;
1082 capabilities.immediate = false;
1085 #if !ENABLE_GL_POINTER
1086 // Re-enable vertex buffer if no pointer support
1087 capabilities.vertexBuffer = true;
1090 oglDisplay.capabilities &= capabilities;
1092 // PrintLn("Selected OpenGL Capabilities: ", oglDisplay.capabilities);
1093 oglSystem.capabilities = oglDisplay.capabilities;
1097 if(oglDisplay.capabilities.vao)
1099 glGenVertexArrays(1, &oglDisplay.vao);
1100 glBindVertexArray(oglDisplay.vao);
1104 oglSystem.capabilities = oglDisplay.capabilities;
1105 SETCAPS(oglDisplay.capabilities);
1107 #if ENABLE_GL_SHADERS
1110 #if ENABLE_GL_LEGACY
1111 if(oglDisplay.compat)
1113 glDisableClientState(GL_VERTEX_ARRAY);
1114 glDisableClientState(GL_NORMAL_ARRAY);
1115 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1116 glDisableClientState(GL_COLOR_ARRAY);
1119 loadShaders(display.displaySystem, "<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1121 #if ENABLE_GL_LEGACY
1124 glDisableVertexAttribArray(GLBufferContents::color);
1125 glDisableVertexAttribArray(GLBufferContents::normal);
1126 glDisableVertexAttribArray(GLBufferContents::texCoord);
1127 glDisableVertexAttribArray(GLBufferContents::vertex);
1128 glBindVertexArray(0);
1137 glBindVertexArray(oglDisplay.vao);
1140 GLEnableClientState(VERTICES);
1142 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1143 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1145 #if defined(__WIN32__)
1146 if(glBlendFuncSeparate)
1147 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1149 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1151 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1155 GLMatrixMode(MatrixMode::texture);
1158 GLMatrixMode(MatrixMode::modelView);
1159 GLLoadIdentity(); // For setting up GLES stack
1160 GLScaled(1.0, 1.0, -1.0);
1161 // glTranslatef(0.375f, 0.375f, 0.0f);
1162 // glTranslatef(-0.625f, -0.625f, 0.0f);
1163 GLMatrixMode(MatrixMode::projection);
1165 if(display.width && display.height)
1166 GLOrtho(0,display.width,display.height,0,0.0,1.0);
1171 glShadeModel(GL_FLAT);
1173 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1174 GLLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1177 ;//GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1179 glFogi(GL_FOG_MODE, GL_EXP);
1180 glFogf(GL_FOG_DENSITY, 0);
1181 glEnable(GL_NORMALIZE);
1184 glDepthFunc(GL_LESS);
1186 #if !defined(__EMSCRIPTEN__)
1187 glDisable(GL_MULTISAMPLE);
1190 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1191 display.ambient = Color { 50,50,50 };
1196 bool CreateDisplay(Display display)
1198 bool result = false;
1199 OGLDisplay oglDisplay = display.driverData;
1200 OGLSystem oglSystem = display.displaySystem.driverData;
1203 oglDisplay = display.driverData = OGLDisplay { };
1204 oglDisplay.capabilities = oglSystem.capabilities;
1206 #if defined(__WIN32__) || defined(USEPBUFFER)
1207 if(!display.alphaBlend)
1210 #if defined(__WIN32__)
1211 oglDisplay.hdc = GetDC(display.window);
1212 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1213 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, &oglDisplay.version, &oglDisplay.compat, (*&display.glCapabilities).compatible)))
1215 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1216 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1220 ReleaseDC(display.window, oglDisplay.hdc);
1221 #elif defined(__unix__) || defined(__APPLE__)
1222 # if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1225 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1227 #if defined(__APPLE__)
1228 XVisualInfo template = { 0 };
1229 XWindowAttributes winAttr;
1231 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1232 template.visualid = XVisualIDFromVisual(winAttr.visual);
1233 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1235 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1236 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1237 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1238 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1240 // visualInfo = oglSystem.visualInfo;
1243 #if !defined(__APPLE__)
1244 oglDisplay.compat = true;
1245 oglDisplay.version = 4;
1250 //printf("visualInfo is not null\n");
1251 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1252 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1253 //XFree(visualInfo);
1256 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1257 if(oglDisplay.glContext)
1259 //printf("CreateDisplay Got a Context\n");
1260 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1266 #if defined(__WIN32__) || defined(USEPBUFFER)
1269 oglDisplay.compat = (*&display.glCapabilities).compatible;
1271 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1276 #if defined(__EMSCRIPTEN__)
1277 emscripten_webgl_make_context_current(oglSystem.glc);
1280 #if defined(__WIN32__) || defined(USEPBUFFER)
1281 initialDisplaySetup(display, !display.alphaBlend, true);
1283 initialDisplaySetup(display, true, true);
1287 if(!useSingleGLContext)
1289 #if defined(__WIN32__)
1290 wglMakeCurrent(null, null);
1291 #elif defined(__unix__) || defined(__APPLE__)
1292 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1295 glXMakeCurrent(xGlobalDisplay, None, null);
1301 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1308 bool DisplaySize(Display display, int width, int height)
1310 OGLDisplay oglDisplay = display.driverData;
1311 bool result = false;
1313 #if defined(__WIN32__) || defined(USEPBUFFER)
1314 OGLSystem oglSystem = display.displaySystem.driverData;
1315 if(display.alphaBlend)
1317 #if defined(__WIN32__)
1318 const int attributes[]=
1320 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1321 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1323 int pixelFormat = 0;
1324 if(wglChoosePixelFormatARB)
1328 float fAttributes[] = {0,0};
1331 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1332 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1333 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1334 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1335 WGL_COLOR_BITS_ARB,24,
1336 WGL_ALPHA_BITS_ARB,8,
1337 WGL_DEPTH_BITS_ARB,16,
1338 WGL_STENCIL_BITS_ARB,0,
1339 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1340 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1341 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1345 //Log("Found wglChoosePixelFormatARB\n");
1347 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1348 if(!valid || !numFormats)
1350 //Log("Can't find 4x multi sampling\n");
1351 iAttributes[19] = 2;
1352 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1353 if(!valid || !numFormats)
1355 // Log("Can't find 2x multi sampling\n");
1356 iAttributes[16] = 0;
1357 iAttributes[17] = 0;
1358 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1359 if(!valid || !numFormats)
1363 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1364 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1365 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1366 WGL_COLOR_BITS_ARB,24,
1367 WGL_ALPHA_BITS_ARB,8,
1368 WGL_DEPTH_BITS_ARB,16,
1371 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1375 if(valid && numFormats)
1377 wglMakeCurrent(null, null);
1381 wglMakeCurrent( null, null );
1382 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1383 if(oglDisplay.hdc && oglDisplay.pBuffer)
1384 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1386 wglDestroyPbufferARB(oglDisplay.pBuffer);
1388 if(!useSingleGLContext)
1389 wglMakeCurrent( null, null );
1392 wglDeleteContext(oglDisplay.glrc);
1394 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1395 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1396 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, null, null, oglDisplay.capabilities.compatible)))
1399 HDC hdc = GetDC(display.window);
1401 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1402 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1404 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1405 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1407 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1409 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1413 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1414 oglDisplay.memDC = CreateCompatibleDC(hdc);
1415 SetMapMode(oglDisplay.memDC, MM_TEXT);
1416 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1417 info->bmiHeader.biPlanes = 1;
1418 info->bmiHeader.biCompression = BI_RGB;
1419 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1420 info->bmiHeader.biWidth = width;
1421 info->bmiHeader.biHeight = height;
1422 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1425 SelectObject(oglDisplay.memDC, newBitmap);
1426 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1429 PIXELFORMATDESCRIPTOR pfd = { 0 };
1430 pfd.nSize = (short)sizeof(pfd);
1432 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1433 pfd.iPixelType = PFD_TYPE_RGBA;
1434 pfd.cColorBits = 32;
1435 //pfd.cAlphaBits = 8;
1436 pfd.cDepthBits = 24;
1437 pfd.iLayerType = PFD_MAIN_PLANE;
1439 oglDisplay.hdc = oglDisplay.memDC;
1441 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1442 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1443 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1445 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1446 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1447 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1452 const int imageSize = width * height * 4;
1454 glGenBuffersARB(2, oglDisplay.imageBuffers);
1456 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1457 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1458 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1459 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1462 oglDisplay.memBitmap = newBitmap;
1463 oglDisplay.stride = width;
1469 ReleaseDC(display.window, hdc);
1471 #elif defined(__unix__) || defined(__APPLE__)
1472 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1477 GLX_DOUBLEBUFFER, True,
1483 GLX_STENCIL_SIZE, 1,
1484 //GLX_DEPTH_SIZE, 24,
1485 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1486 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1492 GLX_PBUFFER_WIDTH, width,
1493 GLX_PBUFFER_HEIGHT, height,
1494 GLX_LARGEST_PBUFFER, False,
1498 // choose a pixel format that meets our minimum requirements
1501 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1504 if(oglDisplay.pixmap)
1506 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1507 oglDisplay.pixmap = None;
1509 if(oglDisplay.shapePixmap)
1511 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1512 oglDisplay.shapePixmap = None;
1515 // Free Shared Memory Pixmap
1516 if(oglDisplay.image)
1518 if(oglDisplay.shminfoShape.shmid != -1)
1520 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1521 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1522 shmdt(oglDisplay.shminfo.shmaddr);
1523 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1525 XDestroyImage(oglDisplay.image);
1526 oglDisplay.image = None;
1528 if(oglDisplay.shapeImage)
1530 if(oglDisplay.shminfoShape.shmid != -1)
1532 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1533 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1534 shmdt(oglDisplay.shminfoShape.shmaddr);
1535 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1537 XDestroyImage(oglDisplay.shapeImage);
1538 oglDisplay.shapeImage = None;
1541 if(oglDisplay.windowPicture)
1542 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1543 if(oglDisplay.pixmapPicture)
1544 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1546 if(oglDisplay.pixmap)
1547 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1549 if(oglDisplay.glContext)
1550 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1551 if(oglDisplay.pBuffer)
1552 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1554 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1555 if(oglDisplay.pBuffer)
1557 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1558 if(oglDisplay.glContext)
1560 glXMakeCurrent(xGlobalDisplay, None, null);
1561 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1563 // Initialize Shared Memory Pixmap
1564 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1565 ZPixmap, null, &oglDisplay.shminfo, width, height);
1566 if(oglDisplay.image)
1568 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1569 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1570 if(oglDisplay.shminfo.shmid != -1)
1572 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1573 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1575 oglDisplay.shminfo.readOnly = False;
1576 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1578 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1579 &oglDisplay.shminfo, width, height, 32);
1581 // Initialize Shared Memory Shape Pixmap
1582 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1583 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1584 if(oglDisplay.shapeImage)
1586 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1587 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1588 if(oglDisplay.shminfoShape.shmid != -1)
1590 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1591 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1593 oglDisplay.shminfoShape.readOnly = False;
1594 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1596 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1597 &oglDisplay.shminfoShape, width, height, 1);
1598 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1601 XRenderPictureAttributes attributes = { 0 };
1602 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1603 #if !defined(__APPLE__)
1604 attributes.repeat = RepeatNormal;
1606 attributes.repeat = 1;
1608 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1609 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1610 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1611 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1614 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1615 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1632 CreateDisplay(display);
1633 #if defined(__WIN32__)
1634 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1635 #elif defined(__unix__) || defined(__APPLE__)
1636 #if defined(__ANDROID__) || defined(__ODROID__)
1639 #elif defined(__EMSCRIPTEN__)
1640 emscripten_webgl_make_context_current(oglSystem.glc);
1642 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1650 SETCAPS(oglDisplay.capabilities);
1652 if(display.alphaBlend && result)
1653 initialDisplaySetup(display, true, false);
1655 if(!result && display.alphaBlend)
1657 printf("Alpha blending windows not supported on this display\n");
1664 glViewport(0,0,width,height);
1665 GLMatrixMode(MatrixMode::projection);
1667 GLOrtho(0,width,height,0,0.0,1.0);
1668 displayWidth = display.width = width;
1669 displayHeight = display.height = height;
1671 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1673 oglDisplay.flipBufW = width;
1674 oglDisplay.flipBufH = height;
1675 #if defined(_GLES) || defined(_GLES2)
1678 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1681 if(oglDisplay.flippingBuffer || !width || !height)
1687 void DisplayPosition(Display display, int x, int y)
1689 OGLDisplay oglDisplay = display.driverData;
1695 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1699 void RestorePalette(Display display)
1703 void StartUpdate(Display display)
1708 OGLDisplay oglDisplay = display.driverData;
1709 glBindVertexArray(oglDisplay.vao);
1712 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1713 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1716 void EndUpdate(Display display)
1720 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1724 void Update(Display display, Box updateBox)
1726 #if defined(__WIN32__) || defined(USEPBUFFER)
1727 OGLDisplay oglDisplay = display.driverData;
1730 #if !defined(__ANDROID__)
1735 #if defined(__WIN32__) || defined(USEPBUFFER)
1736 if(display.alphaBlend)
1738 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1739 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1740 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1741 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1742 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1745 #if defined(__WIN32__)
1747 POINT point = { oglDisplay.x, oglDisplay.y};
1748 POINT srcPoint = { 0, 0 };
1749 BLENDFUNCTION blend = { 0 };
1751 size.cx = display.width;
1752 size.cy = display.height;
1753 blend.BlendOp = AC_SRC_OVER;
1754 blend.BlendFlags = 0;
1755 blend.SourceConstantAlpha = 255;
1756 blend.AlphaFormat = AC_SRC_ALPHA;
1759 // Process partial images. Mapping the buffer waits for
1760 // outstanding DMA transfers into the buffer to finish.
1761 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1762 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1764 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1765 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1768 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1769 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1772 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1775 // Unmap the image buffers
1776 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1777 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1779 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1780 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1782 // Bind two different buffer objects and start the glReadPixels
1783 // asynchronously. Each call will return directly after
1784 // starting the DMA transfer.
1785 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1786 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1788 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1789 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1793 #elif defined(__unix__) || defined(__APPLE__)
1794 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1796 XTransform transform =
1799 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1800 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1801 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1804 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1805 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1806 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1807 #if !defined(__APPLE__)
1808 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1810 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1812 XFlush(xGlobalDisplay);
1820 #if defined(__WIN32__)
1821 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1822 SwapBuffers(oglDisplay.hdc);
1823 //ecere::sys::Sleep(0.1);
1824 #elif defined(__unix__) || defined(__APPLE__)
1825 #if defined(__ANDROID__) || defined(__ODROID__)
1827 #elif defined(__EMSCRIPTEN__)
1829 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1835 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1837 if(bitmap.driverData)
1839 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1840 glDeleteTextures(1, &tex);
1841 bitmap.driverData = 0;
1843 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1846 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1848 OGLSystem oglSystem = displaySystem.driverData;
1849 GLCapabilities capabilities = oglSystem.capabilities;
1850 bool result = false;
1852 GLuint glBitmap = 0;
1854 uint w = width, h = height;
1855 if(!capabilities.nonPow2Textures)
1860 w = Min(w, oglSystem.maxTextureSize);
1861 h = Min(h, oglSystem.maxTextureSize);
1863 glGenTextures(1, &glBitmap);
1864 glBindTexture(GL_TEXTURE_2D, glBitmap);
1866 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1868 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1869 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1871 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1872 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1875 if(!capabilities.shaders)
1876 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1879 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1881 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1882 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1886 bitmap.driverData = (void *)(uintptr)glBitmap;
1887 bitmap.driver = displaySystem.driver;
1895 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1897 bool result = false;
1898 OGLSystem oglSystem = displaySystem.driverData;
1899 GLCapabilities capabilities = oglSystem.capabilities;
1900 Bitmap convBitmap = bitmap;
1904 convBitmap.Copy(bitmap);
1907 // Pre process the bitmap... First make it 32 bit
1908 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1911 uint w = bitmap.width, h = bitmap.height;
1912 GLuint glBitmap = 0;
1913 if(!capabilities.nonPow2Textures)
1918 w = Min(w, oglSystem.maxTextureSize);
1919 h = Min(h, oglSystem.maxTextureSize);
1923 while(w * 2 < h) w *= 2;
1924 while(h * 2 < w) h *= 2;
1927 // Switch ARGB to RGBA
1928 //if(bitmap.format != pixelFormatRGBA)
1930 for(c=0; c<bitmap.size; c++)
1932 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1934 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1935 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1938 // convBitmap.pixelFormat = pixelFormat888;
1941 glGenTextures(1, &glBitmap);
1944 //int error = glGetError();
1948 glBindTexture(GL_TEXTURE_2D, glBitmap);
1949 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1951 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1952 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1954 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1956 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1957 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1959 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1960 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1961 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1962 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1966 if(!capabilities.shaders)
1967 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1972 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1977 if(bitmap.width != w || bitmap.height != h)
1979 mipMap = Bitmap { };
1980 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1982 Surface mipSurface = mipMap.GetSurface(0,0,null);
1983 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1993 mipMap = convBitmap;
2000 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2001 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2002 //printf("Calling glTexImage2D\n");
2003 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2004 //printf("width = %d (Should be %d, %d)\n", width, w, h);
2005 if((error = glGetError()))
2007 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2008 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2012 if(mipMap != convBitmap)
2017 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2018 bitmap.driverData = (void *)(uintptr)glBitmap;
2019 bitmap.driver = displaySystem.driver;
2024 FreeBitmap(displaySystem, bitmap);
2025 else if(oglSystem.loadingFont)
2027 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2029 oglSystem.loadingFont = false;
2035 void ReleaseSurface(Display display, Surface surface)
2037 glDisable(GL_SCISSOR_TEST);
2038 delete surface.driverData;
2039 surface.driverData = null;
2042 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2047 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2049 bool result = false;
2050 OGLDisplay oglDisplay = display.driverData;
2051 OGLSurface oglSurface = surface.driverData = OGLSurface { };
2054 SETCAPS(oglDisplay.capabilities);
2055 if(displayWidth != display.width || displayHeight != display.height)
2057 displayWidth = display.width;
2058 displayHeight = display.height;
2060 glViewport(0,0,display.width,display.height);
2062 GLOrtho(0,display.width,display.height,0,0.0,1.0);
2065 surface.offset.x = x;
2066 surface.offset.y = y;
2067 surface.unclippedBox = surface.box = clip;
2068 oglSurface.bitmapMult[0] = 1;
2069 oglSurface.bitmapMult[1] = 1;
2070 oglSurface.bitmapMult[2] = 1;
2071 oglSurface.bitmapMult[3] = 1;
2073 glEnable(GL_SCISSOR_TEST);
2076 (display.height) -(y+clip.bottom)-1,
2077 clip.right-clip.left+1,
2078 clip.bottom-clip.top+1);
2084 void Clip(Display display, Surface surface, Box clip)
2091 box.Clip(surface.unclippedBox);
2095 box = surface.box = surface.unclippedBox;
2096 box.left += surface.offset.x;
2097 box.top += surface.offset.y;
2098 box.right+= surface.offset.x;
2099 box.bottom += surface.offset.y;
2102 box.left,display.height - box.bottom - 1,
2103 box.right-box.left+1, box.bottom-box.top+1);
2106 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2108 bool result = false;
2109 OGLDisplay oglDisplay = display.driverData;
2110 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2112 if(oglDisplay.flippingBuffer)
2114 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2117 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2123 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2124 #if ENABLE_GL_LEGACY
2125 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2126 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2127 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2129 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2132 for(row = 0; row<h; row++)
2133 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2140 void SetForeground(Display display, Surface surface, ColorAlpha color)
2142 OGLSurface oglSurface = surface.driverData;
2144 oglSurface.foreground[0] = color.color.r/255.0f;
2145 oglSurface.foreground[1] = color.color.g/255.0f;
2146 oglSurface.foreground[2] = color.color.b/255.0f;
2147 //oglSurface.foreground[3] = 1.0f;
2148 oglSurface.foreground[3] = color.a/255.0f;
2150 //if(!oglSurface.foreground[3])printf("bug");
2153 void SetBackground(Display display, Surface surface, ColorAlpha color)
2155 OGLSurface oglSurface = surface.driverData;
2157 oglSurface.background[0] = color.color.r/255.0f;
2158 oglSurface.background[1] = color.color.g/255.0f;
2159 oglSurface.background[2] = color.color.b/255.0f;
2160 //oglSurface.background[3] = 1.0;
2161 oglSurface.background[3] = color.a/255.0f;
2164 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2166 OGLSurface oglSurface = surface.driverData;
2168 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2169 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2170 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2171 oglSurface.bitmapMult[3] = color.a/255.0f;
2174 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2179 void PutPixel(Display display, Surface surface,int x,int y)
2181 OGLSurface oglSurface = surface.driverData;
2182 GLColor4fv(oglSurface.foreground);
2184 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2185 GLVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2189 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2191 OGLSurface oglSurface = surface.driverData;
2192 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2207 x1 += surface.offset.x;
2208 y1 += surface.offset.y;
2209 x2 += surface.offset.x;
2210 y2 += surface.offset.y;
2212 GLColor4fv(oglSurface.foreground);
2216 GLTexCoord2f(0.5f, 0);
2217 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2218 GLTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2219 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2227 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2228 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2234 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2236 OGLSurface oglSurface = surface.driverData;
2237 x1 += surface.offset.x;
2238 y1 += surface.offset.y;
2239 x2 += surface.offset.x;
2240 y2 += surface.offset.y;
2242 GLColor4fv(oglSurface.foreground);
2247 GLTexCoord2f(0.5f, 0);
2248 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2249 GLTexCoord2f(y2-y1 + 0.5f, 0);
2250 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2252 GLTexCoord2f(0.5f, 0);
2253 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2254 GLTexCoord2f(x2 - x1 + 0.5f, 0);
2255 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2257 GLTexCoord2f(0.5f, 0);
2258 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2259 GLTexCoord2f(y1 - y2 + 0.5f, 0);
2260 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2262 GLTexCoord2f(0.5f, 0);
2263 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2264 GLTexCoord2f(x1 - x2 + 0.5f, 0);
2265 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2269 GLBegin(GL_LINE_LOOP);
2276 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2277 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2278 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2279 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2284 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2286 OGLSurface oglSurface = surface.driverData;
2288 GLColor4fv(oglSurface.background);
2290 GLRecti(x1+surface.offset.x, y1+surface.offset.y,
2291 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2293 GLRectf(x1+surface.offset.x, y1+surface.offset.y,
2294 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2298 void Clear(Display display, Surface surface, ClearType type)
2300 OGLDisplay oglDisplay = display.driverData;
2301 OGLSurface oglSurface = surface.driverData;
2304 if(type != depthBuffer)
2305 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2306 if(type != colorBuffer && !oglDisplay.depthWrite)
2308 glDepthMask((byte)bool::true);
2310 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2311 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2312 if(type != colorBuffer && !oglDisplay.depthWrite)
2314 glDepthMask((byte)bool::false);
2318 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2323 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2325 OGLSurface oglSurface = surface.driverData;
2326 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
2329 if(!oglSurface.writingText)
2331 // glTranslatef(-0.375f, -0.375f, 0.0f);
2332 GLSetupTexturing(true);
2333 GLColor4fv(oglSurface.bitmapMult);
2334 glBindTexture(GL_TEXTURE_2D, tex);
2335 GLBegin(GLIMTKMode::quads);
2337 else if(lastBlitTex != tex)
2341 glBindTexture(GL_TEXTURE_2D, tex);
2342 GLBegin(GLIMTKMode::quads);
2348 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2349 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2350 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2351 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2352 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2353 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2354 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2355 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2360 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2361 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2362 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2363 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2364 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2365 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2366 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2367 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2370 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2371 GLVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2372 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2373 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2374 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2375 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2376 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2377 GLVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2379 if(!oglSurface.writingText)
2382 GLSetupTexturing(false);
2383 //glTranslate(0.375, 0.375, 0.0);
2387 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2389 OGLSurface oglSurface = surface.driverData;
2391 //glTranslate(-0.375, -0.375, 0.0);
2393 GLSetupTexturing(true);
2394 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2396 GLColor4fv(oglSurface.bitmapMult);
2398 GLBegin(GLIMTKMode::quads);
2402 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2403 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2405 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2406 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2408 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2409 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2411 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2412 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2416 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2417 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2419 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2420 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2422 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2423 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2425 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2426 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2431 GLSetupTexturing(false);
2433 //glTranslate(0.375, 0.375, 0.0);
2436 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2438 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2441 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2443 float s2dw,s2dh,d2sw,d2sh;
2444 //bool flipX = false, flipY = false;
2446 if(Sgn(w) != Sgn(sw))
2452 if(Sgn(h) != Sgn(sh))
2464 //Clip against the edges of the source
2467 dx+=(int)((0-sx) * s2dw);
2468 w-=(int)((0-sx) * s2dw);
2474 dy+=(int)((0-sy) * s2dh);
2475 h-=(int)((0-sy) * s2dh);
2480 if(sx+sw>bitmap.width-1)
2482 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2483 sw-=sx+sw-(bitmap.width-1)-1;
2485 if(sy+sh>(bitmap.height-1))
2487 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2488 sh-=sy+sh-(bitmap.height-1)-1;
2490 //Clip against the edges of the surfaceination
2491 if(dx<surface.box.left)
2494 sx+=(int)((surface.box.left-dx)*d2sw);
2495 sw-=(int)((surface.box.left-dx)*d2sw);
2496 w-=surface.box.left-dx;
2497 dx=surface.box.left;
2499 if(dy<surface.box.top)
2501 sy+=(int)((surface.box.top-dy)*d2sh);
2502 sh-=(int)((surface.box.top-dy)*d2sh);
2503 h-=surface.box.top-dy;
2506 if(dx+w>surface.box.right)
2508 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2509 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2510 w-=dx+w-surface.box.right-1;
2512 if(dy+h>surface.box.bottom)
2514 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2515 h-=dy+h-surface.box.bottom-1;
2517 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2519 dx += surface.offset.x;
2520 dy += surface.offset.y;
2522 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2524 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2525 #if ENABLE_GL_LEGACY
2528 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2529 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2530 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2531 glRasterPos2d(dx,dy);
2532 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2533 glPixelZoom(s2dw, -s2dh);
2534 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2535 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2536 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2537 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2540 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2544 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2546 //Clip against the edges of the source
2559 if(sx+w>bitmap.width-1)
2560 w-=sx+w-(bitmap.width-1)-1;
2561 if(sy+h>bitmap.height-1)
2562 h-=sy+h-(bitmap.height-1)-1;
2563 //Clip against the edges of the surfaceination
2564 if(dx<surface.box.left)
2567 sx+=surface.box.left-dx;
2568 w-=surface.box.left-dx;
2569 dx=surface.box.left;
2571 if(dy<surface.box.top)
2573 sy+=surface.box.top-dy;
2574 h-=surface.box.top-dy;
2577 if(dx+w>surface.box.right)
2579 //if(flip) sx+=dx+w-surface.box.right-1;
2580 w-=dx+w-surface.box.right-1;
2582 if(dy+h>surface.box.bottom)
2583 h-=dy+h-surface.box.bottom-1;
2587 dx += surface.offset.x;
2588 dy += surface.offset.y;
2590 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2592 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2593 #if ENABLE_GL_LEGACY
2596 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2597 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2598 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2599 glRasterPos2d(dx,dy);
2601 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2602 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2603 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2604 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2607 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2611 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2613 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2616 void UnloadFont(DisplaySystem displaySystem, Font font)
2618 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2621 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2624 OGLSystem oglSystem = displaySystem.driverData;
2625 oglSystem.loadingFont = true;
2626 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2630 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2632 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2635 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2639 OGLSurface oglSurface = surface.driverData;
2640 OGLSystem oglSystem = display.displaySystem.driverData;
2641 oglSystem.loadingFont = true;
2643 //glTranslated(-0.375, -0.375, 0.0);
2645 if(surface.textOpacity)
2647 int w = 0, h, adv = 0;
2648 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2650 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2653 oglSurface.writingText = true;
2655 GLSetupTexturing(true);
2657 if(surface.font.outlineSize)
2659 ColorAlpha outlineColor = surface.outlineColor;
2660 GLColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2661 oglSurface.writingOutline = true;
2663 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2664 if(lastBlitTex) GLEnd();
2665 oglSurface.writingOutline = false;
2667 GLColor4fv(oglSurface.foreground);
2670 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2671 if(lastBlitTex) GLEnd();
2674 oglSurface.writingText = false;
2675 oglSystem.loadingFont = false;
2677 GLSetupTexturing(false);
2679 //glTranslated(0.375, 0.375, 0.0);
2683 void TextFont(Display display, Surface surface, Font font)
2685 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2688 void TextOpacity(Display display, Surface surface, bool opaque)
2690 OGLSurface oglSurface = surface.driverData;
2691 oglSurface.opaqueText = opaque;
2694 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2696 OGLSurface oglSurface = surface.driverData;
2697 OGLSystem oglSystem = display.displaySystem.driverData;
2698 oglSystem.loadingFont = true;
2699 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2700 oglSystem.loadingFont = false;
2703 void DrawingChar(Display display, Surface surface, char character)
2708 void LineStipple(Display display, Surface surface, uint32 stipple)
2712 #if ENABLE_GL_LEGACY
2715 glLineStipple(1, (uint16)stipple);
2716 glEnable(GL_LINE_STIPPLE);
2721 stippleEnabled = true;
2722 glsupLineStipple(1, (uint16)stipple);
2727 #if ENABLE_GL_LEGACY
2729 glDisable(GL_LINE_STIPPLE);
2733 stippleEnabled = false;
2734 GLMatrixMode(GL_TEXTURE);
2736 GLMatrixMode(MatrixMode::projection);
2737 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2742 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2743 void SetRenderState(Display display, RenderState state, uint value)
2745 OGLDisplay oglDisplay = display.driverData;
2749 #ifndef __EMSCRIPTEN__
2751 glEnable(GL_MULTISAMPLE);
2753 glDisable(GL_MULTISAMPLE);
2757 #if ENABLE_GL_LEGACY
2759 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2763 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2766 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2767 oglDisplay.depthWrite = (bool)value;
2771 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2772 #if ENABLE_GL_SHADERS
2774 shader_fogColor(color[0], color[1], color[2]);
2779 glFogfv(GL_FOG_COLOR, (float *)&color);
2784 #if ENABLE_GL_SHADERS
2786 shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2791 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2795 //#if !defined(__EMSCRIPTEN__)
2796 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2801 #if ENABLE_GL_SHADERS
2803 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2809 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2810 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2817 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2822 #if defined(__WIN32__)
2823 if(wglSwapIntervalEXT)
2824 wglSwapIntervalEXT(value ? 1 : 0);
2831 void SetLight(Display display, int id, Light light)
2833 #if ENABLE_GL_SHADERS
2835 shader_setLight(display, id, light);
2841 if(light != null && !light.flags.off)
2843 Object lightObject = light.lightObject;
2844 float position[4] = { 0, 0, 0, 0 };
2845 float color[4] = { 0, 0, 0, 1 };
2848 glEnable(GL_LIGHT0 + id);
2850 if(!light.multiplier) light.multiplier = 1.0f;
2852 color[0] = light.diffuse.r * light.multiplier;
2853 color[1] = light.diffuse.g * light.multiplier;
2854 color[2] = light.diffuse.b * light.multiplier;
2855 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2857 color[0] = light.ambient.r * light.multiplier;
2858 color[1] = light.ambient.g * light.multiplier;
2859 color[2] = light.ambient.b * light.multiplier;
2860 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2862 color[0] = light.specular.r * light.multiplier;
2863 color[1] = light.specular.g * light.multiplier;
2864 color[2] = light.specular.b * light.multiplier;
2865 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2869 // Positional Lights, including Spot Lights (and omni light with flags.spot not set)
2870 Matrix * mat = &lightObject.matrix;
2871 l = { mat->m[3][0], mat->m[3][1], mat->m[3][2] };
2872 if(display.display3D.camera)
2873 l.Subtract(l, display.display3D.camera.cPosition);
2875 position[0] = (float)l.x, position[1] = (float)l.y, position[2] = (float)l.z, position[3] = 1;
2876 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2878 if(light.flags.attenuation)
2880 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2881 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2882 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2886 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, 1);
2887 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, 0);
2888 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, 0);
2891 if((light.flags.spot && light.fallOff < 360) || (lightObject && (light.direction.x || light.direction.y || light.direction.z)))
2893 // Figure out exponent out of the hot spot
2894 #define MAXLIGHT 0.9
2895 float exponent = light.flags.spot ? (float)(log(MAXLIGHT) / log(cos(light.hotSpot / 2))) : 1;
2896 Degrees cutOff = light.flags.spot ? light.fallOff/2 : 90;
2897 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2899 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2900 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)cutOff);
2901 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2905 float d[4] = { 0, 0, 1, 0 };
2906 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, d);
2907 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, 180);
2908 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, 1);
2914 // Display Light Position
2915 glDisable(GL_LIGHTING);
2916 glDisable(GL_DEPTH_TEST);
2920 glVertex3fv(position);
2922 glEnable(GL_DEPTH_TEST);
2923 glEnable(GL_LIGHTING);
2927 if(lightObject.flags.root || !lightObject.parent)
2929 positionVector = light.target.transform.position;
2930 positionVector.Subtract(positionVector, display.camera.cPosition);
2934 positionVector.MultMatrix(light.target.transform.position,
2935 lightObject.light.target.parent.matrix);
2936 positionVector.Subtract(positionVector, display.camera.cPosition);
2939 position[0] = positionVector.x;
2940 position[1] = positionVector.y;
2941 position[2] = positionVector.z;
2943 glDisable(GL_LIGHTING);
2944 glDisable(GL_DEPTH_TEST);
2948 glVertex3fv(position);
2950 glEnable(GL_DEPTH_TEST);
2951 glEnable(GL_LIGHTING);
2957 // Directional Light
2958 Vector3D vector { 0,0,-1 };
2961 mat.RotationQuaternion(light.orientation);
2962 direction.MultMatrix(vector, mat);
2963 l.Normalize(direction);
2964 position[0] = (float)l.x, position[1] = (float)l.y, position[2] = (float)l.z, position[3] = 0;
2965 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2969 glDisable(GL_LIGHT0 + id);
2974 void SetCamera(Display display, Surface surface, Camera camera)
2976 OGLDisplay oglDisplay = display.driverData;
2978 if(surface && camera)
2980 int left = surface.box.left + surface.offset.x;
2981 int top = surface.box.top + surface.offset.y;
2982 int right = surface.box.right + surface.offset.x;
2983 int bottom = surface.box.bottom + surface.offset.y;
2984 float origX = surface.offset.x + camera.origin.x;
2985 float origY = surface.offset.y + camera.origin.y;
2987 int y = display.height - bottom - 1;
2988 int w = right - left + 1;
2989 int h = bottom - top + 1;
2992 glViewport(x, y, w, h);
2994 // *** Projection Matrix ***
2995 GLMatrixMode(MatrixMode::projection);
2996 if(!display.display3D.camera)
2999 if(display.display3D.collectingHits)
3001 float pickX = display.display3D.pickX + surface.offset.x;
3002 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3006 w / display.display3D.pickWidth, 0, 0, 0,
3007 0, h / display.display3D.pickHeight, 0, 0,
3009 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3010 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3013 GLLoadMatrixd(pickMatrix.array);
3018 (left - origX) * camera.zMin / camera.focalX,
3019 (right - origX) * camera.zMin / camera.focalX,
3020 (bottom - origY) * camera.zMin / camera.focalY,
3021 (top - origY) * camera.zMin / camera.focalY,
3022 camera.zMin, camera.zMax);
3024 glDisable(GL_BLEND);
3026 // *** Z Inverted Identity Matrix ***
3027 GLMatrixMode(MatrixMode::modelView);
3028 if(!display.display3D.camera)
3033 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3035 // *** View Matrix ***
3036 GLMultMatrixd(camera.viewMatrix.array);
3041 glEnable(GL_DEPTH_TEST);
3043 GLSetupLighting(true);
3046 glShadeModel(GL_SMOOTH);
3048 glDepthMask((byte)bool::true);
3049 oglDisplay.depthWrite = true;
3051 #ifndef __EMSCRIPTEN__
3052 glEnable(GL_MULTISAMPLE);
3055 else if(surface && display.display3D.camera)
3058 oglDisplay.depthWrite = false;
3059 glViewport(0,0,display.width,display.height);
3061 glDisable(GL_CULL_FACE);
3062 glDisable(GL_DEPTH_TEST);
3064 GLSetupTexturing(false);
3065 GLSetupLighting(false);
3068 GLDisableClientState(COLORS);
3070 #if ENABLE_GL_SHADERS
3072 shader_setPerVertexColor(false);
3077 glShadeModel(GL_FLAT);
3080 #if !defined(__EMSCRIPTEN__)
3081 glDisable(GL_MULTISAMPLE);
3084 // *** Restore 2D MODELVIEW Matrix ***
3087 // *** Restore 2D PROJECTION Matrix ***
3088 GLMatrixMode(MatrixMode::projection);
3094 void ApplyMaterial(Display display, Material material, Mesh mesh)
3097 if(material.flags.doubleSided)
3101 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3103 glDisable(GL_CULL_FACE);
3109 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3111 glEnable(GL_CULL_FACE);
3115 GLSetupFog(!material.flags.noFog);
3118 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3120 Bitmap map = material.baseMap;
3121 GLSetupTexturing(true);
3122 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3124 GLMatrixMode(GL_TEXTURE);
3126 if(material.uScale && material.vScale)
3127 GLScalef(material.uScale, material.vScale, 1);
3128 GLMatrixMode(MatrixMode::modelView);
3130 if(material.flags.tile)
3132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3142 GLSetupTexturing(false);
3144 #if ENABLE_GL_SHADERS
3146 shader_setMaterial(material, mesh.flags.colors);
3152 if(mesh.flags.colors)
3154 GLColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3155 glEnable(GL_COLOR_MATERIAL);
3159 glDisable(GL_COLOR_MATERIAL);
3161 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3162 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3165 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3166 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3170 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3171 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3174 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3175 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3178 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3183 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3185 OGLMesh oglMesh = mesh.data;
3188 OGLSystem oglSystem = displaySystem.driverData;
3189 SETCAPS(oglSystem.capabilities);
3190 if(!mesh.flags.vertices)
3192 oglMesh.vertices.free(glCaps_vertexBuffer);
3193 delete mesh.vertices;
3195 if(!mesh.flags.normals)
3197 oglMesh.normals.free(glCaps_vertexBuffer);
3198 delete mesh.normals;
3200 if(!mesh.flags.texCoords1)
3202 oglMesh.texCoords.free(glCaps_vertexBuffer);
3203 delete mesh.texCoords;
3205 if(!mesh.flags.texCoords2)
3207 oglMesh.texCoords2.free(glCaps_vertexBuffer);
3208 // delete mesh.texCoords2;
3210 if(!mesh.flags.colors)
3212 oglMesh.colors.free(glCaps_vertexBuffer);
3223 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3225 bool result = false;
3228 mesh.data = OGLMesh { };
3231 if(mesh.nVertices == nVertices)
3233 // Same number of vertices, adding features (Leaves the other features pointers alone)
3234 if(mesh.flags != flags)
3236 if(!mesh.flags.vertices && flags.vertices)
3238 if(flags.doubleVertices)
3240 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3243 mesh.vertices = new Vector3Df[nVertices];
3245 if(!mesh.flags.normals && flags.normals)
3247 if(flags.doubleNormals)
3249 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3252 mesh.normals = new Vector3Df[nVertices];
3254 if(!mesh.flags.texCoords1 && flags.texCoords1)
3256 mesh.texCoords = new Pointf[nVertices];
3258 if(!mesh.flags.colors && flags.colors)
3260 mesh.colors = new ColorRGBAf[nVertices];
3266 // New number of vertices, reallocate all current and new features
3267 flags |= mesh.flags;
3270 if(flags.doubleVertices)
3272 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3275 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3279 if(flags.doubleNormals)
3281 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3284 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3286 if(flags.texCoords1)
3288 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3292 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3300 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3302 OGLSystem oglSystem = displaySystem.driverData;
3303 SETCAPS(oglSystem.capabilities);
3304 if(glCaps_vertexBuffer)
3306 OGLMesh oglMesh = mesh.data;
3307 if(!flags) flags = mesh.flags;
3309 oglMesh.vertices.allocate(
3310 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, staticDraw);
3313 oglMesh.normals.allocate(
3314 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, staticDraw);
3316 if(flags.texCoords1)
3317 oglMesh.texCoords.allocate(
3318 mesh.nVertices * sizeof(Pointf), mesh.texCoords, staticDraw);
3321 oglMesh.colors.allocate(
3322 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, staticDraw);
3326 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3333 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3335 OGLSystem oglSystem = displaySystem.driverData;
3336 SETCAPS(oglSystem.capabilities);
3339 oglIndices.buffer.free(glCaps_vertexBuffer);
3340 delete oglIndices.indices;
3345 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3347 OGLIndices oglIndices = OGLIndices { };
3350 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3351 oglIndices.nIndices = nIndices;
3356 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3358 OGLSystem oglSystem = displaySystem.driverData;
3359 SETCAPS(oglSystem.capabilities);
3360 if(glCaps_vertexBuffer)
3362 if(!glCaps_intAndDouble && indices32bit)
3364 if(!oglIndices.buffer.buffer)
3365 glGenBuffers(1, &oglIndices.buffer.buffer);
3366 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3367 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3370 uint * pointer = (uint *)oglIndices.indices;
3373 if(nIndices > oglSystem.shortBDSize)
3375 oglSystem.shortBDSize = nIndices;
3376 oglSystem.shortBDBuffer = renew oglSystem.shortBDBuffer uint16[oglSystem.shortBDSize];
3378 b = oglSystem.shortBDBuffer;
3379 for(i = 0; i < nIndices; i++)
3380 b[i] = (uint16)pointer[i];
3382 glBufferData(GL_ELEMENT_ARRAY_BUFFER, nIndices * sizeof(uint16), b, GL_STATIC_DRAW);
3386 oglIndices.buffer.allocate(
3387 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3388 oglIndices.indices, staticDraw);
3392 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3395 return oglIndices.indices;
3398 void SelectMesh(Display display, Mesh mesh)
3400 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3401 #if defined(__WIN32__)
3402 if(glUnlockArraysEXT)
3404 if(!glCaps_vertexBuffer && display.display3D.mesh)
3405 glUnlockArraysEXT();
3409 OGLMesh oglMesh = mesh.data;
3411 // *** Vertex Stream ***
3412 GLEnableClientState(VERTICES);
3413 if(!display.display3D.collectingHits && oglMesh)
3415 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3417 // *** Normals Stream ***
3418 if(mesh.normals || mesh.flags.normals)
3420 GLEnableClientState(NORMALS);
3421 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3424 GLDisableClientState(NORMALS);
3426 // *** Texture Coordinates Stream ***
3427 if(mesh.texCoords || mesh.flags.texCoords1)
3429 GLEnableClientState(TEXCOORDS);
3430 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3433 GLDisableClientState(TEXCOORDS);
3435 // *** Color Stream ***
3436 if(mesh.colors || mesh.flags.colors)
3438 GLEnableClientState(COLORS);
3439 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3442 GLDisableClientState(COLORS);
3446 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3447 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3449 GLEnableClientState(NORMALS);
3450 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3453 GLDisableClientState(NORMALS);
3454 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3456 GLEnableClientState(TEXCOORDS);
3457 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3460 GLDisableClientState(TEXCOORDS);
3461 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3463 GLEnableClientState(COLORS);
3464 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3467 GLDisableClientState(COLORS);
3470 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3472 #if defined(__WIN32__)
3475 if(!glCaps_vertexBuffer)
3476 glLockArraysEXT(0, mesh.nVertices);
3481 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3483 if(primitive->type.vertexRange)
3486 glDrawArrays(getPrimitiveType(primitive->type.primitiveType), primitive->first, primitive->nVertices);
3490 OGLIndices oglIndices = primitive->data;
3491 GLEAB eab = ((!display.display3D.collectingHits && oglIndices && glCaps_vertexBuffer) ? oglIndices.buffer : noEAB);
3492 if(!glCaps_intAndDouble && !glCaps_vertexBuffer && primitive->type.indices32bit)
3494 uint16 * temp = new uint16[primitive->nIndices];
3495 uint32 * src = (uint32 *)(oglIndices ? oglIndices.indices : primitive->indices);
3497 for(i = 0; i < primitive->nIndices; i++)
3498 temp[i] = (uint16)src[i];
3499 eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices, GL_UNSIGNED_SHORT, temp);
3503 eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices,
3504 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3505 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3506 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3510 void PushMatrix(Display display)
3515 void PopMatrix(Display display, bool setMatrix)
3520 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3522 Matrix matrix = transMatrix;
3523 Camera camera = useCamera ? display.display3D.camera : null;
3528 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3533 matrix.m[3][0] - camera.cPosition.x,
3534 matrix.m[3][1] - camera.cPosition.y,
3535 matrix.m[3][2] - camera.cPosition.z);
3547 GLMultMatrixd(matrix.array);
3552 public void UseSingleGLContext(bool useSingle)
3554 useSingleGLContext = useSingle;
3557 default dllexport void *
3558 #if defined(__WIN32__)
3559 __attribute__((stdcall))
3561 IS_GLGetContext(DisplaySystem displaySystem)
3565 #if defined(__WIN32__)
3566 OGLSystem system = displaySystem.driverData;
3568 #elif defined(__ANDROID__) || defined(__ODROID__)
3570 #elif defined(__EMSCRIPTEN__)
3571 OGLSystem system = displaySystem.driverData;
3572 return (void *)system.glc;
3574 OGLSystem system = displaySystem.driverData;
3575 return system.glContext;