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;
383 #if defined(__WIN32__)
394 byte * pboMemory1, * pboMemory2;
396 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
397 GLXContext glContext;
400 XShmSegmentInfo shminfo;
402 XShmSegmentInfo shminfoShape;
407 X11Picture windowPicture;
408 X11Picture pixmapPicture;
410 X11Picture shapePicture;
414 class OGLSystem : struct
418 #if defined(__WIN32__)
419 PIXELFORMATDESCRIPTOR pfd;
424 #elif defined(__EMSCRIPTEN__)
425 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
426 #elif !defined(__ANDROID__) && !defined(__ODROID__)
427 XVisualInfo * visualInfo;
428 GLXContext glContext;
429 GLXDrawable glxDrawable;
431 GLCapabilities capabilities;
436 uint16 *shortBDBuffer;
440 class OGLSurface : struct
448 float foreground[4], background[4], bitmapMult[4];
451 class OGLMesh : struct
462 class OGLIndices : struct
472 #if defined(__WIN32__)
473 static HGLRC winCreateContext(HDC hdc, int * contextVersion, bool * isCompatible, bool compatible)
476 if(wglCreateContextAttribsARB)
478 int versions[12][2] =
480 { 4, 5 }, { 4, 4 }, { 4, 3 }, { 4, 2 }, { 4, 1 }, { 4, 0 },
481 { 3, 3 }, { 3, 2 }, { 3, 1 }, { 3, 0 },
485 bool tryingCompat = compatible;
489 for(v = 0; !result && v < sizeof(versions) / sizeof(versions[0]); v++)
491 int v0 = versions[v][0], v1 = versions[v][1];
492 if(!tryingCompat || v0 >= 3)
494 bool coreNotion = v0 > 3 || (v0 == 3 && v1 >= 3);
497 WGL_CONTEXT_MAJOR_VERSION_ARB, v0, WGL_CONTEXT_MINOR_VERSION_ARB, v1,
499 WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
501 coreNotion ? WGL_CONTEXT_PROFILE_MASK_ARB : 0, coreNotion ? (tryingCompat ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB) : 0,
504 result = wglCreateContextAttribsARB(hdc, null, attribs);
507 if(contextVersion) *contextVersion = v0;
508 if(isCompatible) *isCompatible = tryingCompat || !coreNotion;
513 tryingCompat = false;
520 if(contextVersion) *contextVersion = 1;
521 if(isCompatible) *isCompatible = true;
522 result = wglCreateContext(hdc);
529 static int maxTMU = 0;
531 static void disableRemainingTMUs(int lastTMU)
534 for(t = lastTMU; t < maxTMU; t++)
536 glActiveTexture(GL_TEXTURE0 + t);
537 glClientActiveTexture(GL_TEXTURE0 + t);
538 glDisable(GL_TEXTURE_2D);
539 glDisable(GL_TEXTURE_CUBE_MAP);
540 GLDisableClientState(TEXCOORDS);
542 glActiveTexture(GL_TEXTURE0);
543 glClientActiveTexture(GL_TEXTURE0);
548 class OpenGLDisplayDriver : DisplayDriver
550 class_property(name) = "OpenGL";
552 bool LockSystem(DisplaySystem displaySystem)
554 #if defined(__EMSCRIPTEN__)
555 OGLSystem oglSystem = displaySystem.driverData;
556 emscripten_webgl_make_context_current(oglSystem.glc);
557 #elif !defined(__ANDROID__) && !defined(__ODROID__)
558 OGLSystem oglSystem = displaySystem.driverData;
559 if(useSingleGLContext) return true;
560 #if defined(__WIN32__)
561 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
562 #elif defined(__unix__) || defined(__APPLE__)
563 //if(previous) return true;
564 // printf("Making SYSTEM current\n");
565 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
566 //previous = oglSystem.glContext;
569 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
570 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
574 void UnlockSystem(DisplaySystem displaySystem)
576 if(useSingleGLContext) return;
577 #if defined(__WIN32__)
578 wglMakeCurrent(null, null);
579 #elif defined(__unix__) || defined(__APPLE__)
580 // printf("Making NULL current\n");
581 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
583 glXMakeCurrent(xGlobalDisplay, None, null);
589 bool Lock(Display display)
591 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
592 OGLDisplay oglDisplay = display.driverData;
593 if(useSingleGLContext) return true;
594 #if defined(__WIN32__)
595 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
596 #elif defined(__unix__) || defined(__APPLE__)
597 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
598 // printf(" Making DISPLAY current\n");
599 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
602 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
603 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
607 void Unlock(Display display)
609 if(useSingleGLContext) return;
610 //printf(" Making NULL current\n");
611 //glXMakeCurrent(xGlobalDisplay, None, null);
613 LockSystem(display.displaySystem);
616 void DestroyDisplay(Display display)
618 OGLDisplay oglDisplay = display.driverData;
622 #if defined(__WIN32__)
623 wglMakeCurrent( null, null );
626 wglDeleteContext(oglDisplay.glrc);
628 if(oglDisplay.hdc && oglDisplay.pBuffer)
629 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
631 if(oglDisplay.pBuffer)
632 wglDestroyPbufferARB(oglDisplay.pBuffer);
635 ReleaseDC(display.window, oglDisplay.hdc);
637 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
638 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
640 #elif defined(__unix__) || defined(__APPLE__)
641 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
643 if(oglDisplay.shapePixmap)
644 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
645 if(oglDisplay.pixmap)
646 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
649 if(oglDisplay.shminfoShape.shmid != -1)
651 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
652 if(oglDisplay.shminfo.shmaddr != (void *)-1)
653 shmdt(oglDisplay.shminfo.shmaddr);
654 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
657 if(oglDisplay.shapeImage)
659 if(oglDisplay.shminfoShape.shmid != -1)
661 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
662 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
663 shmdt(oglDisplay.shminfoShape.shmaddr);
664 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
666 XDestroyImage(oglDisplay.shapeImage);
667 oglDisplay.shapeImage = None;
670 glXMakeCurrent(xGlobalDisplay, None, null);
672 if(oglDisplay.glContext)
673 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
676 delete oglDisplay.flippingBuffer;
678 display.driverData = null;
682 #if !defined(__EMSCRIPTEN__)
683 void ::CheckCapabilities(OGLSystem oglSystem, OGLDisplay oglDisplay, bool canCheckExtensions)
685 GLCapabilities capabilities;
687 const char * extensions = (canCheckExtensions && (!oglDisplay || oglDisplay.compat)) ? (const char *)glGetString(GL_EXTENSIONS) : null;
690 printf("extensions: %s\n", extensions);
693 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
696 capabilities = { fixedFunction = true, vertexPointer = true, vertexBuffer = true, pointSize = true, legacyFormats = true, frameBuffer = extensions && strstr(extensions, "GL_OES_framebuffer_object") };
697 #elif defined(_GLES2)
698 capabilities = { glCaps_shaders = true, vertexBuffer = true, pointSize = true, frameBuffer = true, legacyFormats = true };
702 nonPow2Textures = glGetStringi || (extensions && (strstr(extensions, "GL_ARB_texture_non_power_of_two")));
707 compatible = oglDisplay.compat;
708 pointSize = oglDisplay.compat;
710 legacy = glBegin != null && oglDisplay.compat;
711 legacyFormats = glBegin != null && oglDisplay.compat;
712 immediate = glBegin != null && oglDisplay.compat;
713 fixedFunction = glBegin != null && oglDisplay.compat;
714 quads = glBegin != null && oglDisplay.compat;
715 select = glSelectBuffer != null && oglDisplay.compat;
717 #if ENABLE_GL_SHADERS
718 shaders = glCreateProgram != null;
720 #if ENABLE_GL_POINTER
721 vertexPointer = oglDisplay.compat;
724 vao = glBindVertexArray != null && !oglDisplay.compat;
727 shaders = glBindFramebuffer != null;
729 vertexBuffer = glBindBuffer != null;
730 // mapBuffer = glMapBuffer != null;
735 PrintLn("max texture size: ", oglSystem.maxTextureSize);
737 if(oglDisplay) oglDisplay.capabilities = capabilities;
738 if(oglSystem) oglSystem.capabilities = capabilities;
742 bool CreateDisplaySystem(DisplaySystem displaySystem)
745 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
748 oglSystem.capabilities = { fixedFunction = true, vertexBuffer = true, frameBuffer = true, pointSize = true };
749 #elif defined(_GLES2)
750 oglSystem.capabilities = { shaders = true, vertexBuffer = true, frameBuffer = true, pointSize = true };
752 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 };
756 PrintLn("OpenGL driver's CreateDisplaySystem()");
760 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
762 oglSystem.hdc = GetDC(oglSystem.hwnd);
766 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
767 oglSystem.pfd.nVersion = 1;
768 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
769 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
770 oglSystem.pfd.cColorBits = 24;
771 oglSystem.pfd.cAlphaBits = 8;
772 oglSystem.pfd.cDepthBits = 24;
773 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
775 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
776 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
778 if(oglSystem.pfd.cColorBits > 8)
780 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
781 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
784 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
786 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
787 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
788 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
789 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
790 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
791 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
792 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
793 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
794 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
795 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
796 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
798 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
799 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
801 // eSystem_LoggingMode(LOG_MSGBOX, null);
803 if(wglChoosePixelFormatARB)
808 float fAttributes[] = {0,0};
811 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
812 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
813 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
814 WGL_COLOR_BITS_ARB,24,
815 WGL_ALPHA_BITS_ARB,8,
816 WGL_DEPTH_BITS_ARB,16,
817 WGL_STENCIL_BITS_ARB,0,
818 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
819 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
820 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
824 //Log("Found wglChoosePixelFormatARB\n");
826 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
827 if(!valid || !numFormats)
829 //Log("Can't find 4x multi sampling\n");
831 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
832 if(!valid || !numFormats)
834 // Log("Can't find 2x multi sampling\n");
837 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
840 if(valid && numFormats)
842 oglSystem.format = pixelFormat;
843 wglMakeCurrent(null, null);
844 wglDeleteContext(oglSystem.glrc);
846 // *** DescribePixelFormat does not support WGL pixel formats! ***
847 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
848 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
849 //Log("Successfully set pixel format\n");
852 PrintLn("winCreateContext()");
854 oglSystem.glrc = winCreateContext(oglSystem.hdc, &oglSystem.version, &oglSystem.compat, displaySystem.glCapabilities.compatible);
856 PrintLn("wglMakeCurrent()");
859 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
863 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
867 wglMakeCurrent(null, null);
869 //eSystem_DumpErrors(true);
873 #elif defined(__unix__) || defined(__APPLE__)
874 #if defined(__ANDROID__) || defined(__ODROID__)
875 #if defined(__ANDROID__)
876 egl_init_display(guiApp.desktop.windowHandle);
877 #elif defined(__ODROID__)
878 egl_init_display((uint)displaySystem.window);
880 CheckCapabilities(oglSystem, null, true);
882 // TODO: Clean this up? Needed here?
883 GLEnableClientState(VERTICES);
885 // Initialize GL state.
886 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
887 glEnable(GL_CULL_FACE);
888 glShadeModel(GL_SMOOTH);
889 glDisable(GL_DEPTH_TEST);
891 glDisable(GL_CULL_FACE);
892 glDisable(GL_DEPTH_TEST);
894 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
897 matrixStack[0][0].Identity();
898 matrixStack[1][0].Identity();
899 matrixStack[2][0].Identity();
901 GLMatrixMode(GL_MODELVIEW);
902 GLScaled(1.0, 1.0, -1.0);
903 GLMatrixMode(GL_PROJECTION);
904 glShadeModel(GL_FLAT);
908 ;//GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
910 glFogi(GL_FOG_MODE, GL_EXP);
911 glFogf(GL_FOG_DENSITY, 0);
912 glEnable(GL_NORMALIZE);
913 glDepthFunc(GL_LESS);
915 glDisable(GL_MULTISAMPLE);
917 glViewport(0,0,eglWidth,eglHeight);
919 GLOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
921 glabCurArrayBuffer = 0;
922 glabCurElementBuffer = 0;
925 #elif defined(__EMSCRIPTEN__)
927 EmscriptenWebGLContextAttributes attribs = { 0 };
929 attribs.antialias = 1;
936 EM_BOOL premultipliedAlpha;
937 EM_BOOL preserveDrawingBuffer;
938 EM_BOOL preferLowPowerToHighPerformance;
939 EM_BOOL failIfMajorPerformanceCaveat;
942 EM_BOOL enableExtensionsByDefault;
945 emscripten_webgl_init_context_attributes(&attribs);
946 oglSystem.maxTextureSize = 16384;
947 oglSystem.glc = emscripten_webgl_create_context("canvas", &attribs);
948 if(emscripten_webgl_make_context_current(oglSystem.glc) == EMSCRIPTEN_RESULT_SUCCESS)
951 /*glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
952 glEnable(GL_BLEND);*/
956 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
957 XSetWindowAttributes attr;
962 #ifndef ECERE_MINIGLX
963 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
966 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
970 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
971 attr.background_pixel = 0;
972 attr.border_pixel = 0;
973 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
974 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
975 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
977 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
978 oglSystem.visualInfo->visual, mask, &attr );
980 if(oglSystem.visualInfo)
982 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
983 if(oglSystem.glContext)
985 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
986 glXMakeCurrent(xGlobalDisplay, None, null);
993 displaySystem.flags.alpha = true;
994 displaySystem.flags.flipping = true;
995 displaySystem.pixelFormat = pixelFormat888;
999 void DestroyDisplaySystem(DisplaySystem displaySystem)
1001 OGLSystem oglSystem = displaySystem.driverData;
1004 glDeleteTextures(1, &stippleTexture);
1008 #if ENABLE_GL_SHADERS
1009 defaultShader.free();
1010 activeShader = null;
1013 delete oglSystem.shortBDBuffer;
1016 #if defined(__WIN32__)
1017 wglMakeCurrent( null, null );
1020 wglDeleteContext(oglSystem.glrc);
1023 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1024 DestroyWindow(oglSystem.hwnd);
1026 #elif defined(__unix__) || defined(__APPLE__)
1027 #if defined(__ANDROID__) || defined(__ODROID__)
1029 #elif defined(__EMSCRIPTEN__)
1030 emscripten_webgl_destroy_context(oglSystem.glc);
1032 if(oglSystem.visualInfo)
1034 #ifdef ECERE_MINIGLX
1035 __miniglx_XFree(oglSystem.visualInfo);
1037 XFree(oglSystem.visualInfo);
1040 if(oglSystem.glContext)
1041 glXDestroyContext(xGlobalDisplay, oglSystem.glContext);
1043 if(oglSystem.glxDrawable)
1045 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1046 oglSystem.glxDrawable = 0;
1053 /*static */bool ::initialDisplaySetup(Display display, bool canCheckExtensions, bool loadExtensions)
1055 OGLDisplay oglDisplay = display.driverData;
1056 OGLSystem oglSystem = display.displaySystem.driverData;
1059 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1060 if(loadExtensions && ogl_LoadFunctions() == ogl_LOAD_FAILED)
1061 PrintLn("ogl_LoadFunctions() failed!");
1062 CheckCapabilities(oglSystem, oglDisplay, canCheckExtensions);
1066 GLCapabilities capabilities = *&display.glCapabilities;
1067 // PrintLn("Available OpenGL Capabilities: ", oglDisplay.capabilities);
1068 // PrintLn("Desired OpenGL Capabilities: ", capabilities);
1070 oglDisplay.originalCapabilities = oglDisplay.capabilities;
1072 // Re-enable glCaps_shaders if no fixed function support
1073 if(!oglDisplay.capabilities.fixedFunction)
1074 capabilities.shaders = true;
1075 // Re-enable fixed function if no glCaps_shaders support
1076 if(!oglDisplay.capabilities.shaders)
1078 capabilities.fixedFunction = true;
1079 capabilities.shaders = false;
1082 if(!capabilities.shaders && !capabilities.fixedFunction)
1084 capabilities.fixedFunction = oglDisplay.capabilities.fixedFunction;
1085 capabilities.shaders = oglDisplay.capabilities.shaders;
1088 // Disable things that don't work with glCaps_shaders
1089 if(capabilities.shaders)
1091 capabilities.fixedFunction = false;
1092 capabilities.legacy = false;
1093 capabilities.immediate = false;
1096 #if !ENABLE_GL_POINTER
1097 // Re-enable vertex buffer if no pointer support
1098 capabilities.vertexBuffer = true;
1101 oglDisplay.capabilities &= capabilities;
1103 // PrintLn("Selected OpenGL Capabilities: ", oglDisplay.capabilities);
1104 oglSystem.capabilities = oglDisplay.capabilities;
1108 if(oglDisplay.capabilities.debug)
1111 oglDisplay.capabilities.debug = false;
1115 if(oglDisplay.capabilities.vao)
1117 glGenVertexArrays(1, &oglDisplay.vao);
1118 glBindVertexArray(oglDisplay.vao);
1122 oglSystem.capabilities = oglDisplay.capabilities;
1123 SETCAPS(oglDisplay.capabilities);
1125 #if ENABLE_GL_SHADERS
1128 #if ENABLE_GL_LEGACY
1129 if(oglDisplay.compat)
1131 glDisableClientState(GL_VERTEX_ARRAY);
1132 glDisableClientState(GL_NORMAL_ARRAY);
1133 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1134 glDisableClientState(GL_COLOR_ARRAY);
1137 defaultShader.select();
1139 #if ENABLE_GL_LEGACY
1142 glDisableVertexAttribArray(GLBufferContents::color);
1143 glDisableVertexAttribArray(GLBufferContents::normal);
1144 glDisableVertexAttribArray(GLBufferContents::texCoord);
1145 glDisableVertexAttribArray(GLBufferContents::vertex);
1146 glDisableVertexAttribArray(GLBufferContents::tangent1);
1147 glDisableVertexAttribArray(GLBufferContents::tangent2);
1148 glBindVertexArray(0);
1157 glBindVertexArray(oglDisplay.vao);
1160 GLEnableClientState(VERTICES);
1162 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1163 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1165 #if defined(__WIN32__)
1166 if(glBlendFuncSeparate)
1167 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1169 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1171 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1175 GLMatrixMode(MatrixMode::texture);
1178 GLMatrixMode(MatrixMode::modelView);
1179 GLLoadIdentity(); // For setting up GLES stack
1180 GLScaled(1.0, 1.0, -1.0);
1181 // glTranslatef(0.375f, 0.375f, 0.0f);
1182 // glTranslatef(-0.625f, -0.625f, 0.0f);
1183 GLMatrixMode(MatrixMode::projection);
1185 if(display.width && display.height)
1186 GLOrtho(0,display.width,display.height,0,0.0,1.0);
1191 glShadeModel(GL_FLAT);
1193 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1194 GLLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1197 ;//GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1199 glFogi(GL_FOG_MODE, GL_EXP);
1200 glFogf(GL_FOG_DENSITY, 0);
1201 glEnable(GL_NORMALIZE);
1204 glDepthFunc(GL_LESS);
1206 #if !defined(__EMSCRIPTEN__)
1207 glDisable(GL_MULTISAMPLE);
1210 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1211 display.ambient = Color { 50,50,50 };
1216 bool CreateDisplay(Display display)
1218 bool result = false;
1219 OGLDisplay oglDisplay = display.driverData;
1220 OGLSystem oglSystem = display.displaySystem.driverData;
1223 oglDisplay = display.driverData = OGLDisplay { };
1224 oglDisplay.capabilities = oglSystem.capabilities;
1226 #if defined(__WIN32__) || defined(USEPBUFFER)
1227 if(!display.alphaBlend)
1230 #if defined(__WIN32__)
1231 oglDisplay.hdc = GetDC(display.window);
1232 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1233 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, &oglDisplay.version, &oglDisplay.compat, (*&display.glCapabilities).compatible)))
1235 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1236 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1240 ReleaseDC(display.window, oglDisplay.hdc);
1241 #elif defined(__unix__) || defined(__APPLE__)
1242 # if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1245 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1247 #if defined(__APPLE__)
1248 XVisualInfo template = { 0 };
1249 XWindowAttributes winAttr;
1251 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1252 template.visualid = XVisualIDFromVisual(winAttr.visual);
1253 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1255 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1256 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1257 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1258 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1260 // visualInfo = oglSystem.visualInfo;
1263 #if !defined(__APPLE__)
1264 oglDisplay.compat = true;
1265 oglDisplay.version = 4;
1270 //printf("visualInfo is not null\n");
1271 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1272 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1273 //XFree(visualInfo);
1276 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1277 if(oglDisplay.glContext)
1279 //printf("CreateDisplay Got a Context\n");
1280 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1286 #if defined(__WIN32__) || defined(USEPBUFFER)
1289 oglDisplay.compat = (*&display.glCapabilities).compatible;
1291 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1296 #if defined(__EMSCRIPTEN__)
1297 emscripten_webgl_make_context_current(oglSystem.glc);
1300 #if defined(__WIN32__) || defined(USEPBUFFER)
1301 initialDisplaySetup(display, !display.alphaBlend, true);
1303 initialDisplaySetup(display, true, true);
1307 if(!useSingleGLContext)
1309 #if defined(__WIN32__)
1310 wglMakeCurrent(null, null);
1311 #elif defined(__unix__) || defined(__APPLE__)
1312 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1315 glXMakeCurrent(xGlobalDisplay, None, null);
1321 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1328 bool DisplaySize(Display display, int width, int height)
1330 OGLDisplay oglDisplay = display.driverData;
1331 bool result = false;
1333 #if defined(__WIN32__) || defined(USEPBUFFER)
1334 OGLSystem oglSystem = display.displaySystem.driverData;
1335 if(display.alphaBlend)
1337 #if defined(__WIN32__)
1338 const int attributes[]=
1340 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1341 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1343 int pixelFormat = 0;
1344 if(wglChoosePixelFormatARB)
1348 float fAttributes[] = {0,0};
1351 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1352 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1353 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1354 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1355 WGL_COLOR_BITS_ARB,24,
1356 WGL_ALPHA_BITS_ARB,8,
1357 WGL_DEPTH_BITS_ARB,16,
1358 WGL_STENCIL_BITS_ARB,0,
1359 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1360 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1361 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1365 //Log("Found wglChoosePixelFormatARB\n");
1367 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1368 if(!valid || !numFormats)
1370 //Log("Can't find 4x multi sampling\n");
1371 iAttributes[19] = 2;
1372 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1373 if(!valid || !numFormats)
1375 // Log("Can't find 2x multi sampling\n");
1376 iAttributes[16] = 0;
1377 iAttributes[17] = 0;
1378 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1379 if(!valid || !numFormats)
1383 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1384 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1385 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1386 WGL_COLOR_BITS_ARB,24,
1387 WGL_ALPHA_BITS_ARB,8,
1388 WGL_DEPTH_BITS_ARB,16,
1391 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1395 if(valid && numFormats)
1397 wglMakeCurrent(null, null);
1401 wglMakeCurrent( null, null );
1402 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1403 if(oglDisplay.hdc && oglDisplay.pBuffer)
1404 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1406 wglDestroyPbufferARB(oglDisplay.pBuffer);
1408 if(!useSingleGLContext)
1409 wglMakeCurrent( null, null );
1412 wglDeleteContext(oglDisplay.glrc);
1414 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1415 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1416 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, null, null, oglDisplay.capabilities.compatible)))
1419 HDC hdc = GetDC(display.window);
1421 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1422 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1424 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1425 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1427 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1429 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1433 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1434 oglDisplay.memDC = CreateCompatibleDC(hdc);
1435 SetMapMode(oglDisplay.memDC, MM_TEXT);
1436 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1437 info->bmiHeader.biPlanes = 1;
1438 info->bmiHeader.biCompression = BI_RGB;
1439 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1440 info->bmiHeader.biWidth = width;
1441 info->bmiHeader.biHeight = height;
1442 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1445 SelectObject(oglDisplay.memDC, newBitmap);
1446 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1449 PIXELFORMATDESCRIPTOR pfd = { 0 };
1450 pfd.nSize = (short)sizeof(pfd);
1452 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1453 pfd.iPixelType = PFD_TYPE_RGBA;
1454 pfd.cColorBits = 32;
1455 //pfd.cAlphaBits = 8;
1456 pfd.cDepthBits = 24;
1457 pfd.iLayerType = PFD_MAIN_PLANE;
1459 oglDisplay.hdc = oglDisplay.memDC;
1461 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1462 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1463 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1465 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1466 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1467 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1472 const int imageSize = width * height * 4;
1474 glGenBuffersARB(2, oglDisplay.imageBuffers);
1476 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1477 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1478 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1479 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1482 oglDisplay.memBitmap = newBitmap;
1483 oglDisplay.stride = width;
1489 ReleaseDC(display.window, hdc);
1491 #elif defined(__unix__) || defined(__APPLE__)
1492 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1497 GLX_DOUBLEBUFFER, True,
1503 GLX_STENCIL_SIZE, 1,
1504 //GLX_DEPTH_SIZE, 24,
1505 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1506 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1512 GLX_PBUFFER_WIDTH, width,
1513 GLX_PBUFFER_HEIGHT, height,
1514 GLX_LARGEST_PBUFFER, False,
1518 // choose a pixel format that meets our minimum requirements
1521 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1524 if(oglDisplay.pixmap)
1526 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1527 oglDisplay.pixmap = None;
1529 if(oglDisplay.shapePixmap)
1531 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1532 oglDisplay.shapePixmap = None;
1535 // Free Shared Memory Pixmap
1536 if(oglDisplay.image)
1538 if(oglDisplay.shminfoShape.shmid != -1)
1540 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1541 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1542 shmdt(oglDisplay.shminfo.shmaddr);
1543 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1545 XDestroyImage(oglDisplay.image);
1546 oglDisplay.image = None;
1548 if(oglDisplay.shapeImage)
1550 if(oglDisplay.shminfoShape.shmid != -1)
1552 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1553 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1554 shmdt(oglDisplay.shminfoShape.shmaddr);
1555 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1557 XDestroyImage(oglDisplay.shapeImage);
1558 oglDisplay.shapeImage = None;
1561 if(oglDisplay.windowPicture)
1562 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1563 if(oglDisplay.pixmapPicture)
1564 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1566 if(oglDisplay.pixmap)
1567 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1569 if(oglDisplay.glContext)
1570 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1571 if(oglDisplay.pBuffer)
1572 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1574 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1575 if(oglDisplay.pBuffer)
1577 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1578 if(oglDisplay.glContext)
1580 glXMakeCurrent(xGlobalDisplay, None, null);
1581 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1583 // Initialize Shared Memory Pixmap
1584 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1585 ZPixmap, null, &oglDisplay.shminfo, width, height);
1586 if(oglDisplay.image)
1588 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1589 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1590 if(oglDisplay.shminfo.shmid != -1)
1592 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1593 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1595 oglDisplay.shminfo.readOnly = False;
1596 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1598 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1599 &oglDisplay.shminfo, width, height, 32);
1601 // Initialize Shared Memory Shape Pixmap
1602 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1603 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1604 if(oglDisplay.shapeImage)
1606 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1607 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1608 if(oglDisplay.shminfoShape.shmid != -1)
1610 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1611 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1613 oglDisplay.shminfoShape.readOnly = False;
1614 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1616 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1617 &oglDisplay.shminfoShape, width, height, 1);
1618 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1621 XRenderPictureAttributes attributes = { 0 };
1622 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1623 #if !defined(__APPLE__)
1624 attributes.repeat = RepeatNormal;
1626 attributes.repeat = 1;
1628 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1629 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1630 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1631 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1634 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1635 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1652 CreateDisplay(display);
1653 #if defined(__WIN32__)
1654 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1655 #elif defined(__unix__) || defined(__APPLE__)
1656 #if defined(__ANDROID__) || defined(__ODROID__)
1659 #elif defined(__EMSCRIPTEN__)
1660 emscripten_webgl_make_context_current(oglSystem.glc);
1662 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1670 SETCAPS(oglDisplay.capabilities);
1672 if(display.alphaBlend && result)
1673 initialDisplaySetup(display, true, false);
1675 if(!result && display.alphaBlend)
1677 printf("Alpha blending windows not supported on this display\n");
1684 glViewport(0,0,width,height);
1685 GLMatrixMode(MatrixMode::projection);
1687 GLOrtho(0,width,height,0,0.0,1.0);
1688 displayWidth = display.width = width;
1689 displayHeight = display.height = height;
1691 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1693 oglDisplay.flipBufW = width;
1694 oglDisplay.flipBufH = height;
1695 #if defined(_GLES) || defined(_GLES2)
1698 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1701 if(oglDisplay.flippingBuffer || !width || !height)
1707 void DisplayPosition(Display display, int x, int y)
1709 OGLDisplay oglDisplay = display.driverData;
1715 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1719 void RestorePalette(Display display)
1723 void StartUpdate(Display display)
1728 OGLDisplay oglDisplay = display.driverData;
1729 glBindVertexArray(oglDisplay.vao);
1732 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1733 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1734 #if ENABLE_GL_SHADERS
1739 void EndUpdate(Display display)
1743 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1747 void Update(Display display, Box updateBox)
1749 #if defined(__WIN32__) || defined(USEPBUFFER)
1750 OGLDisplay oglDisplay = display.driverData;
1753 #if !defined(__ANDROID__)
1758 #if defined(__WIN32__) || defined(USEPBUFFER)
1759 if(display.alphaBlend)
1761 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1762 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1763 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1764 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1765 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1768 #if defined(__WIN32__)
1770 POINT point = { oglDisplay.x, oglDisplay.y};
1771 POINT srcPoint = { 0, 0 };
1772 BLENDFUNCTION blend = { 0 };
1774 size.cx = display.width;
1775 size.cy = display.height;
1776 blend.BlendOp = AC_SRC_OVER;
1777 blend.BlendFlags = 0;
1778 blend.SourceConstantAlpha = 255;
1779 blend.AlphaFormat = AC_SRC_ALPHA;
1782 // Process partial images. Mapping the buffer waits for
1783 // outstanding DMA transfers into the buffer to finish.
1784 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1785 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1787 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1788 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1791 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1792 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1795 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1798 // Unmap the image buffers
1799 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1800 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1802 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1803 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1805 // Bind two different buffer objects and start the glReadPixels
1806 // asynchronously. Each call will return directly after
1807 // starting the DMA transfer.
1808 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1809 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1811 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1812 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1816 #elif defined(__unix__) || defined(__APPLE__)
1817 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1819 XTransform transform =
1822 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1823 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1824 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1827 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1828 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1829 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1830 #if !defined(__APPLE__)
1831 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1833 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1835 XFlush(xGlobalDisplay);
1843 #if defined(__WIN32__)
1844 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1845 SwapBuffers(oglDisplay.hdc);
1846 //ecere::sys::Sleep(0.1);
1847 #elif defined(__unix__) || defined(__APPLE__)
1848 #if defined(__ANDROID__) || defined(__ODROID__)
1850 #elif defined(__EMSCRIPTEN__)
1852 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1858 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1860 if(bitmap.driverData)
1862 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1863 glDeleteTextures(1, &tex);
1864 bitmap.driverData = 0;
1866 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1869 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1871 OGLSystem oglSystem = displaySystem.driverData;
1872 GLCapabilities capabilities = oglSystem.capabilities;
1873 bool result = false;
1875 GLuint glBitmap = 0;
1877 uint w = width, h = height;
1878 if(!capabilities.nonPow2Textures)
1883 w = Min(w, oglSystem.maxTextureSize);
1884 h = Min(h, oglSystem.maxTextureSize);
1886 glGenTextures(1, &glBitmap);
1887 glBindTexture(GL_TEXTURE_2D, glBitmap);
1889 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1891 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1892 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1894 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1895 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1898 if(!capabilities.shaders)
1899 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1902 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1904 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1905 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1909 bitmap.driverData = (void *)(uintptr)glBitmap;
1910 bitmap.driver = displaySystem.driver;
1918 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps, uint cubeMapFace)
1920 bool result = false;
1921 OGLSystem oglSystem = displaySystem.driverData;
1922 GLCapabilities capabilities = oglSystem.capabilities;
1923 Bitmap convBitmap = bitmap;
1924 bool oldStyleCubeMap = (cubeMapFace >> 3) != 0;
1925 int face = (cubeMapFace & 7) - 1;
1929 convBitmap.Copy(bitmap);
1932 // Pre process the bitmap... First make it 32 bit
1933 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1936 uint w = bitmap.width, h = bitmap.height;
1937 GLuint glBitmap = cubeMapFace && face > 0 ? (GLuint)(uintptr)bitmap.driverData : 0;
1938 int target = cubeMapFace ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
1939 if(!capabilities.nonPow2Textures)
1944 w = Min(w, oglSystem.maxTextureSize);
1945 h = Min(h, oglSystem.maxTextureSize);
1949 while(w * 2 < h) w *= 2;
1950 while(h * 2 < w) h *= 2;
1953 // Switch ARGB to RGBA
1954 //if(bitmap.format != pixelFormatRGBA)
1956 int size = convBitmap.stride * convBitmap.height;
1957 for(c = 0; c < size; c++)
1959 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1961 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1962 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1965 // convBitmap.pixelFormat = pixelFormat888;
1967 if(cubeMapFace && oldStyleCubeMap)
1969 if(face == 0 || face == 1 || face == 4 || face == 5)
1971 uint w = convBitmap.width;
1972 uint32 * tmp = new uint [convBitmap.width];
1974 for(y = 0; y < convBitmap.height; y++)
1976 uint32 * pic = (uint32 *)((byte *)convBitmap.picture + y * w * 4);
1977 for(x = 0; x < w; x++)
1978 tmp[x] = pic[w-1-x];
1979 memcpy(pic, tmp, w*4);
1983 else if(face == 2 || face == 3)
1987 tmp.Allocate(null, convBitmap.width, convBitmap.height, 0, convBitmap.pixelFormat, false);
1988 for(y = 0; y < convBitmap.height; y++)
1990 memcpy(tmp.picture + convBitmap.width * 4 * y,
1991 convBitmap.picture + (convBitmap.height-1-y) * convBitmap.width * 4,
1992 convBitmap.width * 4);
1994 memcpy(convBitmap.picture, tmp.picture, convBitmap.sizeBytes);
2001 glGenTextures(1, &glBitmap);
2004 //int error = glGetError();
2008 glBindTexture(target, glBitmap);
2009 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2011 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
2012 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2014 //glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2016 //glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP);
2017 //glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP);
2019 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2020 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2022 #ifndef GL_TEXTURE_WRAP_R
2023 #define GL_TEXTURE_WRAP_R 0x8072
2026 #if !defined(__EMSCRIPTEN__)
2028 glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
2031 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
2032 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
2036 if(!capabilities.shaders)
2037 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2042 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
2047 if(bitmap.width != w || bitmap.height != h)
2049 mipMap = Bitmap { };
2050 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
2052 Surface mipSurface = mipMap.GetSurface(0,0,null);
2053 mipSurface.blend = false;
2054 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
2064 mipMap = convBitmap;
2071 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2072 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);
2073 //printf("Calling glTexImage2D\n");
2074 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2075 //printf("width = %d (Should be %d, %d)\n", width, w, h);
2076 if((error = glGetError()))
2078 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2079 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2083 if(mipMap != convBitmap)
2088 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2089 bitmap.driverData = (void *)(uintptr)glBitmap;
2090 bitmap.driver = displaySystem.driver;
2095 FreeBitmap(displaySystem, bitmap);
2096 else if(oglSystem.loadingFont)
2098 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2099 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2100 oglSystem.loadingFont = false;
2106 void ReleaseSurface(Display display, Surface surface)
2108 glDisable(GL_SCISSOR_TEST);
2109 delete surface.driverData;
2110 surface.driverData = null;
2113 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2118 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2120 bool result = false;
2121 OGLDisplay oglDisplay = display.driverData;
2122 OGLSurface oglSurface = surface.driverData = OGLSurface { };
2125 SETCAPS(oglDisplay.capabilities);
2126 if(displayWidth != display.width || displayHeight != display.height)
2128 displayWidth = display.width;
2129 displayHeight = display.height;
2131 glViewport(0,0,display.width,display.height);
2133 GLOrtho(0,display.width,display.height,0,0.0,1.0);
2136 surface.offset.x = x;
2137 surface.offset.y = y;
2138 surface.unclippedBox = surface.box = clip;
2139 oglSurface.bitmapMult[0] = 1;
2140 oglSurface.bitmapMult[1] = 1;
2141 oglSurface.bitmapMult[2] = 1;
2142 oglSurface.bitmapMult[3] = 1;
2144 glEnable(GL_SCISSOR_TEST);
2147 (display.height) -(y+clip.bottom)-1,
2148 clip.right-clip.left+1,
2149 clip.bottom-clip.top+1);
2155 void Clip(Display display, Surface surface, Box clip)
2162 box.Clip(surface.unclippedBox);
2166 box = surface.box = surface.unclippedBox;
2167 box.left += surface.offset.x;
2168 box.top += surface.offset.y;
2169 box.right+= surface.offset.x;
2170 box.bottom += surface.offset.y;
2173 box.left,display.height - box.bottom - 1,
2174 box.right-box.left+1, box.bottom-box.top+1);
2177 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2179 bool result = false;
2180 OGLDisplay oglDisplay = display.driverData;
2181 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2183 if(oglDisplay.flippingBuffer)
2185 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2188 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2194 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2195 #if ENABLE_GL_LEGACY
2196 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2197 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2198 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2200 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2203 for(row = 0; row<h; row++)
2204 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2211 void SetForeground(Display display, Surface surface, ColorAlpha color)
2213 OGLSurface oglSurface = surface.driverData;
2215 oglSurface.foreground[0] = color.color.r/255.0f;
2216 oglSurface.foreground[1] = color.color.g/255.0f;
2217 oglSurface.foreground[2] = color.color.b/255.0f;
2218 //oglSurface.foreground[3] = 1.0f;
2219 oglSurface.foreground[3] = color.a/255.0f;
2221 //if(!oglSurface.foreground[3])printf("bug");
2224 void SetBackground(Display display, Surface surface, ColorAlpha color)
2226 OGLSurface oglSurface = surface.driverData;
2228 oglSurface.background[0] = color.color.r/255.0f;
2229 oglSurface.background[1] = color.color.g/255.0f;
2230 oglSurface.background[2] = color.color.b/255.0f;
2231 //oglSurface.background[3] = 1.0;
2232 oglSurface.background[3] = color.a/255.0f;
2235 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2237 OGLSurface oglSurface = surface.driverData;
2239 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2240 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2241 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2242 oglSurface.bitmapMult[3] = color.a/255.0f;
2245 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2250 void PutPixel(Display display, Surface surface,int x,int y)
2252 OGLSurface oglSurface = surface.driverData;
2253 GLColor4fv(oglSurface.foreground);
2255 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2256 GLVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2260 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2262 OGLSurface oglSurface = surface.driverData;
2263 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2278 x1 += surface.offset.x;
2279 y1 += surface.offset.y;
2280 x2 += surface.offset.x;
2281 y2 += surface.offset.y;
2283 GLColor4fv(oglSurface.foreground);
2287 GLTexCoord2f(0.5f, 0);
2288 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2289 GLTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2290 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2298 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2299 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2305 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2307 OGLSurface oglSurface = surface.driverData;
2308 x1 += surface.offset.x;
2309 y1 += surface.offset.y;
2310 x2 += surface.offset.x;
2311 y2 += surface.offset.y;
2313 GLColor4fv(oglSurface.foreground);
2318 GLTexCoord2f(0.5f, 0);
2319 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2320 GLTexCoord2f(y2-y1 + 0.5f, 0);
2321 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2323 GLTexCoord2f(0.5f, 0);
2324 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2325 GLTexCoord2f(x2 - x1 + 0.5f, 0);
2326 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2328 GLTexCoord2f(0.5f, 0);
2329 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2330 GLTexCoord2f(y1 - y2 + 0.5f, 0);
2331 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2333 GLTexCoord2f(0.5f, 0);
2334 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2335 GLTexCoord2f(x1 - x2 + 0.5f, 0);
2336 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2340 GLBegin(GL_LINE_LOOP);
2347 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2348 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2349 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2350 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2355 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2357 OGLSurface oglSurface = surface.driverData;
2359 GLColor4fv(oglSurface.background);
2361 GLRecti(x1+surface.offset.x, y1+surface.offset.y,
2362 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2364 GLRectf(x1+surface.offset.x, y1+surface.offset.y,
2365 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2369 void Clear(Display display, Surface surface, ClearType type)
2371 OGLDisplay oglDisplay = display.driverData;
2372 OGLSurface oglSurface = surface.driverData;
2375 if(type != depthBuffer)
2376 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2377 if(type != colorBuffer && !oglDisplay.depthWrite)
2379 glDepthMask((byte)bool::true);
2381 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2382 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2383 if(type != colorBuffer && !oglDisplay.depthWrite)
2385 glDepthMask((byte)bool::false);
2389 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2394 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2396 OGLSurface oglSurface = surface.driverData;
2397 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
2400 if(!oglSurface.writingText)
2402 // glTranslatef(-0.375f, -0.375f, 0.0f);
2403 GLSetupTexturing(true);
2404 GLColor4fv(oglSurface.bitmapMult);
2405 glBindTexture(GL_TEXTURE_2D, tex);
2406 GLBegin(GLIMTKMode::quads);
2408 else if(lastBlitTex != tex)
2412 glBindTexture(GL_TEXTURE_2D, tex);
2413 GLBegin(GLIMTKMode::quads);
2419 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2420 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2421 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2422 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2423 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2424 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2425 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2426 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2431 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2432 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2433 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2434 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2435 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2436 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2437 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2438 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2441 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2442 GLVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2443 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2444 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2445 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2446 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2447 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2448 GLVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2450 if(!oglSurface.writingText)
2453 GLSetupTexturing(false);
2454 //glTranslate(0.375, 0.375, 0.0);
2458 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2460 OGLSurface oglSurface = surface.driverData;
2462 //glTranslate(-0.375, -0.375, 0.0);
2464 GLSetupTexturing(true);
2465 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2467 GLColor4fv(oglSurface.bitmapMult);
2469 GLBegin(GLIMTKMode::quads);
2473 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2474 GLVertex2i(dx+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+surface.offset.y);
2479 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2480 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2482 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2483 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2487 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2488 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2490 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2491 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2493 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2494 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2496 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2497 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2502 GLSetupTexturing(false);
2504 //glTranslate(0.375, 0.375, 0.0);
2507 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2509 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2512 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2514 float s2dw,s2dh,d2sw,d2sh;
2515 //bool flipX = false, flipY = false;
2517 if(Sgn(w) != Sgn(sw))
2523 if(Sgn(h) != Sgn(sh))
2535 //Clip against the edges of the source
2538 dx+=(int)((0-sx) * s2dw);
2539 w-=(int)((0-sx) * s2dw);
2545 dy+=(int)((0-sy) * s2dh);
2546 h-=(int)((0-sy) * s2dh);
2551 if(sx+sw>bitmap.width-1)
2553 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2554 sw-=sx+sw-(bitmap.width-1)-1;
2556 if(sy+sh>(bitmap.height-1))
2558 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2559 sh-=sy+sh-(bitmap.height-1)-1;
2561 //Clip against the edges of the surfaceination
2562 if(dx<surface.box.left)
2565 sx+=(int)((surface.box.left-dx)*d2sw);
2566 sw-=(int)((surface.box.left-dx)*d2sw);
2567 w-=surface.box.left-dx;
2568 dx=surface.box.left;
2570 if(dy<surface.box.top)
2572 sy+=(int)((surface.box.top-dy)*d2sh);
2573 sh-=(int)((surface.box.top-dy)*d2sh);
2574 h-=surface.box.top-dy;
2577 if(dx+w>surface.box.right)
2579 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2580 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2581 w-=dx+w-surface.box.right-1;
2583 if(dy+h>surface.box.bottom)
2585 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2586 h-=dy+h-surface.box.bottom-1;
2588 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2590 dx += surface.offset.x;
2591 dy += surface.offset.y;
2593 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2595 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2596 #if ENABLE_GL_LEGACY
2599 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2600 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2601 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2602 glRasterPos2d(dx,dy);
2603 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2604 glPixelZoom(s2dw, -s2dh);
2605 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2606 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2607 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2608 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2611 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2615 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2617 //Clip against the edges of the source
2630 if(sx+w>bitmap.width-1)
2631 w-=sx+w-(bitmap.width-1)-1;
2632 if(sy+h>bitmap.height-1)
2633 h-=sy+h-(bitmap.height-1)-1;
2634 //Clip against the edges of the surfaceination
2635 if(dx<surface.box.left)
2638 sx+=surface.box.left-dx;
2639 w-=surface.box.left-dx;
2640 dx=surface.box.left;
2642 if(dy<surface.box.top)
2644 sy+=surface.box.top-dy;
2645 h-=surface.box.top-dy;
2648 if(dx+w>surface.box.right)
2650 //if(flip) sx+=dx+w-surface.box.right-1;
2651 w-=dx+w-surface.box.right-1;
2653 if(dy+h>surface.box.bottom)
2654 h-=dy+h-surface.box.bottom-1;
2658 dx += surface.offset.x;
2659 dy += surface.offset.y;
2661 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2663 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2664 #if ENABLE_GL_LEGACY
2667 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2668 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2669 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2670 glRasterPos2d(dx,dy);
2672 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2673 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2674 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2675 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2678 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2682 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2684 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2687 void UnloadFont(DisplaySystem displaySystem, Font font)
2689 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2692 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2695 OGLSystem oglSystem = displaySystem.driverData;
2696 oglSystem.loadingFont = true;
2697 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2701 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2703 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2706 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2710 OGLSurface oglSurface = surface.driverData;
2711 OGLSystem oglSystem = display.displaySystem.driverData;
2712 oglSystem.loadingFont = true;
2714 //glTranslated(-0.375, -0.375, 0.0);
2716 if(surface.textOpacity)
2718 int w = 0, h, adv = 0;
2719 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2721 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2724 oglSurface.writingText = true;
2726 GLSetupTexturing(true);
2729 if(surface.font.outlineSize)
2731 ColorAlpha outlineColor = surface.outlineColor;
2734 GLColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2735 oglSurface.writingOutline = true;
2737 oglSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &fx, y, prevGlyph, rPrevGlyph, null);
2738 if(lastBlitTex) GLEnd();
2739 oglSurface.writingOutline = false;
2741 GLColor4fv(oglSurface.foreground);
2744 oglSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &x, y, prevGlyph, rPrevGlyph, null);
2746 if(lastBlitTex) GLEnd();
2749 oglSurface.writingText = false;
2750 oglSystem.loadingFont = false;
2752 GLSetupTexturing(false);
2754 //glTranslated(0.375, 0.375, 0.0);
2758 void TextFont(Display display, Surface surface, Font font)
2760 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2763 void TextOpacity(Display display, Surface surface, bool opaque)
2765 OGLSurface oglSurface = surface.driverData;
2766 oglSurface.opaqueText = opaque;
2769 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2771 OGLSurface oglSurface = surface.driverData;
2772 OGLSystem oglSystem = display.displaySystem.driverData;
2773 oglSystem.loadingFont = true;
2774 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2775 oglSystem.loadingFont = false;
2778 void DrawingChar(Display display, Surface surface, char character)
2783 void LineStipple(Display display, Surface surface, uint32 stipple)
2787 #if ENABLE_GL_LEGACY
2790 glLineStipple(1, (uint16)stipple);
2791 glEnable(GL_LINE_STIPPLE);
2796 stippleEnabled = true;
2797 glsupLineStipple(1, (uint16)stipple);
2802 #if ENABLE_GL_LEGACY
2804 glDisable(GL_LINE_STIPPLE);
2808 stippleEnabled = false;
2809 GLMatrixMode(GL_TEXTURE);
2811 GLMatrixMode(MatrixMode::projection);
2812 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2817 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2818 void SetRenderState(Display display, RenderState state, uint value)
2820 OGLDisplay oglDisplay = display.driverData;
2824 #ifndef __EMSCRIPTEN__
2826 glEnable(GL_MULTISAMPLE);
2828 glDisable(GL_MULTISAMPLE);
2832 #if ENABLE_GL_LEGACY
2834 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2838 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2841 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2842 oglDisplay.depthWrite = (bool)value;
2846 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2847 #if ENABLE_GL_SHADERS
2849 defaultShader.setFogColor(color[0], color[1], color[2]);
2854 glFogfv(GL_FOG_COLOR, (float *)&color);
2859 #if ENABLE_GL_SHADERS
2861 defaultShader.setFogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2866 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2870 //#if !defined(__EMSCRIPTEN__)
2871 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2876 #if ENABLE_GL_SHADERS
2878 defaultShader.setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2884 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2885 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2892 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2897 #if defined(__WIN32__)
2898 if(wglSwapIntervalEXT)
2899 wglSwapIntervalEXT(value ? 1 : 0);
2906 void SetLight(Display display, int id, Light light)
2908 #if ENABLE_GL_SHADERS
2910 defaultShader.setLight(display, id, light);
2916 if(light != null && !light.flags.off)
2918 Object lightObject = light.lightObject;
2919 float position[4] = { 0, 0, 0, 0 };
2920 float color[4] = { 0, 0, 0, 1 };
2923 glEnable(GL_LIGHT0 + id);
2925 if(!light.multiplier) light.multiplier = 1.0f;
2929 color[0] = light.diffuse.r * light.multiplier;
2930 color[1] = light.diffuse.g * light.multiplier;
2931 color[2] = light.diffuse.b * light.multiplier;
2932 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2934 color[0] = light.ambient.r * light.multiplier;
2935 color[1] = light.ambient.g * light.multiplier;
2936 color[2] = light.ambient.b * light.multiplier;
2937 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2939 color[0] = light.specular.r * light.multiplier;
2940 color[1] = light.specular.g * light.multiplier;
2941 color[2] = light.specular.b * light.multiplier;
2942 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2946 // Positional Lights, including Spot Lights (and omni light with flags.spot not set)
2947 Matrix * mat = &lightObject.matrix;
2948 l = { mat->m[3][0], mat->m[3][1], mat->m[3][2] };
2949 if(display.display3D && display.display3D.camera)
2950 l.Subtract(l, display.display3D.camera.cPosition);
2952 position[0] = (float)l.x, position[1] = (float)l.y, position[2] = (float)l.z, position[3] = 1;
2954 if(light.flags.attenuation)
2956 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2957 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2958 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2962 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, 1);
2963 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, 0);
2964 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, 0);
2967 if((light.flags.spot && light.fallOff < 360) || (lightObject && (light.direction.x || light.direction.y || light.direction.z)))
2969 // Figure out exponent out of the hot spot
2970 #define MAXLIGHT 0.9
2971 float exponent = light.flags.spot ? (float)(log(MAXLIGHT) / log(cos(light.hotSpot / 2))) : 1;
2972 Degrees cutOff = light.flags.spot ? light.fallOff/2 : 90;
2973 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2975 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2976 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)cutOff);
2977 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2981 float d[4] = { 0, 0, 1, 0 };
2982 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, d);
2983 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, 180);
2984 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, 1);
2990 // Display Light Position
2991 glDisable(GL_LIGHTING);
2992 glDisable(GL_DEPTH_TEST);
2996 glVertex3fv(position);
2998 glEnable(GL_DEPTH_TEST);
2999 glEnable(GL_LIGHTING);
3003 if(lightObject.flags.root || !lightObject.parent)
3005 positionVector = light.target.transform.position;
3006 positionVector.Subtract(positionVector, display.camera.cPosition);
3010 positionVector.MultMatrix(light.target.transform.position,
3011 lightObject.light.target.parent.matrix);
3012 positionVector.Subtract(positionVector, display.camera.cPosition);
3015 position[0] = positionVector.x;
3016 position[1] = positionVector.y;
3017 position[2] = positionVector.z;
3019 glDisable(GL_LIGHTING);
3020 glDisable(GL_DEPTH_TEST);
3024 glVertex3fv(position);
3026 glEnable(GL_DEPTH_TEST);
3027 glEnable(GL_LIGHTING);
3033 // Directional Light
3034 Vector3D vector { 0,0,-1 };
3037 mat.RotationQuaternion(light.orientation);
3038 direction.MultMatrix(vector, mat);
3039 l.Normalize(direction);
3040 position[0] = (float)l.x, position[1] = (float)l.y, position[2] = (float)l.z, position[3] = 0;
3042 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3043 if(display.display3D)
3046 Vector3Df v { position[0], position[1], position[2] };
3048 float * lp = display.display3D.light0Pos;
3049 if(display.display3D.camera)
3050 m = display.display3D.camera.viewMatrix;
3057 lp[3] = position[3];
3061 glDisable(GL_LIGHT0 + id);
3066 void SetCamera(Display display, Surface surface, Camera camera)
3068 OGLDisplay oglDisplay = display.driverData;
3070 if(surface && camera)
3072 int left = surface.box.left + surface.offset.x;
3073 int top = surface.box.top + surface.offset.y;
3074 int right = surface.box.right + surface.offset.x;
3075 int bottom = surface.box.bottom + surface.offset.y;
3076 float origX = surface.offset.x + camera.origin.x;
3077 float origY = surface.offset.y + camera.origin.y;
3079 int y = display.height - bottom - 1;
3080 int w = right - left + 1;
3081 int h = bottom - top + 1;
3084 glViewport(x, y, w, h);
3086 GLMatrixMode(MatrixMode::texture);
3087 if(!display.display3D.camera)
3091 // *** Projection Matrix ***
3092 GLMatrixMode(MatrixMode::projection);
3093 if(!display.display3D.camera)
3096 if(display.display3D.collectingHits)
3098 float pickX = display.display3D.pickX + surface.offset.x;
3099 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3103 w / display.display3D.pickWidth, 0, 0, 0,
3104 0, h / display.display3D.pickHeight, 0, 0,
3106 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3107 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3110 GLLoadMatrixd(pickMatrix.array);
3115 (left - origX) * camera.zMin / camera.focalX,
3116 (right - origX) * camera.zMin / camera.focalX,
3117 (bottom - origY) * camera.zMin / camera.focalY,
3118 (top - origY) * camera.zMin / camera.focalY,
3119 camera.zMin, camera.zMax);
3121 glDisable(GL_BLEND);
3123 // *** Z Inverted Identity Matrix ***
3124 GLMatrixMode(MatrixMode::modelView);
3125 if(!display.display3D.camera)
3130 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3132 // *** View Matrix ***
3133 GLMultMatrixd(camera.viewMatrix.array);
3135 #if ENABLE_GL_SHADERS
3138 defaultShader.select();
3139 defaultShader.setCamera(camera);
3146 glEnable(GL_DEPTH_TEST);
3148 GLSetupLighting(true);
3151 glShadeModel(GL_SMOOTH);
3153 glDepthMask((byte)bool::true);
3154 oglDisplay.depthWrite = true;
3156 #ifndef __EMSCRIPTEN__
3157 glEnable(GL_MULTISAMPLE);
3160 else if(surface && display.display3D.camera)
3163 oglDisplay.depthWrite = false;
3164 glViewport(0,0,display.width,display.height);
3166 glDisable(GL_CULL_FACE);
3167 glDisable(GL_DEPTH_TEST);
3169 GLDisableClientState(COLORS);
3170 #if ENABLE_GL_SHADERS
3173 GLDisableClientState(TANGENTS1);
3174 GLDisableClientState(TANGENTS2);
3177 GLDisableClientState(NORMALS);
3180 GLDisableClientState(LIGHTVECTORS);
3183 // *** Restore 2D MODELVIEW Matrix ***
3186 // *** Restore 2D PROJECTION Matrix ***
3187 GLMatrixMode(MatrixMode::projection);
3190 // *** Restore 2D TEXTURE Matrix ***
3191 GLMatrixMode(MatrixMode::texture);
3194 #if ENABLE_GL_SHADERS
3196 defaultShader.select();
3202 disableRemainingTMUs(1);
3203 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
3204 glDisable(GL_TEXTURE_CUBE_MAP);
3206 glDisable(GL_TEXTURE_GEN_STR);
3208 glDisable(GL_TEXTURE_GEN_R);
3209 glDisable(GL_TEXTURE_GEN_S);
3210 glDisable(GL_TEXTURE_GEN_T);
3215 GLSetupTexturing(false);
3216 GLSetupLighting(false);
3219 #if ENABLE_GL_SHADERS
3222 defaultShader.setPerVertexColor(false);
3223 defaultShader.setMaterial(null, 0);
3229 glShadeModel(GL_FLAT);
3232 #if !defined(__EMSCRIPTEN__)
3233 glDisable(GL_MULTISAMPLE);
3238 void ApplyMaterial(Display display, Material material, Mesh mesh)
3240 Shader shader = material.shader ? material.shader : defaultShader;
3241 MaterialFlags flags = material.flags;
3243 static int lastSeparate = 0;
3245 bool normalMapped = false;
3246 OGLMesh oglMesh = mesh ? mesh.data : null;
3249 #if ENABLE_GL_SHADERS
3250 if(glCaps_shaders && shader)
3255 if(flags.doubleSided)
3259 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !flags.singleSideLight);
3261 glDisable(GL_CULL_FACE);
3267 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3269 glEnable(GL_CULL_FACE);
3273 GLSetupFog(!flags.noFog);
3275 #if ENABLE_GL_SHADERS
3277 activeShader.setMaterial(material, mesh.flags);
3283 if(material.bumpMap && mesh.lightVectors)
3285 float color[4] = { 1,1,1,1 };
3286 glActiveTexture(GL_TEXTURE0 + tmu);
3287 glClientActiveTexture(GL_TEXTURE0 + tmu++);
3288 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
3289 glDisable(GL_TEXTURE_CUBE_MAP);
3290 glEnable(GL_TEXTURE_2D);
3292 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3293 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
3294 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
3295 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
3296 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3297 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
3298 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3300 if(0) //((DefaultShaderBits)defaultShader.state).debugging)
3302 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
3303 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
3304 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
3305 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
3306 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
3310 glDisable(GL_TEXTURE_GEN_STR);
3312 glDisable(GL_TEXTURE_GEN_R);
3313 glDisable(GL_TEXTURE_GEN_S);
3314 glDisable(GL_TEXTURE_GEN_T);
3316 glDisable(GL_LIGHTING);
3317 lightingEnabled = false;
3319 GLMatrixMode(GL_TEXTURE);
3321 if(material.uScale && material.vScale)
3322 GLScalef(material.uScale, material.vScale, 1);
3323 GLMatrixMode(MatrixMode::modelView);
3327 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3328 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3332 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3333 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3336 glActiveTexture(GL_TEXTURE0 + tmu);
3337 glClientActiveTexture(GL_TEXTURE0 + tmu);
3339 normalMapped = true;
3341 // Modulate base color
3342 if(material.diffuse.r < 1 || material.diffuse.g < 1 || material.diffuse.b < 1)
3345 glDisable(GL_TEXTURE_CUBE_MAP);
3346 glEnable(GL_TEXTURE_2D);
3347 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
3348 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3349 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
3350 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
3352 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
3353 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
3354 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3355 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3357 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
3358 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT);
3359 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
3360 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
3362 color[0] = material.diffuse.r, color[1] = material.diffuse.g, color[2] = material.diffuse.b, color[3] = 1.0;
3363 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
3364 glActiveTexture(GL_TEXTURE0 + tmu);
3365 glClientActiveTexture(GL_TEXTURE0 + tmu);
3368 // Add ambient light
3370 ColorRGB ambient { material.ambient.r * 0.2f, material.ambient.g * 0.2f, material.ambient.g * 0.2f };
3371 if(ambient.r > 0 || ambient.g > 0 || ambient.b > 0)
3374 glDisable(GL_TEXTURE_CUBE_MAP);
3375 glEnable(GL_TEXTURE_2D);
3376 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
3377 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3378 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
3379 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
3381 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
3382 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
3383 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3384 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3386 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
3387 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT);
3388 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
3389 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
3391 color[0] = ambient.r, color[1] = ambient.g, color[2] = ambient.b, color[3] = 1.0;
3392 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
3393 glActiveTexture(GL_TEXTURE0 + tmu);
3394 glClientActiveTexture(GL_TEXTURE0 + tmu);
3400 GLDisableClientState(LIGHTVECTORS);
3401 if(!lightingEnabled)
3403 glEnable(GL_LIGHTING);
3404 lightingEnabled = true;
3410 if(flags.cubeMap || (material.baseMap && (mesh.texCoords || mesh.flags.texCoords1)))
3412 Bitmap map = material.baseMap;
3413 int diffuseTarget = flags.cubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
3418 glActiveTexture(GL_TEXTURE0 + tmu);
3419 glClientActiveTexture(GL_TEXTURE0 + tmu++);
3420 glEnable(diffuseTarget);
3421 glDisable(flags.cubeMap ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP);
3425 #if ENABLE_GL_SHADERS
3426 if(glCaps_shaders && !flags.cubeMap)
3427 GLSetupTexturing(true);
3430 glBindTexture(diffuseTarget, (GLuint)(uintptr)map.driverData);
3437 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3438 GLEnableClientState(TEXCOORDS);
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);
3480 glDisable(GL_TEXTURE_GEN_STR);
3482 glDisable(GL_TEXTURE_GEN_R);
3483 glDisable(GL_TEXTURE_GEN_S);
3484 glDisable(GL_TEXTURE_GEN_T);
3487 glClientActiveTexture(GL_TEXTURE0);
3492 glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
3493 glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
3497 glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3498 glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3503 GLSetupTexturing(false);
3506 #if ENABLE_GL_FFP && !defined(_GLES)
3509 int separate = material.flags.separateSpecular ? GL_SEPARATE_SPECULAR_COLOR : GL_SINGLE_COLOR;
3510 if(separate != lastSeparate)
3512 GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, separate);
3513 lastSeparate = separate;
3518 if((flags.cubeMap && material.baseMap) ||
3519 (mesh.texCoords && (material.baseMap || material.bumpMap || material.specularMap || material.reflectMap)))
3524 glActiveTexture(GL_TEXTURE0 + tmu - 1);
3525 glClientActiveTexture(GL_TEXTURE0 + tmu - 1);
3528 GLMatrixMode(GL_TEXTURE);
3530 if(material.uScale && material.vScale)
3531 GLScalef(material.uScale, material.vScale, 1);
3532 GLMatrixMode(MatrixMode::modelView);
3536 glActiveTexture(GL_TEXTURE0);
3537 glClientActiveTexture(GL_TEXTURE0);
3545 if(material.envMap && material.refractiveIndex)
3547 float color[4] = { material.opacity, material.opacity, material.opacity, 1.0 };
3548 glActiveTexture(GL_TEXTURE0 + tmu);
3549 glClientActiveTexture(GL_TEXTURE0 + tmu++);
3550 glBindTexture(GL_TEXTURE_CUBE_MAP, (GLuint)(uintptr)material.envMap.driverData);
3551 glEnable(GL_TEXTURE_CUBE_MAP);
3553 glEnable(GL_TEXTURE_GEN_STR);
3554 glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3556 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3557 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3558 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3559 glEnable(GL_TEXTURE_GEN_R);
3560 glEnable(GL_TEXTURE_GEN_S);
3561 glEnable(GL_TEXTURE_GEN_T);
3564 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3567 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
3569 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
3570 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
3572 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
3573 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
3575 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
3576 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
3578 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3579 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3581 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
3582 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
3586 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
3587 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, GL_CONSTANT);
3588 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
3589 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
3592 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
3594 GLMatrixMode(MatrixMode::texture);
3596 double * s = display.display3D.camera.inverseTranspose.array;
3597 Quaternion q = display.display3D.camera.cOrientation;
3602 mat.RotationQuaternion(q);
3613 GLLoadMatrixd(m.array);
3615 GLMatrixMode(MatrixMode::modelView);
3618 if(material.envMap && material.reflectivity)
3620 float color[4] = { 1.0f - material.reflectivity, 1.0f - material.reflectivity, 1.0f - material.reflectivity, 1.0 };
3621 glActiveTexture(GL_TEXTURE0 + tmu);
3622 glClientActiveTexture(GL_TEXTURE0 + tmu++);
3623 glBindTexture(GL_TEXTURE_CUBE_MAP, (GLuint)(uintptr)material.envMap.driverData);
3624 glEnable(GL_TEXTURE_CUBE_MAP);
3626 glEnable(GL_TEXTURE_GEN_STR);
3627 glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3629 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3630 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3631 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
3632 glEnable(GL_TEXTURE_GEN_R);
3633 glEnable(GL_TEXTURE_GEN_S);
3634 glEnable(GL_TEXTURE_GEN_T);
3637 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3640 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
3642 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
3643 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
3645 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
3646 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
3648 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
3649 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
3650 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
3651 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
3652 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
3653 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
3657 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
3658 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, GL_CONSTANT);
3659 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
3660 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
3663 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
3665 GLMatrixMode(MatrixMode::texture);
3667 double * s = display.display3D.camera.inverseTranspose.array;
3675 GLLoadMatrixd(m.array);
3677 GLMatrixMode(MatrixMode::modelView);
3685 disableRemainingTMUs(tmu);
3687 if(mesh.flags.colors)
3689 GLColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3690 glEnable(GL_COLOR_MATERIAL);
3694 glDisable(GL_COLOR_MATERIAL);
3696 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3697 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3700 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3701 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3704 if(material.power > 0.1)
3706 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3707 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3711 float color[4] = { 0,0,0,0 };
3712 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3715 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3716 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3718 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3723 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3725 OGLMesh oglMesh = mesh.data;
3728 OGLSystem oglSystem = displaySystem.driverData;
3729 SETCAPS(oglSystem.capabilities);
3730 if(!mesh.flags.vertices)
3732 oglMesh.vertices.free(glCaps_vertexBuffer);
3733 delete mesh.vertices;
3735 if(!mesh.flags.normals)
3737 oglMesh.normals.free(glCaps_vertexBuffer);
3738 delete mesh.normals;
3740 if(!mesh.flags.tangents)
3742 oglMesh.tangents.free(glCaps_vertexBuffer);
3743 delete mesh.tangents;
3745 if(!mesh.flags.lightVectors)
3747 oglMesh.lightVectors.free(glCaps_vertexBuffer);
3748 delete mesh.lightVectors;
3750 if(!mesh.flags.texCoords1)
3752 oglMesh.texCoords.free(glCaps_vertexBuffer);
3753 delete mesh.texCoords;
3755 if(!mesh.flags.texCoords2)
3757 oglMesh.texCoords2.free(glCaps_vertexBuffer);
3758 // delete mesh.texCoords2;
3760 if(!mesh.flags.colors)
3762 oglMesh.colors.free(glCaps_vertexBuffer);
3773 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3775 bool result = false;
3778 mesh.data = OGLMesh { };
3781 if(mesh.nVertices == nVertices)
3783 // Same number of vertices, adding features (Leaves the other features pointers alone)
3784 if(mesh.flags != flags)
3786 if(!mesh.flags.vertices && flags.vertices)
3788 if(flags.doubleVertices)
3790 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3793 mesh.vertices = new Vector3Df[nVertices];
3795 if(!mesh.flags.normals && flags.normals)
3797 if(flags.doubleNormals)
3799 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3802 mesh.normals = new Vector3Df[nVertices];
3804 if(!mesh.flags.tangents && flags.tangents)
3806 mesh.tangents = new Vector3Df[2*nVertices];
3808 if(!mesh.flags.lightVectors && flags.lightVectors)
3810 mesh.lightVectors = new ColorRGB[nVertices];
3812 if(!mesh.flags.texCoords1 && flags.texCoords1)
3814 mesh.texCoords = new Pointf[nVertices];
3816 if(!mesh.flags.colors && flags.colors)
3818 mesh.colors = new ColorRGBAf[nVertices];
3824 // New number of vertices, reallocate all current and new features
3825 flags |= mesh.flags;
3828 if(flags.doubleVertices)
3830 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3833 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3837 if(flags.doubleNormals)
3839 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3842 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3844 if(flags.texCoords1)
3846 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3850 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3854 mesh.tangents = renew mesh.tangents Vector3Df[2 * nVertices];
3856 if(flags.lightVectors)
3858 mesh.lightVectors = renew mesh.lightVectors ColorRGB[nVertices];
3866 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3868 OGLSystem oglSystem = displaySystem.driverData;
3869 SETCAPS(oglSystem.capabilities);
3870 if(glCaps_vertexBuffer)
3872 OGLMesh oglMesh = mesh.data;
3873 if(!flags) flags = mesh.flags;
3875 oglMesh.vertices.allocate(
3876 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, staticDraw);
3879 oglMesh.normals.allocate(
3880 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, staticDraw);
3882 if(flags.texCoords1)
3883 oglMesh.texCoords.allocate(
3884 mesh.nVertices * sizeof(Pointf), mesh.texCoords, staticDraw);
3887 oglMesh.colors.allocate(
3888 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, staticDraw);
3891 oglMesh.tangents.allocate(mesh.nVertices * 2*sizeof(Vector3Df), mesh.tangents, staticDraw);
3893 if(flags.lightVectors)
3894 oglMesh.lightVectors.allocate(mesh.nVertices * sizeof(ColorRGB), mesh.lightVectors, staticDraw);
3898 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3905 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3907 OGLSystem oglSystem = displaySystem.driverData;
3908 SETCAPS(oglSystem.capabilities);
3911 oglIndices.buffer.free(glCaps_vertexBuffer);
3912 delete oglIndices.indices;
3917 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3919 OGLIndices oglIndices = OGLIndices { };
3922 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3923 oglIndices.nIndices = nIndices;
3928 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3930 OGLSystem oglSystem = displaySystem.driverData;
3931 SETCAPS(oglSystem.capabilities);
3932 if(glCaps_vertexBuffer)
3934 if(!glCaps_intAndDouble && indices32bit)
3936 if(!oglIndices.buffer.buffer)
3937 glGenBuffers(1, &oglIndices.buffer.buffer);
3938 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3939 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3942 uint * pointer = (uint *)oglIndices.indices;
3945 if(nIndices > oglSystem.shortBDSize)
3947 oglSystem.shortBDSize = nIndices;
3948 oglSystem.shortBDBuffer = renew oglSystem.shortBDBuffer uint16[oglSystem.shortBDSize];
3950 b = oglSystem.shortBDBuffer;
3951 for(i = 0; i < nIndices; i++)
3952 b[i] = (uint16)pointer[i];
3954 glBufferData(GL_ELEMENT_ARRAY_BUFFER, nIndices * sizeof(uint16), b, GL_STATIC_DRAW);
3958 oglIndices.buffer.allocate(
3959 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3960 oglIndices.indices, staticDraw);
3964 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3967 return oglIndices.indices;
3970 void SelectMesh(Display display, Mesh mesh)
3972 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3973 #if defined(__WIN32__)
3974 if(glUnlockArraysEXT)
3976 if(!glCaps_vertexBuffer && display.display3D.mesh)
3977 glUnlockArraysEXT();
3981 OGLMesh oglMesh = mesh.data;
3983 // *** Vertex Stream ***
3984 GLEnableClientState(VERTICES);
3985 if(!display.display3D.collectingHits && oglMesh)
3987 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3989 // *** Normals Stream ***
3990 if(mesh.normals || mesh.flags.normals)
3992 GLEnableClientState(NORMALS);
3993 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3996 GLDisableClientState(NORMALS);
3998 #if ENABLE_GL_SHADERS
4001 // *** Tangents Stream ***
4002 if(mesh.tangents || mesh.flags.tangents)
4004 GLEnableClientState(TANGENTS1);
4005 GLEnableClientState(TANGENTS2);
4006 oglMesh.tangents.use(tangent1, 3, GL_FLOAT, sizeof(Vector3Df)*2, oglMesh.tangents.buffer ? null : mesh.tangents);
4007 oglMesh.tangents.use(tangent2, 3, GL_FLOAT, sizeof(Vector3Df)*2, oglMesh.tangents.buffer ? (void *)sizeof(Vector3Df) : mesh.tangents+1);
4011 GLDisableClientState(TANGENTS1);
4012 GLDisableClientState(TANGENTS2);
4017 // *** Texture Coordinates Stream ***
4018 if(mesh.texCoords || mesh.flags.texCoords1)
4020 GLEnableClientState(TEXCOORDS);
4021 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
4024 GLDisableClientState(TEXCOORDS);
4029 // *** Normal Map Aligned Light Vector ***
4030 if(mesh.lightVectors || mesh.flags.lightVectors)
4032 GLEnableClientState(LIGHTVECTORS);
4033 oglMesh.lightVectors.use(lightVector, 3, GL_FLOAT, 0, oglMesh.lightVectors.buffer ? null : mesh.lightVectors);
4036 GLDisableClientState(LIGHTVECTORS);
4040 // *** Color Stream ***
4041 if(mesh.colors || mesh.flags.colors)
4043 GLEnableClientState(COLORS);
4044 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
4047 GLDisableClientState(COLORS);
4051 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
4052 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
4054 GLEnableClientState(NORMALS);
4055 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
4058 GLDisableClientState(NORMALS);
4059 #if ENABLE_GL_SHADERS
4062 if((mesh.tangents || mesh.flags.tangents) && !display.display3D.collectingHits)
4064 GLEnableClientState(TANGENTS1);
4065 GLEnableClientState(TANGENTS2);
4066 noAB.use(tangent1, 3, GL_FLOAT, sizeof(Vector3Df)*2, mesh.tangents);
4067 noAB.use(tangent2, 3, GL_FLOAT, sizeof(Vector3Df)*2, mesh.tangents+1);
4071 GLDisableClientState(TANGENTS1);
4072 GLDisableClientState(TANGENTS2);
4077 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
4079 GLEnableClientState(TEXCOORDS);
4080 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
4083 GLDisableClientState(TEXCOORDS);
4088 if((mesh.lightVectors || mesh.flags.lightVectors) && !display.display3D.collectingHits)
4090 GLEnableClientState(LIGHTVECTORS);
4091 noAB.use(lightVector, 3, GL_FLOAT, sizeof(ColorRGB), mesh.lightVectors);
4094 GLDisableClientState(LIGHTVECTORS);
4098 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
4100 GLEnableClientState(COLORS);
4101 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
4104 GLDisableClientState(COLORS);
4107 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
4109 #if defined(__WIN32__)
4112 if(!glCaps_vertexBuffer)
4113 glLockArraysEXT(0, mesh.nVertices);
4118 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
4120 if(primitive->type.vertexRange)
4123 glDrawArrays(getPrimitiveType(primitive->type.primitiveType), primitive->first, primitive->nVertices);
4127 OGLIndices oglIndices = primitive->data;
4128 GLEAB eab = ((!display.display3D.collectingHits && oglIndices && glCaps_vertexBuffer) ? oglIndices.buffer : noEAB);
4129 if(!glCaps_intAndDouble && !glCaps_vertexBuffer && primitive->type.indices32bit)
4131 uint16 * temp = new uint16[primitive->nIndices];
4132 uint32 * src = (uint32 *)(oglIndices ? oglIndices.indices : primitive->indices);
4134 for(i = 0; i < primitive->nIndices; i++)
4135 temp[i] = (uint16)src[i];
4136 eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices, GL_UNSIGNED_SHORT, temp);
4140 eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices,
4141 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
4142 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
4143 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
4147 void PushMatrix(Display display)
4152 void PopMatrix(Display display, bool setMatrix)
4157 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
4159 Matrix matrix = transMatrix;
4160 Camera camera = useCamera ? display.display3D.camera : null;
4165 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
4170 matrix.m[3][0] - camera.cPosition.x,
4171 matrix.m[3][1] - camera.cPosition.y,
4172 matrix.m[3][2] - camera.cPosition.z);
4184 GLMultMatrixd(matrix.array);
4189 public void UseSingleGLContext(bool useSingle)
4191 useSingleGLContext = useSingle;
4194 default dllexport void *
4195 #if defined(__WIN32__)
4196 __attribute__((stdcall))
4198 IS_GLGetContext(DisplaySystem displaySystem)
4202 #if defined(__WIN32__)
4203 OGLSystem system = displaySystem.driverData;
4205 #elif defined(__ANDROID__) || defined(__ODROID__)
4207 #elif defined(__EMSCRIPTEN__)
4208 OGLSystem system = displaySystem.driverData;
4209 return (void *)system.glc;
4211 OGLSystem system = displaySystem.driverData;
4212 return system.glContext;