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(__ODROID__) && !defined(__EMSCRIPTEN__)
55 #define property _property
59 #define Window X11Window
60 #define Cursor X11Cursor
62 #define Display X11Display
64 #define KeyCode X11KeyCode
65 #define Picture X11Picture
66 #define Glyph X11Glyph
70 #include <X11/Xutil.h>
72 #include <X11/extensions/XShm.h>
75 #include <X11/extensions/Xrender.h>
76 #include <X11/extensions/shape.h>
95 #if defined(__APPLE__)
96 #include <OpenGl/gl.h>
99 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
101 #if defined(__WIN32__)
102 //#define WIN32_LEAN_AND_MEAN
104 #define _WIN32_WINNT 0x0502
105 #define String Sting_
110 #if defined(__ANDROID__) || defined(__ODROID__)
113 #define property _property
116 #define Window X11Window
117 #define Cursor X11Cursor
119 #define Display X11Display
121 #define KeyCode X11KeyCode
122 #define Picture X11Picture
140 #elif defined(__EMSCRIPTEN__)
142 #define property _property
147 //#include <GLES/gl.h>
148 //#include <EGL/egl.h>
150 //#include <GLES2/gl.h>
151 //#include <EGL/egl.h>
153 //#include <GLES2/gl2.h>
155 #include <emscripten/emscripten.h>
164 #if defined(__ODROID__) && !defined(ES1_1)
168 #if defined(__EMSCRIPTEN__)
177 #if defined(__unix__) || defined(__APPLE__)
179 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
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(__ODROID__) && !defined(__EMSCRIPTEN__)
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(__ODROID__) && !defined(__EMSCRIPTEN__)
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(__ODROID__) && !defined(__EMSCRIPTEN__)
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(__ODROID__) || defined(__EMSCRIPTEN__)
691 glXMakeCurrent(xGlobalDisplay, None, null);
697 bool Lock(Display display)
699 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
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(__ODROID__) || defined(__EMSCRIPTEN__)
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 static bool ::initialDisplaySetup(Display display)
1022 loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1024 glEnableClientState(GL_VERTEX_ARRAY);
1026 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1027 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1029 #if defined(__WIN32__)
1030 if(glBlendFuncSeparate)
1031 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1033 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1035 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1039 glMatrixMode(MatrixMode::modelView);
1040 glLoadIdentity(); // For setting up GLES stack
1041 glScaled(1.0, 1.0, -1.0);
1042 // glTranslatef(0.375f, 0.375f, 0.0f);
1043 // glTranslatef(-0.625f, -0.625f, 0.0f);
1044 glMatrixMode(MatrixMode::projection);
1045 #if !defined(EM_MODE) && !defined(SHADERS)
1046 glShadeModel(GL_FLAT);
1048 // #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1050 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1052 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1053 glFogi(GL_FOG_MODE, GL_EXP);
1054 glFogf(GL_FOG_DENSITY, 0);
1055 glEnable(GL_NORMALIZE);
1057 glDepthFunc(GL_LESS);
1059 glDisable(GL_MULTISAMPLE_ARB);
1060 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1061 display.ambient = Color { 50,50,50 };
1066 bool CreateDisplay(Display display)
1068 bool result = false;
1069 OGLDisplay oglDisplay = display.driverData;
1070 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
1071 OGLSystem oglSystem = display.displaySystem.driverData;
1075 oglDisplay = display.driverData = OGLDisplay { };
1076 //printf("Inside CreateDisplay\n");
1078 #if defined(__WIN32__) || defined(USEPBUFFER)
1079 if(!display.alphaBlend)
1082 #if defined(__WIN32__)
1083 oglDisplay.hdc = GetDC(display.window);
1084 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1085 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1087 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1088 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1092 ReleaseDC(display.window, oglDisplay.hdc);
1093 #elif defined(__unix__) || defined(__APPLE__)
1094 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1096 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1098 #if defined(__APPLE__)
1099 XVisualInfo template = { 0 };
1100 XWindowAttributes winAttr;
1102 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1103 template.visualid = XVisualIDFromVisual(winAttr.visual);
1104 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1106 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1107 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1108 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1109 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1111 // visualInfo = oglSystem.visualInfo;
1116 //printf("visualInfo is not null\n");
1117 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1118 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1119 //XFree(visualInfo);
1122 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1123 if(oglDisplay.glContext)
1125 //printf("CreateDisplay Got a Context\n");
1126 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1132 #if defined(__WIN32__) || defined(USEPBUFFER)
1136 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1141 ogl_LoadFunctions();
1142 CheckExtensions(oglSystem);
1143 vboAvailable = glBindBuffer != null;
1145 initialDisplaySetup(display);
1148 if(!useSingleGLContext)
1150 #if defined(__WIN32__)
1151 wglMakeCurrent(null, null);
1152 #elif defined(__unix__) || defined(__APPLE__)
1153 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1156 glXMakeCurrent(xGlobalDisplay, None, null);
1162 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1170 bool DisplaySize(Display display, int width, int height)
1172 OGLDisplay oglDisplay = display.driverData;
1174 bool result = false;
1176 //printf("Inside DisplaySize\n");
1177 #if defined(__WIN32__) || defined(USEPBUFFER)
1178 OGLSystem oglSystem = display.displaySystem.driverData;
1179 if(display.alphaBlend)
1181 #if defined(__WIN32__)
1182 const int attributes[]=
1184 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1185 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1187 int pixelFormat = 0;
1188 if(wglChoosePixelFormatARB)
1192 float fAttributes[] = {0,0};
1195 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1196 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1197 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1198 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1199 WGL_COLOR_BITS_ARB,24,
1200 WGL_ALPHA_BITS_ARB,8,
1201 WGL_DEPTH_BITS_ARB,16,
1202 WGL_STENCIL_BITS_ARB,0,
1203 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1204 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1205 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1209 //Log("Found wglChoosePixelFormatARB\n");
1211 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1212 if(!valid || !numFormats)
1214 //Log("Can't find 4x multi sampling\n");
1215 iAttributes[19] = 2;
1216 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1217 if(!valid || !numFormats)
1219 // Log("Can't find 2x multi sampling\n");
1220 iAttributes[16] = 0;
1221 iAttributes[17] = 0;
1222 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1223 if(!valid || !numFormats)
1227 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1228 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1229 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1230 WGL_COLOR_BITS_ARB,24,
1231 WGL_ALPHA_BITS_ARB,8,
1232 WGL_DEPTH_BITS_ARB,16,
1235 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1239 if(valid && numFormats)
1241 wglMakeCurrent(null, null);
1245 wglMakeCurrent( null, null );
1246 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1247 if(oglDisplay.hdc && oglDisplay.pBuffer)
1248 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1250 wglDestroyPbufferARB(oglDisplay.pBuffer);
1252 if(!useSingleGLContext)
1253 wglMakeCurrent( null, null );
1256 wglDeleteContext(oglDisplay.glrc);
1258 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1259 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1260 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1263 HDC hdc = GetDC(display.window);
1265 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1266 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1268 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1269 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1271 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1273 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1277 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1278 oglDisplay.memDC = CreateCompatibleDC(hdc);
1279 SetMapMode(oglDisplay.memDC, MM_TEXT);
1280 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1281 info->bmiHeader.biPlanes = 1;
1282 info->bmiHeader.biCompression = BI_RGB;
1283 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1284 info->bmiHeader.biWidth = width;
1285 info->bmiHeader.biHeight = height;
1286 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1289 SelectObject(oglDisplay.memDC, newBitmap);
1290 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1293 PIXELFORMATDESCRIPTOR pfd = { 0 };
1294 pfd.nSize = (short)sizeof(pfd);
1296 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1297 pfd.iPixelType = PFD_TYPE_RGBA;
1298 pfd.cColorBits = 32;
1299 //pfd.cAlphaBits = 8;
1300 pfd.cDepthBits = 24;
1301 pfd.iLayerType = PFD_MAIN_PLANE;
1303 oglDisplay.hdc = oglDisplay.memDC;
1305 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1306 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1307 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1309 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1310 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1311 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1316 const int imageSize = width * height * 4;
1318 glGenBuffersARB(2, oglDisplay.imageBuffers);
1320 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1321 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1322 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1323 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1326 oglDisplay.memBitmap = newBitmap;
1327 oglDisplay.stride = width;
1333 ReleaseDC(display.window, hdc);
1335 #elif defined(__unix__) || defined(__APPLE__)
1336 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1341 GLX_DOUBLEBUFFER, True,
1347 GLX_STENCIL_SIZE, 1,
1348 //GLX_DEPTH_SIZE, 24,
1349 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1350 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1356 GLX_PBUFFER_WIDTH, width,
1357 GLX_PBUFFER_HEIGHT, height,
1358 GLX_LARGEST_PBUFFER, False,
1362 // choose a pixel format that meets our minimum requirements
1365 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1368 if(oglDisplay.pixmap)
1370 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1371 oglDisplay.pixmap = None;
1373 if(oglDisplay.shapePixmap)
1375 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1376 oglDisplay.shapePixmap = None;
1379 // Free Shared Memory Pixmap
1380 if(oglDisplay.image)
1382 if(oglDisplay.shminfoShape.shmid != -1)
1384 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1385 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1386 shmdt(oglDisplay.shminfo.shmaddr);
1387 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1389 XDestroyImage(oglDisplay.image);
1390 oglDisplay.image = None;
1392 if(oglDisplay.shapeImage)
1394 if(oglDisplay.shminfoShape.shmid != -1)
1396 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1397 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1398 shmdt(oglDisplay.shminfoShape.shmaddr);
1399 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1401 XDestroyImage(oglDisplay.shapeImage);
1402 oglDisplay.shapeImage = None;
1405 if(oglDisplay.windowPicture)
1406 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1407 if(oglDisplay.pixmapPicture)
1408 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1410 if(oglDisplay.pixmap)
1411 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1413 if(oglDisplay.glContext)
1414 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1415 if(oglDisplay.pBuffer)
1416 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1418 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1419 if(oglDisplay.pBuffer)
1421 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1422 if(oglDisplay.glContext)
1424 glXMakeCurrent(xGlobalDisplay, None, null);
1425 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1427 // Initialize Shared Memory Pixmap
1428 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1429 ZPixmap, null, &oglDisplay.shminfo, width, height);
1430 if(oglDisplay.image)
1432 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1433 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1434 if(oglDisplay.shminfo.shmid != -1)
1436 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1437 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1439 oglDisplay.shminfo.readOnly = False;
1440 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1442 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1443 &oglDisplay.shminfo, width, height, 32);
1445 // Initialize Shared Memory Shape Pixmap
1446 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1447 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1448 if(oglDisplay.shapeImage)
1450 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1451 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1452 if(oglDisplay.shminfoShape.shmid != -1)
1454 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1455 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1457 oglDisplay.shminfoShape.readOnly = False;
1458 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1460 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1461 &oglDisplay.shminfoShape, width, height, 1);
1462 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1465 XRenderPictureAttributes attributes = { 0 };
1466 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1467 #if !defined(__APPLE__)
1468 attributes.repeat = RepeatNormal;
1470 attributes.repeat = 1;
1472 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1473 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1474 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1475 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1478 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1479 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1496 CreateDisplay(display);
1497 #if defined(__WIN32__)
1498 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1499 #elif defined(__unix__) || defined(__APPLE__)
1500 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1504 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1512 if(display.alphaBlend && result)
1513 initialDisplaySetup(display);
1515 if(!result && display.alphaBlend)
1517 printf("Alpha blending windows not supported on this display\n");
1524 glViewport(0,0,width,height);
1525 glMatrixMode(MatrixMode::projection);
1527 glOrtho(0,width,height,0,0.0,1.0);
1528 displayWidth = display.width = width;
1529 displayHeight = display.height = height;
1531 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1533 oglDisplay.flipBufW = width;
1534 oglDisplay.flipBufH = height;
1538 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1541 if(oglDisplay.flippingBuffer || !width || !height)
1547 void DisplayPosition(Display display, int x, int y)
1549 OGLDisplay oglDisplay = display.driverData;
1555 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1559 void RestorePalette(Display display)
1563 void StartUpdate(Display display)
1567 void EndUpdate(Display display)
1571 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1575 void Update(Display display, Box updateBox)
1577 #if defined(__WIN32__) || defined(USEPBUFFER)
1578 OGLDisplay oglDisplay = display.driverData;
1580 //Logf("DisplayScreen\n");
1582 #if !defined(__ANDROID__)
1587 #if defined(__WIN32__) || defined(USEPBUFFER)
1588 if(display.alphaBlend)
1590 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1591 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1592 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1593 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1594 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1597 #if defined(__WIN32__)
1599 POINT point = { oglDisplay.x, oglDisplay.y};
1600 POINT srcPoint = { 0, 0 };
1601 BLENDFUNCTION blend = { 0 };
1603 size.cx = display.width;
1604 size.cy = display.height;
1605 blend.BlendOp = AC_SRC_OVER;
1606 blend.BlendFlags = 0;
1607 blend.SourceConstantAlpha = 255;
1608 blend.AlphaFormat = AC_SRC_ALPHA;
1611 // Process partial images. Mapping the buffer waits for
1612 // outstanding DMA transfers into the buffer to finish.
1613 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1614 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1616 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1617 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1620 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1621 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1624 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1627 // Unmap the image buffers
1628 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1629 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1631 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1632 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1634 // Bind two different buffer objects and start the glReadPixels
1635 // asynchronously. Each call will return directly after
1636 // starting the DMA transfer.
1637 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1638 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1640 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1641 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1645 #elif defined(__unix__) || defined(__APPLE__)
1646 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1648 XTransform transform =
1651 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1652 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1653 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1656 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1657 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1658 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1659 #if !defined(__APPLE__)
1660 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1662 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1664 XFlush(xGlobalDisplay);
1672 #if defined(__WIN32__)
1673 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1674 SwapBuffers(oglDisplay.hdc);
1675 #elif defined(__unix__) || defined(__APPLE__)
1676 #if defined(__ANDROID__) || defined(__ODROID__)
1677 eglSwapBuffers(eglDisplay, eglSurface);
1678 #elif defined(__EMSCRIPTEN__)
1681 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1685 //Logf("Out of DisplayScreen\n");
1688 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1690 if(bitmap.driverData)
1692 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1693 glDeleteTextures(1, &tex);
1694 bitmap.driverData = 0;
1696 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1699 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1701 OGLSystem oglSystem = displaySystem.driverData;
1702 bool result = false;
1704 GLuint glBitmap = 0;
1706 uint w = width, h = height;
1707 if(oglSystem.pow2textures)
1712 w = Min(w, oglSystem.maxTextureSize);
1713 h = Min(h, oglSystem.maxTextureSize);
1715 glGenTextures(1, &glBitmap);
1716 glBindTexture(GL_TEXTURE_2D, glBitmap);
1718 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1720 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1723 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1724 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1726 #if !defined(SHADERS)
1727 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1730 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1732 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1733 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1737 bitmap.driverData = (void *)(uintptr)glBitmap;
1738 bitmap.driver = displaySystem.driver;
1746 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1748 bool result = false;
1749 OGLSystem oglSystem = displaySystem.driverData;
1750 Bitmap convBitmap = bitmap;
1754 convBitmap.Copy(bitmap);
1757 // Pre process the bitmap... First make it 32 bit
1758 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1761 uint w = bitmap.width, h = bitmap.height;
1762 GLuint glBitmap = 0;
1763 if(oglSystem.pow2textures)
1768 w = Min(w, oglSystem.maxTextureSize);
1769 h = Min(h, oglSystem.maxTextureSize);
1773 while(w * 2 < h) w *= 2;
1774 while(h * 2 < w) h *= 2;
1777 // Switch ARGB to RGBA
1778 //if(bitmap.format != pixelFormatRGBA)
1780 for(c=0; c<bitmap.size; c++)
1782 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1784 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1785 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1788 // convBitmap.pixelFormat = pixelFormat888;
1791 glGenTextures(1, &glBitmap);
1794 //int error = glGetError();
1798 glBindTexture(GL_TEXTURE_2D, glBitmap);
1799 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1801 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1802 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1804 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1806 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1807 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1809 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1810 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1811 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1812 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1815 #if !defined(SHADERS)
1816 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1821 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1826 if(bitmap.width != w || bitmap.height != h)
1828 mipMap = Bitmap { };
1829 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1831 Surface mipSurface = mipMap.GetSurface(0,0,null);
1832 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1842 mipMap = convBitmap;
1849 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1850 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1851 //printf("Calling glTexImage2D\n");
1852 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
1853 //printf("width = %d (Should be %d, %d)\n", width, w, h);
1854 if((error = glGetError()))
1856 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
1857 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
1861 if(mipMap != convBitmap)
1866 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
1867 bitmap.driverData = (void *)(uintptr)glBitmap;
1868 bitmap.driver = displaySystem.driver;
1873 FreeBitmap(displaySystem, bitmap);
1874 else if(oglSystem.loadingFont)
1876 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1877 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1878 oglSystem.loadingFont = false;
1884 void ReleaseSurface(Display display, Surface surface)
1886 glDisable(GL_SCISSOR_TEST);
1887 delete surface.driverData;
1888 surface.driverData = null;
1891 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
1896 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
1898 bool result = false;
1899 OGLSurface oglSurface = surface.driverData = OGLSurface { };
1901 //Logf("GetSurface\n");
1905 if(displayWidth != display.width || displayHeight != display.height)
1907 displayWidth = display.width;
1908 displayHeight = display.height;
1910 glViewport(0,0,display.width,display.height);
1912 glOrtho(0,display.width,display.height,0,0.0,1.0);
1915 surface.offset.x = x;
1916 surface.offset.y = y;
1917 surface.unclippedBox = surface.box = clip;
1918 oglSurface.bitmapMult[0] = 1;
1919 oglSurface.bitmapMult[1] = 1;
1920 oglSurface.bitmapMult[2] = 1;
1921 oglSurface.bitmapMult[3] = 1;
1923 glEnable(GL_SCISSOR_TEST);
1926 (display.height) -(y+clip.bottom)-1,
1927 clip.right-clip.left+1,
1928 clip.bottom-clip.top+1);
1934 void Clip(Display display, Surface surface, Box clip)
1943 box.Clip(surface.unclippedBox);
1947 box = surface.box = surface.unclippedBox;
1948 box.left += surface.offset.x;
1949 box.top += surface.offset.y;
1950 box.right+= surface.offset.x;
1951 box.bottom += surface.offset.y;
1954 box.left,display.height - box.bottom - 1,
1955 box.right-box.left+1, box.bottom-box.top+1);
1958 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
1960 bool result = false;
1961 OGLDisplay oglDisplay = display.driverData;
1962 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
1964 if(oglDisplay.flippingBuffer)
1966 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
1969 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
1975 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1976 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
1977 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1978 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1979 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
1982 for(row = 0; row<h; row++)
1983 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
1990 void SetForeground(Display display, Surface surface, ColorAlpha color)
1992 OGLSurface oglSurface = surface.driverData;
1994 //Logf("SetForeground\n");
1996 oglSurface.foreground[0] = color.color.r/255.0f;
1997 oglSurface.foreground[1] = color.color.g/255.0f;
1998 oglSurface.foreground[2] = color.color.b/255.0f;
1999 //oglSurface.foreground[3] = 1.0f;
2000 oglSurface.foreground[3] = color.a/255.0f;
2002 //if(!oglSurface.foreground[3])printf("bug");
2005 void SetBackground(Display display, Surface surface, ColorAlpha color)
2007 OGLSurface oglSurface = surface.driverData;
2009 //Logf("SetBackground\n");
2011 oglSurface.background[0] = color.color.r/255.0f;
2012 oglSurface.background[1] = color.color.g/255.0f;
2013 oglSurface.background[2] = color.color.b/255.0f;
2014 //oglSurface.background[3] = 1.0;
2015 oglSurface.background[3] = color.a/255.0f;
2018 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2020 OGLSurface oglSurface = surface.driverData;
2022 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2023 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2024 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2025 oglSurface.bitmapMult[3] = color.a/255.0f;
2028 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2033 void PutPixel(Display display, Surface surface,int x,int y)
2035 OGLSurface oglSurface = surface.driverData;
2037 //Logf("PutPixel\n");
2039 glColor4fv(oglSurface.foreground);
2041 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2042 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2047 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2049 OGLSurface oglSurface = surface.driverData;
2050 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2065 x1 += surface.offset.x;
2066 y1 += surface.offset.y;
2067 x2 += surface.offset.x;
2068 y2 += surface.offset.y;
2072 glColor4fv(oglSurface.foreground);
2074 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2077 glTexCoord2f(0.5f, 0);
2078 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2079 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2080 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2089 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2090 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2096 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2098 OGLSurface oglSurface = surface.driverData;
2099 x1 += surface.offset.x;
2100 y1 += surface.offset.y;
2101 x2 += surface.offset.x;
2102 y2 += surface.offset.y;
2104 //Logf("Rectangle\n");
2106 glColor4fv(oglSurface.foreground);
2107 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2112 glTexCoord2f(0.5f, 0);
2113 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2114 glTexCoord2f(y2-y1 + 0.5f, 0);
2115 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2117 glTexCoord2f(0.5f, 0);
2118 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2119 glTexCoord2f(x2 - x1 + 0.5f, 0);
2120 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2122 glTexCoord2f(0.5f, 0);
2123 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2124 glTexCoord2f(y1 - y2 + 0.5f, 0);
2125 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2127 glTexCoord2f(0.5f, 0);
2128 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2129 glTexCoord2f(x1 - x2 + 0.5f, 0);
2130 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2135 glBegin(GL_LINE_LOOP);
2142 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2143 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2144 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2145 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2150 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2152 OGLSurface oglSurface = surface.driverData;
2155 glColor4fv(oglSurface.background);
2159 glVertex2f(x1+surface.offset.x, y1+surface.offset.y);
2160 glVertex2f(x1+surface.offset.x, y2+surface.offset.y+1);
2161 glVertex2f(x2+surface.offset.x+1, y2+surface.offset.y+1);
2162 glVertex2f(x2+surface.offset.x+1, y1+surface.offset.y);
2165 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2166 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2169 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2170 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2174 void Clear(Display display, Surface surface, ClearType type)
2176 OGLDisplay oglDisplay = display.driverData;
2177 OGLSurface oglSurface = surface.driverData;
2180 if(type != depthBuffer)
2181 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2182 if(type != colorBuffer && !oglDisplay.depthWrite)
2184 glDepthMask((byte)bool::true);
2186 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2187 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2188 if(type != colorBuffer && !oglDisplay.depthWrite)
2190 glDepthMask((byte)bool::false);
2194 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2199 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2201 OGLSurface oglSurface = surface.driverData;
2203 if(!oglSurface.writingText)
2205 // glTranslatef(-0.375f, -0.375f, 0.0f);
2206 GLSetupTexturing(true);
2207 glColor4fv(oglSurface.bitmapMult);
2209 else if(oglSurface.xOffset)
2210 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2212 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2213 glBegin(GLIMTKMode::quads);
2217 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2218 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2219 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2220 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2221 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2222 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2223 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2224 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2229 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2230 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2231 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2232 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2233 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2234 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2235 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2236 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2239 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2240 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2241 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2242 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2243 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2244 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2245 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2246 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2250 if(!oglSurface.writingText)
2252 GLSetupTexturing(false);
2254 //glTranslate(0.375, 0.375, 0.0);
2256 else if(oglSurface.xOffset)
2257 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2260 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2262 OGLSurface oglSurface = surface.driverData;
2264 //glTranslate(-0.375, -0.375, 0.0);
2266 GLSetupTexturing(true);
2267 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2269 glColor4fv(oglSurface.bitmapMult);
2271 glBegin(GLIMTKMode::quads);
2275 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2276 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2278 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2279 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2281 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2282 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2284 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2285 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2289 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2290 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2292 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2293 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2295 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2296 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2298 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2299 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2304 GLSetupTexturing(false);
2306 //glTranslate(0.375, 0.375, 0.0);
2309 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2311 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2314 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2316 #if !defined(EM_MODE)
2317 float s2dw,s2dh,d2sw,d2sh;
2318 //bool flipX = false, flipY = false;
2320 //Logf("StretchDI\n");
2322 if(Sgn(w) != Sgn(sw))
2328 if(Sgn(h) != Sgn(sh))
2340 //Clip against the edges of the source
2343 dx+=(int)((0-sx) * s2dw);
2344 w-=(int)((0-sx) * s2dw);
2350 dy+=(int)((0-sy) * s2dh);
2351 h-=(int)((0-sy) * s2dh);
2356 if(sx+sw>bitmap.width-1)
2358 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2359 sw-=sx+sw-(bitmap.width-1)-1;
2361 if(sy+sh>(bitmap.height-1))
2363 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2364 sh-=sy+sh-(bitmap.height-1)-1;
2366 //Clip against the edges of the surfaceination
2367 if(dx<surface.box.left)
2370 sx+=(int)((surface.box.left-dx)*d2sw);
2371 sw-=(int)((surface.box.left-dx)*d2sw);
2372 w-=surface.box.left-dx;
2373 dx=surface.box.left;
2375 if(dy<surface.box.top)
2377 sy+=(int)((surface.box.top-dy)*d2sh);
2378 sh-=(int)((surface.box.top-dy)*d2sh);
2379 h-=surface.box.top-dy;
2382 if(dx+w>surface.box.right)
2384 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2385 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2386 w-=dx+w-surface.box.right-1;
2388 if(dy+h>surface.box.bottom)
2390 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2391 h-=dy+h-surface.box.bottom-1;
2393 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2395 dx += surface.offset.x;
2396 dy += surface.offset.y;
2398 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2400 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2401 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2402 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2403 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2404 #if !defined(SHADERS)
2405 glRasterPos2d(dx,dy);
2406 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2407 glPixelZoom(s2dw, -s2dh);
2408 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2410 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2411 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2412 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2413 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2418 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2420 #if !defined(EM_MODE)
2423 //Clip against the edges of the source
2436 if(sx+w>bitmap.width-1)
2437 w-=sx+w-(bitmap.width-1)-1;
2438 if(sy+h>bitmap.height-1)
2439 h-=sy+h-(bitmap.height-1)-1;
2440 //Clip against the edges of the surfaceination
2441 if(dx<surface.box.left)
2444 sx+=surface.box.left-dx;
2445 w-=surface.box.left-dx;
2446 dx=surface.box.left;
2448 if(dy<surface.box.top)
2450 sy+=surface.box.top-dy;
2451 h-=surface.box.top-dy;
2454 if(dx+w>surface.box.right)
2456 //if(flip) sx+=dx+w-surface.box.right-1;
2457 w-=dx+w-surface.box.right-1;
2459 if(dy+h>surface.box.bottom)
2460 h-=dy+h-surface.box.bottom-1;
2464 dx += surface.offset.x;
2465 dy += surface.offset.y;
2467 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2469 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2470 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2471 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2472 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2473 #if !defined(SHADERS)
2474 glRasterPos2d(dx,dy);
2476 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2478 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2479 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2480 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2481 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2486 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2488 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2491 void UnloadFont(DisplaySystem displaySystem, Font font)
2493 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2496 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2499 OGLSystem oglSystem = displaySystem.driverData;
2500 oglSystem.loadingFont = true;
2501 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2505 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2507 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2510 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2512 OGLSurface oglSurface = surface.driverData;
2513 OGLSystem oglSystem = display.displaySystem.driverData;
2514 oglSystem.loadingFont = true;
2516 //glTranslated(-0.375, -0.375, 0.0);
2520 if(surface.textOpacity)
2523 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2525 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2528 oglSurface.writingText = true;
2530 GLSetupTexturing(true);
2532 if(surface.font.outlineSize)
2534 ColorAlpha outlineColor = surface.outlineColor;
2535 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2536 oglSurface.writingOutline = true;
2537 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2538 oglSurface.writingOutline = false;
2540 glColor4fv(oglSurface.foreground);
2542 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2543 oglSurface.writingText = false;
2544 oglSystem.loadingFont = false;
2546 GLSetupTexturing(false);
2548 //glTranslated(0.375, 0.375, 0.0);
2551 void TextFont(Display display, Surface surface, Font font)
2553 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2556 void TextOpacity(Display display, Surface surface, bool opaque)
2558 OGLSurface oglSurface = surface.driverData;
2559 oglSurface.opaqueText = opaque;
2562 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2564 OGLSurface oglSurface = surface.driverData;
2565 OGLSystem oglSystem = display.displaySystem.driverData;
2566 oglSystem.loadingFont = true;
2567 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2568 oglSystem.loadingFont = false;
2571 void DrawingChar(Display display, Surface surface, char character)
2576 void LineStipple(Display display, Surface surface, uint32 stipple)
2578 //Logf("Stipple\n");
2582 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2583 stippleEnabled = true;
2584 glesLineStipple(1, (uint16)stipple);
2586 glLineStipple(1, (uint16)stipple);
2587 glEnable(GL_LINE_STIPPLE);
2592 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2593 stippleEnabled = false;
2594 glMatrixMode(GL_TEXTURE);
2596 glMatrixMode(MatrixMode::projection);
2597 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2599 glDisable(GL_LINE_STIPPLE);
2603 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2604 void SetRenderState(Display display, RenderState state, uint value)
2606 OGLDisplay oglDisplay = display.driverData;
2607 //Logf("RenderState\n");
2613 glEnable(GL_MULTISAMPLE_ARB);
2615 glDisable(GL_MULTISAMPLE_ARB);
2619 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2623 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2626 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2627 oglDisplay.depthWrite = (bool)value;
2631 #if !defined(SHADERS)
2632 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2633 glFogfv(GL_FOG_COLOR, (float *)&color);
2638 #if !defined(SHADERS)
2639 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2643 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2647 #if defined(SHADERS)
2648 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2649 #elif !defined(EM_MODE)
2650 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2651 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2657 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2662 #if defined(__WIN32__)
2663 wglSwapIntervalEXT(value ? 1 : 0);
2670 void SetLight(Display display, int id, Light light)
2672 #if defined(SHADERS)
2673 shader_setLight(display, id, light);
2674 #elif !defined(EM_MODE)
2675 //Logf("SetLight\n");
2679 Object lightObject = light.lightObject;
2680 float position[4] = { 0, 0, 0, 0 };
2681 float color[4] = { 0, 0, 0, 1 };
2683 glEnable(GL_LIGHT0 + id);
2685 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
2686 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
2687 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
2690 if(!light.multiplier) light.multiplier = 1.0f;
2692 color[0] = light.diffuse.r * light.multiplier;
2693 color[1] = light.diffuse.g * light.multiplier;
2694 color[2] = light.diffuse.b * light.multiplier;
2695 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2697 color[0] = light.ambient.r * light.multiplier;
2698 color[1] = light.ambient.g * light.multiplier;
2699 color[2] = light.ambient.b * light.multiplier;
2700 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2701 color[0] = light.specular.r * light.multiplier;
2702 color[1] = light.specular.g * light.multiplier;
2703 color[2] = light.specular.b * light.multiplier;
2704 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2708 Vector3D positionVector;
2709 if(light.flags.spot)
2711 if(lightObject.flags.root || !lightObject.parent)
2713 positionVector = lightObject.transform.position;
2714 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2718 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2719 if(display.display3D.camera)
2720 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2726 if(!light.direction.x && !light.direction.y && !light.direction.z)
2728 Vector3Df vector { 0,0,-1 };
2730 mat.RotationQuaternion(light.orientation);
2731 positionVector.MultMatrixf(vector, mat);
2735 positionVector = light.direction;
2740 position[0] = (float)positionVector.x;
2741 position[1] = (float)positionVector.y;
2742 position[2] = (float)positionVector.z;
2744 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2747 // Display Light Position
2748 glDisable(GL_LIGHTING);
2749 glDisable(GL_DEPTH_TEST);
2753 glVertex3fv(position);
2755 glEnable(GL_DEPTH_TEST);
2756 glEnable(GL_LIGHTING);
2760 if(lightObject.flags.root || !lightObject.parent)
2762 positionVector = light.target.transform.position;
2763 positionVector.Subtract(positionVector, display.camera.cPosition);
2767 positionVector.MultMatrix(light.target.transform.position,
2768 lightObject.light.target.parent.matrix);
2769 positionVector.Subtract(positionVector, display.camera.cPosition);
2772 position[0] = positionVector.x;
2773 position[1] = positionVector.y;
2774 position[2] = positionVector.z;
2776 glDisable(GL_LIGHTING);
2777 glDisable(GL_DEPTH_TEST);
2781 glVertex3fv(position);
2783 glEnable(GL_DEPTH_TEST);
2784 glEnable(GL_LIGHTING);
2787 if(light.flags.attenuation)
2789 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2790 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2791 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2794 if(light.flags.spot)
2797 #define MAXLIGHT 0.9
2798 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2799 // Figure out exponent out of the hot spot
2800 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2802 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2803 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2804 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2809 Vector3Df vector { 0,0,-1 };
2810 Vector3Df direction;
2813 mat.RotationQuaternion(light.orientation);
2814 direction.MultMatrix(vector, mat);
2816 position[0] = direction.x;
2817 position[1] = direction.y;
2818 position[2] = direction.z;
2820 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2824 glDisable(GL_LIGHT0 + id);
2828 void SetCamera(Display display, Surface surface, Camera camera)
2830 OGLDisplay oglDisplay = display.driverData;
2831 //Logf("SetCamera\n");
2833 if(surface && camera)
2835 int left = surface.box.left + surface.offset.x;
2836 int top = surface.box.top + surface.offset.y;
2837 int right = surface.box.right + surface.offset.x;
2838 int bottom = surface.box.bottom + surface.offset.y;
2839 float origX = surface.offset.x + camera.origin.x;
2840 float origY = surface.offset.y + camera.origin.y;
2842 int y = display.height - bottom - 1;
2843 int w = right - left + 1;
2844 int h = bottom - top + 1;
2847 glViewport(x, y, w, h);
2849 // *** Projection Matrix ***
2850 glMatrixMode(MatrixMode::projection);
2851 if(!display.display3D.camera)
2854 if(display.display3D.collectingHits)
2856 float pickX = display.display3D.pickX + surface.offset.x;
2857 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
2861 w / display.display3D.pickWidth, 0, 0, 0,
2862 0, h / display.display3D.pickHeight, 0, 0,
2864 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
2865 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
2868 glLoadMatrixd(pickMatrix.array);
2873 (left - origX) * camera.zMin / camera.focalX,
2874 (right - origX) * camera.zMin / camera.focalX,
2875 (bottom - origY) * camera.zMin / camera.focalY,
2876 (top - origY) * camera.zMin / camera.focalY,
2877 camera.zMin, camera.zMax);
2879 glDisable(GL_BLEND);
2881 // *** Z Inverted Identity Matrix ***
2882 glMatrixMode(MatrixMode::modelView);
2883 if(!display.display3D.camera)
2888 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
2890 // *** View Matrix ***
2891 glMultMatrixd(camera.viewMatrix.array);
2896 glEnable(GL_DEPTH_TEST);
2898 GLSetupLighting(true);
2899 #if !defined(EM_MODE) && !defined(SHADERS)
2900 glShadeModel(GL_SMOOTH);
2902 glDepthMask((byte)bool::true);
2903 oglDisplay.depthWrite = true;
2905 glEnable(GL_MULTISAMPLE_ARB);
2907 else if(surface && display.display3D.camera)
2909 oglDisplay.depthWrite = false;
2910 glViewport(0,0,display.width,display.height);
2912 glDisable(GL_CULL_FACE);
2913 glDisable(GL_DEPTH_TEST);
2915 GLSetupTexturing(false);
2916 GLSetupLighting(false);
2917 #if !defined(SHADERS) && !defined(EM_MODE)
2919 glShadeModel(GL_FLAT);
2922 glDisable(GL_MULTISAMPLE_ARB);
2924 // *** Restore 2D MODELVIEW Matrix ***
2927 // *** Restore 2D PROJECTION Matrix ***
2928 glMatrixMode(MatrixMode::projection);
2934 void ApplyMaterial(Display display, Material material, Mesh mesh)
2936 //Logf("ApplyMaterial\n");
2939 if(material.flags.doubleSided)
2941 #if !defined(EM_MODE) && !defined(SHADERS)
2942 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
2944 glDisable(GL_CULL_FACE);
2948 #if !defined(EM_MODE) && !defined(SHADERS)
2949 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
2951 glEnable(GL_CULL_FACE);
2954 #if !defined(SHADERS)
2956 if(material.flags.noFog)
2963 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
2965 Bitmap map = material.baseMap;
2966 GLSetupTexturing(true);
2967 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
2969 glMatrixMode(GL_TEXTURE);
2971 if(material.uScale && material.vScale)
2972 glScalef(material.uScale, material.vScale, 1);
2973 glMatrixMode(MatrixMode::modelView);
2975 if(material.flags.tile)
2977 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2978 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2982 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2983 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2987 GLSetupTexturing(false);
2989 #if defined(SHADERS)
2990 shader_setMaterial(material, mesh.flags.colors);
2991 #elif defined(EM_MODE)
2992 glimtkColor4f(material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity);
2994 if(mesh.flags.colors)
2996 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
2997 glEnable(GL_COLOR_MATERIAL);
3001 glDisable(GL_COLOR_MATERIAL);
3003 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3004 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3007 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3008 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3012 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3013 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3016 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3017 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3020 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3024 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3026 OGLMesh oglMesh = mesh.data;
3029 if(!mesh.flags.vertices)
3031 oglMesh.vertices.free();
3032 delete mesh.vertices;
3034 if(!mesh.flags.normals)
3036 oglMesh.normals.free();
3037 delete mesh.normals;
3039 if(!mesh.flags.texCoords1)
3041 oglMesh.texCoords.free();
3042 delete mesh.texCoords;
3044 if(!mesh.flags.texCoords2)
3046 oglMesh.texCoords2.free();
3047 // delete mesh.texCoords2;
3049 if(!mesh.flags.colors)
3051 oglMesh.colors.free();
3062 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3064 bool result = false;
3067 mesh.data = OGLMesh { };
3070 if(mesh.nVertices == nVertices)
3072 // Same number of vertices, adding features (Leaves the other features pointers alone)
3073 if(mesh.flags != flags)
3075 if(!mesh.flags.vertices && flags.vertices)
3077 if(flags.doubleVertices)
3079 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3082 mesh.vertices = new Vector3Df[nVertices];
3084 if(!mesh.flags.normals && flags.normals)
3086 if(flags.doubleNormals)
3088 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3091 mesh.normals = new Vector3Df[nVertices];
3093 if(!mesh.flags.texCoords1 && flags.texCoords1)
3095 mesh.texCoords = new Pointf[nVertices];
3097 if(!mesh.flags.colors && flags.colors)
3099 mesh.colors = new ColorRGBAf[nVertices];
3105 // New number of vertices, reallocate all current and new features
3106 flags |= mesh.flags;
3109 if(flags.doubleVertices)
3111 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3114 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3118 if(flags.doubleNormals)
3120 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3123 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3125 if(flags.texCoords1)
3127 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3131 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3139 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3141 OGLMesh oglMesh = mesh.data;
3142 if(!flags) flags = mesh.flags;
3147 oglMesh.vertices.upload(
3148 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3151 oglMesh.normals.upload(
3152 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3154 if(flags.texCoords1)
3155 oglMesh.texCoords.upload(
3156 mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3159 oglMesh.colors.upload(
3160 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3164 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3171 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3175 oglIndices.buffer.free();
3176 delete oglIndices.indices;
3181 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3183 OGLIndices oglIndices = OGLIndices { };
3186 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3187 oglIndices.nIndices = nIndices;
3192 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3199 if(!oglIndices.buffer.buffer)
3200 glGenBuffers(1, &oglIndices.buffer.buffer);
3201 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3202 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3203 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3207 oglIndices.buffer.upload(
3208 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3209 oglIndices.indices); //GL_STATIC_DRAW_ARB);
3213 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3216 return oglIndices.indices;
3219 void SelectMesh(Display display, Mesh mesh)
3221 //Logf("SelectMesh\n");
3223 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3225 #if defined(__WIN32__)
3226 if(glUnlockArraysEXT)
3228 if(!vboAvailable && display.display3D.mesh)
3229 glUnlockArraysEXT();
3234 OGLMesh oglMesh = mesh.data;
3236 // *** Vertex Stream ***
3237 glEnableClientState(GL_VERTEX_ARRAY);
3238 if(!display.display3D.collectingHits && oglMesh)
3240 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3242 // *** Normals Stream ***
3243 if(mesh.normals || mesh.flags.normals)
3245 glEnableClientState(GL_NORMAL_ARRAY);
3246 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3249 glDisableClientState(GL_NORMAL_ARRAY);
3251 // *** Texture Coordinates Stream ***
3252 if(mesh.texCoords || mesh.flags.texCoords1)
3254 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3255 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3258 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3260 // *** Color Stream ***
3261 if(mesh.colors || mesh.flags.colors)
3263 glEnableClientState(GL_COLOR_ARRAY);
3264 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3267 glDisableClientState(GL_COLOR_ARRAY);
3271 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3272 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3274 glEnableClientState(GL_NORMAL_ARRAY);
3275 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3278 glDisableClientState(GL_NORMAL_ARRAY);
3279 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3281 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3282 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3285 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3286 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3288 glEnableClientState(GL_COLOR_ARRAY);
3289 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3292 glDisableClientState(GL_COLOR_ARRAY);
3295 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3297 #if defined(__WIN32__)
3301 glLockArraysEXT(0, mesh.nVertices);
3307 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3309 //Logf("DrawPrimitives\n");
3311 if(primitive->type.vertexRange)
3312 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3315 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3316 // HACK TO SPEED THINGS UP...
3318 /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3319 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3322 glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
3325 OGLIndices oglIndices = primitive->data;
3326 MeshFeatures flags = mesh.flags;
3327 for(c = 0; c<primitive->nIndices; c++)
3329 uint16 index = ((uint16 *) oglIndices.indices)[c];
3330 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3331 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3332 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3333 glVertex3fv((float *)&mesh.vertices[index]);
3342 OGLIndices oglIndices = primitive->data;
3343 GLEAB eab = ((!display.display3D.collectingHits && oglIndices) ? oglIndices.buffer : noEAB);
3345 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3346 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3347 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3348 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3353 void PushMatrix(Display display)
3358 void PopMatrix(Display display, bool setMatrix)
3363 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3365 Matrix matrix = transMatrix;
3366 Camera camera = useCamera ? display.display3D.camera : null;
3371 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3376 matrix.m[3][0] - camera.cPosition.x,
3377 matrix.m[3][1] - camera.cPosition.y,
3378 matrix.m[3][2] - camera.cPosition.z);
3390 glMultMatrixd(matrix.array);
3395 public void UseSingleGLContext(bool useSingle)
3397 useSingleGLContext = useSingle;
3400 default dllexport void *
3401 #if defined(__WIN32__)
3402 __attribute__((stdcall))
3404 IS_GLGetContext(DisplaySystem displaySystem)
3408 #if defined(__WIN32__)
3409 OGLSystem system = displaySystem.driverData;
3411 #elif defined(__ANDROID__) || defined(__ODROID__)
3413 #elif defined(__EMSCRIPTEN__)
3415 OGLSystem system = displaySystem.driverData;
3416 return system.glContext;