3 namespace gfx::drivers;
11 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
13 # include "gl_core_3_3.h"
15 # include "gl_compat_4_4.h"
19 #if defined(__ANDROID__) || defined(__ODROID__)
28 #define GL_BGRA_EXT 0x80E1
32 #undef glEnableClientState
33 #undef glDisableClientState
34 #undef GL_VERTEX_ARRAY
35 #undef GL_NORMAL_ARRAY
36 #undef GL_TEXTURE_COORD_ARRAY
39 #define glEnableClientState glEnableVertexAttribArray
40 #define glDisableClientState glDisableVertexAttribArray
41 #define GL_VERTEX_ARRAY GLBufferContents::vertex
42 #define GL_NORMAL_ARRAY GLBufferContents::normal
43 #define GL_TEXTURE_COORD_ARRAY GLBufferContents::texCoord
44 #define GL_COLOR_ARRAY GLBufferContents::color
48 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
50 #if defined(__unix__) || defined(__APPLE__)
52 #if !defined(__MINGW32__)
53 #define GL_GLEXT_PROTOTYPES
56 #define pointer _pointer
59 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
61 #define property _property
65 #define Window X11Window
66 #define Cursor X11Cursor
68 #define Display X11Display
70 #define KeyCode X11KeyCode
71 #define Picture X11Picture
75 #include <X11/Xutil.h>
77 #include <X11/extensions/XShm.h>
80 #include <X11/extensions/Xrender.h>
81 #include <X11/extensions/shape.h>
99 #if defined(__APPLE__)
100 #include <OpenGl/gl.h>
103 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
105 #if defined(__WIN32__)
106 //#define WIN32_LEAN_AND_MEAN
108 #define _WIN32_WINNT 0x0502
109 #define String Sting_
114 #if defined(__ANDROID__) || defined(__ODROID__)
115 #if defined(__ODROID__) && !defined(ES1_1)
120 #define property _property
123 #define Window X11Window
124 #define Cursor X11Cursor
126 #define Display X11Display
128 #define KeyCode X11KeyCode
129 #define Picture X11Picture
147 #elif defined(__EMSCRIPTEN__)
151 #define property _property
155 //#include <GLES/gl.h>
156 #include <GLES2/gl2.h>
158 #include <emscripten/emscripten.h>
159 #include <emscripten/html5.h>
172 #if defined(__unix__) || defined(__APPLE__)
174 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
180 #define glLoadMatrix glLoadMatrixd
181 #define glMultMatrix glMultMatrixd
182 #define glGetMatrix glGetDoublev
183 #define glTranslate glTranslated
184 #define glScale glScaled
187 #define glVertex3v glVertex3dv
188 #define glNormal3v glNormal3dv
192 //#ifdef VERTEX_FORMAT_DOUBLE
194 #define glLoadMatrix glLoadMatrixd
195 #define glMultMatrix glMultMatrixd
196 #define glGetMatrix glGetDoublev
197 #define glVertex3v glVertex3dv
198 #define glNormal3v glNormal3dv
199 #define glTranslate glTranslated
200 #define glScale glScaled
201 //#define GL_VERTEX_FORMAT GL_DOUBLE
205 #define glLoadMatrix glLoadMatrixf
206 #define glMultMatrix glMultMatrixf
207 #define glGetMatrix glGetFloatv
208 #define glVertex3v glVertex3fv
209 #define glNormal3v glNormal3fv
210 #define glTranslate glTranslatef
211 #define glScale glScalef
212 //#define GL_VERTEX_FORMAT GL_FLOAT
217 #define GL_ARRAY_BUFFER_ARB 0x8892
218 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
219 #define GL_STATIC_DRAW_ARB 0x88E4
220 #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
221 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
223 #define GL_MULTISAMPLE_ARB 0x809D
225 #if defined(__WIN32__)
228 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
229 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
231 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
232 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
234 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
235 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
236 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
237 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
238 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
239 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
240 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
241 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
242 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
243 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = null;
244 static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = null;
248 #if defined(__ANDROID__) || defined(__ODROID__)
249 #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
250 #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
251 #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
252 #define GL_BGRA_EXT 0
255 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
257 #define GL_POLYGON_STIPPLE 0xFFFF
258 #define GL_LINE_STIPPLE 0xFFFF
259 #define GL_LINE 0xFFFF
260 #define GL_FILL 0xFFFF
261 #define GL_ALL_ATTRIB_BITS 0xFFFF
262 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
268 #define GL_QUAD_STRIP 0
269 //#define GL_DOUBLE 0
270 //#define GL_UNSIGNED_INT 0
273 //#define GL_LINE_STIPPLE 0
274 #define GL_UNPACK_ROW_LENGTH 0
275 #define GL_UNPACK_SKIP_PIXELS 0
276 #define GL_UNPACK_SKIP_ROWS 0
278 #define GL_PACK_ROW_LENGTH 0
279 #define GL_PACK_SKIP_ROWS 0
280 #define GL_PACK_SKIP_PIXELS 0
286 #if defined(__ANDROID__) || defined(__ODROID__)
287 #define glBindFramebuffer glBindFramebufferOES
288 #define glBindRenderbuffer glBindRenderbufferOES
289 #define glFramebufferTexture2D glFramebufferTexture2DOES
290 #define glGenFramebuffers glGenFramebuffersOES
291 #define glGenRenderbuffers glGenRenderbuffersOES
292 #define glDeleteFramebuffers glDeleteFramebuffersOES
293 #define glDeleteRenderbuffers glDeleteRenderbuffersOES
296 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
297 #define GL_INT 0x1404
298 #define GL_UNSIGNED_INT 0x1405
299 #define GL_DOUBLE 0x140A
303 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
334 #undef glLoadIdentity
339 #undef glColorMaterial
342 #define glRecti glimtkRecti
343 #define glBegin glimtkBegin
344 #define glTexCoord2i glimtkTexCoord2i
345 #define glVertex2i glimtkVertex2i
346 #define glTexCoord2d glimtkTexCoord2d
347 #define glVertex2d glimtkVertex2d
348 #define glTexCoord2f glimtkTexCoord2f
349 #define glVertex2f glimtkVertex2f
350 #define glEnd glimtkEnd
351 #define glColor3f glimtkColor3f
352 #define glColor4ub glimtkColor4ub
353 #define glColor4fv glimtkColor4fv
354 #define glNormal3fv glimtkNormal3fv
355 #define glNormal3f glimtkNormal3f
356 #define glTexCoord2fv glimtkTexCoord2fv
357 #define glVertex3d glimtkVertex3d
358 #define glVertex3dv glimtkVertex3dv
359 #define glVertex3f glimtkVertex3f
360 #define glVertex3fv glimtkVertex3fv
362 #define glLoadMatrixd glmsLoadMatrixd
363 #define glMultMatrixd glmsMultMatrixd
364 #define glFrustum glmsFrustum
365 #define glOrtho glmsOrtho
366 #define glScaled glmsScaled
367 #define glScalef glmsScaled
368 #define glTranslated glmsTranslated
369 #define glRotated glmsRotated
370 #define glMatrixMode glmsMatrixMode
371 #define glLoadIdentity glmsLoadIdentity
372 #define glPushMatrix glmsPushMatrix
373 #define glPopMatrix glmsPopMatrix
375 #define glLineStipple glesLineStipple
376 #define glColorMaterial glesColorMaterial
377 #define glLightModeli glesLightModeli
381 public void glesColorMaterial(int a, int b)
383 PrintLn("glColorMaterial stub");
386 static GLuint stippleTexture;
387 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
388 static bool stippleEnabled;
391 public void glesLineStipple( int i, unsigned short j )
395 for(x = 0; x < 16; x++)
397 bool v = (j & (1 << x)) != 0;
398 texture[x] = v ? 0xFFFFFFFF : 0;
401 glGenTextures(1, &stippleTexture);
402 glBindTexture(GL_TEXTURE_2D, stippleTexture);
403 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
405 // TOOD: Special shading code for stippling?
406 GLSetupTexturing(true);
407 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
408 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
409 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
410 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
411 glMatrixMode(GL_TEXTURE);
413 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
414 glScaled(i/16.0, 1, 1.0f);
415 glTranslated(0.5, 0.5, 0);
416 glMatrixMode(MatrixMode::projection);
419 public void glesLightModeli( unsigned int pname, int param )
421 #if !defined(SHADERS)
422 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
423 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
427 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
428 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
431 #if defined(__ANDROID__) || defined(__ODROID__)
432 void glFogi( unsigned int pname, int param ) { }
433 void glPolygonMode( unsigned int i, unsigned int j ) { }
436 // *** Picking won't be supported for now ***
437 void glPushName( unsigned int i ) { }
438 void glLoadName( unsigned int i ) { }
441 // Probably replace by regular glBlendFunc ...
442 void glBlendFuncSeparate(int a, int b, int c, int d)
447 // For direct pixel blitting...
448 void glRasterPos2d(double a, double b) { }
449 void glPixelZoom(float a, float b) { }
450 void glDrawPixels(int a, int b, int c, int d, void * e) { }
454 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
455 static int primitiveTypes[RenderPrimitiveType] =
457 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN,
458 #if defined(SHADERS) || defined(ES1_1) || defined(ES2)
459 GL_TRIANGLE_FAN, // NOTE: This will only work for single quads
463 GLIMTKMode::quadStrip,
468 public void GLSetupTexturing(bool enable)
471 shader_texturing(enable);
473 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
477 public void GLSetupFog(bool enable)
482 (enable ? glEnable : glDisable)(GL_FOG);
486 public void GLSetupLighting(bool enable)
489 shader_lighting(enable);
491 (enable ? glEnable : glDisable)(GL_LIGHTING);
495 // Non OpenGL ES friendly stuff
497 #if defined(ES1_1) || defined(ES2)
499 //#undef GL_UNSIGNED_INT
505 #undef GL_POLYGON_STIPPLE
506 #undef GL_LINE_STIPPLE
509 #undef GL_ALL_ATTRIB_BITS
510 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
514 static int displayWidth, displayHeight;
516 #define GL_CLAMP_TO_EDGE 0x812F
518 static bool vboAvailable;
520 static bool useSingleGLContext = false;
521 class OGLDisplay : struct
523 #if defined(__WIN32__)
534 byte * pboMemory1, * pboMemory2;
536 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
537 GLXContext glContext;
540 XShmSegmentInfo shminfo;
542 XShmSegmentInfo shminfoShape;
547 X11Picture windowPicture;
548 X11Picture pixmapPicture;
550 X11Picture shapePicture;
553 ColorAlpha * flippingBuffer;
554 int flipBufH, flipBufW;
560 static void APIENTRY openglCallbackFunction(GLenum source,
565 const GLchar* message,
566 const void* userParam)
568 PrintLn("---------------------opengl-callback-start------------");
569 PrintLn("message: ", message);
573 case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
574 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
575 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
576 case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
577 case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
578 case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
585 case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
586 case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
587 case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
589 PrintLn("---------------------opengl-callback-end--------------");
593 class OGLSystem : struct
598 #if defined(__WIN32__)
599 PIXELFORMATDESCRIPTOR pfd;
604 #elif defined(__EMSCRIPTEN__)
605 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
606 #elif !defined(__ANDROID__) && !defined(__ODROID__)
607 XVisualInfo * visualInfo;
608 GLXContext glContext;
609 GLXDrawable glxDrawable;
613 class OGLSurface : struct
621 float foreground[4], background[4], bitmapMult[4];
624 class OGLMesh : struct
633 class OGLIndices : struct
643 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
645 static void setupDebugging()
647 if(glDebugMessageCallback)
649 GLuint unusedIds = 0;
651 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
653 glDebugMessageCallback(openglCallbackFunction, null);
654 glDebugMessageControl(GL_DONT_CARE,
666 #if defined(__WIN32__)
667 static HGLRC winCreateContext(HDC hdc)
671 if(wglCreateContextAttribsARB)
675 WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
676 WGL_CONTEXT_MINOR_VERSION_ARB, 4,
677 WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | */WGL_CONTEXT_DEBUG_BIT_ARB,
678 WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB /*WGL_CONTEXT_CORE_PROFILE_BIT_ARB*/,
681 result = wglCreateContextAttribsARB(hdc, null, attribs);
687 result = wglCreateContextAttribsARB(hdc, null, attribs);
692 result = wglCreateContext(hdc);
697 class OpenGLDisplayDriver : DisplayDriver
699 class_property(name) = "OpenGL";
701 bool LockSystem(DisplaySystem displaySystem)
703 #if defined(__EMSCRIPTEN__)
704 OGLSystem oglSystem = displaySystem.driverData;
705 emscripten_webgl_make_context_current(oglSystem.glc);
706 #elif !defined(__ANDROID__) && !defined(__ODROID__)
707 OGLSystem oglSystem = displaySystem.driverData;
708 if(useSingleGLContext) return true;
709 #if defined(__WIN32__)
710 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
711 #elif defined(__unix__) || defined(__APPLE__)
712 //if(previous) return true;
713 // printf("Making SYSTEM current\n");
714 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
715 //previous = oglSystem.glContext;
718 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
719 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
723 void UnlockSystem(DisplaySystem displaySystem)
725 if(useSingleGLContext) return;
726 #if defined(__WIN32__)
727 wglMakeCurrent(null, null);
728 #elif defined(__unix__) || defined(__APPLE__)
729 // printf("Making NULL current\n");
730 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
732 glXMakeCurrent(xGlobalDisplay, None, null);
738 bool Lock(Display display)
740 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
741 OGLDisplay oglDisplay = display.driverData;
742 if(useSingleGLContext) return true;
743 #if defined(__WIN32__)
744 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
745 #elif defined(__unix__) || defined(__APPLE__)
746 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
747 // printf(" Making DISPLAY current\n");
748 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
751 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
752 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
756 void Unlock(Display display)
758 if(useSingleGLContext) return;
759 //printf(" Making NULL current\n");
760 //glXMakeCurrent(xGlobalDisplay, None, null);
762 LockSystem(display.displaySystem);
765 void DestroyDisplay(Display display)
767 OGLDisplay oglDisplay = display.driverData;
771 #if defined(__WIN32__)
772 wglMakeCurrent( null, null );
775 wglDeleteContext(oglDisplay.glrc);
777 if(oglDisplay.hdc && oglDisplay.pBuffer)
778 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
780 if(oglDisplay.pBuffer)
781 wglDestroyPbufferARB(oglDisplay.pBuffer);
784 ReleaseDC(display.window, oglDisplay.hdc);
786 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
787 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
789 #elif defined(__unix__) || defined(__APPLE__)
790 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
792 if(oglDisplay.shapePixmap)
793 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
794 if(oglDisplay.pixmap)
795 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
798 if(oglDisplay.shminfoShape.shmid != -1)
800 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
801 if(oglDisplay.shminfo.shmaddr != (void *)-1)
802 shmdt(oglDisplay.shminfo.shmaddr);
803 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
806 if(oglDisplay.shapeImage)
808 if(oglDisplay.shminfoShape.shmid != -1)
810 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
811 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
812 shmdt(oglDisplay.shminfoShape.shmaddr);
813 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
815 XDestroyImage(oglDisplay.shapeImage);
816 oglDisplay.shapeImage = None;
819 glXMakeCurrent(xGlobalDisplay, None, null);
821 if(oglDisplay.glContext)
822 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
825 delete oglDisplay.flippingBuffer;
827 display.driverData = null;
831 void ::CheckExtensions(OGLSystem oglSystem)
833 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
835 printf("extensions: %s\n", extensions);
838 oglSystem.pow2textures = (extensions && strstr(extensions, "GL_ARB_texture_non_power_of_two")) ? false : true;
839 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
842 bool CreateDisplaySystem(DisplaySystem displaySystem)
845 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
848 PrintLn("OpenGL driver's CreateDisplaySystem()");
852 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
854 oglSystem.hdc = GetDC(oglSystem.hwnd);
858 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
859 oglSystem.pfd.nVersion = 1;
860 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
861 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
862 oglSystem.pfd.cColorBits = 24;
863 oglSystem.pfd.cAlphaBits = 8;
864 oglSystem.pfd.cDepthBits = 24;
865 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
867 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
868 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
870 if(oglSystem.pfd.cColorBits > 8)
872 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
873 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
876 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
878 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
879 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
880 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
881 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
882 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
883 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
884 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
885 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
886 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
887 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
888 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
890 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
891 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
893 // eSystem_LoggingMode(LOG_MSGBOX, null);
895 if(wglChoosePixelFormatARB)
900 float fAttributes[] = {0,0};
903 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
904 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
905 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
906 WGL_COLOR_BITS_ARB,24,
907 WGL_ALPHA_BITS_ARB,8,
908 WGL_DEPTH_BITS_ARB,16,
909 WGL_STENCIL_BITS_ARB,0,
910 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
911 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
912 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
916 //Log("Found wglChoosePixelFormatARB\n");
918 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
919 if(!valid || !numFormats)
921 //Log("Can't find 4x multi sampling\n");
923 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
924 if(!valid || !numFormats)
926 // Log("Can't find 2x multi sampling\n");
929 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
932 if(valid && numFormats)
934 oglSystem.format = pixelFormat;
935 wglMakeCurrent(null, null);
936 wglDeleteContext(oglSystem.glrc);
938 // *** DescribePixelFormat does not support WGL pixel formats! ***
939 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
940 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
941 //Log("Successfully set pixel format\n");
944 PrintLn("winCreateContext()");
946 oglSystem.glrc = winCreateContext(oglSystem.hdc);
948 PrintLn("wglMakeCurrent()");
950 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
954 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
958 wglMakeCurrent(null, null);
960 //eSystem_DumpErrors(true);
964 #elif defined(__unix__) || defined(__APPLE__)
966 #if defined(__ANDROID__) || defined(__ODROID__)
967 #if defined(__ANDROID__)
968 egl_init_display(guiApp.desktop.windowHandle);
969 #elif defined(__ODROID__)
970 egl_init_display((uint)displaySystem.window);
971 CheckExtensions(oglSystem);
974 // TODO: Clean this up? Needed here?
975 glEnableClientState(GL_VERTEX_ARRAY);
977 // Initialize GL state.
978 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
979 glEnable(GL_CULL_FACE);
980 glShadeModel(GL_SMOOTH);
981 glDisable(GL_DEPTH_TEST);
983 glDisable(GL_CULL_FACE);
984 glDisable(GL_DEPTH_TEST);
986 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
989 matrixStack[0][0].Identity();
990 matrixStack[1][0].Identity();
991 matrixStack[2][0].Identity();
993 glmsMatrixMode(GL_MODELVIEW);
994 glScaled(1.0, 1.0, -1.0);
995 glmsMatrixMode(GL_PROJECTION);
996 glShadeModel(GL_FLAT);
998 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
999 glFogi(GL_FOG_MODE, GL_EXP);
1000 glFogf(GL_FOG_DENSITY, 0);
1001 glEnable(GL_NORMALIZE);
1002 glDepthFunc(GL_LESS);
1004 glDisable(GL_MULTISAMPLE_ARB);
1006 glViewport(0,0,eglWidth,eglHeight);
1008 glOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
1010 glabCurArrayBuffer = 0;
1011 glabCurElementBuffer = 0;
1014 #elif defined(__EMSCRIPTEN__)
1016 EmscriptenWebGLContextAttributes attribs = { 0 };
1018 attribs.antialias = 1;
1025 EM_BOOL premultipliedAlpha;
1026 EM_BOOL preserveDrawingBuffer;
1027 EM_BOOL preferLowPowerToHighPerformance;
1028 EM_BOOL failIfMajorPerformanceCaveat;
1031 EM_BOOL enableExtensionsByDefault;
1034 emscripten_webgl_init_context_attributes(&attribs);
1035 oglSystem.pow2textures = true;
1036 oglSystem.maxTextureSize = 16384;
1037 oglSystem.glc = emscripten_webgl_create_context("canvas", &attribs);
1038 if(emscripten_webgl_make_context_current(oglSystem.glc) == EMSCRIPTEN_RESULT_SUCCESS)
1041 /*glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1042 glEnable(GL_BLEND);*/
1046 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1047 XSetWindowAttributes attr;
1052 #ifndef ECERE_MINIGLX
1053 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1056 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1060 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
1061 attr.background_pixel = 0;
1062 attr.border_pixel = 0;
1063 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1064 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1065 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1067 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1068 oglSystem.visualInfo->visual, mask, &attr );
1070 if(oglSystem.visualInfo)
1072 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1073 if(oglSystem.glContext)
1075 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1077 // CheckExtensions(oglSystem);
1078 glXMakeCurrent(xGlobalDisplay, None, null);
1085 displaySystem.flags.alpha = true;
1086 displaySystem.flags.flipping = true;
1087 displaySystem.pixelFormat = pixelFormat888;
1091 void DestroyDisplaySystem(DisplaySystem displaySystem)
1093 OGLSystem oglSystem = displaySystem.driverData;
1096 glDeleteTextures(1, &stippleTexture);
1102 #if defined(__WIN32__)
1103 wglMakeCurrent( null, null );
1106 wglDeleteContext(oglSystem.glrc);
1109 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1110 DestroyWindow(oglSystem.hwnd);
1112 #elif defined(__unix__) || defined(__APPLE__)
1113 #if defined(__ANDROID__) || defined(__ODROID__)
1115 #elif defined(__EMSCRIPTEN__)
1116 emscripten_webgl_destroy_context(oglSystem.glc);
1118 if(oglSystem.visualInfo)
1120 #ifdef ECERE_MINIGLX
1121 __miniglx_XFree(oglSystem.visualInfo);
1123 XFree(oglSystem.visualInfo);
1127 if(oglSystem.glxDrawable)
1129 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1130 oglSystem.glxDrawable = 0;
1137 static bool ::initialDisplaySetup(Display display)
1141 loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1143 glEnableClientState(GL_VERTEX_ARRAY);
1145 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1146 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1148 #if defined(__WIN32__)
1149 if(glBlendFuncSeparate)
1150 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1152 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1154 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1158 glMatrixMode(MatrixMode::modelView);
1159 glLoadIdentity(); // For setting up GLES stack
1160 glScaled(1.0, 1.0, -1.0);
1161 // glTranslatef(0.375f, 0.375f, 0.0f);
1162 // glTranslatef(-0.625f, -0.625f, 0.0f);
1163 glMatrixMode(MatrixMode::projection);
1164 #if !defined(EM_MODE) && !defined(SHADERS)
1165 glShadeModel(GL_FLAT);
1167 // #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1169 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1171 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1172 glFogi(GL_FOG_MODE, GL_EXP);
1173 glFogf(GL_FOG_DENSITY, 0);
1174 glEnable(GL_NORMALIZE);
1176 glDepthFunc(GL_LESS);
1178 glDisable(GL_MULTISAMPLE_ARB);
1179 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1180 display.ambient = Color { 50,50,50 };
1185 bool CreateDisplay(Display display)
1187 bool result = false;
1188 OGLDisplay oglDisplay = display.driverData;
1189 #if !defined(__ANDROID__) && !defined(__ODROID__)
1190 OGLSystem oglSystem = display.displaySystem.driverData;
1194 oglDisplay = display.driverData = OGLDisplay { };
1195 //printf("Inside CreateDisplay\n");
1197 #if defined(__WIN32__) || defined(USEPBUFFER)
1198 if(!display.alphaBlend)
1201 #if defined(__WIN32__)
1202 oglDisplay.hdc = GetDC(display.window);
1203 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1204 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1206 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1207 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1211 ReleaseDC(display.window, oglDisplay.hdc);
1212 #elif defined(__unix__) || defined(__APPLE__)
1213 # if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1216 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1218 #if defined(__APPLE__)
1219 XVisualInfo template = { 0 };
1220 XWindowAttributes winAttr;
1222 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1223 template.visualid = XVisualIDFromVisual(winAttr.visual);
1224 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1226 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1227 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1228 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1229 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1231 // visualInfo = oglSystem.visualInfo;
1236 //printf("visualInfo is not null\n");
1237 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1238 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1239 //XFree(visualInfo);
1242 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1243 if(oglDisplay.glContext)
1245 //printf("CreateDisplay Got a Context\n");
1246 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1252 #if defined(__WIN32__) || defined(USEPBUFFER)
1256 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1261 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1264 PrintLn("Calling ogl_LoadFunctions() in CreateDisplay()");
1266 if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
1267 PrintLn("ogl_LoadFunctions() failed!");
1270 PrintLn("CheckExtensions()");
1272 CheckExtensions(oglSystem);
1273 vboAvailable = glBindBuffer != null;
1276 PrintLn("vboAvailable is: ", vboAvailable);
1285 #if defined(__EMSCRIPTEN__)
1286 emscripten_webgl_make_context_current(oglSystem.glc);
1289 initialDisplaySetup(display);
1292 if(!useSingleGLContext)
1294 #if defined(__WIN32__)
1295 wglMakeCurrent(null, null);
1296 #elif defined(__unix__) || defined(__APPLE__)
1297 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1300 glXMakeCurrent(xGlobalDisplay, None, null);
1306 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1314 bool DisplaySize(Display display, int width, int height)
1316 OGLDisplay oglDisplay = display.driverData;
1318 bool result = false;
1320 //printf("Inside DisplaySize\n");
1321 #if defined(__WIN32__) || defined(USEPBUFFER)
1322 OGLSystem oglSystem = display.displaySystem.driverData;
1323 if(display.alphaBlend)
1325 #if defined(__WIN32__)
1326 const int attributes[]=
1328 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1329 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1331 int pixelFormat = 0;
1332 if(wglChoosePixelFormatARB)
1336 float fAttributes[] = {0,0};
1339 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1340 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1341 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1342 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1343 WGL_COLOR_BITS_ARB,24,
1344 WGL_ALPHA_BITS_ARB,8,
1345 WGL_DEPTH_BITS_ARB,16,
1346 WGL_STENCIL_BITS_ARB,0,
1347 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1348 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1349 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1353 //Log("Found wglChoosePixelFormatARB\n");
1355 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1356 if(!valid || !numFormats)
1358 //Log("Can't find 4x multi sampling\n");
1359 iAttributes[19] = 2;
1360 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1361 if(!valid || !numFormats)
1363 // Log("Can't find 2x multi sampling\n");
1364 iAttributes[16] = 0;
1365 iAttributes[17] = 0;
1366 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1367 if(!valid || !numFormats)
1371 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1372 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1373 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1374 WGL_COLOR_BITS_ARB,24,
1375 WGL_ALPHA_BITS_ARB,8,
1376 WGL_DEPTH_BITS_ARB,16,
1379 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1383 if(valid && numFormats)
1385 wglMakeCurrent(null, null);
1389 wglMakeCurrent( null, null );
1390 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1391 if(oglDisplay.hdc && oglDisplay.pBuffer)
1392 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1394 wglDestroyPbufferARB(oglDisplay.pBuffer);
1396 if(!useSingleGLContext)
1397 wglMakeCurrent( null, null );
1400 wglDeleteContext(oglDisplay.glrc);
1402 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1403 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1404 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1407 HDC hdc = GetDC(display.window);
1409 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1410 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1412 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1413 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1415 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1417 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1421 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1422 oglDisplay.memDC = CreateCompatibleDC(hdc);
1423 SetMapMode(oglDisplay.memDC, MM_TEXT);
1424 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1425 info->bmiHeader.biPlanes = 1;
1426 info->bmiHeader.biCompression = BI_RGB;
1427 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1428 info->bmiHeader.biWidth = width;
1429 info->bmiHeader.biHeight = height;
1430 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1433 SelectObject(oglDisplay.memDC, newBitmap);
1434 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1437 PIXELFORMATDESCRIPTOR pfd = { 0 };
1438 pfd.nSize = (short)sizeof(pfd);
1440 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1441 pfd.iPixelType = PFD_TYPE_RGBA;
1442 pfd.cColorBits = 32;
1443 //pfd.cAlphaBits = 8;
1444 pfd.cDepthBits = 24;
1445 pfd.iLayerType = PFD_MAIN_PLANE;
1447 oglDisplay.hdc = oglDisplay.memDC;
1449 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1450 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1451 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1453 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1454 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1455 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1460 const int imageSize = width * height * 4;
1462 glGenBuffersARB(2, oglDisplay.imageBuffers);
1464 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1465 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1466 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1467 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1470 oglDisplay.memBitmap = newBitmap;
1471 oglDisplay.stride = width;
1477 ReleaseDC(display.window, hdc);
1479 #elif defined(__unix__) || defined(__APPLE__)
1480 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1485 GLX_DOUBLEBUFFER, True,
1491 GLX_STENCIL_SIZE, 1,
1492 //GLX_DEPTH_SIZE, 24,
1493 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1494 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1500 GLX_PBUFFER_WIDTH, width,
1501 GLX_PBUFFER_HEIGHT, height,
1502 GLX_LARGEST_PBUFFER, False,
1506 // choose a pixel format that meets our minimum requirements
1509 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1512 if(oglDisplay.pixmap)
1514 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1515 oglDisplay.pixmap = None;
1517 if(oglDisplay.shapePixmap)
1519 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1520 oglDisplay.shapePixmap = None;
1523 // Free Shared Memory Pixmap
1524 if(oglDisplay.image)
1526 if(oglDisplay.shminfoShape.shmid != -1)
1528 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1529 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1530 shmdt(oglDisplay.shminfo.shmaddr);
1531 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1533 XDestroyImage(oglDisplay.image);
1534 oglDisplay.image = None;
1536 if(oglDisplay.shapeImage)
1538 if(oglDisplay.shminfoShape.shmid != -1)
1540 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1541 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1542 shmdt(oglDisplay.shminfoShape.shmaddr);
1543 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1545 XDestroyImage(oglDisplay.shapeImage);
1546 oglDisplay.shapeImage = None;
1549 if(oglDisplay.windowPicture)
1550 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1551 if(oglDisplay.pixmapPicture)
1552 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1554 if(oglDisplay.pixmap)
1555 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1557 if(oglDisplay.glContext)
1558 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1559 if(oglDisplay.pBuffer)
1560 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1562 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1563 if(oglDisplay.pBuffer)
1565 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1566 if(oglDisplay.glContext)
1568 glXMakeCurrent(xGlobalDisplay, None, null);
1569 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1571 // Initialize Shared Memory Pixmap
1572 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1573 ZPixmap, null, &oglDisplay.shminfo, width, height);
1574 if(oglDisplay.image)
1576 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1577 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1578 if(oglDisplay.shminfo.shmid != -1)
1580 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1581 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1583 oglDisplay.shminfo.readOnly = False;
1584 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1586 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1587 &oglDisplay.shminfo, width, height, 32);
1589 // Initialize Shared Memory Shape Pixmap
1590 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1591 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1592 if(oglDisplay.shapeImage)
1594 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1595 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1596 if(oglDisplay.shminfoShape.shmid != -1)
1598 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1599 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1601 oglDisplay.shminfoShape.readOnly = False;
1602 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1604 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1605 &oglDisplay.shminfoShape, width, height, 1);
1606 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1609 XRenderPictureAttributes attributes = { 0 };
1610 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1611 #if !defined(__APPLE__)
1612 attributes.repeat = RepeatNormal;
1614 attributes.repeat = 1;
1616 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1617 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1618 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1619 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1622 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1623 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1640 CreateDisplay(display);
1641 #if defined(__WIN32__)
1642 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1643 #elif defined(__unix__) || defined(__APPLE__)
1644 #if defined(__ANDROID__) || defined(__ODROID__)
1647 #elif defined(__EMSCRIPTEN__)
1648 emscripten_webgl_make_context_current(oglSystem.glc);
1650 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1658 if(display.alphaBlend && result)
1659 initialDisplaySetup(display);
1661 if(!result && display.alphaBlend)
1663 printf("Alpha blending windows not supported on this display\n");
1670 glViewport(0,0,width,height);
1671 glMatrixMode(MatrixMode::projection);
1673 glOrtho(0,width,height,0,0.0,1.0);
1674 displayWidth = display.width = width;
1675 displayHeight = display.height = height;
1677 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1679 oglDisplay.flipBufW = width;
1680 oglDisplay.flipBufH = height;
1681 #if defined(ES1_1) || defined(ES2)
1684 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1687 if(oglDisplay.flippingBuffer || !width || !height)
1693 void DisplayPosition(Display display, int x, int y)
1695 OGLDisplay oglDisplay = display.driverData;
1701 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1705 void RestorePalette(Display display)
1709 void StartUpdate(Display display)
1713 void EndUpdate(Display display)
1717 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1721 void Update(Display display, Box updateBox)
1723 #if defined(__WIN32__) || defined(USEPBUFFER)
1724 OGLDisplay oglDisplay = display.driverData;
1726 //Logf("DisplayScreen\n");
1728 #if !defined(__ANDROID__)
1733 #if defined(__WIN32__) || defined(USEPBUFFER)
1734 if(display.alphaBlend)
1736 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1737 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1738 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1739 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1740 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1743 #if defined(__WIN32__)
1745 POINT point = { oglDisplay.x, oglDisplay.y};
1746 POINT srcPoint = { 0, 0 };
1747 BLENDFUNCTION blend = { 0 };
1749 size.cx = display.width;
1750 size.cy = display.height;
1751 blend.BlendOp = AC_SRC_OVER;
1752 blend.BlendFlags = 0;
1753 blend.SourceConstantAlpha = 255;
1754 blend.AlphaFormat = AC_SRC_ALPHA;
1757 // Process partial images. Mapping the buffer waits for
1758 // outstanding DMA transfers into the buffer to finish.
1759 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1760 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1762 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1763 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1766 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1767 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1770 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1773 // Unmap the image buffers
1774 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1775 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1777 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1778 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1780 // Bind two different buffer objects and start the glReadPixels
1781 // asynchronously. Each call will return directly after
1782 // starting the DMA transfer.
1783 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1784 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1786 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1787 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1791 #elif defined(__unix__) || defined(__APPLE__)
1792 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1794 XTransform transform =
1797 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1798 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1799 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1802 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1803 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1804 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1805 #if !defined(__APPLE__)
1806 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1808 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1810 XFlush(xGlobalDisplay);
1818 #if defined(__WIN32__)
1819 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1820 SwapBuffers(oglDisplay.hdc);
1821 //ecere::sys::Sleep(0.1);
1822 #elif defined(__unix__) || defined(__APPLE__)
1823 #if defined(__ANDROID__) || defined(__ODROID__)
1825 #elif defined(__EMSCRIPTEN__)
1827 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1831 //Logf("Out of DisplayScreen\n");
1834 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1836 if(bitmap.driverData)
1838 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1839 glDeleteTextures(1, &tex);
1840 bitmap.driverData = 0;
1842 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1845 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1847 OGLSystem oglSystem = displaySystem.driverData;
1848 bool result = false;
1850 GLuint glBitmap = 0;
1852 uint w = width, h = height;
1853 if(oglSystem.pow2textures)
1858 w = Min(w, oglSystem.maxTextureSize);
1859 h = Min(h, oglSystem.maxTextureSize);
1861 glGenTextures(1, &glBitmap);
1862 glBindTexture(GL_TEXTURE_2D, glBitmap);
1864 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1866 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1867 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1869 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1870 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1872 #if !defined(SHADERS)
1873 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1876 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1878 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1879 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1883 bitmap.driverData = (void *)(uintptr)glBitmap;
1884 bitmap.driver = displaySystem.driver;
1892 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1894 bool result = false;
1895 OGLSystem oglSystem = displaySystem.driverData;
1896 Bitmap convBitmap = bitmap;
1900 convBitmap.Copy(bitmap);
1903 // Pre process the bitmap... First make it 32 bit
1904 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1907 uint w = bitmap.width, h = bitmap.height;
1908 GLuint glBitmap = 0;
1909 if(oglSystem.pow2textures)
1914 w = Min(w, oglSystem.maxTextureSize);
1915 h = Min(h, oglSystem.maxTextureSize);
1919 while(w * 2 < h) w *= 2;
1920 while(h * 2 < w) h *= 2;
1923 // Switch ARGB to RGBA
1924 //if(bitmap.format != pixelFormatRGBA)
1926 for(c=0; c<bitmap.size; c++)
1928 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1930 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1931 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1934 // convBitmap.pixelFormat = pixelFormat888;
1937 glGenTextures(1, &glBitmap);
1940 //int error = glGetError();
1944 glBindTexture(GL_TEXTURE_2D, glBitmap);
1945 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1947 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1948 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1950 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1952 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1953 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1955 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1956 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1957 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1958 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1961 #if !defined(SHADERS)
1962 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1967 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1972 if(bitmap.width != w || bitmap.height != h)
1974 mipMap = Bitmap { };
1975 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1977 Surface mipSurface = mipMap.GetSurface(0,0,null);
1978 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1988 mipMap = convBitmap;
1995 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1996 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1997 //printf("Calling glTexImage2D\n");
1998 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
1999 //printf("width = %d (Should be %d, %d)\n", width, w, h);
2000 if((error = glGetError()))
2002 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2003 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2007 if(mipMap != convBitmap)
2012 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2013 bitmap.driverData = (void *)(uintptr)glBitmap;
2014 bitmap.driver = displaySystem.driver;
2019 FreeBitmap(displaySystem, bitmap);
2020 else if(oglSystem.loadingFont)
2022 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2023 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2024 oglSystem.loadingFont = false;
2030 void ReleaseSurface(Display display, Surface surface)
2032 glDisable(GL_SCISSOR_TEST);
2033 delete surface.driverData;
2034 surface.driverData = null;
2037 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2042 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2044 bool result = false;
2045 OGLSurface oglSurface = surface.driverData = OGLSurface { };
2047 //Logf("GetSurface\n");
2051 if(displayWidth != display.width || displayHeight != display.height)
2053 displayWidth = display.width;
2054 displayHeight = display.height;
2056 glViewport(0,0,display.width,display.height);
2058 glOrtho(0,display.width,display.height,0,0.0,1.0);
2061 surface.offset.x = x;
2062 surface.offset.y = y;
2063 surface.unclippedBox = surface.box = clip;
2064 oglSurface.bitmapMult[0] = 1;
2065 oglSurface.bitmapMult[1] = 1;
2066 oglSurface.bitmapMult[2] = 1;
2067 oglSurface.bitmapMult[3] = 1;
2069 glEnable(GL_SCISSOR_TEST);
2072 (display.height) -(y+clip.bottom)-1,
2073 clip.right-clip.left+1,
2074 clip.bottom-clip.top+1);
2080 void Clip(Display display, Surface surface, Box clip)
2089 box.Clip(surface.unclippedBox);
2093 box = surface.box = surface.unclippedBox;
2094 box.left += surface.offset.x;
2095 box.top += surface.offset.y;
2096 box.right+= surface.offset.x;
2097 box.bottom += surface.offset.y;
2100 box.left,display.height - box.bottom - 1,
2101 box.right-box.left+1, box.bottom-box.top+1);
2104 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2106 bool result = false;
2107 OGLDisplay oglDisplay = display.driverData;
2108 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2110 if(oglDisplay.flippingBuffer)
2112 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2115 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2121 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2122 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2123 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2124 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2125 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2128 for(row = 0; row<h; row++)
2129 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2136 void SetForeground(Display display, Surface surface, ColorAlpha color)
2138 OGLSurface oglSurface = surface.driverData;
2140 //Logf("SetForeground\n");
2142 oglSurface.foreground[0] = color.color.r/255.0f;
2143 oglSurface.foreground[1] = color.color.g/255.0f;
2144 oglSurface.foreground[2] = color.color.b/255.0f;
2145 //oglSurface.foreground[3] = 1.0f;
2146 oglSurface.foreground[3] = color.a/255.0f;
2148 //if(!oglSurface.foreground[3])printf("bug");
2151 void SetBackground(Display display, Surface surface, ColorAlpha color)
2153 OGLSurface oglSurface = surface.driverData;
2155 //Logf("SetBackground\n");
2157 oglSurface.background[0] = color.color.r/255.0f;
2158 oglSurface.background[1] = color.color.g/255.0f;
2159 oglSurface.background[2] = color.color.b/255.0f;
2160 //oglSurface.background[3] = 1.0;
2161 oglSurface.background[3] = color.a/255.0f;
2164 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2166 OGLSurface oglSurface = surface.driverData;
2168 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2169 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2170 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2171 oglSurface.bitmapMult[3] = color.a/255.0f;
2174 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2179 void PutPixel(Display display, Surface surface,int x,int y)
2181 OGLSurface oglSurface = surface.driverData;
2183 //Logf("PutPixel\n");
2185 glColor4fv(oglSurface.foreground);
2187 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2188 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2193 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2195 OGLSurface oglSurface = surface.driverData;
2196 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2211 x1 += surface.offset.x;
2212 y1 += surface.offset.y;
2213 x2 += surface.offset.x;
2214 y2 += surface.offset.y;
2218 glColor4fv(oglSurface.foreground);
2220 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2223 glTexCoord2f(0.5f, 0);
2224 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2225 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2226 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2235 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2236 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2242 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2244 OGLSurface oglSurface = surface.driverData;
2245 x1 += surface.offset.x;
2246 y1 += surface.offset.y;
2247 x2 += surface.offset.x;
2248 y2 += surface.offset.y;
2250 //Logf("Rectangle\n");
2252 glColor4fv(oglSurface.foreground);
2253 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2258 glTexCoord2f(0.5f, 0);
2259 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2260 glTexCoord2f(y2-y1 + 0.5f, 0);
2261 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2263 glTexCoord2f(0.5f, 0);
2264 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2265 glTexCoord2f(x2 - x1 + 0.5f, 0);
2266 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2268 glTexCoord2f(0.5f, 0);
2269 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2270 glTexCoord2f(y1 - y2 + 0.5f, 0);
2271 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2273 glTexCoord2f(0.5f, 0);
2274 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2275 glTexCoord2f(x1 - x2 + 0.5f, 0);
2276 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2281 glBegin(GL_LINE_LOOP);
2288 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2289 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2290 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2291 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2296 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2298 OGLSurface oglSurface = surface.driverData;
2301 glColor4fv(oglSurface.background);
2303 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2304 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2306 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2307 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2311 void Clear(Display display, Surface surface, ClearType type)
2313 OGLDisplay oglDisplay = display.driverData;
2314 OGLSurface oglSurface = surface.driverData;
2317 if(type != depthBuffer)
2318 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2319 if(type != colorBuffer && !oglDisplay.depthWrite)
2321 glDepthMask((byte)bool::true);
2323 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2324 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2325 if(type != colorBuffer && !oglDisplay.depthWrite)
2327 glDepthMask((byte)bool::false);
2331 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2336 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2338 OGLSurface oglSurface = surface.driverData;
2340 if(!oglSurface.writingText)
2342 // glTranslatef(-0.375f, -0.375f, 0.0f);
2343 GLSetupTexturing(true);
2344 glColor4fv(oglSurface.bitmapMult);
2346 else if(oglSurface.xOffset)
2347 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2349 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2350 glBegin(GLIMTKMode::quads);
2354 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2355 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2356 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2357 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2358 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2359 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2360 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2361 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2366 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2367 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2368 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2369 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2370 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2371 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2372 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2373 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2376 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2377 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2378 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2379 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2380 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2381 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2382 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2383 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2387 if(!oglSurface.writingText)
2389 GLSetupTexturing(false);
2391 //glTranslate(0.375, 0.375, 0.0);
2393 else if(oglSurface.xOffset)
2394 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2397 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2399 OGLSurface oglSurface = surface.driverData;
2401 //glTranslate(-0.375, -0.375, 0.0);
2403 GLSetupTexturing(true);
2404 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2406 glColor4fv(oglSurface.bitmapMult);
2408 glBegin(GLIMTKMode::quads);
2412 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2413 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2415 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2416 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2418 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2419 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2421 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2422 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2426 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2427 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2429 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2430 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2432 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2433 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2435 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2436 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2441 GLSetupTexturing(false);
2443 //glTranslate(0.375, 0.375, 0.0);
2446 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2448 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2451 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2453 float s2dw,s2dh,d2sw,d2sh;
2454 //bool flipX = false, flipY = false;
2456 //Logf("StretchDI\n");
2458 if(Sgn(w) != Sgn(sw))
2464 if(Sgn(h) != Sgn(sh))
2476 //Clip against the edges of the source
2479 dx+=(int)((0-sx) * s2dw);
2480 w-=(int)((0-sx) * s2dw);
2486 dy+=(int)((0-sy) * s2dh);
2487 h-=(int)((0-sy) * s2dh);
2492 if(sx+sw>bitmap.width-1)
2494 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2495 sw-=sx+sw-(bitmap.width-1)-1;
2497 if(sy+sh>(bitmap.height-1))
2499 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2500 sh-=sy+sh-(bitmap.height-1)-1;
2502 //Clip against the edges of the surfaceination
2503 if(dx<surface.box.left)
2506 sx+=(int)((surface.box.left-dx)*d2sw);
2507 sw-=(int)((surface.box.left-dx)*d2sw);
2508 w-=surface.box.left-dx;
2509 dx=surface.box.left;
2511 if(dy<surface.box.top)
2513 sy+=(int)((surface.box.top-dy)*d2sh);
2514 sh-=(int)((surface.box.top-dy)*d2sh);
2515 h-=surface.box.top-dy;
2518 if(dx+w>surface.box.right)
2520 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2521 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2522 w-=dx+w-surface.box.right-1;
2524 if(dy+h>surface.box.bottom)
2526 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2527 h-=dy+h-surface.box.bottom-1;
2529 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2531 dx += surface.offset.x;
2532 dy += surface.offset.y;
2534 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2536 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2537 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2538 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2539 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2540 #if !defined(SHADERS)
2541 glRasterPos2d(dx,dy);
2542 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2543 glPixelZoom(s2dw, -s2dh);
2544 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2546 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2547 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2548 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2549 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2553 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2557 //Clip against the edges of the source
2570 if(sx+w>bitmap.width-1)
2571 w-=sx+w-(bitmap.width-1)-1;
2572 if(sy+h>bitmap.height-1)
2573 h-=sy+h-(bitmap.height-1)-1;
2574 //Clip against the edges of the surfaceination
2575 if(dx<surface.box.left)
2578 sx+=surface.box.left-dx;
2579 w-=surface.box.left-dx;
2580 dx=surface.box.left;
2582 if(dy<surface.box.top)
2584 sy+=surface.box.top-dy;
2585 h-=surface.box.top-dy;
2588 if(dx+w>surface.box.right)
2590 //if(flip) sx+=dx+w-surface.box.right-1;
2591 w-=dx+w-surface.box.right-1;
2593 if(dy+h>surface.box.bottom)
2594 h-=dy+h-surface.box.bottom-1;
2598 dx += surface.offset.x;
2599 dy += surface.offset.y;
2601 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2603 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2604 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2605 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2606 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2607 #if !defined(SHADERS)
2608 glRasterPos2d(dx,dy);
2610 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2612 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2613 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2614 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2615 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2619 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2621 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2624 void UnloadFont(DisplaySystem displaySystem, Font font)
2626 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2629 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2632 OGLSystem oglSystem = displaySystem.driverData;
2633 oglSystem.loadingFont = true;
2634 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2638 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2640 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2643 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2645 OGLSurface oglSurface = surface.driverData;
2646 OGLSystem oglSystem = display.displaySystem.driverData;
2647 oglSystem.loadingFont = true;
2649 //glTranslated(-0.375, -0.375, 0.0);
2653 if(surface.textOpacity)
2656 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2658 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2661 oglSurface.writingText = true;
2663 GLSetupTexturing(true);
2665 if(surface.font.outlineSize)
2667 ColorAlpha outlineColor = surface.outlineColor;
2668 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2669 oglSurface.writingOutline = true;
2670 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2671 oglSurface.writingOutline = false;
2673 glColor4fv(oglSurface.foreground);
2675 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2676 oglSurface.writingText = false;
2677 oglSystem.loadingFont = false;
2679 GLSetupTexturing(false);
2681 //glTranslated(0.375, 0.375, 0.0);
2684 void TextFont(Display display, Surface surface, Font font)
2686 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2689 void TextOpacity(Display display, Surface surface, bool opaque)
2691 OGLSurface oglSurface = surface.driverData;
2692 oglSurface.opaqueText = opaque;
2695 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2697 OGLSurface oglSurface = surface.driverData;
2698 OGLSystem oglSystem = display.displaySystem.driverData;
2699 oglSystem.loadingFont = true;
2700 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2701 oglSystem.loadingFont = false;
2704 void DrawingChar(Display display, Surface surface, char character)
2709 void LineStipple(Display display, Surface surface, uint32 stipple)
2711 //Logf("Stipple\n");
2715 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2716 stippleEnabled = true;
2717 glesLineStipple(1, (uint16)stipple);
2719 glLineStipple(1, (uint16)stipple);
2720 glEnable(GL_LINE_STIPPLE);
2725 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2726 stippleEnabled = false;
2727 glMatrixMode(GL_TEXTURE);
2729 glMatrixMode(MatrixMode::projection);
2730 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2732 glDisable(GL_LINE_STIPPLE);
2737 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2738 void SetRenderState(Display display, RenderState state, uint value)
2740 OGLDisplay oglDisplay = display.driverData;
2741 //Logf("RenderState\n");
2746 #ifndef __EMSCRIPTEN__
2748 glEnable(GL_MULTISAMPLE_ARB);
2750 glDisable(GL_MULTISAMPLE_ARB);
2754 #if !defined(ES1_1) && !defined(ES2)
2755 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2759 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2762 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2763 oglDisplay.depthWrite = (bool)value;
2767 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2768 #if defined(SHADERS)
2769 shader_fogColor(color[0], color[1], color[2]);
2771 glFogfv(GL_FOG_COLOR, (float *)&color);
2776 #if defined(SHADERS)
2777 shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2779 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2783 //#if !defined(__EMSCRIPTEN__)
2784 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2789 #if defined(SHADERS)
2790 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2792 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2793 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2799 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2804 #if defined(__WIN32__)
2805 wglSwapIntervalEXT(value ? 1 : 0);
2812 void SetLight(Display display, int id, Light light)
2814 #if defined(SHADERS)
2815 shader_setLight(display, id, light);
2817 //Logf("SetLight\n");
2821 Object lightObject = light.lightObject;
2822 float position[4] = { 0, 0, 0, 0 };
2823 float color[4] = { 0, 0, 0, 1 };
2825 glEnable(GL_LIGHT0 + id);
2827 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
2828 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
2829 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
2832 if(!light.multiplier) light.multiplier = 1.0f;
2834 color[0] = light.diffuse.r * light.multiplier;
2835 color[1] = light.diffuse.g * light.multiplier;
2836 color[2] = light.diffuse.b * light.multiplier;
2837 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2839 color[0] = light.ambient.r * light.multiplier;
2840 color[1] = light.ambient.g * light.multiplier;
2841 color[2] = light.ambient.b * light.multiplier;
2842 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2843 color[0] = light.specular.r * light.multiplier;
2844 color[1] = light.specular.g * light.multiplier;
2845 color[2] = light.specular.b * light.multiplier;
2846 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2850 Vector3D positionVector;
2851 if(light.flags.spot)
2853 if(lightObject.flags.root || !lightObject.parent)
2855 positionVector = lightObject.transform.position;
2856 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2860 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2861 if(display.display3D.camera)
2862 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2868 if(!light.direction.x && !light.direction.y && !light.direction.z)
2870 Vector3Df vector { 0,0,-1 };
2872 mat.RotationQuaternion(light.orientation);
2873 positionVector.MultMatrixf(vector, mat);
2877 positionVector = light.direction;
2882 position[0] = (float)positionVector.x;
2883 position[1] = (float)positionVector.y;
2884 position[2] = (float)positionVector.z;
2886 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2889 // Display Light Position
2890 glDisable(GL_LIGHTING);
2891 glDisable(GL_DEPTH_TEST);
2895 glVertex3fv(position);
2897 glEnable(GL_DEPTH_TEST);
2898 glEnable(GL_LIGHTING);
2902 if(lightObject.flags.root || !lightObject.parent)
2904 positionVector = light.target.transform.position;
2905 positionVector.Subtract(positionVector, display.camera.cPosition);
2909 positionVector.MultMatrix(light.target.transform.position,
2910 lightObject.light.target.parent.matrix);
2911 positionVector.Subtract(positionVector, display.camera.cPosition);
2914 position[0] = positionVector.x;
2915 position[1] = positionVector.y;
2916 position[2] = positionVector.z;
2918 glDisable(GL_LIGHTING);
2919 glDisable(GL_DEPTH_TEST);
2923 glVertex3fv(position);
2925 glEnable(GL_DEPTH_TEST);
2926 glEnable(GL_LIGHTING);
2929 if(light.flags.attenuation)
2931 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2932 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2933 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2936 if(light.flags.spot)
2939 #define MAXLIGHT 0.9
2940 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2941 // Figure out exponent out of the hot spot
2942 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2944 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2945 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2946 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2951 Vector3Df vector { 0,0,-1 };
2952 Vector3Df direction;
2955 mat.RotationQuaternion(light.orientation);
2956 direction.MultMatrix(vector, mat);
2958 position[0] = direction.x;
2959 position[1] = direction.y;
2960 position[2] = direction.z;
2962 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2966 glDisable(GL_LIGHT0 + id);
2970 void SetCamera(Display display, Surface surface, Camera camera)
2972 OGLDisplay oglDisplay = display.driverData;
2973 //Logf("SetCamera\n");
2975 if(surface && camera)
2977 int left = surface.box.left + surface.offset.x;
2978 int top = surface.box.top + surface.offset.y;
2979 int right = surface.box.right + surface.offset.x;
2980 int bottom = surface.box.bottom + surface.offset.y;
2981 float origX = surface.offset.x + camera.origin.x;
2982 float origY = surface.offset.y + camera.origin.y;
2984 int y = display.height - bottom - 1;
2985 int w = right - left + 1;
2986 int h = bottom - top + 1;
2989 glViewport(x, y, w, h);
2991 // *** Projection Matrix ***
2992 glMatrixMode(MatrixMode::projection);
2993 if(!display.display3D.camera)
2996 if(display.display3D.collectingHits)
2998 float pickX = display.display3D.pickX + surface.offset.x;
2999 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3003 w / display.display3D.pickWidth, 0, 0, 0,
3004 0, h / display.display3D.pickHeight, 0, 0,
3006 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3007 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3010 glLoadMatrixd(pickMatrix.array);
3015 (left - origX) * camera.zMin / camera.focalX,
3016 (right - origX) * camera.zMin / camera.focalX,
3017 (bottom - origY) * camera.zMin / camera.focalY,
3018 (top - origY) * camera.zMin / camera.focalY,
3019 camera.zMin, camera.zMax);
3021 glDisable(GL_BLEND);
3023 // *** Z Inverted Identity Matrix ***
3024 glMatrixMode(MatrixMode::modelView);
3025 if(!display.display3D.camera)
3030 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3032 // *** View Matrix ***
3033 glMultMatrixd(camera.viewMatrix.array);
3038 glEnable(GL_DEPTH_TEST);
3040 GLSetupLighting(true);
3041 #if !defined(SHADERS)
3042 glShadeModel(GL_SMOOTH);
3044 glDepthMask((byte)bool::true);
3045 oglDisplay.depthWrite = true;
3047 #ifndef __EMSCRIPTEN__
3048 glEnable(GL_MULTISAMPLE_ARB);
3051 else if(surface && display.display3D.camera)
3054 oglDisplay.depthWrite = false;
3055 glViewport(0,0,display.width,display.height);
3057 glDisable(GL_CULL_FACE);
3058 glDisable(GL_DEPTH_TEST);
3061 GLSetupTexturing(false);
3062 GLSetupLighting(false);
3065 glDisableClientState(GL_COLOR_ARRAY);
3067 #if defined(SHADERS)
3068 shader_setPerVertexColor(false);
3070 glShadeModel(GL_FLAT);
3073 #if !defined(__EMSCRIPTEN__)
3074 glDisable(GL_MULTISAMPLE_ARB);
3077 // *** Restore 2D MODELVIEW Matrix ***
3080 // *** Restore 2D PROJECTION Matrix ***
3081 glMatrixMode(MatrixMode::projection);
3087 void ApplyMaterial(Display display, Material material, Mesh mesh)
3089 //Logf("ApplyMaterial\n");
3092 if(material.flags.doubleSided)
3094 #if !defined(SHADERS)
3095 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3097 glDisable(GL_CULL_FACE);
3101 #if !defined(SHADERS)
3102 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3104 glEnable(GL_CULL_FACE);
3108 GLSetupFog(!material.flags.noFog);
3111 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3113 Bitmap map = material.baseMap;
3114 GLSetupTexturing(true);
3115 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3117 glMatrixMode(GL_TEXTURE);
3119 if(material.uScale && material.vScale)
3120 glScalef(material.uScale, material.vScale, 1);
3121 glMatrixMode(MatrixMode::modelView);
3123 if(material.flags.tile)
3125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3135 GLSetupTexturing(false);
3137 #if defined(SHADERS)
3138 shader_setMaterial(material, mesh.flags.colors);
3140 if(mesh.flags.colors)
3142 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3143 glEnable(GL_COLOR_MATERIAL);
3147 glDisable(GL_COLOR_MATERIAL);
3149 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3150 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3153 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3154 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3158 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3159 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3162 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3163 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3166 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3170 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3172 OGLMesh oglMesh = mesh.data;
3175 if(!mesh.flags.vertices)
3177 oglMesh.vertices.free();
3178 delete mesh.vertices;
3180 if(!mesh.flags.normals)
3182 oglMesh.normals.free();
3183 delete mesh.normals;
3185 if(!mesh.flags.texCoords1)
3187 oglMesh.texCoords.free();
3188 delete mesh.texCoords;
3190 if(!mesh.flags.texCoords2)
3192 oglMesh.texCoords2.free();
3193 // delete mesh.texCoords2;
3195 if(!mesh.flags.colors)
3197 oglMesh.colors.free();
3208 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3210 bool result = false;
3213 mesh.data = OGLMesh { };
3216 if(mesh.nVertices == nVertices)
3218 // Same number of vertices, adding features (Leaves the other features pointers alone)
3219 if(mesh.flags != flags)
3221 if(!mesh.flags.vertices && flags.vertices)
3223 if(flags.doubleVertices)
3225 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3228 mesh.vertices = new Vector3Df[nVertices];
3230 if(!mesh.flags.normals && flags.normals)
3232 if(flags.doubleNormals)
3234 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3237 mesh.normals = new Vector3Df[nVertices];
3239 if(!mesh.flags.texCoords1 && flags.texCoords1)
3241 mesh.texCoords = new Pointf[nVertices];
3243 if(!mesh.flags.colors && flags.colors)
3245 mesh.colors = new ColorRGBAf[nVertices];
3251 // New number of vertices, reallocate all current and new features
3252 flags |= mesh.flags;
3255 if(flags.doubleVertices)
3257 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3260 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3264 if(flags.doubleNormals)
3266 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3269 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3271 if(flags.texCoords1)
3273 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3277 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3285 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3287 OGLMesh oglMesh = mesh.data;
3288 if(!flags) flags = mesh.flags;
3293 oglMesh.vertices.upload(
3294 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3297 oglMesh.normals.upload(
3298 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3300 if(flags.texCoords1)
3301 oglMesh.texCoords.upload(
3302 mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3305 oglMesh.colors.upload(
3306 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3310 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3317 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3321 oglIndices.buffer.free();
3322 delete oglIndices.indices;
3327 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3329 OGLIndices oglIndices = OGLIndices { };
3332 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3333 oglIndices.nIndices = nIndices;
3338 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3342 #if defined(ES1_1) || defined(ES2)
3345 if(!oglIndices.buffer.buffer)
3346 glGenBuffers(1, &oglIndices.buffer.buffer);
3347 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3348 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3349 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3353 oglIndices.buffer.upload(
3354 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3355 oglIndices.indices); //GL_STATIC_DRAW_ARB);
3359 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3362 return oglIndices.indices;
3365 void SelectMesh(Display display, Mesh mesh)
3367 //Logf("SelectMesh\n");
3369 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3371 #if defined(__WIN32__)
3372 if(glUnlockArraysEXT)
3374 if(!vboAvailable && display.display3D.mesh)
3375 glUnlockArraysEXT();
3380 OGLMesh oglMesh = mesh.data;
3382 // *** Vertex Stream ***
3383 glEnableClientState(GL_VERTEX_ARRAY);
3384 if(!display.display3D.collectingHits && oglMesh)
3386 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3388 // *** Normals Stream ***
3389 if(mesh.normals || mesh.flags.normals)
3391 glEnableClientState(GL_NORMAL_ARRAY);
3392 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3395 glDisableClientState(GL_NORMAL_ARRAY);
3397 // *** Texture Coordinates Stream ***
3398 if(mesh.texCoords || mesh.flags.texCoords1)
3400 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3401 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3404 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3406 // *** Color Stream ***
3407 if(mesh.colors || mesh.flags.colors)
3409 glEnableClientState(GL_COLOR_ARRAY);
3410 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3413 glDisableClientState(GL_COLOR_ARRAY);
3417 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3418 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3420 glEnableClientState(GL_NORMAL_ARRAY);
3421 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3424 glDisableClientState(GL_NORMAL_ARRAY);
3425 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3427 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3428 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3431 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3432 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3434 glEnableClientState(GL_COLOR_ARRAY);
3435 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3438 glDisableClientState(GL_COLOR_ARRAY);
3441 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3443 #if defined(__WIN32__)
3447 glLockArraysEXT(0, mesh.nVertices);
3453 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3455 //Logf("DrawPrimitives\n");
3457 if(primitive->type.vertexRange)
3458 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3461 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3462 // HACK TO SPEED THINGS UP...
3464 /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3465 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3468 glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
3471 OGLIndices oglIndices = primitive->data;
3472 MeshFeatures flags = mesh.flags;
3473 for(c = 0; c<primitive->nIndices; c++)
3475 uint16 index = ((uint16 *) oglIndices.indices)[c];
3476 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3477 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3478 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3479 glVertex3fv((float *)&mesh.vertices[index]);
3488 OGLIndices oglIndices = primitive->data;
3489 GLEAB eab = ((!display.display3D.collectingHits && oglIndices) ? oglIndices.buffer : noEAB);
3491 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3492 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3493 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3494 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3499 void PushMatrix(Display display)
3504 void PopMatrix(Display display, bool setMatrix)
3509 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3511 Matrix matrix = transMatrix;
3512 Camera camera = useCamera ? display.display3D.camera : null;
3517 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3522 matrix.m[3][0] - camera.cPosition.x,
3523 matrix.m[3][1] - camera.cPosition.y,
3524 matrix.m[3][2] - camera.cPosition.z);
3536 glMultMatrixd(matrix.array);
3541 public void UseSingleGLContext(bool useSingle)
3543 useSingleGLContext = useSingle;
3546 default dllexport void *
3547 #if defined(__WIN32__)
3548 __attribute__((stdcall))
3550 IS_GLGetContext(DisplaySystem displaySystem)
3554 #if defined(__WIN32__)
3555 OGLSystem system = displaySystem.driverData;
3557 #elif defined(__ANDROID__) || defined(__ODROID__)
3559 #elif defined(__EMSCRIPTEN__)
3560 OGLSystem system = displaySystem.driverData;
3561 return (void *)system.glc;
3563 OGLSystem system = displaySystem.driverData;
3564 return system.glContext;