3 namespace gfx::drivers;
11 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
13 # include "gl_core_3_3.h"
15 # include "gl_compat_4_4.h"
19 #if defined(__ANDROID__) || defined(__ODROID__)
28 #define GL_BGRA_EXT 0x80E1
32 #undef glEnableClientState
33 #undef glDisableClientState
34 #undef GL_VERTEX_ARRAY
35 #undef GL_NORMAL_ARRAY
36 #undef GL_TEXTURE_COORD_ARRAY
39 #define glEnableClientState glEnableVertexAttribArray
40 #define glDisableClientState glDisableVertexAttribArray
41 #define GL_VERTEX_ARRAY GLBufferContents::vertex
42 #define GL_NORMAL_ARRAY GLBufferContents::normal
43 #define GL_TEXTURE_COORD_ARRAY GLBufferContents::texCoord
44 #define GL_COLOR_ARRAY GLBufferContents::color
48 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
50 #if defined(__unix__) || defined(__APPLE__)
52 #if !defined(__MINGW32__)
53 #define GL_GLEXT_PROTOTYPES
56 #define pointer _pointer
59 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
61 #define property _property
65 #define Window X11Window
66 #define Cursor X11Cursor
68 #define Display X11Display
70 #define KeyCode X11KeyCode
71 #define Picture X11Picture
75 #include <X11/Xutil.h>
77 #include <X11/extensions/XShm.h>
80 #include <X11/extensions/Xrender.h>
81 #include <X11/extensions/shape.h>
99 #if defined(__APPLE__)
100 #include <OpenGl/gl.h>
103 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
105 #if defined(__WIN32__)
106 //#define WIN32_LEAN_AND_MEAN
108 #define _WIN32_WINNT 0x0502
109 #define String Sting_
114 #if defined(__ANDROID__) || defined(__ODROID__)
115 #if defined(__ODROID__) && !defined(ES1_1)
120 #define property _property
123 #define Window X11Window
124 #define Cursor X11Cursor
126 #define Display X11Display
128 #define KeyCode X11KeyCode
129 #define Picture X11Picture
147 #elif defined(__EMSCRIPTEN__)
151 #define property _property
155 //#include <GLES/gl.h>
156 #include <GLES2/gl2.h>
158 #include <emscripten/emscripten.h>
159 #include <emscripten/html5.h>
172 #if defined(__unix__) || defined(__APPLE__)
174 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
180 #define glLoadMatrix glLoadMatrixd
181 #define glMultMatrix glMultMatrixd
182 #define glGetMatrix glGetDoublev
183 #define glTranslate glTranslated
184 #define glScale glScaled
187 #define glVertex3v glVertex3dv
188 #define glNormal3v glNormal3dv
192 //#ifdef VERTEX_FORMAT_DOUBLE
194 #define glLoadMatrix glLoadMatrixd
195 #define glMultMatrix glMultMatrixd
196 #define glGetMatrix glGetDoublev
197 #define glVertex3v glVertex3dv
198 #define glNormal3v glNormal3dv
199 #define glTranslate glTranslated
200 #define glScale glScaled
201 //#define GL_VERTEX_FORMAT GL_DOUBLE
205 #define glLoadMatrix glLoadMatrixf
206 #define glMultMatrix glMultMatrixf
207 #define glGetMatrix glGetFloatv
208 #define glVertex3v glVertex3fv
209 #define glNormal3v glNormal3fv
210 #define glTranslate glTranslatef
211 #define glScale glScalef
212 //#define GL_VERTEX_FORMAT GL_FLOAT
217 #define GL_ARRAY_BUFFER_ARB 0x8892
218 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
219 #define GL_STATIC_DRAW_ARB 0x88E4
220 #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
221 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
223 #define GL_MULTISAMPLE_ARB 0x809D
225 #if defined(__WIN32__)
228 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
229 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
231 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
232 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
234 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
235 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
236 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
237 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
238 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
239 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
240 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
241 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
242 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
243 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = null;
244 static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = null;
248 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
250 GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
251 GLAPI void APIENTRY glUnlockArraysEXT (void);
255 #if defined(__ANDROID__) || defined(__ODROID__)
256 #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
257 #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
258 #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
259 #define GL_BGRA_EXT 0
262 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
264 #define GL_POLYGON_STIPPLE 0xFFFF
265 #define GL_LINE_STIPPLE 0xFFFF
266 #define GL_LINE 0xFFFF
267 #define GL_FILL 0xFFFF
268 #define GL_ALL_ATTRIB_BITS 0xFFFF
269 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
275 #define GL_QUAD_STRIP 0
276 //#define GL_DOUBLE 0
277 //#define GL_UNSIGNED_INT 0
280 //#define GL_LINE_STIPPLE 0
281 #define GL_UNPACK_ROW_LENGTH 0
282 #define GL_UNPACK_SKIP_PIXELS 0
283 #define GL_UNPACK_SKIP_ROWS 0
285 #define GL_PACK_ROW_LENGTH 0
286 #define GL_PACK_SKIP_ROWS 0
287 #define GL_PACK_SKIP_PIXELS 0
293 #if defined(__ANDROID__) || defined(__ODROID__)
294 #define glBindFramebuffer glBindFramebufferOES
295 #define glBindRenderbuffer glBindRenderbufferOES
296 #define glFramebufferTexture2D glFramebufferTexture2DOES
297 #define glGenFramebuffers glGenFramebuffersOES
298 #define glGenRenderbuffers glGenRenderbuffersOES
299 #define glDeleteFramebuffers glDeleteFramebuffersOES
300 #define glDeleteRenderbuffers glDeleteRenderbuffersOES
303 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
304 #define GL_INT 0x1404
305 #define GL_UNSIGNED_INT 0x1405
306 #define GL_DOUBLE 0x140A
310 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
341 #undef glLoadIdentity
346 #undef glColorMaterial
349 #define glRecti glimtkRecti
350 #define glBegin glimtkBegin
351 #define glTexCoord2i glimtkTexCoord2i
352 #define glVertex2i glimtkVertex2i
353 #define glTexCoord2d glimtkTexCoord2d
354 #define glVertex2d glimtkVertex2d
355 #define glTexCoord2f glimtkTexCoord2f
356 #define glVertex2f glimtkVertex2f
357 #define glEnd glimtkEnd
358 #define glColor3f glimtkColor3f
359 #define glColor4ub glimtkColor4ub
360 #define glColor4fv glimtkColor4fv
361 #define glNormal3fv glimtkNormal3fv
362 #define glNormal3f glimtkNormal3f
363 #define glTexCoord2fv glimtkTexCoord2fv
364 #define glVertex3d glimtkVertex3d
365 #define glVertex3dv glimtkVertex3dv
366 #define glVertex3f glimtkVertex3f
367 #define glVertex3fv glimtkVertex3fv
369 #define glLoadMatrixd glmsLoadMatrixd
370 #define glMultMatrixd glmsMultMatrixd
371 #define glFrustum glmsFrustum
372 #define glOrtho glmsOrtho
373 #define glScaled glmsScaled
374 #define glScalef glmsScaled
375 #define glTranslated glmsTranslated
376 #define glRotated glmsRotated
377 #define glMatrixMode glmsMatrixMode
378 #define glLoadIdentity glmsLoadIdentity
379 #define glPushMatrix glmsPushMatrix
380 #define glPopMatrix glmsPopMatrix
382 #define glLineStipple glesLineStipple
383 #define glColorMaterial glesColorMaterial
384 #define glLightModeli glesLightModeli
388 public void glesColorMaterial(int a, int b)
390 PrintLn("glColorMaterial stub");
393 static GLuint stippleTexture;
394 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
395 static bool stippleEnabled;
398 public void glesLineStipple( int i, unsigned short j )
402 for(x = 0; x < 16; x++)
404 bool v = (j & (1 << x)) != 0;
405 texture[x] = v ? 0xFFFFFFFF : 0;
408 glGenTextures(1, &stippleTexture);
409 glBindTexture(GL_TEXTURE_2D, stippleTexture);
410 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
412 // TOOD: Special shading code for stippling?
413 GLSetupTexturing(true);
414 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
415 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
416 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
417 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
418 glMatrixMode(GL_TEXTURE);
420 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
421 glScaled(i/16.0, 1, 1.0f);
422 glTranslated(0.5, 0.5, 0);
423 glMatrixMode(MatrixMode::projection);
426 public void glesLightModeli( unsigned int pname, int param )
428 #if !defined(SHADERS)
429 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
430 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
434 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
435 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
438 #if defined(__ANDROID__) || defined(__ODROID__)
439 void glFogi( unsigned int pname, int param ) { }
440 void glPolygonMode( unsigned int i, unsigned int j ) { }
443 // *** Picking won't be supported for now ***
444 void glPushName( unsigned int i ) { }
445 void glLoadName( unsigned int i ) { }
448 // Probably replace by regular glBlendFunc ...
449 void glBlendFuncSeparate(int a, int b, int c, int d)
454 // For direct pixel blitting...
455 void glRasterPos2d(double a, double b) { }
456 void glPixelZoom(float a, float b) { }
457 void glDrawPixels(int a, int b, int c, int d, void * e) { }
461 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
462 static int primitiveTypes[RenderPrimitiveType] =
464 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN,
465 #if defined(SHADERS) || defined(ES1_1) || defined(ES2)
466 GL_TRIANGLE_FAN, // NOTE: This will only work for single quads
470 GLIMTKMode::quadStrip,
475 public void GLSetupTexturing(bool enable)
478 shader_texturing(enable);
480 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
484 public void GLSetupFog(bool enable)
489 (enable ? glEnable : glDisable)(GL_FOG);
493 public void GLSetupLighting(bool enable)
496 shader_lighting(enable);
498 (enable ? glEnable : glDisable)(GL_LIGHTING);
502 // Non OpenGL ES friendly stuff
504 #if defined(ES1_1) || defined(ES2)
506 //#undef GL_UNSIGNED_INT
512 #undef GL_POLYGON_STIPPLE
513 #undef GL_LINE_STIPPLE
516 #undef GL_ALL_ATTRIB_BITS
517 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
521 static int displayWidth, displayHeight;
523 #define GL_CLAMP_TO_EDGE 0x812F
525 /*static */bool vboAvailable;
527 static bool useSingleGLContext = false;
528 class OGLDisplay : struct
530 #if defined(__WIN32__)
541 byte * pboMemory1, * pboMemory2;
543 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
544 GLXContext glContext;
547 XShmSegmentInfo shminfo;
549 XShmSegmentInfo shminfoShape;
554 X11Picture windowPicture;
555 X11Picture pixmapPicture;
557 X11Picture shapePicture;
560 ColorAlpha * flippingBuffer;
561 int flipBufH, flipBufW;
566 #if defined(_DEBUG) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
567 //#define GL_DEBUGGING
571 static void APIENTRY openglCallbackFunction(GLenum source,
576 const GLchar* message,
577 const void* userParam)
579 PrintLn("---------------------opengl-callback-start------------");
580 PrintLn("message: ", message);
584 case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
585 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
586 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
587 case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
588 case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
589 case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
596 case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
597 case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
598 case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
600 PrintLn("---------------------opengl-callback-end--------------");
604 class OGLSystem : struct
609 #if defined(__WIN32__)
610 PIXELFORMATDESCRIPTOR pfd;
615 #elif defined(__EMSCRIPTEN__)
616 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
617 #elif !defined(__ANDROID__) && !defined(__ODROID__)
618 XVisualInfo * visualInfo;
619 GLXContext glContext;
620 GLXDrawable glxDrawable;
624 class OGLSurface : struct
632 float foreground[4], background[4], bitmapMult[4];
635 class OGLMesh : struct
644 class OGLIndices : struct
655 static void setupDebugging()
657 if(glDebugMessageCallback)
659 GLuint unusedIds = 0;
661 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
663 glDebugMessageCallback(openglCallbackFunction, null);
664 glDebugMessageControl(GL_DONT_CARE,
674 #if defined(__WIN32__)
675 static HGLRC winCreateContext(HDC hdc)
679 if(wglCreateContextAttribsARB)
683 WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
684 WGL_CONTEXT_MINOR_VERSION_ARB, 4,
685 WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | */WGL_CONTEXT_DEBUG_BIT_ARB,
686 WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB /*WGL_CONTEXT_CORE_PROFILE_BIT_ARB*/,
689 result = wglCreateContextAttribsARB(hdc, null, attribs);
695 result = wglCreateContextAttribsARB(hdc, null, attribs);
700 result = wglCreateContext(hdc);
705 class OpenGLDisplayDriver : DisplayDriver
707 class_property(name) = "OpenGL";
709 bool LockSystem(DisplaySystem displaySystem)
711 #if defined(__EMSCRIPTEN__)
712 OGLSystem oglSystem = displaySystem.driverData;
713 emscripten_webgl_make_context_current(oglSystem.glc);
714 #elif !defined(__ANDROID__) && !defined(__ODROID__)
715 OGLSystem oglSystem = displaySystem.driverData;
716 if(useSingleGLContext) return true;
717 #if defined(__WIN32__)
718 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
719 #elif defined(__unix__) || defined(__APPLE__)
720 //if(previous) return true;
721 // printf("Making SYSTEM current\n");
722 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
723 //previous = oglSystem.glContext;
726 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
727 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
731 void UnlockSystem(DisplaySystem displaySystem)
733 if(useSingleGLContext) return;
734 #if defined(__WIN32__)
735 wglMakeCurrent(null, null);
736 #elif defined(__unix__) || defined(__APPLE__)
737 // printf("Making NULL current\n");
738 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
740 glXMakeCurrent(xGlobalDisplay, None, null);
746 bool Lock(Display display)
748 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
749 OGLDisplay oglDisplay = display.driverData;
750 if(useSingleGLContext) return true;
751 #if defined(__WIN32__)
752 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
753 #elif defined(__unix__) || defined(__APPLE__)
754 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
755 // printf(" Making DISPLAY current\n");
756 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
759 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
760 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
764 void Unlock(Display display)
766 if(useSingleGLContext) return;
767 //printf(" Making NULL current\n");
768 //glXMakeCurrent(xGlobalDisplay, None, null);
770 LockSystem(display.displaySystem);
773 void DestroyDisplay(Display display)
775 OGLDisplay oglDisplay = display.driverData;
779 #if defined(__WIN32__)
780 wglMakeCurrent( null, null );
783 wglDeleteContext(oglDisplay.glrc);
785 if(oglDisplay.hdc && oglDisplay.pBuffer)
786 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
788 if(oglDisplay.pBuffer)
789 wglDestroyPbufferARB(oglDisplay.pBuffer);
792 ReleaseDC(display.window, oglDisplay.hdc);
794 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
795 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
797 #elif defined(__unix__) || defined(__APPLE__)
798 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
800 if(oglDisplay.shapePixmap)
801 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
802 if(oglDisplay.pixmap)
803 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
806 if(oglDisplay.shminfoShape.shmid != -1)
808 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
809 if(oglDisplay.shminfo.shmaddr != (void *)-1)
810 shmdt(oglDisplay.shminfo.shmaddr);
811 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
814 if(oglDisplay.shapeImage)
816 if(oglDisplay.shminfoShape.shmid != -1)
818 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
819 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
820 shmdt(oglDisplay.shminfoShape.shmaddr);
821 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
823 XDestroyImage(oglDisplay.shapeImage);
824 oglDisplay.shapeImage = None;
827 glXMakeCurrent(xGlobalDisplay, None, null);
829 if(oglDisplay.glContext)
830 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
833 delete oglDisplay.flippingBuffer;
835 display.driverData = null;
839 void ::CheckExtensions(OGLSystem oglSystem)
841 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
843 printf("extensions: %s\n", extensions);
846 oglSystem.pow2textures = (extensions && strstr(extensions, "GL_ARB_texture_non_power_of_two")) ? false : true;
847 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
849 PrintLn("max texture size: ", oglSystem.maxTextureSize);
853 bool CreateDisplaySystem(DisplaySystem displaySystem)
856 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
859 PrintLn("OpenGL driver's CreateDisplaySystem()");
863 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
865 oglSystem.hdc = GetDC(oglSystem.hwnd);
869 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
870 oglSystem.pfd.nVersion = 1;
871 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
872 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
873 oglSystem.pfd.cColorBits = 24;
874 oglSystem.pfd.cAlphaBits = 8;
875 oglSystem.pfd.cDepthBits = 24;
876 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
878 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
879 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
881 if(oglSystem.pfd.cColorBits > 8)
883 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
884 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
887 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
889 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
890 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
891 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
892 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
893 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
894 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
895 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
896 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
897 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
898 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
899 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
901 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
902 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
904 // eSystem_LoggingMode(LOG_MSGBOX, null);
906 if(wglChoosePixelFormatARB)
911 float fAttributes[] = {0,0};
914 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
915 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
916 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
917 WGL_COLOR_BITS_ARB,24,
918 WGL_ALPHA_BITS_ARB,8,
919 WGL_DEPTH_BITS_ARB,16,
920 WGL_STENCIL_BITS_ARB,0,
921 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
922 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
923 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
927 //Log("Found wglChoosePixelFormatARB\n");
929 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
930 if(!valid || !numFormats)
932 //Log("Can't find 4x multi sampling\n");
934 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
935 if(!valid || !numFormats)
937 // Log("Can't find 2x multi sampling\n");
940 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
943 if(valid && numFormats)
945 oglSystem.format = pixelFormat;
946 wglMakeCurrent(null, null);
947 wglDeleteContext(oglSystem.glrc);
949 // *** DescribePixelFormat does not support WGL pixel formats! ***
950 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
951 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
952 //Log("Successfully set pixel format\n");
955 PrintLn("winCreateContext()");
957 oglSystem.glrc = winCreateContext(oglSystem.hdc);
959 PrintLn("wglMakeCurrent()");
961 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
965 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
969 wglMakeCurrent(null, null);
971 //eSystem_DumpErrors(true);
975 #elif defined(__unix__) || defined(__APPLE__)
977 #if defined(__ANDROID__) || defined(__ODROID__)
978 #if defined(__ANDROID__)
979 egl_init_display(guiApp.desktop.windowHandle);
980 #elif defined(__ODROID__)
981 egl_init_display((uint)displaySystem.window);
982 CheckExtensions(oglSystem);
985 // TODO: Clean this up? Needed here?
986 glEnableClientState(GL_VERTEX_ARRAY);
988 // Initialize GL state.
989 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
990 glEnable(GL_CULL_FACE);
991 glShadeModel(GL_SMOOTH);
992 glDisable(GL_DEPTH_TEST);
994 glDisable(GL_CULL_FACE);
995 glDisable(GL_DEPTH_TEST);
997 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1000 matrixStack[0][0].Identity();
1001 matrixStack[1][0].Identity();
1002 matrixStack[2][0].Identity();
1004 glmsMatrixMode(GL_MODELVIEW);
1005 glScaled(1.0, 1.0, -1.0);
1006 glmsMatrixMode(GL_PROJECTION);
1007 glShadeModel(GL_FLAT);
1009 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1010 glFogi(GL_FOG_MODE, GL_EXP);
1011 glFogf(GL_FOG_DENSITY, 0);
1012 glEnable(GL_NORMALIZE);
1013 glDepthFunc(GL_LESS);
1015 glDisable(GL_MULTISAMPLE_ARB);
1017 glViewport(0,0,eglWidth,eglHeight);
1019 glOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
1021 glabCurArrayBuffer = 0;
1022 glabCurElementBuffer = 0;
1025 #elif defined(__EMSCRIPTEN__)
1027 EmscriptenWebGLContextAttributes attribs = { 0 };
1029 attribs.antialias = 1;
1036 EM_BOOL premultipliedAlpha;
1037 EM_BOOL preserveDrawingBuffer;
1038 EM_BOOL preferLowPowerToHighPerformance;
1039 EM_BOOL failIfMajorPerformanceCaveat;
1042 EM_BOOL enableExtensionsByDefault;
1045 emscripten_webgl_init_context_attributes(&attribs);
1046 oglSystem.pow2textures = true;
1047 oglSystem.maxTextureSize = 16384;
1048 oglSystem.glc = emscripten_webgl_create_context("canvas", &attribs);
1049 if(emscripten_webgl_make_context_current(oglSystem.glc) == EMSCRIPTEN_RESULT_SUCCESS)
1052 /*glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1053 glEnable(GL_BLEND);*/
1057 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1058 XSetWindowAttributes attr;
1063 #ifndef ECERE_MINIGLX
1064 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1067 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1071 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
1072 attr.background_pixel = 0;
1073 attr.border_pixel = 0;
1074 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1075 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1076 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1078 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1079 oglSystem.visualInfo->visual, mask, &attr );
1081 if(oglSystem.visualInfo)
1083 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1084 if(oglSystem.glContext)
1086 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1088 // CheckExtensions(oglSystem);
1089 glXMakeCurrent(xGlobalDisplay, None, null);
1096 displaySystem.flags.alpha = true;
1097 displaySystem.flags.flipping = true;
1098 displaySystem.pixelFormat = pixelFormat888;
1102 void DestroyDisplaySystem(DisplaySystem displaySystem)
1104 OGLSystem oglSystem = displaySystem.driverData;
1107 glDeleteTextures(1, &stippleTexture);
1113 #if defined(__WIN32__)
1114 wglMakeCurrent( null, null );
1117 wglDeleteContext(oglSystem.glrc);
1120 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1121 DestroyWindow(oglSystem.hwnd);
1123 #elif defined(__unix__) || defined(__APPLE__)
1124 #if defined(__ANDROID__) || defined(__ODROID__)
1126 #elif defined(__EMSCRIPTEN__)
1127 emscripten_webgl_destroy_context(oglSystem.glc);
1129 if(oglSystem.visualInfo)
1131 #ifdef ECERE_MINIGLX
1132 __miniglx_XFree(oglSystem.visualInfo);
1134 XFree(oglSystem.visualInfo);
1138 if(oglSystem.glxDrawable)
1140 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1141 oglSystem.glxDrawable = 0;
1148 static bool ::initialDisplaySetup(Display display)
1152 loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1154 glEnableClientState(GL_VERTEX_ARRAY);
1156 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1157 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1159 #if defined(__WIN32__)
1160 if(glBlendFuncSeparate)
1161 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1163 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1165 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1169 glMatrixMode(MatrixMode::modelView);
1170 glLoadIdentity(); // For setting up GLES stack
1171 glScaled(1.0, 1.0, -1.0);
1172 // glTranslatef(0.375f, 0.375f, 0.0f);
1173 // glTranslatef(-0.625f, -0.625f, 0.0f);
1174 glMatrixMode(MatrixMode::projection);
1175 #if !defined(EM_MODE) && !defined(SHADERS)
1176 glShadeModel(GL_FLAT);
1178 // #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1180 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1182 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1183 glFogi(GL_FOG_MODE, GL_EXP);
1184 glFogf(GL_FOG_DENSITY, 0);
1185 glEnable(GL_NORMALIZE);
1187 glDepthFunc(GL_LESS);
1189 glDisable(GL_MULTISAMPLE_ARB);
1190 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1191 display.ambient = Color { 50,50,50 };
1196 bool CreateDisplay(Display display)
1198 bool result = false;
1199 OGLDisplay oglDisplay = display.driverData;
1200 #if !defined(__ANDROID__) && !defined(__ODROID__)
1201 OGLSystem oglSystem = display.displaySystem.driverData;
1205 oglDisplay = display.driverData = OGLDisplay { };
1206 //printf("Inside CreateDisplay\n");
1208 #if defined(__WIN32__) || defined(USEPBUFFER)
1209 if(!display.alphaBlend)
1212 #if defined(__WIN32__)
1213 oglDisplay.hdc = GetDC(display.window);
1214 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1215 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1217 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1218 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1222 ReleaseDC(display.window, oglDisplay.hdc);
1223 #elif defined(__unix__) || defined(__APPLE__)
1224 # if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1227 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1229 #if defined(__APPLE__)
1230 XVisualInfo template = { 0 };
1231 XWindowAttributes winAttr;
1233 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1234 template.visualid = XVisualIDFromVisual(winAttr.visual);
1235 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1237 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1238 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1239 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1240 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1242 // visualInfo = oglSystem.visualInfo;
1247 //printf("visualInfo is not null\n");
1248 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1249 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1250 //XFree(visualInfo);
1253 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1254 if(oglDisplay.glContext)
1256 //printf("CreateDisplay Got a Context\n");
1257 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1263 #if defined(__WIN32__) || defined(USEPBUFFER)
1267 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1272 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1275 PrintLn("Calling ogl_LoadFunctions() in CreateDisplay()");
1277 if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
1278 PrintLn("ogl_LoadFunctions() failed!");
1281 PrintLn("CheckExtensions()");
1283 CheckExtensions(oglSystem);
1284 vboAvailable = glBindBuffer != null;
1287 PrintLn("vboAvailable is: ", vboAvailable);
1290 # ifdef GL_DEBUGGING
1296 #if defined(__EMSCRIPTEN__)
1297 emscripten_webgl_make_context_current(oglSystem.glc);
1300 initialDisplaySetup(display);
1303 if(!useSingleGLContext)
1305 #if defined(__WIN32__)
1306 wglMakeCurrent(null, null);
1307 #elif defined(__unix__) || defined(__APPLE__)
1308 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1311 glXMakeCurrent(xGlobalDisplay, None, null);
1317 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1325 bool DisplaySize(Display display, int width, int height)
1327 OGLDisplay oglDisplay = display.driverData;
1329 bool result = false;
1331 //printf("Inside DisplaySize\n");
1332 #if defined(__WIN32__) || defined(USEPBUFFER)
1333 OGLSystem oglSystem = display.displaySystem.driverData;
1334 if(display.alphaBlend)
1336 #if defined(__WIN32__)
1337 const int attributes[]=
1339 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1340 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1342 int pixelFormat = 0;
1343 if(wglChoosePixelFormatARB)
1347 float fAttributes[] = {0,0};
1350 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1351 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1352 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1353 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1354 WGL_COLOR_BITS_ARB,24,
1355 WGL_ALPHA_BITS_ARB,8,
1356 WGL_DEPTH_BITS_ARB,16,
1357 WGL_STENCIL_BITS_ARB,0,
1358 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1359 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1360 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1364 //Log("Found wglChoosePixelFormatARB\n");
1366 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1367 if(!valid || !numFormats)
1369 //Log("Can't find 4x multi sampling\n");
1370 iAttributes[19] = 2;
1371 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1372 if(!valid || !numFormats)
1374 // Log("Can't find 2x multi sampling\n");
1375 iAttributes[16] = 0;
1376 iAttributes[17] = 0;
1377 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1378 if(!valid || !numFormats)
1382 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1383 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1384 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1385 WGL_COLOR_BITS_ARB,24,
1386 WGL_ALPHA_BITS_ARB,8,
1387 WGL_DEPTH_BITS_ARB,16,
1390 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1394 if(valid && numFormats)
1396 wglMakeCurrent(null, null);
1400 wglMakeCurrent( null, null );
1401 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1402 if(oglDisplay.hdc && oglDisplay.pBuffer)
1403 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1405 wglDestroyPbufferARB(oglDisplay.pBuffer);
1407 if(!useSingleGLContext)
1408 wglMakeCurrent( null, null );
1411 wglDeleteContext(oglDisplay.glrc);
1413 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1414 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1415 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1418 HDC hdc = GetDC(display.window);
1420 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1421 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1423 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1424 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1426 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1428 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1432 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1433 oglDisplay.memDC = CreateCompatibleDC(hdc);
1434 SetMapMode(oglDisplay.memDC, MM_TEXT);
1435 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1436 info->bmiHeader.biPlanes = 1;
1437 info->bmiHeader.biCompression = BI_RGB;
1438 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1439 info->bmiHeader.biWidth = width;
1440 info->bmiHeader.biHeight = height;
1441 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1444 SelectObject(oglDisplay.memDC, newBitmap);
1445 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1448 PIXELFORMATDESCRIPTOR pfd = { 0 };
1449 pfd.nSize = (short)sizeof(pfd);
1451 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1452 pfd.iPixelType = PFD_TYPE_RGBA;
1453 pfd.cColorBits = 32;
1454 //pfd.cAlphaBits = 8;
1455 pfd.cDepthBits = 24;
1456 pfd.iLayerType = PFD_MAIN_PLANE;
1458 oglDisplay.hdc = oglDisplay.memDC;
1460 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1461 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1462 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1464 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1465 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1466 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1471 const int imageSize = width * height * 4;
1473 glGenBuffersARB(2, oglDisplay.imageBuffers);
1475 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1476 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1477 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1478 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1481 oglDisplay.memBitmap = newBitmap;
1482 oglDisplay.stride = width;
1488 ReleaseDC(display.window, hdc);
1490 #elif defined(__unix__) || defined(__APPLE__)
1491 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1496 GLX_DOUBLEBUFFER, True,
1502 GLX_STENCIL_SIZE, 1,
1503 //GLX_DEPTH_SIZE, 24,
1504 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1505 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1511 GLX_PBUFFER_WIDTH, width,
1512 GLX_PBUFFER_HEIGHT, height,
1513 GLX_LARGEST_PBUFFER, False,
1517 // choose a pixel format that meets our minimum requirements
1520 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1523 if(oglDisplay.pixmap)
1525 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1526 oglDisplay.pixmap = None;
1528 if(oglDisplay.shapePixmap)
1530 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1531 oglDisplay.shapePixmap = None;
1534 // Free Shared Memory Pixmap
1535 if(oglDisplay.image)
1537 if(oglDisplay.shminfoShape.shmid != -1)
1539 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1540 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1541 shmdt(oglDisplay.shminfo.shmaddr);
1542 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1544 XDestroyImage(oglDisplay.image);
1545 oglDisplay.image = None;
1547 if(oglDisplay.shapeImage)
1549 if(oglDisplay.shminfoShape.shmid != -1)
1551 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1552 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1553 shmdt(oglDisplay.shminfoShape.shmaddr);
1554 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1556 XDestroyImage(oglDisplay.shapeImage);
1557 oglDisplay.shapeImage = None;
1560 if(oglDisplay.windowPicture)
1561 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1562 if(oglDisplay.pixmapPicture)
1563 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1565 if(oglDisplay.pixmap)
1566 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1568 if(oglDisplay.glContext)
1569 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1570 if(oglDisplay.pBuffer)
1571 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1573 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1574 if(oglDisplay.pBuffer)
1576 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1577 if(oglDisplay.glContext)
1579 glXMakeCurrent(xGlobalDisplay, None, null);
1580 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1582 // Initialize Shared Memory Pixmap
1583 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1584 ZPixmap, null, &oglDisplay.shminfo, width, height);
1585 if(oglDisplay.image)
1587 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1588 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1589 if(oglDisplay.shminfo.shmid != -1)
1591 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1592 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1594 oglDisplay.shminfo.readOnly = False;
1595 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1597 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1598 &oglDisplay.shminfo, width, height, 32);
1600 // Initialize Shared Memory Shape Pixmap
1601 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1602 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1603 if(oglDisplay.shapeImage)
1605 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1606 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1607 if(oglDisplay.shminfoShape.shmid != -1)
1609 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1610 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1612 oglDisplay.shminfoShape.readOnly = False;
1613 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1615 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1616 &oglDisplay.shminfoShape, width, height, 1);
1617 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1620 XRenderPictureAttributes attributes = { 0 };
1621 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1622 #if !defined(__APPLE__)
1623 attributes.repeat = RepeatNormal;
1625 attributes.repeat = 1;
1627 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1628 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1629 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1630 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1633 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1634 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1651 CreateDisplay(display);
1652 #if defined(__WIN32__)
1653 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1654 #elif defined(__unix__) || defined(__APPLE__)
1655 #if defined(__ANDROID__) || defined(__ODROID__)
1658 #elif defined(__EMSCRIPTEN__)
1659 emscripten_webgl_make_context_current(oglSystem.glc);
1661 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1669 if(display.alphaBlend && result)
1670 initialDisplaySetup(display);
1672 if(!result && display.alphaBlend)
1674 printf("Alpha blending windows not supported on this display\n");
1681 glViewport(0,0,width,height);
1682 glMatrixMode(MatrixMode::projection);
1684 glOrtho(0,width,height,0,0.0,1.0);
1685 displayWidth = display.width = width;
1686 displayHeight = display.height = height;
1688 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1690 oglDisplay.flipBufW = width;
1691 oglDisplay.flipBufH = height;
1692 #if defined(ES1_1) || defined(ES2)
1695 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1698 if(oglDisplay.flippingBuffer || !width || !height)
1704 void DisplayPosition(Display display, int x, int y)
1706 OGLDisplay oglDisplay = display.driverData;
1712 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1716 void RestorePalette(Display display)
1720 void StartUpdate(Display display)
1724 void EndUpdate(Display display)
1728 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1732 void Update(Display display, Box updateBox)
1734 #if defined(__WIN32__) || defined(USEPBUFFER)
1735 OGLDisplay oglDisplay = display.driverData;
1737 //Logf("DisplayScreen\n");
1739 #if !defined(__ANDROID__)
1744 #if defined(__WIN32__) || defined(USEPBUFFER)
1745 if(display.alphaBlend)
1747 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1748 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1749 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1750 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1751 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1754 #if defined(__WIN32__)
1756 POINT point = { oglDisplay.x, oglDisplay.y};
1757 POINT srcPoint = { 0, 0 };
1758 BLENDFUNCTION blend = { 0 };
1760 size.cx = display.width;
1761 size.cy = display.height;
1762 blend.BlendOp = AC_SRC_OVER;
1763 blend.BlendFlags = 0;
1764 blend.SourceConstantAlpha = 255;
1765 blend.AlphaFormat = AC_SRC_ALPHA;
1768 // Process partial images. Mapping the buffer waits for
1769 // outstanding DMA transfers into the buffer to finish.
1770 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1771 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1773 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1774 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1777 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1778 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1781 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1784 // Unmap the image buffers
1785 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1786 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1788 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1789 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1791 // Bind two different buffer objects and start the glReadPixels
1792 // asynchronously. Each call will return directly after
1793 // starting the DMA transfer.
1794 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1795 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1797 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1798 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1802 #elif defined(__unix__) || defined(__APPLE__)
1803 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1805 XTransform transform =
1808 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1809 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1810 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1813 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1814 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1815 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1816 #if !defined(__APPLE__)
1817 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1819 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1821 XFlush(xGlobalDisplay);
1829 #if defined(__WIN32__)
1830 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1831 SwapBuffers(oglDisplay.hdc);
1832 //ecere::sys::Sleep(0.1);
1833 #elif defined(__unix__) || defined(__APPLE__)
1834 #if defined(__ANDROID__) || defined(__ODROID__)
1836 #elif defined(__EMSCRIPTEN__)
1838 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1842 //Logf("Out of DisplayScreen\n");
1845 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1847 if(bitmap.driverData)
1849 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1850 glDeleteTextures(1, &tex);
1851 bitmap.driverData = 0;
1853 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1856 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1858 OGLSystem oglSystem = displaySystem.driverData;
1859 bool result = false;
1861 GLuint glBitmap = 0;
1863 uint w = width, h = height;
1864 if(oglSystem.pow2textures)
1869 w = Min(w, oglSystem.maxTextureSize);
1870 h = Min(h, oglSystem.maxTextureSize);
1872 glGenTextures(1, &glBitmap);
1873 glBindTexture(GL_TEXTURE_2D, glBitmap);
1875 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1877 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1878 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1880 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1881 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1883 #if !defined(SHADERS)
1884 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1887 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1889 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1890 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1894 bitmap.driverData = (void *)(uintptr)glBitmap;
1895 bitmap.driver = displaySystem.driver;
1903 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1905 bool result = false;
1906 OGLSystem oglSystem = displaySystem.driverData;
1907 Bitmap convBitmap = bitmap;
1911 convBitmap.Copy(bitmap);
1914 // Pre process the bitmap... First make it 32 bit
1915 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1918 uint w = bitmap.width, h = bitmap.height;
1919 GLuint glBitmap = 0;
1920 if(oglSystem.pow2textures)
1925 w = Min(w, oglSystem.maxTextureSize);
1926 h = Min(h, oglSystem.maxTextureSize);
1930 while(w * 2 < h) w *= 2;
1931 while(h * 2 < w) h *= 2;
1934 // Switch ARGB to RGBA
1935 //if(bitmap.format != pixelFormatRGBA)
1937 for(c=0; c<bitmap.size; c++)
1939 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1941 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1942 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1945 // convBitmap.pixelFormat = pixelFormat888;
1948 glGenTextures(1, &glBitmap);
1951 //int error = glGetError();
1955 glBindTexture(GL_TEXTURE_2D, glBitmap);
1956 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1958 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1959 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1961 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1963 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1964 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1966 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1967 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1968 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1969 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1972 #if !defined(SHADERS)
1973 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1978 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1983 if(bitmap.width != w || bitmap.height != h)
1985 mipMap = Bitmap { };
1986 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1988 Surface mipSurface = mipMap.GetSurface(0,0,null);
1989 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1999 mipMap = convBitmap;
2006 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2007 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2008 //printf("Calling glTexImage2D\n");
2009 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2010 //printf("width = %d (Should be %d, %d)\n", width, w, h);
2011 if((error = glGetError()))
2013 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2014 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2018 if(mipMap != convBitmap)
2023 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2024 bitmap.driverData = (void *)(uintptr)glBitmap;
2025 bitmap.driver = displaySystem.driver;
2030 FreeBitmap(displaySystem, bitmap);
2031 else if(oglSystem.loadingFont)
2033 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2034 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2035 oglSystem.loadingFont = false;
2041 void ReleaseSurface(Display display, Surface surface)
2043 glDisable(GL_SCISSOR_TEST);
2044 delete surface.driverData;
2045 surface.driverData = null;
2048 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2053 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2055 bool result = false;
2056 OGLSurface oglSurface = surface.driverData = OGLSurface { };
2058 //Logf("GetSurface\n");
2062 if(displayWidth != display.width || displayHeight != display.height)
2064 displayWidth = display.width;
2065 displayHeight = display.height;
2067 glViewport(0,0,display.width,display.height);
2069 glOrtho(0,display.width,display.height,0,0.0,1.0);
2072 surface.offset.x = x;
2073 surface.offset.y = y;
2074 surface.unclippedBox = surface.box = clip;
2075 oglSurface.bitmapMult[0] = 1;
2076 oglSurface.bitmapMult[1] = 1;
2077 oglSurface.bitmapMult[2] = 1;
2078 oglSurface.bitmapMult[3] = 1;
2080 glEnable(GL_SCISSOR_TEST);
2083 (display.height) -(y+clip.bottom)-1,
2084 clip.right-clip.left+1,
2085 clip.bottom-clip.top+1);
2091 void Clip(Display display, Surface surface, Box clip)
2100 box.Clip(surface.unclippedBox);
2104 box = surface.box = surface.unclippedBox;
2105 box.left += surface.offset.x;
2106 box.top += surface.offset.y;
2107 box.right+= surface.offset.x;
2108 box.bottom += surface.offset.y;
2111 box.left,display.height - box.bottom - 1,
2112 box.right-box.left+1, box.bottom-box.top+1);
2115 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2117 bool result = false;
2118 OGLDisplay oglDisplay = display.driverData;
2119 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2121 if(oglDisplay.flippingBuffer)
2123 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2126 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2132 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2133 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2134 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2135 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2136 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2139 for(row = 0; row<h; row++)
2140 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2147 void SetForeground(Display display, Surface surface, ColorAlpha color)
2149 OGLSurface oglSurface = surface.driverData;
2151 //Logf("SetForeground\n");
2153 oglSurface.foreground[0] = color.color.r/255.0f;
2154 oglSurface.foreground[1] = color.color.g/255.0f;
2155 oglSurface.foreground[2] = color.color.b/255.0f;
2156 //oglSurface.foreground[3] = 1.0f;
2157 oglSurface.foreground[3] = color.a/255.0f;
2159 //if(!oglSurface.foreground[3])printf("bug");
2162 void SetBackground(Display display, Surface surface, ColorAlpha color)
2164 OGLSurface oglSurface = surface.driverData;
2166 //Logf("SetBackground\n");
2168 oglSurface.background[0] = color.color.r/255.0f;
2169 oglSurface.background[1] = color.color.g/255.0f;
2170 oglSurface.background[2] = color.color.b/255.0f;
2171 //oglSurface.background[3] = 1.0;
2172 oglSurface.background[3] = color.a/255.0f;
2175 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2177 OGLSurface oglSurface = surface.driverData;
2179 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2180 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2181 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2182 oglSurface.bitmapMult[3] = color.a/255.0f;
2185 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2190 void PutPixel(Display display, Surface surface,int x,int y)
2192 OGLSurface oglSurface = surface.driverData;
2194 //Logf("PutPixel\n");
2196 glColor4fv(oglSurface.foreground);
2198 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2199 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2204 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2206 OGLSurface oglSurface = surface.driverData;
2207 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2222 x1 += surface.offset.x;
2223 y1 += surface.offset.y;
2224 x2 += surface.offset.x;
2225 y2 += surface.offset.y;
2229 glColor4fv(oglSurface.foreground);
2231 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2234 glTexCoord2f(0.5f, 0);
2235 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2236 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2237 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2246 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2247 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2253 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2255 OGLSurface oglSurface = surface.driverData;
2256 x1 += surface.offset.x;
2257 y1 += surface.offset.y;
2258 x2 += surface.offset.x;
2259 y2 += surface.offset.y;
2261 //Logf("Rectangle\n");
2263 glColor4fv(oglSurface.foreground);
2264 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2269 glTexCoord2f(0.5f, 0);
2270 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2271 glTexCoord2f(y2-y1 + 0.5f, 0);
2272 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2274 glTexCoord2f(0.5f, 0);
2275 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2276 glTexCoord2f(x2 - x1 + 0.5f, 0);
2277 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2279 glTexCoord2f(0.5f, 0);
2280 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2281 glTexCoord2f(y1 - y2 + 0.5f, 0);
2282 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2284 glTexCoord2f(0.5f, 0);
2285 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2286 glTexCoord2f(x1 - x2 + 0.5f, 0);
2287 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2292 glBegin(GL_LINE_LOOP);
2299 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2300 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2301 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2302 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2307 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2309 OGLSurface oglSurface = surface.driverData;
2312 glColor4fv(oglSurface.background);
2314 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2315 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2317 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2318 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2322 void Clear(Display display, Surface surface, ClearType type)
2324 OGLDisplay oglDisplay = display.driverData;
2325 OGLSurface oglSurface = surface.driverData;
2328 if(type != depthBuffer)
2329 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2330 if(type != colorBuffer && !oglDisplay.depthWrite)
2332 glDepthMask((byte)bool::true);
2334 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2335 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2336 if(type != colorBuffer && !oglDisplay.depthWrite)
2338 glDepthMask((byte)bool::false);
2342 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2347 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2349 OGLSurface oglSurface = surface.driverData;
2351 if(!oglSurface.writingText)
2353 // glTranslatef(-0.375f, -0.375f, 0.0f);
2354 GLSetupTexturing(true);
2355 glColor4fv(oglSurface.bitmapMult);
2357 else if(oglSurface.xOffset)
2358 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2360 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2361 glBegin(GLIMTKMode::quads);
2365 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2366 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2367 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2368 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2369 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2370 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2371 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2372 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2377 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2378 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2379 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2380 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2381 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2382 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2383 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2384 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2387 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2388 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2389 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2390 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2391 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2392 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2393 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2394 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2398 if(!oglSurface.writingText)
2400 GLSetupTexturing(false);
2402 //glTranslate(0.375, 0.375, 0.0);
2404 else if(oglSurface.xOffset)
2405 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2408 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2410 OGLSurface oglSurface = surface.driverData;
2412 //glTranslate(-0.375, -0.375, 0.0);
2414 GLSetupTexturing(true);
2415 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2417 glColor4fv(oglSurface.bitmapMult);
2419 glBegin(GLIMTKMode::quads);
2423 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2424 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2426 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2427 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2429 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2430 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2432 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2433 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2437 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2438 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2440 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2441 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2443 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2444 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2446 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2447 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2452 GLSetupTexturing(false);
2454 //glTranslate(0.375, 0.375, 0.0);
2457 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2459 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2462 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2464 float s2dw,s2dh,d2sw,d2sh;
2465 //bool flipX = false, flipY = false;
2467 //Logf("StretchDI\n");
2469 if(Sgn(w) != Sgn(sw))
2475 if(Sgn(h) != Sgn(sh))
2487 //Clip against the edges of the source
2490 dx+=(int)((0-sx) * s2dw);
2491 w-=(int)((0-sx) * s2dw);
2497 dy+=(int)((0-sy) * s2dh);
2498 h-=(int)((0-sy) * s2dh);
2503 if(sx+sw>bitmap.width-1)
2505 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2506 sw-=sx+sw-(bitmap.width-1)-1;
2508 if(sy+sh>(bitmap.height-1))
2510 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2511 sh-=sy+sh-(bitmap.height-1)-1;
2513 //Clip against the edges of the surfaceination
2514 if(dx<surface.box.left)
2517 sx+=(int)((surface.box.left-dx)*d2sw);
2518 sw-=(int)((surface.box.left-dx)*d2sw);
2519 w-=surface.box.left-dx;
2520 dx=surface.box.left;
2522 if(dy<surface.box.top)
2524 sy+=(int)((surface.box.top-dy)*d2sh);
2525 sh-=(int)((surface.box.top-dy)*d2sh);
2526 h-=surface.box.top-dy;
2529 if(dx+w>surface.box.right)
2531 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2532 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2533 w-=dx+w-surface.box.right-1;
2535 if(dy+h>surface.box.bottom)
2537 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2538 h-=dy+h-surface.box.bottom-1;
2540 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2542 dx += surface.offset.x;
2543 dy += surface.offset.y;
2545 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2547 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2548 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2549 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2550 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2551 #if !defined(SHADERS)
2552 glRasterPos2d(dx,dy);
2553 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2554 glPixelZoom(s2dw, -s2dh);
2555 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2557 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2558 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2559 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2560 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2564 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2568 //Clip against the edges of the source
2581 if(sx+w>bitmap.width-1)
2582 w-=sx+w-(bitmap.width-1)-1;
2583 if(sy+h>bitmap.height-1)
2584 h-=sy+h-(bitmap.height-1)-1;
2585 //Clip against the edges of the surfaceination
2586 if(dx<surface.box.left)
2589 sx+=surface.box.left-dx;
2590 w-=surface.box.left-dx;
2591 dx=surface.box.left;
2593 if(dy<surface.box.top)
2595 sy+=surface.box.top-dy;
2596 h-=surface.box.top-dy;
2599 if(dx+w>surface.box.right)
2601 //if(flip) sx+=dx+w-surface.box.right-1;
2602 w-=dx+w-surface.box.right-1;
2604 if(dy+h>surface.box.bottom)
2605 h-=dy+h-surface.box.bottom-1;
2609 dx += surface.offset.x;
2610 dy += surface.offset.y;
2612 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2614 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2615 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2616 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2617 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2618 #if !defined(SHADERS)
2619 glRasterPos2d(dx,dy);
2621 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2623 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2624 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2625 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2626 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2630 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2632 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2635 void UnloadFont(DisplaySystem displaySystem, Font font)
2637 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2640 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2643 OGLSystem oglSystem = displaySystem.driverData;
2644 oglSystem.loadingFont = true;
2645 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2649 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2651 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2654 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2656 OGLSurface oglSurface = surface.driverData;
2657 OGLSystem oglSystem = display.displaySystem.driverData;
2658 oglSystem.loadingFont = true;
2660 //glTranslated(-0.375, -0.375, 0.0);
2664 if(surface.textOpacity)
2667 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2669 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2672 oglSurface.writingText = true;
2674 GLSetupTexturing(true);
2676 if(surface.font.outlineSize)
2678 ColorAlpha outlineColor = surface.outlineColor;
2679 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2680 oglSurface.writingOutline = true;
2681 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2682 oglSurface.writingOutline = false;
2684 glColor4fv(oglSurface.foreground);
2686 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2687 oglSurface.writingText = false;
2688 oglSystem.loadingFont = false;
2690 GLSetupTexturing(false);
2692 //glTranslated(0.375, 0.375, 0.0);
2695 void TextFont(Display display, Surface surface, Font font)
2697 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2700 void TextOpacity(Display display, Surface surface, bool opaque)
2702 OGLSurface oglSurface = surface.driverData;
2703 oglSurface.opaqueText = opaque;
2706 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2708 OGLSurface oglSurface = surface.driverData;
2709 OGLSystem oglSystem = display.displaySystem.driverData;
2710 oglSystem.loadingFont = true;
2711 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2712 oglSystem.loadingFont = false;
2715 void DrawingChar(Display display, Surface surface, char character)
2720 void LineStipple(Display display, Surface surface, uint32 stipple)
2722 //Logf("Stipple\n");
2726 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2727 stippleEnabled = true;
2728 glesLineStipple(1, (uint16)stipple);
2730 glLineStipple(1, (uint16)stipple);
2731 glEnable(GL_LINE_STIPPLE);
2736 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
2737 stippleEnabled = false;
2738 glMatrixMode(GL_TEXTURE);
2740 glMatrixMode(MatrixMode::projection);
2741 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2743 glDisable(GL_LINE_STIPPLE);
2748 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2749 void SetRenderState(Display display, RenderState state, uint value)
2751 OGLDisplay oglDisplay = display.driverData;
2752 //Logf("RenderState\n");
2757 #ifndef __EMSCRIPTEN__
2759 glEnable(GL_MULTISAMPLE_ARB);
2761 glDisable(GL_MULTISAMPLE_ARB);
2765 #if !defined(ES1_1) && !defined(ES2)
2766 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2770 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2773 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2774 oglDisplay.depthWrite = (bool)value;
2778 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2779 #if defined(SHADERS)
2780 shader_fogColor(color[0], color[1], color[2]);
2782 glFogfv(GL_FOG_COLOR, (float *)&color);
2787 #if defined(SHADERS)
2788 shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2790 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2794 //#if !defined(__EMSCRIPTEN__)
2795 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2800 #if defined(SHADERS)
2801 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2803 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2804 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2810 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2815 #if defined(__WIN32__)
2816 if(wglSwapIntervalEXT)
2817 wglSwapIntervalEXT(value ? 1 : 0);
2824 void SetLight(Display display, int id, Light light)
2826 #if defined(SHADERS)
2827 shader_setLight(display, id, light);
2829 //Logf("SetLight\n");
2833 Object lightObject = light.lightObject;
2834 float position[4] = { 0, 0, 0, 0 };
2835 float color[4] = { 0, 0, 0, 1 };
2837 glEnable(GL_LIGHT0 + id);
2839 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
2840 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
2841 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
2844 if(!light.multiplier) light.multiplier = 1.0f;
2846 color[0] = light.diffuse.r * light.multiplier;
2847 color[1] = light.diffuse.g * light.multiplier;
2848 color[2] = light.diffuse.b * light.multiplier;
2849 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2851 color[0] = light.ambient.r * light.multiplier;
2852 color[1] = light.ambient.g * light.multiplier;
2853 color[2] = light.ambient.b * light.multiplier;
2854 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2855 color[0] = light.specular.r * light.multiplier;
2856 color[1] = light.specular.g * light.multiplier;
2857 color[2] = light.specular.b * light.multiplier;
2858 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2862 Vector3D positionVector;
2863 if(light.flags.spot)
2865 if(lightObject.flags.root || !lightObject.parent)
2867 positionVector = lightObject.transform.position;
2868 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2872 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2873 if(display.display3D.camera)
2874 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2880 if(!light.direction.x && !light.direction.y && !light.direction.z)
2882 Vector3Df vector { 0,0,-1 };
2884 mat.RotationQuaternion(light.orientation);
2885 positionVector.MultMatrixf(vector, mat);
2889 positionVector = light.direction;
2894 position[0] = (float)positionVector.x;
2895 position[1] = (float)positionVector.y;
2896 position[2] = (float)positionVector.z;
2898 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2901 // Display Light Position
2902 glDisable(GL_LIGHTING);
2903 glDisable(GL_DEPTH_TEST);
2907 glVertex3fv(position);
2909 glEnable(GL_DEPTH_TEST);
2910 glEnable(GL_LIGHTING);
2914 if(lightObject.flags.root || !lightObject.parent)
2916 positionVector = light.target.transform.position;
2917 positionVector.Subtract(positionVector, display.camera.cPosition);
2921 positionVector.MultMatrix(light.target.transform.position,
2922 lightObject.light.target.parent.matrix);
2923 positionVector.Subtract(positionVector, display.camera.cPosition);
2926 position[0] = positionVector.x;
2927 position[1] = positionVector.y;
2928 position[2] = positionVector.z;
2930 glDisable(GL_LIGHTING);
2931 glDisable(GL_DEPTH_TEST);
2935 glVertex3fv(position);
2937 glEnable(GL_DEPTH_TEST);
2938 glEnable(GL_LIGHTING);
2941 if(light.flags.attenuation)
2943 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2944 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2945 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2948 if(light.flags.spot)
2951 #define MAXLIGHT 0.9
2952 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2953 // Figure out exponent out of the hot spot
2954 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2956 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2957 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2958 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2963 Vector3Df vector { 0,0,-1 };
2964 Vector3Df direction;
2967 mat.RotationQuaternion(light.orientation);
2968 direction.MultMatrix(vector, mat);
2970 position[0] = direction.x;
2971 position[1] = direction.y;
2972 position[2] = direction.z;
2974 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2978 glDisable(GL_LIGHT0 + id);
2982 void SetCamera(Display display, Surface surface, Camera camera)
2984 OGLDisplay oglDisplay = display.driverData;
2985 //Logf("SetCamera\n");
2987 if(surface && camera)
2989 int left = surface.box.left + surface.offset.x;
2990 int top = surface.box.top + surface.offset.y;
2991 int right = surface.box.right + surface.offset.x;
2992 int bottom = surface.box.bottom + surface.offset.y;
2993 float origX = surface.offset.x + camera.origin.x;
2994 float origY = surface.offset.y + camera.origin.y;
2996 int y = display.height - bottom - 1;
2997 int w = right - left + 1;
2998 int h = bottom - top + 1;
3001 glViewport(x, y, w, h);
3003 // *** Projection Matrix ***
3004 glMatrixMode(MatrixMode::projection);
3005 if(!display.display3D.camera)
3008 if(display.display3D.collectingHits)
3010 float pickX = display.display3D.pickX + surface.offset.x;
3011 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3015 w / display.display3D.pickWidth, 0, 0, 0,
3016 0, h / display.display3D.pickHeight, 0, 0,
3018 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3019 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3022 glLoadMatrixd(pickMatrix.array);
3027 (left - origX) * camera.zMin / camera.focalX,
3028 (right - origX) * camera.zMin / camera.focalX,
3029 (bottom - origY) * camera.zMin / camera.focalY,
3030 (top - origY) * camera.zMin / camera.focalY,
3031 camera.zMin, camera.zMax);
3033 glDisable(GL_BLEND);
3035 // *** Z Inverted Identity Matrix ***
3036 glMatrixMode(MatrixMode::modelView);
3037 if(!display.display3D.camera)
3042 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3044 // *** View Matrix ***
3045 glMultMatrixd(camera.viewMatrix.array);
3050 glEnable(GL_DEPTH_TEST);
3052 GLSetupLighting(true);
3053 #if !defined(SHADERS)
3054 glShadeModel(GL_SMOOTH);
3056 glDepthMask((byte)bool::true);
3057 oglDisplay.depthWrite = true;
3059 #ifndef __EMSCRIPTEN__
3060 glEnable(GL_MULTISAMPLE_ARB);
3063 else if(surface && display.display3D.camera)
3066 oglDisplay.depthWrite = false;
3067 glViewport(0,0,display.width,display.height);
3069 glDisable(GL_CULL_FACE);
3070 glDisable(GL_DEPTH_TEST);
3073 GLSetupTexturing(false);
3074 GLSetupLighting(false);
3077 glDisableClientState(GL_COLOR_ARRAY);
3079 #if defined(SHADERS)
3080 shader_setPerVertexColor(false);
3082 glShadeModel(GL_FLAT);
3085 #if !defined(__EMSCRIPTEN__)
3086 glDisable(GL_MULTISAMPLE_ARB);
3089 // *** Restore 2D MODELVIEW Matrix ***
3092 // *** Restore 2D PROJECTION Matrix ***
3093 glMatrixMode(MatrixMode::projection);
3099 void ApplyMaterial(Display display, Material material, Mesh mesh)
3101 //Logf("ApplyMaterial\n");
3104 if(material.flags.doubleSided)
3106 #if !defined(SHADERS)
3107 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3109 glDisable(GL_CULL_FACE);
3113 #if !defined(SHADERS)
3114 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3116 glEnable(GL_CULL_FACE);
3120 GLSetupFog(!material.flags.noFog);
3123 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3125 Bitmap map = material.baseMap;
3126 GLSetupTexturing(true);
3127 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3129 glMatrixMode(GL_TEXTURE);
3131 if(material.uScale && material.vScale)
3132 glScalef(material.uScale, material.vScale, 1);
3133 glMatrixMode(MatrixMode::modelView);
3135 if(material.flags.tile)
3137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3142 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3143 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3147 GLSetupTexturing(false);
3149 #if defined(SHADERS)
3150 shader_setMaterial(material, mesh.flags.colors);
3152 if(mesh.flags.colors)
3154 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3155 glEnable(GL_COLOR_MATERIAL);
3159 glDisable(GL_COLOR_MATERIAL);
3161 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3162 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3165 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3166 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3170 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3171 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3174 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3175 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3178 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3182 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3184 OGLMesh oglMesh = mesh.data;
3187 if(!mesh.flags.vertices)
3189 oglMesh.vertices.free();
3190 delete mesh.vertices;
3192 if(!mesh.flags.normals)
3194 oglMesh.normals.free();
3195 delete mesh.normals;
3197 if(!mesh.flags.texCoords1)
3199 oglMesh.texCoords.free();
3200 delete mesh.texCoords;
3202 if(!mesh.flags.texCoords2)
3204 oglMesh.texCoords2.free();
3205 // delete mesh.texCoords2;
3207 if(!mesh.flags.colors)
3209 oglMesh.colors.free();
3220 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3222 bool result = false;
3225 mesh.data = OGLMesh { };
3228 if(mesh.nVertices == nVertices)
3230 // Same number of vertices, adding features (Leaves the other features pointers alone)
3231 if(mesh.flags != flags)
3233 if(!mesh.flags.vertices && flags.vertices)
3235 if(flags.doubleVertices)
3237 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3240 mesh.vertices = new Vector3Df[nVertices];
3242 if(!mesh.flags.normals && flags.normals)
3244 if(flags.doubleNormals)
3246 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3249 mesh.normals = new Vector3Df[nVertices];
3251 if(!mesh.flags.texCoords1 && flags.texCoords1)
3253 mesh.texCoords = new Pointf[nVertices];
3255 if(!mesh.flags.colors && flags.colors)
3257 mesh.colors = new ColorRGBAf[nVertices];
3263 // New number of vertices, reallocate all current and new features
3264 flags |= mesh.flags;
3267 if(flags.doubleVertices)
3269 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3272 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3276 if(flags.doubleNormals)
3278 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3281 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3283 if(flags.texCoords1)
3285 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3289 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3297 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3299 OGLMesh oglMesh = mesh.data;
3300 if(!flags) flags = mesh.flags;
3305 oglMesh.vertices.upload(
3306 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3309 oglMesh.normals.upload(
3310 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3312 if(flags.texCoords1)
3313 oglMesh.texCoords.upload(
3314 mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3317 oglMesh.colors.upload(
3318 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3322 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3329 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3333 oglIndices.buffer.free();
3334 delete oglIndices.indices;
3339 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3341 OGLIndices oglIndices = OGLIndices { };
3344 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3345 oglIndices.nIndices = nIndices;
3350 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3354 #if defined(ES1_1) || defined(ES2)
3357 if(!oglIndices.buffer.buffer)
3358 glGenBuffers(1, &oglIndices.buffer.buffer);
3359 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3360 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3361 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3365 oglIndices.buffer.upload(
3366 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3367 oglIndices.indices); //GL_STATIC_DRAW_ARB);
3371 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3374 return oglIndices.indices;
3377 void SelectMesh(Display display, Mesh mesh)
3379 //Logf("SelectMesh\n");
3381 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3383 #if defined(__WIN32__)
3384 if(glUnlockArraysEXT)
3386 if(!vboAvailable && display.display3D.mesh)
3387 glUnlockArraysEXT();
3392 OGLMesh oglMesh = mesh.data;
3394 // *** Vertex Stream ***
3395 glEnableClientState(GL_VERTEX_ARRAY);
3396 if(!display.display3D.collectingHits && oglMesh)
3398 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3400 // *** Normals Stream ***
3401 if(mesh.normals || mesh.flags.normals)
3403 glEnableClientState(GL_NORMAL_ARRAY);
3404 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3407 glDisableClientState(GL_NORMAL_ARRAY);
3409 // *** Texture Coordinates Stream ***
3410 if(mesh.texCoords || mesh.flags.texCoords1)
3412 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3413 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3416 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3418 // *** Color Stream ***
3419 if(mesh.colors || mesh.flags.colors)
3421 glEnableClientState(GL_COLOR_ARRAY);
3422 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3425 glDisableClientState(GL_COLOR_ARRAY);
3429 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3430 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3432 glEnableClientState(GL_NORMAL_ARRAY);
3433 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3436 glDisableClientState(GL_NORMAL_ARRAY);
3437 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3439 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3440 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3443 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3444 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3446 glEnableClientState(GL_COLOR_ARRAY);
3447 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3450 glDisableClientState(GL_COLOR_ARRAY);
3453 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3455 #if defined(__WIN32__)
3459 glLockArraysEXT(0, mesh.nVertices);
3465 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3467 //Logf("DrawPrimitives\n");
3469 if(primitive->type.vertexRange)
3470 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3473 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3474 // HACK TO SPEED THINGS UP...
3476 /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3477 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3480 glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
3483 OGLIndices oglIndices = primitive->data;
3484 MeshFeatures flags = mesh.flags;
3485 for(c = 0; c<primitive->nIndices; c++)
3487 uint16 index = ((uint16 *) oglIndices.indices)[c];
3488 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3489 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3490 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3491 glVertex3fv((float *)&mesh.vertices[index]);
3500 OGLIndices oglIndices = primitive->data;
3501 GLEAB eab = ((!display.display3D.collectingHits && oglIndices && vboAvailable) ? oglIndices.buffer : noEAB);
3502 #if defined(ES1_1) || defined(ES2)
3503 if(!vboAvailable && primitive->type.indices32bit)
3505 uint16 * temp = new uint16[primitive->nIndices];
3506 uint32 * src = (uint32 *)(oglIndices ? oglIndices.indices : primitive->indices);
3508 for(i = 0; i < primitive->nIndices; i++)
3509 temp[i] = (uint16)src[i];
3510 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices, GL_UNSIGNED_SHORT, temp);
3515 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3516 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3517 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3518 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3523 void PushMatrix(Display display)
3528 void PopMatrix(Display display, bool setMatrix)
3533 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3535 Matrix matrix = transMatrix;
3536 Camera camera = useCamera ? display.display3D.camera : null;
3541 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3546 matrix.m[3][0] - camera.cPosition.x,
3547 matrix.m[3][1] - camera.cPosition.y,
3548 matrix.m[3][2] - camera.cPosition.z);
3560 glMultMatrixd(matrix.array);
3565 public void UseSingleGLContext(bool useSingle)
3567 useSingleGLContext = useSingle;
3570 default dllexport void *
3571 #if defined(__WIN32__)
3572 __attribute__((stdcall))
3574 IS_GLGetContext(DisplaySystem displaySystem)
3578 #if defined(__WIN32__)
3579 OGLSystem system = displaySystem.driverData;
3581 #elif defined(__ANDROID__) || defined(__ODROID__)
3583 #elif defined(__EMSCRIPTEN__)
3584 OGLSystem system = displaySystem.driverData;
3585 return (void *)system.glc;
3587 OGLSystem system = displaySystem.driverData;
3588 return system.glContext;