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 static bool ::initialDisplaySetup(Display display)
1075 loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1077 glEnableClientState(GL_VERTEX_ARRAY);
1079 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1080 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1082 #if defined(__WIN32__)
1083 if(glBlendFuncSeparate)
1084 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1086 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1088 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1092 glMatrixMode(MatrixMode::modelView);
1093 glLoadIdentity(); // For setting up GLES stack
1094 glScaled(1.0, 1.0, -1.0);
1095 // glTranslatef(0.375f, 0.375f, 0.0f);
1096 // glTranslatef(-0.625f, -0.625f, 0.0f);
1097 glMatrixMode(MatrixMode::projection);
1098 #if !defined(EM_MODE) && !defined(SHADERS)
1099 glShadeModel(GL_FLAT);
1101 // #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1103 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1105 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1106 glFogi(GL_FOG_MODE, GL_EXP);
1107 glFogf(GL_FOG_DENSITY, 0);
1108 glEnable(GL_NORMALIZE);
1110 glDepthFunc(GL_LESS);
1112 glDisable(GL_MULTISAMPLE_ARB);
1113 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1114 display.ambient = Color { 50,50,50 };
1119 bool CreateDisplay(Display display)
1121 bool result = false;
1122 OGLDisplay oglDisplay = display.driverData;
1123 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
1124 OGLSystem oglSystem = display.displaySystem.driverData;
1128 oglDisplay = display.driverData = OGLDisplay { };
1129 //printf("Inside CreateDisplay\n");
1131 #if defined(__WIN32__) || defined(USEPBUFFER)
1132 if(!display.alphaBlend)
1135 #if defined(__WIN32__)
1136 oglDisplay.hdc = GetDC(display.window);
1137 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1138 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1140 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1141 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1145 ReleaseDC(display.window, oglDisplay.hdc);
1146 #elif defined(__unix__) || defined(__APPLE__)
1147 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1149 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1151 #if defined(__APPLE__)
1152 XVisualInfo template = { 0 };
1153 XWindowAttributes winAttr;
1155 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1156 template.visualid = XVisualIDFromVisual(winAttr.visual);
1157 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1159 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1160 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1161 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1162 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1164 // visualInfo = oglSystem.visualInfo;
1169 //printf("visualInfo is not null\n");
1170 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1171 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1172 //XFree(visualInfo);
1175 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1176 if(oglDisplay.glContext)
1178 //printf("CreateDisplay Got a Context\n");
1179 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1185 #if defined(__WIN32__) || defined(USEPBUFFER)
1189 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1194 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1195 ogl_LoadFunctions();
1197 CheckExtensions(oglSystem);
1198 vboAvailable = glBindBuffer != null;
1200 initialDisplaySetup(display);
1203 if(!useSingleGLContext)
1205 #if defined(__WIN32__)
1206 wglMakeCurrent(null, null);
1207 #elif defined(__unix__) || defined(__APPLE__)
1208 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1211 glXMakeCurrent(xGlobalDisplay, None, null);
1217 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1225 bool DisplaySize(Display display, int width, int height)
1227 OGLDisplay oglDisplay = display.driverData;
1229 bool result = false;
1231 //printf("Inside DisplaySize\n");
1232 #if defined(__WIN32__) || defined(USEPBUFFER)
1233 OGLSystem oglSystem = display.displaySystem.driverData;
1234 if(display.alphaBlend)
1236 #if defined(__WIN32__)
1237 const int attributes[]=
1239 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1240 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1242 int pixelFormat = 0;
1243 if(wglChoosePixelFormatARB)
1247 float fAttributes[] = {0,0};
1250 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1251 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1252 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1253 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1254 WGL_COLOR_BITS_ARB,24,
1255 WGL_ALPHA_BITS_ARB,8,
1256 WGL_DEPTH_BITS_ARB,16,
1257 WGL_STENCIL_BITS_ARB,0,
1258 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1259 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1260 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1264 //Log("Found wglChoosePixelFormatARB\n");
1266 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1267 if(!valid || !numFormats)
1269 //Log("Can't find 4x multi sampling\n");
1270 iAttributes[19] = 2;
1271 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1272 if(!valid || !numFormats)
1274 // Log("Can't find 2x multi sampling\n");
1275 iAttributes[16] = 0;
1276 iAttributes[17] = 0;
1277 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1278 if(!valid || !numFormats)
1282 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1283 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1284 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1285 WGL_COLOR_BITS_ARB,24,
1286 WGL_ALPHA_BITS_ARB,8,
1287 WGL_DEPTH_BITS_ARB,16,
1290 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1294 if(valid && numFormats)
1296 wglMakeCurrent(null, null);
1300 wglMakeCurrent( null, null );
1301 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1302 if(oglDisplay.hdc && oglDisplay.pBuffer)
1303 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1305 wglDestroyPbufferARB(oglDisplay.pBuffer);
1307 if(!useSingleGLContext)
1308 wglMakeCurrent( null, null );
1311 wglDeleteContext(oglDisplay.glrc);
1313 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1314 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1315 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1318 HDC hdc = GetDC(display.window);
1320 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1321 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1323 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1324 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1326 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1328 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1332 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1333 oglDisplay.memDC = CreateCompatibleDC(hdc);
1334 SetMapMode(oglDisplay.memDC, MM_TEXT);
1335 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1336 info->bmiHeader.biPlanes = 1;
1337 info->bmiHeader.biCompression = BI_RGB;
1338 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1339 info->bmiHeader.biWidth = width;
1340 info->bmiHeader.biHeight = height;
1341 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1344 SelectObject(oglDisplay.memDC, newBitmap);
1345 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1348 PIXELFORMATDESCRIPTOR pfd = { 0 };
1349 pfd.nSize = (short)sizeof(pfd);
1351 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1352 pfd.iPixelType = PFD_TYPE_RGBA;
1353 pfd.cColorBits = 32;
1354 //pfd.cAlphaBits = 8;
1355 pfd.cDepthBits = 24;
1356 pfd.iLayerType = PFD_MAIN_PLANE;
1358 oglDisplay.hdc = oglDisplay.memDC;
1360 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1361 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1362 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1364 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1365 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1366 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1371 const int imageSize = width * height * 4;
1373 glGenBuffersARB(2, oglDisplay.imageBuffers);
1375 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1376 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1377 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1378 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1381 oglDisplay.memBitmap = newBitmap;
1382 oglDisplay.stride = width;
1388 ReleaseDC(display.window, hdc);
1390 #elif defined(__unix__) || defined(__APPLE__)
1391 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1396 GLX_DOUBLEBUFFER, True,
1402 GLX_STENCIL_SIZE, 1,
1403 //GLX_DEPTH_SIZE, 24,
1404 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1405 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1411 GLX_PBUFFER_WIDTH, width,
1412 GLX_PBUFFER_HEIGHT, height,
1413 GLX_LARGEST_PBUFFER, False,
1417 // choose a pixel format that meets our minimum requirements
1420 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1423 if(oglDisplay.pixmap)
1425 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1426 oglDisplay.pixmap = None;
1428 if(oglDisplay.shapePixmap)
1430 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1431 oglDisplay.shapePixmap = None;
1434 // Free Shared Memory Pixmap
1435 if(oglDisplay.image)
1437 if(oglDisplay.shminfoShape.shmid != -1)
1439 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1440 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1441 shmdt(oglDisplay.shminfo.shmaddr);
1442 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1444 XDestroyImage(oglDisplay.image);
1445 oglDisplay.image = None;
1447 if(oglDisplay.shapeImage)
1449 if(oglDisplay.shminfoShape.shmid != -1)
1451 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1452 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1453 shmdt(oglDisplay.shminfoShape.shmaddr);
1454 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1456 XDestroyImage(oglDisplay.shapeImage);
1457 oglDisplay.shapeImage = None;
1460 if(oglDisplay.windowPicture)
1461 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1462 if(oglDisplay.pixmapPicture)
1463 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1465 if(oglDisplay.pixmap)
1466 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1468 if(oglDisplay.glContext)
1469 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1470 if(oglDisplay.pBuffer)
1471 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1473 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1474 if(oglDisplay.pBuffer)
1476 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1477 if(oglDisplay.glContext)
1479 glXMakeCurrent(xGlobalDisplay, None, null);
1480 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1482 // Initialize Shared Memory Pixmap
1483 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1484 ZPixmap, null, &oglDisplay.shminfo, width, height);
1485 if(oglDisplay.image)
1487 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1488 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1489 if(oglDisplay.shminfo.shmid != -1)
1491 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1492 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1494 oglDisplay.shminfo.readOnly = False;
1495 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1497 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1498 &oglDisplay.shminfo, width, height, 32);
1500 // Initialize Shared Memory Shape Pixmap
1501 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1502 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1503 if(oglDisplay.shapeImage)
1505 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1506 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1507 if(oglDisplay.shminfoShape.shmid != -1)
1509 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1510 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1512 oglDisplay.shminfoShape.readOnly = False;
1513 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1515 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1516 &oglDisplay.shminfoShape, width, height, 1);
1517 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1520 XRenderPictureAttributes attributes = { 0 };
1521 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1522 #if !defined(__APPLE__)
1523 attributes.repeat = RepeatNormal;
1525 attributes.repeat = 1;
1527 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1528 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1529 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1530 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1533 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1534 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1551 CreateDisplay(display);
1552 #if defined(__WIN32__)
1553 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1554 #elif defined(__unix__) || defined(__APPLE__)
1555 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1559 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1567 if(display.alphaBlend && result)
1568 initialDisplaySetup(display);
1570 if(!result && display.alphaBlend)
1572 printf("Alpha blending windows not supported on this display\n");
1579 glViewport(0,0,width,height);
1580 glMatrixMode(MatrixMode::projection);
1582 glOrtho(0,width,height,0,0.0,1.0);
1583 displayWidth = display.width = width;
1584 displayHeight = display.height = height;
1586 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1588 oglDisplay.flipBufW = width;
1589 oglDisplay.flipBufH = height;
1593 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1596 if(oglDisplay.flippingBuffer || !width || !height)
1602 void DisplayPosition(Display display, int x, int y)
1604 OGLDisplay oglDisplay = display.driverData;
1610 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1614 void RestorePalette(Display display)
1618 void StartUpdate(Display display)
1622 void EndUpdate(Display display)
1626 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1630 void Update(Display display, Box updateBox)
1632 #if defined(__WIN32__) || defined(USEPBUFFER)
1633 OGLDisplay oglDisplay = display.driverData;
1635 //Logf("DisplayScreen\n");
1637 #if !defined(__ANDROID__)
1642 #if defined(__WIN32__) || defined(USEPBUFFER)
1643 if(display.alphaBlend)
1645 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1646 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1647 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1648 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1649 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1652 #if defined(__WIN32__)
1654 POINT point = { oglDisplay.x, oglDisplay.y};
1655 POINT srcPoint = { 0, 0 };
1656 BLENDFUNCTION blend = { 0 };
1658 size.cx = display.width;
1659 size.cy = display.height;
1660 blend.BlendOp = AC_SRC_OVER;
1661 blend.BlendFlags = 0;
1662 blend.SourceConstantAlpha = 255;
1663 blend.AlphaFormat = AC_SRC_ALPHA;
1666 // Process partial images. Mapping the buffer waits for
1667 // outstanding DMA transfers into the buffer to finish.
1668 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1669 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1671 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1672 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1675 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1676 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1679 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1682 // Unmap the image buffers
1683 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1684 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1686 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1687 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1689 // Bind two different buffer objects and start the glReadPixels
1690 // asynchronously. Each call will return directly after
1691 // starting the DMA transfer.
1692 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1693 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1695 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1696 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1700 #elif defined(__unix__) || defined(__APPLE__)
1701 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1703 XTransform transform =
1706 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1707 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1708 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1711 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1712 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1713 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1714 #if !defined(__APPLE__)
1715 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1717 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1719 XFlush(xGlobalDisplay);
1727 #if defined(__WIN32__)
1728 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1729 SwapBuffers(oglDisplay.hdc);
1730 #elif defined(__unix__) || defined(__APPLE__)
1731 #if defined(__ANDROID__) || defined(__ODROID__)
1733 #elif defined(__EMSCRIPTEN__)
1736 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1740 //Logf("Out of DisplayScreen\n");
1743 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1745 if(bitmap.driverData)
1747 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1748 glDeleteTextures(1, &tex);
1749 bitmap.driverData = 0;
1751 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1754 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1756 OGLSystem oglSystem = displaySystem.driverData;
1757 bool result = false;
1759 GLuint glBitmap = 0;
1761 uint w = width, h = height;
1762 if(oglSystem.pow2textures)
1767 w = Min(w, oglSystem.maxTextureSize);
1768 h = Min(h, oglSystem.maxTextureSize);
1770 glGenTextures(1, &glBitmap);
1771 glBindTexture(GL_TEXTURE_2D, glBitmap);
1773 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1775 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1776 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1778 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1779 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1781 #if !defined(SHADERS)
1782 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1785 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1787 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1788 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1792 bitmap.driverData = (void *)(uintptr)glBitmap;
1793 bitmap.driver = displaySystem.driver;
1801 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1803 bool result = false;
1804 OGLSystem oglSystem = displaySystem.driverData;
1805 Bitmap convBitmap = bitmap;
1809 convBitmap.Copy(bitmap);
1812 // Pre process the bitmap... First make it 32 bit
1813 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1816 uint w = bitmap.width, h = bitmap.height;
1817 GLuint glBitmap = 0;
1818 if(oglSystem.pow2textures)
1823 w = Min(w, oglSystem.maxTextureSize);
1824 h = Min(h, oglSystem.maxTextureSize);
1828 while(w * 2 < h) w *= 2;
1829 while(h * 2 < w) h *= 2;
1832 // Switch ARGB to RGBA
1833 //if(bitmap.format != pixelFormatRGBA)
1835 for(c=0; c<bitmap.size; c++)
1837 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1839 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1840 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1843 // convBitmap.pixelFormat = pixelFormat888;
1846 glGenTextures(1, &glBitmap);
1849 //int error = glGetError();
1853 glBindTexture(GL_TEXTURE_2D, glBitmap);
1854 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1856 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1857 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1859 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1861 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1862 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1864 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1865 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1866 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1867 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1870 #if !defined(SHADERS)
1871 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1876 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1881 if(bitmap.width != w || bitmap.height != h)
1883 mipMap = Bitmap { };
1884 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1886 Surface mipSurface = mipMap.GetSurface(0,0,null);
1887 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1897 mipMap = convBitmap;
1904 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1905 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1906 //printf("Calling glTexImage2D\n");
1907 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
1908 //printf("width = %d (Should be %d, %d)\n", width, w, h);
1909 if((error = glGetError()))
1911 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
1912 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
1916 if(mipMap != convBitmap)
1921 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
1922 bitmap.driverData = (void *)(uintptr)glBitmap;
1923 bitmap.driver = displaySystem.driver;
1928 FreeBitmap(displaySystem, bitmap);
1929 else if(oglSystem.loadingFont)
1931 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1932 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1933 oglSystem.loadingFont = false;
1939 void ReleaseSurface(Display display, Surface surface)
1941 glDisable(GL_SCISSOR_TEST);
1942 delete surface.driverData;
1943 surface.driverData = null;
1946 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
1951 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
1953 bool result = false;
1954 OGLSurface oglSurface = surface.driverData = OGLSurface { };
1956 //Logf("GetSurface\n");
1960 if(displayWidth != display.width || displayHeight != display.height)
1962 displayWidth = display.width;
1963 displayHeight = display.height;
1965 glViewport(0,0,display.width,display.height);
1967 glOrtho(0,display.width,display.height,0,0.0,1.0);
1970 surface.offset.x = x;
1971 surface.offset.y = y;
1972 surface.unclippedBox = surface.box = clip;
1973 oglSurface.bitmapMult[0] = 1;
1974 oglSurface.bitmapMult[1] = 1;
1975 oglSurface.bitmapMult[2] = 1;
1976 oglSurface.bitmapMult[3] = 1;
1978 glEnable(GL_SCISSOR_TEST);
1981 (display.height) -(y+clip.bottom)-1,
1982 clip.right-clip.left+1,
1983 clip.bottom-clip.top+1);
1989 void Clip(Display display, Surface surface, Box clip)
1998 box.Clip(surface.unclippedBox);
2002 box = surface.box = surface.unclippedBox;
2003 box.left += surface.offset.x;
2004 box.top += surface.offset.y;
2005 box.right+= surface.offset.x;
2006 box.bottom += surface.offset.y;
2009 box.left,display.height - box.bottom - 1,
2010 box.right-box.left+1, box.bottom-box.top+1);
2013 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2015 bool result = false;
2016 OGLDisplay oglDisplay = display.driverData;
2017 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2019 if(oglDisplay.flippingBuffer)
2021 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2024 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2030 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2031 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2032 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2033 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2034 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2037 for(row = 0; row<h; row++)
2038 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2045 void SetForeground(Display display, Surface surface, ColorAlpha color)
2047 OGLSurface oglSurface = surface.driverData;
2049 //Logf("SetForeground\n");
2051 oglSurface.foreground[0] = color.color.r/255.0f;
2052 oglSurface.foreground[1] = color.color.g/255.0f;
2053 oglSurface.foreground[2] = color.color.b/255.0f;
2054 //oglSurface.foreground[3] = 1.0f;
2055 oglSurface.foreground[3] = color.a/255.0f;
2057 //if(!oglSurface.foreground[3])printf("bug");
2060 void SetBackground(Display display, Surface surface, ColorAlpha color)
2062 OGLSurface oglSurface = surface.driverData;
2064 //Logf("SetBackground\n");
2066 oglSurface.background[0] = color.color.r/255.0f;
2067 oglSurface.background[1] = color.color.g/255.0f;
2068 oglSurface.background[2] = color.color.b/255.0f;
2069 //oglSurface.background[3] = 1.0;
2070 oglSurface.background[3] = color.a/255.0f;
2073 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2075 OGLSurface oglSurface = surface.driverData;
2077 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2078 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2079 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2080 oglSurface.bitmapMult[3] = color.a/255.0f;
2083 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2088 void PutPixel(Display display, Surface surface,int x,int y)
2090 OGLSurface oglSurface = surface.driverData;
2092 //Logf("PutPixel\n");
2094 glColor4fv(oglSurface.foreground);
2096 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2097 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2102 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2104 OGLSurface oglSurface = surface.driverData;
2105 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2120 x1 += surface.offset.x;
2121 y1 += surface.offset.y;
2122 x2 += surface.offset.x;
2123 y2 += surface.offset.y;
2127 glColor4fv(oglSurface.foreground);
2129 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2132 glTexCoord2f(0.5f, 0);
2133 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2134 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2135 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2144 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2145 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2151 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2153 OGLSurface oglSurface = surface.driverData;
2154 x1 += surface.offset.x;
2155 y1 += surface.offset.y;
2156 x2 += surface.offset.x;
2157 y2 += surface.offset.y;
2159 //Logf("Rectangle\n");
2161 glColor4fv(oglSurface.foreground);
2162 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2167 glTexCoord2f(0.5f, 0);
2168 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2169 glTexCoord2f(y2-y1 + 0.5f, 0);
2170 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2172 glTexCoord2f(0.5f, 0);
2173 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2174 glTexCoord2f(x2 - x1 + 0.5f, 0);
2175 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2177 glTexCoord2f(0.5f, 0);
2178 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2179 glTexCoord2f(y1 - y2 + 0.5f, 0);
2180 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2182 glTexCoord2f(0.5f, 0);
2183 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2184 glTexCoord2f(x1 - x2 + 0.5f, 0);
2185 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2190 glBegin(GL_LINE_LOOP);
2197 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2198 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2199 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2200 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2205 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2207 OGLSurface oglSurface = surface.driverData;
2210 glColor4fv(oglSurface.background);
2214 glVertex2f(x1+surface.offset.x, y1+surface.offset.y);
2215 glVertex2f(x1+surface.offset.x, y2+surface.offset.y+1);
2216 glVertex2f(x2+surface.offset.x+1, y2+surface.offset.y+1);
2217 glVertex2f(x2+surface.offset.x+1, y1+surface.offset.y);
2220 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2221 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2224 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2225 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2229 void Clear(Display display, Surface surface, ClearType type)
2231 OGLDisplay oglDisplay = display.driverData;
2232 OGLSurface oglSurface = surface.driverData;
2235 if(type != depthBuffer)
2236 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2237 if(type != colorBuffer && !oglDisplay.depthWrite)
2239 glDepthMask((byte)bool::true);
2241 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2242 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2243 if(type != colorBuffer && !oglDisplay.depthWrite)
2245 glDepthMask((byte)bool::false);
2249 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2254 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2256 OGLSurface oglSurface = surface.driverData;
2258 if(!oglSurface.writingText)
2260 // glTranslatef(-0.375f, -0.375f, 0.0f);
2261 GLSetupTexturing(true);
2262 glColor4fv(oglSurface.bitmapMult);
2264 else if(oglSurface.xOffset)
2265 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2267 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2268 glBegin(GLIMTKMode::quads);
2272 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2273 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2274 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2275 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2276 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2277 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2278 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2279 glVertex2i(dx+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+surface.offset.y);
2286 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2287 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2288 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2289 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2290 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2291 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2294 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2295 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2296 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2297 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2298 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2299 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2300 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2301 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2305 if(!oglSurface.writingText)
2307 GLSetupTexturing(false);
2309 //glTranslate(0.375, 0.375, 0.0);
2311 else if(oglSurface.xOffset)
2312 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2315 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2317 OGLSurface oglSurface = surface.driverData;
2319 //glTranslate(-0.375, -0.375, 0.0);
2321 GLSetupTexturing(true);
2322 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2324 glColor4fv(oglSurface.bitmapMult);
2326 glBegin(GLIMTKMode::quads);
2330 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2331 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2333 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2334 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2336 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2337 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2339 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2340 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2344 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2345 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2347 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2348 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2350 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2351 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2353 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2354 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2359 GLSetupTexturing(false);
2361 //glTranslate(0.375, 0.375, 0.0);
2364 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2366 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2369 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2371 #if !defined(EM_MODE)
2372 float s2dw,s2dh,d2sw,d2sh;
2373 //bool flipX = false, flipY = false;
2375 //Logf("StretchDI\n");
2377 if(Sgn(w) != Sgn(sw))
2383 if(Sgn(h) != Sgn(sh))
2395 //Clip against the edges of the source
2398 dx+=(int)((0-sx) * s2dw);
2399 w-=(int)((0-sx) * s2dw);
2405 dy+=(int)((0-sy) * s2dh);
2406 h-=(int)((0-sy) * s2dh);
2411 if(sx+sw>bitmap.width-1)
2413 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2414 sw-=sx+sw-(bitmap.width-1)-1;
2416 if(sy+sh>(bitmap.height-1))
2418 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2419 sh-=sy+sh-(bitmap.height-1)-1;
2421 //Clip against the edges of the surfaceination
2422 if(dx<surface.box.left)
2425 sx+=(int)((surface.box.left-dx)*d2sw);
2426 sw-=(int)((surface.box.left-dx)*d2sw);
2427 w-=surface.box.left-dx;
2428 dx=surface.box.left;
2430 if(dy<surface.box.top)
2432 sy+=(int)((surface.box.top-dy)*d2sh);
2433 sh-=(int)((surface.box.top-dy)*d2sh);
2434 h-=surface.box.top-dy;
2437 if(dx+w>surface.box.right)
2439 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2440 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2441 w-=dx+w-surface.box.right-1;
2443 if(dy+h>surface.box.bottom)
2445 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2446 h-=dy+h-surface.box.bottom-1;
2448 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2450 dx += surface.offset.x;
2451 dy += surface.offset.y;
2453 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2455 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2456 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2457 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2458 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2459 #if !defined(SHADERS)
2460 glRasterPos2d(dx,dy);
2461 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2462 glPixelZoom(s2dw, -s2dh);
2463 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2465 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2466 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2467 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2468 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2473 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2475 #if !defined(EM_MODE)
2478 //Clip against the edges of the source
2491 if(sx+w>bitmap.width-1)
2492 w-=sx+w-(bitmap.width-1)-1;
2493 if(sy+h>bitmap.height-1)
2494 h-=sy+h-(bitmap.height-1)-1;
2495 //Clip against the edges of the surfaceination
2496 if(dx<surface.box.left)
2499 sx+=surface.box.left-dx;
2500 w-=surface.box.left-dx;
2501 dx=surface.box.left;
2503 if(dy<surface.box.top)
2505 sy+=surface.box.top-dy;
2506 h-=surface.box.top-dy;
2509 if(dx+w>surface.box.right)
2511 //if(flip) sx+=dx+w-surface.box.right-1;
2512 w-=dx+w-surface.box.right-1;
2514 if(dy+h>surface.box.bottom)
2515 h-=dy+h-surface.box.bottom-1;
2519 dx += surface.offset.x;
2520 dy += surface.offset.y;
2522 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2524 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2525 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2526 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2527 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2528 #if !defined(SHADERS)
2529 glRasterPos2d(dx,dy);
2531 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2533 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2534 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2535 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2536 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2541 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2543 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2546 void UnloadFont(DisplaySystem displaySystem, Font font)
2548 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2551 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2554 OGLSystem oglSystem = displaySystem.driverData;
2555 oglSystem.loadingFont = true;
2556 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2560 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2562 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2565 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2567 OGLSurface oglSurface = surface.driverData;
2568 OGLSystem oglSystem = display.displaySystem.driverData;
2569 oglSystem.loadingFont = true;
2571 //glTranslated(-0.375, -0.375, 0.0);
2575 if(surface.textOpacity)
2578 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2580 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2583 oglSurface.writingText = true;
2585 GLSetupTexturing(true);
2587 if(surface.font.outlineSize)
2589 ColorAlpha outlineColor = surface.outlineColor;
2590 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2591 oglSurface.writingOutline = true;
2592 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2593 oglSurface.writingOutline = false;
2595 glColor4fv(oglSurface.foreground);
2597 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2598 oglSurface.writingText = false;
2599 oglSystem.loadingFont = false;
2601 GLSetupTexturing(false);
2603 //glTranslated(0.375, 0.375, 0.0);
2606 void TextFont(Display display, Surface surface, Font font)
2608 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2611 void TextOpacity(Display display, Surface surface, bool opaque)
2613 OGLSurface oglSurface = surface.driverData;
2614 oglSurface.opaqueText = opaque;
2617 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2619 OGLSurface oglSurface = surface.driverData;
2620 OGLSystem oglSystem = display.displaySystem.driverData;
2621 oglSystem.loadingFont = true;
2622 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2623 oglSystem.loadingFont = false;
2626 void DrawingChar(Display display, Surface surface, char character)
2631 void LineStipple(Display display, Surface surface, uint32 stipple)
2633 //Logf("Stipple\n");
2637 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2638 stippleEnabled = true;
2639 glesLineStipple(1, (uint16)stipple);
2641 glLineStipple(1, (uint16)stipple);
2642 glEnable(GL_LINE_STIPPLE);
2647 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2648 stippleEnabled = false;
2649 glMatrixMode(GL_TEXTURE);
2651 glMatrixMode(MatrixMode::projection);
2652 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2654 glDisable(GL_LINE_STIPPLE);
2658 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2659 void SetRenderState(Display display, RenderState state, uint value)
2661 OGLDisplay oglDisplay = display.driverData;
2662 //Logf("RenderState\n");
2668 glEnable(GL_MULTISAMPLE_ARB);
2670 glDisable(GL_MULTISAMPLE_ARB);
2674 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2678 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2681 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2682 oglDisplay.depthWrite = (bool)value;
2686 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2687 #if defined(SHADERS)
2688 shader_fogColor(color[0], color[1], color[2]);
2690 glFogfv(GL_FOG_COLOR, (float *)&color);
2695 #if defined(SHADERS)
2696 shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2698 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2702 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2706 #if defined(SHADERS)
2707 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2708 #elif !defined(EM_MODE)
2709 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2710 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2716 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2721 #if defined(__WIN32__)
2722 wglSwapIntervalEXT(value ? 1 : 0);
2729 void SetLight(Display display, int id, Light light)
2731 #if defined(SHADERS)
2732 shader_setLight(display, id, light);
2733 #elif !defined(EM_MODE)
2734 //Logf("SetLight\n");
2738 Object lightObject = light.lightObject;
2739 float position[4] = { 0, 0, 0, 0 };
2740 float color[4] = { 0, 0, 0, 1 };
2742 glEnable(GL_LIGHT0 + id);
2744 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
2745 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
2746 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
2749 if(!light.multiplier) light.multiplier = 1.0f;
2751 color[0] = light.diffuse.r * light.multiplier;
2752 color[1] = light.diffuse.g * light.multiplier;
2753 color[2] = light.diffuse.b * light.multiplier;
2754 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2756 color[0] = light.ambient.r * light.multiplier;
2757 color[1] = light.ambient.g * light.multiplier;
2758 color[2] = light.ambient.b * light.multiplier;
2759 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2760 color[0] = light.specular.r * light.multiplier;
2761 color[1] = light.specular.g * light.multiplier;
2762 color[2] = light.specular.b * light.multiplier;
2763 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2767 Vector3D positionVector;
2768 if(light.flags.spot)
2770 if(lightObject.flags.root || !lightObject.parent)
2772 positionVector = lightObject.transform.position;
2773 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2777 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2778 if(display.display3D.camera)
2779 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2785 if(!light.direction.x && !light.direction.y && !light.direction.z)
2787 Vector3Df vector { 0,0,-1 };
2789 mat.RotationQuaternion(light.orientation);
2790 positionVector.MultMatrixf(vector, mat);
2794 positionVector = light.direction;
2799 position[0] = (float)positionVector.x;
2800 position[1] = (float)positionVector.y;
2801 position[2] = (float)positionVector.z;
2803 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2806 // Display Light Position
2807 glDisable(GL_LIGHTING);
2808 glDisable(GL_DEPTH_TEST);
2812 glVertex3fv(position);
2814 glEnable(GL_DEPTH_TEST);
2815 glEnable(GL_LIGHTING);
2819 if(lightObject.flags.root || !lightObject.parent)
2821 positionVector = light.target.transform.position;
2822 positionVector.Subtract(positionVector, display.camera.cPosition);
2826 positionVector.MultMatrix(light.target.transform.position,
2827 lightObject.light.target.parent.matrix);
2828 positionVector.Subtract(positionVector, display.camera.cPosition);
2831 position[0] = positionVector.x;
2832 position[1] = positionVector.y;
2833 position[2] = positionVector.z;
2835 glDisable(GL_LIGHTING);
2836 glDisable(GL_DEPTH_TEST);
2840 glVertex3fv(position);
2842 glEnable(GL_DEPTH_TEST);
2843 glEnable(GL_LIGHTING);
2846 if(light.flags.attenuation)
2848 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2849 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2850 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2853 if(light.flags.spot)
2856 #define MAXLIGHT 0.9
2857 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2858 // Figure out exponent out of the hot spot
2859 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2861 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2862 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2863 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2868 Vector3Df vector { 0,0,-1 };
2869 Vector3Df direction;
2872 mat.RotationQuaternion(light.orientation);
2873 direction.MultMatrix(vector, mat);
2875 position[0] = direction.x;
2876 position[1] = direction.y;
2877 position[2] = direction.z;
2879 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2883 glDisable(GL_LIGHT0 + id);
2887 void SetCamera(Display display, Surface surface, Camera camera)
2889 OGLDisplay oglDisplay = display.driverData;
2890 //Logf("SetCamera\n");
2892 if(surface && camera)
2894 int left = surface.box.left + surface.offset.x;
2895 int top = surface.box.top + surface.offset.y;
2896 int right = surface.box.right + surface.offset.x;
2897 int bottom = surface.box.bottom + surface.offset.y;
2898 float origX = surface.offset.x + camera.origin.x;
2899 float origY = surface.offset.y + camera.origin.y;
2901 int y = display.height - bottom - 1;
2902 int w = right - left + 1;
2903 int h = bottom - top + 1;
2906 glViewport(x, y, w, h);
2908 // *** Projection Matrix ***
2909 glMatrixMode(MatrixMode::projection);
2910 if(!display.display3D.camera)
2913 if(display.display3D.collectingHits)
2915 float pickX = display.display3D.pickX + surface.offset.x;
2916 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
2920 w / display.display3D.pickWidth, 0, 0, 0,
2921 0, h / display.display3D.pickHeight, 0, 0,
2923 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
2924 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
2927 glLoadMatrixd(pickMatrix.array);
2932 (left - origX) * camera.zMin / camera.focalX,
2933 (right - origX) * camera.zMin / camera.focalX,
2934 (bottom - origY) * camera.zMin / camera.focalY,
2935 (top - origY) * camera.zMin / camera.focalY,
2936 camera.zMin, camera.zMax);
2938 glDisable(GL_BLEND);
2940 // *** Z Inverted Identity Matrix ***
2941 glMatrixMode(MatrixMode::modelView);
2942 if(!display.display3D.camera)
2947 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
2949 // *** View Matrix ***
2950 glMultMatrixd(camera.viewMatrix.array);
2955 glEnable(GL_DEPTH_TEST);
2957 GLSetupLighting(true);
2958 #if !defined(EM_MODE) && !defined(SHADERS)
2959 glShadeModel(GL_SMOOTH);
2961 glDepthMask((byte)bool::true);
2962 oglDisplay.depthWrite = true;
2964 glEnable(GL_MULTISAMPLE_ARB);
2966 else if(surface && display.display3D.camera)
2969 oglDisplay.depthWrite = false;
2970 glViewport(0,0,display.width,display.height);
2972 glDisable(GL_CULL_FACE);
2973 glDisable(GL_DEPTH_TEST);
2975 GLSetupTexturing(false);
2976 GLSetupLighting(false);
2979 glDisableClientState(GL_COLOR_ARRAY);
2981 #if !defined(SHADERS) && !defined(EM_MODE)
2982 glShadeModel(GL_FLAT);
2985 glDisable(GL_MULTISAMPLE_ARB);
2987 // *** Restore 2D MODELVIEW Matrix ***
2990 // *** Restore 2D PROJECTION Matrix ***
2991 glMatrixMode(MatrixMode::projection);
2997 void ApplyMaterial(Display display, Material material, Mesh mesh)
2999 //Logf("ApplyMaterial\n");
3002 if(material.flags.doubleSided)
3004 #if !defined(EM_MODE) && !defined(SHADERS)
3005 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3007 glDisable(GL_CULL_FACE);
3011 #if !defined(EM_MODE) && !defined(SHADERS)
3012 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3014 glEnable(GL_CULL_FACE);
3018 GLSetupFog(!material.flags.noFog);
3021 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3023 Bitmap map = material.baseMap;
3024 GLSetupTexturing(true);
3025 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3027 glMatrixMode(GL_TEXTURE);
3029 if(material.uScale && material.vScale)
3030 glScalef(material.uScale, material.vScale, 1);
3031 glMatrixMode(MatrixMode::modelView);
3033 if(material.flags.tile)
3035 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3036 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3040 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3041 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3045 GLSetupTexturing(false);
3047 #if defined(SHADERS)
3048 shader_setMaterial(material, mesh.flags.colors);
3049 #elif defined(EM_MODE)
3050 glimtkColor4f(material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity);
3052 if(mesh.flags.colors)
3054 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3055 glEnable(GL_COLOR_MATERIAL);
3059 glDisable(GL_COLOR_MATERIAL);
3061 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3062 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3065 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3066 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3070 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3071 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3074 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3075 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3078 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3082 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3084 OGLMesh oglMesh = mesh.data;
3087 if(!mesh.flags.vertices)
3089 oglMesh.vertices.free();
3090 delete mesh.vertices;
3092 if(!mesh.flags.normals)
3094 oglMesh.normals.free();
3095 delete mesh.normals;
3097 if(!mesh.flags.texCoords1)
3099 oglMesh.texCoords.free();
3100 delete mesh.texCoords;
3102 if(!mesh.flags.texCoords2)
3104 oglMesh.texCoords2.free();
3105 // delete mesh.texCoords2;
3107 if(!mesh.flags.colors)
3109 oglMesh.colors.free();
3120 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3122 bool result = false;
3125 mesh.data = OGLMesh { };
3128 if(mesh.nVertices == nVertices)
3130 // Same number of vertices, adding features (Leaves the other features pointers alone)
3131 if(mesh.flags != flags)
3133 if(!mesh.flags.vertices && flags.vertices)
3135 if(flags.doubleVertices)
3137 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3140 mesh.vertices = new Vector3Df[nVertices];
3142 if(!mesh.flags.normals && flags.normals)
3144 if(flags.doubleNormals)
3146 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3149 mesh.normals = new Vector3Df[nVertices];
3151 if(!mesh.flags.texCoords1 && flags.texCoords1)
3153 mesh.texCoords = new Pointf[nVertices];
3155 if(!mesh.flags.colors && flags.colors)
3157 mesh.colors = new ColorRGBAf[nVertices];
3163 // New number of vertices, reallocate all current and new features
3164 flags |= mesh.flags;
3167 if(flags.doubleVertices)
3169 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3172 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3176 if(flags.doubleNormals)
3178 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3181 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3183 if(flags.texCoords1)
3185 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3189 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3197 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3199 OGLMesh oglMesh = mesh.data;
3200 if(!flags) flags = mesh.flags;
3205 oglMesh.vertices.upload(
3206 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3209 oglMesh.normals.upload(
3210 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3212 if(flags.texCoords1)
3213 oglMesh.texCoords.upload(
3214 mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3217 oglMesh.colors.upload(
3218 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3222 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3229 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3233 oglIndices.buffer.free();
3234 delete oglIndices.indices;
3239 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3241 OGLIndices oglIndices = OGLIndices { };
3244 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3245 oglIndices.nIndices = nIndices;
3250 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3257 if(!oglIndices.buffer.buffer)
3258 glGenBuffers(1, &oglIndices.buffer.buffer);
3259 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3260 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3261 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3265 oglIndices.buffer.upload(
3266 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3267 oglIndices.indices); //GL_STATIC_DRAW_ARB);
3271 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3274 return oglIndices.indices;
3277 void SelectMesh(Display display, Mesh mesh)
3279 //Logf("SelectMesh\n");
3281 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3283 #if defined(__WIN32__)
3284 if(glUnlockArraysEXT)
3286 if(!vboAvailable && display.display3D.mesh)
3287 glUnlockArraysEXT();
3292 OGLMesh oglMesh = mesh.data;
3294 // *** Vertex Stream ***
3295 glEnableClientState(GL_VERTEX_ARRAY);
3296 if(!display.display3D.collectingHits && oglMesh)
3298 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3300 // *** Normals Stream ***
3301 if(mesh.normals || mesh.flags.normals)
3303 glEnableClientState(GL_NORMAL_ARRAY);
3304 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3307 glDisableClientState(GL_NORMAL_ARRAY);
3309 // *** Texture Coordinates Stream ***
3310 if(mesh.texCoords || mesh.flags.texCoords1)
3312 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3313 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3316 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3318 // *** Color Stream ***
3319 if(mesh.colors || mesh.flags.colors)
3321 glEnableClientState(GL_COLOR_ARRAY);
3322 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3325 glDisableClientState(GL_COLOR_ARRAY);
3329 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3330 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3332 glEnableClientState(GL_NORMAL_ARRAY);
3333 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3336 glDisableClientState(GL_NORMAL_ARRAY);
3337 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3339 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3340 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3343 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3344 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3346 glEnableClientState(GL_COLOR_ARRAY);
3347 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3350 glDisableClientState(GL_COLOR_ARRAY);
3353 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3355 #if defined(__WIN32__)
3359 glLockArraysEXT(0, mesh.nVertices);
3365 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3367 //Logf("DrawPrimitives\n");
3369 if(primitive->type.vertexRange)
3370 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3373 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3374 // HACK TO SPEED THINGS UP...
3376 /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3377 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3380 glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
3383 OGLIndices oglIndices = primitive->data;
3384 MeshFeatures flags = mesh.flags;
3385 for(c = 0; c<primitive->nIndices; c++)
3387 uint16 index = ((uint16 *) oglIndices.indices)[c];
3388 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3389 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3390 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3391 glVertex3fv((float *)&mesh.vertices[index]);
3400 OGLIndices oglIndices = primitive->data;
3401 GLEAB eab = ((!display.display3D.collectingHits && oglIndices) ? oglIndices.buffer : noEAB);
3403 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3404 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3405 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3406 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3411 void PushMatrix(Display display)
3416 void PopMatrix(Display display, bool setMatrix)
3421 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3423 Matrix matrix = transMatrix;
3424 Camera camera = useCamera ? display.display3D.camera : null;
3429 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3434 matrix.m[3][0] - camera.cPosition.x,
3435 matrix.m[3][1] - camera.cPosition.y,
3436 matrix.m[3][2] - camera.cPosition.z);
3448 glMultMatrixd(matrix.array);
3453 public void UseSingleGLContext(bool useSingle)
3455 useSingleGLContext = useSingle;
3458 default dllexport void *
3459 #if defined(__WIN32__)
3460 __attribute__((stdcall))
3462 IS_GLGetContext(DisplaySystem displaySystem)
3466 #if defined(__WIN32__)
3467 OGLSystem system = displaySystem.driverData;
3469 #elif defined(__ANDROID__) || defined(__ODROID__)
3471 #elif defined(__EMSCRIPTEN__)
3473 OGLSystem system = displaySystem.driverData;
3474 return system.glContext;