1 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
4 #if defined(_DEBUG) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
15 namespace gfx::drivers;
17 #include "glHelpers.h"
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 GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
88 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;
168 // Might toggle without Reload:
169 bool glcaps_shaders, glcaps_fixedFunction, glcaps_immediate, glcaps_legacy, glcaps_pointSize, glcaps_frameBuffer;
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 // TOCHECK: Do we really need to pass glcaps_shaders?
246 public void glsupLineStipple( int i, unsigned short j )
250 for(x = 0; x < 16; x++)
252 bool v = (j & (1 << x)) != 0;
253 texture[x] = v ? 0xFFFFFFFF : 0;
256 glGenTextures(1, &stippleTexture);
257 glBindTexture(GL_TEXTURE_2D, stippleTexture);
258 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
260 // TOOD: Special shading code for stippling?
261 GLSetupTexturing(true);
262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
266 GLMatrixMode(GL_TEXTURE);
268 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
269 GLScaled(i/16.0, 1, 1.0f);
270 GLTranslated(0.5, 0.5, 0);
271 GLMatrixMode(MatrixMode::projection);
274 // Exported to build _GLES version...
275 public void glsupLightModeli( unsigned int pname, int param )
278 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
279 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
284 void glFogi( unsigned int pname, int param ) { }
285 void glPolygonMode( unsigned int i, unsigned int j ) { }
286 void glBlendFuncSeparate(int a, int b, int c, int d)
293 #if defined(_GLES) || defined(_GLES2)
294 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
297 #if !ENABLE_GL_SELECT
299 // *** Picking won't be supported for now ***
300 void glPushName( unsigned int i ) { }
301 void glLoadName( unsigned int i ) { }
306 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
307 static inline uint getPrimitiveType(RenderPrimitiveType type)
309 static int primitiveTypes[RenderPrimitiveType] =
311 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN,
313 GLIMTKMode::quadStrip,
316 // NOTE: This will only work for single quads
317 return (type == quads && !glcaps_quads) ? GL_TRIANGLE_FAN : primitiveTypes[type];
320 public void GLSetupTexturing(bool enable)
322 #if ENABLE_GL_SHADERS
324 shader_texturing(enable);
329 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
333 public void GLSetupFog(bool enable)
335 #if ENABLE_GL_SHADERS
342 (enable ? glEnable : glDisable)(GL_FOG);
346 bool lightingEnabled;
348 public void GLSetupLighting(bool enable)
350 lightingEnabled = enable;
351 #if ENABLE_GL_SHADERS
353 shader_lighting(enable);
358 (enable ? glEnable : glDisable)(GL_LIGHTING);
363 static int displayWidth, displayHeight;
365 #define GL_CLAMP_TO_EDGE 0x812F
367 static bool useSingleGLContext = false;
368 class OGLDisplay : struct
370 #if defined(__WIN32__)
381 byte * pboMemory1, * pboMemory2;
383 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
384 GLXContext glContext;
387 XShmSegmentInfo shminfo;
389 XShmSegmentInfo shminfoShape;
394 X11Picture windowPicture;
395 X11Picture pixmapPicture;
397 X11Picture shapePicture;
400 GLCapabilities capabilities, originalCapabilities;
402 ColorAlpha * flippingBuffer;
403 int flipBufH, flipBufW;
408 class OGLSystem : struct
412 #if ENABLE_GL_SHADERS
417 #if defined(__WIN32__)
418 PIXELFORMATDESCRIPTOR pfd;
423 #elif defined(__EMSCRIPTEN__)
424 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
425 #elif !defined(__ANDROID__) && !defined(__ODROID__)
426 XVisualInfo * visualInfo;
427 GLXContext glContext;
428 GLXDrawable glxDrawable;
430 GLCapabilities capabilities;
433 class OGLSurface : struct
441 float foreground[4], background[4], bitmapMult[4];
444 class OGLMesh : struct
453 class OGLIndices : struct
463 #if defined(__WIN32__)
464 static HGLRC winCreateContext(HDC hdc, int * contextVersion, bool * isCompatible)
467 if(wglCreateContextAttribsARB)
469 int versions[12][2] =
471 { 4, 5 }, { 4, 4 }, { 4, 3 }, { 4, 2 }, { 4, 1 }, { 4, 0 },
472 { 3, 3 }, { 3, 2 }, { 3, 1 }, { 3, 0 },
476 bool tryingCompat = true;
480 for(v = 0; !result && v < sizeof(versions) / sizeof(versions[0]); v++)
482 int v0 = versions[v][0], v1 = versions[v][1];
483 if(!tryingCompat || v0 >= 3)
485 bool coreNotion = v0 > 3 || (v0 == 3 && v1 >= 3);
488 WGL_CONTEXT_MAJOR_VERSION_ARB, v0, WGL_CONTEXT_MINOR_VERSION_ARB, v1,
490 WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
492 coreNotion ? WGL_CONTEXT_PROFILE_MASK_ARB : 0, coreNotion ? (tryingCompat ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB) : 0,
495 result = wglCreateContextAttribsARB(hdc, null, attribs);
498 if(contextVersion) *contextVersion = v0;
499 if(isCompatible) *isCompatible = tryingCompat || !coreNotion;
504 tryingCompat = false;
511 if(contextVersion) *contextVersion = 1;
512 if(isCompatible) *isCompatible = true;
513 result = wglCreateContext(hdc);
519 class OpenGLDisplayDriver : DisplayDriver
521 class_property(name) = "OpenGL";
523 bool LockSystem(DisplaySystem displaySystem)
525 #if defined(__EMSCRIPTEN__)
526 OGLSystem oglSystem = displaySystem.driverData;
527 emscripten_webgl_make_context_current(oglSystem.glc);
528 #elif !defined(__ANDROID__) && !defined(__ODROID__)
529 OGLSystem oglSystem = displaySystem.driverData;
530 if(useSingleGLContext) return true;
531 #if defined(__WIN32__)
532 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
533 #elif defined(__unix__) || defined(__APPLE__)
534 //if(previous) return true;
535 // printf("Making SYSTEM current\n");
536 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
537 //previous = oglSystem.glContext;
540 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
541 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
545 void UnlockSystem(DisplaySystem displaySystem)
547 if(useSingleGLContext) return;
548 #if defined(__WIN32__)
549 wglMakeCurrent(null, null);
550 #elif defined(__unix__) || defined(__APPLE__)
551 // printf("Making NULL current\n");
552 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
554 glXMakeCurrent(xGlobalDisplay, None, null);
560 bool Lock(Display display)
562 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
563 OGLDisplay oglDisplay = display.driverData;
564 if(useSingleGLContext) return true;
565 #if defined(__WIN32__)
566 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
567 #elif defined(__unix__) || defined(__APPLE__)
568 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
569 // printf(" Making DISPLAY current\n");
570 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
573 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
574 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
578 void Unlock(Display display)
580 if(useSingleGLContext) return;
581 //printf(" Making NULL current\n");
582 //glXMakeCurrent(xGlobalDisplay, None, null);
584 LockSystem(display.displaySystem);
587 void DestroyDisplay(Display display)
589 OGLDisplay oglDisplay = display.driverData;
593 #if defined(__WIN32__)
594 wglMakeCurrent( null, null );
597 wglDeleteContext(oglDisplay.glrc);
599 if(oglDisplay.hdc && oglDisplay.pBuffer)
600 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
602 if(oglDisplay.pBuffer)
603 wglDestroyPbufferARB(oglDisplay.pBuffer);
606 ReleaseDC(display.window, oglDisplay.hdc);
608 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
609 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
611 #elif defined(__unix__) || defined(__APPLE__)
612 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
614 if(oglDisplay.shapePixmap)
615 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
616 if(oglDisplay.pixmap)
617 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
620 if(oglDisplay.shminfoShape.shmid != -1)
622 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
623 if(oglDisplay.shminfo.shmaddr != (void *)-1)
624 shmdt(oglDisplay.shminfo.shmaddr);
625 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
628 if(oglDisplay.shapeImage)
630 if(oglDisplay.shminfoShape.shmid != -1)
632 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
633 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
634 shmdt(oglDisplay.shminfoShape.shmaddr);
635 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
637 XDestroyImage(oglDisplay.shapeImage);
638 oglDisplay.shapeImage = None;
641 glXMakeCurrent(xGlobalDisplay, None, null);
643 if(oglDisplay.glContext)
644 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
647 delete oglDisplay.flippingBuffer;
649 display.driverData = null;
653 #if !defined(__EMSCRIPTEN__)
654 void ::CheckCapabilities(OGLSystem oglSystem, OGLDisplay oglDisplay)
656 GLCapabilities capabilities;
658 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
661 printf("extensions: %s\n", extensions);
664 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
667 capabilities = { fixedFunction = true, vertexBuffer = true, pointSize = true, frameBuffer = extensions && strstr(extensions, "GL_OES_framebuffer_object") };
668 #elif defined(_GLES2)
669 capabilities = { glcaps_shaders = true, vertexBuffer = true, pointSize = true, frameBuffer = true };
673 nonPow2Textures = extensions && strstr(extensions, "GL_ARB_texture_non_power_of_two");
677 legacy = glBegin != null;
678 immediate = glBegin != null;
679 fixedFunction = glBegin != null;
680 quads = glBegin != null;
682 #if ENABLE_GL_SHADERS
683 shaders = glCreateProgram != null;
686 shaders = glBindFramebuffer != null;
688 vertexBuffer = glBindBuffer != null;
689 // mapBuffer = glMapBuffer != null;
694 PrintLn("max texture size: ", oglSystem.maxTextureSize);
696 if(oglDisplay) oglDisplay.capabilities = capabilities;
697 if(oglSystem) oglSystem.capabilities = capabilities;
701 bool CreateDisplaySystem(DisplaySystem displaySystem)
704 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
707 oglSystem.capabilities = { fixedFunction = true, vertexBuffer = true, frameBuffer = true, pointSize = true };
708 #elif defined(_GLES2)
709 oglSystem.capabilities = { shaders = true, vertexBuffer = true, frameBuffer = true, pointSize = true };
711 oglSystem.capabilities = { shaders = true, fixedFunction = true, immediate = true, legacy = true, pointSize = true, quads = true, intAndDouble = true, vertexBuffer = true, frameBuffer = true, nonPow2Textures = true };
715 PrintLn("OpenGL driver's CreateDisplaySystem()");
719 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
721 oglSystem.hdc = GetDC(oglSystem.hwnd);
725 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
726 oglSystem.pfd.nVersion = 1;
727 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
728 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
729 oglSystem.pfd.cColorBits = 24;
730 oglSystem.pfd.cAlphaBits = 8;
731 oglSystem.pfd.cDepthBits = 24;
732 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
734 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
735 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
737 if(oglSystem.pfd.cColorBits > 8)
739 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
740 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
743 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
745 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
746 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
747 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
748 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
749 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
750 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
751 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
752 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
753 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
754 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
755 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
757 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
758 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
760 // eSystem_LoggingMode(LOG_MSGBOX, null);
762 if(wglChoosePixelFormatARB)
767 float fAttributes[] = {0,0};
770 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
771 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
772 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
773 WGL_COLOR_BITS_ARB,24,
774 WGL_ALPHA_BITS_ARB,8,
775 WGL_DEPTH_BITS_ARB,16,
776 WGL_STENCIL_BITS_ARB,0,
777 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
778 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
779 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
783 //Log("Found wglChoosePixelFormatARB\n");
785 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
786 if(!valid || !numFormats)
788 //Log("Can't find 4x multi sampling\n");
790 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
791 if(!valid || !numFormats)
793 // Log("Can't find 2x multi sampling\n");
796 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
799 if(valid && numFormats)
801 oglSystem.format = pixelFormat;
802 wglMakeCurrent(null, null);
803 wglDeleteContext(oglSystem.glrc);
805 // *** DescribePixelFormat does not support WGL pixel formats! ***
806 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
807 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
808 //Log("Successfully set pixel format\n");
811 PrintLn("winCreateContext()");
813 oglSystem.glrc = winCreateContext(oglSystem.hdc, null, null);
815 PrintLn("wglMakeCurrent()");
818 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
822 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
826 wglMakeCurrent(null, null);
828 //eSystem_DumpErrors(true);
832 #elif defined(__unix__) || defined(__APPLE__)
833 #if defined(__ANDROID__) || defined(__ODROID__)
834 #if defined(__ANDROID__)
835 egl_init_display(guiApp.desktop.windowHandle);
836 #elif defined(__ODROID__)
837 egl_init_display((uint)displaySystem.window);
839 CheckCapabilities(oglSystem, null);
841 // TODO: Clean this up? Needed here?
842 GLEnableClientState(VERTICES);
844 // Initialize GL state.
845 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
846 glEnable(GL_CULL_FACE);
847 glShadeModel(GL_SMOOTH);
848 glDisable(GL_DEPTH_TEST);
850 glDisable(GL_CULL_FACE);
851 glDisable(GL_DEPTH_TEST);
853 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
856 matrixStack[0][0].Identity();
857 matrixStack[1][0].Identity();
858 matrixStack[2][0].Identity();
860 GLMatrixMode(GL_MODELVIEW);
861 GLScaled(1.0, 1.0, -1.0);
862 GLMatrixMode(GL_PROJECTION);
863 glShadeModel(GL_FLAT);
867 GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
869 glFogi(GL_FOG_MODE, GL_EXP);
870 glFogf(GL_FOG_DENSITY, 0);
871 glEnable(GL_NORMALIZE);
872 glDepthFunc(GL_LESS);
874 glDisable(GL_MULTISAMPLE);
876 glViewport(0,0,eglWidth,eglHeight);
878 GLOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
880 glabCurArrayBuffer = 0;
881 glabCurElementBuffer = 0;
884 #elif defined(__EMSCRIPTEN__)
886 EmscriptenWebGLContextAttributes attribs = { 0 };
888 attribs.antialias = 1;
895 EM_BOOL premultipliedAlpha;
896 EM_BOOL preserveDrawingBuffer;
897 EM_BOOL preferLowPowerToHighPerformance;
898 EM_BOOL failIfMajorPerformanceCaveat;
901 EM_BOOL enableExtensionsByDefault;
904 emscripten_webgl_init_context_attributes(&attribs);
905 oglSystem.maxTextureSize = 16384;
906 oglSystem.glc = emscripten_webgl_create_context("canvas", &attribs);
907 if(emscripten_webgl_make_context_current(oglSystem.glc) == EMSCRIPTEN_RESULT_SUCCESS)
910 /*glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
911 glEnable(GL_BLEND);*/
915 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
916 XSetWindowAttributes attr;
921 #ifndef ECERE_MINIGLX
922 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
925 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
929 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
930 attr.background_pixel = 0;
931 attr.border_pixel = 0;
932 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
933 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
934 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
936 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
937 oglSystem.visualInfo->visual, mask, &attr );
939 if(oglSystem.visualInfo)
941 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
942 if(oglSystem.glContext)
944 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
945 glXMakeCurrent(xGlobalDisplay, None, null);
952 displaySystem.flags.alpha = true;
953 displaySystem.flags.flipping = true;
954 displaySystem.pixelFormat = pixelFormat888;
958 void DestroyDisplaySystem(DisplaySystem displaySystem)
960 OGLSystem oglSystem = displaySystem.driverData;
963 glDeleteTextures(1, &stippleTexture);
967 #if ENABLE_GL_SHADERS
968 if(oglSystem.shadingProgram)
969 glDeleteProgram(oglSystem.shadingProgram);
970 if(oglSystem.fragmentShader)
971 glDeleteShader(oglSystem.fragmentShader);
972 if(oglSystem.vertexShader)
973 glDeleteShader(oglSystem.vertexShader);
978 #if defined(__WIN32__)
979 wglMakeCurrent( null, null );
982 wglDeleteContext(oglSystem.glrc);
985 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
986 DestroyWindow(oglSystem.hwnd);
988 #elif defined(__unix__) || defined(__APPLE__)
989 #if defined(__ANDROID__) || defined(__ODROID__)
991 #elif defined(__EMSCRIPTEN__)
992 emscripten_webgl_destroy_context(oglSystem.glc);
994 if(oglSystem.visualInfo)
997 __miniglx_XFree(oglSystem.visualInfo);
999 XFree(oglSystem.visualInfo);
1003 if(oglSystem.glxDrawable)
1005 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1006 oglSystem.glxDrawable = 0;
1013 /*static */bool ::initialDisplaySetup(Display display)
1015 OGLDisplay oglDisplay = display.driverData;
1016 OGLSystem oglSystem = display.displaySystem.driverData;
1019 oglSystem.capabilities = oglDisplay.capabilities;
1020 SETCAPS(oglDisplay.capabilities);
1022 #if ENABLE_GL_SHADERS
1024 loadShaders(display.displaySystem, "<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1025 #if ENABLE_GL_LEGACY
1028 glDisableVertexAttribArray(GLBufferContents::color);
1029 glDisableVertexAttribArray(GLBufferContents::normal);
1030 glDisableVertexAttribArray(GLBufferContents::texCoord);
1031 glDisableVertexAttribArray(GLBufferContents::vertex);
1037 GLEnableClientState(VERTICES);
1039 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1040 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1042 #if defined(__WIN32__)
1043 if(glBlendFuncSeparate)
1044 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1046 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1048 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1052 GLMatrixMode(MatrixMode::texture);
1055 GLMatrixMode(MatrixMode::modelView);
1056 GLLoadIdentity(); // For setting up GLES stack
1057 GLScaled(1.0, 1.0, -1.0);
1058 // glTranslatef(0.375f, 0.375f, 0.0f);
1059 // glTranslatef(-0.625f, -0.625f, 0.0f);
1060 GLMatrixMode(MatrixMode::projection);
1062 if(display.width && display.height)
1063 GLOrtho(0,display.width,display.height,0,0.0,1.0);
1068 glShadeModel(GL_FLAT);
1070 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1071 GLLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1074 GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1076 glFogi(GL_FOG_MODE, GL_EXP);
1077 glFogf(GL_FOG_DENSITY, 0);
1078 glEnable(GL_NORMALIZE);
1081 glDepthFunc(GL_LESS);
1083 #if !defined(__EMSCRIPTEN__)
1084 glDisable(GL_MULTISAMPLE);
1087 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1088 display.ambient = Color { 50,50,50 };
1093 bool CreateDisplay(Display display)
1095 bool result = false;
1096 OGLDisplay oglDisplay = display.driverData;
1097 OGLSystem oglSystem = display.displaySystem.driverData;
1100 oglDisplay = display.driverData = OGLDisplay { };
1101 oglDisplay.capabilities = oglSystem.capabilities;
1103 #if defined(__WIN32__) || defined(USEPBUFFER)
1104 if(!display.alphaBlend)
1107 #if defined(__WIN32__)
1108 oglDisplay.hdc = GetDC(display.window);
1109 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1110 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, null, null)))
1112 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1113 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1117 ReleaseDC(display.window, oglDisplay.hdc);
1118 #elif defined(__unix__) || defined(__APPLE__)
1119 # if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1122 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1124 #if defined(__APPLE__)
1125 XVisualInfo template = { 0 };
1126 XWindowAttributes winAttr;
1128 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1129 template.visualid = XVisualIDFromVisual(winAttr.visual);
1130 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1132 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1133 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1134 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1135 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1137 // visualInfo = oglSystem.visualInfo;
1142 //printf("visualInfo is not null\n");
1143 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1144 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1145 //XFree(visualInfo);
1148 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1149 if(oglDisplay.glContext)
1151 //printf("CreateDisplay Got a Context\n");
1152 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1158 #if defined(__WIN32__) || defined(USEPBUFFER)
1162 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1167 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1170 PrintLn("Calling ogl_LoadFunctions() in CreateDisplay()");
1172 if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
1173 PrintLn("ogl_LoadFunctions() failed!");
1176 PrintLn("CheckCapabilities()");
1178 CheckCapabilities(oglSystem, oglDisplay);
1181 PrintLn("vboAvailable is: ", vboAvailable);
1184 # ifdef GL_DEBUGGING
1190 #if defined(__EMSCRIPTEN__)
1191 emscripten_webgl_make_context_current(oglSystem.glc);
1196 GLCapabilities capabilities = *&display.glCapabilities;
1197 // PrintLn("Available OpenGL Capabilities: ", oglDisplay.capabilities);
1198 // PrintLn("Desired OpenGL Capabilities: ", capabilities);
1200 oglDisplay.originalCapabilities = oglDisplay.capabilities;
1202 // Re-enable glcaps_shaders if no fixed function support
1203 if(!oglDisplay.capabilities.fixedFunction)
1204 capabilities.shaders = true;
1205 // Re-enable fixed function if no glcaps_shaders support
1206 if(!oglDisplay.capabilities.shaders)
1208 capabilities.fixedFunction = true;
1209 capabilities.shaders = false;
1212 // Disable things that don't work with glcaps_shaders
1213 if(capabilities.shaders)
1215 capabilities.fixedFunction = false;
1216 capabilities.legacy = false;
1217 capabilities.immediate = false;
1220 #if !ENABLE_GL_POINTER
1221 // Re-enable vertex buffer if no pointer support
1222 capabilities.vertexBuffer = true;
1225 oglDisplay.capabilities &= capabilities;
1227 // PrintLn("Selected OpenGL Capabilities: ", oglDisplay.capabilities);
1228 oglSystem.capabilities = oglDisplay.capabilities;
1231 initialDisplaySetup(display);
1234 if(!useSingleGLContext)
1236 #if defined(__WIN32__)
1237 wglMakeCurrent(null, null);
1238 #elif defined(__unix__) || defined(__APPLE__)
1239 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1242 glXMakeCurrent(xGlobalDisplay, None, null);
1248 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1255 bool DisplaySize(Display display, int width, int height)
1257 OGLDisplay oglDisplay = display.driverData;
1258 bool result = false;
1260 #if defined(__WIN32__) || defined(USEPBUFFER)
1261 OGLSystem oglSystem = display.displaySystem.driverData;
1262 if(display.alphaBlend)
1264 #if defined(__WIN32__)
1265 const int attributes[]=
1267 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1268 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1270 int pixelFormat = 0;
1271 if(wglChoosePixelFormatARB)
1275 float fAttributes[] = {0,0};
1278 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1279 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1280 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1281 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1282 WGL_COLOR_BITS_ARB,24,
1283 WGL_ALPHA_BITS_ARB,8,
1284 WGL_DEPTH_BITS_ARB,16,
1285 WGL_STENCIL_BITS_ARB,0,
1286 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1287 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1288 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1292 //Log("Found wglChoosePixelFormatARB\n");
1294 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1295 if(!valid || !numFormats)
1297 //Log("Can't find 4x multi sampling\n");
1298 iAttributes[19] = 2;
1299 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1300 if(!valid || !numFormats)
1302 // Log("Can't find 2x multi sampling\n");
1303 iAttributes[16] = 0;
1304 iAttributes[17] = 0;
1305 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1306 if(!valid || !numFormats)
1310 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1311 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1312 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1313 WGL_COLOR_BITS_ARB,24,
1314 WGL_ALPHA_BITS_ARB,8,
1315 WGL_DEPTH_BITS_ARB,16,
1318 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1322 if(valid && numFormats)
1324 wglMakeCurrent(null, null);
1328 wglMakeCurrent( null, null );
1329 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1330 if(oglDisplay.hdc && oglDisplay.pBuffer)
1331 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1333 wglDestroyPbufferARB(oglDisplay.pBuffer);
1335 if(!useSingleGLContext)
1336 wglMakeCurrent( null, null );
1339 wglDeleteContext(oglDisplay.glrc);
1341 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1342 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1343 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, null, null)))
1346 HDC hdc = GetDC(display.window);
1348 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1349 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1351 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1352 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1354 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1356 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1360 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1361 oglDisplay.memDC = CreateCompatibleDC(hdc);
1362 SetMapMode(oglDisplay.memDC, MM_TEXT);
1363 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1364 info->bmiHeader.biPlanes = 1;
1365 info->bmiHeader.biCompression = BI_RGB;
1366 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1367 info->bmiHeader.biWidth = width;
1368 info->bmiHeader.biHeight = height;
1369 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1372 SelectObject(oglDisplay.memDC, newBitmap);
1373 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1376 PIXELFORMATDESCRIPTOR pfd = { 0 };
1377 pfd.nSize = (short)sizeof(pfd);
1379 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1380 pfd.iPixelType = PFD_TYPE_RGBA;
1381 pfd.cColorBits = 32;
1382 //pfd.cAlphaBits = 8;
1383 pfd.cDepthBits = 24;
1384 pfd.iLayerType = PFD_MAIN_PLANE;
1386 oglDisplay.hdc = oglDisplay.memDC;
1388 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1389 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1390 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1392 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1393 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1394 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1399 const int imageSize = width * height * 4;
1401 glGenBuffersARB(2, oglDisplay.imageBuffers);
1403 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1404 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1405 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1406 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1409 oglDisplay.memBitmap = newBitmap;
1410 oglDisplay.stride = width;
1416 ReleaseDC(display.window, hdc);
1418 #elif defined(__unix__) || defined(__APPLE__)
1419 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1424 GLX_DOUBLEBUFFER, True,
1430 GLX_STENCIL_SIZE, 1,
1431 //GLX_DEPTH_SIZE, 24,
1432 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1433 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1439 GLX_PBUFFER_WIDTH, width,
1440 GLX_PBUFFER_HEIGHT, height,
1441 GLX_LARGEST_PBUFFER, False,
1445 // choose a pixel format that meets our minimum requirements
1448 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1451 if(oglDisplay.pixmap)
1453 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1454 oglDisplay.pixmap = None;
1456 if(oglDisplay.shapePixmap)
1458 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1459 oglDisplay.shapePixmap = None;
1462 // Free Shared Memory Pixmap
1463 if(oglDisplay.image)
1465 if(oglDisplay.shminfoShape.shmid != -1)
1467 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1468 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1469 shmdt(oglDisplay.shminfo.shmaddr);
1470 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1472 XDestroyImage(oglDisplay.image);
1473 oglDisplay.image = None;
1475 if(oglDisplay.shapeImage)
1477 if(oglDisplay.shminfoShape.shmid != -1)
1479 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1480 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1481 shmdt(oglDisplay.shminfoShape.shmaddr);
1482 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1484 XDestroyImage(oglDisplay.shapeImage);
1485 oglDisplay.shapeImage = None;
1488 if(oglDisplay.windowPicture)
1489 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1490 if(oglDisplay.pixmapPicture)
1491 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1493 if(oglDisplay.pixmap)
1494 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1496 if(oglDisplay.glContext)
1497 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1498 if(oglDisplay.pBuffer)
1499 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1501 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1502 if(oglDisplay.pBuffer)
1504 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1505 if(oglDisplay.glContext)
1507 glXMakeCurrent(xGlobalDisplay, None, null);
1508 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1510 // Initialize Shared Memory Pixmap
1511 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1512 ZPixmap, null, &oglDisplay.shminfo, width, height);
1513 if(oglDisplay.image)
1515 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1516 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1517 if(oglDisplay.shminfo.shmid != -1)
1519 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1520 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1522 oglDisplay.shminfo.readOnly = False;
1523 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1525 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1526 &oglDisplay.shminfo, width, height, 32);
1528 // Initialize Shared Memory Shape Pixmap
1529 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1530 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1531 if(oglDisplay.shapeImage)
1533 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1534 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1535 if(oglDisplay.shminfoShape.shmid != -1)
1537 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1538 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1540 oglDisplay.shminfoShape.readOnly = False;
1541 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1543 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1544 &oglDisplay.shminfoShape, width, height, 1);
1545 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1548 XRenderPictureAttributes attributes = { 0 };
1549 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1550 #if !defined(__APPLE__)
1551 attributes.repeat = RepeatNormal;
1553 attributes.repeat = 1;
1555 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1556 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1557 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1558 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1561 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1562 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1579 CreateDisplay(display);
1580 #if defined(__WIN32__)
1581 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1582 #elif defined(__unix__) || defined(__APPLE__)
1583 #if defined(__ANDROID__) || defined(__ODROID__)
1586 #elif defined(__EMSCRIPTEN__)
1587 emscripten_webgl_make_context_current(oglSystem.glc);
1589 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1597 SETCAPS(oglDisplay.capabilities);
1599 if(display.alphaBlend && result)
1600 initialDisplaySetup(display);
1602 if(!result && display.alphaBlend)
1604 printf("Alpha blending windows not supported on this display\n");
1611 glViewport(0,0,width,height);
1612 GLMatrixMode(MatrixMode::projection);
1614 GLOrtho(0,width,height,0,0.0,1.0);
1615 displayWidth = display.width = width;
1616 displayHeight = display.height = height;
1618 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1620 oglDisplay.flipBufW = width;
1621 oglDisplay.flipBufH = height;
1622 #if defined(_GLES) || defined(_GLES2)
1625 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1628 if(oglDisplay.flippingBuffer || !width || !height)
1634 void DisplayPosition(Display display, int x, int y)
1636 OGLDisplay oglDisplay = display.driverData;
1642 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1646 void RestorePalette(Display display)
1650 void StartUpdate(Display display)
1654 void EndUpdate(Display display)
1658 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1662 void Update(Display display, Box updateBox)
1664 #if defined(__WIN32__) || defined(USEPBUFFER)
1665 OGLDisplay oglDisplay = display.driverData;
1668 #if !defined(__ANDROID__)
1673 #if defined(__WIN32__) || defined(USEPBUFFER)
1674 if(display.alphaBlend)
1676 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1677 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1678 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1679 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1680 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1683 #if defined(__WIN32__)
1685 POINT point = { oglDisplay.x, oglDisplay.y};
1686 POINT srcPoint = { 0, 0 };
1687 BLENDFUNCTION blend = { 0 };
1689 size.cx = display.width;
1690 size.cy = display.height;
1691 blend.BlendOp = AC_SRC_OVER;
1692 blend.BlendFlags = 0;
1693 blend.SourceConstantAlpha = 255;
1694 blend.AlphaFormat = AC_SRC_ALPHA;
1697 // Process partial images. Mapping the buffer waits for
1698 // outstanding DMA transfers into the buffer to finish.
1699 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1700 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1702 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1703 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1706 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1707 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1710 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1713 // Unmap the image buffers
1714 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1715 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1717 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1718 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1720 // Bind two different buffer objects and start the glReadPixels
1721 // asynchronously. Each call will return directly after
1722 // starting the DMA transfer.
1723 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1724 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1726 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1727 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1731 #elif defined(__unix__) || defined(__APPLE__)
1732 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1734 XTransform transform =
1737 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1738 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1739 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1742 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1743 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1744 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1745 #if !defined(__APPLE__)
1746 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1748 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1750 XFlush(xGlobalDisplay);
1758 #if defined(__WIN32__)
1759 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1760 SwapBuffers(oglDisplay.hdc);
1761 //ecere::sys::Sleep(0.1);
1762 #elif defined(__unix__) || defined(__APPLE__)
1763 #if defined(__ANDROID__) || defined(__ODROID__)
1765 #elif defined(__EMSCRIPTEN__)
1767 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1773 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1775 if(bitmap.driverData)
1777 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1778 glDeleteTextures(1, &tex);
1779 bitmap.driverData = 0;
1781 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1784 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1786 OGLSystem oglSystem = displaySystem.driverData;
1787 GLCapabilities capabilities = oglSystem.capabilities;
1788 bool result = false;
1790 GLuint glBitmap = 0;
1792 uint w = width, h = height;
1793 if(!capabilities.nonPow2Textures)
1798 w = Min(w, oglSystem.maxTextureSize);
1799 h = Min(h, oglSystem.maxTextureSize);
1801 glGenTextures(1, &glBitmap);
1802 glBindTexture(GL_TEXTURE_2D, glBitmap);
1804 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1806 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1807 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1809 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1810 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1813 if(!capabilities.shaders)
1814 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1817 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1819 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1820 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1824 bitmap.driverData = (void *)(uintptr)glBitmap;
1825 bitmap.driver = displaySystem.driver;
1833 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1835 bool result = false;
1836 OGLSystem oglSystem = displaySystem.driverData;
1837 GLCapabilities capabilities = oglSystem.capabilities;
1838 Bitmap convBitmap = bitmap;
1842 convBitmap.Copy(bitmap);
1845 // Pre process the bitmap... First make it 32 bit
1846 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1849 uint w = bitmap.width, h = bitmap.height;
1850 GLuint glBitmap = 0;
1851 if(!capabilities.nonPow2Textures)
1856 w = Min(w, oglSystem.maxTextureSize);
1857 h = Min(h, oglSystem.maxTextureSize);
1861 while(w * 2 < h) w *= 2;
1862 while(h * 2 < w) h *= 2;
1865 // Switch ARGB to RGBA
1866 //if(bitmap.format != pixelFormatRGBA)
1868 for(c=0; c<bitmap.size; c++)
1870 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1872 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1873 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1876 // convBitmap.pixelFormat = pixelFormat888;
1879 glGenTextures(1, &glBitmap);
1882 //int error = glGetError();
1886 glBindTexture(GL_TEXTURE_2D, glBitmap);
1887 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1889 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1890 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1892 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1894 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1895 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1897 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1898 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1899 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1900 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1904 if(!capabilities.shaders)
1905 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1910 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1915 if(bitmap.width != w || bitmap.height != h)
1917 mipMap = Bitmap { };
1918 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1920 Surface mipSurface = mipMap.GetSurface(0,0,null);
1921 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1931 mipMap = convBitmap;
1938 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1939 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1940 //printf("Calling glTexImage2D\n");
1941 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
1942 //printf("width = %d (Should be %d, %d)\n", width, w, h);
1943 if((error = glGetError()))
1945 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
1946 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
1950 if(mipMap != convBitmap)
1955 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
1956 bitmap.driverData = (void *)(uintptr)glBitmap;
1957 bitmap.driver = displaySystem.driver;
1962 FreeBitmap(displaySystem, bitmap);
1963 else if(oglSystem.loadingFont)
1965 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1966 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1967 oglSystem.loadingFont = false;
1973 void ReleaseSurface(Display display, Surface surface)
1975 glDisable(GL_SCISSOR_TEST);
1976 delete surface.driverData;
1977 surface.driverData = null;
1980 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
1985 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
1987 bool result = false;
1988 OGLDisplay oglDisplay = display.driverData;
1989 OGLSurface oglSurface = surface.driverData = OGLSurface { };
1992 SETCAPS(oglDisplay.capabilities);
1993 if(displayWidth != display.width || displayHeight != display.height)
1995 displayWidth = display.width;
1996 displayHeight = display.height;
1998 glViewport(0,0,display.width,display.height);
2000 GLOrtho(0,display.width,display.height,0,0.0,1.0);
2003 surface.offset.x = x;
2004 surface.offset.y = y;
2005 surface.unclippedBox = surface.box = clip;
2006 oglSurface.bitmapMult[0] = 1;
2007 oglSurface.bitmapMult[1] = 1;
2008 oglSurface.bitmapMult[2] = 1;
2009 oglSurface.bitmapMult[3] = 1;
2011 glEnable(GL_SCISSOR_TEST);
2014 (display.height) -(y+clip.bottom)-1,
2015 clip.right-clip.left+1,
2016 clip.bottom-clip.top+1);
2022 void Clip(Display display, Surface surface, Box clip)
2029 box.Clip(surface.unclippedBox);
2033 box = surface.box = surface.unclippedBox;
2034 box.left += surface.offset.x;
2035 box.top += surface.offset.y;
2036 box.right+= surface.offset.x;
2037 box.bottom += surface.offset.y;
2040 box.left,display.height - box.bottom - 1,
2041 box.right-box.left+1, box.bottom-box.top+1);
2044 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2046 bool result = false;
2047 OGLDisplay oglDisplay = display.driverData;
2048 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2050 if(oglDisplay.flippingBuffer)
2052 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2055 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2061 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2062 #if ENABLE_GL_LEGACY
2063 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2064 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2065 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2067 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2070 for(row = 0; row<h; row++)
2071 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2078 void SetForeground(Display display, Surface surface, ColorAlpha color)
2080 OGLSurface oglSurface = surface.driverData;
2082 oglSurface.foreground[0] = color.color.r/255.0f;
2083 oglSurface.foreground[1] = color.color.g/255.0f;
2084 oglSurface.foreground[2] = color.color.b/255.0f;
2085 //oglSurface.foreground[3] = 1.0f;
2086 oglSurface.foreground[3] = color.a/255.0f;
2088 //if(!oglSurface.foreground[3])printf("bug");
2091 void SetBackground(Display display, Surface surface, ColorAlpha color)
2093 OGLSurface oglSurface = surface.driverData;
2095 oglSurface.background[0] = color.color.r/255.0f;
2096 oglSurface.background[1] = color.color.g/255.0f;
2097 oglSurface.background[2] = color.color.b/255.0f;
2098 //oglSurface.background[3] = 1.0;
2099 oglSurface.background[3] = color.a/255.0f;
2102 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2104 OGLSurface oglSurface = surface.driverData;
2106 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2107 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2108 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2109 oglSurface.bitmapMult[3] = color.a/255.0f;
2112 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2117 void PutPixel(Display display, Surface surface,int x,int y)
2119 OGLSurface oglSurface = surface.driverData;
2120 GLColor4fv(oglSurface.foreground);
2122 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2123 GLVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2127 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2129 OGLSurface oglSurface = surface.driverData;
2130 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2145 x1 += surface.offset.x;
2146 y1 += surface.offset.y;
2147 x2 += surface.offset.x;
2148 y2 += surface.offset.y;
2150 GLColor4fv(oglSurface.foreground);
2154 GLTexCoord2f(0.5f, 0);
2155 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2156 GLTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2157 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2165 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2166 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2172 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2174 OGLSurface oglSurface = surface.driverData;
2175 x1 += surface.offset.x;
2176 y1 += surface.offset.y;
2177 x2 += surface.offset.x;
2178 y2 += surface.offset.y;
2180 GLColor4fv(oglSurface.foreground);
2185 GLTexCoord2f(0.5f, 0);
2186 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2187 GLTexCoord2f(y2-y1 + 0.5f, 0);
2188 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2190 GLTexCoord2f(0.5f, 0);
2191 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2192 GLTexCoord2f(x2 - x1 + 0.5f, 0);
2193 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2195 GLTexCoord2f(0.5f, 0);
2196 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2197 GLTexCoord2f(y1 - y2 + 0.5f, 0);
2198 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2200 GLTexCoord2f(0.5f, 0);
2201 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2202 GLTexCoord2f(x1 - x2 + 0.5f, 0);
2203 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2207 GLBegin(GL_LINE_LOOP);
2214 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2215 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2216 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2217 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2222 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2224 OGLSurface oglSurface = surface.driverData;
2226 GLColor4fv(oglSurface.background);
2228 GLRecti(x1+surface.offset.x, y1+surface.offset.y,
2229 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2231 GLRectf(x1+surface.offset.x, y1+surface.offset.y,
2232 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2236 void Clear(Display display, Surface surface, ClearType type)
2238 OGLDisplay oglDisplay = display.driverData;
2239 OGLSurface oglSurface = surface.driverData;
2242 if(type != depthBuffer)
2243 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2244 if(type != colorBuffer && !oglDisplay.depthWrite)
2246 glDepthMask((byte)bool::true);
2248 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2249 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2250 if(type != colorBuffer && !oglDisplay.depthWrite)
2252 glDepthMask((byte)bool::false);
2256 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2261 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2263 OGLSurface oglSurface = surface.driverData;
2265 if(!oglSurface.writingText)
2267 // glTranslatef(-0.375f, -0.375f, 0.0f);
2268 GLSetupTexturing(true);
2269 GLColor4fv(oglSurface.bitmapMult);
2271 else if(oglSurface.xOffset)
2272 GLTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2274 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2275 GLBegin(GLIMTKMode::quads);
2279 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2280 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2281 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2282 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2283 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2284 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2285 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2286 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2291 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2292 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2293 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2294 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2295 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2296 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2297 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2298 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2301 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2302 GLVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2303 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2304 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2305 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2306 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2307 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2308 GLVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2312 if(!oglSurface.writingText)
2314 GLSetupTexturing(false);
2316 //glTranslate(0.375, 0.375, 0.0);
2318 else if(oglSurface.xOffset)
2319 GLTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2322 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2324 OGLSurface oglSurface = surface.driverData;
2326 //glTranslate(-0.375, -0.375, 0.0);
2328 GLSetupTexturing(true);
2329 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2331 GLColor4fv(oglSurface.bitmapMult);
2333 GLBegin(GLIMTKMode::quads);
2337 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2338 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2340 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2341 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2343 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2344 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2346 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2347 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2351 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2352 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2354 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2355 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2357 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2358 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2360 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2361 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2366 GLSetupTexturing(false);
2368 //glTranslate(0.375, 0.375, 0.0);
2371 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2373 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2376 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2378 float s2dw,s2dh,d2sw,d2sh;
2379 //bool flipX = false, flipY = false;
2381 if(Sgn(w) != Sgn(sw))
2387 if(Sgn(h) != Sgn(sh))
2399 //Clip against the edges of the source
2402 dx+=(int)((0-sx) * s2dw);
2403 w-=(int)((0-sx) * s2dw);
2409 dy+=(int)((0-sy) * s2dh);
2410 h-=(int)((0-sy) * s2dh);
2415 if(sx+sw>bitmap.width-1)
2417 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2418 sw-=sx+sw-(bitmap.width-1)-1;
2420 if(sy+sh>(bitmap.height-1))
2422 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2423 sh-=sy+sh-(bitmap.height-1)-1;
2425 //Clip against the edges of the surfaceination
2426 if(dx<surface.box.left)
2429 sx+=(int)((surface.box.left-dx)*d2sw);
2430 sw-=(int)((surface.box.left-dx)*d2sw);
2431 w-=surface.box.left-dx;
2432 dx=surface.box.left;
2434 if(dy<surface.box.top)
2436 sy+=(int)((surface.box.top-dy)*d2sh);
2437 sh-=(int)((surface.box.top-dy)*d2sh);
2438 h-=surface.box.top-dy;
2441 if(dx+w>surface.box.right)
2443 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2444 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2445 w-=dx+w-surface.box.right-1;
2447 if(dy+h>surface.box.bottom)
2449 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2450 h-=dy+h-surface.box.bottom-1;
2452 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2454 dx += surface.offset.x;
2455 dy += surface.offset.y;
2457 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2459 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2460 #if ENABLE_GL_LEGACY
2463 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2464 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2465 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2466 glRasterPos2d(dx,dy);
2467 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2468 glPixelZoom(s2dw, -s2dh);
2469 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2470 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2471 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2472 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2475 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2479 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2481 //Clip against the edges of the source
2494 if(sx+w>bitmap.width-1)
2495 w-=sx+w-(bitmap.width-1)-1;
2496 if(sy+h>bitmap.height-1)
2497 h-=sy+h-(bitmap.height-1)-1;
2498 //Clip against the edges of the surfaceination
2499 if(dx<surface.box.left)
2502 sx+=surface.box.left-dx;
2503 w-=surface.box.left-dx;
2504 dx=surface.box.left;
2506 if(dy<surface.box.top)
2508 sy+=surface.box.top-dy;
2509 h-=surface.box.top-dy;
2512 if(dx+w>surface.box.right)
2514 //if(flip) sx+=dx+w-surface.box.right-1;
2515 w-=dx+w-surface.box.right-1;
2517 if(dy+h>surface.box.bottom)
2518 h-=dy+h-surface.box.bottom-1;
2522 dx += surface.offset.x;
2523 dy += surface.offset.y;
2525 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2527 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2528 #if ENABLE_GL_LEGACY
2531 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2532 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2533 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2534 glRasterPos2d(dx,dy);
2536 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2537 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2538 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2539 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2542 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2546 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2548 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2551 void UnloadFont(DisplaySystem displaySystem, Font font)
2553 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2556 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2559 OGLSystem oglSystem = displaySystem.driverData;
2560 oglSystem.loadingFont = true;
2561 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2565 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2567 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2570 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2572 OGLSurface oglSurface = surface.driverData;
2573 OGLSystem oglSystem = display.displaySystem.driverData;
2574 oglSystem.loadingFont = true;
2576 //glTranslated(-0.375, -0.375, 0.0);
2578 if(surface.textOpacity)
2580 int w = 0, h, adv = 0;
2581 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2583 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2586 oglSurface.writingText = true;
2588 GLSetupTexturing(true);
2590 if(surface.font.outlineSize)
2592 ColorAlpha outlineColor = surface.outlineColor;
2593 GLColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2594 oglSurface.writingOutline = true;
2595 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2596 oglSurface.writingOutline = false;
2598 GLColor4fv(oglSurface.foreground);
2600 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2601 oglSurface.writingText = false;
2602 oglSystem.loadingFont = false;
2604 GLSetupTexturing(false);
2606 //glTranslated(0.375, 0.375, 0.0);
2609 void TextFont(Display display, Surface surface, Font font)
2611 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2614 void TextOpacity(Display display, Surface surface, bool opaque)
2616 OGLSurface oglSurface = surface.driverData;
2617 oglSurface.opaqueText = opaque;
2620 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2622 OGLSurface oglSurface = surface.driverData;
2623 OGLSystem oglSystem = display.displaySystem.driverData;
2624 oglSystem.loadingFont = true;
2625 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2626 oglSystem.loadingFont = false;
2629 void DrawingChar(Display display, Surface surface, char character)
2634 void LineStipple(Display display, Surface surface, uint32 stipple)
2638 #if ENABLE_GL_LEGACY
2641 glLineStipple(1, (uint16)stipple);
2642 glEnable(GL_LINE_STIPPLE);
2647 stippleEnabled = true;
2648 glsupLineStipple(1, (uint16)stipple);
2653 #if ENABLE_GL_LEGACY
2655 glDisable(GL_LINE_STIPPLE);
2659 stippleEnabled = false;
2660 GLMatrixMode(GL_TEXTURE);
2662 GLMatrixMode(MatrixMode::projection);
2663 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2668 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2669 void SetRenderState(Display display, RenderState state, uint value)
2671 OGLDisplay oglDisplay = display.driverData;
2675 #ifndef __EMSCRIPTEN__
2677 glEnable(GL_MULTISAMPLE);
2679 glDisable(GL_MULTISAMPLE);
2683 #if ENABLE_GL_LEGACY
2685 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2689 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2692 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2693 oglDisplay.depthWrite = (bool)value;
2697 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2698 #if ENABLE_GL_SHADERS
2700 shader_fogColor(color[0], color[1], color[2]);
2705 glFogfv(GL_FOG_COLOR, (float *)&color);
2710 #if ENABLE_GL_SHADERS
2712 shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2717 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2721 //#if !defined(__EMSCRIPTEN__)
2722 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2727 #if ENABLE_GL_SHADERS
2729 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2735 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2736 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2743 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2748 #if defined(__WIN32__)
2749 if(wglSwapIntervalEXT)
2750 wglSwapIntervalEXT(value ? 1 : 0);
2757 void SetLight(Display display, int id, Light light)
2759 #if ENABLE_GL_SHADERS
2761 shader_setLight(display, id, light);
2769 Object lightObject = light.lightObject;
2770 float position[4] = { 0, 0, 0, 0 };
2771 float color[4] = { 0, 0, 0, 1 };
2773 glEnable(GL_LIGHT0 + id);
2775 if(!light.multiplier) light.multiplier = 1.0f;
2777 color[0] = light.diffuse.r * light.multiplier;
2778 color[1] = light.diffuse.g * light.multiplier;
2779 color[2] = light.diffuse.b * light.multiplier;
2780 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2782 color[0] = light.ambient.r * light.multiplier;
2783 color[1] = light.ambient.g * light.multiplier;
2784 color[2] = light.ambient.b * light.multiplier;
2785 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2786 color[0] = light.specular.r * light.multiplier;
2787 color[1] = light.specular.g * light.multiplier;
2788 color[2] = light.specular.b * light.multiplier;
2789 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2793 Vector3D positionVector;
2794 if(light.flags.spot)
2796 if(lightObject.flags.root || !lightObject.parent)
2798 positionVector = lightObject.transform.position;
2799 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2803 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2804 if(display.display3D.camera)
2805 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2811 if(!light.direction.x && !light.direction.y && !light.direction.z)
2813 Vector3Df vector { 0,0,-1 };
2815 mat.RotationQuaternion(light.orientation);
2816 positionVector.MultMatrixf(vector, mat);
2820 positionVector = light.direction;
2825 position[0] = (float)positionVector.x;
2826 position[1] = (float)positionVector.y;
2827 position[2] = (float)positionVector.z;
2829 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2832 // Display Light Position
2833 glDisable(GL_LIGHTING);
2834 glDisable(GL_DEPTH_TEST);
2838 glVertex3fv(position);
2840 glEnable(GL_DEPTH_TEST);
2841 glEnable(GL_LIGHTING);
2845 if(lightObject.flags.root || !lightObject.parent)
2847 positionVector = light.target.transform.position;
2848 positionVector.Subtract(positionVector, display.camera.cPosition);
2852 positionVector.MultMatrix(light.target.transform.position,
2853 lightObject.light.target.parent.matrix);
2854 positionVector.Subtract(positionVector, display.camera.cPosition);
2857 position[0] = positionVector.x;
2858 position[1] = positionVector.y;
2859 position[2] = positionVector.z;
2861 glDisable(GL_LIGHTING);
2862 glDisable(GL_DEPTH_TEST);
2866 glVertex3fv(position);
2868 glEnable(GL_DEPTH_TEST);
2869 glEnable(GL_LIGHTING);
2872 if(light.flags.attenuation)
2874 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2875 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2876 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2879 if(light.flags.spot)
2882 #define MAXLIGHT 0.9
2883 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2884 // Figure out exponent out of the hot spot
2885 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2887 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2888 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2889 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2894 Vector3Df vector { 0,0,-1 };
2895 Vector3Df direction;
2898 mat.RotationQuaternion(light.orientation);
2899 direction.MultMatrix(vector, mat);
2901 position[0] = direction.x;
2902 position[1] = direction.y;
2903 position[2] = direction.z;
2905 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2909 glDisable(GL_LIGHT0 + id);
2914 void SetCamera(Display display, Surface surface, Camera camera)
2916 OGLDisplay oglDisplay = display.driverData;
2918 if(surface && camera)
2920 int left = surface.box.left + surface.offset.x;
2921 int top = surface.box.top + surface.offset.y;
2922 int right = surface.box.right + surface.offset.x;
2923 int bottom = surface.box.bottom + surface.offset.y;
2924 float origX = surface.offset.x + camera.origin.x;
2925 float origY = surface.offset.y + camera.origin.y;
2927 int y = display.height - bottom - 1;
2928 int w = right - left + 1;
2929 int h = bottom - top + 1;
2932 glViewport(x, y, w, h);
2934 // *** Projection Matrix ***
2935 GLMatrixMode(MatrixMode::projection);
2936 if(!display.display3D.camera)
2939 if(display.display3D.collectingHits)
2941 float pickX = display.display3D.pickX + surface.offset.x;
2942 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
2946 w / display.display3D.pickWidth, 0, 0, 0,
2947 0, h / display.display3D.pickHeight, 0, 0,
2949 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
2950 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
2953 GLLoadMatrixd(pickMatrix.array);
2958 (left - origX) * camera.zMin / camera.focalX,
2959 (right - origX) * camera.zMin / camera.focalX,
2960 (bottom - origY) * camera.zMin / camera.focalY,
2961 (top - origY) * camera.zMin / camera.focalY,
2962 camera.zMin, camera.zMax);
2964 glDisable(GL_BLEND);
2966 // *** Z Inverted Identity Matrix ***
2967 GLMatrixMode(MatrixMode::modelView);
2968 if(!display.display3D.camera)
2973 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
2975 // *** View Matrix ***
2976 GLMultMatrixd(camera.viewMatrix.array);
2981 glEnable(GL_DEPTH_TEST);
2983 GLSetupLighting(true);
2986 glShadeModel(GL_SMOOTH);
2988 glDepthMask((byte)bool::true);
2989 oglDisplay.depthWrite = true;
2991 #ifndef __EMSCRIPTEN__
2992 glEnable(GL_MULTISAMPLE);
2995 else if(surface && display.display3D.camera)
2998 oglDisplay.depthWrite = false;
2999 glViewport(0,0,display.width,display.height);
3001 glDisable(GL_CULL_FACE);
3002 glDisable(GL_DEPTH_TEST);
3004 GLSetupTexturing(false);
3005 GLSetupLighting(false);
3008 GLDisableClientState(COLORS);
3010 #if ENABLE_GL_SHADERS
3012 shader_setPerVertexColor(false);
3017 glShadeModel(GL_FLAT);
3020 #if !defined(__EMSCRIPTEN__)
3021 glDisable(GL_MULTISAMPLE);
3024 // *** Restore 2D MODELVIEW Matrix ***
3027 // *** Restore 2D PROJECTION Matrix ***
3028 GLMatrixMode(MatrixMode::projection);
3034 void ApplyMaterial(Display display, Material material, Mesh mesh)
3037 if(material.flags.doubleSided)
3041 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3043 glDisable(GL_CULL_FACE);
3049 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3051 glEnable(GL_CULL_FACE);
3055 GLSetupFog(!material.flags.noFog);
3058 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3060 Bitmap map = material.baseMap;
3061 GLSetupTexturing(true);
3062 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3064 GLMatrixMode(GL_TEXTURE);
3066 if(material.uScale && material.vScale)
3067 GLScalef(material.uScale, material.vScale, 1);
3068 GLMatrixMode(MatrixMode::modelView);
3070 if(material.flags.tile)
3072 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3073 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3077 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3082 GLSetupTexturing(false);
3084 #if ENABLE_GL_SHADERS
3086 shader_setMaterial(material, mesh.flags.colors);
3092 if(mesh.flags.colors)
3094 GLColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3095 glEnable(GL_COLOR_MATERIAL);
3099 glDisable(GL_COLOR_MATERIAL);
3101 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3102 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3105 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3106 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3110 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3111 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3114 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3115 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3118 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3123 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3125 OGLMesh oglMesh = mesh.data;
3128 OGLSystem oglSystem = displaySystem.driverData;
3129 SETCAPS(oglSystem.capabilities);
3130 if(!mesh.flags.vertices)
3132 oglMesh.vertices.free(glcaps_vertexBuffer);
3133 delete mesh.vertices;
3135 if(!mesh.flags.normals)
3137 oglMesh.normals.free(glcaps_vertexBuffer);
3138 delete mesh.normals;
3140 if(!mesh.flags.texCoords1)
3142 oglMesh.texCoords.free(glcaps_vertexBuffer);
3143 delete mesh.texCoords;
3145 if(!mesh.flags.texCoords2)
3147 oglMesh.texCoords2.free(glcaps_vertexBuffer);
3148 // delete mesh.texCoords2;
3150 if(!mesh.flags.colors)
3152 oglMesh.colors.free(glcaps_vertexBuffer);
3163 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3165 bool result = false;
3168 mesh.data = OGLMesh { };
3171 if(mesh.nVertices == nVertices)
3173 // Same number of vertices, adding features (Leaves the other features pointers alone)
3174 if(mesh.flags != flags)
3176 if(!mesh.flags.vertices && flags.vertices)
3178 if(flags.doubleVertices)
3180 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3183 mesh.vertices = new Vector3Df[nVertices];
3185 if(!mesh.flags.normals && flags.normals)
3187 if(flags.doubleNormals)
3189 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3192 mesh.normals = new Vector3Df[nVertices];
3194 if(!mesh.flags.texCoords1 && flags.texCoords1)
3196 mesh.texCoords = new Pointf[nVertices];
3198 if(!mesh.flags.colors && flags.colors)
3200 mesh.colors = new ColorRGBAf[nVertices];
3206 // New number of vertices, reallocate all current and new features
3207 flags |= mesh.flags;
3210 if(flags.doubleVertices)
3212 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3215 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3219 if(flags.doubleNormals)
3221 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3224 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3226 if(flags.texCoords1)
3228 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3232 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3240 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3242 OGLSystem oglSystem = displaySystem.driverData;
3243 SETCAPS(oglSystem.capabilities);
3244 if(glcaps_vertexBuffer)
3246 OGLMesh oglMesh = mesh.data;
3247 if(!flags) flags = mesh.flags;
3249 oglMesh.vertices.upload(
3250 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices);
3253 oglMesh.normals.upload(
3254 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals);
3256 if(flags.texCoords1)
3257 oglMesh.texCoords.upload(
3258 mesh.nVertices * sizeof(Pointf), mesh.texCoords);
3261 oglMesh.colors.upload(
3262 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors);
3266 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3273 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3275 OGLSystem oglSystem = displaySystem.driverData;
3276 SETCAPS(oglSystem.capabilities);
3279 oglIndices.buffer.free(glcaps_vertexBuffer);
3280 delete oglIndices.indices;
3285 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3287 OGLIndices oglIndices = OGLIndices { };
3290 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3291 oglIndices.nIndices = nIndices;
3296 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3298 OGLSystem oglSystem = displaySystem.driverData;
3299 SETCAPS(oglSystem.capabilities);
3300 if(glcaps_vertexBuffer)
3302 #if !ENABLE_GL_INTDBL
3305 if(!oglIndices.buffer.buffer)
3306 glGenBuffers(1, &oglIndices.buffer.buffer);
3307 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3308 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3309 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW);
3313 oglIndices.buffer.upload(
3314 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3315 oglIndices.indices);
3319 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3322 return oglIndices.indices;
3325 void SelectMesh(Display display, Mesh mesh)
3327 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3328 #if defined(__WIN32__)
3329 if(glUnlockArraysEXT)
3331 if(!glcaps_vertexBuffer && display.display3D.mesh)
3332 glUnlockArraysEXT();
3336 OGLMesh oglMesh = mesh.data;
3338 // *** Vertex Stream ***
3339 GLEnableClientState(VERTICES);
3340 if(!display.display3D.collectingHits && oglMesh)
3342 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3344 // *** Normals Stream ***
3345 if(mesh.normals || mesh.flags.normals)
3347 GLEnableClientState(NORMALS);
3348 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3351 GLDisableClientState(NORMALS);
3353 // *** Texture Coordinates Stream ***
3354 if(mesh.texCoords || mesh.flags.texCoords1)
3356 GLEnableClientState(TEXCOORDS);
3357 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3360 GLDisableClientState(TEXCOORDS);
3362 // *** Color Stream ***
3363 if(mesh.colors || mesh.flags.colors)
3365 GLEnableClientState(COLORS);
3366 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3369 GLDisableClientState(COLORS);
3373 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3374 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3376 GLEnableClientState(NORMALS);
3377 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3380 GLDisableClientState(NORMALS);
3381 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3383 GLEnableClientState(TEXCOORDS);
3384 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3387 GLDisableClientState(TEXCOORDS);
3388 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3390 GLEnableClientState(COLORS);
3391 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3394 GLDisableClientState(COLORS);
3397 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3399 #if defined(__WIN32__)
3402 if(!glcaps_vertexBuffer)
3403 glLockArraysEXT(0, mesh.nVertices);
3408 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3410 if(primitive->type.vertexRange)
3413 glDrawArrays(getPrimitiveType(primitive->type.primitiveType), primitive->first, primitive->nVertices);
3417 OGLIndices oglIndices = primitive->data;
3418 GLEAB eab = ((!display.display3D.collectingHits && oglIndices && glcaps_vertexBuffer) ? oglIndices.buffer : noEAB);
3419 #if !ENABLE_GL_INTDBL
3420 if(!glcaps_vertexBuffer && primitive->type.indices32bit)
3422 uint16 * temp = new uint16[primitive->nIndices];
3423 uint32 * src = (uint32 *)(oglIndices ? oglIndices.indices : primitive->indices);
3425 for(i = 0; i < primitive->nIndices; i++)
3426 temp[i] = (uint16)src[i];
3427 eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices, GL_UNSIGNED_SHORT, temp);
3432 eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices,
3433 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3434 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3435 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3439 void PushMatrix(Display display)
3444 void PopMatrix(Display display, bool setMatrix)
3449 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3451 Matrix matrix = transMatrix;
3452 Camera camera = useCamera ? display.display3D.camera : null;
3457 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3462 matrix.m[3][0] - camera.cPosition.x,
3463 matrix.m[3][1] - camera.cPosition.y,
3464 matrix.m[3][2] - camera.cPosition.z);
3476 GLMultMatrixd(matrix.array);
3481 public void UseSingleGLContext(bool useSingle)
3483 useSingleGLContext = useSingle;
3486 default dllexport void *
3487 #if defined(__WIN32__)
3488 __attribute__((stdcall))
3490 IS_GLGetContext(DisplaySystem displaySystem)
3494 #if defined(__WIN32__)
3495 OGLSystem system = displaySystem.driverData;
3497 #elif defined(__ANDROID__) || defined(__ODROID__)
3499 #elif defined(__EMSCRIPTEN__)
3500 OGLSystem system = displaySystem.driverData;
3501 return (void *)system.glc;
3503 OGLSystem system = displaySystem.driverData;
3504 return system.glContext;