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"
19 #if defined(__ANDROID__) || defined(__ODROID__)
30 #undef glEnableClientState
31 #undef glDisableClientState
32 #undef GL_VERTEX_ARRAY
33 #undef GL_NORMAL_ARRAY
34 #undef GL_TEXTURE_COORD_ARRAY
37 #define glEnableClientState glEnableVertexAttribArray
38 #define glDisableClientState glDisableVertexAttribArray
39 #define GL_VERTEX_ARRAY GLBufferContents::vertex
40 #define GL_NORMAL_ARRAY GLBufferContents::normal
41 #define GL_TEXTURE_COORD_ARRAY GLBufferContents::texCoord
42 #define GL_COLOR_ARRAY GLBufferContents::color
46 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
48 #if defined(__unix__) || defined(__APPLE__)
50 #if !defined(__MINGW32__)
51 #define GL_GLEXT_PROTOTYPES
54 #define pointer _pointer
57 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
59 #define property _property
63 #define Window X11Window
64 #define Cursor X11Cursor
66 #define Display X11Display
68 #define KeyCode X11KeyCode
69 #define Picture X11Picture
73 #include <X11/Xutil.h>
75 #include <X11/extensions/XShm.h>
78 #include <X11/extensions/Xrender.h>
79 #include <X11/extensions/shape.h>
97 #if defined(__APPLE__)
98 #include <OpenGl/gl.h>
101 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
103 #if defined(__WIN32__)
104 //#define WIN32_LEAN_AND_MEAN
106 #define _WIN32_WINNT 0x0502
107 #define String Sting_
112 #if defined(__ANDROID__) || defined(__ODROID__)
115 #define property _property
118 #define Window X11Window
119 #define Cursor X11Cursor
121 #define Display X11Display
123 #define KeyCode X11KeyCode
124 #define Picture X11Picture
142 #elif defined(__EMSCRIPTEN__)
144 #define property _property
149 //#include <GLES/gl.h>
150 //#include <GLES2/gl.h>
152 #include <emscripten/emscripten.h>
161 #if defined(__ODROID__) && !defined(ES1_1)
165 #if defined(__EMSCRIPTEN__)
174 #if defined(__unix__) || defined(__APPLE__)
176 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
182 #define glLoadMatrix glLoadMatrixd
183 #define glMultMatrix glMultMatrixd
184 #define glGetMatrix glGetDoublev
185 #define glTranslate glTranslated
186 #define glScale glScaled
189 #define glVertex3v glVertex3dv
190 #define glNormal3v glNormal3dv
194 //#ifdef VERTEX_FORMAT_DOUBLE
196 #define glLoadMatrix glLoadMatrixd
197 #define glMultMatrix glMultMatrixd
198 #define glGetMatrix glGetDoublev
199 #define glVertex3v glVertex3dv
200 #define glNormal3v glNormal3dv
201 #define glTranslate glTranslated
202 #define glScale glScaled
203 //#define GL_VERTEX_FORMAT GL_DOUBLE
207 #define glLoadMatrix glLoadMatrixf
208 #define glMultMatrix glMultMatrixf
209 #define glGetMatrix glGetFloatv
210 #define glVertex3v glVertex3fv
211 #define glNormal3v glNormal3fv
212 #define glTranslate glTranslatef
213 #define glScale glScalef
214 //#define GL_VERTEX_FORMAT GL_FLOAT
219 #define GL_ARRAY_BUFFER_ARB 0x8892
220 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
221 #define GL_STATIC_DRAW_ARB 0x88E4
222 #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
223 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
225 #define GL_MULTISAMPLE_ARB 0x809D
227 #if defined(__WIN32__)
230 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
231 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
233 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
234 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
236 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
237 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
238 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
239 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
240 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
241 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
242 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
243 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
244 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
245 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = null;
246 static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = null;
248 #elif defined(__ANDROID__) || defined(__ODROID__)
250 #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
251 #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
252 #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
254 #define GL_POLYGON_STIPPLE 0xFFFF
255 #define GL_LINE_STIPPLE 0xFFFF
256 #define GL_LINE 0xFFFF
257 #define GL_FILL 0xFFFF
258 #define GL_ALL_ATTRIB_BITS 0xFFFF
259 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
265 #define GL_QUAD_STRIP 0
266 //#define GL_DOUBLE 0
267 //#define GL_UNSIGNED_INT 0
270 //#define GL_LINE_STIPPLE 0
271 #define GL_BGRA_EXT 0
272 #define GL_UNPACK_ROW_LENGTH 0
273 #define GL_UNPACK_SKIP_PIXELS 0
274 #define GL_UNPACK_SKIP_ROWS 0
276 #define GL_PACK_ROW_LENGTH 0
277 #define GL_PACK_SKIP_ROWS 0
278 #define GL_PACK_SKIP_PIXELS 0
283 #if defined(__ANDROID__) || defined(__ODROID__)
284 #define glBindFramebuffer glBindFramebufferOES
285 #define glBindRenderbuffer glBindRenderbufferOES
286 #define glFramebufferTexture2D glFramebufferTexture2DOES
287 #define glGenFramebuffers glGenFramebuffersOES
288 #define glGenRenderbuffers glGenRenderbuffersOES
289 #define glDeleteFramebuffers glDeleteFramebuffersOES
290 #define glDeleteRenderbuffers glDeleteRenderbuffersOES
292 #define GL_INT 0x1404
293 #define GL_UNSIGNED_INT 0x1405
294 #define GL_DOUBLE 0x140A
298 #if defined(ES1_1) || defined(SHADERS)
329 #undef glLoadIdentity
334 #undef glColorMaterial
337 #define glRecti glimtkRecti
338 #define glBegin glimtkBegin
339 #define glTexCoord2i glimtkTexCoord2i
340 #define glVertex2i glimtkVertex2i
341 #define glTexCoord2d glimtkTexCoord2d
342 #define glVertex2d glimtkVertex2d
343 #define glTexCoord2f glimtkTexCoord2f
344 #define glVertex2f glimtkVertex2f
345 #define glEnd glimtkEnd
346 #define glColor3f glimtkColor3f
347 #define glColor4ub glimtkColor4ub
348 #define glColor4fv glimtkColor4fv
349 #define glNormal3fv glimtkNormal3fv
350 #define glNormal3f glimtkNormal3f
351 #define glTexCoord2fv glimtkTexCoord2fv
352 #define glVertex3d glimtkVertex3d
353 #define glVertex3dv glimtkVertex3dv
354 #define glVertex3f glimtkVertex3f
355 #define glVertex3fv glimtkVertex3fv
357 #define glLoadMatrixd glmsLoadMatrixd
358 #define glMultMatrixd glmsMultMatrixd
359 #define glFrustum glmsFrustum
360 #define glOrtho glmsOrtho
361 #define glScaled glmsScaled
362 #define glScalef glmsScaled
363 #define glTranslated glmsTranslated
364 #define glRotated glmsRotated
365 #define glMatrixMode glmsMatrixMode
366 #define glLoadIdentity glmsLoadIdentity
367 #define glPushMatrix glmsPushMatrix
368 #define glPopMatrix glmsPopMatrix
370 #define glLineStipple glesLineStipple
371 #define glColorMaterial glesColorMaterial
372 #define glLightModeli glesLightModeli
376 public void glesColorMaterial(int a, int b)
378 PrintLn("glColorMaterial stub");
381 static GLuint stippleTexture;
382 #if defined(ES1_1) || defined(SHADERS) || defined(EM_MODE)
383 static bool stippleEnabled;
386 public void glesLineStipple( int i, unsigned short j )
390 for(x = 0; x < 16; x++)
392 bool v = (j & (1 << x)) != 0;
393 texture[x] = v ? 0xFFFFFFFF : 0;
396 glGenTextures(1, &stippleTexture);
397 glBindTexture(GL_TEXTURE_2D, stippleTexture);
398 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
400 // TOOD: Special shading code for stippling?
401 GLSetupTexturing(true);
402 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
403 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
404 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
406 glMatrixMode(GL_TEXTURE);
408 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
409 glScaled(i/16.0, 1, 1.0f);
410 glTranslated(0.5, 0.5, 0);
411 glMatrixMode(MatrixMode::projection);
414 public void glesLightModeli( unsigned int pname, int param )
416 #if !defined(EM_MODE) && !defined(SHADERS)
417 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
418 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
422 #if defined(__ANDROID__) || defined(__ODROID__)
423 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
424 void glFogi( unsigned int pname, int param ) { }
425 void glPolygonMode( unsigned int i, unsigned int j ) { }
428 // *** Picking won't be supported for now ***
429 void glPushName( unsigned int i ) { }
430 void glLoadName( unsigned int i ) { }
433 // Probably replace by regular glBlendFunc ...
434 void glBlendFuncSeparate(int a, int b, int c, int d)
439 // For direct pixel blitting...
440 void glRasterPos2d(double a, double b) { }
441 void glPixelZoom(float a, float b) { }
442 void glDrawPixels(int a, int b, int c, int d, void * e) { }
446 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
447 static int primitiveTypes[RenderPrimitiveType] =
449 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GLIMTKMode::quads, GLIMTKMode::quadStrip, GL_LINE_STRIP
453 public void GLSetupTexturing(bool enable)
456 shader_texturing(enable);
458 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
462 public void GLSetupFog(bool enable)
466 #elif !defined(EM_MODE)
467 (enable ? glEnable : glDisable)(GL_FOG);
471 public void GLSetupLighting(bool enable)
474 shader_lighting(enable);
475 #elif !defined(EM_MODE)
476 (enable ? glEnable : glDisable)(GL_LIGHTING);
480 // Non OpenGL ES friendly stuff
484 //#undef GL_UNSIGNED_INT
490 #undef GL_POLYGON_STIPPLE
491 #undef GL_LINE_STIPPLE
494 #undef GL_ALL_ATTRIB_BITS
495 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
499 static int displayWidth, displayHeight;
501 #define GL_CLAMP_TO_EDGE 0x812F
503 static bool vboAvailable;
505 static bool useSingleGLContext = false;
506 class OGLDisplay : struct
508 #if defined(__WIN32__)
519 byte * pboMemory1, * pboMemory2;
521 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
522 GLXContext glContext;
525 XShmSegmentInfo shminfo;
527 XShmSegmentInfo shminfoShape;
532 X11Picture windowPicture;
533 X11Picture pixmapPicture;
535 X11Picture shapePicture;
538 ColorAlpha * flippingBuffer;
539 int flipBufH, flipBufW;
545 static void APIENTRY openglCallbackFunction(GLenum source,
550 const GLchar* message,
551 const void* userParam)
553 PrintLn("---------------------opengl-callback-start------------");
554 PrintLn("message: ", message);
558 case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
559 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
560 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
561 case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
562 case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
563 case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
570 case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
571 case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
572 case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
574 PrintLn("---------------------opengl-callback-end--------------");
578 class OGLSystem : struct
583 #if defined(__WIN32__)
584 PIXELFORMATDESCRIPTOR pfd;
589 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
590 XVisualInfo * visualInfo;
591 GLXContext glContext;
592 GLXDrawable glxDrawable;
596 class OGLSurface : struct
604 float foreground[4], background[4], bitmapMult[4];
607 class OGLMesh : struct
616 class OGLIndices : struct
626 static void setupDebugging()
629 if(glDebugMessageCallback)
631 GLuint unusedIds = 0;
633 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
634 glDebugMessageCallback(openglCallbackFunction, null);
635 glDebugMessageControl(GL_DONT_CARE,
645 #if defined(__WIN32__)
646 static HGLRC winCreateContext(HDC hdc)
648 if(wglCreateContextAttribsARB)
652 WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
653 WGL_CONTEXT_MINOR_VERSION_ARB, 4,
654 WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | */WGL_CONTEXT_DEBUG_BIT_ARB,
655 WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB /*WGL_CONTEXT_CORE_PROFILE_BIT_ARB*/,
658 return wglCreateContextAttribsARB(hdc, null, attribs);
661 return wglCreateContext(hdc);
665 class OpenGLDisplayDriver : DisplayDriver
667 class_property(name) = "OpenGL";
669 bool LockSystem(DisplaySystem displaySystem)
671 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
672 OGLSystem oglSystem = displaySystem.driverData;
673 if(useSingleGLContext) return true;
674 #if defined(__WIN32__)
675 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
676 #elif defined(__unix__) || defined(__APPLE__)
677 //if(previous) return true;
678 // printf("Making SYSTEM current\n");
679 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
680 //previous = oglSystem.glContext;
683 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
684 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
688 void UnlockSystem(DisplaySystem displaySystem)
690 if(useSingleGLContext) return;
691 #if defined(__WIN32__)
692 wglMakeCurrent(null, null);
693 #elif defined(__unix__) || defined(__APPLE__)
694 // printf("Making NULL current\n");
695 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
697 glXMakeCurrent(xGlobalDisplay, None, null);
703 bool Lock(Display display)
705 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
706 OGLDisplay oglDisplay = display.driverData;
707 if(useSingleGLContext) return true;
708 #if defined(__WIN32__)
709 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
710 #elif defined(__unix__) || defined(__APPLE__)
711 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
712 // printf(" Making DISPLAY current\n");
713 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
716 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
717 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
721 void Unlock(Display display)
723 if(useSingleGLContext) return;
724 //printf(" Making NULL current\n");
725 //glXMakeCurrent(xGlobalDisplay, None, null);
727 LockSystem(display.displaySystem);
730 void DestroyDisplay(Display display)
732 OGLDisplay oglDisplay = display.driverData;
736 #if defined(__WIN32__)
737 wglMakeCurrent( null, null );
740 wglDeleteContext(oglDisplay.glrc);
742 if(oglDisplay.hdc && oglDisplay.pBuffer)
743 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
745 if(oglDisplay.pBuffer)
746 wglDestroyPbufferARB(oglDisplay.pBuffer);
749 ReleaseDC(display.window, oglDisplay.hdc);
751 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
752 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
754 #elif defined(__unix__) || defined(__APPLE__)
755 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
757 if(oglDisplay.shapePixmap)
758 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
759 if(oglDisplay.pixmap)
760 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
763 if(oglDisplay.shminfoShape.shmid != -1)
765 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
766 if(oglDisplay.shminfo.shmaddr != (void *)-1)
767 shmdt(oglDisplay.shminfo.shmaddr);
768 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
771 if(oglDisplay.shapeImage)
773 if(oglDisplay.shminfoShape.shmid != -1)
775 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
776 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
777 shmdt(oglDisplay.shminfoShape.shmaddr);
778 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
780 XDestroyImage(oglDisplay.shapeImage);
781 oglDisplay.shapeImage = None;
784 glXMakeCurrent(xGlobalDisplay, None, null);
786 if(oglDisplay.glContext)
787 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
790 delete oglDisplay.flippingBuffer;
792 display.driverData = null;
796 void ::CheckExtensions(OGLSystem oglSystem)
798 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
800 oglSystem.pow2textures = strstr(extensions, "GL_ARB_texture_non_power_of_two") ? false : true;
801 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
804 bool CreateDisplaySystem(DisplaySystem displaySystem)
807 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
810 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
812 oglSystem.hdc = GetDC(oglSystem.hwnd);
816 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
817 oglSystem.pfd.nVersion = 1;
818 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
819 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
820 oglSystem.pfd.cColorBits = 24;
821 oglSystem.pfd.cAlphaBits = 8;
822 oglSystem.pfd.cDepthBits = 24;
823 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
825 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
826 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
828 if(oglSystem.pfd.cColorBits > 8)
830 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
831 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
834 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
836 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
837 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
838 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
839 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
840 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
841 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
842 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
843 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
844 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
845 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
846 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
848 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
849 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
851 // eSystem_LoggingMode(LOG_MSGBOX, null);
853 if(wglChoosePixelFormatARB)
858 float fAttributes[] = {0,0};
861 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
862 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
863 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
864 WGL_COLOR_BITS_ARB,24,
865 WGL_ALPHA_BITS_ARB,8,
866 WGL_DEPTH_BITS_ARB,16,
867 WGL_STENCIL_BITS_ARB,0,
868 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
869 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
870 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
874 //Log("Found wglChoosePixelFormatARB\n");
876 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
877 if(!valid || !numFormats)
879 //Log("Can't find 4x multi sampling\n");
881 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
882 if(!valid || !numFormats)
884 // Log("Can't find 2x multi sampling\n");
887 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
890 if(valid && numFormats)
892 oglSystem.format = pixelFormat;
893 wglMakeCurrent(null, null);
894 wglDeleteContext(oglSystem.glrc);
896 // *** DescribePixelFormat does not support WGL pixel formats! ***
897 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
898 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
899 //Log("Successfully set pixel format\n");
901 oglSystem.glrc = winCreateContext(oglSystem.hdc);
902 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
906 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
910 wglMakeCurrent(null, null);
912 //eSystem_DumpErrors(true);
916 #elif defined(__unix__) || defined(__APPLE__)
918 #if defined(__ANDROID__) || defined(__ODROID__)
919 #if defined(__ANDROID__)
920 egl_init_display(guiApp.desktop.windowHandle);
921 #elif defined(__ODROID__)
922 egl_init_display((uint)displaySystem.window);
923 CheckExtensions(oglSystem);
926 // TODO: Clean this up? Needed here?
927 glEnableClientState(GL_VERTEX_ARRAY);
929 // Initialize GL state.
930 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
931 glEnable(GL_CULL_FACE);
932 glShadeModel(GL_SMOOTH);
933 glDisable(GL_DEPTH_TEST);
935 glDisable(GL_CULL_FACE);
936 glDisable(GL_DEPTH_TEST);
938 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
941 matrixStack[0][0].Identity();
942 matrixStack[1][0].Identity();
943 matrixStack[2][0].Identity();
945 glmsMatrixMode(GL_MODELVIEW);
946 glScaled(1.0, 1.0, -1.0);
947 glmsMatrixMode(GL_PROJECTION);
948 glShadeModel(GL_FLAT);
950 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
951 glFogi(GL_FOG_MODE, GL_EXP);
952 glFogf(GL_FOG_DENSITY, 0);
953 glEnable(GL_NORMALIZE);
954 glDepthFunc(GL_LESS);
956 glDisable(GL_MULTISAMPLE_ARB);
958 glViewport(0,0,eglWidth,eglHeight);
960 glOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
962 glabCurArrayBuffer = 0;
963 glabCurElementBuffer = 0;
966 #elif defined(__EMSCRIPTEN__)
967 if(glfwInit() == GL_TRUE)
969 const int width = 640, height = 480;
970 if(glfwOpenWindow(width, height, 8, 8, 8, 8, 16, 0, GLFW_WINDOW) == GL_TRUE)
976 printf("glfwOpenWindow() failed\n"); //glfwTerminate();
979 printf("glfwInit() failed\n"); //glfwTerminate();
982 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
983 XSetWindowAttributes attr;
988 #ifndef ECERE_MINIGLX
989 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
992 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
996 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
997 attr.background_pixel = 0;
998 attr.border_pixel = 0;
999 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1000 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1001 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1003 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1004 oglSystem.visualInfo->visual, mask, &attr );
1006 if(oglSystem.visualInfo)
1008 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1009 if(oglSystem.glContext)
1011 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1013 // CheckExtensions(oglSystem);
1014 glXMakeCurrent(xGlobalDisplay, None, null);
1021 displaySystem.flags.alpha = true;
1022 displaySystem.flags.flipping = true;
1023 displaySystem.pixelFormat = pixelFormat888;
1027 void DestroyDisplaySystem(DisplaySystem displaySystem)
1029 OGLSystem oglSystem = displaySystem.driverData;
1032 glDeleteTextures(1, &stippleTexture);
1036 #if defined(__WIN32__)
1037 wglMakeCurrent( null, null );
1040 wglDeleteContext(oglSystem.glrc);
1043 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1044 DestroyWindow(oglSystem.hwnd);
1046 #elif defined(__unix__) || defined(__APPLE__)
1047 #if defined(__ANDROID__) || defined(__ODROID__)
1049 #elif defined(__EMSCRIPTEN__)
1052 if(oglSystem.visualInfo)
1054 #ifdef ECERE_MINIGLX
1055 __miniglx_XFree(oglSystem.visualInfo);
1057 XFree(oglSystem.visualInfo);
1061 if(oglSystem.glxDrawable)
1063 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1064 oglSystem.glxDrawable = 0;
1071 bool CreateDisplay(Display display)
1073 bool result = false;
1074 OGLDisplay oglDisplay = display.driverData;
1075 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
1076 OGLSystem oglSystem = display.displaySystem.driverData;
1080 oglDisplay = display.driverData = OGLDisplay { };
1081 //printf("Inside CreateDisplay\n");
1083 #if defined(__WIN32__) || defined(USEPBUFFER)
1084 if(!display.alphaBlend)
1087 #if defined(__WIN32__)
1088 oglDisplay.hdc = GetDC(display.window);
1089 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1090 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1092 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1093 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1097 ReleaseDC(display.window, oglDisplay.hdc);
1098 #elif defined(__unix__) || defined(__APPLE__)
1099 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1101 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1103 #if defined(__APPLE__)
1104 XVisualInfo template = { 0 };
1105 XWindowAttributes winAttr;
1107 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1108 template.visualid = XVisualIDFromVisual(winAttr.visual);
1109 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1111 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1112 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1113 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1114 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1116 // visualInfo = oglSystem.visualInfo;
1121 //printf("visualInfo is not null\n");
1122 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1123 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1124 //XFree(visualInfo);
1127 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1128 if(oglDisplay.glContext)
1130 //printf("CreateDisplay Got a Context\n");
1131 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1137 #if defined(__WIN32__) || defined(USEPBUFFER)
1143 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1144 ogl_LoadFunctions();
1145 CheckExtensions(oglSystem);
1146 vboAvailable = glBindBuffer != null;
1150 loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1152 glEnableClientState(GL_VERTEX_ARRAY);
1154 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1155 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1157 #if defined(__WIN32__)
1158 if(glBlendFuncSeparate)
1159 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1161 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1163 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1167 glMatrixMode(MatrixMode::modelView);
1168 glLoadIdentity(); // For setting up GLES stack
1169 glScaled(1.0, 1.0, -1.0);
1170 // glTranslatef(0.375f, 0.375f, 0.0f);
1171 // glTranslatef(-0.625f, -0.625f, 0.0f);
1172 glMatrixMode(MatrixMode::projection);
1173 #if !defined(EM_MODE) && !defined(SHADERS)
1174 glShadeModel(GL_FLAT);
1176 // #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1178 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1179 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1180 glFogi(GL_FOG_MODE, GL_EXP);
1181 glFogf(GL_FOG_DENSITY, 0);
1182 glEnable(GL_NORMALIZE);
1184 glDepthFunc(GL_LESS);
1186 glDisable(GL_MULTISAMPLE_ARB);
1188 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1189 display.ambient = Color { 50,50,50 };
1192 if(!useSingleGLContext)
1194 #if defined(__WIN32__)
1195 wglMakeCurrent(null, null);
1196 #elif defined(__unix__) || defined(__APPLE__)
1197 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1200 glXMakeCurrent(xGlobalDisplay, None, null);
1206 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1214 bool DisplaySize(Display display, int width, int height)
1216 OGLDisplay oglDisplay = display.driverData;
1218 bool result = false;
1220 //printf("Inside DisplaySize\n");
1221 #if defined(__WIN32__) || defined(USEPBUFFER)
1222 OGLSystem oglSystem = display.displaySystem.driverData;
1223 if(display.alphaBlend)
1225 #if defined(__WIN32__)
1226 const int attributes[]=
1228 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1229 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1231 int pixelFormat = 0;
1232 if(wglChoosePixelFormatARB)
1236 float fAttributes[] = {0,0};
1239 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1240 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1241 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1242 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1243 WGL_COLOR_BITS_ARB,24,
1244 WGL_ALPHA_BITS_ARB,8,
1245 WGL_DEPTH_BITS_ARB,16,
1246 WGL_STENCIL_BITS_ARB,0,
1247 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1248 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1249 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1253 //Log("Found wglChoosePixelFormatARB\n");
1255 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1256 if(!valid || !numFormats)
1258 //Log("Can't find 4x multi sampling\n");
1259 iAttributes[19] = 2;
1260 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1261 if(!valid || !numFormats)
1263 // Log("Can't find 2x multi sampling\n");
1264 iAttributes[16] = 0;
1265 iAttributes[17] = 0;
1266 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1267 if(!valid || !numFormats)
1271 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1272 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1273 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1274 WGL_COLOR_BITS_ARB,24,
1275 WGL_ALPHA_BITS_ARB,8,
1276 WGL_DEPTH_BITS_ARB,16,
1279 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1283 if(valid && numFormats)
1285 wglMakeCurrent(null, null);
1289 wglMakeCurrent( null, null );
1290 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1291 if(oglDisplay.hdc && oglDisplay.pBuffer)
1292 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1294 wglDestroyPbufferARB(oglDisplay.pBuffer);
1296 if(!useSingleGLContext)
1297 wglMakeCurrent( null, null );
1300 wglDeleteContext(oglDisplay.glrc);
1302 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1303 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1304 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1307 HDC hdc = GetDC(display.window);
1309 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1310 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1312 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1313 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1315 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1317 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1321 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1322 oglDisplay.memDC = CreateCompatibleDC(hdc);
1323 SetMapMode(oglDisplay.memDC, MM_TEXT);
1324 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1325 info->bmiHeader.biPlanes = 1;
1326 info->bmiHeader.biCompression = BI_RGB;
1327 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1328 info->bmiHeader.biWidth = width;
1329 info->bmiHeader.biHeight = height;
1330 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1333 SelectObject(oglDisplay.memDC, newBitmap);
1334 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1337 PIXELFORMATDESCRIPTOR pfd = { 0 };
1338 pfd.nSize = (short)sizeof(pfd);
1340 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1341 pfd.iPixelType = PFD_TYPE_RGBA;
1342 pfd.cColorBits = 32;
1343 //pfd.cAlphaBits = 8;
1344 pfd.cDepthBits = 24;
1345 pfd.iLayerType = PFD_MAIN_PLANE;
1347 oglDisplay.hdc = oglDisplay.memDC;
1349 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1350 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1351 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1353 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1354 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1355 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1360 const int imageSize = width * height * 4;
1362 glGenBuffersARB(2, oglDisplay.imageBuffers);
1364 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1365 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1366 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1367 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1370 oglDisplay.memBitmap = newBitmap;
1371 oglDisplay.stride = width;
1377 ReleaseDC(display.window, hdc);
1379 #elif defined(__unix__) || defined(__APPLE__)
1380 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1385 GLX_DOUBLEBUFFER, True,
1391 GLX_STENCIL_SIZE, 1,
1392 //GLX_DEPTH_SIZE, 24,
1393 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1394 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1400 GLX_PBUFFER_WIDTH, width,
1401 GLX_PBUFFER_HEIGHT, height,
1402 GLX_LARGEST_PBUFFER, False,
1406 // choose a pixel format that meets our minimum requirements
1409 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1412 if(oglDisplay.pixmap)
1414 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1415 oglDisplay.pixmap = None;
1417 if(oglDisplay.shapePixmap)
1419 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1420 oglDisplay.shapePixmap = None;
1423 // Free Shared Memory Pixmap
1424 if(oglDisplay.image)
1426 if(oglDisplay.shminfoShape.shmid != -1)
1428 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1429 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1430 shmdt(oglDisplay.shminfo.shmaddr);
1431 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1433 XDestroyImage(oglDisplay.image);
1434 oglDisplay.image = None;
1436 if(oglDisplay.shapeImage)
1438 if(oglDisplay.shminfoShape.shmid != -1)
1440 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1441 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1442 shmdt(oglDisplay.shminfoShape.shmaddr);
1443 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1445 XDestroyImage(oglDisplay.shapeImage);
1446 oglDisplay.shapeImage = None;
1449 if(oglDisplay.windowPicture)
1450 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1451 if(oglDisplay.pixmapPicture)
1452 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1454 if(oglDisplay.pixmap)
1455 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1457 if(oglDisplay.glContext)
1458 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1459 if(oglDisplay.pBuffer)
1460 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1462 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1463 if(oglDisplay.pBuffer)
1465 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1466 if(oglDisplay.glContext)
1468 glXMakeCurrent(xGlobalDisplay, None, null);
1469 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1471 // Initialize Shared Memory Pixmap
1472 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1473 ZPixmap, null, &oglDisplay.shminfo, width, height);
1474 if(oglDisplay.image)
1476 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1477 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1478 if(oglDisplay.shminfo.shmid != -1)
1480 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1481 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1483 oglDisplay.shminfo.readOnly = False;
1484 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1486 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1487 &oglDisplay.shminfo, width, height, 32);
1489 // Initialize Shared Memory Shape Pixmap
1490 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1491 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1492 if(oglDisplay.shapeImage)
1494 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1495 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1496 if(oglDisplay.shminfoShape.shmid != -1)
1498 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1499 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1501 oglDisplay.shminfoShape.readOnly = False;
1502 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1504 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1505 &oglDisplay.shminfoShape, width, height, 1);
1506 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1509 XRenderPictureAttributes attributes = { 0 };
1510 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1511 #if !defined(__APPLE__)
1512 attributes.repeat = RepeatNormal;
1514 attributes.repeat = 1;
1516 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1517 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1518 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1519 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1522 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1523 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1540 CreateDisplay(display);
1541 #if defined(__WIN32__)
1542 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1543 #elif defined(__unix__) || defined(__APPLE__)
1544 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1548 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1555 if(!result && display.alphaBlend)
1557 printf("Alpha blending windows not supported on this display\n");
1564 glViewport(0,0,width,height);
1565 glMatrixMode(MatrixMode::projection);
1567 glOrtho(0,width,height,0,0.0,1.0);
1568 displayWidth = display.width = width;
1569 displayHeight = display.height = height;
1571 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1573 oglDisplay.flipBufW = width;
1574 oglDisplay.flipBufH = height;
1578 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1581 if(oglDisplay.flippingBuffer || !width || !height)
1587 void DisplayPosition(Display display, int x, int y)
1589 OGLDisplay oglDisplay = display.driverData;
1595 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1599 void RestorePalette(Display display)
1603 void StartUpdate(Display display)
1607 void EndUpdate(Display display)
1611 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1615 void Update(Display display, Box updateBox)
1617 #if defined(__WIN32__) || defined(USEPBUFFER)
1618 OGLDisplay oglDisplay = display.driverData;
1620 //Logf("DisplayScreen\n");
1622 #if !defined(__ANDROID__)
1627 #if defined(__WIN32__) || defined(USEPBUFFER)
1628 if(display.alphaBlend)
1630 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1631 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1632 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1633 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1634 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1637 #if defined(__WIN32__)
1639 POINT point = { oglDisplay.x, oglDisplay.y};
1640 POINT srcPoint = { 0, 0 };
1641 BLENDFUNCTION blend = { 0 };
1643 size.cx = display.width;
1644 size.cy = display.height;
1645 blend.BlendOp = AC_SRC_OVER;
1646 blend.BlendFlags = 0;
1647 blend.SourceConstantAlpha = 255;
1648 blend.AlphaFormat = AC_SRC_ALPHA;
1651 // Process partial images. Mapping the buffer waits for
1652 // outstanding DMA transfers into the buffer to finish.
1653 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1654 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1656 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1657 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1660 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1661 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1664 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1667 // Unmap the image buffers
1668 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1669 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1671 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1672 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1674 // Bind two different buffer objects and start the glReadPixels
1675 // asynchronously. Each call will return directly after
1676 // starting the DMA transfer.
1677 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1678 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1680 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1681 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1685 #elif defined(__unix__) || defined(__APPLE__)
1686 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1688 XTransform transform =
1691 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1692 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1693 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1696 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1697 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1698 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1699 #if !defined(__APPLE__)
1700 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1702 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1704 XFlush(xGlobalDisplay);
1712 #if defined(__WIN32__)
1713 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1714 SwapBuffers(oglDisplay.hdc);
1715 #elif defined(__unix__) || defined(__APPLE__)
1716 #if defined(__ANDROID__) || defined(__ODROID__)
1718 #elif defined(__EMSCRIPTEN__)
1721 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1725 //Logf("Out of DisplayScreen\n");
1728 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1730 if(bitmap.driverData)
1732 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1733 glDeleteTextures(1, &tex);
1734 bitmap.driverData = 0;
1736 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1739 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1741 OGLSystem oglSystem = displaySystem.driverData;
1742 bool result = false;
1744 GLuint glBitmap = 0;
1746 uint w = width, h = height;
1747 if(oglSystem.pow2textures)
1752 w = Min(w, oglSystem.maxTextureSize);
1753 h = Min(h, oglSystem.maxTextureSize);
1755 glGenTextures(1, &glBitmap);
1756 glBindTexture(GL_TEXTURE_2D, glBitmap);
1758 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1760 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1761 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1763 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1764 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1766 #if !defined(SHADERS)
1767 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1770 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1772 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1773 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1777 bitmap.driverData = (void *)(uintptr)glBitmap;
1778 bitmap.driver = displaySystem.driver;
1786 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1788 bool result = false;
1789 OGLSystem oglSystem = displaySystem.driverData;
1790 Bitmap convBitmap = bitmap;
1794 convBitmap.Copy(bitmap);
1797 // Pre process the bitmap... First make it 32 bit
1798 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1801 uint w = bitmap.width, h = bitmap.height;
1802 GLuint glBitmap = 0;
1803 if(oglSystem.pow2textures)
1808 w = Min(w, oglSystem.maxTextureSize);
1809 h = Min(h, oglSystem.maxTextureSize);
1813 while(w * 2 < h) w *= 2;
1814 while(h * 2 < w) h *= 2;
1817 // Switch ARGB to RGBA
1818 //if(bitmap.format != pixelFormatRGBA)
1820 for(c=0; c<bitmap.size; c++)
1822 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1824 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1825 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1828 // convBitmap.pixelFormat = pixelFormat888;
1831 glGenTextures(1, &glBitmap);
1834 //int error = glGetError();
1838 glBindTexture(GL_TEXTURE_2D, glBitmap);
1839 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1841 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1842 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1844 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1846 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1847 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1849 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1850 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1851 #if !defined(__ANDROID__) && !defined(SHADERS)
1852 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1855 #if !defined(SHADERS)
1856 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1861 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1866 if(bitmap.width != w || bitmap.height != h)
1868 mipMap = Bitmap { };
1869 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1871 Surface mipSurface = mipMap.GetSurface(0,0,null);
1872 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1882 mipMap = convBitmap;
1889 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1890 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1891 //printf("Calling glTexImage2D\n");
1892 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
1893 //printf("width = %d (Should be %d, %d)\n", width, w, h);
1894 if((error = glGetError()))
1896 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
1897 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
1901 if(mipMap != convBitmap)
1906 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
1907 bitmap.driverData = (void *)(uintptr)glBitmap;
1908 bitmap.driver = displaySystem.driver;
1913 FreeBitmap(displaySystem, bitmap);
1914 else if(oglSystem.loadingFont)
1916 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1917 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1918 oglSystem.loadingFont = false;
1924 void ReleaseSurface(Display display, Surface surface)
1926 glDisable(GL_SCISSOR_TEST);
1927 delete surface.driverData;
1928 surface.driverData = null;
1931 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
1936 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
1938 bool result = false;
1939 OGLSurface oglSurface = surface.driverData = OGLSurface { };
1941 //Logf("GetSurface\n");
1945 if(displayWidth != display.width || displayHeight != display.height)
1947 displayWidth = display.width;
1948 displayHeight = display.height;
1950 glViewport(0,0,display.width,display.height);
1952 glOrtho(0,display.width,display.height,0,0.0,1.0);
1955 surface.offset.x = x;
1956 surface.offset.y = y;
1957 surface.unclippedBox = surface.box = clip;
1958 oglSurface.bitmapMult[0] = 1;
1959 oglSurface.bitmapMult[1] = 1;
1960 oglSurface.bitmapMult[2] = 1;
1961 oglSurface.bitmapMult[3] = 1;
1963 glEnable(GL_SCISSOR_TEST);
1966 (display.height) -(y+clip.bottom)-1,
1967 clip.right-clip.left+1,
1968 clip.bottom-clip.top+1);
1974 void Clip(Display display, Surface surface, Box clip)
1983 box.Clip(surface.unclippedBox);
1987 box = surface.box = surface.unclippedBox;
1988 box.left += surface.offset.x;
1989 box.top += surface.offset.y;
1990 box.right+= surface.offset.x;
1991 box.bottom += surface.offset.y;
1994 box.left,display.height - box.bottom - 1,
1995 box.right-box.left+1, box.bottom-box.top+1);
1998 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2000 bool result = false;
2001 OGLDisplay oglDisplay = display.driverData;
2002 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2004 if(oglDisplay.flippingBuffer)
2006 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2009 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2015 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2016 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2017 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2018 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2019 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2022 for(row = 0; row<h; row++)
2023 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2030 void SetForeground(Display display, Surface surface, ColorAlpha color)
2032 OGLSurface oglSurface = surface.driverData;
2034 //Logf("SetForeground\n");
2036 oglSurface.foreground[0] = color.color.r/255.0f;
2037 oglSurface.foreground[1] = color.color.g/255.0f;
2038 oglSurface.foreground[2] = color.color.b/255.0f;
2039 //oglSurface.foreground[3] = 1.0f;
2040 oglSurface.foreground[3] = color.a/255.0f;
2042 //if(!oglSurface.foreground[3])printf("bug");
2045 void SetBackground(Display display, Surface surface, ColorAlpha color)
2047 OGLSurface oglSurface = surface.driverData;
2049 //Logf("SetBackground\n");
2051 oglSurface.background[0] = color.color.r/255.0f;
2052 oglSurface.background[1] = color.color.g/255.0f;
2053 oglSurface.background[2] = color.color.b/255.0f;
2054 //oglSurface.background[3] = 1.0;
2055 oglSurface.background[3] = color.a/255.0f;
2058 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2060 OGLSurface oglSurface = surface.driverData;
2062 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2063 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2064 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2065 oglSurface.bitmapMult[3] = color.a/255.0f;
2068 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2073 void PutPixel(Display display, Surface surface,int x,int y)
2075 OGLSurface oglSurface = surface.driverData;
2077 //Logf("PutPixel\n");
2079 glColor4fv(oglSurface.foreground);
2081 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2082 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2087 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2089 OGLSurface oglSurface = surface.driverData;
2090 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2105 x1 += surface.offset.x;
2106 y1 += surface.offset.y;
2107 x2 += surface.offset.x;
2108 y2 += surface.offset.y;
2112 glColor4fv(oglSurface.foreground);
2114 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2117 glTexCoord2f(0.5f, 0);
2118 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2119 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2120 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2129 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2130 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2136 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2138 OGLSurface oglSurface = surface.driverData;
2139 x1 += surface.offset.x;
2140 y1 += surface.offset.y;
2141 x2 += surface.offset.x;
2142 y2 += surface.offset.y;
2144 //Logf("Rectangle\n");
2146 glColor4fv(oglSurface.foreground);
2147 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2152 glTexCoord2f(0.5f, 0);
2153 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2154 glTexCoord2f(y2-y1 + 0.5f, 0);
2155 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2157 glTexCoord2f(0.5f, 0);
2158 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2159 glTexCoord2f(x2 - x1 + 0.5f, 0);
2160 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2162 glTexCoord2f(0.5f, 0);
2163 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2164 glTexCoord2f(y1 - y2 + 0.5f, 0);
2165 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2167 glTexCoord2f(0.5f, 0);
2168 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2169 glTexCoord2f(x1 - x2 + 0.5f, 0);
2170 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2175 glBegin(GL_LINE_LOOP);
2182 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2183 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2184 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2185 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2190 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2192 OGLSurface oglSurface = surface.driverData;
2195 glColor4fv(oglSurface.background);
2199 glVertex2f(x1+surface.offset.x, y1+surface.offset.y);
2200 glVertex2f(x1+surface.offset.x, y2+surface.offset.y+1);
2201 glVertex2f(x2+surface.offset.x+1, y2+surface.offset.y+1);
2202 glVertex2f(x2+surface.offset.x+1, y1+surface.offset.y);
2205 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2206 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2209 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2210 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2214 void Clear(Display display, Surface surface, ClearType type)
2216 OGLDisplay oglDisplay = display.driverData;
2217 OGLSurface oglSurface = surface.driverData;
2220 if(type != depthBuffer)
2221 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2222 if(type != colorBuffer && !oglDisplay.depthWrite)
2224 glDepthMask((byte)bool::true);
2226 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2227 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2228 if(type != colorBuffer && !oglDisplay.depthWrite)
2230 glDepthMask((byte)bool::false);
2234 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2239 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2241 OGLSurface oglSurface = surface.driverData;
2243 if(!oglSurface.writingText)
2245 // glTranslatef(-0.375f, -0.375f, 0.0f);
2246 GLSetupTexturing(true);
2247 glColor4fv(oglSurface.bitmapMult);
2249 else if(oglSurface.xOffset)
2250 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2252 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2253 glBegin(GLIMTKMode::quads);
2257 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2258 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2259 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2260 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2261 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2262 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2263 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2264 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2269 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2270 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2271 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2272 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2273 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2274 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2275 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2276 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2279 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2280 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2281 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2282 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2283 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2284 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2285 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2286 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2290 if(!oglSurface.writingText)
2292 GLSetupTexturing(false);
2294 //glTranslate(0.375, 0.375, 0.0);
2296 else if(oglSurface.xOffset)
2297 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2300 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2302 OGLSurface oglSurface = surface.driverData;
2304 //glTranslate(-0.375, -0.375, 0.0);
2306 GLSetupTexturing(true);
2307 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2309 glColor4fv(oglSurface.bitmapMult);
2311 glBegin(GLIMTKMode::quads);
2315 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2316 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2318 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2319 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2321 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2322 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2324 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2325 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2329 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2330 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2332 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2333 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2335 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2336 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2338 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2339 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2344 GLSetupTexturing(false);
2346 //glTranslate(0.375, 0.375, 0.0);
2349 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2351 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2354 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2356 #if !defined(EM_MODE)
2357 float s2dw,s2dh,d2sw,d2sh;
2358 //bool flipX = false, flipY = false;
2360 //Logf("StretchDI\n");
2362 if(Sgn(w) != Sgn(sw))
2368 if(Sgn(h) != Sgn(sh))
2380 //Clip against the edges of the source
2383 dx+=(int)((0-sx) * s2dw);
2384 w-=(int)((0-sx) * s2dw);
2390 dy+=(int)((0-sy) * s2dh);
2391 h-=(int)((0-sy) * s2dh);
2396 if(sx+sw>bitmap.width-1)
2398 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2399 sw-=sx+sw-(bitmap.width-1)-1;
2401 if(sy+sh>(bitmap.height-1))
2403 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2404 sh-=sy+sh-(bitmap.height-1)-1;
2406 //Clip against the edges of the surfaceination
2407 if(dx<surface.box.left)
2410 sx+=(int)((surface.box.left-dx)*d2sw);
2411 sw-=(int)((surface.box.left-dx)*d2sw);
2412 w-=surface.box.left-dx;
2413 dx=surface.box.left;
2415 if(dy<surface.box.top)
2417 sy+=(int)((surface.box.top-dy)*d2sh);
2418 sh-=(int)((surface.box.top-dy)*d2sh);
2419 h-=surface.box.top-dy;
2422 if(dx+w>surface.box.right)
2424 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2425 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2426 w-=dx+w-surface.box.right-1;
2428 if(dy+h>surface.box.bottom)
2430 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2431 h-=dy+h-surface.box.bottom-1;
2433 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2435 dx += surface.offset.x;
2436 dy += surface.offset.y;
2438 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2440 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2441 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2442 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2443 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2444 #if !defined(SHADERS)
2445 glRasterPos2d(dx,dy);
2446 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2447 glPixelZoom(s2dw, -s2dh);
2448 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2450 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2451 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2452 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2453 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2458 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2460 #if !defined(EM_MODE)
2463 //Clip against the edges of the source
2476 if(sx+w>bitmap.width-1)
2477 w-=sx+w-(bitmap.width-1)-1;
2478 if(sy+h>bitmap.height-1)
2479 h-=sy+h-(bitmap.height-1)-1;
2480 //Clip against the edges of the surfaceination
2481 if(dx<surface.box.left)
2484 sx+=surface.box.left-dx;
2485 w-=surface.box.left-dx;
2486 dx=surface.box.left;
2488 if(dy<surface.box.top)
2490 sy+=surface.box.top-dy;
2491 h-=surface.box.top-dy;
2494 if(dx+w>surface.box.right)
2496 //if(flip) sx+=dx+w-surface.box.right-1;
2497 w-=dx+w-surface.box.right-1;
2499 if(dy+h>surface.box.bottom)
2500 h-=dy+h-surface.box.bottom-1;
2504 dx += surface.offset.x;
2505 dy += surface.offset.y;
2507 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2509 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2510 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2511 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2512 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2513 #if !defined(SHADERS)
2514 glRasterPos2d(dx,dy);
2516 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2518 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2519 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2520 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2521 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2526 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2528 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2531 void UnloadFont(DisplaySystem displaySystem, Font font)
2533 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2536 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
2539 OGLSystem oglSystem = displaySystem.driverData;
2540 oglSystem.loadingFont = true;
2541 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
2545 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
2547 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
2550 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
2552 OGLSurface oglSurface = surface.driverData;
2553 OGLSystem oglSystem = display.displaySystem.driverData;
2554 oglSystem.loadingFont = true;
2556 //glTranslated(-0.375, -0.375, 0.0);
2560 if(surface.textOpacity)
2563 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
2564 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2567 oglSurface.writingText = true;
2569 GLSetupTexturing(true);
2571 if(surface.outline.size)
2573 ColorAlpha outlineColor = surface.outline.color;
2574 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2575 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2576 //glEnable(GL_BLEND);
2578 oglSurface.writingOutline = true;
2579 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
2580 oglSurface.writingOutline = false;
2582 glColor4fv(oglSurface.foreground);
2584 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
2585 oglSurface.writingText = false;
2586 oglSystem.loadingFont = false;
2588 GLSetupTexturing(false);
2590 //glTranslated(0.375, 0.375, 0.0);
2593 void TextFont(Display display, Surface surface, Font font)
2595 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2598 void TextOpacity(Display display, Surface surface, bool opaque)
2600 OGLSurface oglSurface = surface.driverData;
2601 oglSurface.opaqueText = opaque;
2604 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
2606 OGLSurface oglSurface = surface.driverData;
2607 OGLSystem oglSystem = display.displaySystem.driverData;
2608 oglSystem.loadingFont = true;
2609 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height);
2610 oglSystem.loadingFont = false;
2613 void DrawingChar(Display display, Surface surface, char character)
2618 void LineStipple(Display display, Surface surface, uint32 stipple)
2620 //Logf("Stipple\n");
2624 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2625 stippleEnabled = true;
2626 glesLineStipple(1, (uint16)stipple);
2628 glLineStipple(1, (uint16)stipple);
2629 glEnable(GL_LINE_STIPPLE);
2634 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2635 stippleEnabled = false;
2636 glMatrixMode(GL_TEXTURE);
2638 glMatrixMode(MatrixMode::projection);
2639 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2641 glDisable(GL_LINE_STIPPLE);
2645 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2646 void SetRenderState(Display display, RenderState state, uint value)
2648 OGLDisplay oglDisplay = display.driverData;
2649 //Logf("RenderState\n");
2655 glEnable(GL_MULTISAMPLE_ARB);
2657 glDisable(GL_MULTISAMPLE_ARB);
2661 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2665 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2668 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2669 oglDisplay.depthWrite = (bool)value;
2673 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2674 #if defined(SHADERS)
2675 shader_fogColor(color[0], color[1], color[2]);
2677 glFogfv(GL_FOG_COLOR, (float *)&color);
2682 #if defined(SHADERS)
2683 shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2685 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2689 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2693 #if defined(SHADERS)
2694 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2695 #elif !defined(EM_MODE)
2696 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2697 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2703 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2708 #if defined(__WIN32__)
2709 wglSwapIntervalEXT(value ? 1 : 0);
2716 void SetLight(Display display, int id, Light light)
2718 #if defined(SHADERS)
2719 shader_setLight(display, id, light);
2720 #elif !defined(EM_MODE)
2721 //Logf("SetLight\n");
2725 Object lightObject = light.lightObject;
2726 float position[4] = { 0, 0, 0, 0 };
2727 float color[4] = { 0, 0, 0, 1 };
2729 glEnable(GL_LIGHT0 + id);
2731 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
2732 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
2733 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
2736 if(!light.multiplier) light.multiplier = 1.0f;
2738 color[0] = light.diffuse.r * light.multiplier;
2739 color[1] = light.diffuse.g * light.multiplier;
2740 color[2] = light.diffuse.b * light.multiplier;
2741 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2743 color[0] = light.ambient.r * light.multiplier;
2744 color[1] = light.ambient.g * light.multiplier;
2745 color[2] = light.ambient.b * light.multiplier;
2746 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2747 color[0] = light.specular.r * light.multiplier;
2748 color[1] = light.specular.g * light.multiplier;
2749 color[2] = light.specular.b * light.multiplier;
2750 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2754 Vector3D positionVector;
2755 if(light.flags.spot)
2757 if(lightObject.flags.root || !lightObject.parent)
2759 positionVector = lightObject.transform.position;
2760 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2764 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2765 if(display.display3D.camera)
2766 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2772 if(!light.direction.x && !light.direction.y && !light.direction.z)
2774 Vector3Df vector { 0,0,-1 };
2776 mat.RotationQuaternion(light.orientation);
2777 positionVector.MultMatrixf(vector, mat);
2781 positionVector = light.direction;
2786 position[0] = (float)positionVector.x;
2787 position[1] = (float)positionVector.y;
2788 position[2] = (float)positionVector.z;
2790 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2793 // Display Light Position
2794 glDisable(GL_LIGHTING);
2795 glDisable(GL_DEPTH_TEST);
2799 glVertex3fv(position);
2801 glEnable(GL_DEPTH_TEST);
2802 glEnable(GL_LIGHTING);
2806 if(lightObject.flags.root || !lightObject.parent)
2808 positionVector = light.target.transform.position;
2809 positionVector.Subtract(positionVector, display.camera.cPosition);
2813 positionVector.MultMatrix(light.target.transform.position,
2814 lightObject.light.target.parent.matrix);
2815 positionVector.Subtract(positionVector, display.camera.cPosition);
2818 position[0] = positionVector.x;
2819 position[1] = positionVector.y;
2820 position[2] = positionVector.z;
2822 glDisable(GL_LIGHTING);
2823 glDisable(GL_DEPTH_TEST);
2827 glVertex3fv(position);
2829 glEnable(GL_DEPTH_TEST);
2830 glEnable(GL_LIGHTING);
2833 if(light.flags.attenuation)
2835 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2836 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2837 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2840 if(light.flags.spot)
2843 #define MAXLIGHT 0.9
2844 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2845 // Figure out exponent out of the hot spot
2846 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2848 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2849 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2850 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2855 Vector3Df vector { 0,0,-1 };
2856 Vector3Df direction;
2859 mat.RotationQuaternion(light.orientation);
2860 direction.MultMatrix(vector, mat);
2862 position[0] = direction.x;
2863 position[1] = direction.y;
2864 position[2] = direction.z;
2866 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2870 glDisable(GL_LIGHT0 + id);
2874 void SetCamera(Display display, Surface surface, Camera camera)
2876 OGLDisplay oglDisplay = display.driverData;
2877 //Logf("SetCamera\n");
2879 if(surface && camera)
2881 int left = surface.box.left + surface.offset.x;
2882 int top = surface.box.top + surface.offset.y;
2883 int right = surface.box.right + surface.offset.x;
2884 int bottom = surface.box.bottom + surface.offset.y;
2885 float origX = surface.offset.x + camera.origin.x;
2886 float origY = surface.offset.y + camera.origin.y;
2888 int y = display.height - bottom - 1;
2889 int w = right - left + 1;
2890 int h = bottom - top + 1;
2893 glViewport(x, y, w, h);
2895 // *** Projection Matrix ***
2896 glMatrixMode(MatrixMode::projection);
2897 if(!display.display3D.camera)
2900 if(display.display3D.collectingHits)
2902 float pickX = display.display3D.pickX + surface.offset.x;
2903 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
2907 w / display.display3D.pickWidth, 0, 0, 0,
2908 0, h / display.display3D.pickHeight, 0, 0,
2910 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
2911 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
2914 glLoadMatrixd(pickMatrix.array);
2919 (left - origX) * camera.zMin / camera.focalX,
2920 (right - origX) * camera.zMin / camera.focalX,
2921 (bottom - origY) * camera.zMin / camera.focalY,
2922 (top - origY) * camera.zMin / camera.focalY,
2923 camera.zMin, camera.zMax);
2925 glDisable(GL_BLEND);
2927 // *** Z Inverted Identity Matrix ***
2928 glMatrixMode(MatrixMode::modelView);
2929 if(!display.display3D.camera)
2934 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
2936 // *** View Matrix ***
2937 glMultMatrixd(camera.viewMatrix.array);
2942 glEnable(GL_DEPTH_TEST);
2944 GLSetupLighting(true);
2945 #if !defined(EM_MODE) && !defined(SHADERS)
2946 glShadeModel(GL_SMOOTH);
2948 glDepthMask((byte)bool::true);
2949 oglDisplay.depthWrite = true;
2951 glEnable(GL_MULTISAMPLE_ARB);
2953 else if(surface && display.display3D.camera)
2956 oglDisplay.depthWrite = false;
2957 glViewport(0,0,display.width,display.height);
2959 glDisable(GL_CULL_FACE);
2960 glDisable(GL_DEPTH_TEST);
2962 GLSetupTexturing(false);
2963 GLSetupLighting(false);
2966 glDisableClientState(GL_COLOR_ARRAY);
2968 #if !defined(SHADERS) && !defined(EM_MODE)
2969 glShadeModel(GL_FLAT);
2972 glDisable(GL_MULTISAMPLE_ARB);
2974 // *** Restore 2D MODELVIEW Matrix ***
2977 // *** Restore 2D PROJECTION Matrix ***
2978 glMatrixMode(MatrixMode::projection);
2984 void ApplyMaterial(Display display, Material material, Mesh mesh)
2986 //Logf("ApplyMaterial\n");
2989 if(material.flags.doubleSided)
2991 #if !defined(EM_MODE) && !defined(SHADERS)
2992 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
2994 glDisable(GL_CULL_FACE);
2998 #if !defined(EM_MODE) && !defined(SHADERS)
2999 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3001 glEnable(GL_CULL_FACE);
3005 GLSetupFog(!material.flags.noFog);
3008 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3010 Bitmap map = material.baseMap;
3011 GLSetupTexturing(true);
3012 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3014 glMatrixMode(GL_TEXTURE);
3016 if(material.uScale && material.vScale)
3017 glScalef(material.uScale, material.vScale, 1);
3018 glMatrixMode(MatrixMode::modelView);
3020 if(material.flags.tile)
3022 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3023 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3027 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3032 GLSetupTexturing(false);
3034 #if defined(SHADERS)
3035 shader_setMaterial(material, mesh.flags.colors);
3036 #elif defined(EM_MODE)
3037 glimtkColor4f(material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity);
3039 if(mesh.flags.colors)
3041 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3042 glEnable(GL_COLOR_MATERIAL);
3046 glDisable(GL_COLOR_MATERIAL);
3048 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3049 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3052 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3053 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3057 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3058 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3061 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3062 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3065 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3069 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3071 OGLMesh oglMesh = mesh.data;
3074 if(!mesh.flags.vertices)
3076 oglMesh.vertices.free();
3077 delete mesh.vertices;
3079 if(!mesh.flags.normals)
3081 oglMesh.normals.free();
3082 delete mesh.normals;
3084 if(!mesh.flags.texCoords1)
3086 oglMesh.texCoords.free();
3087 delete mesh.texCoords;
3089 if(!mesh.flags.texCoords2)
3091 oglMesh.texCoords2.free();
3092 // delete mesh.texCoords2;
3094 if(!mesh.flags.colors)
3096 oglMesh.colors.free();
3107 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3109 bool result = false;
3112 mesh.data = OGLMesh { };
3115 if(mesh.nVertices == nVertices)
3117 // Same number of vertices, adding features (Leaves the other features pointers alone)
3118 if(mesh.flags != flags)
3120 if(!mesh.flags.vertices && flags.vertices)
3122 if(flags.doubleVertices)
3124 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3127 mesh.vertices = new Vector3Df[nVertices];
3129 if(!mesh.flags.normals && flags.normals)
3131 if(flags.doubleNormals)
3133 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3136 mesh.normals = new Vector3Df[nVertices];
3138 if(!mesh.flags.texCoords1 && flags.texCoords1)
3140 mesh.texCoords = new Pointf[nVertices];
3142 if(!mesh.flags.colors && flags.colors)
3144 mesh.colors = new ColorRGBAf[nVertices];
3150 // New number of vertices, reallocate all current and new features
3151 flags |= mesh.flags;
3154 if(flags.doubleVertices)
3156 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3159 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3163 if(flags.doubleNormals)
3165 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3168 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3170 if(flags.texCoords1)
3172 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3176 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3184 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3186 OGLMesh oglMesh = mesh.data;
3187 if(!flags) flags = mesh.flags;
3192 oglMesh.vertices.upload(
3193 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3196 oglMesh.normals.upload(
3197 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3199 if(flags.texCoords1)
3200 oglMesh.texCoords.upload(
3201 mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3204 oglMesh.colors.upload(
3205 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3209 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3216 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3220 oglIndices.buffer.free();
3221 delete oglIndices.indices;
3226 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3228 OGLIndices oglIndices = OGLIndices { };
3231 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3232 oglIndices.nIndices = nIndices;
3237 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3244 if(!oglIndices.buffer.buffer)
3245 glGenBuffers(1, &oglIndices.buffer.buffer);
3246 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3247 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3248 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3252 oglIndices.buffer.upload(
3253 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3254 oglIndices.indices); //GL_STATIC_DRAW_ARB);
3258 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3261 return oglIndices.indices;
3264 void SelectMesh(Display display, Mesh mesh)
3266 //Logf("SelectMesh\n");
3268 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3270 #if defined(__WIN32__)
3271 if(glUnlockArraysEXT)
3273 if(!vboAvailable && display.display3D.mesh)
3274 glUnlockArraysEXT();
3279 OGLMesh oglMesh = mesh.data;
3281 // *** Vertex Stream ***
3282 glEnableClientState(GL_VERTEX_ARRAY);
3283 if(!display.display3D.collectingHits && oglMesh)
3285 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3287 // *** Normals Stream ***
3288 if(mesh.normals || mesh.flags.normals)
3290 glEnableClientState(GL_NORMAL_ARRAY);
3291 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3294 glDisableClientState(GL_NORMAL_ARRAY);
3296 // *** Texture Coordinates Stream ***
3297 if(mesh.texCoords || mesh.flags.texCoords1)
3299 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3300 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3303 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3305 // *** Color Stream ***
3306 if(mesh.colors || mesh.flags.colors)
3308 glEnableClientState(GL_COLOR_ARRAY);
3309 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3312 glDisableClientState(GL_COLOR_ARRAY);
3316 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3317 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3319 glEnableClientState(GL_NORMAL_ARRAY);
3320 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3323 glDisableClientState(GL_NORMAL_ARRAY);
3324 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3326 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3327 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3330 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3331 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3333 glEnableClientState(GL_COLOR_ARRAY);
3334 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3337 glDisableClientState(GL_COLOR_ARRAY);
3340 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3342 #if defined(__WIN32__)
3346 glLockArraysEXT(0, mesh.nVertices);
3352 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3354 //Logf("DrawPrimitives\n");
3356 if(primitive->type.vertexRange)
3357 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3360 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3361 // HACK TO SPEED THINGS UP...
3363 /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3364 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3367 glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
3370 OGLIndices oglIndices = primitive->data;
3371 MeshFeatures flags = mesh.flags;
3372 for(c = 0; c<primitive->nIndices; c++)
3374 uint16 index = ((uint16 *) oglIndices.indices)[c];
3375 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3376 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3377 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3378 glVertex3fv((float *)&mesh.vertices[index]);
3387 OGLIndices oglIndices = primitive->data;
3388 GLEAB eab = ((!display.display3D.collectingHits && oglIndices) ? oglIndices.buffer : noEAB);
3390 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3391 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3392 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3393 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3398 void PushMatrix(Display display)
3403 void PopMatrix(Display display, bool setMatrix)
3408 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3410 Matrix matrix = transMatrix;
3411 Camera camera = useCamera ? display.display3D.camera : null;
3416 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3421 matrix.m[3][0] - camera.cPosition.x,
3422 matrix.m[3][1] - camera.cPosition.y,
3423 matrix.m[3][2] - camera.cPosition.z);
3435 glMultMatrixd(matrix.array);
3440 public void UseSingleGLContext(bool useSingle)
3442 useSingleGLContext = useSingle;
3445 default dllexport void *
3446 #if defined(__WIN32__)
3447 __attribute__((stdcall))
3449 IS_GLGetContext(DisplaySystem displaySystem)
3453 #if defined(__WIN32__)
3454 OGLSystem system = displaySystem.driverData;
3456 #elif defined(__ANDROID__) || defined(__ODROID__)
3458 #elif defined(__EMSCRIPTEN__)
3460 OGLSystem system = displaySystem.driverData;
3461 return system.glContext;