1 namespace gfx::drivers;
9 #define GL_BGRA_EXT 0x80E1
11 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
13 # include "gl_core_3_3.h"
15 # include "gl_compat_4_4.h"
26 #undef glEnableClientState
27 #undef glDisableClientState
28 #undef GL_VERTEX_ARRAY
29 #undef GL_NORMAL_ARRAY
30 #undef GL_TEXTURE_COORD_ARRAY
33 #define glEnableClientState glEnableVertexAttribArray
34 #define glDisableClientState glDisableVertexAttribArray
35 #define GL_VERTEX_ARRAY GLBufferContents::vertex
36 #define GL_NORMAL_ARRAY GLBufferContents::normal
37 #define GL_TEXTURE_COORD_ARRAY GLBufferContents::texCoord
38 #define GL_COLOR_ARRAY GLBufferContents::color
42 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
44 #if defined(__unix__) || defined(__APPLE__)
46 #if !defined(__MINGW32__)
47 #define GL_GLEXT_PROTOTYPES
50 #define pointer _pointer
53 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
55 #define property _property
59 #define Window X11Window
60 #define Cursor X11Cursor
62 #define Display X11Display
64 #define KeyCode X11KeyCode
65 #define Picture X11Picture
69 #include <X11/Xutil.h>
71 #include <X11/extensions/XShm.h>
74 #include <X11/extensions/Xrender.h>
75 #include <X11/extensions/shape.h>
93 #if defined(__APPLE__)
94 #include <OpenGl/gl.h>
97 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
99 #if defined(__WIN32__)
100 //#define WIN32_LEAN_AND_MEAN
102 #define _WIN32_WINNT 0x0502
103 #define String Sting_
108 #if defined(__ANDROID__) || defined(__ODROID__)
111 #define property _property
114 #define Window X11Window
115 #define Cursor X11Cursor
117 #define Display X11Display
119 #define KeyCode X11KeyCode
120 #define Picture X11Picture
138 #elif defined(__EMSCRIPTEN__)
140 #define property _property
145 //#include <GLES/gl.h>
146 //#include <EGL/egl.h>
148 //#include <GLES2/gl.h>
149 //#include <EGL/egl.h>
151 //#include <GLES2/gl2.h>
153 #include <emscripten/emscripten.h>
162 #if defined(__ODROID__) && !defined(ES1_1)
166 #if defined(__EMSCRIPTEN__)
177 #if defined(__unix__) || defined(__APPLE__)
179 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
185 #define glLoadMatrix glLoadMatrixd
186 #define glMultMatrix glMultMatrixd
187 #define glGetMatrix glGetDoublev
188 #define glTranslate glTranslated
189 #define glScale glScaled
192 #define glVertex3v glVertex3dv
193 #define glNormal3v glNormal3dv
197 //#ifdef VERTEX_FORMAT_DOUBLE
199 #define glLoadMatrix glLoadMatrixd
200 #define glMultMatrix glMultMatrixd
201 #define glGetMatrix glGetDoublev
202 #define glVertex3v glVertex3dv
203 #define glNormal3v glNormal3dv
204 #define glTranslate glTranslated
205 #define glScale glScaled
206 //#define GL_VERTEX_FORMAT GL_DOUBLE
210 #define glLoadMatrix glLoadMatrixf
211 #define glMultMatrix glMultMatrixf
212 #define glGetMatrix glGetFloatv
213 #define glVertex3v glVertex3fv
214 #define glNormal3v glNormal3fv
215 #define glTranslate glTranslatef
216 #define glScale glScalef
217 //#define GL_VERTEX_FORMAT GL_FLOAT
222 #define GL_ARRAY_BUFFER_ARB 0x8892
223 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
224 #define GL_STATIC_DRAW_ARB 0x88E4
225 #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
226 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
228 #define GL_MULTISAMPLE_ARB 0x809D
230 #if defined(__WIN32__)
233 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
234 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
236 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
237 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
239 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
240 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
241 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
242 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
243 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
244 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
245 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
246 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
247 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
248 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = null;
249 static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = null;
251 #elif defined(__ANDROID__) || defined(__ODROID__)
253 #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
254 #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
255 #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
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_BGRA_EXT 0
275 #define GL_UNPACK_ROW_LENGTH 0
276 #define GL_UNPACK_SKIP_PIXELS 0
277 #define GL_UNPACK_SKIP_ROWS 0
279 #define GL_PACK_ROW_LENGTH 0
280 #define GL_PACK_SKIP_ROWS 0
281 #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
295 #define GL_INT 0x1404
296 #define GL_UNSIGNED_INT 0x1405
297 #define GL_DOUBLE 0x140A
301 #if defined(ES1_1) || defined(SHADERS)
332 #undef glLoadIdentity
337 #undef glColorMaterial
340 #define glRecti glimtkRecti
341 #define glBegin glimtkBegin
342 #define glTexCoord2i glimtkTexCoord2i
343 #define glVertex2i glimtkVertex2i
344 #define glTexCoord2d glimtkTexCoord2d
345 #define glVertex2d glimtkVertex2d
346 #define glTexCoord2f glimtkTexCoord2f
347 #define glVertex2f glimtkVertex2f
348 #define glEnd glimtkEnd
349 #define glColor3f glimtkColor3f
350 #define glColor4ub glimtkColor4ub
351 #define glColor4fv glimtkColor4fv
352 #define glNormal3fv glimtkNormal3fv
353 #define glNormal3f glimtkNormal3f
354 #define glTexCoord2fv glimtkTexCoord2fv
355 #define glVertex3d glimtkVertex3d
356 #define glVertex3dv glimtkVertex3dv
357 #define glVertex3f glimtkVertex3f
358 #define glVertex3fv glimtkVertex3fv
360 #define glLoadMatrixd glmsLoadMatrixd
361 #define glMultMatrixd glmsMultMatrixd
362 #define glFrustum glmsFrustum
363 #define glOrtho glmsOrtho
364 #define glScaled glmsScaled
365 #define glScalef glmsScaled
366 #define glTranslated glmsTranslated
367 #define glRotated glmsRotated
368 #define glMatrixMode glmsMatrixMode
369 #define glLoadIdentity glmsLoadIdentity
370 #define glPushMatrix glmsPushMatrix
371 #define glPopMatrix glmsPopMatrix
373 #define glLineStipple glesLineStipple
374 #define glColorMaterial glesColorMaterial
375 #define glLightModeli glesLightModeli
379 public void glesColorMaterial(int a, int b)
381 PrintLn("glColorMaterial stub");
384 static GLuint stippleTexture;
385 #if defined(ES1_1) || defined(SHADERS) || defined(EM_MODE)
386 static bool stippleEnabled;
389 public void glesLineStipple( int i, unsigned short j )
393 for(x = 0; x < 16; x++)
395 bool v = (j & (1 << x)) != 0;
396 texture[x] = v ? 0xFFFFFFFF : 0;
399 glGenTextures(1, &stippleTexture);
400 glBindTexture(GL_TEXTURE_2D, stippleTexture);
401 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
403 // TOOD: Special shading code for stippling?
404 GLSetupTexturing(true);
405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
406 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
407 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
408 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
409 glMatrixMode(GL_TEXTURE);
411 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
412 glScaled(i/16.0, 1, 1.0f);
413 glTranslated(0.5, 0.5, 0);
414 glMatrixMode(MatrixMode::projection);
417 public void glesLightModeli( unsigned int pname, int param )
419 #if !defined(EM_MODE) && !defined(SHADERS)
420 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
421 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
425 #if defined(__ANDROID__) || defined(__ODROID__)
426 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
427 void glFogi( unsigned int pname, int param ) { }
428 void glPolygonMode( unsigned int i, unsigned int j ) { }
431 // *** Picking won't be supported for now ***
432 void glPushName( unsigned int i ) { }
433 void glLoadName( unsigned int i ) { }
436 // Probably replace by regular glBlendFunc ...
437 void glBlendFuncSeparate(int a, int b, int c, int d)
442 // For direct pixel blitting...
443 void glRasterPos2d(double a, double b) { }
444 void glPixelZoom(float a, float b) { }
445 void glDrawPixels(int a, int b, int c, int d, void * e) { }
449 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
450 static int primitiveTypes[RenderPrimitiveType] =
452 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GLIMTKMode::quads, GLIMTKMode::quadStrip, GL_LINE_STRIP
456 public void GLSetupTexturing(bool enable)
459 shader_texturing(enable);
461 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
465 public void GLSetupLighting(bool enable)
468 shader_lighting(enable);
469 #elif !defined(EM_MODE)
470 (enable ? glEnable : glDisable)(GL_LIGHTING);
474 // Non OpenGL ES friendly stuff
478 //#undef GL_UNSIGNED_INT
484 #undef GL_POLYGON_STIPPLE
485 #undef GL_LINE_STIPPLE
488 #undef GL_ALL_ATTRIB_BITS
489 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
493 static int displayWidth, displayHeight;
495 #define GL_CLAMP_TO_EDGE 0x812F
497 static bool vboAvailable;
499 static bool useSingleGLContext = false;
500 class OGLDisplay : struct
502 #if defined(__WIN32__)
513 byte * pboMemory1, * pboMemory2;
515 #elif !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
516 GLXContext glContext;
519 XShmSegmentInfo shminfo;
521 XShmSegmentInfo shminfoShape;
526 X11Picture windowPicture;
527 X11Picture pixmapPicture;
529 X11Picture shapePicture;
532 ColorAlpha * flippingBuffer;
533 int flipBufH, flipBufW;
539 static void APIENTRY openglCallbackFunction(GLenum source,
544 const GLchar* message,
545 const void* userParam)
547 PrintLn("---------------------opengl-callback-start------------");
548 PrintLn("message: ", message);
552 case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
553 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
554 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
555 case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
556 case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
557 case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
564 case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
565 case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
566 case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
568 PrintLn("---------------------opengl-callback-end--------------");
572 class OGLSystem : struct
577 #if defined(__WIN32__)
578 PIXELFORMATDESCRIPTOR pfd;
583 #elif !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
584 XVisualInfo * visualInfo;
585 GLXContext glContext;
586 GLXDrawable glxDrawable;
590 class OGLSurface : struct
598 float foreground[4], background[4], bitmapMult[4];
601 class OGLMesh : struct
610 class OGLIndices : struct
620 static void setupDebugging()
623 if(glDebugMessageCallback)
625 GLuint unusedIds = 0;
627 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
628 glDebugMessageCallback(openglCallbackFunction, null);
629 glDebugMessageControl(GL_DONT_CARE,
639 #if defined(__WIN32__)
640 static HGLRC winCreateContext(HDC hdc)
642 if(wglCreateContextAttribsARB)
646 WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
647 WGL_CONTEXT_MINOR_VERSION_ARB, 4,
648 WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | */WGL_CONTEXT_DEBUG_BIT_ARB,
649 WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB /*WGL_CONTEXT_CORE_PROFILE_BIT_ARB*/,
652 return wglCreateContextAttribsARB(hdc, null, attribs);
655 return wglCreateContext(hdc);
659 class OpenGLDisplayDriver : DisplayDriver
661 class_property(name) = "OpenGL";
663 bool LockSystem(DisplaySystem displaySystem)
665 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
666 OGLSystem oglSystem = displaySystem.driverData;
667 if(useSingleGLContext) return true;
668 #if defined(__WIN32__)
669 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
670 #elif defined(__unix__) || defined(__APPLE__)
671 //if(previous) return true;
672 // printf("Making SYSTEM current\n");
673 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
674 //previous = oglSystem.glContext;
677 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
678 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
682 void UnlockSystem(DisplaySystem displaySystem)
684 if(useSingleGLContext) return;
685 #if defined(__WIN32__)
686 wglMakeCurrent(null, null);
687 #elif defined(__unix__) || defined(__APPLE__)
688 // printf("Making NULL current\n");
689 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
691 glXMakeCurrent(xGlobalDisplay, None, null);
697 bool Lock(Display display)
699 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
700 OGLDisplay oglDisplay = display.driverData;
701 if(useSingleGLContext) return true;
702 #if defined(__WIN32__)
703 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
704 #elif defined(__unix__) || defined(__APPLE__)
705 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
706 // printf(" Making DISPLAY current\n");
707 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
710 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
711 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
715 void Unlock(Display display)
717 if(useSingleGLContext) return;
718 //printf(" Making NULL current\n");
719 //glXMakeCurrent(xGlobalDisplay, None, null);
721 LockSystem(display.displaySystem);
724 void DestroyDisplay(Display display)
726 OGLDisplay oglDisplay = display.driverData;
730 #if defined(__WIN32__)
731 wglMakeCurrent( null, null );
734 wglDeleteContext(oglDisplay.glrc);
736 if(oglDisplay.hdc && oglDisplay.pBuffer)
737 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
739 if(oglDisplay.pBuffer)
740 wglDestroyPbufferARB(oglDisplay.pBuffer);
743 ReleaseDC(display.window, oglDisplay.hdc);
745 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
746 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
748 #elif defined(__unix__) || defined(__APPLE__)
749 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
751 if(oglDisplay.shapePixmap)
752 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
753 if(oglDisplay.pixmap)
754 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
757 if(oglDisplay.shminfoShape.shmid != -1)
759 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
760 if(oglDisplay.shminfo.shmaddr != (void *)-1)
761 shmdt(oglDisplay.shminfo.shmaddr);
762 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
765 if(oglDisplay.shapeImage)
767 if(oglDisplay.shminfoShape.shmid != -1)
769 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
770 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
771 shmdt(oglDisplay.shminfoShape.shmaddr);
772 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
774 XDestroyImage(oglDisplay.shapeImage);
775 oglDisplay.shapeImage = None;
778 glXMakeCurrent(xGlobalDisplay, None, null);
780 if(oglDisplay.glContext)
781 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
784 delete oglDisplay.flippingBuffer;
786 display.driverData = null;
790 void ::CheckExtensions(OGLSystem oglSystem)
792 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
794 oglSystem.pow2textures = strstr(extensions, "GL_ARB_texture_non_power_of_two") ? false : true;
795 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
798 bool CreateDisplaySystem(DisplaySystem displaySystem)
801 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
804 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
806 oglSystem.hdc = GetDC(oglSystem.hwnd);
810 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
811 oglSystem.pfd.nVersion = 1;
812 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
813 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
814 oglSystem.pfd.cColorBits = 24;
815 oglSystem.pfd.cAlphaBits = 8;
816 oglSystem.pfd.cDepthBits = 24;
817 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
819 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
820 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
822 if(oglSystem.pfd.cColorBits > 8)
824 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
825 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
828 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
830 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
831 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
832 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
833 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
834 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
835 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
836 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
837 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
838 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
839 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
840 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
842 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
843 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
845 // eSystem_LoggingMode(LOG_MSGBOX, null);
847 if(wglChoosePixelFormatARB)
852 float fAttributes[] = {0,0};
855 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
856 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
857 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
858 WGL_COLOR_BITS_ARB,24,
859 WGL_ALPHA_BITS_ARB,8,
860 WGL_DEPTH_BITS_ARB,16,
861 WGL_STENCIL_BITS_ARB,0,
862 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
863 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
864 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
868 //Log("Found wglChoosePixelFormatARB\n");
870 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
871 if(!valid || !numFormats)
873 //Log("Can't find 4x multi sampling\n");
875 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
876 if(!valid || !numFormats)
878 // Log("Can't find 2x multi sampling\n");
881 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
884 if(valid && numFormats)
886 oglSystem.format = pixelFormat;
887 wglMakeCurrent(null, null);
888 wglDeleteContext(oglSystem.glrc);
890 // *** DescribePixelFormat does not support WGL pixel formats! ***
891 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
892 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
893 //Log("Successfully set pixel format\n");
895 oglSystem.glrc = winCreateContext(oglSystem.hdc);
896 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
900 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
904 wglMakeCurrent(null, null);
906 //eSystem_DumpErrors(true);
910 #elif defined(__unix__) || defined(__APPLE__)
912 #if defined(__ANDROID__)
913 egl_init_display(guiApp.desktop.windowHandle);
914 #elif defined(__ODROID__)
915 egl_init_display((uint)displaySystem.window);
916 CheckExtensions(oglSystem);
918 #elif defined(__EMSCRIPTEN__)
919 if(glfwInit() == GL_TRUE)
921 const int width = 640, height = 480;
922 if(glfwOpenWindow(width, height, 8, 8, 8, 8, 16, 0, GLFW_WINDOW) == GL_TRUE)
928 printf("glfwOpenWindow() failed\n"); //glfwTerminate();
931 printf("glfwInit() failed\n"); //glfwTerminate();
934 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
935 XSetWindowAttributes attr;
940 #ifndef ECERE_MINIGLX
941 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
944 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
948 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
949 attr.background_pixel = 0;
950 attr.border_pixel = 0;
951 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
952 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
953 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
955 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
956 oglSystem.visualInfo->visual, mask, &attr );
958 if(oglSystem.visualInfo)
960 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
961 if(oglSystem.glContext)
963 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
965 // CheckExtensions(oglSystem);
966 glXMakeCurrent(xGlobalDisplay, None, null);
973 displaySystem.flags.alpha = true;
974 displaySystem.flags.flipping = true;
975 displaySystem.pixelFormat = pixelFormat888;
979 void DestroyDisplaySystem(DisplaySystem displaySystem)
981 OGLSystem oglSystem = displaySystem.driverData;
983 #if defined(__WIN32__)
984 wglMakeCurrent( null, null );
987 wglDeleteContext(oglSystem.glrc);
990 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
991 DestroyWindow(oglSystem.hwnd);
993 #elif defined(__unix__) || defined(__APPLE__)
994 #if defined(__ANDROID__) || defined(__ODROID__)
996 #elif defined(__EMSCRIPTEN__)
999 if(oglSystem.visualInfo)
1001 #ifdef ECERE_MINIGLX
1002 __miniglx_XFree(oglSystem.visualInfo);
1004 XFree(oglSystem.visualInfo);
1008 if(oglSystem.glxDrawable)
1010 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1011 oglSystem.glxDrawable = 0;
1018 bool CreateDisplay(Display display)
1020 bool result = false;
1021 OGLDisplay oglDisplay = display.driverData;
1022 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1023 OGLSystem oglSystem = display.displaySystem.driverData;
1027 oglDisplay = display.driverData = OGLDisplay { };
1028 //printf("Inside CreateDisplay\n");
1030 #if defined(__WIN32__) || defined(USEPBUFFER)
1031 if(!display.alphaBlend)
1034 #if defined(__WIN32__)
1035 oglDisplay.hdc = GetDC(display.window);
1036 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1037 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1039 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1040 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1044 ReleaseDC(display.window, oglDisplay.hdc);
1045 #elif defined(__unix__) || defined(__APPLE__)
1046 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1048 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1050 #if defined(__APPLE__)
1051 XVisualInfo template = { 0 };
1052 XWindowAttributes winAttr;
1054 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1055 template.visualid = XVisualIDFromVisual(winAttr.visual);
1056 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1058 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1059 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1060 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1061 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1063 // visualInfo = oglSystem.visualInfo;
1068 //printf("visualInfo is not null\n");
1069 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1070 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1071 //XFree(visualInfo);
1074 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1075 if(oglDisplay.glContext)
1077 //printf("CreateDisplay Got a Context\n");
1078 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1084 #if defined(__WIN32__) || defined(USEPBUFFER)
1090 ogl_LoadFunctions();
1091 CheckExtensions(oglSystem);
1092 vboAvailable = glBindBuffer != null;
1095 loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1097 glEnableClientState(GL_VERTEX_ARRAY);
1098 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1099 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1101 #if defined(__WIN32__)
1102 if(glBlendFuncSeparate)
1103 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1105 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1107 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1111 glMatrixMode(MatrixMode::modelView);
1112 glLoadIdentity(); // For setting up GLES stack
1113 glScaled(1.0, 1.0, -1.0);
1114 // glTranslatef(0.375f, 0.375f, 0.0f);
1115 // glTranslatef(-0.625f, -0.625f, 0.0f);
1116 glMatrixMode(MatrixMode::projection);
1117 #if !defined(EM_MODE) && !defined(SHADERS)
1118 glShadeModel(GL_FLAT);
1120 // #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1122 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1123 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1124 glFogi(GL_FOG_MODE, GL_EXP);
1125 glFogf(GL_FOG_DENSITY, 0);
1126 glEnable(GL_NORMALIZE);
1128 glDepthFunc(GL_LESS);
1130 glDisable(GL_MULTISAMPLE_ARB);
1132 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1133 display.ambient = Color { 50,50,50 };
1136 if(!useSingleGLContext)
1138 #if defined(__WIN32__)
1139 wglMakeCurrent(null, null);
1140 #elif defined(__unix__) || defined(__APPLE__)
1141 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1144 glXMakeCurrent(xGlobalDisplay, None, null);
1150 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1158 bool DisplaySize(Display display, int width, int height)
1160 OGLDisplay oglDisplay = display.driverData;
1162 bool result = false;
1164 //printf("Inside DisplaySize\n");
1165 #if defined(__WIN32__) || defined(USEPBUFFER)
1166 OGLSystem oglSystem = display.displaySystem.driverData;
1167 if(display.alphaBlend)
1169 #if defined(__WIN32__)
1170 const int attributes[]=
1172 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1173 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1175 int pixelFormat = 0;
1176 if(wglChoosePixelFormatARB)
1180 float fAttributes[] = {0,0};
1183 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1184 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1185 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1186 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1187 WGL_COLOR_BITS_ARB,24,
1188 WGL_ALPHA_BITS_ARB,8,
1189 WGL_DEPTH_BITS_ARB,16,
1190 WGL_STENCIL_BITS_ARB,0,
1191 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1192 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1193 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1197 //Log("Found wglChoosePixelFormatARB\n");
1199 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1200 if(!valid || !numFormats)
1202 //Log("Can't find 4x multi sampling\n");
1203 iAttributes[19] = 2;
1204 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1205 if(!valid || !numFormats)
1207 // Log("Can't find 2x multi sampling\n");
1208 iAttributes[16] = 0;
1209 iAttributes[17] = 0;
1210 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1211 if(!valid || !numFormats)
1215 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1216 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1217 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1218 WGL_COLOR_BITS_ARB,24,
1219 WGL_ALPHA_BITS_ARB,8,
1220 WGL_DEPTH_BITS_ARB,16,
1223 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1227 if(valid && numFormats)
1229 wglMakeCurrent(null, null);
1233 wglMakeCurrent( null, null );
1234 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1235 if(oglDisplay.hdc && oglDisplay.pBuffer)
1236 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1238 wglDestroyPbufferARB(oglDisplay.pBuffer);
1240 if(!useSingleGLContext)
1241 wglMakeCurrent( null, null );
1244 wglDeleteContext(oglDisplay.glrc);
1246 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1247 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1248 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1251 HDC hdc = GetDC(display.window);
1253 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1254 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1256 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1257 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1259 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1261 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1265 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1266 oglDisplay.memDC = CreateCompatibleDC(hdc);
1267 SetMapMode(oglDisplay.memDC, MM_TEXT);
1268 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1269 info->bmiHeader.biPlanes = 1;
1270 info->bmiHeader.biCompression = BI_RGB;
1271 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1272 info->bmiHeader.biWidth = width;
1273 info->bmiHeader.biHeight = height;
1274 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1277 SelectObject(oglDisplay.memDC, newBitmap);
1278 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1281 PIXELFORMATDESCRIPTOR pfd = { 0 };
1282 pfd.nSize = (short)sizeof(pfd);
1284 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1285 pfd.iPixelType = PFD_TYPE_RGBA;
1286 pfd.cColorBits = 32;
1287 //pfd.cAlphaBits = 8;
1288 pfd.cDepthBits = 24;
1289 pfd.iLayerType = PFD_MAIN_PLANE;
1291 oglDisplay.hdc = oglDisplay.memDC;
1293 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1294 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1295 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1297 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1298 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1299 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1304 const int imageSize = width * height * 4;
1306 glGenBuffersARB(2, oglDisplay.imageBuffers);
1308 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1309 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1310 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1311 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1314 oglDisplay.memBitmap = newBitmap;
1315 oglDisplay.stride = width;
1321 ReleaseDC(display.window, hdc);
1323 #elif defined(__unix__) || defined(__APPLE__)
1324 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1329 GLX_DOUBLEBUFFER, True,
1335 GLX_STENCIL_SIZE, 1,
1336 //GLX_DEPTH_SIZE, 24,
1337 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1338 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1344 GLX_PBUFFER_WIDTH, width,
1345 GLX_PBUFFER_HEIGHT, height,
1346 GLX_LARGEST_PBUFFER, False,
1350 // choose a pixel format that meets our minimum requirements
1353 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1356 if(oglDisplay.pixmap)
1358 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1359 oglDisplay.pixmap = None;
1361 if(oglDisplay.shapePixmap)
1363 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1364 oglDisplay.shapePixmap = None;
1367 // Free Shared Memory Pixmap
1368 if(oglDisplay.image)
1370 if(oglDisplay.shminfoShape.shmid != -1)
1372 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1373 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1374 shmdt(oglDisplay.shminfo.shmaddr);
1375 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1377 XDestroyImage(oglDisplay.image);
1378 oglDisplay.image = None;
1380 if(oglDisplay.shapeImage)
1382 if(oglDisplay.shminfoShape.shmid != -1)
1384 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1385 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1386 shmdt(oglDisplay.shminfoShape.shmaddr);
1387 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1389 XDestroyImage(oglDisplay.shapeImage);
1390 oglDisplay.shapeImage = None;
1393 if(oglDisplay.windowPicture)
1394 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1395 if(oglDisplay.pixmapPicture)
1396 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1398 if(oglDisplay.pixmap)
1399 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1401 if(oglDisplay.glContext)
1402 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1403 if(oglDisplay.pBuffer)
1404 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1406 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1407 if(oglDisplay.pBuffer)
1409 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1410 if(oglDisplay.glContext)
1412 glXMakeCurrent(xGlobalDisplay, None, null);
1413 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1415 // Initialize Shared Memory Pixmap
1416 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1417 ZPixmap, null, &oglDisplay.shminfo, width, height);
1418 if(oglDisplay.image)
1420 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1421 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1422 if(oglDisplay.shminfo.shmid != -1)
1424 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1425 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1427 oglDisplay.shminfo.readOnly = False;
1428 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1430 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1431 &oglDisplay.shminfo, width, height, 32);
1433 // Initialize Shared Memory Shape Pixmap
1434 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1435 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1436 if(oglDisplay.shapeImage)
1438 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1439 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1440 if(oglDisplay.shminfoShape.shmid != -1)
1442 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1443 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1445 oglDisplay.shminfoShape.readOnly = False;
1446 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1448 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1449 &oglDisplay.shminfoShape, width, height, 1);
1450 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1453 XRenderPictureAttributes attributes = { 0 };
1454 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1455 #if !defined(__APPLE__)
1456 attributes.repeat = RepeatNormal;
1458 attributes.repeat = 1;
1460 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1461 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1462 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1463 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1466 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1467 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1484 CreateDisplay(display);
1485 #if defined(__WIN32__)
1486 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1487 #elif defined(__unix__) || defined(__APPLE__)
1488 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1492 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1499 if(!result && display.alphaBlend)
1501 printf("Alpha blending windows not supported on this display\n");
1508 glViewport(0,0,width,height);
1509 glMatrixMode(MatrixMode::projection);
1511 glOrtho(0,width,height,0,0.0,1.0);
1512 displayWidth = display.width = width;
1513 displayHeight = display.height = height;
1515 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1517 oglDisplay.flipBufW = width;
1518 oglDisplay.flipBufH = height;
1522 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1525 if(oglDisplay.flippingBuffer || !width || !height)
1531 void DisplayPosition(Display display, int x, int y)
1533 OGLDisplay oglDisplay = display.driverData;
1539 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1543 void RestorePalette(Display display)
1547 void StartUpdate(Display display)
1551 void EndUpdate(Display display)
1555 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1559 void Update(Display display, Box updateBox)
1561 #if defined(__WIN32__) || defined(USEPBUFFER)
1562 OGLDisplay oglDisplay = display.driverData;
1564 //Logf("DisplayScreen\n");
1566 #if !defined(__ANDROID__)
1571 #if defined(__WIN32__) || defined(USEPBUFFER)
1572 if(display.alphaBlend)
1574 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1575 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1576 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1577 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1578 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1581 #if defined(__WIN32__)
1583 POINT point = { oglDisplay.x, oglDisplay.y};
1584 POINT srcPoint = { 0, 0 };
1585 BLENDFUNCTION blend = { 0 };
1587 size.cx = display.width;
1588 size.cy = display.height;
1589 blend.BlendOp = AC_SRC_OVER;
1590 blend.BlendFlags = 0;
1591 blend.SourceConstantAlpha = 255;
1592 blend.AlphaFormat = AC_SRC_ALPHA;
1595 // Process partial images. Mapping the buffer waits for
1596 // outstanding DMA transfers into the buffer to finish.
1597 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1598 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1600 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1601 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1604 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1605 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1608 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1611 // Unmap the image buffers
1612 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1613 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1615 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1616 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1618 // Bind two different buffer objects and start the glReadPixels
1619 // asynchronously. Each call will return directly after
1620 // starting the DMA transfer.
1621 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1622 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1624 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1625 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1629 #elif defined(__unix__) || defined(__APPLE__)
1630 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1632 XTransform transform =
1635 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1636 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1637 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1640 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1641 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1642 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1643 #if !defined(__APPLE__)
1644 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1646 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1648 XFlush(xGlobalDisplay);
1656 #if defined(__WIN32__)
1657 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1658 SwapBuffers(oglDisplay.hdc);
1659 #elif defined(__unix__) || defined(__APPLE__)
1660 #if defined(__ANDROID__) || defined(__ODROID__)
1661 eglSwapBuffers(eglDisplay, eglSurface);
1662 #elif defined(__EMSCRIPTEN__)
1665 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1669 //Logf("Out of DisplayScreen\n");
1672 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1674 if(bitmap.driverData)
1676 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1677 glDeleteTextures(1, &tex);
1678 bitmap.driverData = 0;
1680 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1683 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1685 OGLSystem oglSystem = displaySystem.driverData;
1686 bool result = false;
1688 GLuint glBitmap = 0;
1690 uint w = width, h = height;
1691 if(oglSystem.pow2textures)
1696 w = Min(w, oglSystem.maxTextureSize);
1697 h = Min(h, oglSystem.maxTextureSize);
1699 glGenTextures(1, &glBitmap);
1700 glBindTexture(GL_TEXTURE_2D, glBitmap);
1702 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1704 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1705 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1707 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1708 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1710 #if !defined(SHADERS)
1711 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1714 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1716 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1717 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1721 bitmap.driverData = (void *)(uintptr)glBitmap;
1722 bitmap.driver = displaySystem.driver;
1730 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1732 bool result = false;
1733 OGLSystem oglSystem = displaySystem.driverData;
1734 Bitmap convBitmap = bitmap;
1738 convBitmap.Copy(bitmap);
1741 // Pre process the bitmap... First make it 32 bit
1742 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1745 uint w = bitmap.width, h = bitmap.height;
1746 GLuint glBitmap = 0;
1747 if(oglSystem.pow2textures)
1752 w = Min(w, oglSystem.maxTextureSize);
1753 h = Min(h, oglSystem.maxTextureSize);
1757 while(w * 2 < h) w *= 2;
1758 while(h * 2 < w) h *= 2;
1761 // Switch ARGB to RGBA
1762 //if(bitmap.format != pixelFormatRGBA)
1764 for(c=0; c<bitmap.size; c++)
1766 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1768 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1769 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1772 // convBitmap.pixelFormat = pixelFormat888;
1775 glGenTextures(1, &glBitmap);
1778 //int error = glGetError();
1782 glBindTexture(GL_TEXTURE_2D, glBitmap);
1783 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1785 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1786 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1788 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1790 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1791 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1793 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1794 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1795 #if !defined(__ANDROID__) && !defined(SHADERS)
1796 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1799 #if !defined(SHADERS)
1800 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1805 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1810 if(bitmap.width != w || bitmap.height != h)
1812 mipMap = Bitmap { };
1813 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1815 Surface mipSurface = mipMap.GetSurface(0,0,null);
1816 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1826 mipMap = convBitmap;
1833 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1834 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1835 //printf("Calling glTexImage2D\n");
1836 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
1837 //printf("width = %d (Should be %d, %d)\n", width, w, h);
1838 if((error = glGetError()))
1840 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
1841 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
1845 if(mipMap != convBitmap)
1850 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
1851 bitmap.driverData = (void *)(uintptr)glBitmap;
1852 bitmap.driver = displaySystem.driver;
1857 FreeBitmap(displaySystem, bitmap);
1858 else if(oglSystem.loadingFont)
1860 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1861 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1862 oglSystem.loadingFont = false;
1868 void ReleaseSurface(Display display, Surface surface)
1870 glDisable(GL_SCISSOR_TEST);
1871 delete surface.driverData;
1872 surface.driverData = null;
1875 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
1880 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
1882 bool result = false;
1883 OGLSurface oglSurface = surface.driverData = OGLSurface { };
1885 //Logf("GetSurface\n");
1889 if(displayWidth != display.width || displayHeight != display.height)
1891 displayWidth = display.width;
1892 displayHeight = display.height;
1894 glViewport(0,0,display.width,display.height);
1896 glOrtho(0,display.width,display.height,0,0.0,1.0);
1899 surface.offset.x = x;
1900 surface.offset.y = y;
1901 surface.unclippedBox = surface.box = clip;
1902 oglSurface.bitmapMult[0] = 1;
1903 oglSurface.bitmapMult[1] = 1;
1904 oglSurface.bitmapMult[2] = 1;
1905 oglSurface.bitmapMult[3] = 1;
1907 glEnable(GL_SCISSOR_TEST);
1910 (display.height) -(y+clip.bottom)-1,
1911 clip.right-clip.left+1,
1912 clip.bottom-clip.top+1);
1918 void Clip(Display display, Surface surface, Box clip)
1927 box.Clip(surface.unclippedBox);
1931 box = surface.box = surface.unclippedBox;
1932 box.left += surface.offset.x;
1933 box.top += surface.offset.y;
1934 box.right+= surface.offset.x;
1935 box.bottom += surface.offset.y;
1938 box.left,display.height - box.bottom - 1,
1939 box.right-box.left+1, box.bottom-box.top+1);
1942 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
1944 bool result = false;
1945 OGLDisplay oglDisplay = display.driverData;
1946 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
1948 if(oglDisplay.flippingBuffer)
1950 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
1953 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
1959 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1960 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
1961 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1962 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1963 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
1966 for(row = 0; row<h; row++)
1967 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
1974 void SetForeground(Display display, Surface surface, ColorAlpha color)
1976 OGLSurface oglSurface = surface.driverData;
1978 //Logf("SetForeground\n");
1980 oglSurface.foreground[0] = color.color.r/255.0f;
1981 oglSurface.foreground[1] = color.color.g/255.0f;
1982 oglSurface.foreground[2] = color.color.b/255.0f;
1983 //oglSurface.foreground[3] = 1.0f;
1984 oglSurface.foreground[3] = color.a/255.0f;
1986 //if(!oglSurface.foreground[3])printf("bug");
1989 void SetBackground(Display display, Surface surface, ColorAlpha color)
1991 OGLSurface oglSurface = surface.driverData;
1993 //Logf("SetBackground\n");
1995 oglSurface.background[0] = color.color.r/255.0f;
1996 oglSurface.background[1] = color.color.g/255.0f;
1997 oglSurface.background[2] = color.color.b/255.0f;
1998 //oglSurface.background[3] = 1.0;
1999 oglSurface.background[3] = color.a/255.0f;
2002 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2004 OGLSurface oglSurface = surface.driverData;
2006 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2007 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2008 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2009 oglSurface.bitmapMult[3] = color.a/255.0f;
2012 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2017 void PutPixel(Display display, Surface surface,int x,int y)
2019 OGLSurface oglSurface = surface.driverData;
2021 //Logf("PutPixel\n");
2023 glColor4fv(oglSurface.foreground);
2025 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2026 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2031 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2033 OGLSurface oglSurface = surface.driverData;
2034 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2049 x1 += surface.offset.x;
2050 y1 += surface.offset.y;
2051 x2 += surface.offset.x;
2052 y2 += surface.offset.y;
2056 glColor4fv(oglSurface.foreground);
2058 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2061 glTexCoord2f(0.5f, 0);
2062 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2063 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2064 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2073 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2074 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2080 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2082 OGLSurface oglSurface = surface.driverData;
2083 x1 += surface.offset.x;
2084 y1 += surface.offset.y;
2085 x2 += surface.offset.x;
2086 y2 += surface.offset.y;
2088 //Logf("Rectangle\n");
2090 glColor4fv(oglSurface.foreground);
2091 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2096 glTexCoord2f(0.5f, 0);
2097 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2098 glTexCoord2f(y2-y1 + 0.5f, 0);
2099 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2101 glTexCoord2f(0.5f, 0);
2102 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2103 glTexCoord2f(x2 - x1 + 0.5f, 0);
2104 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2106 glTexCoord2f(0.5f, 0);
2107 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2108 glTexCoord2f(y1 - y2 + 0.5f, 0);
2109 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2111 glTexCoord2f(0.5f, 0);
2112 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2113 glTexCoord2f(x1 - x2 + 0.5f, 0);
2114 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2119 glBegin(GL_LINE_LOOP);
2126 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2127 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2128 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2129 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2134 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2136 OGLSurface oglSurface = surface.driverData;
2139 glColor4fv(oglSurface.background);
2143 glVertex2f(x1+surface.offset.x, y1+surface.offset.y);
2144 glVertex2f(x1+surface.offset.x, y2+surface.offset.y+1);
2145 glVertex2f(x2+surface.offset.x+1, y2+surface.offset.y+1);
2146 glVertex2f(x2+surface.offset.x+1, y1+surface.offset.y);
2149 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2150 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2153 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2154 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2158 void Clear(Display display, Surface surface, ClearType type)
2160 OGLDisplay oglDisplay = display.driverData;
2161 OGLSurface oglSurface = surface.driverData;
2164 if(type != depthBuffer)
2165 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2166 if(type != colorBuffer && !oglDisplay.depthWrite)
2168 glDepthMask((byte)bool::true);
2170 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2171 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2172 if(type != colorBuffer && !oglDisplay.depthWrite)
2174 glDepthMask((byte)bool::false);
2178 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2183 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2185 OGLSurface oglSurface = surface.driverData;
2187 if(!oglSurface.writingText)
2189 // glTranslatef(-0.375f, -0.375f, 0.0f);
2190 GLSetupTexturing(true);
2191 glColor4fv(oglSurface.bitmapMult);
2193 else if(oglSurface.xOffset)
2194 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2196 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2197 glBegin(GLIMTKMode::quads);
2201 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2202 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2203 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2204 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2205 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2206 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2207 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2208 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2213 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2214 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2215 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2216 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2217 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2218 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2219 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2220 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2223 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2224 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2225 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2226 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2227 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2228 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2229 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2230 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2234 if(!oglSurface.writingText)
2236 GLSetupTexturing(false);
2238 //glTranslate(0.375, 0.375, 0.0);
2240 else if(oglSurface.xOffset)
2241 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2244 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2246 OGLSurface oglSurface = surface.driverData;
2248 //glTranslate(-0.375, -0.375, 0.0);
2250 GLSetupTexturing(true);
2251 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2253 glColor4fv(oglSurface.bitmapMult);
2255 glBegin(GLIMTKMode::quads);
2259 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2260 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2262 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2263 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2265 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2266 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2268 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2269 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2273 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2274 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2276 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2277 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2279 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2280 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2282 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2283 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2288 GLSetupTexturing(false);
2290 //glTranslate(0.375, 0.375, 0.0);
2293 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2295 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2298 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2300 #if !defined(EM_MODE)
2301 float s2dw,s2dh,d2sw,d2sh;
2302 //bool flipX = false, flipY = false;
2304 //Logf("StretchDI\n");
2306 if(Sgn(w) != Sgn(sw))
2312 if(Sgn(h) != Sgn(sh))
2324 //Clip against the edges of the source
2327 dx+=(int)((0-sx) * s2dw);
2328 w-=(int)((0-sx) * s2dw);
2334 dy+=(int)((0-sy) * s2dh);
2335 h-=(int)((0-sy) * s2dh);
2340 if(sx+sw>bitmap.width-1)
2342 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2343 sw-=sx+sw-(bitmap.width-1)-1;
2345 if(sy+sh>(bitmap.height-1))
2347 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2348 sh-=sy+sh-(bitmap.height-1)-1;
2350 //Clip against the edges of the surfaceination
2351 if(dx<surface.box.left)
2354 sx+=(int)((surface.box.left-dx)*d2sw);
2355 sw-=(int)((surface.box.left-dx)*d2sw);
2356 w-=surface.box.left-dx;
2357 dx=surface.box.left;
2359 if(dy<surface.box.top)
2361 sy+=(int)((surface.box.top-dy)*d2sh);
2362 sh-=(int)((surface.box.top-dy)*d2sh);
2363 h-=surface.box.top-dy;
2366 if(dx+w>surface.box.right)
2368 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2369 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2370 w-=dx+w-surface.box.right-1;
2372 if(dy+h>surface.box.bottom)
2374 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2375 h-=dy+h-surface.box.bottom-1;
2377 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2379 dx += surface.offset.x;
2380 dy += surface.offset.y;
2382 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2384 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2385 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2386 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2387 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2388 #if !defined(SHADERS)
2389 glRasterPos2d(dx,dy);
2390 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2391 glPixelZoom(s2dw, -s2dh);
2392 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2394 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2395 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2396 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2397 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2402 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2404 #if !defined(EM_MODE)
2407 //Clip against the edges of the source
2420 if(sx+w>bitmap.width-1)
2421 w-=sx+w-(bitmap.width-1)-1;
2422 if(sy+h>bitmap.height-1)
2423 h-=sy+h-(bitmap.height-1)-1;
2424 //Clip against the edges of the surfaceination
2425 if(dx<surface.box.left)
2428 sx+=surface.box.left-dx;
2429 w-=surface.box.left-dx;
2430 dx=surface.box.left;
2432 if(dy<surface.box.top)
2434 sy+=surface.box.top-dy;
2435 h-=surface.box.top-dy;
2438 if(dx+w>surface.box.right)
2440 //if(flip) sx+=dx+w-surface.box.right-1;
2441 w-=dx+w-surface.box.right-1;
2443 if(dy+h>surface.box.bottom)
2444 h-=dy+h-surface.box.bottom-1;
2448 dx += surface.offset.x;
2449 dy += surface.offset.y;
2451 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2453 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2454 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2455 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2456 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2457 #if !defined(SHADERS)
2458 glRasterPos2d(dx,dy);
2460 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2462 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2463 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2464 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2465 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2470 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2472 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2475 void UnloadFont(DisplaySystem displaySystem, Font font)
2477 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2480 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
2483 OGLSystem oglSystem = displaySystem.driverData;
2484 oglSystem.loadingFont = true;
2485 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
2489 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
2491 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
2494 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
2496 OGLSurface oglSurface = surface.driverData;
2497 OGLSystem oglSystem = display.displaySystem.driverData;
2498 oglSystem.loadingFont = true;
2500 //glTranslated(-0.375, -0.375, 0.0);
2504 if(surface.textOpacity)
2507 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
2508 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2511 oglSurface.writingText = true;
2513 GLSetupTexturing(true);
2515 if(surface.outline.size)
2517 ColorAlpha outlineColor = surface.outline.color;
2518 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2519 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2520 //glEnable(GL_BLEND);
2522 oglSurface.writingOutline = true;
2523 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
2524 oglSurface.writingOutline = false;
2526 glColor4fv(oglSurface.foreground);
2528 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
2529 oglSurface.writingText = false;
2530 oglSystem.loadingFont = false;
2532 GLSetupTexturing(false);
2534 //glTranslated(0.375, 0.375, 0.0);
2537 void TextFont(Display display, Surface surface, Font font)
2539 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2542 void TextOpacity(Display display, Surface surface, bool opaque)
2544 OGLSurface oglSurface = surface.driverData;
2545 oglSurface.opaqueText = opaque;
2548 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
2550 OGLSurface oglSurface = surface.driverData;
2551 OGLSystem oglSystem = display.displaySystem.driverData;
2552 oglSystem.loadingFont = true;
2553 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height);
2554 oglSystem.loadingFont = false;
2557 void DrawingChar(Display display, Surface surface, char character)
2562 void LineStipple(Display display, Surface surface, uint32 stipple)
2564 //Logf("Stipple\n");
2568 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2569 stippleEnabled = true;
2570 glesLineStipple(1, (uint16)stipple);
2572 glLineStipple(1, (uint16)stipple);
2573 glEnable(GL_LINE_STIPPLE);
2578 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2579 stippleEnabled = false;
2580 glMatrixMode(GL_TEXTURE);
2582 glMatrixMode(MatrixMode::projection);
2583 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2585 glDisable(GL_LINE_STIPPLE);
2589 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2590 void SetRenderState(Display display, RenderState state, uint value)
2592 OGLDisplay oglDisplay = display.driverData;
2593 //Logf("RenderState\n");
2599 glEnable(GL_MULTISAMPLE_ARB);
2601 glDisable(GL_MULTISAMPLE_ARB);
2605 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2609 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2612 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2613 oglDisplay.depthWrite = (bool)value;
2617 #if !defined(SHADERS)
2618 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2619 glFogfv(GL_FOG_COLOR, (float *)&color);
2624 #if !defined(SHADERS)
2625 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2629 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2633 #if defined(SHADERS)
2634 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2635 #elif !defined(EM_MODE)
2636 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2637 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2643 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2648 #if defined(__WIN32__)
2649 wglSwapIntervalEXT(value ? 1 : 0);
2656 void SetLight(Display display, int id, Light light)
2658 #if defined(SHADERS)
2659 shader_setLight(display, id, light);
2660 #elif !defined(EM_MODE)
2661 //Logf("SetLight\n");
2665 Object lightObject = light.lightObject;
2666 float position[4] = { 0, 0, 0, 0 };
2667 float color[4] = { 0, 0, 0, 1 };
2669 glEnable(GL_LIGHT0 + id);
2671 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
2672 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
2673 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
2676 if(!light.multiplier) light.multiplier = 1.0f;
2678 color[0] = light.diffuse.r * light.multiplier;
2679 color[1] = light.diffuse.g * light.multiplier;
2680 color[2] = light.diffuse.b * light.multiplier;
2681 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2683 color[0] = light.ambient.r * light.multiplier;
2684 color[1] = light.ambient.g * light.multiplier;
2685 color[2] = light.ambient.b * light.multiplier;
2686 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2687 color[0] = light.specular.r * light.multiplier;
2688 color[1] = light.specular.g * light.multiplier;
2689 color[2] = light.specular.b * light.multiplier;
2690 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2694 Vector3D positionVector;
2695 if(light.flags.spot)
2697 if(lightObject.flags.root || !lightObject.parent)
2699 positionVector = lightObject.transform.position;
2700 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2704 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2705 if(display.display3D.camera)
2706 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2712 if(!light.direction.x && !light.direction.y && !light.direction.z)
2714 Vector3Df vector { 0,0,-1 };
2716 mat.RotationQuaternion(light.orientation);
2717 positionVector.MultMatrixf(vector, mat);
2721 positionVector = light.direction;
2726 position[0] = (float)positionVector.x;
2727 position[1] = (float)positionVector.y;
2728 position[2] = (float)positionVector.z;
2730 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2733 // Display Light Position
2734 glDisable(GL_LIGHTING);
2735 glDisable(GL_DEPTH_TEST);
2739 glVertex3fv(position);
2741 glEnable(GL_DEPTH_TEST);
2742 glEnable(GL_LIGHTING);
2746 if(lightObject.flags.root || !lightObject.parent)
2748 positionVector = light.target.transform.position;
2749 positionVector.Subtract(positionVector, display.camera.cPosition);
2753 positionVector.MultMatrix(light.target.transform.position,
2754 lightObject.light.target.parent.matrix);
2755 positionVector.Subtract(positionVector, display.camera.cPosition);
2758 position[0] = positionVector.x;
2759 position[1] = positionVector.y;
2760 position[2] = positionVector.z;
2762 glDisable(GL_LIGHTING);
2763 glDisable(GL_DEPTH_TEST);
2767 glVertex3fv(position);
2769 glEnable(GL_DEPTH_TEST);
2770 glEnable(GL_LIGHTING);
2773 if(light.flags.attenuation)
2775 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2776 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2777 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2780 if(light.flags.spot)
2783 #define MAXLIGHT 0.9
2784 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2785 // Figure out exponent out of the hot spot
2786 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2788 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2789 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2790 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2795 Vector3Df vector { 0,0,-1 };
2796 Vector3Df direction;
2799 mat.RotationQuaternion(light.orientation);
2800 direction.MultMatrix(vector, mat);
2802 position[0] = direction.x;
2803 position[1] = direction.y;
2804 position[2] = direction.z;
2806 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2810 glDisable(GL_LIGHT0 + id);
2814 void SetCamera(Display display, Surface surface, Camera camera)
2816 OGLDisplay oglDisplay = display.driverData;
2817 //Logf("SetCamera\n");
2821 int left = surface.box.left + surface.offset.x;
2822 int top = surface.box.top + surface.offset.y;
2823 int right = surface.box.right + surface.offset.x;
2824 int bottom = surface.box.bottom + surface.offset.y;
2825 float origX = surface.offset.x + camera.origin.x;
2826 float origY = surface.offset.y + camera.origin.y;
2828 int y = display.height - bottom - 1;
2829 int w = right - left + 1;
2830 int h = bottom - top + 1;
2833 glViewport(x, y, w, h);
2835 // *** Projection Matrix ***
2836 glMatrixMode(MatrixMode::projection);
2837 if(!display.display3D.camera)
2840 if(display.display3D.collectingHits)
2842 float pickX = display.display3D.pickX + surface.offset.x;
2843 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
2847 w / display.display3D.pickWidth, 0, 0, 0,
2848 0, h / display.display3D.pickHeight, 0, 0,
2850 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
2851 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
2854 glLoadMatrixd(pickMatrix.array);
2859 (left - origX) * camera.zMin / camera.focalX,
2860 (right - origX) * camera.zMin / camera.focalX,
2861 (bottom - origY) * camera.zMin / camera.focalY,
2862 (top - origY) * camera.zMin / camera.focalY,
2863 camera.zMin, camera.zMax);
2865 glDisable(GL_BLEND);
2867 // *** Z Inverted Identity Matrix ***
2868 glMatrixMode(MatrixMode::modelView);
2869 if(!display.display3D.camera)
2874 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
2876 // *** View Matrix ***
2877 glMultMatrixd(camera.viewMatrix.array);
2882 glEnable(GL_DEPTH_TEST);
2884 GLSetupLighting(true);
2885 #if !defined(EM_MODE) && !defined(SHADERS)
2886 glShadeModel(GL_SMOOTH);
2888 glDepthMask((byte)bool::true);
2889 oglDisplay.depthWrite = true;
2891 glEnable(GL_MULTISAMPLE_ARB);
2893 else if(display.display3D.camera)
2895 oglDisplay.depthWrite = false;
2896 glViewport(0,0,display.width,display.height);
2898 glDisable(GL_CULL_FACE);
2899 glDisable(GL_DEPTH_TEST);
2901 GLSetupTexturing(false);
2902 GLSetupLighting(false);
2903 #if !defined(SHADERS) && !defined(EM_MODE)
2905 glShadeModel(GL_FLAT);
2908 glDisable(GL_MULTISAMPLE_ARB);
2910 // *** Restore 2D MODELVIEW Matrix ***
2913 // *** Restore 2D PROJECTION Matrix ***
2914 glMatrixMode(MatrixMode::projection);
2920 void ApplyMaterial(Display display, Material material, Mesh mesh)
2922 //Logf("ApplyMaterial\n");
2925 if(material.flags.doubleSided)
2927 #if !defined(EM_MODE) && !defined(SHADERS)
2928 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
2930 glDisable(GL_CULL_FACE);
2934 #if !defined(EM_MODE) && !defined(SHADERS)
2935 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
2937 glEnable(GL_CULL_FACE);
2940 #if !defined(SHADERS)
2942 if(material.flags.noFog)
2949 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
2951 Bitmap map = material.baseMap;
2952 GLSetupTexturing(true);
2953 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
2955 glMatrixMode(GL_TEXTURE);
2957 if(material.uScale && material.vScale)
2958 glScalef(material.uScale, material.vScale, 1);
2959 glMatrixMode(MatrixMode::modelView);
2961 if(material.flags.tile)
2963 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2964 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2968 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2969 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2973 GLSetupTexturing(false);
2975 #if defined(SHADERS)
2976 shader_setMaterial(material, mesh.flags.colors);
2977 #elif defined(EM_MODE)
2978 glimtkColor4f(material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity);
2980 if(mesh.flags.colors)
2982 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
2983 glEnable(GL_COLOR_MATERIAL);
2987 glDisable(GL_COLOR_MATERIAL);
2989 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
2990 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
2993 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
2994 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
2998 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
2999 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3002 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3003 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3006 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3010 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3012 OGLMesh oglMesh = mesh.data;
3015 if(!mesh.flags.vertices)
3017 oglMesh.vertices.free();
3018 delete mesh.vertices;
3020 if(!mesh.flags.normals)
3022 oglMesh.normals.free();
3023 delete mesh.normals;
3025 if(!mesh.flags.texCoords1)
3027 oglMesh.texCoords.free();
3028 delete mesh.texCoords;
3030 if(!mesh.flags.texCoords2)
3032 oglMesh.texCoords2.free();
3033 // delete mesh.texCoords2;
3035 if(!mesh.flags.colors)
3037 oglMesh.colors.free();
3048 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3050 bool result = false;
3053 mesh.data = OGLMesh { };
3056 if(mesh.nVertices == nVertices)
3058 // Same number of vertices, adding features (Leaves the other features pointers alone)
3059 if(mesh.flags != flags)
3061 if(!mesh.flags.vertices && flags.vertices)
3063 if(flags.doubleVertices)
3065 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3068 mesh.vertices = new Vector3Df[nVertices];
3070 if(!mesh.flags.normals && flags.normals)
3072 if(flags.doubleNormals)
3074 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3077 mesh.normals = new Vector3Df[nVertices];
3079 if(!mesh.flags.texCoords1 && flags.texCoords1)
3081 mesh.texCoords = new Pointf[nVertices];
3083 if(!mesh.flags.colors && flags.colors)
3085 mesh.colors = new ColorRGBAf[nVertices];
3091 // New number of vertices, reallocate all current and new features
3092 flags |= mesh.flags;
3095 if(flags.doubleVertices)
3097 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3100 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3104 if(flags.doubleNormals)
3106 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3109 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3111 if(flags.texCoords1)
3113 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3117 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3125 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3127 OGLMesh oglMesh = mesh.data;
3128 if(!flags) flags = mesh.flags;
3133 oglMesh.vertices.upload(
3134 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3137 oglMesh.normals.upload(
3138 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3140 if(flags.texCoords1)
3141 oglMesh.texCoords.upload(
3142 mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3145 oglMesh.colors.upload(
3146 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3150 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3157 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3161 oglIndices.buffer.free();
3162 delete oglIndices.indices;
3167 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3169 OGLIndices oglIndices = OGLIndices { };
3172 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3173 oglIndices.nIndices = nIndices;
3178 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3185 if(!oglIndices.buffer.buffer)
3186 glGenBuffers(1, &oglIndices.buffer.buffer);
3187 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3188 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3189 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3193 oglIndices.buffer.upload(
3194 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3195 oglIndices.indices); //GL_STATIC_DRAW_ARB);
3199 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3202 return oglIndices.indices;
3205 void SelectMesh(Display display, Mesh mesh)
3207 //Logf("SelectMesh\n");
3209 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
3211 #if defined(__WIN32__)
3212 if(glUnlockArraysEXT)
3214 if(!vboAvailable && display.display3D.mesh)
3215 glUnlockArraysEXT();
3220 OGLMesh oglMesh = mesh.data;
3222 // *** Vertex Stream ***
3223 glEnableClientState(GL_VERTEX_ARRAY);
3224 if(!display.display3D.collectingHits && oglMesh)
3226 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3228 // *** Normals Stream ***
3229 if(mesh.normals || mesh.flags.normals)
3231 glEnableClientState(GL_NORMAL_ARRAY);
3232 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3235 glDisableClientState(GL_NORMAL_ARRAY);
3237 // *** Texture Coordinates Stream ***
3238 if(mesh.texCoords || mesh.flags.texCoords1)
3240 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3241 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3244 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3246 // *** Color Stream ***
3247 if(mesh.colors || mesh.flags.colors)
3249 glEnableClientState(GL_COLOR_ARRAY);
3250 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3253 glDisableClientState(GL_COLOR_ARRAY);
3257 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3258 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3260 glEnableClientState(GL_NORMAL_ARRAY);
3261 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3264 glDisableClientState(GL_NORMAL_ARRAY);
3265 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3267 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3268 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3271 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3272 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3274 glEnableClientState(GL_COLOR_ARRAY);
3275 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3278 glDisableClientState(GL_COLOR_ARRAY);
3281 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
3283 #if defined(__WIN32__)
3287 glLockArraysEXT(0, mesh.nVertices);
3293 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3295 //Logf("DrawPrimitives\n");
3297 if(primitive->type.vertexRange)
3298 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3301 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3302 // HACK TO SPEED THINGS UP...
3304 /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3305 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3308 glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
3311 OGLIndices oglIndices = primitive->data;
3312 MeshFeatures flags = mesh.flags;
3313 for(c = 0; c<primitive->nIndices; c++)
3315 uint16 index = ((uint16 *) oglIndices.indices)[c];
3316 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3317 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3318 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3319 glVertex3fv((float *)&mesh.vertices[index]);
3328 OGLIndices oglIndices = primitive->data;
3329 GLEAB eab = ((!display.display3D.collectingHits && oglIndices) ? oglIndices.buffer : noEAB);
3331 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3332 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3333 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3334 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3339 void PushMatrix(Display display)
3344 void PopMatrix(Display display, bool setMatrix)
3349 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3351 Matrix matrix = transMatrix;
3352 Camera camera = useCamera ? display.display3D.camera : null;
3357 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3362 matrix.m[3][0] - camera.cPosition.x,
3363 matrix.m[3][1] - camera.cPosition.y,
3364 matrix.m[3][2] - camera.cPosition.z);
3376 glMultMatrixd(matrix.array);
3381 public void UseSingleGLContext(bool useSingle)
3383 useSingleGLContext = useSingle;
3386 default dllexport void *
3387 #if defined(__WIN32__)
3388 __attribute__((stdcall))
3390 IS_GLGetContext(DisplaySystem displaySystem)
3394 #if defined(__WIN32__)
3395 OGLSystem system = displaySystem.driverData;
3397 #elif defined(__ANDROID__) || defined(__ODROID__)
3399 #elif defined(__EMSCRIPTEN__)
3401 OGLSystem system = displaySystem.driverData;
3402 return system.glContext;