1 namespace gfx::drivers;
9 #define GL_BGRA_EXT 0x80E1
11 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
13 # include "gl_core_3_3.h"
15 # include "gl_compat_4_4.h"
26 #undef glEnableClientState
27 #undef glDisableClientState
28 #undef GL_VERTEX_ARRAY
29 #undef GL_NORMAL_ARRAY
30 #undef GL_TEXTURE_COORD_ARRAY
33 #define glEnableClientState glEnableVertexAttribArray
34 #define glDisableClientState glDisableVertexAttribArray
35 #define GL_VERTEX_ARRAY GLBufferContents::vertex
36 #define GL_NORMAL_ARRAY GLBufferContents::normal
37 #define GL_TEXTURE_COORD_ARRAY GLBufferContents::texCoord
38 #define GL_COLOR_ARRAY GLBufferContents::color
42 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
44 #if defined(__unix__) || defined(__APPLE__)
46 #if !defined(__MINGW32__)
47 #define GL_GLEXT_PROTOTYPES
50 #define pointer _pointer
53 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
55 #define property _property
59 #define Window X11Window
60 #define Cursor X11Cursor
62 #define Display X11Display
64 #define KeyCode X11KeyCode
65 #define Picture X11Picture
69 #include <X11/Xutil.h>
71 #include <X11/extensions/XShm.h>
74 #include <X11/extensions/Xrender.h>
75 #include <X11/extensions/shape.h>
93 #if defined(__APPLE__)
94 #include <OpenGl/gl.h>
97 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
99 #if defined(__WIN32__)
100 //#define WIN32_LEAN_AND_MEAN
102 #define _WIN32_WINNT 0x0502
103 #define String Sting_
108 #if defined(__ANDROID__) || defined(__ODROID__)
111 #define property _property
114 #define Window X11Window
115 #define Cursor X11Cursor
117 #define Display X11Display
119 #define KeyCode X11KeyCode
120 #define Picture X11Picture
138 #elif defined(__EMSCRIPTEN__)
140 #define property _property
145 //#include <GLES/gl.h>
146 //#include <EGL/egl.h>
148 //#include <GLES2/gl.h>
149 //#include <EGL/egl.h>
151 //#include <GLES2/gl2.h>
153 #include <emscripten/emscripten.h>
162 #if defined(__ODROID__) && !defined(ES1_1)
166 #if defined(__EMSCRIPTEN__)
175 #if defined(__unix__) || defined(__APPLE__)
177 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
183 #define glLoadMatrix glLoadMatrixd
184 #define glMultMatrix glMultMatrixd
185 #define glGetMatrix glGetDoublev
186 #define glTranslate glTranslated
187 #define glScale glScaled
190 #define glVertex3v glVertex3dv
191 #define glNormal3v glNormal3dv
195 //#ifdef VERTEX_FORMAT_DOUBLE
197 #define glLoadMatrix glLoadMatrixd
198 #define glMultMatrix glMultMatrixd
199 #define glGetMatrix glGetDoublev
200 #define glVertex3v glVertex3dv
201 #define glNormal3v glNormal3dv
202 #define glTranslate glTranslated
203 #define glScale glScaled
204 //#define GL_VERTEX_FORMAT GL_DOUBLE
208 #define glLoadMatrix glLoadMatrixf
209 #define glMultMatrix glMultMatrixf
210 #define glGetMatrix glGetFloatv
211 #define glVertex3v glVertex3fv
212 #define glNormal3v glNormal3fv
213 #define glTranslate glTranslatef
214 #define glScale glScalef
215 //#define GL_VERTEX_FORMAT GL_FLOAT
220 #define GL_ARRAY_BUFFER_ARB 0x8892
221 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
222 #define GL_STATIC_DRAW_ARB 0x88E4
223 #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
224 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
226 #define GL_MULTISAMPLE_ARB 0x809D
228 #if defined(__WIN32__)
231 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
232 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
234 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
235 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
237 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
238 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
239 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
240 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
241 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
242 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
243 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
244 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
245 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
246 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = null;
247 static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = null;
249 #elif defined(__ANDROID__) || defined(__ODROID__)
251 #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
252 #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
253 #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
255 #define GL_POLYGON_STIPPLE 0xFFFF
256 #define GL_LINE_STIPPLE 0xFFFF
257 #define GL_LINE 0xFFFF
258 #define GL_FILL 0xFFFF
259 #define GL_ALL_ATTRIB_BITS 0xFFFF
260 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
266 #define GL_QUAD_STRIP 0
267 //#define GL_DOUBLE 0
268 //#define GL_UNSIGNED_INT 0
271 //#define GL_LINE_STIPPLE 0
272 #define GL_BGRA_EXT 0
273 #define GL_UNPACK_ROW_LENGTH 0
274 #define GL_UNPACK_SKIP_PIXELS 0
275 #define GL_UNPACK_SKIP_ROWS 0
277 #define GL_PACK_ROW_LENGTH 0
278 #define GL_PACK_SKIP_ROWS 0
279 #define GL_PACK_SKIP_PIXELS 0
284 #if defined(__ANDROID__) || defined(__ODROID__)
285 #define glBindFramebuffer glBindFramebufferOES
286 #define glBindRenderbuffer glBindRenderbufferOES
287 #define glFramebufferTexture2D glFramebufferTexture2DOES
288 #define glGenFramebuffers glGenFramebuffersOES
289 #define glGenRenderbuffers glGenRenderbuffersOES
290 #define glDeleteFramebuffers glDeleteFramebuffersOES
291 #define glDeleteRenderbuffers glDeleteRenderbuffersOES
293 #define GL_INT 0x1404
294 #define GL_UNSIGNED_INT 0x1405
295 #define GL_DOUBLE 0x140A
299 #if defined(ES1_1) || defined(SHADERS)
330 #undef glLoadIdentity
335 #undef glColorMaterial
338 #define glRecti glimtkRecti
339 #define glBegin glimtkBegin
340 #define glTexCoord2i glimtkTexCoord2i
341 #define glVertex2i glimtkVertex2i
342 #define glTexCoord2d glimtkTexCoord2d
343 #define glVertex2d glimtkVertex2d
344 #define glTexCoord2f glimtkTexCoord2f
345 #define glVertex2f glimtkVertex2f
346 #define glEnd glimtkEnd
347 #define glColor3f glimtkColor3f
348 #define glColor4ub glimtkColor4ub
349 #define glColor4fv glimtkColor4fv
350 #define glNormal3fv glimtkNormal3fv
351 #define glNormal3f glimtkNormal3f
352 #define glTexCoord2fv glimtkTexCoord2fv
353 #define glVertex3d glimtkVertex3d
354 #define glVertex3dv glimtkVertex3dv
355 #define glVertex3f glimtkVertex3f
356 #define glVertex3fv glimtkVertex3fv
358 #define glLoadMatrixd glmsLoadMatrixd
359 #define glMultMatrixd glmsMultMatrixd
360 #define glFrustum glmsFrustum
361 #define glOrtho glmsOrtho
362 #define glScaled glmsScaled
363 #define glScalef glmsScaled
364 #define glTranslated glmsTranslated
365 #define glRotated glmsRotated
366 #define glMatrixMode glmsMatrixMode
367 #define glLoadIdentity glmsLoadIdentity
368 #define glPushMatrix glmsPushMatrix
369 #define glPopMatrix glmsPopMatrix
371 #define glLineStipple glesLineStipple
372 #define glColorMaterial glesColorMaterial
373 #define glLightModeli glesLightModeli
377 public void glesColorMaterial(int a, int b)
379 PrintLn("glColorMaterial stub");
382 static GLuint stippleTexture;
383 #if defined(ES1_1) || defined(SHADERS) || defined(EM_MODE)
384 static bool stippleEnabled;
387 public void glesLineStipple( int i, unsigned short j )
391 for(x = 0; x < 16; x++)
393 bool v = (j & (1 << x)) != 0;
394 texture[x] = v ? 0xFFFFFFFF : 0;
397 glGenTextures(1, &stippleTexture);
398 glBindTexture(GL_TEXTURE_2D, stippleTexture);
399 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
401 // TOOD: Special shading code for stippling?
402 GLSetupTexturing(true);
403 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
404 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
406 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
407 glMatrixMode(GL_TEXTURE);
409 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
410 glScaled(i/16.0, 1, 1.0f);
411 glTranslated(0.5, 0.5, 0);
412 glMatrixMode(MatrixMode::projection);
415 public void glesLightModeli( unsigned int pname, int param )
417 #if !defined(EM_MODE) && !defined(SHADERS)
418 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
419 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
423 #if defined(__ANDROID__) || defined(__ODROID__)
424 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
425 void glFogi( unsigned int pname, int param ) { }
426 void glPolygonMode( unsigned int i, unsigned int j ) { }
429 // *** Picking won't be supported for now ***
430 void glPushName( unsigned int i ) { }
431 void glLoadName( unsigned int i ) { }
434 // Probably replace by regular glBlendFunc ...
435 void glBlendFuncSeparate(int a, int b, int c, int d)
440 // For direct pixel blitting...
441 void glRasterPos2d(double a, double b) { }
442 void glPixelZoom(float a, float b) { }
443 void glDrawPixels(int a, int b, int c, int d, void * e) { }
447 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
448 static int primitiveTypes[RenderPrimitiveType] =
450 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GLIMTKMode::quads, GLIMTKMode::quadStrip, GL_LINE_STRIP
454 public void GLSetupTexturing(bool enable)
457 shader_texturing(enable);
459 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
463 public void GLSetupLighting(bool enable)
466 shader_lighting(enable);
467 #elif !defined(EM_MODE)
468 (enable ? glEnable : glDisable)(GL_LIGHTING);
472 // Non OpenGL ES friendly stuff
476 //#undef GL_UNSIGNED_INT
482 #undef GL_POLYGON_STIPPLE
483 #undef GL_LINE_STIPPLE
486 #undef GL_ALL_ATTRIB_BITS
487 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
491 static int displayWidth, displayHeight;
493 #define GL_CLAMP_TO_EDGE 0x812F
495 static bool vboAvailable;
497 static bool useSingleGLContext = false;
498 class OGLDisplay : struct
500 #if defined(__WIN32__)
511 byte * pboMemory1, * pboMemory2;
513 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
514 GLXContext glContext;
517 XShmSegmentInfo shminfo;
519 XShmSegmentInfo shminfoShape;
524 X11Picture windowPicture;
525 X11Picture pixmapPicture;
527 X11Picture shapePicture;
530 ColorAlpha * flippingBuffer;
531 int flipBufH, flipBufW;
537 static void APIENTRY openglCallbackFunction(GLenum source,
542 const GLchar* message,
543 const void* userParam)
545 PrintLn("---------------------opengl-callback-start------------");
546 PrintLn("message: ", message);
550 case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
551 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
552 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
553 case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
554 case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
555 case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
562 case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
563 case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
564 case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
566 PrintLn("---------------------opengl-callback-end--------------");
570 class OGLSystem : struct
575 #if defined(__WIN32__)
576 PIXELFORMATDESCRIPTOR pfd;
581 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
582 XVisualInfo * visualInfo;
583 GLXContext glContext;
584 GLXDrawable glxDrawable;
588 class OGLSurface : struct
596 float foreground[4], background[4], bitmapMult[4];
599 class OGLMesh : struct
608 class OGLIndices : struct
618 static void setupDebugging()
621 if(glDebugMessageCallback)
623 GLuint unusedIds = 0;
625 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
626 glDebugMessageCallback(openglCallbackFunction, null);
627 glDebugMessageControl(GL_DONT_CARE,
637 #if defined(__WIN32__)
638 static HGLRC winCreateContext(HDC hdc)
640 if(wglCreateContextAttribsARB)
644 WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
645 WGL_CONTEXT_MINOR_VERSION_ARB, 4,
646 WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | */WGL_CONTEXT_DEBUG_BIT_ARB,
647 WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB /*WGL_CONTEXT_CORE_PROFILE_BIT_ARB*/,
650 return wglCreateContextAttribsARB(hdc, null, attribs);
653 return wglCreateContext(hdc);
657 class OpenGLDisplayDriver : DisplayDriver
659 class_property(name) = "OpenGL";
661 bool LockSystem(DisplaySystem displaySystem)
663 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
664 OGLSystem oglSystem = displaySystem.driverData;
665 if(useSingleGLContext) return true;
666 #if defined(__WIN32__)
667 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
668 #elif defined(__unix__) || defined(__APPLE__)
669 //if(previous) return true;
670 // printf("Making SYSTEM current\n");
671 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
672 //previous = oglSystem.glContext;
675 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
676 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
680 void UnlockSystem(DisplaySystem displaySystem)
682 if(useSingleGLContext) return;
683 #if defined(__WIN32__)
684 wglMakeCurrent(null, null);
685 #elif defined(__unix__) || defined(__APPLE__)
686 // printf("Making NULL current\n");
687 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
689 glXMakeCurrent(xGlobalDisplay, None, null);
695 bool Lock(Display display)
697 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
698 OGLDisplay oglDisplay = display.driverData;
699 if(useSingleGLContext) return true;
700 #if defined(__WIN32__)
701 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
702 #elif defined(__unix__) || defined(__APPLE__)
703 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
704 // printf(" Making DISPLAY current\n");
705 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
708 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
709 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
713 void Unlock(Display display)
715 if(useSingleGLContext) return;
716 //printf(" Making NULL current\n");
717 //glXMakeCurrent(xGlobalDisplay, None, null);
719 LockSystem(display.displaySystem);
722 void DestroyDisplay(Display display)
724 OGLDisplay oglDisplay = display.driverData;
728 #if defined(__WIN32__)
729 wglMakeCurrent( null, null );
732 wglDeleteContext(oglDisplay.glrc);
734 if(oglDisplay.hdc && oglDisplay.pBuffer)
735 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
737 if(oglDisplay.pBuffer)
738 wglDestroyPbufferARB(oglDisplay.pBuffer);
741 ReleaseDC(display.window, oglDisplay.hdc);
743 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
744 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
746 #elif defined(__unix__) || defined(__APPLE__)
747 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
749 if(oglDisplay.shapePixmap)
750 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
751 if(oglDisplay.pixmap)
752 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
755 if(oglDisplay.shminfoShape.shmid != -1)
757 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
758 if(oglDisplay.shminfo.shmaddr != (void *)-1)
759 shmdt(oglDisplay.shminfo.shmaddr);
760 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
763 if(oglDisplay.shapeImage)
765 if(oglDisplay.shminfoShape.shmid != -1)
767 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
768 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
769 shmdt(oglDisplay.shminfoShape.shmaddr);
770 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
772 XDestroyImage(oglDisplay.shapeImage);
773 oglDisplay.shapeImage = None;
776 glXMakeCurrent(xGlobalDisplay, None, null);
778 if(oglDisplay.glContext)
779 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
782 delete oglDisplay.flippingBuffer;
784 display.driverData = null;
788 void ::CheckExtensions(OGLSystem oglSystem)
790 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
792 oglSystem.pow2textures = strstr(extensions, "GL_ARB_texture_non_power_of_two") ? false : true;
793 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
796 bool CreateDisplaySystem(DisplaySystem displaySystem)
799 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
802 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
804 oglSystem.hdc = GetDC(oglSystem.hwnd);
808 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
809 oglSystem.pfd.nVersion = 1;
810 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
811 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
812 oglSystem.pfd.cColorBits = 24;
813 oglSystem.pfd.cAlphaBits = 8;
814 oglSystem.pfd.cDepthBits = 24;
815 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
817 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
818 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
820 if(oglSystem.pfd.cColorBits > 8)
822 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
823 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
826 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
828 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
829 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
830 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
831 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
832 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
833 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
834 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
835 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
836 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
837 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
838 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
840 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
841 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
843 // eSystem_LoggingMode(LOG_MSGBOX, null);
845 if(wglChoosePixelFormatARB)
850 float fAttributes[] = {0,0};
853 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
854 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
855 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
856 WGL_COLOR_BITS_ARB,24,
857 WGL_ALPHA_BITS_ARB,8,
858 WGL_DEPTH_BITS_ARB,16,
859 WGL_STENCIL_BITS_ARB,0,
860 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
861 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
862 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
866 //Log("Found wglChoosePixelFormatARB\n");
868 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
869 if(!valid || !numFormats)
871 //Log("Can't find 4x multi sampling\n");
873 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
874 if(!valid || !numFormats)
876 // Log("Can't find 2x multi sampling\n");
879 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
882 if(valid && numFormats)
884 oglSystem.format = pixelFormat;
885 wglMakeCurrent(null, null);
886 wglDeleteContext(oglSystem.glrc);
888 // *** DescribePixelFormat does not support WGL pixel formats! ***
889 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
890 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
891 //Log("Successfully set pixel format\n");
893 oglSystem.glrc = winCreateContext(oglSystem.hdc);
894 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
898 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
902 wglMakeCurrent(null, null);
904 //eSystem_DumpErrors(true);
908 #elif defined(__unix__) || defined(__APPLE__)
910 #if defined(__ANDROID__)
911 egl_init_display(guiApp.desktop.windowHandle);
912 #elif defined(__ODROID__)
913 egl_init_display((uint)displaySystem.window);
914 CheckExtensions(oglSystem);
916 #elif defined(__EMSCRIPTEN__)
917 if(glfwInit() == GL_TRUE)
919 const int width = 640, height = 480;
920 if(glfwOpenWindow(width, height, 8, 8, 8, 8, 16, 0, GLFW_WINDOW) == GL_TRUE)
926 printf("glfwOpenWindow() failed\n"); //glfwTerminate();
929 printf("glfwInit() failed\n"); //glfwTerminate();
932 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
933 XSetWindowAttributes attr;
938 #ifndef ECERE_MINIGLX
939 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
942 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
946 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
947 attr.background_pixel = 0;
948 attr.border_pixel = 0;
949 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
950 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
951 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
953 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
954 oglSystem.visualInfo->visual, mask, &attr );
956 if(oglSystem.visualInfo)
958 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
959 if(oglSystem.glContext)
961 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
963 CheckExtensions(oglSystem);
964 glXMakeCurrent(xGlobalDisplay, None, null);
971 displaySystem.flags.alpha = true;
972 displaySystem.flags.flipping = true;
973 displaySystem.pixelFormat = pixelFormat888;
977 void DestroyDisplaySystem(DisplaySystem displaySystem)
979 OGLSystem oglSystem = displaySystem.driverData;
981 #if defined(__WIN32__)
982 wglMakeCurrent( null, null );
985 wglDeleteContext(oglSystem.glrc);
988 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
989 DestroyWindow(oglSystem.hwnd);
991 #elif defined(__unix__) || defined(__APPLE__)
992 #if defined(__ANDROID__) || defined(__ODROID__)
994 #elif defined(__EMSCRIPTEN__)
997 if(oglSystem.visualInfo)
1000 __miniglx_XFree(oglSystem.visualInfo);
1002 XFree(oglSystem.visualInfo);
1006 if(oglSystem.glxDrawable)
1008 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1009 oglSystem.glxDrawable = 0;
1016 static bool ::initialDisplaySetup(Display display)
1020 loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1022 glEnableClientState(GL_VERTEX_ARRAY);
1024 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1025 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1027 #if defined(__WIN32__)
1028 if(glBlendFuncSeparate)
1029 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1031 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1033 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1037 glMatrixMode(MatrixMode::modelView);
1038 glLoadIdentity(); // For setting up GLES stack
1039 glScaled(1.0, 1.0, -1.0);
1040 // glTranslatef(0.375f, 0.375f, 0.0f);
1041 // glTranslatef(-0.625f, -0.625f, 0.0f);
1042 glMatrixMode(MatrixMode::projection);
1043 #if !defined(EM_MODE) && !defined(SHADERS)
1044 glShadeModel(GL_FLAT);
1046 // #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1048 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1050 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1051 glFogi(GL_FOG_MODE, GL_EXP);
1052 glFogf(GL_FOG_DENSITY, 0);
1053 glEnable(GL_NORMALIZE);
1055 glDepthFunc(GL_LESS);
1057 glDisable(GL_MULTISAMPLE_ARB);
1058 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1059 display.ambient = Color { 50,50,50 };
1064 bool CreateDisplay(Display display)
1066 bool result = false;
1067 OGLDisplay oglDisplay = display.driverData;
1068 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
1069 OGLSystem oglSystem = display.displaySystem.driverData;
1073 oglDisplay = display.driverData = OGLDisplay { };
1074 //printf("Inside CreateDisplay\n");
1076 #if defined(__WIN32__) || defined(USEPBUFFER)
1077 if(!display.alphaBlend)
1080 #if defined(__WIN32__)
1081 oglDisplay.hdc = GetDC(display.window);
1082 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1083 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1085 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1086 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1090 ReleaseDC(display.window, oglDisplay.hdc);
1091 #elif defined(__unix__) || defined(__APPLE__)
1092 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1094 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1096 #if defined(__APPLE__)
1097 XVisualInfo template = { 0 };
1098 XWindowAttributes winAttr;
1100 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1101 template.visualid = XVisualIDFromVisual(winAttr.visual);
1102 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1104 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1105 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1106 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1107 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1109 // visualInfo = oglSystem.visualInfo;
1114 //printf("visualInfo is not null\n");
1115 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1116 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1117 //XFree(visualInfo);
1120 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1121 if(oglDisplay.glContext)
1123 //printf("CreateDisplay Got a Context\n");
1124 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1130 #if defined(__WIN32__) || defined(USEPBUFFER)
1134 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1139 ogl_LoadFunctions();
1140 CheckExtensions(oglSystem);
1141 vboAvailable = glBindBuffer != null;
1143 initialDisplaySetup(display);
1146 if(!useSingleGLContext)
1148 #if defined(__WIN32__)
1149 wglMakeCurrent(null, null);
1150 #elif defined(__unix__) || defined(__APPLE__)
1151 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1154 glXMakeCurrent(xGlobalDisplay, None, null);
1160 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1168 bool DisplaySize(Display display, int width, int height)
1170 OGLDisplay oglDisplay = display.driverData;
1172 bool result = false;
1174 //printf("Inside DisplaySize\n");
1175 #if defined(__WIN32__) || defined(USEPBUFFER)
1176 OGLSystem oglSystem = display.displaySystem.driverData;
1177 if(display.alphaBlend)
1179 #if defined(__WIN32__)
1180 const int attributes[]=
1182 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1183 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1185 int pixelFormat = 0;
1186 if(wglChoosePixelFormatARB)
1190 float fAttributes[] = {0,0};
1193 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1194 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1195 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1196 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1197 WGL_COLOR_BITS_ARB,24,
1198 WGL_ALPHA_BITS_ARB,8,
1199 WGL_DEPTH_BITS_ARB,16,
1200 WGL_STENCIL_BITS_ARB,0,
1201 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1202 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1203 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1207 //Log("Found wglChoosePixelFormatARB\n");
1209 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1210 if(!valid || !numFormats)
1212 //Log("Can't find 4x multi sampling\n");
1213 iAttributes[19] = 2;
1214 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1215 if(!valid || !numFormats)
1217 // Log("Can't find 2x multi sampling\n");
1218 iAttributes[16] = 0;
1219 iAttributes[17] = 0;
1220 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1221 if(!valid || !numFormats)
1225 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1226 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1227 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1228 WGL_COLOR_BITS_ARB,24,
1229 WGL_ALPHA_BITS_ARB,8,
1230 WGL_DEPTH_BITS_ARB,16,
1233 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1237 if(valid && numFormats)
1239 wglMakeCurrent(null, null);
1243 wglMakeCurrent( null, null );
1244 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1245 if(oglDisplay.hdc && oglDisplay.pBuffer)
1246 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1248 wglDestroyPbufferARB(oglDisplay.pBuffer);
1250 if(!useSingleGLContext)
1251 wglMakeCurrent( null, null );
1254 wglDeleteContext(oglDisplay.glrc);
1256 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1257 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1258 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1261 HDC hdc = GetDC(display.window);
1263 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1264 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1266 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1267 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1269 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1271 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1275 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1276 oglDisplay.memDC = CreateCompatibleDC(hdc);
1277 SetMapMode(oglDisplay.memDC, MM_TEXT);
1278 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1279 info->bmiHeader.biPlanes = 1;
1280 info->bmiHeader.biCompression = BI_RGB;
1281 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1282 info->bmiHeader.biWidth = width;
1283 info->bmiHeader.biHeight = height;
1284 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1287 SelectObject(oglDisplay.memDC, newBitmap);
1288 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1291 PIXELFORMATDESCRIPTOR pfd = { 0 };
1292 pfd.nSize = (short)sizeof(pfd);
1294 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1295 pfd.iPixelType = PFD_TYPE_RGBA;
1296 pfd.cColorBits = 32;
1297 //pfd.cAlphaBits = 8;
1298 pfd.cDepthBits = 24;
1299 pfd.iLayerType = PFD_MAIN_PLANE;
1301 oglDisplay.hdc = oglDisplay.memDC;
1303 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1304 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1305 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1307 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1308 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1309 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1314 const int imageSize = width * height * 4;
1316 glGenBuffersARB(2, oglDisplay.imageBuffers);
1318 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1319 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1320 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1321 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1324 oglDisplay.memBitmap = newBitmap;
1325 oglDisplay.stride = width;
1331 ReleaseDC(display.window, hdc);
1333 #elif defined(__unix__) || defined(__APPLE__)
1334 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1339 GLX_DOUBLEBUFFER, True,
1345 GLX_STENCIL_SIZE, 1,
1346 //GLX_DEPTH_SIZE, 24,
1347 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1348 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1354 GLX_PBUFFER_WIDTH, width,
1355 GLX_PBUFFER_HEIGHT, height,
1356 GLX_LARGEST_PBUFFER, False,
1360 // choose a pixel format that meets our minimum requirements
1363 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1366 if(oglDisplay.pixmap)
1368 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1369 oglDisplay.pixmap = None;
1371 if(oglDisplay.shapePixmap)
1373 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1374 oglDisplay.shapePixmap = None;
1377 // Free Shared Memory Pixmap
1378 if(oglDisplay.image)
1380 if(oglDisplay.shminfoShape.shmid != -1)
1382 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1383 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1384 shmdt(oglDisplay.shminfo.shmaddr);
1385 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1387 XDestroyImage(oglDisplay.image);
1388 oglDisplay.image = None;
1390 if(oglDisplay.shapeImage)
1392 if(oglDisplay.shminfoShape.shmid != -1)
1394 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1395 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1396 shmdt(oglDisplay.shminfoShape.shmaddr);
1397 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1399 XDestroyImage(oglDisplay.shapeImage);
1400 oglDisplay.shapeImage = None;
1403 if(oglDisplay.windowPicture)
1404 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1405 if(oglDisplay.pixmapPicture)
1406 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1408 if(oglDisplay.pixmap)
1409 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1411 if(oglDisplay.glContext)
1412 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1413 if(oglDisplay.pBuffer)
1414 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1416 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1417 if(oglDisplay.pBuffer)
1419 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1420 if(oglDisplay.glContext)
1422 glXMakeCurrent(xGlobalDisplay, None, null);
1423 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1425 // Initialize Shared Memory Pixmap
1426 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1427 ZPixmap, null, &oglDisplay.shminfo, width, height);
1428 if(oglDisplay.image)
1430 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1431 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1432 if(oglDisplay.shminfo.shmid != -1)
1434 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1435 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1437 oglDisplay.shminfo.readOnly = False;
1438 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1440 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1441 &oglDisplay.shminfo, width, height, 32);
1443 // Initialize Shared Memory Shape Pixmap
1444 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1445 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1446 if(oglDisplay.shapeImage)
1448 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1449 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1450 if(oglDisplay.shminfoShape.shmid != -1)
1452 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1453 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1455 oglDisplay.shminfoShape.readOnly = False;
1456 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1458 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1459 &oglDisplay.shminfoShape, width, height, 1);
1460 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1463 XRenderPictureAttributes attributes = { 0 };
1464 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1465 #if !defined(__APPLE__)
1466 attributes.repeat = RepeatNormal;
1468 attributes.repeat = 1;
1470 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1471 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1472 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1473 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1476 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1477 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1494 CreateDisplay(display);
1495 #if defined(__WIN32__)
1496 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1497 #elif defined(__unix__) || defined(__APPLE__)
1498 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1502 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1510 if(display.alphaBlend && result)
1511 initialDisplaySetup(display);
1513 if(!result && display.alphaBlend)
1515 printf("Alpha blending windows not supported on this display\n");
1522 glViewport(0,0,width,height);
1523 glMatrixMode(MatrixMode::projection);
1525 glOrtho(0,width,height,0,0.0,1.0);
1526 displayWidth = display.width = width;
1527 displayHeight = display.height = height;
1529 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1531 oglDisplay.flipBufW = width;
1532 oglDisplay.flipBufH = height;
1536 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1539 if(oglDisplay.flippingBuffer || !width || !height)
1545 void DisplayPosition(Display display, int x, int y)
1547 OGLDisplay oglDisplay = display.driverData;
1553 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1557 void RestorePalette(Display display)
1561 void StartUpdate(Display display)
1565 void EndUpdate(Display display)
1569 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1573 void Update(Display display, Box updateBox)
1575 #if defined(__WIN32__) || defined(USEPBUFFER)
1576 OGLDisplay oglDisplay = display.driverData;
1578 //Logf("DisplayScreen\n");
1580 #if !defined(__ANDROID__)
1585 #if defined(__WIN32__) || defined(USEPBUFFER)
1586 if(display.alphaBlend)
1588 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1589 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1590 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1591 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1592 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1595 #if defined(__WIN32__)
1597 POINT point = { oglDisplay.x, oglDisplay.y};
1598 POINT srcPoint = { 0, 0 };
1599 BLENDFUNCTION blend = { 0 };
1601 size.cx = display.width;
1602 size.cy = display.height;
1603 blend.BlendOp = AC_SRC_OVER;
1604 blend.BlendFlags = 0;
1605 blend.SourceConstantAlpha = 255;
1606 blend.AlphaFormat = AC_SRC_ALPHA;
1609 // Process partial images. Mapping the buffer waits for
1610 // outstanding DMA transfers into the buffer to finish.
1611 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1612 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1614 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1615 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1618 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1619 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1622 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1625 // Unmap the image buffers
1626 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1627 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1629 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1630 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1632 // Bind two different buffer objects and start the glReadPixels
1633 // asynchronously. Each call will return directly after
1634 // starting the DMA transfer.
1635 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1636 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1638 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1639 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1643 #elif defined(__unix__) || defined(__APPLE__)
1644 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1646 XTransform transform =
1649 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1650 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1651 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1654 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1655 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1656 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1657 #if !defined(__APPLE__)
1658 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1660 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1662 XFlush(xGlobalDisplay);
1670 #if defined(__WIN32__)
1671 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1672 SwapBuffers(oglDisplay.hdc);
1673 #elif defined(__unix__) || defined(__APPLE__)
1674 #if defined(__ANDROID__) || defined(__ODROID__)
1675 eglSwapBuffers(eglDisplay, eglSurface);
1676 #elif defined(__EMSCRIPTEN__)
1679 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1683 //Logf("Out of DisplayScreen\n");
1686 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1688 if(bitmap.driverData)
1690 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1691 glDeleteTextures(1, &tex);
1692 bitmap.driverData = 0;
1694 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1697 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1699 OGLSystem oglSystem = displaySystem.driverData;
1700 bool result = false;
1702 GLuint glBitmap = 0;
1704 uint w = width, h = height;
1705 if(oglSystem.pow2textures)
1710 w = Min(w, oglSystem.maxTextureSize);
1711 h = Min(h, oglSystem.maxTextureSize);
1713 glGenTextures(1, &glBitmap);
1714 glBindTexture(GL_TEXTURE_2D, glBitmap);
1716 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1718 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1722 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1724 #if !defined(SHADERS)
1725 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1728 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1730 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1731 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1735 bitmap.driverData = (void *)(uintptr)glBitmap;
1736 bitmap.driver = displaySystem.driver;
1744 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1746 bool result = false;
1747 OGLSystem oglSystem = displaySystem.driverData;
1748 Bitmap convBitmap = bitmap;
1752 convBitmap.Copy(bitmap);
1755 // Pre process the bitmap... First make it 32 bit
1756 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1759 uint w = bitmap.width, h = bitmap.height;
1760 GLuint glBitmap = 0;
1761 if(oglSystem.pow2textures)
1766 w = Min(w, oglSystem.maxTextureSize);
1767 h = Min(h, oglSystem.maxTextureSize);
1771 while(w * 2 < h) w *= 2;
1772 while(h * 2 < w) h *= 2;
1775 // Switch ARGB to RGBA
1776 //if(bitmap.format != pixelFormatRGBA)
1778 for(c=0; c<bitmap.size; c++)
1780 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1782 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1783 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1786 // convBitmap.pixelFormat = pixelFormat888;
1789 glGenTextures(1, &glBitmap);
1792 //int error = glGetError();
1796 glBindTexture(GL_TEXTURE_2D, glBitmap);
1797 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1799 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1800 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1802 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1804 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1805 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1807 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1808 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1809 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1810 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1813 #if !defined(SHADERS)
1814 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1819 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1824 if(bitmap.width != w || bitmap.height != h)
1826 mipMap = Bitmap { };
1827 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1829 Surface mipSurface = mipMap.GetSurface(0,0,null);
1830 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1840 mipMap = convBitmap;
1847 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1848 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1849 //printf("Calling glTexImage2D\n");
1850 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
1851 //printf("width = %d (Should be %d, %d)\n", width, w, h);
1852 if((error = glGetError()))
1854 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
1855 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
1859 if(mipMap != convBitmap)
1864 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
1865 bitmap.driverData = (void *)(uintptr)glBitmap;
1866 bitmap.driver = displaySystem.driver;
1871 FreeBitmap(displaySystem, bitmap);
1872 else if(oglSystem.loadingFont)
1874 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1875 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1876 oglSystem.loadingFont = false;
1882 void ReleaseSurface(Display display, Surface surface)
1884 glDisable(GL_SCISSOR_TEST);
1885 delete surface.driverData;
1886 surface.driverData = null;
1889 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
1894 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
1896 bool result = false;
1897 OGLSurface oglSurface = surface.driverData = OGLSurface { };
1899 //Logf("GetSurface\n");
1903 if(displayWidth != display.width || displayHeight != display.height)
1905 displayWidth = display.width;
1906 displayHeight = display.height;
1908 glViewport(0,0,display.width,display.height);
1910 glOrtho(0,display.width,display.height,0,0.0,1.0);
1913 surface.offset.x = x;
1914 surface.offset.y = y;
1915 surface.unclippedBox = surface.box = clip;
1916 oglSurface.bitmapMult[0] = 1;
1917 oglSurface.bitmapMult[1] = 1;
1918 oglSurface.bitmapMult[2] = 1;
1919 oglSurface.bitmapMult[3] = 1;
1921 glEnable(GL_SCISSOR_TEST);
1924 (display.height) -(y+clip.bottom)-1,
1925 clip.right-clip.left+1,
1926 clip.bottom-clip.top+1);
1932 void Clip(Display display, Surface surface, Box clip)
1941 box.Clip(surface.unclippedBox);
1945 box = surface.box = surface.unclippedBox;
1946 box.left += surface.offset.x;
1947 box.top += surface.offset.y;
1948 box.right+= surface.offset.x;
1949 box.bottom += surface.offset.y;
1952 box.left,display.height - box.bottom - 1,
1953 box.right-box.left+1, box.bottom-box.top+1);
1956 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
1958 bool result = false;
1959 OGLDisplay oglDisplay = display.driverData;
1960 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
1962 if(oglDisplay.flippingBuffer)
1964 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
1967 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
1973 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1974 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
1975 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1976 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1977 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
1980 for(row = 0; row<h; row++)
1981 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
1988 void SetForeground(Display display, Surface surface, ColorAlpha color)
1990 OGLSurface oglSurface = surface.driverData;
1992 //Logf("SetForeground\n");
1994 oglSurface.foreground[0] = color.color.r/255.0f;
1995 oglSurface.foreground[1] = color.color.g/255.0f;
1996 oglSurface.foreground[2] = color.color.b/255.0f;
1997 //oglSurface.foreground[3] = 1.0f;
1998 oglSurface.foreground[3] = color.a/255.0f;
2000 //if(!oglSurface.foreground[3])printf("bug");
2003 void SetBackground(Display display, Surface surface, ColorAlpha color)
2005 OGLSurface oglSurface = surface.driverData;
2007 //Logf("SetBackground\n");
2009 oglSurface.background[0] = color.color.r/255.0f;
2010 oglSurface.background[1] = color.color.g/255.0f;
2011 oglSurface.background[2] = color.color.b/255.0f;
2012 //oglSurface.background[3] = 1.0;
2013 oglSurface.background[3] = color.a/255.0f;
2016 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2018 OGLSurface oglSurface = surface.driverData;
2020 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2021 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2022 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2023 oglSurface.bitmapMult[3] = color.a/255.0f;
2026 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2031 void PutPixel(Display display, Surface surface,int x,int y)
2033 OGLSurface oglSurface = surface.driverData;
2035 //Logf("PutPixel\n");
2037 glColor4fv(oglSurface.foreground);
2039 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2040 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2045 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2047 OGLSurface oglSurface = surface.driverData;
2048 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2063 x1 += surface.offset.x;
2064 y1 += surface.offset.y;
2065 x2 += surface.offset.x;
2066 y2 += surface.offset.y;
2070 glColor4fv(oglSurface.foreground);
2072 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2075 glTexCoord2f(0.5f, 0);
2076 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2077 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2078 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2087 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2088 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2094 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2096 OGLSurface oglSurface = surface.driverData;
2097 x1 += surface.offset.x;
2098 y1 += surface.offset.y;
2099 x2 += surface.offset.x;
2100 y2 += surface.offset.y;
2102 //Logf("Rectangle\n");
2104 glColor4fv(oglSurface.foreground);
2105 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2110 glTexCoord2f(0.5f, 0);
2111 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2112 glTexCoord2f(y2-y1 + 0.5f, 0);
2113 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2115 glTexCoord2f(0.5f, 0);
2116 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2117 glTexCoord2f(x2 - x1 + 0.5f, 0);
2118 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2120 glTexCoord2f(0.5f, 0);
2121 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2122 glTexCoord2f(y1 - y2 + 0.5f, 0);
2123 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2125 glTexCoord2f(0.5f, 0);
2126 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2127 glTexCoord2f(x1 - x2 + 0.5f, 0);
2128 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2133 glBegin(GL_LINE_LOOP);
2140 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2141 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2142 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2143 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2148 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2150 OGLSurface oglSurface = surface.driverData;
2153 glColor4fv(oglSurface.background);
2157 glVertex2f(x1+surface.offset.x, y1+surface.offset.y);
2158 glVertex2f(x1+surface.offset.x, y2+surface.offset.y+1);
2159 glVertex2f(x2+surface.offset.x+1, y2+surface.offset.y+1);
2160 glVertex2f(x2+surface.offset.x+1, y1+surface.offset.y);
2163 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2164 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2167 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2168 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2172 void Clear(Display display, Surface surface, ClearType type)
2174 OGLDisplay oglDisplay = display.driverData;
2175 OGLSurface oglSurface = surface.driverData;
2178 if(type != depthBuffer)
2179 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2180 if(type != colorBuffer && !oglDisplay.depthWrite)
2182 glDepthMask((byte)bool::true);
2184 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2185 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2186 if(type != colorBuffer && !oglDisplay.depthWrite)
2188 glDepthMask((byte)bool::false);
2192 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2197 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2199 OGLSurface oglSurface = surface.driverData;
2201 if(!oglSurface.writingText)
2203 // glTranslatef(-0.375f, -0.375f, 0.0f);
2204 GLSetupTexturing(true);
2205 glColor4fv(oglSurface.bitmapMult);
2207 else if(oglSurface.xOffset)
2208 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2210 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2211 glBegin(GLIMTKMode::quads);
2215 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2216 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2217 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2218 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2219 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2220 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2221 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2222 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2227 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2228 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2229 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2230 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2231 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2232 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2233 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2234 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2237 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2238 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2239 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2240 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2241 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2242 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2243 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2244 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2248 if(!oglSurface.writingText)
2250 GLSetupTexturing(false);
2252 //glTranslate(0.375, 0.375, 0.0);
2254 else if(oglSurface.xOffset)
2255 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2258 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2260 OGLSurface oglSurface = surface.driverData;
2262 //glTranslate(-0.375, -0.375, 0.0);
2264 GLSetupTexturing(true);
2265 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2267 glColor4fv(oglSurface.bitmapMult);
2269 glBegin(GLIMTKMode::quads);
2273 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2274 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2276 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2277 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2279 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2280 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2282 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2283 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2287 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2288 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2290 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2291 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2293 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2294 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2296 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2297 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2302 GLSetupTexturing(false);
2304 //glTranslate(0.375, 0.375, 0.0);
2307 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2309 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2312 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2314 #if !defined(EM_MODE)
2315 float s2dw,s2dh,d2sw,d2sh;
2316 //bool flipX = false, flipY = false;
2318 //Logf("StretchDI\n");
2320 if(Sgn(w) != Sgn(sw))
2326 if(Sgn(h) != Sgn(sh))
2338 //Clip against the edges of the source
2341 dx+=(int)((0-sx) * s2dw);
2342 w-=(int)((0-sx) * s2dw);
2348 dy+=(int)((0-sy) * s2dh);
2349 h-=(int)((0-sy) * s2dh);
2354 if(sx+sw>bitmap.width-1)
2356 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2357 sw-=sx+sw-(bitmap.width-1)-1;
2359 if(sy+sh>(bitmap.height-1))
2361 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2362 sh-=sy+sh-(bitmap.height-1)-1;
2364 //Clip against the edges of the surfaceination
2365 if(dx<surface.box.left)
2368 sx+=(int)((surface.box.left-dx)*d2sw);
2369 sw-=(int)((surface.box.left-dx)*d2sw);
2370 w-=surface.box.left-dx;
2371 dx=surface.box.left;
2373 if(dy<surface.box.top)
2375 sy+=(int)((surface.box.top-dy)*d2sh);
2376 sh-=(int)((surface.box.top-dy)*d2sh);
2377 h-=surface.box.top-dy;
2380 if(dx+w>surface.box.right)
2382 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2383 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2384 w-=dx+w-surface.box.right-1;
2386 if(dy+h>surface.box.bottom)
2388 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2389 h-=dy+h-surface.box.bottom-1;
2391 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2393 dx += surface.offset.x;
2394 dy += surface.offset.y;
2396 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2398 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2399 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2400 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2401 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2402 #if !defined(SHADERS)
2403 glRasterPos2d(dx,dy);
2404 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2405 glPixelZoom(s2dw, -s2dh);
2406 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2408 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2409 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2410 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2411 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2416 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2418 #if !defined(EM_MODE)
2421 //Clip against the edges of the source
2434 if(sx+w>bitmap.width-1)
2435 w-=sx+w-(bitmap.width-1)-1;
2436 if(sy+h>bitmap.height-1)
2437 h-=sy+h-(bitmap.height-1)-1;
2438 //Clip against the edges of the surfaceination
2439 if(dx<surface.box.left)
2442 sx+=surface.box.left-dx;
2443 w-=surface.box.left-dx;
2444 dx=surface.box.left;
2446 if(dy<surface.box.top)
2448 sy+=surface.box.top-dy;
2449 h-=surface.box.top-dy;
2452 if(dx+w>surface.box.right)
2454 //if(flip) sx+=dx+w-surface.box.right-1;
2455 w-=dx+w-surface.box.right-1;
2457 if(dy+h>surface.box.bottom)
2458 h-=dy+h-surface.box.bottom-1;
2462 dx += surface.offset.x;
2463 dy += surface.offset.y;
2465 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2467 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2468 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2469 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2470 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2471 #if !defined(SHADERS)
2472 glRasterPos2d(dx,dy);
2474 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2476 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2477 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2478 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2479 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2484 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2486 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2489 void UnloadFont(DisplaySystem displaySystem, Font font)
2491 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2494 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2497 OGLSystem oglSystem = displaySystem.driverData;
2498 oglSystem.loadingFont = true;
2499 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2503 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2505 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2508 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2510 OGLSurface oglSurface = surface.driverData;
2511 OGLSystem oglSystem = display.displaySystem.driverData;
2512 oglSystem.loadingFont = true;
2514 //glTranslated(-0.375, -0.375, 0.0);
2518 if(surface.textOpacity)
2521 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2523 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2526 oglSurface.writingText = true;
2528 GLSetupTexturing(true);
2530 if(surface.font.outlineSize)
2532 ColorAlpha outlineColor = surface.outlineColor;
2533 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2534 oglSurface.writingOutline = true;
2535 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2536 oglSurface.writingOutline = false;
2538 glColor4fv(oglSurface.foreground);
2540 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2541 oglSurface.writingText = false;
2542 oglSystem.loadingFont = false;
2544 GLSetupTexturing(false);
2546 //glTranslated(0.375, 0.375, 0.0);
2549 void TextFont(Display display, Surface surface, Font font)
2551 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2554 void TextOpacity(Display display, Surface surface, bool opaque)
2556 OGLSurface oglSurface = surface.driverData;
2557 oglSurface.opaqueText = opaque;
2560 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2562 OGLSurface oglSurface = surface.driverData;
2563 OGLSystem oglSystem = display.displaySystem.driverData;
2564 oglSystem.loadingFont = true;
2565 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2566 oglSystem.loadingFont = false;
2569 void DrawingChar(Display display, Surface surface, char character)
2574 void LineStipple(Display display, Surface surface, uint32 stipple)
2576 //Logf("Stipple\n");
2580 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2581 stippleEnabled = true;
2582 glesLineStipple(1, (uint16)stipple);
2584 glLineStipple(1, (uint16)stipple);
2585 glEnable(GL_LINE_STIPPLE);
2590 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2591 stippleEnabled = false;
2592 glMatrixMode(GL_TEXTURE);
2594 glMatrixMode(MatrixMode::projection);
2595 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2597 glDisable(GL_LINE_STIPPLE);
2601 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2602 void SetRenderState(Display display, RenderState state, uint value)
2604 OGLDisplay oglDisplay = display.driverData;
2605 //Logf("RenderState\n");
2611 glEnable(GL_MULTISAMPLE_ARB);
2613 glDisable(GL_MULTISAMPLE_ARB);
2617 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2621 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2624 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2625 oglDisplay.depthWrite = (bool)value;
2629 #if !defined(SHADERS)
2630 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2631 glFogfv(GL_FOG_COLOR, (float *)&color);
2636 #if !defined(SHADERS)
2637 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2641 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2645 #if defined(SHADERS)
2646 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2647 #elif !defined(EM_MODE)
2648 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2649 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2655 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2660 #if defined(__WIN32__)
2661 wglSwapIntervalEXT(value ? 1 : 0);
2668 void SetLight(Display display, int id, Light light)
2670 #if defined(SHADERS)
2671 shader_setLight(display, id, light);
2672 #elif !defined(EM_MODE)
2673 //Logf("SetLight\n");
2677 Object lightObject = light.lightObject;
2678 float position[4] = { 0, 0, 0, 0 };
2679 float color[4] = { 0, 0, 0, 1 };
2681 glEnable(GL_LIGHT0 + id);
2683 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
2684 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
2685 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
2688 if(!light.multiplier) light.multiplier = 1.0f;
2690 color[0] = light.diffuse.r * light.multiplier;
2691 color[1] = light.diffuse.g * light.multiplier;
2692 color[2] = light.diffuse.b * light.multiplier;
2693 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2695 color[0] = light.ambient.r * light.multiplier;
2696 color[1] = light.ambient.g * light.multiplier;
2697 color[2] = light.ambient.b * light.multiplier;
2698 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2699 color[0] = light.specular.r * light.multiplier;
2700 color[1] = light.specular.g * light.multiplier;
2701 color[2] = light.specular.b * light.multiplier;
2702 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2706 Vector3D positionVector;
2707 if(light.flags.spot)
2709 if(lightObject.flags.root || !lightObject.parent)
2711 positionVector = lightObject.transform.position;
2712 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2716 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2717 if(display.display3D.camera)
2718 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2724 if(!light.direction.x && !light.direction.y && !light.direction.z)
2726 Vector3Df vector { 0,0,-1 };
2728 mat.RotationQuaternion(light.orientation);
2729 positionVector.MultMatrixf(vector, mat);
2733 positionVector = light.direction;
2738 position[0] = (float)positionVector.x;
2739 position[1] = (float)positionVector.y;
2740 position[2] = (float)positionVector.z;
2742 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2745 // Display Light Position
2746 glDisable(GL_LIGHTING);
2747 glDisable(GL_DEPTH_TEST);
2751 glVertex3fv(position);
2753 glEnable(GL_DEPTH_TEST);
2754 glEnable(GL_LIGHTING);
2758 if(lightObject.flags.root || !lightObject.parent)
2760 positionVector = light.target.transform.position;
2761 positionVector.Subtract(positionVector, display.camera.cPosition);
2765 positionVector.MultMatrix(light.target.transform.position,
2766 lightObject.light.target.parent.matrix);
2767 positionVector.Subtract(positionVector, display.camera.cPosition);
2770 position[0] = positionVector.x;
2771 position[1] = positionVector.y;
2772 position[2] = positionVector.z;
2774 glDisable(GL_LIGHTING);
2775 glDisable(GL_DEPTH_TEST);
2779 glVertex3fv(position);
2781 glEnable(GL_DEPTH_TEST);
2782 glEnable(GL_LIGHTING);
2785 if(light.flags.attenuation)
2787 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2788 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2789 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2792 if(light.flags.spot)
2795 #define MAXLIGHT 0.9
2796 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2797 // Figure out exponent out of the hot spot
2798 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2800 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2801 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2802 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2807 Vector3Df vector { 0,0,-1 };
2808 Vector3Df direction;
2811 mat.RotationQuaternion(light.orientation);
2812 direction.MultMatrix(vector, mat);
2814 position[0] = direction.x;
2815 position[1] = direction.y;
2816 position[2] = direction.z;
2818 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2822 glDisable(GL_LIGHT0 + id);
2826 void SetCamera(Display display, Surface surface, Camera camera)
2828 OGLDisplay oglDisplay = display.driverData;
2829 //Logf("SetCamera\n");
2831 if(surface && camera)
2833 int left = surface.box.left + surface.offset.x;
2834 int top = surface.box.top + surface.offset.y;
2835 int right = surface.box.right + surface.offset.x;
2836 int bottom = surface.box.bottom + surface.offset.y;
2837 float origX = surface.offset.x + camera.origin.x;
2838 float origY = surface.offset.y + camera.origin.y;
2840 int y = display.height - bottom - 1;
2841 int w = right - left + 1;
2842 int h = bottom - top + 1;
2845 glViewport(x, y, w, h);
2847 // *** Projection Matrix ***
2848 glMatrixMode(MatrixMode::projection);
2849 if(!display.display3D.camera)
2852 if(display.display3D.collectingHits)
2854 float pickX = display.display3D.pickX + surface.offset.x;
2855 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
2859 w / display.display3D.pickWidth, 0, 0, 0,
2860 0, h / display.display3D.pickHeight, 0, 0,
2862 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
2863 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
2866 glLoadMatrixd(pickMatrix.array);
2871 (left - origX) * camera.zMin / camera.focalX,
2872 (right - origX) * camera.zMin / camera.focalX,
2873 (bottom - origY) * camera.zMin / camera.focalY,
2874 (top - origY) * camera.zMin / camera.focalY,
2875 camera.zMin, camera.zMax);
2877 glDisable(GL_BLEND);
2879 // *** Z Inverted Identity Matrix ***
2880 glMatrixMode(MatrixMode::modelView);
2881 if(!display.display3D.camera)
2886 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
2888 // *** View Matrix ***
2889 glMultMatrixd(camera.viewMatrix.array);
2894 glEnable(GL_DEPTH_TEST);
2896 GLSetupLighting(true);
2897 #if !defined(EM_MODE) && !defined(SHADERS)
2898 glShadeModel(GL_SMOOTH);
2900 glDepthMask((byte)bool::true);
2901 oglDisplay.depthWrite = true;
2903 glEnable(GL_MULTISAMPLE_ARB);
2905 else if(surface && display.display3D.camera)
2907 oglDisplay.depthWrite = false;
2908 glViewport(0,0,display.width,display.height);
2910 glDisable(GL_CULL_FACE);
2911 glDisable(GL_DEPTH_TEST);
2913 GLSetupTexturing(false);
2914 GLSetupLighting(false);
2915 #if !defined(SHADERS) && !defined(EM_MODE)
2917 glShadeModel(GL_FLAT);
2920 glDisable(GL_MULTISAMPLE_ARB);
2922 // *** Restore 2D MODELVIEW Matrix ***
2925 // *** Restore 2D PROJECTION Matrix ***
2926 glMatrixMode(MatrixMode::projection);
2932 void ApplyMaterial(Display display, Material material, Mesh mesh)
2934 //Logf("ApplyMaterial\n");
2937 if(material.flags.doubleSided)
2939 #if !defined(EM_MODE) && !defined(SHADERS)
2940 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
2942 glDisable(GL_CULL_FACE);
2946 #if !defined(EM_MODE) && !defined(SHADERS)
2947 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
2949 glEnable(GL_CULL_FACE);
2952 #if !defined(SHADERS)
2954 if(material.flags.noFog)
2961 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
2963 Bitmap map = material.baseMap;
2964 GLSetupTexturing(true);
2965 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
2967 glMatrixMode(GL_TEXTURE);
2969 if(material.uScale && material.vScale)
2970 glScalef(material.uScale, material.vScale, 1);
2971 glMatrixMode(MatrixMode::modelView);
2973 if(material.flags.tile)
2975 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2976 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2980 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2981 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2985 GLSetupTexturing(false);
2987 #if defined(SHADERS)
2988 shader_setMaterial(material, mesh.flags.colors);
2989 #elif defined(EM_MODE)
2990 glimtkColor4f(material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity);
2992 if(mesh.flags.colors)
2994 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
2995 glEnable(GL_COLOR_MATERIAL);
2999 glDisable(GL_COLOR_MATERIAL);
3001 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3002 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3005 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3006 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3010 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3011 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3014 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3015 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3018 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3022 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3024 OGLMesh oglMesh = mesh.data;
3027 if(!mesh.flags.vertices)
3029 oglMesh.vertices.free();
3030 delete mesh.vertices;
3032 if(!mesh.flags.normals)
3034 oglMesh.normals.free();
3035 delete mesh.normals;
3037 if(!mesh.flags.texCoords1)
3039 oglMesh.texCoords.free();
3040 delete mesh.texCoords;
3042 if(!mesh.flags.texCoords2)
3044 oglMesh.texCoords2.free();
3045 // delete mesh.texCoords2;
3047 if(!mesh.flags.colors)
3049 oglMesh.colors.free();
3060 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3062 bool result = false;
3065 mesh.data = OGLMesh { };
3068 if(mesh.nVertices == nVertices)
3070 // Same number of vertices, adding features (Leaves the other features pointers alone)
3071 if(mesh.flags != flags)
3073 if(!mesh.flags.vertices && flags.vertices)
3075 if(flags.doubleVertices)
3077 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3080 mesh.vertices = new Vector3Df[nVertices];
3082 if(!mesh.flags.normals && flags.normals)
3084 if(flags.doubleNormals)
3086 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3089 mesh.normals = new Vector3Df[nVertices];
3091 if(!mesh.flags.texCoords1 && flags.texCoords1)
3093 mesh.texCoords = new Pointf[nVertices];
3095 if(!mesh.flags.colors && flags.colors)
3097 mesh.colors = new ColorRGBAf[nVertices];
3103 // New number of vertices, reallocate all current and new features
3104 flags |= mesh.flags;
3107 if(flags.doubleVertices)
3109 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3112 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3116 if(flags.doubleNormals)
3118 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3121 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3123 if(flags.texCoords1)
3125 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3129 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3137 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3139 OGLMesh oglMesh = mesh.data;
3140 if(!flags) flags = mesh.flags;
3145 oglMesh.vertices.upload(
3146 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3149 oglMesh.normals.upload(
3150 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3152 if(flags.texCoords1)
3153 oglMesh.texCoords.upload(
3154 mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3157 oglMesh.colors.upload(
3158 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3162 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3169 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3173 oglIndices.buffer.free();
3174 delete oglIndices.indices;
3179 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3181 OGLIndices oglIndices = OGLIndices { };
3184 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3185 oglIndices.nIndices = nIndices;
3190 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3197 if(!oglIndices.buffer.buffer)
3198 glGenBuffers(1, &oglIndices.buffer.buffer);
3199 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3200 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3201 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3205 oglIndices.buffer.upload(
3206 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3207 oglIndices.indices); //GL_STATIC_DRAW_ARB);
3211 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3214 return oglIndices.indices;
3217 void SelectMesh(Display display, Mesh mesh)
3219 //Logf("SelectMesh\n");
3221 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3223 #if defined(__WIN32__)
3224 if(glUnlockArraysEXT)
3226 if(!vboAvailable && display.display3D.mesh)
3227 glUnlockArraysEXT();
3232 OGLMesh oglMesh = mesh.data;
3234 // *** Vertex Stream ***
3235 glEnableClientState(GL_VERTEX_ARRAY);
3236 if(!display.display3D.collectingHits && oglMesh)
3238 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3240 // *** Normals Stream ***
3241 if(mesh.normals || mesh.flags.normals)
3243 glEnableClientState(GL_NORMAL_ARRAY);
3244 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3247 glDisableClientState(GL_NORMAL_ARRAY);
3249 // *** Texture Coordinates Stream ***
3250 if(mesh.texCoords || mesh.flags.texCoords1)
3252 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3253 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3256 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3258 // *** Color Stream ***
3259 if(mesh.colors || mesh.flags.colors)
3261 glEnableClientState(GL_COLOR_ARRAY);
3262 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3265 glDisableClientState(GL_COLOR_ARRAY);
3269 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3270 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3272 glEnableClientState(GL_NORMAL_ARRAY);
3273 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3276 glDisableClientState(GL_NORMAL_ARRAY);
3277 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3279 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3280 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3283 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3284 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3286 glEnableClientState(GL_COLOR_ARRAY);
3287 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3290 glDisableClientState(GL_COLOR_ARRAY);
3293 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3295 #if defined(__WIN32__)
3299 glLockArraysEXT(0, mesh.nVertices);
3305 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3307 //Logf("DrawPrimitives\n");
3309 if(primitive->type.vertexRange)
3310 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3313 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3314 // HACK TO SPEED THINGS UP...
3316 /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3317 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3320 glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
3323 OGLIndices oglIndices = primitive->data;
3324 MeshFeatures flags = mesh.flags;
3325 for(c = 0; c<primitive->nIndices; c++)
3327 uint16 index = ((uint16 *) oglIndices.indices)[c];
3328 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3329 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3330 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3331 glVertex3fv((float *)&mesh.vertices[index]);
3340 OGLIndices oglIndices = primitive->data;
3341 GLEAB eab = ((!display.display3D.collectingHits && oglIndices) ? oglIndices.buffer : noEAB);
3343 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3344 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3345 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3346 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3351 void PushMatrix(Display display)
3356 void PopMatrix(Display display, bool setMatrix)
3361 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3363 Matrix matrix = transMatrix;
3364 Camera camera = useCamera ? display.display3D.camera : null;
3369 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3374 matrix.m[3][0] - camera.cPosition.x,
3375 matrix.m[3][1] - camera.cPosition.y,
3376 matrix.m[3][2] - camera.cPosition.z);
3388 glMultMatrixd(matrix.array);
3393 public void UseSingleGLContext(bool useSingle)
3395 useSingleGLContext = useSingle;
3398 default dllexport void *
3399 #if defined(__WIN32__)
3400 __attribute__((stdcall))
3402 IS_GLGetContext(DisplaySystem displaySystem)
3406 #if defined(__WIN32__)
3407 OGLSystem system = displaySystem.driverData;
3409 #elif defined(__ANDROID__) || defined(__ODROID__)
3411 #elif defined(__EMSCRIPTEN__)
3413 OGLSystem system = displaySystem.driverData;
3414 return system.glContext;