1 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
4 #if defined(_DEBUG) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
13 import "defaultShader"
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 defaultShader.texturing(enable);
328 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
332 public void GLSetupFog(bool enable)
334 #if ENABLE_GL_SHADERS
336 defaultShader.fog(enable);
341 (enable ? glEnable : glDisable)(GL_FOG);
345 bool lightingEnabled;
347 public void GLSetupLighting(bool enable)
349 lightingEnabled = enable;
350 #if ENABLE_GL_SHADERS
352 defaultShader.lighting(enable);
357 (enable ? glEnable : glDisable)(GL_LIGHTING);
362 /*static */GLuint lastBlitTex;
366 static int displayWidth, displayHeight;
368 #define GL_CLAMP_TO_EDGE 0x812F
370 static bool useSingleGLContext = false;
371 class OGLDisplay : struct
373 GLCapabilities capabilities, originalCapabilities;
377 ColorAlpha * flippingBuffer;
378 int flipBufH, flipBufW;
384 #if defined(__WIN32__)
395 byte * pboMemory1, * pboMemory2;
397 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
398 GLXContext glContext;
401 XShmSegmentInfo shminfo;
403 XShmSegmentInfo shminfoShape;
408 X11Picture windowPicture;
409 X11Picture pixmapPicture;
411 X11Picture shapePicture;
415 class OGLSystem : struct
419 #if defined(__WIN32__)
420 PIXELFORMATDESCRIPTOR pfd;
425 #elif defined(__EMSCRIPTEN__)
426 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
427 #elif !defined(__ANDROID__) && !defined(__ODROID__)
428 XVisualInfo * visualInfo;
429 GLXContext glContext;
430 GLXDrawable glxDrawable;
432 GLCapabilities capabilities;
437 uint16 *shortBDBuffer;
441 class OGLSurface : struct
449 float foreground[4], background[4], bitmapMult[4];
452 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 || 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 frameBuffer = 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 defaultShader.free();
994 delete oglSystem.shortBDBuffer;
997 #if defined(__WIN32__)
998 wglMakeCurrent( null, null );
1001 wglDeleteContext(oglSystem.glrc);
1004 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1005 DestroyWindow(oglSystem.hwnd);
1007 #elif defined(__unix__) || defined(__APPLE__)
1008 #if defined(__ANDROID__) || defined(__ODROID__)
1010 #elif defined(__EMSCRIPTEN__)
1011 emscripten_webgl_destroy_context(oglSystem.glc);
1013 if(oglSystem.visualInfo)
1015 #ifdef ECERE_MINIGLX
1016 __miniglx_XFree(oglSystem.visualInfo);
1018 XFree(oglSystem.visualInfo);
1021 if(oglSystem.glContext)
1022 glXDestroyContext(xGlobalDisplay, oglSystem.glContext);
1024 if(oglSystem.glxDrawable)
1026 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1027 oglSystem.glxDrawable = 0;
1034 /*static */bool ::initialDisplaySetup(Display display, bool canCheckExtensions, bool loadExtensions)
1036 OGLDisplay oglDisplay = display.driverData;
1037 OGLSystem oglSystem = display.displaySystem.driverData;
1040 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1041 if(loadExtensions && ogl_LoadFunctions() == ogl_LOAD_FAILED)
1042 PrintLn("ogl_LoadFunctions() failed!");
1043 CheckCapabilities(oglSystem, oglDisplay, canCheckExtensions);
1047 GLCapabilities capabilities = *&display.glCapabilities;
1048 // PrintLn("Available OpenGL Capabilities: ", oglDisplay.capabilities);
1049 // PrintLn("Desired OpenGL Capabilities: ", capabilities);
1051 oglDisplay.originalCapabilities = oglDisplay.capabilities;
1053 // Re-enable glCaps_shaders if no fixed function support
1054 if(!oglDisplay.capabilities.fixedFunction)
1055 capabilities.shaders = true;
1056 // Re-enable fixed function if no glCaps_shaders support
1057 if(!oglDisplay.capabilities.shaders)
1059 capabilities.fixedFunction = true;
1060 capabilities.shaders = false;
1063 if(!capabilities.shaders && !capabilities.fixedFunction)
1065 capabilities.fixedFunction = oglDisplay.capabilities.fixedFunction;
1066 capabilities.shaders = oglDisplay.capabilities.shaders;
1069 // Disable things that don't work with glCaps_shaders
1070 if(capabilities.shaders)
1072 capabilities.fixedFunction = false;
1073 capabilities.legacy = false;
1074 capabilities.immediate = false;
1077 #if !ENABLE_GL_POINTER
1078 // Re-enable vertex buffer if no pointer support
1079 capabilities.vertexBuffer = true;
1082 oglDisplay.capabilities &= capabilities;
1084 // PrintLn("Selected OpenGL Capabilities: ", oglDisplay.capabilities);
1085 oglSystem.capabilities = oglDisplay.capabilities;
1089 if(oglDisplay.capabilities.debug)
1092 oglDisplay.capabilities.debug = false;
1096 if(oglDisplay.capabilities.vao)
1098 glGenVertexArrays(1, &oglDisplay.vao);
1099 glBindVertexArray(oglDisplay.vao);
1103 oglSystem.capabilities = oglDisplay.capabilities;
1104 SETCAPS(oglDisplay.capabilities);
1106 #if ENABLE_GL_SHADERS
1109 #if ENABLE_GL_LEGACY
1110 if(oglDisplay.compat)
1112 glDisableClientState(GL_VERTEX_ARRAY);
1113 glDisableClientState(GL_NORMAL_ARRAY);
1114 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1115 glDisableClientState(GL_COLOR_ARRAY);
1118 defaultShader.select();
1120 #if ENABLE_GL_LEGACY
1123 glDisableVertexAttribArray(GLBufferContents::color);
1124 glDisableVertexAttribArray(GLBufferContents::normal);
1125 glDisableVertexAttribArray(GLBufferContents::texCoord);
1126 glDisableVertexAttribArray(GLBufferContents::vertex);
1127 glDisableVertexAttribArray(GLBufferContents::tangent1);
1128 glDisableVertexAttribArray(GLBufferContents::tangent2);
1130 glBindVertexArray(0);
1140 glBindVertexArray(oglDisplay.vao);
1143 GLEnableClientState(VERTICES);
1145 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1146 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1148 #if defined(__WIN32__)
1149 if(glBlendFuncSeparate)
1150 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1152 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1154 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1158 GLMatrixMode(MatrixMode::texture);
1161 GLMatrixMode(MatrixMode::modelView);
1162 GLLoadIdentity(); // For setting up GLES stack
1163 GLScaled(1.0, 1.0, -1.0);
1164 // glTranslatef(0.375f, 0.375f, 0.0f);
1165 // glTranslatef(-0.625f, -0.625f, 0.0f);
1166 GLMatrixMode(MatrixMode::projection);
1168 if(display.width && display.height)
1169 GLOrtho(0,display.width,display.height,0,0.0,1.0);
1174 glShadeModel(GL_FLAT);
1176 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1177 GLLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1180 ;//GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1182 glFogi(GL_FOG_MODE, GL_EXP);
1183 glFogf(GL_FOG_DENSITY, 0);
1184 glEnable(GL_NORMALIZE);
1187 glDepthFunc(GL_LESS);
1189 #if !defined(__EMSCRIPTEN__)
1190 glDisable(GL_MULTISAMPLE);
1193 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1194 display.ambient = Color { 50,50,50 };
1199 bool CreateDisplay(Display display)
1201 bool result = false;
1202 OGLDisplay oglDisplay = display.driverData;
1203 OGLSystem oglSystem = display.displaySystem.driverData;
1206 oglDisplay = display.driverData = OGLDisplay { };
1207 oglDisplay.capabilities = oglSystem.capabilities;
1209 #if defined(__WIN32__) || defined(USEPBUFFER)
1210 if(!display.alphaBlend)
1213 #if defined(__WIN32__)
1214 oglDisplay.hdc = GetDC(display.window);
1215 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1216 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, &oglDisplay.version, &oglDisplay.compat, (*&display.glCapabilities).compatible)))
1218 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1219 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1223 ReleaseDC(display.window, oglDisplay.hdc);
1224 #elif defined(__unix__) || defined(__APPLE__)
1225 # if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1228 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1230 #if defined(__APPLE__)
1231 XVisualInfo template = { 0 };
1232 XWindowAttributes winAttr;
1234 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1235 template.visualid = XVisualIDFromVisual(winAttr.visual);
1236 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1238 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1239 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1240 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1241 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1243 // visualInfo = oglSystem.visualInfo;
1246 #if !defined(__APPLE__)
1247 oglDisplay.compat = true;
1248 oglDisplay.version = 4;
1253 //printf("visualInfo is not null\n");
1254 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1255 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1256 //XFree(visualInfo);
1259 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1260 if(oglDisplay.glContext)
1262 //printf("CreateDisplay Got a Context\n");
1263 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1269 #if defined(__WIN32__) || defined(USEPBUFFER)
1272 oglDisplay.compat = (*&display.glCapabilities).compatible;
1274 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1279 #if defined(__EMSCRIPTEN__)
1280 emscripten_webgl_make_context_current(oglSystem.glc);
1283 #if defined(__WIN32__) || defined(USEPBUFFER)
1284 initialDisplaySetup(display, !display.alphaBlend, true);
1286 initialDisplaySetup(display, true, true);
1290 if(!useSingleGLContext)
1292 #if defined(__WIN32__)
1293 wglMakeCurrent(null, null);
1294 #elif defined(__unix__) || defined(__APPLE__)
1295 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1298 glXMakeCurrent(xGlobalDisplay, None, null);
1304 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1311 bool DisplaySize(Display display, int width, int height)
1313 OGLDisplay oglDisplay = display.driverData;
1314 bool result = false;
1316 #if defined(__WIN32__) || defined(USEPBUFFER)
1317 OGLSystem oglSystem = display.displaySystem.driverData;
1318 if(display.alphaBlend)
1320 #if defined(__WIN32__)
1321 const int attributes[]=
1323 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1324 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1326 int pixelFormat = 0;
1327 if(wglChoosePixelFormatARB)
1331 float fAttributes[] = {0,0};
1334 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1335 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1336 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1337 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1338 WGL_COLOR_BITS_ARB,24,
1339 WGL_ALPHA_BITS_ARB,8,
1340 WGL_DEPTH_BITS_ARB,16,
1341 WGL_STENCIL_BITS_ARB,0,
1342 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1343 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1344 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1348 //Log("Found wglChoosePixelFormatARB\n");
1350 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1351 if(!valid || !numFormats)
1353 //Log("Can't find 4x multi sampling\n");
1354 iAttributes[19] = 2;
1355 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1356 if(!valid || !numFormats)
1358 // Log("Can't find 2x multi sampling\n");
1359 iAttributes[16] = 0;
1360 iAttributes[17] = 0;
1361 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1362 if(!valid || !numFormats)
1366 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1367 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1368 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1369 WGL_COLOR_BITS_ARB,24,
1370 WGL_ALPHA_BITS_ARB,8,
1371 WGL_DEPTH_BITS_ARB,16,
1374 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1378 if(valid && numFormats)
1380 wglMakeCurrent(null, null);
1384 wglMakeCurrent( null, null );
1385 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1386 if(oglDisplay.hdc && oglDisplay.pBuffer)
1387 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1389 wglDestroyPbufferARB(oglDisplay.pBuffer);
1391 if(!useSingleGLContext)
1392 wglMakeCurrent( null, null );
1395 wglDeleteContext(oglDisplay.glrc);
1397 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1398 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1399 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, null, null, oglDisplay.capabilities.compatible)))
1402 HDC hdc = GetDC(display.window);
1404 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1405 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1407 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1408 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1410 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1412 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1416 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1417 oglDisplay.memDC = CreateCompatibleDC(hdc);
1418 SetMapMode(oglDisplay.memDC, MM_TEXT);
1419 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1420 info->bmiHeader.biPlanes = 1;
1421 info->bmiHeader.biCompression = BI_RGB;
1422 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1423 info->bmiHeader.biWidth = width;
1424 info->bmiHeader.biHeight = height;
1425 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1428 SelectObject(oglDisplay.memDC, newBitmap);
1429 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1432 PIXELFORMATDESCRIPTOR pfd = { 0 };
1433 pfd.nSize = (short)sizeof(pfd);
1435 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1436 pfd.iPixelType = PFD_TYPE_RGBA;
1437 pfd.cColorBits = 32;
1438 //pfd.cAlphaBits = 8;
1439 pfd.cDepthBits = 24;
1440 pfd.iLayerType = PFD_MAIN_PLANE;
1442 oglDisplay.hdc = oglDisplay.memDC;
1444 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1445 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1446 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1448 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1449 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1450 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1455 const int imageSize = width * height * 4;
1457 glGenBuffersARB(2, oglDisplay.imageBuffers);
1459 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1460 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1461 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1462 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1465 oglDisplay.memBitmap = newBitmap;
1466 oglDisplay.stride = width;
1472 ReleaseDC(display.window, hdc);
1474 #elif defined(__unix__) || defined(__APPLE__)
1475 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1480 GLX_DOUBLEBUFFER, True,
1486 GLX_STENCIL_SIZE, 1,
1487 //GLX_DEPTH_SIZE, 24,
1488 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1489 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1495 GLX_PBUFFER_WIDTH, width,
1496 GLX_PBUFFER_HEIGHT, height,
1497 GLX_LARGEST_PBUFFER, False,
1501 // choose a pixel format that meets our minimum requirements
1504 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1507 if(oglDisplay.pixmap)
1509 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1510 oglDisplay.pixmap = None;
1512 if(oglDisplay.shapePixmap)
1514 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1515 oglDisplay.shapePixmap = None;
1518 // Free Shared Memory Pixmap
1519 if(oglDisplay.image)
1521 if(oglDisplay.shminfoShape.shmid != -1)
1523 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1524 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1525 shmdt(oglDisplay.shminfo.shmaddr);
1526 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1528 XDestroyImage(oglDisplay.image);
1529 oglDisplay.image = None;
1531 if(oglDisplay.shapeImage)
1533 if(oglDisplay.shminfoShape.shmid != -1)
1535 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1536 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1537 shmdt(oglDisplay.shminfoShape.shmaddr);
1538 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1540 XDestroyImage(oglDisplay.shapeImage);
1541 oglDisplay.shapeImage = None;
1544 if(oglDisplay.windowPicture)
1545 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1546 if(oglDisplay.pixmapPicture)
1547 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1549 if(oglDisplay.pixmap)
1550 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1552 if(oglDisplay.glContext)
1553 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1554 if(oglDisplay.pBuffer)
1555 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1557 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1558 if(oglDisplay.pBuffer)
1560 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1561 if(oglDisplay.glContext)
1563 glXMakeCurrent(xGlobalDisplay, None, null);
1564 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1566 // Initialize Shared Memory Pixmap
1567 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1568 ZPixmap, null, &oglDisplay.shminfo, width, height);
1569 if(oglDisplay.image)
1571 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1572 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1573 if(oglDisplay.shminfo.shmid != -1)
1575 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1576 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1578 oglDisplay.shminfo.readOnly = False;
1579 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1581 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1582 &oglDisplay.shminfo, width, height, 32);
1584 // Initialize Shared Memory Shape Pixmap
1585 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1586 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1587 if(oglDisplay.shapeImage)
1589 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1590 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1591 if(oglDisplay.shminfoShape.shmid != -1)
1593 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1594 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1596 oglDisplay.shminfoShape.readOnly = False;
1597 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1599 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1600 &oglDisplay.shminfoShape, width, height, 1);
1601 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1604 XRenderPictureAttributes attributes = { 0 };
1605 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1606 #if !defined(__APPLE__)
1607 attributes.repeat = RepeatNormal;
1609 attributes.repeat = 1;
1611 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1612 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1613 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1614 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1617 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1618 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1635 CreateDisplay(display);
1636 #if defined(__WIN32__)
1637 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1638 #elif defined(__unix__) || defined(__APPLE__)
1639 #if defined(__ANDROID__) || defined(__ODROID__)
1642 #elif defined(__EMSCRIPTEN__)
1643 emscripten_webgl_make_context_current(oglSystem.glc);
1645 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1653 SETCAPS(oglDisplay.capabilities);
1655 if(display.alphaBlend && result)
1656 initialDisplaySetup(display, true, false);
1658 if(!result && display.alphaBlend)
1660 printf("Alpha blending windows not supported on this display\n");
1667 glViewport(0,0,width,height);
1668 GLMatrixMode(MatrixMode::projection);
1670 GLOrtho(0,width,height,0,0.0,1.0);
1671 displayWidth = display.width = width;
1672 displayHeight = display.height = height;
1674 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1676 oglDisplay.flipBufW = width;
1677 oglDisplay.flipBufH = height;
1678 #if defined(_GLES) || defined(_GLES2)
1681 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1684 if(oglDisplay.flippingBuffer || !width || !height)
1690 void DisplayPosition(Display display, int x, int y)
1692 OGLDisplay oglDisplay = display.driverData;
1698 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1702 void RestorePalette(Display display)
1706 void StartUpdate(Display display)
1711 OGLDisplay oglDisplay = display.driverData;
1712 glBindVertexArray(oglDisplay.vao);
1715 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1716 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1717 #if ENABLE_GL_SHADERS
1722 void EndUpdate(Display display)
1726 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1730 void Update(Display display, Box updateBox)
1732 #if defined(__WIN32__) || defined(USEPBUFFER)
1733 OGLDisplay oglDisplay = display.driverData;
1736 #if !defined(__ANDROID__)
1741 #if defined(__WIN32__) || defined(USEPBUFFER)
1742 if(display.alphaBlend)
1744 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1745 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1746 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1747 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1748 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1751 #if defined(__WIN32__)
1753 POINT point = { oglDisplay.x, oglDisplay.y};
1754 POINT srcPoint = { 0, 0 };
1755 BLENDFUNCTION blend = { 0 };
1757 size.cx = display.width;
1758 size.cy = display.height;
1759 blend.BlendOp = AC_SRC_OVER;
1760 blend.BlendFlags = 0;
1761 blend.SourceConstantAlpha = 255;
1762 blend.AlphaFormat = AC_SRC_ALPHA;
1765 // Process partial images. Mapping the buffer waits for
1766 // outstanding DMA transfers into the buffer to finish.
1767 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1768 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1770 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1771 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1774 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1775 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1778 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1781 // Unmap the image buffers
1782 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1783 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1785 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1786 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1788 // Bind two different buffer objects and start the glReadPixels
1789 // asynchronously. Each call will return directly after
1790 // starting the DMA transfer.
1791 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1792 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1794 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1795 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1799 #elif defined(__unix__) || defined(__APPLE__)
1800 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1802 XTransform transform =
1805 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1806 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1807 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1810 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1811 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1812 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1813 #if !defined(__APPLE__)
1814 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1816 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1818 XFlush(xGlobalDisplay);
1826 #if defined(__WIN32__)
1827 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1828 SwapBuffers(oglDisplay.hdc);
1829 //ecere::sys::Sleep(0.1);
1830 #elif defined(__unix__) || defined(__APPLE__)
1831 #if defined(__ANDROID__) || defined(__ODROID__)
1833 #elif defined(__EMSCRIPTEN__)
1835 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1841 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1843 if(bitmap.driverData)
1845 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1846 glDeleteTextures(1, &tex);
1847 bitmap.driverData = 0;
1849 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1852 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1854 OGLSystem oglSystem = displaySystem.driverData;
1855 GLCapabilities capabilities = oglSystem.capabilities;
1856 bool result = false;
1858 GLuint glBitmap = 0;
1860 uint w = width, h = height;
1861 if(!capabilities.nonPow2Textures)
1866 w = Min(w, oglSystem.maxTextureSize);
1867 h = Min(h, oglSystem.maxTextureSize);
1869 glGenTextures(1, &glBitmap);
1870 glBindTexture(GL_TEXTURE_2D, glBitmap);
1872 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1874 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1875 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1877 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1878 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1881 if(!capabilities.shaders)
1882 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1885 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1887 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1888 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1892 bitmap.driverData = (void *)(uintptr)glBitmap;
1893 bitmap.driver = displaySystem.driver;
1901 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps, uint cubeMapFace)
1903 bool result = false;
1904 OGLSystem oglSystem = displaySystem.driverData;
1905 GLCapabilities capabilities = oglSystem.capabilities;
1906 Bitmap convBitmap = bitmap;
1907 bool oldStyleCubeMap = (cubeMapFace >> 3) != 0;
1908 int face = (cubeMapFace & 7) - 1;
1912 convBitmap.Copy(bitmap);
1915 // Pre process the bitmap... First make it 32 bit
1916 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1919 uint w = bitmap.width, h = bitmap.height;
1920 GLuint glBitmap = cubeMapFace && face > 0 ? (GLuint)(uintptr)bitmap.driverData : 0;
1921 int target = cubeMapFace ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
1922 if(!capabilities.nonPow2Textures)
1927 w = Min(w, oglSystem.maxTextureSize);
1928 h = Min(h, oglSystem.maxTextureSize);
1932 while(w * 2 < h) w *= 2;
1933 while(h * 2 < w) h *= 2;
1936 // Switch ARGB to RGBA
1937 //if(bitmap.format != pixelFormatRGBA)
1939 int size = convBitmap.stride * convBitmap.height;
1940 for(c = 0; c < size; c++)
1942 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1944 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1945 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1948 // convBitmap.pixelFormat = pixelFormat888;
1950 if(cubeMapFace && oldStyleCubeMap)
1952 if(face == 0 || face == 1 || face == 4 || face == 5)
1954 uint w = convBitmap.width;
1955 uint32 * tmp = new uint [convBitmap.width];
1957 for(y = 0; y < convBitmap.height; y++)
1959 uint32 * pic = (uint32 *)((byte *)convBitmap.picture + y * w * 4);
1960 for(x = 0; x < w; x++)
1961 tmp[x] = pic[w-1-x];
1962 memcpy(pic, tmp, w*4);
1966 else if(face == 2 || face == 3)
1970 tmp.Allocate(null, convBitmap.width, convBitmap.height, 0, convBitmap.pixelFormat, false);
1971 for(y = 0; y < convBitmap.height; y++)
1973 memcpy(tmp.picture + convBitmap.width * 4 * y,
1974 convBitmap.picture + (convBitmap.height-1-y) * convBitmap.width * 4,
1975 convBitmap.width * 4);
1977 memcpy(convBitmap.picture, tmp.picture, convBitmap.sizeBytes);
1984 glGenTextures(1, &glBitmap);
1987 //int error = glGetError();
1991 glBindTexture(target, glBitmap);
1992 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1994 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1995 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1997 //glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1999 //glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP);
2000 //glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP);
2002 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2003 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2005 #ifndef GL_TEXTURE_WRAP_R
2006 #define GL_TEXTURE_WRAP_R 0x8072
2009 #if !defined(__EMSCRIPTEN__)
2011 glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
2014 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
2015 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
2019 if(!capabilities.shaders)
2020 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2025 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
2030 if(bitmap.width != w || bitmap.height != h)
2032 mipMap = Bitmap { };
2033 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
2035 Surface mipSurface = mipMap.GetSurface(0,0,null);
2036 mipSurface.blend = false;
2037 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
2047 mipMap = convBitmap;
2054 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2055 glTexImage2D(cubeMapFace ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2056 //printf("Calling glTexImage2D\n");
2057 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2058 //printf("width = %d (Should be %d, %d)\n", width, w, h);
2059 if((error = glGetError()))
2061 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2062 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2066 if(mipMap != convBitmap)
2071 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2072 bitmap.driverData = (void *)(uintptr)glBitmap;
2073 bitmap.driver = displaySystem.driver;
2078 FreeBitmap(displaySystem, bitmap);
2079 else if(oglSystem.loadingFont)
2081 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2082 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2083 oglSystem.loadingFont = false;
2089 void ReleaseSurface(Display display, Surface surface)
2091 glDisable(GL_SCISSOR_TEST);
2092 delete surface.driverData;
2093 surface.driverData = null;
2096 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2101 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2103 bool result = false;
2104 OGLDisplay oglDisplay = display.driverData;
2105 OGLSurface oglSurface = surface.driverData = OGLSurface { };
2108 SETCAPS(oglDisplay.capabilities);
2109 if(displayWidth != display.width || displayHeight != display.height)
2111 displayWidth = display.width;
2112 displayHeight = display.height;
2114 glViewport(0,0,display.width,display.height);
2116 GLOrtho(0,display.width,display.height,0,0.0,1.0);
2119 surface.offset.x = x;
2120 surface.offset.y = y;
2121 surface.unclippedBox = surface.box = clip;
2122 oglSurface.bitmapMult[0] = 1;
2123 oglSurface.bitmapMult[1] = 1;
2124 oglSurface.bitmapMult[2] = 1;
2125 oglSurface.bitmapMult[3] = 1;
2127 glEnable(GL_SCISSOR_TEST);
2130 (display.height) -(y+clip.bottom)-1,
2131 clip.right-clip.left+1,
2132 clip.bottom-clip.top+1);
2138 void Clip(Display display, Surface surface, Box clip)
2145 box.Clip(surface.unclippedBox);
2149 box = surface.box = surface.unclippedBox;
2150 box.left += surface.offset.x;
2151 box.top += surface.offset.y;
2152 box.right+= surface.offset.x;
2153 box.bottom += surface.offset.y;
2156 box.left,display.height - box.bottom - 1,
2157 box.right-box.left+1, box.bottom-box.top+1);
2160 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2162 bool result = false;
2163 OGLDisplay oglDisplay = display.driverData;
2164 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2166 if(oglDisplay.flippingBuffer)
2168 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2171 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2177 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2178 #if ENABLE_GL_LEGACY
2179 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2180 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2181 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2183 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2186 for(row = 0; row<h; row++)
2187 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2194 void SetForeground(Display display, Surface surface, ColorAlpha color)
2196 OGLSurface oglSurface = surface.driverData;
2198 oglSurface.foreground[0] = color.color.r/255.0f;
2199 oglSurface.foreground[1] = color.color.g/255.0f;
2200 oglSurface.foreground[2] = color.color.b/255.0f;
2201 //oglSurface.foreground[3] = 1.0f;
2202 oglSurface.foreground[3] = color.a/255.0f;
2204 //if(!oglSurface.foreground[3])printf("bug");
2207 void SetBackground(Display display, Surface surface, ColorAlpha color)
2209 OGLSurface oglSurface = surface.driverData;
2211 oglSurface.background[0] = color.color.r/255.0f;
2212 oglSurface.background[1] = color.color.g/255.0f;
2213 oglSurface.background[2] = color.color.b/255.0f;
2214 //oglSurface.background[3] = 1.0;
2215 oglSurface.background[3] = color.a/255.0f;
2218 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2220 OGLSurface oglSurface = surface.driverData;
2222 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2223 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2224 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2225 oglSurface.bitmapMult[3] = color.a/255.0f;
2228 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2233 void PutPixel(Display display, Surface surface,int x,int y)
2235 OGLSurface oglSurface = surface.driverData;
2236 GLColor4fv(oglSurface.foreground);
2238 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2239 GLVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2243 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2245 OGLSurface oglSurface = surface.driverData;
2246 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2261 x1 += surface.offset.x;
2262 y1 += surface.offset.y;
2263 x2 += surface.offset.x;
2264 y2 += surface.offset.y;
2266 GLColor4fv(oglSurface.foreground);
2270 GLTexCoord2f(0.5f, 0);
2271 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2272 GLTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2273 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2281 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2282 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2288 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2290 OGLSurface oglSurface = surface.driverData;
2291 x1 += surface.offset.x;
2292 y1 += surface.offset.y;
2293 x2 += surface.offset.x;
2294 y2 += surface.offset.y;
2296 GLColor4fv(oglSurface.foreground);
2301 GLTexCoord2f(0.5f, 0);
2302 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2303 GLTexCoord2f(y2-y1 + 0.5f, 0);
2304 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2306 GLTexCoord2f(0.5f, 0);
2307 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2308 GLTexCoord2f(x2 - x1 + 0.5f, 0);
2309 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2311 GLTexCoord2f(0.5f, 0);
2312 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2313 GLTexCoord2f(y1 - y2 + 0.5f, 0);
2314 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2316 GLTexCoord2f(0.5f, 0);
2317 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2318 GLTexCoord2f(x1 - x2 + 0.5f, 0);
2319 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2323 GLBegin(GL_LINE_LOOP);
2330 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2331 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2332 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2333 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2338 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2340 OGLSurface oglSurface = surface.driverData;
2342 GLColor4fv(oglSurface.background);
2344 GLRecti(x1+surface.offset.x, y1+surface.offset.y,
2345 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2347 GLRectf(x1+surface.offset.x, y1+surface.offset.y,
2348 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2352 void Clear(Display display, Surface surface, ClearType type)
2354 OGLDisplay oglDisplay = display.driverData;
2355 OGLSurface oglSurface = surface.driverData;
2358 if(type != depthBuffer)
2359 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2360 if(type != colorBuffer && !oglDisplay.depthWrite)
2362 glDepthMask((byte)bool::true);
2364 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2365 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2366 if(type != colorBuffer && !oglDisplay.depthWrite)
2368 glDepthMask((byte)bool::false);
2372 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2377 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2379 OGLSurface oglSurface = surface.driverData;
2380 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
2383 if(!oglSurface.writingText)
2385 // glTranslatef(-0.375f, -0.375f, 0.0f);
2386 GLSetupTexturing(true);
2387 GLColor4fv(oglSurface.bitmapMult);
2388 glBindTexture(GL_TEXTURE_2D, tex);
2389 GLBegin(GLIMTKMode::quads);
2391 else if(lastBlitTex != tex)
2395 glBindTexture(GL_TEXTURE_2D, tex);
2396 GLBegin(GLIMTKMode::quads);
2402 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2403 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2404 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2405 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2406 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2407 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2408 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2409 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2414 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2415 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2416 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2417 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2418 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2419 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2420 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2421 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2424 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2425 GLVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2426 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2427 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2428 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2429 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2430 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2431 GLVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2433 if(!oglSurface.writingText)
2436 GLSetupTexturing(false);
2437 //glTranslate(0.375, 0.375, 0.0);
2441 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2443 OGLSurface oglSurface = surface.driverData;
2445 //glTranslate(-0.375, -0.375, 0.0);
2447 GLSetupTexturing(true);
2448 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2450 GLColor4fv(oglSurface.bitmapMult);
2452 GLBegin(GLIMTKMode::quads);
2456 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2457 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2459 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2460 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2462 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2463 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2465 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2466 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2470 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2471 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2473 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2474 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2476 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2477 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2479 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2480 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2485 GLSetupTexturing(false);
2487 //glTranslate(0.375, 0.375, 0.0);
2490 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2492 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2495 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2497 float s2dw,s2dh,d2sw,d2sh;
2498 //bool flipX = false, flipY = false;
2500 if(Sgn(w) != Sgn(sw))
2506 if(Sgn(h) != Sgn(sh))
2518 //Clip against the edges of the source
2521 dx+=(int)((0-sx) * s2dw);
2522 w-=(int)((0-sx) * s2dw);
2528 dy+=(int)((0-sy) * s2dh);
2529 h-=(int)((0-sy) * s2dh);
2534 if(sx+sw>bitmap.width-1)
2536 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2537 sw-=sx+sw-(bitmap.width-1)-1;
2539 if(sy+sh>(bitmap.height-1))
2541 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2542 sh-=sy+sh-(bitmap.height-1)-1;
2544 //Clip against the edges of the surfaceination
2545 if(dx<surface.box.left)
2548 sx+=(int)((surface.box.left-dx)*d2sw);
2549 sw-=(int)((surface.box.left-dx)*d2sw);
2550 w-=surface.box.left-dx;
2551 dx=surface.box.left;
2553 if(dy<surface.box.top)
2555 sy+=(int)((surface.box.top-dy)*d2sh);
2556 sh-=(int)((surface.box.top-dy)*d2sh);
2557 h-=surface.box.top-dy;
2560 if(dx+w>surface.box.right)
2562 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2563 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2564 w-=dx+w-surface.box.right-1;
2566 if(dy+h>surface.box.bottom)
2568 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2569 h-=dy+h-surface.box.bottom-1;
2571 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2573 dx += surface.offset.x;
2574 dy += surface.offset.y;
2576 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2578 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2579 #if ENABLE_GL_LEGACY
2582 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2583 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2584 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2585 glRasterPos2d(dx,dy);
2586 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2587 glPixelZoom(s2dw, -s2dh);
2588 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2589 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2590 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2591 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2594 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2598 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2600 //Clip against the edges of the source
2613 if(sx+w>bitmap.width-1)
2614 w-=sx+w-(bitmap.width-1)-1;
2615 if(sy+h>bitmap.height-1)
2616 h-=sy+h-(bitmap.height-1)-1;
2617 //Clip against the edges of the surfaceination
2618 if(dx<surface.box.left)
2621 sx+=surface.box.left-dx;
2622 w-=surface.box.left-dx;
2623 dx=surface.box.left;
2625 if(dy<surface.box.top)
2627 sy+=surface.box.top-dy;
2628 h-=surface.box.top-dy;
2631 if(dx+w>surface.box.right)
2633 //if(flip) sx+=dx+w-surface.box.right-1;
2634 w-=dx+w-surface.box.right-1;
2636 if(dy+h>surface.box.bottom)
2637 h-=dy+h-surface.box.bottom-1;
2641 dx += surface.offset.x;
2642 dy += surface.offset.y;
2644 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2646 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2647 #if ENABLE_GL_LEGACY
2650 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2651 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2652 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2653 glRasterPos2d(dx,dy);
2655 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2656 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2657 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2658 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2661 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2665 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2667 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2670 void UnloadFont(DisplaySystem displaySystem, Font font)
2672 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2675 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2678 OGLSystem oglSystem = displaySystem.driverData;
2679 oglSystem.loadingFont = true;
2680 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2684 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2686 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2689 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2691 if(len && text[0] && surface.font)
2693 OGLSurface oglSurface = surface.driverData;
2694 OGLSystem oglSystem = display.displaySystem.driverData;
2695 oglSystem.loadingFont = true;
2697 //glTranslated(-0.375, -0.375, 0.0);
2699 if(surface.textOpacity)
2701 int w = 0, h, adv = 0;
2702 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2704 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2707 oglSurface.writingText = true;
2709 GLSetupTexturing(true);
2712 if(surface.font.outlineSize)
2714 ColorAlpha outlineColor = surface.outlineColor;
2717 GLColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2718 oglSurface.writingOutline = true;
2720 oglSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &fx, y, prevGlyph, rPrevGlyph, null);
2721 if(lastBlitTex) GLEnd();
2722 oglSurface.writingOutline = false;
2724 GLColor4fv(oglSurface.foreground);
2727 oglSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &x, y, prevGlyph, rPrevGlyph, null);
2729 if(lastBlitTex) GLEnd();
2732 oglSurface.writingText = false;
2733 oglSystem.loadingFont = false;
2735 GLSetupTexturing(false);
2737 //glTranslated(0.375, 0.375, 0.0);
2741 void TextFont(Display display, Surface surface, Font font)
2743 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2746 void TextOpacity(Display display, Surface surface, bool opaque)
2748 OGLSurface oglSurface = surface.driverData;
2749 oglSurface.opaqueText = opaque;
2752 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2754 OGLSurface oglSurface = surface.driverData;
2755 OGLSystem oglSystem = display.displaySystem.driverData;
2756 oglSystem.loadingFont = true;
2757 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2758 oglSystem.loadingFont = false;
2761 void DrawingChar(Display display, Surface surface, char character)
2766 void LineStipple(Display display, Surface surface, uint32 stipple)
2770 #if ENABLE_GL_LEGACY
2773 glLineStipple(1, (uint16)stipple);
2774 glEnable(GL_LINE_STIPPLE);
2779 stippleEnabled = true;
2780 glsupLineStipple(1, (uint16)stipple);
2785 #if ENABLE_GL_LEGACY
2787 glDisable(GL_LINE_STIPPLE);
2791 stippleEnabled = false;
2792 GLMatrixMode(GL_TEXTURE);
2794 GLMatrixMode(MatrixMode::projection);
2795 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2800 void ::disableRemainingTMUs(Display display, int lastTMU)
2802 OGLDisplay oglDisplay = display.driverData;
2804 for(t = lastTMU; t < oglDisplay.maxTMU; t++)
2806 glActiveTexture(GL_TEXTURE0 + t);
2807 glClientActiveTexture(GL_TEXTURE0 + t);
2808 glDisable(GL_TEXTURE_2D);
2809 glDisable(GL_TEXTURE_CUBE_MAP);
2810 GLDisableClientState(TEXCOORDS);
2812 glActiveTexture(GL_TEXTURE0);
2813 glClientActiveTexture(GL_TEXTURE0);
2814 oglDisplay.maxTMU = lastTMU;
2818 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2819 void SetRenderState(Display display, RenderState state, uint value)
2821 OGLDisplay oglDisplay = display.driverData;
2825 #ifndef __EMSCRIPTEN__
2827 glEnable(GL_MULTISAMPLE);
2829 glDisable(GL_MULTISAMPLE);
2833 #if ENABLE_GL_LEGACY
2835 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2839 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2842 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2843 oglDisplay.depthWrite = (bool)value;
2847 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2848 #if ENABLE_GL_SHADERS
2850 defaultShader.setFogColor(color[0], color[1], color[2]);
2855 glFogfv(GL_FOG_COLOR, (float *)&color);
2860 #if ENABLE_GL_SHADERS
2862 defaultShader.setFogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2867 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2871 //#if !defined(__EMSCRIPTEN__)
2872 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2877 #if ENABLE_GL_SHADERS
2879 defaultShader.setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2885 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2886 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2893 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2898 #if defined(__WIN32__)
2899 if(wglSwapIntervalEXT)
2900 wglSwapIntervalEXT(value ? 1 : 0);
2907 void SetLight(Display display, int id, Light light)
2909 #if ENABLE_GL_SHADERS
2911 defaultShader.setLight(display, id, light);
2917 if(light != null && !light.flags.off)
2919 Object lightObject = light.lightObject;
2920 float position[4] = { 0, 0, 0, 0 };
2921 float color[4] = { 0, 0, 0, 1 };
2924 glEnable(GL_LIGHT0 + id);
2926 if(!light.multiplier) light.multiplier = 1.0f;
2930 color[0] = light.diffuse.r * light.multiplier;
2931 color[1] = light.diffuse.g * light.multiplier;
2932 color[2] = light.diffuse.b * light.multiplier;
2933 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2935 color[0] = light.ambient.r * light.multiplier;
2936 color[1] = light.ambient.g * light.multiplier;
2937 color[2] = light.ambient.b * light.multiplier;
2938 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2940 color[0] = light.specular.r * light.multiplier;
2941 color[1] = light.specular.g * light.multiplier;
2942 color[2] = light.specular.b * light.multiplier;
2943 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2947 // Positional Lights, including Spot Lights (and omni light with flags.spot not set)
2948 Matrix * mat = &lightObject.matrix;
2949 l = { mat->m[3][0], mat->m[3][1], mat->m[3][2] };
2950 if(display.display3D && display.display3D.camera)
2951 l.Subtract(l, display.display3D.camera.cPosition);
2953 position[0] = (float)l.x, position[1] = (float)l.y, position[2] = (float)l.z, position[3] = 1;
2955 if(light.flags.attenuation)
2957 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2958 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2959 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2963 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, 1);
2964 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, 0);
2965 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, 0);
2968 if((light.flags.spot && light.fallOff < 360) || (lightObject && (light.direction.x || light.direction.y || light.direction.z)))
2970 // Figure out exponent out of the hot spot
2971 #define MAXLIGHT 0.9
2972 float exponent = light.flags.spot ? (float)(log(MAXLIGHT) / log(cos(light.hotSpot / 2))) : 1;
2973 Degrees cutOff = light.flags.spot ? light.fallOff/2 : 90;
2974 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2976 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2977 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)cutOff);
2978 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2982 float d[4] = { 0, 0, 1, 0 };
2983 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, d);
2984 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, 180);
2985 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, 1);
2991 // Display Light Position
2992 glDisable(GL_LIGHTING);
2993 glDisable(GL_DEPTH_TEST);
2997 glVertex3fv(position);
2999 glEnable(GL_DEPTH_TEST);
3000 glEnable(GL_LIGHTING);
3004 if(lightObject.flags.root || !lightObject.parent)
3006 positionVector = light.target.transform.position;
3007 positionVector.Subtract(positionVector, display.camera.cPosition);
3011 positionVector.MultMatrix(light.target.transform.position,
3012 lightObject.light.target.parent.matrix);
3013 positionVector.Subtract(positionVector, display.camera.cPosition);
3016 position[0] = positionVector.x;
3017 position[1] = positionVector.y;
3018 position[2] = positionVector.z;
3020 glDisable(GL_LIGHTING);
3021 glDisable(GL_DEPTH_TEST);
3025 glVertex3fv(position);
3027 glEnable(GL_DEPTH_TEST);
3028 glEnable(GL_LIGHTING);
3034 // Directional Light
3035 Vector3D vector { 0,0,-1 };
3038 mat.RotationQuaternion(light.orientation);
3039 direction.MultMatrix(vector, mat);
3040 l.Normalize(direction);
3041 position[0] = (float)l.x, position[1] = (float)l.y, position[2] = (float)l.z, position[3] = 0;
3043 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3044 if(display.display3D)
3047 Vector3Df v { position[0], position[1], position[2] };
3049 float * lp = display.display3D.light0Pos;
3050 if(display.display3D.camera)
3051 m = display.display3D.camera.viewMatrix;
3058 lp[3] = position[3];
3062 glDisable(GL_LIGHT0 + id);
3067 void SetCamera(Display display, Surface surface, Camera camera)
3069 OGLDisplay oglDisplay = display.driverData;
3071 if(surface && camera)
3073 int left = surface.box.left + surface.offset.x;
3074 int top = surface.box.top + surface.offset.y;
3075 int right = surface.box.right + surface.offset.x;
3076 int bottom = surface.box.bottom + surface.offset.y;
3077 float origX = surface.offset.x + camera.origin.x;
3078 float origY = surface.offset.y + camera.origin.y;
3080 int y = display.height - bottom - 1;
3081 int w = right - left + 1;
3082 int h = bottom - top + 1;
3085 glViewport(x, y, w, h);
3087 GLMatrixMode(MatrixMode::texture);
3088 if(!display.display3D.camera)
3092 // *** Projection Matrix ***
3093 GLMatrixMode(MatrixMode::projection);
3094 if(!display.display3D.camera)
3097 if(display.display3D.collectingHits)
3099 float pickX = display.display3D.pickX + surface.offset.x;
3100 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3104 w / display.display3D.pickWidth, 0, 0, 0,
3105 0, h / display.display3D.pickHeight, 0, 0,
3107 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3108 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3111 GLLoadMatrixd(pickMatrix.array);
3116 (left - origX) * camera.zMin / camera.focalX,
3117 (right - origX) * camera.zMin / camera.focalX,
3118 (bottom - origY) * camera.zMin / camera.focalY,
3119 (top - origY) * camera.zMin / camera.focalY,
3120 camera.zMin, camera.zMax);
3122 glDisable(GL_BLEND);
3124 // *** Z Inverted Identity Matrix ***
3125 GLMatrixMode(MatrixMode::modelView);
3126 if(!display.display3D.camera)
3131 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3133 // *** View Matrix ***
3134 GLMultMatrixd(camera.viewMatrix.array);
3136 #if ENABLE_GL_SHADERS
3139 defaultShader.select();
3140 defaultShader.setCamera(camera);
3147 glEnable(GL_DEPTH_TEST);
3149 GLSetupLighting(true);
3152 glShadeModel(GL_SMOOTH);
3154 glDepthMask((byte)bool::true);
3155 oglDisplay.depthWrite = true;
3157 #ifndef __EMSCRIPTEN__
3158 glEnable(GL_MULTISAMPLE);
3161 else if(surface && display.display3D.camera)
3164 oglDisplay.depthWrite = false;
3165 glViewport(0,0,display.width,display.height);
3167 glDisable(GL_CULL_FACE);
3168 glDisable(GL_DEPTH_TEST);
3170 GLDisableClientState(COLORS);
3171 #if ENABLE_GL_SHADERS
3174 GLDisableClientState(TANGENTS1);
3175 GLDisableClientState(TANGENTS2);
3178 GLDisableClientState(NORMALS);
3181 GLDisableClientState(LIGHTVECTORS);
3184 // *** Restore 2D MODELVIEW Matrix ***
3185 GLMatrixMode(MatrixMode::modelView);
3188 // *** Restore 2D TEXTURE Matrix ***
3189 GLMatrixMode(MatrixMode::texture);
3192 // *** Restore 2D PROJECTION Matrix ***
3193 GLMatrixMode(MatrixMode::projection);
3196 // NOTE: We expect the 2D projection matrix to be the active one for GetSurface to call glOrtho()
3198 #if ENABLE_GL_SHADERS
3200 defaultShader.select();
3206 disableRemainingTMUs(display, 0);
3207 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
3209 glDisable(GL_TEXTURE_CUBE_MAP);
3211 glDisable(GL_TEXTURE_GEN_STR);
3213 glDisable(GL_TEXTURE_GEN_R);
3214 glDisable(GL_TEXTURE_GEN_S);
3215 glDisable(GL_TEXTURE_GEN_T);
3220 GLSetupTexturing(false);
3221 GLSetupLighting(false);
3224 #if ENABLE_GL_SHADERS
3227 defaultShader.setPerVertexColor(false);
3228 defaultShader.setMaterial(null, 0);
3234 glShadeModel(GL_FLAT);
3237 #if !defined(__EMSCRIPTEN__)
3238 glDisable(GL_MULTISAMPLE);
3243 void ApplyMaterial(Display display, Material material, Mesh mesh)
3245 Shader shader = material.shader ? material.shader : defaultShader;
3246 MaterialFlags flags = material.flags;
3248 static int lastSeparate = 0;
3250 bool normalMapped = false;
3251 OGLMesh oglMesh = mesh ? mesh.data : null;
3254 #if ENABLE_GL_SHADERS
3255 if(glCaps_shaders && shader)
3260 if(flags.doubleSided)
3264 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !flags.singleSideLight);
3266 glDisable(GL_CULL_FACE);
3272 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3274 glEnable(GL_CULL_FACE);
3278 GLSetupFog(!flags.noFog);
3280 #if ENABLE_GL_SHADERS
3282 activeShader.setMaterial(material, mesh.flags);
3288 if(material.bumpMap && mesh.lightVectors)
3290 float color[4] = { 1,1,1,1 };
3291 glActiveTexture(GL_TEXTURE0 + tmu);
3292 glClientActiveTexture(GL_TEXTURE0 + tmu++);
3293 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
3294 glDisable(GL_TEXTURE_CUBE_MAP);
3295 glEnable(GL_TEXTURE_2D);
3297 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3298 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
3299 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
3300 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
3301 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3302 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
3303 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3305 if(0) //((DefaultShaderBits)defaultShader.state).debugging)
3307 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
3308 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
3309 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
3310 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
3311 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
3315 glDisable(GL_TEXTURE_GEN_STR);
3317 glDisable(GL_TEXTURE_GEN_R);
3318 glDisable(GL_TEXTURE_GEN_S);
3319 glDisable(GL_TEXTURE_GEN_T);
3321 glDisable(GL_LIGHTING);
3322 lightingEnabled = false;
3324 GLMatrixMode(GL_TEXTURE);
3326 if(material.uScale && material.vScale)
3327 GLScalef(material.uScale, material.vScale, 1);
3328 GLMatrixMode(MatrixMode::modelView);
3332 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3333 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3337 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3338 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3341 glActiveTexture(GL_TEXTURE0 + tmu);
3342 glClientActiveTexture(GL_TEXTURE0 + tmu);
3344 normalMapped = true;
3346 // Modulate base color
3347 if(material.diffuse.r < 1 || material.diffuse.g < 1 || material.diffuse.b < 1)
3350 glDisable(GL_TEXTURE_CUBE_MAP);
3351 glEnable(GL_TEXTURE_2D);
3352 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
3353 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3354 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
3355 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
3357 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
3358 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
3359 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3360 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3362 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
3363 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT);
3364 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
3365 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
3367 color[0] = material.diffuse.r, color[1] = material.diffuse.g, color[2] = material.diffuse.b, color[3] = 1.0;
3368 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
3369 glActiveTexture(GL_TEXTURE0 + tmu);
3370 glClientActiveTexture(GL_TEXTURE0 + tmu);
3373 // Add ambient light
3375 ColorRGB ambient { material.ambient.r * 0.2f, material.ambient.g * 0.2f, material.ambient.g * 0.2f };
3376 if(ambient.r > 0 || ambient.g > 0 || ambient.b > 0)
3379 glDisable(GL_TEXTURE_CUBE_MAP);
3380 glEnable(GL_TEXTURE_2D);
3381 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
3382 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3383 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
3384 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
3386 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
3387 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
3388 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3389 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3391 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
3392 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT);
3393 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
3394 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
3396 color[0] = ambient.r, color[1] = ambient.g, color[2] = ambient.b, color[3] = 1.0;
3397 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
3398 glActiveTexture(GL_TEXTURE0 + tmu);
3399 glClientActiveTexture(GL_TEXTURE0 + tmu);
3405 GLDisableClientState(LIGHTVECTORS);
3406 if(!lightingEnabled)
3408 glEnable(GL_LIGHTING);
3409 lightingEnabled = true;
3415 if(flags.cubeMap || (material.baseMap && (mesh.texCoords || mesh.flags.texCoords1)))
3417 Bitmap map = material.baseMap;
3418 int diffuseTarget = flags.cubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
3423 glActiveTexture(GL_TEXTURE0 + tmu);
3424 glClientActiveTexture(GL_TEXTURE0 + tmu++);
3425 glEnable(diffuseTarget);
3426 glDisable(flags.cubeMap ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP);
3430 #if ENABLE_GL_SHADERS
3431 if(glCaps_shaders && !flags.cubeMap)
3432 GLSetupTexturing(true);
3435 glBindTexture(diffuseTarget, (GLuint)(uintptr)map.driverData);
3440 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
3441 /* // This did not have the desired effect with a GL_ALPHA texture
3442 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3443 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
3444 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
3445 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
3446 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
3447 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
3448 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
3449 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3450 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3451 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
3452 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
3458 glEnable(GL_TEXTURE_GEN_STR);
3459 // GL_OBJECT_LINEAR: No extension support?
3460 // glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
3462 GLfloat xPlane[] = { 1.0f, 0.0f, 0.0f, 0 };
3463 GLfloat yPlane[] = { 0.0f,-1.0f, 0.0f, 0 };
3464 GLfloat zPlane[] = { 0.0f, 0.0f,-1.0f, 0 };
3465 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
3466 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
3467 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
3468 glTexGenfv(GL_R, GL_OBJECT_PLANE, zPlane);
3469 glTexGenfv(GL_S, GL_OBJECT_PLANE, xPlane);
3470 glTexGenfv(GL_T, GL_OBJECT_PLANE, yPlane);
3472 glEnable(GL_TEXTURE_GEN_R);
3473 glEnable(GL_TEXTURE_GEN_S);
3474 glEnable(GL_TEXTURE_GEN_T);
3477 GLDisableClientState(TEXCOORDS);
3482 glDisable(GL_TEXTURE_GEN_STR);
3484 glDisable(GL_TEXTURE_GEN_R);
3485 glDisable(GL_TEXTURE_GEN_S);
3486 glDisable(GL_TEXTURE_GEN_T);
3490 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3491 GLEnableClientState(TEXCOORDS);
3493 glClientActiveTexture(GL_TEXTURE0);
3498 glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
3499 glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
3503 glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3504 glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3509 GLSetupTexturing(false);
3512 #if ENABLE_GL_FFP && !defined(_GLES)
3515 int separate = material.flags.separateSpecular ? GL_SEPARATE_SPECULAR_COLOR : GL_SINGLE_COLOR;
3516 if(separate != lastSeparate)
3518 GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, separate);
3519 lastSeparate = separate;
3524 if((flags.cubeMap && material.baseMap) ||
3525 (mesh.texCoords && (material.baseMap || material.bumpMap || material.specularMap || material.reflectMap)))
3530 glActiveTexture(GL_TEXTURE0 + tmu - 1);
3531 glClientActiveTexture(GL_TEXTURE0 + tmu - 1);
3534 GLMatrixMode(GL_TEXTURE);
3536 if(material.uScale && material.vScale)
3537 GLScalef(material.uScale, material.vScale, 1);
3538 GLMatrixMode(MatrixMode::modelView);
3542 glActiveTexture(GL_TEXTURE0);
3543 glClientActiveTexture(GL_TEXTURE0);
3551 if(material.envMap && material.refractiveIndex)
3553 float color[4] = { material.opacity, material.opacity, material.opacity, 1.0 };
3554 glActiveTexture(GL_TEXTURE0 + tmu);
3555 glClientActiveTexture(GL_TEXTURE0 + tmu++);
3556 glBindTexture(GL_TEXTURE_CUBE_MAP, (GLuint)(uintptr)material.envMap.driverData);
3557 glEnable(GL_TEXTURE_CUBE_MAP);
3559 glEnable(GL_TEXTURE_GEN_STR);
3560 glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3562 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3563 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3564 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3565 glEnable(GL_TEXTURE_GEN_R);
3566 glEnable(GL_TEXTURE_GEN_S);
3567 glEnable(GL_TEXTURE_GEN_T);
3570 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3573 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
3575 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
3576 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
3578 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
3579 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
3581 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
3582 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
3584 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3585 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3587 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
3588 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
3592 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
3593 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, GL_CONSTANT);
3594 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
3595 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
3598 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
3600 GLMatrixMode(MatrixMode::texture);
3602 double * s = display.display3D.camera.viewMatrix.array;
3606 k*s[0],-k*s[4],-k*s[8], 0,
3607 k*s[1],-k*s[5],-k*s[9], 0,
3608 k*s[2],-k*s[6],-k*s[10],0,
3611 GLLoadMatrixd(m.array);
3613 GLMatrixMode(MatrixMode::modelView);
3616 if(material.envMap && material.reflectivity)
3618 float color[4] = { 1.0f - material.reflectivity, 1.0f - material.reflectivity, 1.0f - material.reflectivity, 1.0 };
3619 glActiveTexture(GL_TEXTURE0 + tmu);
3620 glClientActiveTexture(GL_TEXTURE0 + tmu++);
3621 glBindTexture(GL_TEXTURE_CUBE_MAP, (GLuint)(uintptr)material.envMap.driverData);
3622 glEnable(GL_TEXTURE_CUBE_MAP);
3624 glEnable(GL_TEXTURE_GEN_STR);
3625 glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3627 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3628 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3629 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3630 glEnable(GL_TEXTURE_GEN_R);
3631 glEnable(GL_TEXTURE_GEN_S);
3632 glEnable(GL_TEXTURE_GEN_T);
3635 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3638 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
3640 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
3641 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
3643 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
3644 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
3646 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
3647 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
3648 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3649 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3650 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
3651 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
3655 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
3656 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, GL_CONSTANT);
3657 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
3658 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
3661 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
3663 GLMatrixMode(MatrixMode::texture);
3665 double * s = display.display3D.camera.inverseTranspose.array;
3673 GLLoadMatrixd(m.array);
3675 GLMatrixMode(MatrixMode::modelView);
3683 disableRemainingTMUs(display, tmu);
3685 if(mesh.flags.colors)
3687 GLColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3688 glEnable(GL_COLOR_MATERIAL);
3692 glDisable(GL_COLOR_MATERIAL);
3694 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3695 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3698 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3699 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3702 if(material.power > 0.1)
3704 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3705 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3709 float color[4] = { 0,0,0,0 };
3710 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3713 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3714 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3716 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3721 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3723 OGLMesh oglMesh = mesh.data;
3726 OGLSystem oglSystem = displaySystem.driverData;
3727 GLCapabilities caps = glCaps;
3728 SETCAPS(oglSystem.capabilities);
3730 if(!mesh.flags.vertices)
3732 oglMesh.vertices.free();
3733 delete mesh.vertices;
3735 if(!mesh.flags.normals)
3737 oglMesh.normals.free();
3738 delete mesh.normals;
3740 if(!mesh.flags.tangents)
3742 oglMesh.tangents.free();
3743 delete mesh.tangents;
3745 if(!mesh.flags.lightVectors)
3747 oglMesh.lightVectors.free();
3748 delete mesh.lightVectors;
3750 if(!mesh.flags.texCoords1)
3752 oglMesh.texCoords.free();
3753 delete mesh.texCoords;
3755 if(!mesh.flags.texCoords2)
3757 oglMesh.texCoords2.free();
3758 // delete mesh.texCoords2;
3760 if(!mesh.flags.colors)
3762 oglMesh.colors.free();
3774 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3776 bool result = false;
3779 mesh.data = OGLMesh { };
3782 if(mesh.nVertices == nVertices)
3784 // Same number of vertices, adding features (Leaves the other features pointers alone)
3785 if(mesh.flags != flags)
3787 if(!mesh.flags.vertices && flags.vertices)
3789 if(flags.doubleVertices)
3791 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3794 mesh.vertices = new Vector3Df[nVertices];
3796 if(!mesh.flags.normals && flags.normals)
3798 if(flags.doubleNormals)
3800 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3803 mesh.normals = new Vector3Df[nVertices];
3805 if(!mesh.flags.tangents && flags.tangents)
3807 mesh.tangents = new Vector3Df[2*nVertices];
3809 if(!mesh.flags.lightVectors && flags.lightVectors)
3811 mesh.lightVectors = new ColorRGB[nVertices];
3813 if(!mesh.flags.texCoords1 && flags.texCoords1)
3815 mesh.texCoords = new Pointf[nVertices];
3817 if(!mesh.flags.colors && flags.colors)
3819 mesh.colors = new ColorRGBAf[nVertices];
3825 // New number of vertices, reallocate all current and new features
3826 flags |= mesh.flags;
3829 if(flags.doubleVertices)
3831 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3834 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3838 if(flags.doubleNormals)
3840 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3843 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3845 if(flags.texCoords1)
3847 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3851 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3855 mesh.tangents = renew mesh.tangents Vector3Df[2 * nVertices];
3857 if(flags.lightVectors)
3859 mesh.lightVectors = renew mesh.lightVectors ColorRGB[nVertices];
3867 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3869 OGLSystem oglSystem = displaySystem.driverData;
3870 GLCapabilities caps = glCaps;
3871 SETCAPS(oglSystem.capabilities);
3873 if(glCaps_vertexBuffer)
3875 OGLMesh oglMesh = mesh.data;
3876 if(!flags) flags = mesh.flags;
3878 oglMesh.vertices.allocate(
3879 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, staticDraw);
3882 oglMesh.normals.allocate(
3883 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, staticDraw);
3885 if(flags.texCoords1)
3886 oglMesh.texCoords.allocate(
3887 mesh.nVertices * sizeof(Pointf), mesh.texCoords, staticDraw);
3890 oglMesh.colors.allocate(
3891 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, staticDraw);
3894 oglMesh.tangents.allocate(mesh.nVertices * 2*sizeof(Vector3Df), mesh.tangents, staticDraw);
3896 if(flags.lightVectors)
3897 oglMesh.lightVectors.allocate(mesh.nVertices * sizeof(ColorRGB), mesh.lightVectors, staticDraw);
3902 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3909 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3911 OGLSystem oglSystem = displaySystem.driverData;
3912 GLCapabilities caps = glCaps;
3913 SETCAPS(oglSystem.capabilities);
3917 oglIndices.buffer.free();
3918 delete oglIndices.indices;
3924 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3926 OGLIndices oglIndices = OGLIndices { };
3929 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3930 oglIndices.nIndices = nIndices;
3935 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3937 OGLSystem oglSystem = displaySystem.driverData;
3938 GLCapabilities caps = glCaps;
3939 SETCAPS(oglSystem.capabilities);
3941 if(glCaps_vertexBuffer)
3943 if(!glCaps_intAndDouble && indices32bit)
3945 if(!oglIndices.buffer.buffer)
3946 glGenBuffers(1, &oglIndices.buffer.buffer);
3947 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3948 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3951 uint * pointer = (uint *)oglIndices.indices;
3954 if(nIndices > oglSystem.shortBDSize)
3956 oglSystem.shortBDSize = nIndices;
3957 oglSystem.shortBDBuffer = renew oglSystem.shortBDBuffer uint16[oglSystem.shortBDSize];
3959 b = oglSystem.shortBDBuffer;
3960 for(i = 0; i < nIndices; i++)
3961 b[i] = (uint16)pointer[i];
3963 glBufferData(GL_ELEMENT_ARRAY_BUFFER, nIndices * sizeof(uint16), b, GL_STATIC_DRAW);
3967 oglIndices.buffer.allocate(
3968 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3969 oglIndices.indices, staticDraw);
3974 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3977 return oglIndices.indices;
3980 void SelectMesh(Display display, Mesh mesh)
3982 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3983 #if defined(__WIN32__)
3984 if(glUnlockArraysEXT)
3986 if(!glCaps_vertexBuffer && display.display3D.mesh)
3987 glUnlockArraysEXT();
3991 OGLMesh oglMesh = mesh.data;
3993 // *** Vertex Stream ***
3994 GLEnableClientState(VERTICES);
3995 if(!display.display3D.collectingHits && oglMesh)
3997 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3999 // *** Normals Stream ***
4000 if(mesh.normals || mesh.flags.normals)
4002 GLEnableClientState(NORMALS);
4003 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
4006 GLDisableClientState(NORMALS);
4008 #if ENABLE_GL_SHADERS
4011 // *** Tangents Stream ***
4012 if(mesh.tangents || mesh.flags.tangents)
4014 GLEnableClientState(TANGENTS1);
4015 GLEnableClientState(TANGENTS2);
4016 oglMesh.tangents.use(tangent1, 3, GL_FLOAT, sizeof(Vector3Df)*2, oglMesh.tangents.buffer ? null : mesh.tangents);
4017 oglMesh.tangents.use(tangent2, 3, GL_FLOAT, sizeof(Vector3Df)*2, oglMesh.tangents.buffer ? (void *)sizeof(Vector3Df) : mesh.tangents+1);
4021 GLDisableClientState(TANGENTS1);
4022 GLDisableClientState(TANGENTS2);
4027 // *** Texture Coordinates Stream ***
4028 if(mesh.texCoords || mesh.flags.texCoords1)
4030 GLEnableClientState(TEXCOORDS);
4031 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
4034 GLDisableClientState(TEXCOORDS);
4039 // *** Normal Map Aligned Light Vector ***
4040 if(mesh.lightVectors || mesh.flags.lightVectors)
4042 GLEnableClientState(LIGHTVECTORS);
4043 oglMesh.lightVectors.use(lightVector, 3, GL_FLOAT, 0, oglMesh.lightVectors.buffer ? null : mesh.lightVectors);
4046 GLDisableClientState(LIGHTVECTORS);
4050 // *** Color Stream ***
4051 if(mesh.colors || mesh.flags.colors)
4053 GLEnableClientState(COLORS);
4054 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
4057 GLDisableClientState(COLORS);
4061 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
4062 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
4064 GLEnableClientState(NORMALS);
4065 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
4068 GLDisableClientState(NORMALS);
4069 #if ENABLE_GL_SHADERS
4072 if((mesh.tangents || mesh.flags.tangents) && !display.display3D.collectingHits)
4074 GLEnableClientState(TANGENTS1);
4075 GLEnableClientState(TANGENTS2);
4076 noAB.use(tangent1, 3, GL_FLOAT, sizeof(Vector3Df)*2, mesh.tangents);
4077 noAB.use(tangent2, 3, GL_FLOAT, sizeof(Vector3Df)*2, mesh.tangents+1);
4081 GLDisableClientState(TANGENTS1);
4082 GLDisableClientState(TANGENTS2);
4087 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
4089 GLEnableClientState(TEXCOORDS);
4090 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
4093 GLDisableClientState(TEXCOORDS);
4098 if((mesh.lightVectors || mesh.flags.lightVectors) && !display.display3D.collectingHits)
4100 GLEnableClientState(LIGHTVECTORS);
4101 noAB.use(lightVector, 3, GL_FLOAT, sizeof(ColorRGB), mesh.lightVectors);
4104 GLDisableClientState(LIGHTVECTORS);
4108 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
4110 GLEnableClientState(COLORS);
4111 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
4114 GLDisableClientState(COLORS);
4117 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
4119 #if defined(__WIN32__)
4122 if(!glCaps_vertexBuffer)
4123 glLockArraysEXT(0, mesh.nVertices);
4128 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
4130 if(primitive->type.vertexRange)
4133 glDrawArrays(getPrimitiveType(primitive->type.primitiveType), primitive->first, primitive->nVertices);
4137 OGLIndices oglIndices = primitive->data;
4138 GLEAB eab = ((!display.display3D.collectingHits && oglIndices && glCaps_vertexBuffer) ? oglIndices.buffer : noEAB);
4139 if(!glCaps_intAndDouble && !glCaps_vertexBuffer && primitive->type.indices32bit)
4141 uint16 * temp = new uint16[primitive->nIndices];
4142 uint32 * src = (uint32 *)(oglIndices ? oglIndices.indices : primitive->indices);
4144 for(i = 0; i < primitive->nIndices; i++)
4145 temp[i] = (uint16)src[i];
4146 eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices, GL_UNSIGNED_SHORT, temp);
4150 eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices,
4151 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
4152 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
4153 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
4157 void PushMatrix(Display display)
4162 void PopMatrix(Display display, bool setMatrix)
4167 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
4169 Matrix matrix = transMatrix;
4170 Camera camera = useCamera ? display.display3D.camera : null;
4175 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
4180 matrix.m[3][0] - camera.cPosition.x,
4181 matrix.m[3][1] - camera.cPosition.y,
4182 matrix.m[3][2] - camera.cPosition.z);
4194 GLMultMatrixd(matrix.array);
4199 public void UseSingleGLContext(bool useSingle)
4201 useSingleGLContext = useSingle;
4204 default dllexport void *
4205 #if defined(__WIN32__)
4206 __attribute__((stdcall))
4208 IS_GLGetContext(DisplaySystem displaySystem)
4212 #if defined(__WIN32__)
4213 OGLSystem system = displaySystem.driverData;
4215 #elif defined(__ANDROID__) || defined(__ODROID__)
4217 #elif defined(__EMSCRIPTEN__)
4218 OGLSystem system = displaySystem.driverData;
4219 return (void *)system.glc;
4221 OGLSystem system = displaySystem.driverData;
4222 return system.glContext;