3 namespace gfx::drivers;
5 #if !defined(_GLES) // OpenGL ES 1
9 #if defined(__ANDROID__)
10 #include <android/native_activity.h>
13 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
15 # include "gl_core_3_3.h"
17 # include "gl_compat_4_4.h"
21 #if defined(__ANDROID__) || defined(__ODROID__)
30 #define GL_BGRA_EXT 0x80E1
34 #undef glEnableClientState
35 #undef glDisableClientState
36 #undef GL_VERTEX_ARRAY
37 #undef GL_NORMAL_ARRAY
38 #undef GL_TEXTURE_COORD_ARRAY
41 #define glEnableClientState glEnableVertexAttribArray
42 #define glDisableClientState glDisableVertexAttribArray
43 #define GL_VERTEX_ARRAY GLBufferContents::vertex
44 #define GL_NORMAL_ARRAY GLBufferContents::normal
45 #define GL_TEXTURE_COORD_ARRAY GLBufferContents::texCoord
46 #define GL_COLOR_ARRAY GLBufferContents::color
50 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
52 #if defined(__unix__) || defined(__APPLE__)
54 #if !defined(__MINGW32__)
55 #define GL_GLEXT_PROTOTYPES
58 #define pointer _pointer
61 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
63 #define property _property
67 #define Window X11Window
68 #define Cursor X11Cursor
70 #define Display X11Display
72 #define KeyCode X11KeyCode
73 #define Picture X11Picture
74 #define Glyph X11Glyph
78 #include <X11/Xutil.h>
80 #include <X11/extensions/XShm.h>
83 #include <X11/extensions/Xrender.h>
84 #include <X11/extensions/shape.h>
103 #if defined(__APPLE__)
104 #include <OpenGl/gl.h>
107 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
109 #if defined(__WIN32__)
110 //#define WIN32_LEAN_AND_MEAN
112 #define _WIN32_WINNT 0x0502
113 #define String Sting_
118 #if defined(__ANDROID__) || defined(__ODROID__)
119 #if defined(__ODROID__) && !defined(_GLES)
124 #define property _property
127 #define Window X11Window
128 #define Cursor X11Cursor
130 #define Display X11Display
132 #define KeyCode X11KeyCode
133 #define Picture X11Picture
151 #elif defined(__EMSCRIPTEN__)
157 #define property _property
161 //#include <GLES/gl.h>
162 #include <GLES2/gl2.h>
164 #include <emscripten/emscripten.h>
165 #include <emscripten/html5.h>
178 #if defined(__unix__) || defined(__APPLE__)
180 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
186 #define glLoadMatrix glLoadMatrixd
187 #define glMultMatrix glMultMatrixd
188 #define glGetMatrix glGetDoublev
189 #define glTranslate glTranslated
190 #define glScale glScaled
193 #define glVertex3v glVertex3dv
194 #define glNormal3v glNormal3dv
198 //#ifdef VERTEX_FORMAT_DOUBLE
200 #define glLoadMatrix glLoadMatrixd
201 #define glMultMatrix glMultMatrixd
202 #define glGetMatrix glGetDoublev
203 #define glVertex3v glVertex3dv
204 #define glNormal3v glNormal3dv
205 #define glTranslate glTranslated
206 #define glScale glScaled
207 //#define GL_VERTEX_FORMAT GL_DOUBLE
211 #define glLoadMatrix glLoadMatrixf
212 #define glMultMatrix glMultMatrixf
213 #define glGetMatrix glGetFloatv
214 #define glVertex3v glVertex3fv
215 #define glNormal3v glNormal3fv
216 #define glTranslate glTranslatef
217 #define glScale glScalef
218 //#define GL_VERTEX_FORMAT GL_FLOAT
223 #define GL_ARRAY_BUFFER_ARB 0x8892
224 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
225 #define GL_STATIC_DRAW_ARB 0x88E4
226 #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
227 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
229 #define GL_MULTISAMPLE_ARB 0x809D
231 #if defined(__WIN32__)
234 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
235 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
237 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
238 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
240 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
241 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
242 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
243 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
244 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
245 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
246 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
247 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
248 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
249 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = null;
250 static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = null;
254 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
256 GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
257 GLAPI void APIENTRY glUnlockArraysEXT (void);
261 #if defined(__ANDROID__) || defined(__ODROID__)
262 #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
263 #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
264 #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
266 // TOFIX: Grab Screen and BlitDI/StretchDI will have wrong colors
268 #define GL_BGRA_EXT GL_RGBA
271 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
273 #define GL_POLYGON_STIPPLE 0xFFFF
274 #define GL_LINE_STIPPLE 0xFFFF
275 #define GL_LINE 0xFFFF
276 #define GL_FILL 0xFFFF
277 #define GL_ALL_ATTRIB_BITS 0xFFFF
278 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
284 #define GL_QUAD_STRIP 0
285 //#define GL_DOUBLE 0
286 //#define GL_UNSIGNED_INT 0
289 //#define GL_LINE_STIPPLE 0
290 #define GL_UNPACK_ROW_LENGTH 0
291 #define GL_UNPACK_SKIP_PIXELS 0
292 #define GL_UNPACK_SKIP_ROWS 0
294 #define GL_PACK_ROW_LENGTH 0
295 #define GL_PACK_SKIP_ROWS 0
296 #define GL_PACK_SKIP_PIXELS 0
302 #if defined(__ANDROID__) || defined(__ODROID__)
303 #define glBindFramebuffer glBindFramebufferOES
304 #define glBindRenderbuffer glBindRenderbufferOES
305 #define glFramebufferTexture2D glFramebufferTexture2DOES
306 #define glGenFramebuffers glGenFramebuffersOES
307 #define glGenRenderbuffers glGenRenderbuffersOES
308 #define glDeleteFramebuffers glDeleteFramebuffersOES
309 #define glDeleteRenderbuffers glDeleteRenderbuffersOES
312 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
313 #define GL_INT 0x1404
314 #define GL_UNSIGNED_INT 0x1405
315 #define GL_DOUBLE 0x140A
319 #if defined(_GLES) || defined(_GLES2) || defined(SHADERS)
350 #undef glLoadIdentity
355 #undef glColorMaterial
358 #define glRecti glimtkRecti
359 #define glBegin glimtkBegin
360 #define glTexCoord2i glimtkTexCoord2i
361 #define glVertex2i glimtkVertex2i
362 #define glTexCoord2d glimtkTexCoord2d
363 #define glVertex2d glimtkVertex2d
364 #define glTexCoord2f glimtkTexCoord2f
365 #define glVertex2f glimtkVertex2f
366 #define glEnd glimtkEnd
367 #define glColor3f glimtkColor3f
368 #define glColor4ub glimtkColor4ub
369 #define glColor4fv glimtkColor4fv
370 #define glNormal3fv glimtkNormal3fv
371 #define glNormal3f glimtkNormal3f
372 #define glTexCoord2fv glimtkTexCoord2fv
373 #define glVertex3d glimtkVertex3d
374 #define glVertex3dv glimtkVertex3dv
375 #define glVertex3f glimtkVertex3f
376 #define glVertex3fv glimtkVertex3fv
378 #define glLoadMatrixd glmsLoadMatrixd
379 #define glMultMatrixd glmsMultMatrixd
380 #define glFrustum glmsFrustum
381 #define glOrtho glmsOrtho
382 #define glScaled glmsScaled
383 #define glScalef glmsScaled
384 #define glTranslated glmsTranslated
385 #define glRotated glmsRotated
386 #define glMatrixMode glmsMatrixMode
387 #define glLoadIdentity glmsLoadIdentity
388 #define glPushMatrix glmsPushMatrix
389 #define glPopMatrix glmsPopMatrix
391 #define glLineStipple glesLineStipple
392 #define glColorMaterial glesColorMaterial
393 #define glLightModeli glesLightModeli
397 public void glesColorMaterial(int a, int b)
399 PrintLn("glColorMaterial stub");
402 static GLuint stippleTexture;
403 #if defined(_GLES) || defined(_GLES2) || defined(SHADERS)
404 static bool stippleEnabled;
407 public void glesLineStipple( int i, unsigned short j )
411 for(x = 0; x < 16; x++)
413 bool v = (j & (1 << x)) != 0;
414 texture[x] = v ? 0xFFFFFFFF : 0;
417 glGenTextures(1, &stippleTexture);
418 glBindTexture(GL_TEXTURE_2D, stippleTexture);
419 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
421 // TOOD: Special shading code for stippling?
422 GLSetupTexturing(true);
423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
424 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
425 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
426 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
427 glMatrixMode(GL_TEXTURE);
429 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
430 glScaled(i/16.0, 1, 1.0f);
431 glTranslated(0.5, 0.5, 0);
432 glMatrixMode(MatrixMode::projection);
435 public void glesLightModeli( unsigned int pname, int param )
437 #if !defined(SHADERS)
438 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
439 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
443 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
444 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
447 #if defined(__ANDROID__) || defined(__ODROID__)
448 void glFogi( unsigned int pname, int param ) { }
449 void glPolygonMode( unsigned int i, unsigned int j ) { }
452 // *** Picking won't be supported for now ***
453 void glPushName( unsigned int i ) { }
454 void glLoadName( unsigned int i ) { }
457 // Probably replace by regular glBlendFunc ...
458 void glBlendFuncSeparate(int a, int b, int c, int d)
463 // For direct pixel blitting...
464 void glRasterPos2d(double a, double b) { }
465 void glPixelZoom(float a, float b) { }
466 void glDrawPixels(int a, int b, int c, int d, void * e) { }
470 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
471 static int primitiveTypes[RenderPrimitiveType] =
473 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN,
474 #if defined(SHADERS) || defined(_GLES) || defined(_GLES2)
475 GL_TRIANGLE_FAN, // NOTE: This will only work for single quads
479 GLIMTKMode::quadStrip,
484 public void GLSetupTexturing(bool enable)
487 shader_texturing(enable);
489 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
493 public void GLSetupFog(bool enable)
498 (enable ? glEnable : glDisable)(GL_FOG);
502 bool lightingEnabled;
504 public void GLSetupLighting(bool enable)
506 lightingEnabled = enable;
508 shader_lighting(enable);
510 (enable ? glEnable : glDisable)(GL_LIGHTING);
514 // Non OpenGL ES friendly stuff
516 #if defined(_GLES) || defined(_GLES2)
518 //#undef GL_UNSIGNED_INT
524 #undef GL_POLYGON_STIPPLE
525 #undef GL_LINE_STIPPLE
528 #undef GL_ALL_ATTRIB_BITS
529 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
533 static int displayWidth, displayHeight;
535 #define GL_CLAMP_TO_EDGE 0x812F
537 /*static */bool vboAvailable;
539 static bool useSingleGLContext = false;
540 class OGLDisplay : struct
542 #if defined(__WIN32__)
553 byte * pboMemory1, * pboMemory2;
555 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
556 GLXContext glContext;
559 XShmSegmentInfo shminfo;
561 XShmSegmentInfo shminfoShape;
566 X11Picture windowPicture;
567 X11Picture pixmapPicture;
569 X11Picture shapePicture;
572 ColorAlpha * flippingBuffer;
573 int flipBufH, flipBufW;
578 #if defined(_DEBUG) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
579 // #define GL_DEBUGGING
583 static void APIENTRY openglCallbackFunction(GLenum source,
588 const GLchar* message,
589 const void* userParam)
591 if(severity == GL_DEBUG_SEVERITY_NOTIFICATION)
593 PrintLn("---------------------opengl-callback-start------------");
594 PrintLn("message: ", message);
598 case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
599 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
600 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
601 case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
602 case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
603 case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
610 case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
611 case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
612 case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
613 default: PrintLn("(other)");
615 PrintLn("---------------------opengl-callback-end--------------");
619 class OGLSystem : struct
624 #if defined(__WIN32__)
625 PIXELFORMATDESCRIPTOR pfd;
630 #elif defined(__EMSCRIPTEN__)
631 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
632 #elif !defined(__ANDROID__) && !defined(__ODROID__)
633 XVisualInfo * visualInfo;
634 GLXContext glContext;
635 GLXDrawable glxDrawable;
639 class OGLSurface : struct
647 float foreground[4], background[4], bitmapMult[4];
650 class OGLMesh : struct
659 class OGLIndices : struct
670 static void setupDebugging()
672 if(glDebugMessageCallback)
674 GLuint unusedIds = 0;
676 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
678 glDebugMessageCallback(openglCallbackFunction, null);
679 glDebugMessageControl(GL_DONT_CARE,
689 #if defined(__WIN32__)
690 static HGLRC winCreateContext(HDC hdc)
694 if(wglCreateContextAttribsARB)
698 WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
699 WGL_CONTEXT_MINOR_VERSION_ARB, 4,
700 WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | */WGL_CONTEXT_DEBUG_BIT_ARB,
701 WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB /*WGL_CONTEXT_CORE_PROFILE_BIT_ARB*/,
704 result = wglCreateContextAttribsARB(hdc, null, attribs);
710 result = wglCreateContextAttribsARB(hdc, null, attribs);
715 result = wglCreateContext(hdc);
720 class OpenGLDisplayDriver : DisplayDriver
722 class_property(name) = "OpenGL";
724 bool LockSystem(DisplaySystem displaySystem)
726 #if defined(__EMSCRIPTEN__)
727 OGLSystem oglSystem = displaySystem.driverData;
728 emscripten_webgl_make_context_current(oglSystem.glc);
729 #elif !defined(__ANDROID__) && !defined(__ODROID__)
730 OGLSystem oglSystem = displaySystem.driverData;
731 if(useSingleGLContext) return true;
732 #if defined(__WIN32__)
733 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
734 #elif defined(__unix__) || defined(__APPLE__)
735 //if(previous) return true;
736 // printf("Making SYSTEM current\n");
737 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
738 //previous = oglSystem.glContext;
741 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
742 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
746 void UnlockSystem(DisplaySystem displaySystem)
748 if(useSingleGLContext) return;
749 #if defined(__WIN32__)
750 wglMakeCurrent(null, null);
751 #elif defined(__unix__) || defined(__APPLE__)
752 // printf("Making NULL current\n");
753 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
755 glXMakeCurrent(xGlobalDisplay, None, null);
761 bool Lock(Display display)
763 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
764 OGLDisplay oglDisplay = display.driverData;
765 if(useSingleGLContext) return true;
766 #if defined(__WIN32__)
767 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
768 #elif defined(__unix__) || defined(__APPLE__)
769 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
770 // printf(" Making DISPLAY current\n");
771 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
774 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
775 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
779 void Unlock(Display display)
781 if(useSingleGLContext) return;
782 //printf(" Making NULL current\n");
783 //glXMakeCurrent(xGlobalDisplay, None, null);
785 LockSystem(display.displaySystem);
788 void DestroyDisplay(Display display)
790 OGLDisplay oglDisplay = display.driverData;
794 #if defined(__WIN32__)
795 wglMakeCurrent( null, null );
798 wglDeleteContext(oglDisplay.glrc);
800 if(oglDisplay.hdc && oglDisplay.pBuffer)
801 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
803 if(oglDisplay.pBuffer)
804 wglDestroyPbufferARB(oglDisplay.pBuffer);
807 ReleaseDC(display.window, oglDisplay.hdc);
809 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
810 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
812 #elif defined(__unix__) || defined(__APPLE__)
813 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
815 if(oglDisplay.shapePixmap)
816 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
817 if(oglDisplay.pixmap)
818 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
821 if(oglDisplay.shminfoShape.shmid != -1)
823 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
824 if(oglDisplay.shminfo.shmaddr != (void *)-1)
825 shmdt(oglDisplay.shminfo.shmaddr);
826 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
829 if(oglDisplay.shapeImage)
831 if(oglDisplay.shminfoShape.shmid != -1)
833 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
834 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
835 shmdt(oglDisplay.shminfoShape.shmaddr);
836 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
838 XDestroyImage(oglDisplay.shapeImage);
839 oglDisplay.shapeImage = None;
842 glXMakeCurrent(xGlobalDisplay, None, null);
844 if(oglDisplay.glContext)
845 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
848 delete oglDisplay.flippingBuffer;
850 display.driverData = null;
854 void ::CheckExtensions(OGLSystem oglSystem)
856 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
858 printf("extensions: %s\n", extensions);
861 oglSystem.pow2textures = (extensions && strstr(extensions, "GL_ARB_texture_non_power_of_two")) ? false : true;
862 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
864 PrintLn("max texture size: ", oglSystem.maxTextureSize);
868 bool CreateDisplaySystem(DisplaySystem displaySystem)
871 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
874 PrintLn("OpenGL driver's CreateDisplaySystem()");
878 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
880 oglSystem.hdc = GetDC(oglSystem.hwnd);
884 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
885 oglSystem.pfd.nVersion = 1;
886 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
887 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
888 oglSystem.pfd.cColorBits = 24;
889 oglSystem.pfd.cAlphaBits = 8;
890 oglSystem.pfd.cDepthBits = 24;
891 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
893 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
894 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
896 if(oglSystem.pfd.cColorBits > 8)
898 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
899 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
902 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
904 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
905 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
906 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
907 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
908 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
909 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
910 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
911 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
912 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
913 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
914 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
916 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
917 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
919 // eSystem_LoggingMode(LOG_MSGBOX, null);
921 if(wglChoosePixelFormatARB)
926 float fAttributes[] = {0,0};
929 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
930 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
931 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
932 WGL_COLOR_BITS_ARB,24,
933 WGL_ALPHA_BITS_ARB,8,
934 WGL_DEPTH_BITS_ARB,16,
935 WGL_STENCIL_BITS_ARB,0,
936 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
937 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
938 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
942 //Log("Found wglChoosePixelFormatARB\n");
944 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
945 if(!valid || !numFormats)
947 //Log("Can't find 4x multi sampling\n");
949 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
950 if(!valid || !numFormats)
952 // Log("Can't find 2x multi sampling\n");
955 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
958 if(valid && numFormats)
960 oglSystem.format = pixelFormat;
961 wglMakeCurrent(null, null);
962 wglDeleteContext(oglSystem.glrc);
964 // *** DescribePixelFormat does not support WGL pixel formats! ***
965 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
966 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
967 //Log("Successfully set pixel format\n");
970 PrintLn("winCreateContext()");
972 oglSystem.glrc = winCreateContext(oglSystem.hdc);
974 PrintLn("wglMakeCurrent()");
976 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
980 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
984 wglMakeCurrent(null, null);
986 //eSystem_DumpErrors(true);
990 #elif defined(__unix__) || defined(__APPLE__)
992 #if defined(__ANDROID__) || defined(__ODROID__)
993 #if defined(__ANDROID__)
994 egl_init_display(guiApp.desktop.windowHandle);
995 #elif defined(__ODROID__)
996 egl_init_display((uint)displaySystem.window);
998 CheckExtensions(oglSystem);
1000 // TODO: Clean this up? Needed here?
1001 glEnableClientState(GL_VERTEX_ARRAY);
1003 // Initialize GL state.
1004 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1005 glEnable(GL_CULL_FACE);
1006 glShadeModel(GL_SMOOTH);
1007 glDisable(GL_DEPTH_TEST);
1009 glDisable(GL_CULL_FACE);
1010 glDisable(GL_DEPTH_TEST);
1012 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1015 matrixStack[0][0].Identity();
1016 matrixStack[1][0].Identity();
1017 matrixStack[2][0].Identity();
1019 glmsMatrixMode(GL_MODELVIEW);
1020 glScaled(1.0, 1.0, -1.0);
1021 glmsMatrixMode(GL_PROJECTION);
1022 glShadeModel(GL_FLAT);
1024 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1025 glFogi(GL_FOG_MODE, GL_EXP);
1026 glFogf(GL_FOG_DENSITY, 0);
1027 glEnable(GL_NORMALIZE);
1028 glDepthFunc(GL_LESS);
1030 glDisable(GL_MULTISAMPLE_ARB);
1032 glViewport(0,0,eglWidth,eglHeight);
1034 glOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
1036 glabCurArrayBuffer = 0;
1037 glabCurElementBuffer = 0;
1040 #elif defined(__EMSCRIPTEN__)
1042 EmscriptenWebGLContextAttributes attribs = { 0 };
1044 attribs.antialias = 1;
1051 EM_BOOL premultipliedAlpha;
1052 EM_BOOL preserveDrawingBuffer;
1053 EM_BOOL preferLowPowerToHighPerformance;
1054 EM_BOOL failIfMajorPerformanceCaveat;
1057 EM_BOOL enableExtensionsByDefault;
1060 emscripten_webgl_init_context_attributes(&attribs);
1061 oglSystem.pow2textures = true;
1062 oglSystem.maxTextureSize = 16384;
1063 oglSystem.glc = emscripten_webgl_create_context("canvas", &attribs);
1064 if(emscripten_webgl_make_context_current(oglSystem.glc) == EMSCRIPTEN_RESULT_SUCCESS)
1067 /*glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1068 glEnable(GL_BLEND);*/
1072 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1073 XSetWindowAttributes attr;
1078 #ifndef ECERE_MINIGLX
1079 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1082 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1086 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
1087 attr.background_pixel = 0;
1088 attr.border_pixel = 0;
1089 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1090 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1091 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1093 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1094 oglSystem.visualInfo->visual, mask, &attr );
1096 if(oglSystem.visualInfo)
1098 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1099 if(oglSystem.glContext)
1101 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1103 // CheckExtensions(oglSystem);
1104 glXMakeCurrent(xGlobalDisplay, None, null);
1111 displaySystem.flags.alpha = true;
1112 displaySystem.flags.flipping = true;
1113 displaySystem.pixelFormat = pixelFormat888;
1117 void DestroyDisplaySystem(DisplaySystem displaySystem)
1119 OGLSystem oglSystem = displaySystem.driverData;
1122 glDeleteTextures(1, &stippleTexture);
1128 #if defined(__WIN32__)
1129 wglMakeCurrent( null, null );
1132 wglDeleteContext(oglSystem.glrc);
1135 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1136 DestroyWindow(oglSystem.hwnd);
1138 #elif defined(__unix__) || defined(__APPLE__)
1139 #if defined(__ANDROID__) || defined(__ODROID__)
1141 #elif defined(__EMSCRIPTEN__)
1142 emscripten_webgl_destroy_context(oglSystem.glc);
1144 if(oglSystem.visualInfo)
1146 #ifdef ECERE_MINIGLX
1147 __miniglx_XFree(oglSystem.visualInfo);
1149 XFree(oglSystem.visualInfo);
1153 if(oglSystem.glxDrawable)
1155 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1156 oglSystem.glxDrawable = 0;
1163 static bool ::initialDisplaySetup(Display display)
1167 loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1169 glEnableClientState(GL_VERTEX_ARRAY);
1171 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1172 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1174 #if defined(__WIN32__)
1175 if(glBlendFuncSeparate)
1176 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1178 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1180 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1184 glMatrixMode(MatrixMode::modelView);
1185 glLoadIdentity(); // For setting up GLES stack
1186 glScaled(1.0, 1.0, -1.0);
1187 // glTranslatef(0.375f, 0.375f, 0.0f);
1188 // glTranslatef(-0.625f, -0.625f, 0.0f);
1189 glMatrixMode(MatrixMode::projection);
1190 #if !defined(EM_MODE) && !defined(SHADERS)
1191 glShadeModel(GL_FLAT);
1193 // #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1195 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1197 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1198 glFogi(GL_FOG_MODE, GL_EXP);
1199 glFogf(GL_FOG_DENSITY, 0);
1200 glEnable(GL_NORMALIZE);
1202 glDepthFunc(GL_LESS);
1204 glDisable(GL_MULTISAMPLE_ARB);
1205 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1206 display.ambient = Color { 50,50,50 };
1211 bool CreateDisplay(Display display)
1213 bool result = false;
1214 OGLDisplay oglDisplay = display.driverData;
1215 #if !defined(__ANDROID__) && !defined(__ODROID__)
1216 OGLSystem oglSystem = display.displaySystem.driverData;
1220 oglDisplay = display.driverData = OGLDisplay { };
1221 //printf("Inside CreateDisplay\n");
1223 #if defined(__WIN32__) || defined(USEPBUFFER)
1224 if(!display.alphaBlend)
1227 #if defined(__WIN32__)
1228 oglDisplay.hdc = GetDC(display.window);
1229 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1230 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1232 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1233 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1237 ReleaseDC(display.window, oglDisplay.hdc);
1238 #elif defined(__unix__) || defined(__APPLE__)
1239 # if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1242 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1244 #if defined(__APPLE__)
1245 XVisualInfo template = { 0 };
1246 XWindowAttributes winAttr;
1248 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1249 template.visualid = XVisualIDFromVisual(winAttr.visual);
1250 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1252 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1253 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1254 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1255 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1257 // visualInfo = oglSystem.visualInfo;
1262 //printf("visualInfo is not null\n");
1263 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1264 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1265 //XFree(visualInfo);
1268 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1269 if(oglDisplay.glContext)
1271 //printf("CreateDisplay Got a Context\n");
1272 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1278 #if defined(__WIN32__) || defined(USEPBUFFER)
1282 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1287 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1290 PrintLn("Calling ogl_LoadFunctions() in CreateDisplay()");
1292 if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
1293 PrintLn("ogl_LoadFunctions() failed!");
1296 PrintLn("CheckExtensions()");
1298 CheckExtensions(oglSystem);
1299 vboAvailable = glBindBuffer != null;
1302 PrintLn("vboAvailable is: ", vboAvailable);
1305 # ifdef GL_DEBUGGING
1311 #if defined(__EMSCRIPTEN__)
1312 emscripten_webgl_make_context_current(oglSystem.glc);
1315 initialDisplaySetup(display);
1318 if(!useSingleGLContext)
1320 #if defined(__WIN32__)
1321 wglMakeCurrent(null, null);
1322 #elif defined(__unix__) || defined(__APPLE__)
1323 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1326 glXMakeCurrent(xGlobalDisplay, None, null);
1332 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1340 bool DisplaySize(Display display, int width, int height)
1342 OGLDisplay oglDisplay = display.driverData;
1344 bool result = false;
1346 //printf("Inside DisplaySize\n");
1347 #if defined(__WIN32__) || defined(USEPBUFFER)
1348 OGLSystem oglSystem = display.displaySystem.driverData;
1349 if(display.alphaBlend)
1351 #if defined(__WIN32__)
1352 const int attributes[]=
1354 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1355 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1357 int pixelFormat = 0;
1358 if(wglChoosePixelFormatARB)
1362 float fAttributes[] = {0,0};
1365 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1366 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1367 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1368 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1369 WGL_COLOR_BITS_ARB,24,
1370 WGL_ALPHA_BITS_ARB,8,
1371 WGL_DEPTH_BITS_ARB,16,
1372 WGL_STENCIL_BITS_ARB,0,
1373 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1374 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1375 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1379 //Log("Found wglChoosePixelFormatARB\n");
1381 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1382 if(!valid || !numFormats)
1384 //Log("Can't find 4x multi sampling\n");
1385 iAttributes[19] = 2;
1386 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1387 if(!valid || !numFormats)
1389 // Log("Can't find 2x multi sampling\n");
1390 iAttributes[16] = 0;
1391 iAttributes[17] = 0;
1392 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1393 if(!valid || !numFormats)
1397 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1398 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1399 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1400 WGL_COLOR_BITS_ARB,24,
1401 WGL_ALPHA_BITS_ARB,8,
1402 WGL_DEPTH_BITS_ARB,16,
1405 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1409 if(valid && numFormats)
1411 wglMakeCurrent(null, null);
1415 wglMakeCurrent( null, null );
1416 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1417 if(oglDisplay.hdc && oglDisplay.pBuffer)
1418 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1420 wglDestroyPbufferARB(oglDisplay.pBuffer);
1422 if(!useSingleGLContext)
1423 wglMakeCurrent( null, null );
1426 wglDeleteContext(oglDisplay.glrc);
1428 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1429 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1430 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1433 HDC hdc = GetDC(display.window);
1435 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1436 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1438 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1439 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1441 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1443 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1447 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1448 oglDisplay.memDC = CreateCompatibleDC(hdc);
1449 SetMapMode(oglDisplay.memDC, MM_TEXT);
1450 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1451 info->bmiHeader.biPlanes = 1;
1452 info->bmiHeader.biCompression = BI_RGB;
1453 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1454 info->bmiHeader.biWidth = width;
1455 info->bmiHeader.biHeight = height;
1456 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1459 SelectObject(oglDisplay.memDC, newBitmap);
1460 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1463 PIXELFORMATDESCRIPTOR pfd = { 0 };
1464 pfd.nSize = (short)sizeof(pfd);
1466 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1467 pfd.iPixelType = PFD_TYPE_RGBA;
1468 pfd.cColorBits = 32;
1469 //pfd.cAlphaBits = 8;
1470 pfd.cDepthBits = 24;
1471 pfd.iLayerType = PFD_MAIN_PLANE;
1473 oglDisplay.hdc = oglDisplay.memDC;
1475 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1476 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1477 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1479 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1480 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1481 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1486 const int imageSize = width * height * 4;
1488 glGenBuffersARB(2, oglDisplay.imageBuffers);
1490 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1491 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1492 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1493 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1496 oglDisplay.memBitmap = newBitmap;
1497 oglDisplay.stride = width;
1503 ReleaseDC(display.window, hdc);
1505 #elif defined(__unix__) || defined(__APPLE__)
1506 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1511 GLX_DOUBLEBUFFER, True,
1517 GLX_STENCIL_SIZE, 1,
1518 //GLX_DEPTH_SIZE, 24,
1519 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1520 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1526 GLX_PBUFFER_WIDTH, width,
1527 GLX_PBUFFER_HEIGHT, height,
1528 GLX_LARGEST_PBUFFER, False,
1532 // choose a pixel format that meets our minimum requirements
1535 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1538 if(oglDisplay.pixmap)
1540 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1541 oglDisplay.pixmap = None;
1543 if(oglDisplay.shapePixmap)
1545 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1546 oglDisplay.shapePixmap = None;
1549 // Free Shared Memory Pixmap
1550 if(oglDisplay.image)
1552 if(oglDisplay.shminfoShape.shmid != -1)
1554 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1555 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1556 shmdt(oglDisplay.shminfo.shmaddr);
1557 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1559 XDestroyImage(oglDisplay.image);
1560 oglDisplay.image = None;
1562 if(oglDisplay.shapeImage)
1564 if(oglDisplay.shminfoShape.shmid != -1)
1566 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1567 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1568 shmdt(oglDisplay.shminfoShape.shmaddr);
1569 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1571 XDestroyImage(oglDisplay.shapeImage);
1572 oglDisplay.shapeImage = None;
1575 if(oglDisplay.windowPicture)
1576 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1577 if(oglDisplay.pixmapPicture)
1578 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1580 if(oglDisplay.pixmap)
1581 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1583 if(oglDisplay.glContext)
1584 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1585 if(oglDisplay.pBuffer)
1586 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1588 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1589 if(oglDisplay.pBuffer)
1591 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1592 if(oglDisplay.glContext)
1594 glXMakeCurrent(xGlobalDisplay, None, null);
1595 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1597 // Initialize Shared Memory Pixmap
1598 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1599 ZPixmap, null, &oglDisplay.shminfo, width, height);
1600 if(oglDisplay.image)
1602 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1603 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1604 if(oglDisplay.shminfo.shmid != -1)
1606 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1607 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1609 oglDisplay.shminfo.readOnly = False;
1610 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1612 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1613 &oglDisplay.shminfo, width, height, 32);
1615 // Initialize Shared Memory Shape Pixmap
1616 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1617 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1618 if(oglDisplay.shapeImage)
1620 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1621 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1622 if(oglDisplay.shminfoShape.shmid != -1)
1624 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1625 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1627 oglDisplay.shminfoShape.readOnly = False;
1628 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1630 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1631 &oglDisplay.shminfoShape, width, height, 1);
1632 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1635 XRenderPictureAttributes attributes = { 0 };
1636 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1637 #if !defined(__APPLE__)
1638 attributes.repeat = RepeatNormal;
1640 attributes.repeat = 1;
1642 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1643 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1644 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1645 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1648 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1649 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1666 CreateDisplay(display);
1667 #if defined(__WIN32__)
1668 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1669 #elif defined(__unix__) || defined(__APPLE__)
1670 #if defined(__ANDROID__) || defined(__ODROID__)
1673 #elif defined(__EMSCRIPTEN__)
1674 emscripten_webgl_make_context_current(oglSystem.glc);
1676 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1684 if(display.alphaBlend && result)
1685 initialDisplaySetup(display);
1687 if(!result && display.alphaBlend)
1689 printf("Alpha blending windows not supported on this display\n");
1696 glViewport(0,0,width,height);
1697 glMatrixMode(MatrixMode::projection);
1699 glOrtho(0,width,height,0,0.0,1.0);
1700 displayWidth = display.width = width;
1701 displayHeight = display.height = height;
1703 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1705 oglDisplay.flipBufW = width;
1706 oglDisplay.flipBufH = height;
1707 #if defined(_GLES) || defined(_GLES2)
1710 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1713 if(oglDisplay.flippingBuffer || !width || !height)
1719 void DisplayPosition(Display display, int x, int y)
1721 OGLDisplay oglDisplay = display.driverData;
1727 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1731 void RestorePalette(Display display)
1735 void StartUpdate(Display display)
1739 void EndUpdate(Display display)
1743 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1747 void Update(Display display, Box updateBox)
1749 #if defined(__WIN32__) || defined(USEPBUFFER)
1750 OGLDisplay oglDisplay = display.driverData;
1752 //Logf("DisplayScreen\n");
1754 #if !defined(__ANDROID__)
1759 #if defined(__WIN32__) || defined(USEPBUFFER)
1760 if(display.alphaBlend)
1762 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1763 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1764 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1765 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1766 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1769 #if defined(__WIN32__)
1771 POINT point = { oglDisplay.x, oglDisplay.y};
1772 POINT srcPoint = { 0, 0 };
1773 BLENDFUNCTION blend = { 0 };
1775 size.cx = display.width;
1776 size.cy = display.height;
1777 blend.BlendOp = AC_SRC_OVER;
1778 blend.BlendFlags = 0;
1779 blend.SourceConstantAlpha = 255;
1780 blend.AlphaFormat = AC_SRC_ALPHA;
1783 // Process partial images. Mapping the buffer waits for
1784 // outstanding DMA transfers into the buffer to finish.
1785 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1786 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1788 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1789 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1792 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1793 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1796 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1799 // Unmap the image buffers
1800 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1801 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1803 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1804 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1806 // Bind two different buffer objects and start the glReadPixels
1807 // asynchronously. Each call will return directly after
1808 // starting the DMA transfer.
1809 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1810 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1812 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1813 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1817 #elif defined(__unix__) || defined(__APPLE__)
1818 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1820 XTransform transform =
1823 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1824 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1825 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1828 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1829 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1830 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1831 #if !defined(__APPLE__)
1832 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1834 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1836 XFlush(xGlobalDisplay);
1844 #if defined(__WIN32__)
1845 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1846 SwapBuffers(oglDisplay.hdc);
1847 //ecere::sys::Sleep(0.1);
1848 #elif defined(__unix__) || defined(__APPLE__)
1849 #if defined(__ANDROID__) || defined(__ODROID__)
1851 #elif defined(__EMSCRIPTEN__)
1853 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1857 //Logf("Out of DisplayScreen\n");
1860 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1862 if(bitmap.driverData)
1864 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1865 glDeleteTextures(1, &tex);
1866 bitmap.driverData = 0;
1868 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1871 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1873 OGLSystem oglSystem = displaySystem.driverData;
1874 bool result = false;
1876 GLuint glBitmap = 0;
1878 uint w = width, h = height;
1879 if(oglSystem.pow2textures)
1884 w = Min(w, oglSystem.maxTextureSize);
1885 h = Min(h, oglSystem.maxTextureSize);
1887 glGenTextures(1, &glBitmap);
1888 glBindTexture(GL_TEXTURE_2D, glBitmap);
1890 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1892 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1893 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1895 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1896 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1898 #if !defined(SHADERS)
1899 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1902 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1904 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1905 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1909 bitmap.driverData = (void *)(uintptr)glBitmap;
1910 bitmap.driver = displaySystem.driver;
1918 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1920 bool result = false;
1921 OGLSystem oglSystem = displaySystem.driverData;
1922 Bitmap convBitmap = bitmap;
1926 convBitmap.Copy(bitmap);
1929 // Pre process the bitmap... First make it 32 bit
1930 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1933 uint w = bitmap.width, h = bitmap.height;
1934 GLuint glBitmap = 0;
1935 if(oglSystem.pow2textures)
1940 w = Min(w, oglSystem.maxTextureSize);
1941 h = Min(h, oglSystem.maxTextureSize);
1945 while(w * 2 < h) w *= 2;
1946 while(h * 2 < w) h *= 2;
1949 // Switch ARGB to RGBA
1950 //if(bitmap.format != pixelFormatRGBA)
1952 for(c=0; c<bitmap.size; c++)
1954 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1956 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1957 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1960 // convBitmap.pixelFormat = pixelFormat888;
1963 glGenTextures(1, &glBitmap);
1966 //int error = glGetError();
1970 glBindTexture(GL_TEXTURE_2D, glBitmap);
1971 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1973 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1974 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1976 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1978 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1979 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1981 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1982 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1983 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1984 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1987 #if !defined(SHADERS)
1988 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1993 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1998 if(bitmap.width != w || bitmap.height != h)
2000 mipMap = Bitmap { };
2001 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
2003 Surface mipSurface = mipMap.GetSurface(0,0,null);
2004 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
2014 mipMap = convBitmap;
2021 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2022 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2023 //printf("Calling glTexImage2D\n");
2024 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2025 //printf("width = %d (Should be %d, %d)\n", width, w, h);
2026 if((error = glGetError()))
2028 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2029 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2033 if(mipMap != convBitmap)
2038 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2039 bitmap.driverData = (void *)(uintptr)glBitmap;
2040 bitmap.driver = displaySystem.driver;
2045 FreeBitmap(displaySystem, bitmap);
2046 else if(oglSystem.loadingFont)
2048 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2049 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2050 oglSystem.loadingFont = false;
2056 void ReleaseSurface(Display display, Surface surface)
2058 glDisable(GL_SCISSOR_TEST);
2059 delete surface.driverData;
2060 surface.driverData = null;
2063 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2068 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2070 bool result = false;
2071 OGLSurface oglSurface = surface.driverData = OGLSurface { };
2073 //Logf("GetSurface\n");
2077 if(displayWidth != display.width || displayHeight != display.height)
2079 displayWidth = display.width;
2080 displayHeight = display.height;
2082 glViewport(0,0,display.width,display.height);
2084 glOrtho(0,display.width,display.height,0,0.0,1.0);
2087 surface.offset.x = x;
2088 surface.offset.y = y;
2089 surface.unclippedBox = surface.box = clip;
2090 oglSurface.bitmapMult[0] = 1;
2091 oglSurface.bitmapMult[1] = 1;
2092 oglSurface.bitmapMult[2] = 1;
2093 oglSurface.bitmapMult[3] = 1;
2095 glEnable(GL_SCISSOR_TEST);
2098 (display.height) -(y+clip.bottom)-1,
2099 clip.right-clip.left+1,
2100 clip.bottom-clip.top+1);
2106 void Clip(Display display, Surface surface, Box clip)
2115 box.Clip(surface.unclippedBox);
2119 box = surface.box = surface.unclippedBox;
2120 box.left += surface.offset.x;
2121 box.top += surface.offset.y;
2122 box.right+= surface.offset.x;
2123 box.bottom += surface.offset.y;
2126 box.left,display.height - box.bottom - 1,
2127 box.right-box.left+1, box.bottom-box.top+1);
2130 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2132 bool result = false;
2133 OGLDisplay oglDisplay = display.driverData;
2134 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2136 if(oglDisplay.flippingBuffer)
2138 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2141 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2147 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2148 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2149 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2150 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2151 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2154 for(row = 0; row<h; row++)
2155 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2162 void SetForeground(Display display, Surface surface, ColorAlpha color)
2164 OGLSurface oglSurface = surface.driverData;
2166 //Logf("SetForeground\n");
2168 oglSurface.foreground[0] = color.color.r/255.0f;
2169 oglSurface.foreground[1] = color.color.g/255.0f;
2170 oglSurface.foreground[2] = color.color.b/255.0f;
2171 //oglSurface.foreground[3] = 1.0f;
2172 oglSurface.foreground[3] = color.a/255.0f;
2174 //if(!oglSurface.foreground[3])printf("bug");
2177 void SetBackground(Display display, Surface surface, ColorAlpha color)
2179 OGLSurface oglSurface = surface.driverData;
2181 //Logf("SetBackground\n");
2183 oglSurface.background[0] = color.color.r/255.0f;
2184 oglSurface.background[1] = color.color.g/255.0f;
2185 oglSurface.background[2] = color.color.b/255.0f;
2186 //oglSurface.background[3] = 1.0;
2187 oglSurface.background[3] = color.a/255.0f;
2190 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2192 OGLSurface oglSurface = surface.driverData;
2194 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2195 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2196 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2197 oglSurface.bitmapMult[3] = color.a/255.0f;
2200 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2205 void PutPixel(Display display, Surface surface,int x,int y)
2207 OGLSurface oglSurface = surface.driverData;
2209 //Logf("PutPixel\n");
2211 glColor4fv(oglSurface.foreground);
2213 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2214 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2219 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2221 OGLSurface oglSurface = surface.driverData;
2222 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2237 x1 += surface.offset.x;
2238 y1 += surface.offset.y;
2239 x2 += surface.offset.x;
2240 y2 += surface.offset.y;
2244 glColor4fv(oglSurface.foreground);
2246 #if defined(_GLES) || defined(_GLES2) || defined(SHADERS)
2249 glTexCoord2f(0.5f, 0);
2250 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2251 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2252 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2261 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2262 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2268 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2270 OGLSurface oglSurface = surface.driverData;
2271 x1 += surface.offset.x;
2272 y1 += surface.offset.y;
2273 x2 += surface.offset.x;
2274 y2 += surface.offset.y;
2276 //Logf("Rectangle\n");
2278 glColor4fv(oglSurface.foreground);
2279 #if defined(_GLES) || defined(_GLES2) || defined(SHADERS)
2284 glTexCoord2f(0.5f, 0);
2285 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2286 glTexCoord2f(y2-y1 + 0.5f, 0);
2287 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2289 glTexCoord2f(0.5f, 0);
2290 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2291 glTexCoord2f(x2 - x1 + 0.5f, 0);
2292 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2294 glTexCoord2f(0.5f, 0);
2295 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2296 glTexCoord2f(y1 - y2 + 0.5f, 0);
2297 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2299 glTexCoord2f(0.5f, 0);
2300 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2301 glTexCoord2f(x1 - x2 + 0.5f, 0);
2302 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2307 glBegin(GL_LINE_LOOP);
2314 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2315 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2316 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2317 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2322 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2324 OGLSurface oglSurface = surface.driverData;
2327 glColor4fv(oglSurface.background);
2329 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2330 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2332 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2333 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2337 void Clear(Display display, Surface surface, ClearType type)
2339 OGLDisplay oglDisplay = display.driverData;
2340 OGLSurface oglSurface = surface.driverData;
2343 if(type != depthBuffer)
2344 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2345 if(type != colorBuffer && !oglDisplay.depthWrite)
2347 glDepthMask((byte)bool::true);
2349 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2350 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2351 if(type != colorBuffer && !oglDisplay.depthWrite)
2353 glDepthMask((byte)bool::false);
2357 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2362 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2364 OGLSurface oglSurface = surface.driverData;
2366 if(!oglSurface.writingText)
2368 // glTranslatef(-0.375f, -0.375f, 0.0f);
2369 GLSetupTexturing(true);
2370 glColor4fv(oglSurface.bitmapMult);
2372 else if(oglSurface.xOffset)
2373 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2375 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2376 glBegin(GLIMTKMode::quads);
2380 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2381 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2382 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2383 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2384 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2385 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2386 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2387 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2392 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2393 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2394 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2395 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2396 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2397 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2398 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2399 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2402 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2403 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2404 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2405 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2406 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2407 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2408 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2409 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2413 if(!oglSurface.writingText)
2415 GLSetupTexturing(false);
2417 //glTranslate(0.375, 0.375, 0.0);
2419 else if(oglSurface.xOffset)
2420 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2423 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2425 OGLSurface oglSurface = surface.driverData;
2427 //glTranslate(-0.375, -0.375, 0.0);
2429 GLSetupTexturing(true);
2430 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2432 glColor4fv(oglSurface.bitmapMult);
2434 glBegin(GLIMTKMode::quads);
2438 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2439 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2441 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2442 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2444 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2445 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2447 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2448 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2452 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2453 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2455 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2456 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2458 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2459 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2461 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2462 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2467 GLSetupTexturing(false);
2469 //glTranslate(0.375, 0.375, 0.0);
2472 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2474 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2477 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2479 float s2dw,s2dh,d2sw,d2sh;
2480 //bool flipX = false, flipY = false;
2482 //Logf("StretchDI\n");
2484 if(Sgn(w) != Sgn(sw))
2490 if(Sgn(h) != Sgn(sh))
2502 //Clip against the edges of the source
2505 dx+=(int)((0-sx) * s2dw);
2506 w-=(int)((0-sx) * s2dw);
2512 dy+=(int)((0-sy) * s2dh);
2513 h-=(int)((0-sy) * s2dh);
2518 if(sx+sw>bitmap.width-1)
2520 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2521 sw-=sx+sw-(bitmap.width-1)-1;
2523 if(sy+sh>(bitmap.height-1))
2525 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2526 sh-=sy+sh-(bitmap.height-1)-1;
2528 //Clip against the edges of the surfaceination
2529 if(dx<surface.box.left)
2532 sx+=(int)((surface.box.left-dx)*d2sw);
2533 sw-=(int)((surface.box.left-dx)*d2sw);
2534 w-=surface.box.left-dx;
2535 dx=surface.box.left;
2537 if(dy<surface.box.top)
2539 sy+=(int)((surface.box.top-dy)*d2sh);
2540 sh-=(int)((surface.box.top-dy)*d2sh);
2541 h-=surface.box.top-dy;
2544 if(dx+w>surface.box.right)
2546 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2547 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2548 w-=dx+w-surface.box.right-1;
2550 if(dy+h>surface.box.bottom)
2552 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2553 h-=dy+h-surface.box.bottom-1;
2555 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2557 dx += surface.offset.x;
2558 dy += surface.offset.y;
2560 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2562 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2563 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2564 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2565 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2566 #if !defined(SHADERS)
2567 glRasterPos2d(dx,dy);
2568 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2569 glPixelZoom(s2dw, -s2dh);
2570 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2572 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2573 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2574 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2575 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2579 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2583 //Clip against the edges of the source
2596 if(sx+w>bitmap.width-1)
2597 w-=sx+w-(bitmap.width-1)-1;
2598 if(sy+h>bitmap.height-1)
2599 h-=sy+h-(bitmap.height-1)-1;
2600 //Clip against the edges of the surfaceination
2601 if(dx<surface.box.left)
2604 sx+=surface.box.left-dx;
2605 w-=surface.box.left-dx;
2606 dx=surface.box.left;
2608 if(dy<surface.box.top)
2610 sy+=surface.box.top-dy;
2611 h-=surface.box.top-dy;
2614 if(dx+w>surface.box.right)
2616 //if(flip) sx+=dx+w-surface.box.right-1;
2617 w-=dx+w-surface.box.right-1;
2619 if(dy+h>surface.box.bottom)
2620 h-=dy+h-surface.box.bottom-1;
2624 dx += surface.offset.x;
2625 dy += surface.offset.y;
2627 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2629 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2630 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2631 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2632 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2633 #if !defined(SHADERS)
2634 glRasterPos2d(dx,dy);
2636 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2638 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2639 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2640 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2641 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2645 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2647 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2650 void UnloadFont(DisplaySystem displaySystem, Font font)
2652 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2655 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2658 OGLSystem oglSystem = displaySystem.driverData;
2659 oglSystem.loadingFont = true;
2660 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2664 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2666 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2669 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2671 OGLSurface oglSurface = surface.driverData;
2672 OGLSystem oglSystem = display.displaySystem.driverData;
2673 oglSystem.loadingFont = true;
2675 //glTranslated(-0.375, -0.375, 0.0);
2679 if(surface.textOpacity)
2682 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2684 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2687 oglSurface.writingText = true;
2689 GLSetupTexturing(true);
2691 if(surface.font.outlineSize)
2693 ColorAlpha outlineColor = surface.outlineColor;
2694 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2695 oglSurface.writingOutline = true;
2696 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2697 oglSurface.writingOutline = false;
2699 glColor4fv(oglSurface.foreground);
2701 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2702 oglSurface.writingText = false;
2703 oglSystem.loadingFont = false;
2705 GLSetupTexturing(false);
2707 //glTranslated(0.375, 0.375, 0.0);
2710 void TextFont(Display display, Surface surface, Font font)
2712 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2715 void TextOpacity(Display display, Surface surface, bool opaque)
2717 OGLSurface oglSurface = surface.driverData;
2718 oglSurface.opaqueText = opaque;
2721 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2723 OGLSurface oglSurface = surface.driverData;
2724 OGLSystem oglSystem = display.displaySystem.driverData;
2725 oglSystem.loadingFont = true;
2726 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2727 oglSystem.loadingFont = false;
2730 void DrawingChar(Display display, Surface surface, char character)
2735 void LineStipple(Display display, Surface surface, uint32 stipple)
2737 //Logf("Stipple\n");
2741 #if defined(_GLES) || defined(_GLES2) || defined(SHADERS)
2742 stippleEnabled = true;
2743 glesLineStipple(1, (uint16)stipple);
2745 glLineStipple(1, (uint16)stipple);
2746 glEnable(GL_LINE_STIPPLE);
2751 #if defined(_GLES) || defined(_GLES2) || defined(SHADERS)
2752 stippleEnabled = false;
2753 glMatrixMode(GL_TEXTURE);
2755 glMatrixMode(MatrixMode::projection);
2756 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2758 glDisable(GL_LINE_STIPPLE);
2763 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2764 void SetRenderState(Display display, RenderState state, uint value)
2766 OGLDisplay oglDisplay = display.driverData;
2767 //Logf("RenderState\n");
2772 #ifndef __EMSCRIPTEN__
2774 glEnable(GL_MULTISAMPLE_ARB);
2776 glDisable(GL_MULTISAMPLE_ARB);
2780 #if !defined(_GLES) && !defined(_GLES2)
2781 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2785 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2788 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2789 oglDisplay.depthWrite = (bool)value;
2793 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2794 #if defined(SHADERS)
2795 shader_fogColor(color[0], color[1], color[2]);
2797 glFogfv(GL_FOG_COLOR, (float *)&color);
2802 #if defined(SHADERS)
2803 shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2805 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2809 //#if !defined(__EMSCRIPTEN__)
2810 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2815 #if defined(SHADERS)
2816 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2818 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2819 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2825 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2830 #if defined(__WIN32__)
2831 if(wglSwapIntervalEXT)
2832 wglSwapIntervalEXT(value ? 1 : 0);
2839 void SetLight(Display display, int id, Light light)
2841 #if defined(SHADERS)
2842 shader_setLight(display, id, light);
2844 //Logf("SetLight\n");
2848 Object lightObject = light.lightObject;
2849 float position[4] = { 0, 0, 0, 0 };
2850 float color[4] = { 0, 0, 0, 1 };
2852 glEnable(GL_LIGHT0 + id);
2854 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
2855 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
2856 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
2859 if(!light.multiplier) light.multiplier = 1.0f;
2861 color[0] = light.diffuse.r * light.multiplier;
2862 color[1] = light.diffuse.g * light.multiplier;
2863 color[2] = light.diffuse.b * light.multiplier;
2864 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2866 color[0] = light.ambient.r * light.multiplier;
2867 color[1] = light.ambient.g * light.multiplier;
2868 color[2] = light.ambient.b * light.multiplier;
2869 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2870 color[0] = light.specular.r * light.multiplier;
2871 color[1] = light.specular.g * light.multiplier;
2872 color[2] = light.specular.b * light.multiplier;
2873 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2877 Vector3D positionVector;
2878 if(light.flags.spot)
2880 if(lightObject.flags.root || !lightObject.parent)
2882 positionVector = lightObject.transform.position;
2883 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2887 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2888 if(display.display3D.camera)
2889 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2895 if(!light.direction.x && !light.direction.y && !light.direction.z)
2897 Vector3Df vector { 0,0,-1 };
2899 mat.RotationQuaternion(light.orientation);
2900 positionVector.MultMatrixf(vector, mat);
2904 positionVector = light.direction;
2909 position[0] = (float)positionVector.x;
2910 position[1] = (float)positionVector.y;
2911 position[2] = (float)positionVector.z;
2913 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2916 // Display Light Position
2917 glDisable(GL_LIGHTING);
2918 glDisable(GL_DEPTH_TEST);
2922 glVertex3fv(position);
2924 glEnable(GL_DEPTH_TEST);
2925 glEnable(GL_LIGHTING);
2929 if(lightObject.flags.root || !lightObject.parent)
2931 positionVector = light.target.transform.position;
2932 positionVector.Subtract(positionVector, display.camera.cPosition);
2936 positionVector.MultMatrix(light.target.transform.position,
2937 lightObject.light.target.parent.matrix);
2938 positionVector.Subtract(positionVector, display.camera.cPosition);
2941 position[0] = positionVector.x;
2942 position[1] = positionVector.y;
2943 position[2] = positionVector.z;
2945 glDisable(GL_LIGHTING);
2946 glDisable(GL_DEPTH_TEST);
2950 glVertex3fv(position);
2952 glEnable(GL_DEPTH_TEST);
2953 glEnable(GL_LIGHTING);
2956 if(light.flags.attenuation)
2958 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2959 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2960 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2963 if(light.flags.spot)
2966 #define MAXLIGHT 0.9
2967 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2968 // Figure out exponent out of the hot spot
2969 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2971 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2972 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2973 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2978 Vector3Df vector { 0,0,-1 };
2979 Vector3Df direction;
2982 mat.RotationQuaternion(light.orientation);
2983 direction.MultMatrix(vector, mat);
2985 position[0] = direction.x;
2986 position[1] = direction.y;
2987 position[2] = direction.z;
2989 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2993 glDisable(GL_LIGHT0 + id);
2997 void SetCamera(Display display, Surface surface, Camera camera)
2999 OGLDisplay oglDisplay = display.driverData;
3000 //Logf("SetCamera\n");
3002 if(surface && camera)
3004 int left = surface.box.left + surface.offset.x;
3005 int top = surface.box.top + surface.offset.y;
3006 int right = surface.box.right + surface.offset.x;
3007 int bottom = surface.box.bottom + surface.offset.y;
3008 float origX = surface.offset.x + camera.origin.x;
3009 float origY = surface.offset.y + camera.origin.y;
3011 int y = display.height - bottom - 1;
3012 int w = right - left + 1;
3013 int h = bottom - top + 1;
3016 glViewport(x, y, w, h);
3018 // *** Projection Matrix ***
3019 glMatrixMode(MatrixMode::projection);
3020 if(!display.display3D.camera)
3023 if(display.display3D.collectingHits)
3025 float pickX = display.display3D.pickX + surface.offset.x;
3026 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3030 w / display.display3D.pickWidth, 0, 0, 0,
3031 0, h / display.display3D.pickHeight, 0, 0,
3033 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3034 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3037 glLoadMatrixd(pickMatrix.array);
3042 (left - origX) * camera.zMin / camera.focalX,
3043 (right - origX) * camera.zMin / camera.focalX,
3044 (bottom - origY) * camera.zMin / camera.focalY,
3045 (top - origY) * camera.zMin / camera.focalY,
3046 camera.zMin, camera.zMax);
3048 glDisable(GL_BLEND);
3050 // *** Z Inverted Identity Matrix ***
3051 glMatrixMode(MatrixMode::modelView);
3052 if(!display.display3D.camera)
3057 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3059 // *** View Matrix ***
3060 glMultMatrixd(camera.viewMatrix.array);
3065 glEnable(GL_DEPTH_TEST);
3067 GLSetupLighting(true);
3068 #if !defined(SHADERS)
3069 glShadeModel(GL_SMOOTH);
3071 glDepthMask((byte)bool::true);
3072 oglDisplay.depthWrite = true;
3074 #ifndef __EMSCRIPTEN__
3075 glEnable(GL_MULTISAMPLE_ARB);
3078 else if(surface && display.display3D.camera)
3081 oglDisplay.depthWrite = false;
3082 glViewport(0,0,display.width,display.height);
3084 glDisable(GL_CULL_FACE);
3085 glDisable(GL_DEPTH_TEST);
3088 GLSetupTexturing(false);
3089 GLSetupLighting(false);
3092 glDisableClientState(GL_COLOR_ARRAY);
3094 #if defined(SHADERS)
3095 shader_setPerVertexColor(false);
3097 glShadeModel(GL_FLAT);
3100 #if !defined(__EMSCRIPTEN__)
3101 glDisable(GL_MULTISAMPLE_ARB);
3104 // *** Restore 2D MODELVIEW Matrix ***
3107 // *** Restore 2D PROJECTION Matrix ***
3108 glMatrixMode(MatrixMode::projection);
3114 void ApplyMaterial(Display display, Material material, Mesh mesh)
3116 //Logf("ApplyMaterial\n");
3119 if(material.flags.doubleSided)
3121 #if !defined(SHADERS)
3122 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3124 glDisable(GL_CULL_FACE);
3128 #if !defined(SHADERS)
3129 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3131 glEnable(GL_CULL_FACE);
3135 GLSetupFog(!material.flags.noFog);
3138 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3140 Bitmap map = material.baseMap;
3141 GLSetupTexturing(true);
3142 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3144 glMatrixMode(GL_TEXTURE);
3146 if(material.uScale && material.vScale)
3147 glScalef(material.uScale, material.vScale, 1);
3148 glMatrixMode(MatrixMode::modelView);
3150 if(material.flags.tile)
3152 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3153 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3157 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3158 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3162 GLSetupTexturing(false);
3164 #if defined(SHADERS)
3165 shader_setMaterial(material, mesh.flags.colors);
3167 if(mesh.flags.colors)
3169 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3170 glEnable(GL_COLOR_MATERIAL);
3174 glDisable(GL_COLOR_MATERIAL);
3176 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3177 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3180 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3181 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3185 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3186 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3189 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3190 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3193 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3197 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3199 OGLMesh oglMesh = mesh.data;
3202 if(!mesh.flags.vertices)
3204 oglMesh.vertices.free();
3205 delete mesh.vertices;
3207 if(!mesh.flags.normals)
3209 oglMesh.normals.free();
3210 delete mesh.normals;
3212 if(!mesh.flags.texCoords1)
3214 oglMesh.texCoords.free();
3215 delete mesh.texCoords;
3217 if(!mesh.flags.texCoords2)
3219 oglMesh.texCoords2.free();
3220 // delete mesh.texCoords2;
3222 if(!mesh.flags.colors)
3224 oglMesh.colors.free();
3235 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3237 bool result = false;
3240 mesh.data = OGLMesh { };
3243 if(mesh.nVertices == nVertices)
3245 // Same number of vertices, adding features (Leaves the other features pointers alone)
3246 if(mesh.flags != flags)
3248 if(!mesh.flags.vertices && flags.vertices)
3250 if(flags.doubleVertices)
3252 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3255 mesh.vertices = new Vector3Df[nVertices];
3257 if(!mesh.flags.normals && flags.normals)
3259 if(flags.doubleNormals)
3261 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3264 mesh.normals = new Vector3Df[nVertices];
3266 if(!mesh.flags.texCoords1 && flags.texCoords1)
3268 mesh.texCoords = new Pointf[nVertices];
3270 if(!mesh.flags.colors && flags.colors)
3272 mesh.colors = new ColorRGBAf[nVertices];
3278 // New number of vertices, reallocate all current and new features
3279 flags |= mesh.flags;
3282 if(flags.doubleVertices)
3284 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3287 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3291 if(flags.doubleNormals)
3293 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3296 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3298 if(flags.texCoords1)
3300 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3304 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3312 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3314 OGLMesh oglMesh = mesh.data;
3315 if(!flags) flags = mesh.flags;
3320 oglMesh.vertices.upload(
3321 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3324 oglMesh.normals.upload(
3325 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3327 if(flags.texCoords1)
3328 oglMesh.texCoords.upload(
3329 mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3332 oglMesh.colors.upload(
3333 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3337 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3344 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3348 oglIndices.buffer.free();
3349 delete oglIndices.indices;
3354 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3356 OGLIndices oglIndices = OGLIndices { };
3359 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3360 oglIndices.nIndices = nIndices;
3365 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3369 #if defined(_GLES) || defined(_GLES2)
3372 if(!oglIndices.buffer.buffer)
3373 glGenBuffers(1, &oglIndices.buffer.buffer);
3374 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3375 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3376 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3380 oglIndices.buffer.upload(
3381 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3382 oglIndices.indices); //GL_STATIC_DRAW_ARB);
3386 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3389 return oglIndices.indices;
3392 void SelectMesh(Display display, Mesh mesh)
3394 //Logf("SelectMesh\n");
3396 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3398 #if defined(__WIN32__)
3399 if(glUnlockArraysEXT)
3401 if(!vboAvailable && display.display3D.mesh)
3402 glUnlockArraysEXT();
3407 OGLMesh oglMesh = mesh.data;
3409 // *** Vertex Stream ***
3410 glEnableClientState(GL_VERTEX_ARRAY);
3411 if(!display.display3D.collectingHits && oglMesh)
3413 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3415 // *** Normals Stream ***
3416 if(mesh.normals || mesh.flags.normals)
3418 glEnableClientState(GL_NORMAL_ARRAY);
3419 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3422 glDisableClientState(GL_NORMAL_ARRAY);
3424 // *** Texture Coordinates Stream ***
3425 if(mesh.texCoords || mesh.flags.texCoords1)
3427 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3428 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3431 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3433 // *** Color Stream ***
3434 if(mesh.colors || mesh.flags.colors)
3436 glEnableClientState(GL_COLOR_ARRAY);
3437 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3440 glDisableClientState(GL_COLOR_ARRAY);
3444 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3445 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3447 glEnableClientState(GL_NORMAL_ARRAY);
3448 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3451 glDisableClientState(GL_NORMAL_ARRAY);
3452 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3454 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3455 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3458 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3459 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3461 glEnableClientState(GL_COLOR_ARRAY);
3462 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3465 glDisableClientState(GL_COLOR_ARRAY);
3468 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3470 #if defined(__WIN32__)
3474 glLockArraysEXT(0, mesh.nVertices);
3480 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3482 //Logf("DrawPrimitives\n");
3484 if(primitive->type.vertexRange)
3485 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3488 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3489 // HACK TO SPEED THINGS UP...
3491 /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3492 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3495 glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
3498 OGLIndices oglIndices = primitive->data;
3499 MeshFeatures flags = mesh.flags;
3500 for(c = 0; c<primitive->nIndices; c++)
3502 uint16 index = ((uint16 *) oglIndices.indices)[c];
3503 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3504 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3505 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3506 glVertex3fv((float *)&mesh.vertices[index]);
3515 OGLIndices oglIndices = primitive->data;
3516 GLEAB eab = ((!display.display3D.collectingHits && oglIndices && vboAvailable) ? oglIndices.buffer : noEAB);
3517 #if defined(_GLES) || defined(_GLES2)
3518 if(!vboAvailable && primitive->type.indices32bit)
3520 uint16 * temp = new uint16[primitive->nIndices];
3521 uint32 * src = (uint32 *)(oglIndices ? oglIndices.indices : primitive->indices);
3523 for(i = 0; i < primitive->nIndices; i++)
3524 temp[i] = (uint16)src[i];
3525 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices, GL_UNSIGNED_SHORT, temp);
3530 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3531 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3532 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3533 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3538 void PushMatrix(Display display)
3543 void PopMatrix(Display display, bool setMatrix)
3548 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3550 Matrix matrix = transMatrix;
3551 Camera camera = useCamera ? display.display3D.camera : null;
3556 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3561 matrix.m[3][0] - camera.cPosition.x,
3562 matrix.m[3][1] - camera.cPosition.y,
3563 matrix.m[3][2] - camera.cPosition.z);
3575 glMultMatrixd(matrix.array);
3580 public void UseSingleGLContext(bool useSingle)
3582 useSingleGLContext = useSingle;
3585 default dllexport void *
3586 #if defined(__WIN32__)
3587 __attribute__((stdcall))
3589 IS_GLGetContext(DisplaySystem displaySystem)
3593 #if defined(__WIN32__)
3594 OGLSystem system = displaySystem.driverData;
3596 #elif defined(__ANDROID__) || defined(__ODROID__)
3598 #elif defined(__EMSCRIPTEN__)
3599 OGLSystem system = displaySystem.driverData;
3600 return (void *)system.glc;
3602 OGLSystem system = displaySystem.driverData;
3603 return system.glContext;