3 namespace gfx::drivers;
11 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
13 # include "gl_core_3_3.h"
15 # include "gl_compat_4_4.h"
19 #if defined(__ANDROID__) || defined(__ODROID__)
28 #define GL_BGRA_EXT 0x80E1
32 #undef glEnableClientState
33 #undef glDisableClientState
34 #undef GL_VERTEX_ARRAY
35 #undef GL_NORMAL_ARRAY
36 #undef GL_TEXTURE_COORD_ARRAY
39 #define glEnableClientState glEnableVertexAttribArray
40 #define glDisableClientState glDisableVertexAttribArray
41 #define GL_VERTEX_ARRAY GLBufferContents::vertex
42 #define GL_NORMAL_ARRAY GLBufferContents::normal
43 #define GL_TEXTURE_COORD_ARRAY GLBufferContents::texCoord
44 #define GL_COLOR_ARRAY GLBufferContents::color
48 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
50 #if defined(__unix__) || defined(__APPLE__)
52 #if !defined(__MINGW32__)
53 #define GL_GLEXT_PROTOTYPES
56 #define pointer _pointer
59 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
61 #define property _property
65 #define Window X11Window
66 #define Cursor X11Cursor
68 #define Display X11Display
70 #define KeyCode X11KeyCode
71 #define Picture X11Picture
75 #include <X11/Xutil.h>
77 #include <X11/extensions/XShm.h>
80 #include <X11/extensions/Xrender.h>
81 #include <X11/extensions/shape.h>
99 #if defined(__APPLE__)
100 #include <OpenGl/gl.h>
103 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
105 #if defined(__WIN32__)
106 //#define WIN32_LEAN_AND_MEAN
108 #define _WIN32_WINNT 0x0502
109 #define String Sting_
114 #if defined(__ANDROID__) || defined(__ODROID__)
117 #define property _property
120 #define Window X11Window
121 #define Cursor X11Cursor
123 #define Display X11Display
125 #define KeyCode X11KeyCode
126 #define Picture X11Picture
144 #elif defined(__EMSCRIPTEN__)
146 #define property _property
151 //#include <GLES/gl.h>
152 //#include <GLES2/gl.h>
154 #include <emscripten/emscripten.h>
163 #if defined(__ODROID__) && !defined(ES1_1)
167 #if defined(__EMSCRIPTEN__)
176 #if defined(__unix__) || defined(__APPLE__)
178 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
184 #define glLoadMatrix glLoadMatrixd
185 #define glMultMatrix glMultMatrixd
186 #define glGetMatrix glGetDoublev
187 #define glTranslate glTranslated
188 #define glScale glScaled
191 #define glVertex3v glVertex3dv
192 #define glNormal3v glNormal3dv
196 //#ifdef VERTEX_FORMAT_DOUBLE
198 #define glLoadMatrix glLoadMatrixd
199 #define glMultMatrix glMultMatrixd
200 #define glGetMatrix glGetDoublev
201 #define glVertex3v glVertex3dv
202 #define glNormal3v glNormal3dv
203 #define glTranslate glTranslated
204 #define glScale glScaled
205 //#define GL_VERTEX_FORMAT GL_DOUBLE
209 #define glLoadMatrix glLoadMatrixf
210 #define glMultMatrix glMultMatrixf
211 #define glGetMatrix glGetFloatv
212 #define glVertex3v glVertex3fv
213 #define glNormal3v glNormal3fv
214 #define glTranslate glTranslatef
215 #define glScale glScalef
216 //#define GL_VERTEX_FORMAT GL_FLOAT
221 #define GL_ARRAY_BUFFER_ARB 0x8892
222 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
223 #define GL_STATIC_DRAW_ARB 0x88E4
224 #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
225 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
227 #define GL_MULTISAMPLE_ARB 0x809D
229 #if defined(__WIN32__)
232 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
233 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
235 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
236 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
238 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
239 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
240 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
241 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
242 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
243 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
244 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
245 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
246 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
247 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = null;
248 static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = null;
250 #elif defined(__ANDROID__) || defined(__ODROID__)
252 #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
253 #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
254 #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
256 #define GL_POLYGON_STIPPLE 0xFFFF
257 #define GL_LINE_STIPPLE 0xFFFF
258 #define GL_LINE 0xFFFF
259 #define GL_FILL 0xFFFF
260 #define GL_ALL_ATTRIB_BITS 0xFFFF
261 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
267 #define GL_QUAD_STRIP 0
268 //#define GL_DOUBLE 0
269 //#define GL_UNSIGNED_INT 0
272 //#define GL_LINE_STIPPLE 0
273 #define GL_BGRA_EXT 0
274 #define GL_UNPACK_ROW_LENGTH 0
275 #define GL_UNPACK_SKIP_PIXELS 0
276 #define GL_UNPACK_SKIP_ROWS 0
278 #define GL_PACK_ROW_LENGTH 0
279 #define GL_PACK_SKIP_ROWS 0
280 #define GL_PACK_SKIP_PIXELS 0
285 #if defined(__ANDROID__) || defined(__ODROID__)
286 #define glBindFramebuffer glBindFramebufferOES
287 #define glBindRenderbuffer glBindRenderbufferOES
288 #define glFramebufferTexture2D glFramebufferTexture2DOES
289 #define glGenFramebuffers glGenFramebuffersOES
290 #define glGenRenderbuffers glGenRenderbuffersOES
291 #define glDeleteFramebuffers glDeleteFramebuffersOES
292 #define glDeleteRenderbuffers glDeleteRenderbuffersOES
294 #define GL_INT 0x1404
295 #define GL_UNSIGNED_INT 0x1405
296 #define GL_DOUBLE 0x140A
300 #if defined(ES1_1) || defined(SHADERS)
331 #undef glLoadIdentity
336 #undef glColorMaterial
339 #define glRecti glimtkRecti
340 #define glBegin glimtkBegin
341 #define glTexCoord2i glimtkTexCoord2i
342 #define glVertex2i glimtkVertex2i
343 #define glTexCoord2d glimtkTexCoord2d
344 #define glVertex2d glimtkVertex2d
345 #define glTexCoord2f glimtkTexCoord2f
346 #define glVertex2f glimtkVertex2f
347 #define glEnd glimtkEnd
348 #define glColor3f glimtkColor3f
349 #define glColor4ub glimtkColor4ub
350 #define glColor4fv glimtkColor4fv
351 #define glNormal3fv glimtkNormal3fv
352 #define glNormal3f glimtkNormal3f
353 #define glTexCoord2fv glimtkTexCoord2fv
354 #define glVertex3d glimtkVertex3d
355 #define glVertex3dv glimtkVertex3dv
356 #define glVertex3f glimtkVertex3f
357 #define glVertex3fv glimtkVertex3fv
359 #define glLoadMatrixd glmsLoadMatrixd
360 #define glMultMatrixd glmsMultMatrixd
361 #define glFrustum glmsFrustum
362 #define glOrtho glmsOrtho
363 #define glScaled glmsScaled
364 #define glScalef glmsScaled
365 #define glTranslated glmsTranslated
366 #define glRotated glmsRotated
367 #define glMatrixMode glmsMatrixMode
368 #define glLoadIdentity glmsLoadIdentity
369 #define glPushMatrix glmsPushMatrix
370 #define glPopMatrix glmsPopMatrix
372 #define glLineStipple glesLineStipple
373 #define glColorMaterial glesColorMaterial
374 #define glLightModeli glesLightModeli
378 public void glesColorMaterial(int a, int b)
380 PrintLn("glColorMaterial stub");
383 static GLuint stippleTexture;
384 #if defined(ES1_1) || defined(SHADERS) || defined(EM_MODE)
385 static bool stippleEnabled;
388 public void glesLineStipple( int i, unsigned short j )
392 for(x = 0; x < 16; x++)
394 bool v = (j & (1 << x)) != 0;
395 texture[x] = v ? 0xFFFFFFFF : 0;
398 glGenTextures(1, &stippleTexture);
399 glBindTexture(GL_TEXTURE_2D, stippleTexture);
400 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
402 // TOOD: Special shading code for stippling?
403 GLSetupTexturing(true);
404 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
406 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
407 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
408 glMatrixMode(GL_TEXTURE);
410 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
411 glScaled(i/16.0, 1, 1.0f);
412 glTranslated(0.5, 0.5, 0);
413 glMatrixMode(MatrixMode::projection);
416 public void glesLightModeli( unsigned int pname, int param )
418 #if !defined(EM_MODE) && !defined(SHADERS)
419 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
420 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
424 #if defined(__ANDROID__) || defined(__ODROID__)
425 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
426 void glFogi( unsigned int pname, int param ) { }
427 void glPolygonMode( unsigned int i, unsigned int j ) { }
430 // *** Picking won't be supported for now ***
431 void glPushName( unsigned int i ) { }
432 void glLoadName( unsigned int i ) { }
435 // Probably replace by regular glBlendFunc ...
436 void glBlendFuncSeparate(int a, int b, int c, int d)
441 // For direct pixel blitting...
442 void glRasterPos2d(double a, double b) { }
443 void glPixelZoom(float a, float b) { }
444 void glDrawPixels(int a, int b, int c, int d, void * e) { }
448 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
449 static int primitiveTypes[RenderPrimitiveType] =
451 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GLIMTKMode::quads, GLIMTKMode::quadStrip, GL_LINE_STRIP
455 public void GLSetupTexturing(bool enable)
458 shader_texturing(enable);
460 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
464 public void GLSetupFog(bool enable)
468 #elif !defined(EM_MODE)
469 (enable ? glEnable : glDisable)(GL_FOG);
473 public void GLSetupLighting(bool enable)
476 shader_lighting(enable);
477 #elif !defined(EM_MODE)
478 (enable ? glEnable : glDisable)(GL_LIGHTING);
482 // Non OpenGL ES friendly stuff
486 //#undef GL_UNSIGNED_INT
492 #undef GL_POLYGON_STIPPLE
493 #undef GL_LINE_STIPPLE
496 #undef GL_ALL_ATTRIB_BITS
497 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
501 static int displayWidth, displayHeight;
503 #define GL_CLAMP_TO_EDGE 0x812F
505 static bool vboAvailable;
507 static bool useSingleGLContext = false;
508 class OGLDisplay : struct
510 #if defined(__WIN32__)
521 byte * pboMemory1, * pboMemory2;
523 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
524 GLXContext glContext;
527 XShmSegmentInfo shminfo;
529 XShmSegmentInfo shminfoShape;
534 X11Picture windowPicture;
535 X11Picture pixmapPicture;
537 X11Picture shapePicture;
540 ColorAlpha * flippingBuffer;
541 int flipBufH, flipBufW;
547 static void APIENTRY openglCallbackFunction(GLenum source,
552 const GLchar* message,
553 const void* userParam)
555 PrintLn("---------------------opengl-callback-start------------");
556 PrintLn("message: ", message);
560 case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
561 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
562 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
563 case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
564 case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
565 case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
572 case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
573 case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
574 case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
576 PrintLn("---------------------opengl-callback-end--------------");
580 class OGLSystem : struct
585 #if defined(__WIN32__)
586 PIXELFORMATDESCRIPTOR pfd;
591 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
592 XVisualInfo * visualInfo;
593 GLXContext glContext;
594 GLXDrawable glxDrawable;
598 class OGLSurface : struct
606 float foreground[4], background[4], bitmapMult[4];
609 class OGLMesh : struct
618 class OGLIndices : struct
628 static void setupDebugging()
631 if(glDebugMessageCallback)
633 GLuint unusedIds = 0;
635 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
636 glDebugMessageCallback(openglCallbackFunction, null);
637 glDebugMessageControl(GL_DONT_CARE,
647 #if defined(__WIN32__)
648 static HGLRC winCreateContext(HDC hdc)
652 if(wglCreateContextAttribsARB)
656 WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
657 WGL_CONTEXT_MINOR_VERSION_ARB, 4,
658 WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | */WGL_CONTEXT_DEBUG_BIT_ARB,
659 WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB /*WGL_CONTEXT_CORE_PROFILE_BIT_ARB*/,
662 result = wglCreateContextAttribsARB(hdc, null, attribs);
668 result = wglCreateContextAttribsARB(hdc, null, attribs);
673 result = wglCreateContext(hdc);
678 class OpenGLDisplayDriver : DisplayDriver
680 class_property(name) = "OpenGL";
682 bool LockSystem(DisplaySystem displaySystem)
684 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
685 OGLSystem oglSystem = displaySystem.driverData;
686 if(useSingleGLContext) return true;
687 #if defined(__WIN32__)
688 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
689 #elif defined(__unix__) || defined(__APPLE__)
690 //if(previous) return true;
691 // printf("Making SYSTEM current\n");
692 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
693 //previous = oglSystem.glContext;
696 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
697 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
701 void UnlockSystem(DisplaySystem displaySystem)
703 if(useSingleGLContext) return;
704 #if defined(__WIN32__)
705 wglMakeCurrent(null, null);
706 #elif defined(__unix__) || defined(__APPLE__)
707 // printf("Making NULL current\n");
708 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
710 glXMakeCurrent(xGlobalDisplay, None, null);
716 bool Lock(Display display)
718 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
719 OGLDisplay oglDisplay = display.driverData;
720 if(useSingleGLContext) return true;
721 #if defined(__WIN32__)
722 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
723 #elif defined(__unix__) || defined(__APPLE__)
724 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
725 // printf(" Making DISPLAY current\n");
726 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
729 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
730 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
734 void Unlock(Display display)
736 if(useSingleGLContext) return;
737 //printf(" Making NULL current\n");
738 //glXMakeCurrent(xGlobalDisplay, None, null);
740 LockSystem(display.displaySystem);
743 void DestroyDisplay(Display display)
745 OGLDisplay oglDisplay = display.driverData;
749 #if defined(__WIN32__)
750 wglMakeCurrent( null, null );
753 wglDeleteContext(oglDisplay.glrc);
755 if(oglDisplay.hdc && oglDisplay.pBuffer)
756 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
758 if(oglDisplay.pBuffer)
759 wglDestroyPbufferARB(oglDisplay.pBuffer);
762 ReleaseDC(display.window, oglDisplay.hdc);
764 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
765 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
767 #elif defined(__unix__) || defined(__APPLE__)
768 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
770 if(oglDisplay.shapePixmap)
771 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
772 if(oglDisplay.pixmap)
773 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
776 if(oglDisplay.shminfoShape.shmid != -1)
778 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
779 if(oglDisplay.shminfo.shmaddr != (void *)-1)
780 shmdt(oglDisplay.shminfo.shmaddr);
781 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
784 if(oglDisplay.shapeImage)
786 if(oglDisplay.shminfoShape.shmid != -1)
788 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
789 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
790 shmdt(oglDisplay.shminfoShape.shmaddr);
791 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
793 XDestroyImage(oglDisplay.shapeImage);
794 oglDisplay.shapeImage = None;
797 glXMakeCurrent(xGlobalDisplay, None, null);
799 if(oglDisplay.glContext)
800 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
803 delete oglDisplay.flippingBuffer;
805 display.driverData = null;
809 void ::CheckExtensions(OGLSystem oglSystem)
811 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
813 printf("extensions: %s\n", extensions);
816 oglSystem.pow2textures = (extensions && strstr(extensions, "GL_ARB_texture_non_power_of_two")) ? false : true;
817 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
820 bool CreateDisplaySystem(DisplaySystem displaySystem)
823 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
826 PrintLn("OpenGL driver's CreateDisplaySystem()");
830 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
832 oglSystem.hdc = GetDC(oglSystem.hwnd);
836 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
837 oglSystem.pfd.nVersion = 1;
838 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
839 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
840 oglSystem.pfd.cColorBits = 24;
841 oglSystem.pfd.cAlphaBits = 8;
842 oglSystem.pfd.cDepthBits = 24;
843 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
845 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
846 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
848 if(oglSystem.pfd.cColorBits > 8)
850 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
851 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
854 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
856 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
857 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
858 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
859 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
860 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
861 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
862 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
863 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
864 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
865 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
866 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
868 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
869 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
871 // eSystem_LoggingMode(LOG_MSGBOX, null);
873 if(wglChoosePixelFormatARB)
878 float fAttributes[] = {0,0};
881 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
882 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
883 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
884 WGL_COLOR_BITS_ARB,24,
885 WGL_ALPHA_BITS_ARB,8,
886 WGL_DEPTH_BITS_ARB,16,
887 WGL_STENCIL_BITS_ARB,0,
888 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
889 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
890 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
894 //Log("Found wglChoosePixelFormatARB\n");
896 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
897 if(!valid || !numFormats)
899 //Log("Can't find 4x multi sampling\n");
901 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
902 if(!valid || !numFormats)
904 // Log("Can't find 2x multi sampling\n");
907 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
910 if(valid && numFormats)
912 oglSystem.format = pixelFormat;
913 wglMakeCurrent(null, null);
914 wglDeleteContext(oglSystem.glrc);
916 // *** DescribePixelFormat does not support WGL pixel formats! ***
917 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
918 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
919 //Log("Successfully set pixel format\n");
922 PrintLn("winCreateContext()");
924 oglSystem.glrc = winCreateContext(oglSystem.hdc);
926 PrintLn("wglMakeCurrent()");
928 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
932 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
936 wglMakeCurrent(null, null);
938 //eSystem_DumpErrors(true);
942 #elif defined(__unix__) || defined(__APPLE__)
944 #if defined(__ANDROID__) || defined(__ODROID__)
945 #if defined(__ANDROID__)
946 egl_init_display(guiApp.desktop.windowHandle);
947 #elif defined(__ODROID__)
948 egl_init_display((uint)displaySystem.window);
949 CheckExtensions(oglSystem);
952 // TODO: Clean this up? Needed here?
953 glEnableClientState(GL_VERTEX_ARRAY);
955 // Initialize GL state.
956 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
957 glEnable(GL_CULL_FACE);
958 glShadeModel(GL_SMOOTH);
959 glDisable(GL_DEPTH_TEST);
961 glDisable(GL_CULL_FACE);
962 glDisable(GL_DEPTH_TEST);
964 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
967 matrixStack[0][0].Identity();
968 matrixStack[1][0].Identity();
969 matrixStack[2][0].Identity();
971 glmsMatrixMode(GL_MODELVIEW);
972 glScaled(1.0, 1.0, -1.0);
973 glmsMatrixMode(GL_PROJECTION);
974 glShadeModel(GL_FLAT);
976 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
977 glFogi(GL_FOG_MODE, GL_EXP);
978 glFogf(GL_FOG_DENSITY, 0);
979 glEnable(GL_NORMALIZE);
980 glDepthFunc(GL_LESS);
982 glDisable(GL_MULTISAMPLE_ARB);
984 glViewport(0,0,eglWidth,eglHeight);
986 glOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
988 glabCurArrayBuffer = 0;
989 glabCurElementBuffer = 0;
992 #elif defined(__EMSCRIPTEN__)
993 if(glfwInit() == GL_TRUE)
995 const int width = 640, height = 480;
996 if(glfwOpenWindow(width, height, 8, 8, 8, 8, 16, 0, GLFW_WINDOW) == GL_TRUE)
1002 printf("glfwOpenWindow() failed\n"); //glfwTerminate();
1005 printf("glfwInit() failed\n"); //glfwTerminate();
1008 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1009 XSetWindowAttributes attr;
1014 #ifndef ECERE_MINIGLX
1015 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1018 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1022 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
1023 attr.background_pixel = 0;
1024 attr.border_pixel = 0;
1025 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1026 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1027 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1029 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1030 oglSystem.visualInfo->visual, mask, &attr );
1032 if(oglSystem.visualInfo)
1034 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1035 if(oglSystem.glContext)
1037 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1039 // CheckExtensions(oglSystem);
1040 glXMakeCurrent(xGlobalDisplay, None, null);
1047 displaySystem.flags.alpha = true;
1048 displaySystem.flags.flipping = true;
1049 displaySystem.pixelFormat = pixelFormat888;
1053 void DestroyDisplaySystem(DisplaySystem displaySystem)
1055 OGLSystem oglSystem = displaySystem.driverData;
1058 glDeleteTextures(1, &stippleTexture);
1062 #if defined(__WIN32__)
1063 wglMakeCurrent( null, null );
1066 wglDeleteContext(oglSystem.glrc);
1069 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1070 DestroyWindow(oglSystem.hwnd);
1072 #elif defined(__unix__) || defined(__APPLE__)
1073 #if defined(__ANDROID__) || defined(__ODROID__)
1075 #elif defined(__EMSCRIPTEN__)
1078 if(oglSystem.visualInfo)
1080 #ifdef ECERE_MINIGLX
1081 __miniglx_XFree(oglSystem.visualInfo);
1083 XFree(oglSystem.visualInfo);
1087 if(oglSystem.glxDrawable)
1089 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1090 oglSystem.glxDrawable = 0;
1097 bool CreateDisplay(Display display)
1099 bool result = false;
1100 OGLDisplay oglDisplay = display.driverData;
1101 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
1102 OGLSystem oglSystem = display.displaySystem.driverData;
1106 oglDisplay = display.driverData = OGLDisplay { };
1107 //printf("Inside CreateDisplay\n");
1109 #if defined(__WIN32__) || defined(USEPBUFFER)
1110 if(!display.alphaBlend)
1113 #if defined(__WIN32__)
1114 oglDisplay.hdc = GetDC(display.window);
1115 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1116 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1118 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1119 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1123 ReleaseDC(display.window, oglDisplay.hdc);
1124 #elif defined(__unix__) || defined(__APPLE__)
1125 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1127 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1129 #if defined(__APPLE__)
1130 XVisualInfo template = { 0 };
1131 XWindowAttributes winAttr;
1133 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1134 template.visualid = XVisualIDFromVisual(winAttr.visual);
1135 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1137 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1138 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1139 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1140 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1142 // visualInfo = oglSystem.visualInfo;
1147 //printf("visualInfo is not null\n");
1148 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1149 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1150 //XFree(visualInfo);
1153 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1154 if(oglDisplay.glContext)
1156 //printf("CreateDisplay Got a Context\n");
1157 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1163 #if defined(__WIN32__) || defined(USEPBUFFER)
1169 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1172 PrintLn("Calling ogl_LoadFunctions() in CreateDisplay()");
1174 ogl_LoadFunctions();
1176 PrintLn("CheckExtensions()");
1178 CheckExtensions(oglSystem);
1179 vboAvailable = glBindBuffer != null;
1182 PrintLn("vboAvailable is: ", vboAvailable);
1191 loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1193 glEnableClientState(GL_VERTEX_ARRAY);
1195 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1196 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1198 #if defined(__WIN32__)
1199 if(glBlendFuncSeparate)
1200 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1202 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1204 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1208 glMatrixMode(MatrixMode::modelView);
1209 glLoadIdentity(); // For setting up GLES stack
1210 glScaled(1.0, 1.0, -1.0);
1211 // glTranslatef(0.375f, 0.375f, 0.0f);
1212 // glTranslatef(-0.625f, -0.625f, 0.0f);
1213 glMatrixMode(MatrixMode::projection);
1214 #if !defined(EM_MODE) && !defined(SHADERS)
1215 glShadeModel(GL_FLAT);
1217 // #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1219 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1220 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1221 glFogi(GL_FOG_MODE, GL_EXP);
1222 glFogf(GL_FOG_DENSITY, 0);
1223 glEnable(GL_NORMALIZE);
1225 glDepthFunc(GL_LESS);
1227 glDisable(GL_MULTISAMPLE_ARB);
1229 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1230 display.ambient = Color { 50,50,50 };
1233 if(!useSingleGLContext)
1235 #if defined(__WIN32__)
1236 wglMakeCurrent(null, null);
1237 #elif defined(__unix__) || defined(__APPLE__)
1238 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1241 glXMakeCurrent(xGlobalDisplay, None, null);
1247 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1255 bool DisplaySize(Display display, int width, int height)
1257 OGLDisplay oglDisplay = display.driverData;
1259 bool result = false;
1261 //printf("Inside DisplaySize\n");
1262 #if defined(__WIN32__) || defined(USEPBUFFER)
1263 OGLSystem oglSystem = display.displaySystem.driverData;
1264 if(display.alphaBlend)
1266 #if defined(__WIN32__)
1267 const int attributes[]=
1269 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1270 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1272 int pixelFormat = 0;
1273 if(wglChoosePixelFormatARB)
1277 float fAttributes[] = {0,0};
1280 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1281 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1282 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1283 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1284 WGL_COLOR_BITS_ARB,24,
1285 WGL_ALPHA_BITS_ARB,8,
1286 WGL_DEPTH_BITS_ARB,16,
1287 WGL_STENCIL_BITS_ARB,0,
1288 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1289 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1290 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1294 //Log("Found wglChoosePixelFormatARB\n");
1296 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1297 if(!valid || !numFormats)
1299 //Log("Can't find 4x multi sampling\n");
1300 iAttributes[19] = 2;
1301 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1302 if(!valid || !numFormats)
1304 // Log("Can't find 2x multi sampling\n");
1305 iAttributes[16] = 0;
1306 iAttributes[17] = 0;
1307 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1308 if(!valid || !numFormats)
1312 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1313 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1314 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1315 WGL_COLOR_BITS_ARB,24,
1316 WGL_ALPHA_BITS_ARB,8,
1317 WGL_DEPTH_BITS_ARB,16,
1320 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1324 if(valid && numFormats)
1326 wglMakeCurrent(null, null);
1330 wglMakeCurrent( null, null );
1331 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1332 if(oglDisplay.hdc && oglDisplay.pBuffer)
1333 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1335 wglDestroyPbufferARB(oglDisplay.pBuffer);
1337 if(!useSingleGLContext)
1338 wglMakeCurrent( null, null );
1341 wglDeleteContext(oglDisplay.glrc);
1343 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1344 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1345 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
1348 HDC hdc = GetDC(display.window);
1350 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1351 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1353 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1354 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1356 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1358 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1362 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1363 oglDisplay.memDC = CreateCompatibleDC(hdc);
1364 SetMapMode(oglDisplay.memDC, MM_TEXT);
1365 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1366 info->bmiHeader.biPlanes = 1;
1367 info->bmiHeader.biCompression = BI_RGB;
1368 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1369 info->bmiHeader.biWidth = width;
1370 info->bmiHeader.biHeight = height;
1371 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1374 SelectObject(oglDisplay.memDC, newBitmap);
1375 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1378 PIXELFORMATDESCRIPTOR pfd = { 0 };
1379 pfd.nSize = (short)sizeof(pfd);
1381 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1382 pfd.iPixelType = PFD_TYPE_RGBA;
1383 pfd.cColorBits = 32;
1384 //pfd.cAlphaBits = 8;
1385 pfd.cDepthBits = 24;
1386 pfd.iLayerType = PFD_MAIN_PLANE;
1388 oglDisplay.hdc = oglDisplay.memDC;
1390 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1391 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1392 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1394 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1395 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1396 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1401 const int imageSize = width * height * 4;
1403 glGenBuffersARB(2, oglDisplay.imageBuffers);
1405 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1406 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1407 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1408 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1411 oglDisplay.memBitmap = newBitmap;
1412 oglDisplay.stride = width;
1418 ReleaseDC(display.window, hdc);
1420 #elif defined(__unix__) || defined(__APPLE__)
1421 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1426 GLX_DOUBLEBUFFER, True,
1432 GLX_STENCIL_SIZE, 1,
1433 //GLX_DEPTH_SIZE, 24,
1434 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1435 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1441 GLX_PBUFFER_WIDTH, width,
1442 GLX_PBUFFER_HEIGHT, height,
1443 GLX_LARGEST_PBUFFER, False,
1447 // choose a pixel format that meets our minimum requirements
1450 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1453 if(oglDisplay.pixmap)
1455 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1456 oglDisplay.pixmap = None;
1458 if(oglDisplay.shapePixmap)
1460 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1461 oglDisplay.shapePixmap = None;
1464 // Free Shared Memory Pixmap
1465 if(oglDisplay.image)
1467 if(oglDisplay.shminfoShape.shmid != -1)
1469 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1470 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1471 shmdt(oglDisplay.shminfo.shmaddr);
1472 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1474 XDestroyImage(oglDisplay.image);
1475 oglDisplay.image = None;
1477 if(oglDisplay.shapeImage)
1479 if(oglDisplay.shminfoShape.shmid != -1)
1481 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1482 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1483 shmdt(oglDisplay.shminfoShape.shmaddr);
1484 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1486 XDestroyImage(oglDisplay.shapeImage);
1487 oglDisplay.shapeImage = None;
1490 if(oglDisplay.windowPicture)
1491 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1492 if(oglDisplay.pixmapPicture)
1493 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1495 if(oglDisplay.pixmap)
1496 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1498 if(oglDisplay.glContext)
1499 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1500 if(oglDisplay.pBuffer)
1501 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1503 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1504 if(oglDisplay.pBuffer)
1506 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1507 if(oglDisplay.glContext)
1509 glXMakeCurrent(xGlobalDisplay, None, null);
1510 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1512 // Initialize Shared Memory Pixmap
1513 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1514 ZPixmap, null, &oglDisplay.shminfo, width, height);
1515 if(oglDisplay.image)
1517 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1518 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1519 if(oglDisplay.shminfo.shmid != -1)
1521 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1522 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1524 oglDisplay.shminfo.readOnly = False;
1525 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1527 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1528 &oglDisplay.shminfo, width, height, 32);
1530 // Initialize Shared Memory Shape Pixmap
1531 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1532 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1533 if(oglDisplay.shapeImage)
1535 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1536 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1537 if(oglDisplay.shminfoShape.shmid != -1)
1539 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1540 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1542 oglDisplay.shminfoShape.readOnly = False;
1543 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1545 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1546 &oglDisplay.shminfoShape, width, height, 1);
1547 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1550 XRenderPictureAttributes attributes = { 0 };
1551 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1552 #if !defined(__APPLE__)
1553 attributes.repeat = RepeatNormal;
1555 attributes.repeat = 1;
1557 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1558 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1559 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1560 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1563 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1564 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1581 CreateDisplay(display);
1582 #if defined(__WIN32__)
1583 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1584 #elif defined(__unix__) || defined(__APPLE__)
1585 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1589 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1596 if(!result && display.alphaBlend)
1598 printf("Alpha blending windows not supported on this display\n");
1605 glViewport(0,0,width,height);
1606 glMatrixMode(MatrixMode::projection);
1608 glOrtho(0,width,height,0,0.0,1.0);
1609 displayWidth = display.width = width;
1610 displayHeight = display.height = height;
1612 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1614 oglDisplay.flipBufW = width;
1615 oglDisplay.flipBufH = height;
1619 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1622 if(oglDisplay.flippingBuffer || !width || !height)
1628 void DisplayPosition(Display display, int x, int y)
1630 OGLDisplay oglDisplay = display.driverData;
1636 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1640 void RestorePalette(Display display)
1644 void StartUpdate(Display display)
1648 void EndUpdate(Display display)
1652 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1656 void Update(Display display, Box updateBox)
1658 #if defined(__WIN32__) || defined(USEPBUFFER)
1659 OGLDisplay oglDisplay = display.driverData;
1661 //Logf("DisplayScreen\n");
1663 #if !defined(__ANDROID__)
1668 #if defined(__WIN32__) || defined(USEPBUFFER)
1669 if(display.alphaBlend)
1671 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1672 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1673 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1674 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1675 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1678 #if defined(__WIN32__)
1680 POINT point = { oglDisplay.x, oglDisplay.y};
1681 POINT srcPoint = { 0, 0 };
1682 BLENDFUNCTION blend = { 0 };
1684 size.cx = display.width;
1685 size.cy = display.height;
1686 blend.BlendOp = AC_SRC_OVER;
1687 blend.BlendFlags = 0;
1688 blend.SourceConstantAlpha = 255;
1689 blend.AlphaFormat = AC_SRC_ALPHA;
1692 // Process partial images. Mapping the buffer waits for
1693 // outstanding DMA transfers into the buffer to finish.
1694 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1695 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1697 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1698 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1701 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1702 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1705 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1708 // Unmap the image buffers
1709 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1710 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1712 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1713 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1715 // Bind two different buffer objects and start the glReadPixels
1716 // asynchronously. Each call will return directly after
1717 // starting the DMA transfer.
1718 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1719 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1721 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1722 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1726 #elif defined(__unix__) || defined(__APPLE__)
1727 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1729 XTransform transform =
1732 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1733 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1734 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1737 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1738 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1739 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1740 #if !defined(__APPLE__)
1741 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1743 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1745 XFlush(xGlobalDisplay);
1753 #if defined(__WIN32__)
1754 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1755 SwapBuffers(oglDisplay.hdc);
1756 #elif defined(__unix__) || defined(__APPLE__)
1757 #if defined(__ANDROID__) || defined(__ODROID__)
1759 #elif defined(__EMSCRIPTEN__)
1762 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1766 //Logf("Out of DisplayScreen\n");
1769 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1771 if(bitmap.driverData)
1773 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1774 glDeleteTextures(1, &tex);
1775 bitmap.driverData = 0;
1777 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1780 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1782 OGLSystem oglSystem = displaySystem.driverData;
1783 bool result = false;
1785 GLuint glBitmap = 0;
1787 uint w = width, h = height;
1788 if(oglSystem.pow2textures)
1793 w = Min(w, oglSystem.maxTextureSize);
1794 h = Min(h, oglSystem.maxTextureSize);
1796 glGenTextures(1, &glBitmap);
1797 glBindTexture(GL_TEXTURE_2D, glBitmap);
1799 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1801 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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_TO_EDGE);
1805 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1807 #if !defined(SHADERS)
1808 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1811 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
1813 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1814 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1818 bitmap.driverData = (void *)(uintptr)glBitmap;
1819 bitmap.driver = displaySystem.driver;
1827 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
1829 bool result = false;
1830 OGLSystem oglSystem = displaySystem.driverData;
1831 Bitmap convBitmap = bitmap;
1835 convBitmap.Copy(bitmap);
1838 // Pre process the bitmap... First make it 32 bit
1839 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
1842 uint w = bitmap.width, h = bitmap.height;
1843 GLuint glBitmap = 0;
1844 if(oglSystem.pow2textures)
1849 w = Min(w, oglSystem.maxTextureSize);
1850 h = Min(h, oglSystem.maxTextureSize);
1854 while(w * 2 < h) w *= 2;
1855 while(h * 2 < w) h *= 2;
1858 // Switch ARGB to RGBA
1859 //if(bitmap.format != pixelFormatRGBA)
1861 for(c=0; c<bitmap.size; c++)
1863 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
1865 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
1866 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
1869 // convBitmap.pixelFormat = pixelFormat888;
1872 glGenTextures(1, &glBitmap);
1875 //int error = glGetError();
1879 glBindTexture(GL_TEXTURE_2D, glBitmap);
1880 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1882 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
1883 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1885 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1887 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1888 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1890 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1891 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1892 #if !defined(__ANDROID__) && !defined(SHADERS)
1893 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
1896 #if !defined(SHADERS)
1897 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1902 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
1907 if(bitmap.width != w || bitmap.height != h)
1909 mipMap = Bitmap { };
1910 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
1912 Surface mipSurface = mipMap.GetSurface(0,0,null);
1913 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
1923 mipMap = convBitmap;
1930 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1931 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
1932 //printf("Calling glTexImage2D\n");
1933 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
1934 //printf("width = %d (Should be %d, %d)\n", width, w, h);
1935 if((error = glGetError()))
1937 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
1938 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
1942 if(mipMap != convBitmap)
1947 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
1948 bitmap.driverData = (void *)(uintptr)glBitmap;
1949 bitmap.driver = displaySystem.driver;
1954 FreeBitmap(displaySystem, bitmap);
1955 else if(oglSystem.loadingFont)
1957 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1958 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1959 oglSystem.loadingFont = false;
1965 void ReleaseSurface(Display display, Surface surface)
1967 glDisable(GL_SCISSOR_TEST);
1968 delete surface.driverData;
1969 surface.driverData = null;
1972 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
1977 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
1979 bool result = false;
1980 OGLSurface oglSurface = surface.driverData = OGLSurface { };
1982 //Logf("GetSurface\n");
1986 if(displayWidth != display.width || displayHeight != display.height)
1988 displayWidth = display.width;
1989 displayHeight = display.height;
1991 glViewport(0,0,display.width,display.height);
1993 glOrtho(0,display.width,display.height,0,0.0,1.0);
1996 surface.offset.x = x;
1997 surface.offset.y = y;
1998 surface.unclippedBox = surface.box = clip;
1999 oglSurface.bitmapMult[0] = 1;
2000 oglSurface.bitmapMult[1] = 1;
2001 oglSurface.bitmapMult[2] = 1;
2002 oglSurface.bitmapMult[3] = 1;
2004 glEnable(GL_SCISSOR_TEST);
2007 (display.height) -(y+clip.bottom)-1,
2008 clip.right-clip.left+1,
2009 clip.bottom-clip.top+1);
2015 void Clip(Display display, Surface surface, Box clip)
2024 box.Clip(surface.unclippedBox);
2028 box = surface.box = surface.unclippedBox;
2029 box.left += surface.offset.x;
2030 box.top += surface.offset.y;
2031 box.right+= surface.offset.x;
2032 box.bottom += surface.offset.y;
2035 box.left,display.height - box.bottom - 1,
2036 box.right-box.left+1, box.bottom-box.top+1);
2039 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2041 bool result = false;
2042 OGLDisplay oglDisplay = display.driverData;
2043 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2045 if(oglDisplay.flippingBuffer)
2047 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2050 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2056 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2057 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2058 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2059 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2060 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2063 for(row = 0; row<h; row++)
2064 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2071 void SetForeground(Display display, Surface surface, ColorAlpha color)
2073 OGLSurface oglSurface = surface.driverData;
2075 //Logf("SetForeground\n");
2077 oglSurface.foreground[0] = color.color.r/255.0f;
2078 oglSurface.foreground[1] = color.color.g/255.0f;
2079 oglSurface.foreground[2] = color.color.b/255.0f;
2080 //oglSurface.foreground[3] = 1.0f;
2081 oglSurface.foreground[3] = color.a/255.0f;
2083 //if(!oglSurface.foreground[3])printf("bug");
2086 void SetBackground(Display display, Surface surface, ColorAlpha color)
2088 OGLSurface oglSurface = surface.driverData;
2090 //Logf("SetBackground\n");
2092 oglSurface.background[0] = color.color.r/255.0f;
2093 oglSurface.background[1] = color.color.g/255.0f;
2094 oglSurface.background[2] = color.color.b/255.0f;
2095 //oglSurface.background[3] = 1.0;
2096 oglSurface.background[3] = color.a/255.0f;
2099 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2101 OGLSurface oglSurface = surface.driverData;
2103 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2104 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2105 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2106 oglSurface.bitmapMult[3] = color.a/255.0f;
2109 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2114 void PutPixel(Display display, Surface surface,int x,int y)
2116 OGLSurface oglSurface = surface.driverData;
2118 //Logf("PutPixel\n");
2120 glColor4fv(oglSurface.foreground);
2122 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2123 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2128 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2130 OGLSurface oglSurface = surface.driverData;
2131 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2146 x1 += surface.offset.x;
2147 y1 += surface.offset.y;
2148 x2 += surface.offset.x;
2149 y2 += surface.offset.y;
2153 glColor4fv(oglSurface.foreground);
2155 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2158 glTexCoord2f(0.5f, 0);
2159 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2160 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2161 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2170 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2171 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2177 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2179 OGLSurface oglSurface = surface.driverData;
2180 x1 += surface.offset.x;
2181 y1 += surface.offset.y;
2182 x2 += surface.offset.x;
2183 y2 += surface.offset.y;
2185 //Logf("Rectangle\n");
2187 glColor4fv(oglSurface.foreground);
2188 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2193 glTexCoord2f(0.5f, 0);
2194 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2195 glTexCoord2f(y2-y1 + 0.5f, 0);
2196 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2198 glTexCoord2f(0.5f, 0);
2199 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2200 glTexCoord2f(x2 - x1 + 0.5f, 0);
2201 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2203 glTexCoord2f(0.5f, 0);
2204 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2205 glTexCoord2f(y1 - y2 + 0.5f, 0);
2206 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2208 glTexCoord2f(0.5f, 0);
2209 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2210 glTexCoord2f(x1 - x2 + 0.5f, 0);
2211 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2216 glBegin(GL_LINE_LOOP);
2223 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2224 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2225 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2226 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2231 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2233 OGLSurface oglSurface = surface.driverData;
2236 glColor4fv(oglSurface.background);
2240 glVertex2f(x1+surface.offset.x, y1+surface.offset.y);
2241 glVertex2f(x1+surface.offset.x, y2+surface.offset.y+1);
2242 glVertex2f(x2+surface.offset.x+1, y2+surface.offset.y+1);
2243 glVertex2f(x2+surface.offset.x+1, y1+surface.offset.y);
2246 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2247 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2250 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2251 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2255 void Clear(Display display, Surface surface, ClearType type)
2257 OGLDisplay oglDisplay = display.driverData;
2258 OGLSurface oglSurface = surface.driverData;
2261 if(type != depthBuffer)
2262 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2263 if(type != colorBuffer && !oglDisplay.depthWrite)
2265 glDepthMask((byte)bool::true);
2267 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2268 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2269 if(type != colorBuffer && !oglDisplay.depthWrite)
2271 glDepthMask((byte)bool::false);
2275 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2280 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2282 OGLSurface oglSurface = surface.driverData;
2284 if(!oglSurface.writingText)
2286 // glTranslatef(-0.375f, -0.375f, 0.0f);
2287 GLSetupTexturing(true);
2288 glColor4fv(oglSurface.bitmapMult);
2290 else if(oglSurface.xOffset)
2291 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2293 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2294 glBegin(GLIMTKMode::quads);
2298 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2299 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2300 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2301 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2302 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2303 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2304 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2305 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2310 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2311 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2312 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2313 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2314 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2315 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2316 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2317 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2320 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2321 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2322 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2323 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2324 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2325 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2326 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2327 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2331 if(!oglSurface.writingText)
2333 GLSetupTexturing(false);
2335 //glTranslate(0.375, 0.375, 0.0);
2337 else if(oglSurface.xOffset)
2338 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2341 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2343 OGLSurface oglSurface = surface.driverData;
2345 //glTranslate(-0.375, -0.375, 0.0);
2347 GLSetupTexturing(true);
2348 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2350 glColor4fv(oglSurface.bitmapMult);
2352 glBegin(GLIMTKMode::quads);
2356 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2357 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2359 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2360 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2362 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2363 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2365 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2366 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2370 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2371 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2373 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2374 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2376 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2377 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2379 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2380 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2385 GLSetupTexturing(false);
2387 //glTranslate(0.375, 0.375, 0.0);
2390 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2392 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2395 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2397 #if !defined(EM_MODE)
2398 float s2dw,s2dh,d2sw,d2sh;
2399 //bool flipX = false, flipY = false;
2401 //Logf("StretchDI\n");
2403 if(Sgn(w) != Sgn(sw))
2409 if(Sgn(h) != Sgn(sh))
2421 //Clip against the edges of the source
2424 dx+=(int)((0-sx) * s2dw);
2425 w-=(int)((0-sx) * s2dw);
2431 dy+=(int)((0-sy) * s2dh);
2432 h-=(int)((0-sy) * s2dh);
2437 if(sx+sw>bitmap.width-1)
2439 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2440 sw-=sx+sw-(bitmap.width-1)-1;
2442 if(sy+sh>(bitmap.height-1))
2444 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2445 sh-=sy+sh-(bitmap.height-1)-1;
2447 //Clip against the edges of the surfaceination
2448 if(dx<surface.box.left)
2451 sx+=(int)((surface.box.left-dx)*d2sw);
2452 sw-=(int)((surface.box.left-dx)*d2sw);
2453 w-=surface.box.left-dx;
2454 dx=surface.box.left;
2456 if(dy<surface.box.top)
2458 sy+=(int)((surface.box.top-dy)*d2sh);
2459 sh-=(int)((surface.box.top-dy)*d2sh);
2460 h-=surface.box.top-dy;
2463 if(dx+w>surface.box.right)
2465 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2466 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2467 w-=dx+w-surface.box.right-1;
2469 if(dy+h>surface.box.bottom)
2471 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2472 h-=dy+h-surface.box.bottom-1;
2474 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2476 dx += surface.offset.x;
2477 dy += surface.offset.y;
2479 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2481 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2482 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2483 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2484 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2485 #if !defined(SHADERS)
2486 glRasterPos2d(dx,dy);
2487 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2488 glPixelZoom(s2dw, -s2dh);
2489 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2491 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2492 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2493 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2494 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2499 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2501 #if !defined(EM_MODE)
2504 //Clip against the edges of the source
2517 if(sx+w>bitmap.width-1)
2518 w-=sx+w-(bitmap.width-1)-1;
2519 if(sy+h>bitmap.height-1)
2520 h-=sy+h-(bitmap.height-1)-1;
2521 //Clip against the edges of the surfaceination
2522 if(dx<surface.box.left)
2525 sx+=surface.box.left-dx;
2526 w-=surface.box.left-dx;
2527 dx=surface.box.left;
2529 if(dy<surface.box.top)
2531 sy+=surface.box.top-dy;
2532 h-=surface.box.top-dy;
2535 if(dx+w>surface.box.right)
2537 //if(flip) sx+=dx+w-surface.box.right-1;
2538 w-=dx+w-surface.box.right-1;
2540 if(dy+h>surface.box.bottom)
2541 h-=dy+h-surface.box.bottom-1;
2545 dx += surface.offset.x;
2546 dy += surface.offset.y;
2548 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2550 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2551 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2552 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2553 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2554 #if !defined(SHADERS)
2555 glRasterPos2d(dx,dy);
2557 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2559 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2560 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2561 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2562 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2567 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2569 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2572 void UnloadFont(DisplaySystem displaySystem, Font font)
2574 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2577 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
2580 OGLSystem oglSystem = displaySystem.driverData;
2581 oglSystem.loadingFont = true;
2582 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
2586 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
2588 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
2591 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
2593 OGLSurface oglSurface = surface.driverData;
2594 OGLSystem oglSystem = display.displaySystem.driverData;
2595 oglSystem.loadingFont = true;
2597 //glTranslated(-0.375, -0.375, 0.0);
2601 if(surface.textOpacity)
2604 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
2605 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2608 oglSurface.writingText = true;
2610 GLSetupTexturing(true);
2612 if(surface.outline.size)
2614 ColorAlpha outlineColor = surface.outline.color;
2615 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2616 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2617 //glEnable(GL_BLEND);
2619 oglSurface.writingOutline = true;
2620 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
2621 oglSurface.writingOutline = false;
2623 glColor4fv(oglSurface.foreground);
2625 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
2626 oglSurface.writingText = false;
2627 oglSystem.loadingFont = false;
2629 GLSetupTexturing(false);
2631 //glTranslated(0.375, 0.375, 0.0);
2634 void TextFont(Display display, Surface surface, Font font)
2636 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2639 void TextOpacity(Display display, Surface surface, bool opaque)
2641 OGLSurface oglSurface = surface.driverData;
2642 oglSurface.opaqueText = opaque;
2645 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
2647 OGLSurface oglSurface = surface.driverData;
2648 OGLSystem oglSystem = display.displaySystem.driverData;
2649 oglSystem.loadingFont = true;
2650 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height);
2651 oglSystem.loadingFont = false;
2654 void DrawingChar(Display display, Surface surface, char character)
2659 void LineStipple(Display display, Surface surface, uint32 stipple)
2661 //Logf("Stipple\n");
2665 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2666 stippleEnabled = true;
2667 glesLineStipple(1, (uint16)stipple);
2669 glLineStipple(1, (uint16)stipple);
2670 glEnable(GL_LINE_STIPPLE);
2675 #if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
2676 stippleEnabled = false;
2677 glMatrixMode(GL_TEXTURE);
2679 glMatrixMode(MatrixMode::projection);
2680 GLSetupTexturing(false); // TODO: Special shading code for stipple?
2682 glDisable(GL_LINE_STIPPLE);
2686 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2687 void SetRenderState(Display display, RenderState state, uint value)
2689 OGLDisplay oglDisplay = display.driverData;
2690 //Logf("RenderState\n");
2696 glEnable(GL_MULTISAMPLE_ARB);
2698 glDisable(GL_MULTISAMPLE_ARB);
2702 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2706 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2709 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2710 oglDisplay.depthWrite = (bool)value;
2714 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2715 #if defined(SHADERS)
2716 shader_fogColor(color[0], color[1], color[2]);
2718 glFogfv(GL_FOG_COLOR, (float *)&color);
2723 #if defined(SHADERS)
2724 shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
2726 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
2730 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
2734 #if defined(SHADERS)
2735 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
2736 #elif !defined(EM_MODE)
2737 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2738 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
2744 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
2749 #if defined(__WIN32__)
2750 wglSwapIntervalEXT(value ? 1 : 0);
2757 void SetLight(Display display, int id, Light light)
2759 #if defined(SHADERS)
2760 shader_setLight(display, id, light);
2761 #elif !defined(EM_MODE)
2762 //Logf("SetLight\n");
2766 Object lightObject = light.lightObject;
2767 float position[4] = { 0, 0, 0, 0 };
2768 float color[4] = { 0, 0, 0, 1 };
2770 glEnable(GL_LIGHT0 + id);
2772 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
2773 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
2774 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
2777 if(!light.multiplier) light.multiplier = 1.0f;
2779 color[0] = light.diffuse.r * light.multiplier;
2780 color[1] = light.diffuse.g * light.multiplier;
2781 color[2] = light.diffuse.b * light.multiplier;
2782 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
2784 color[0] = light.ambient.r * light.multiplier;
2785 color[1] = light.ambient.g * light.multiplier;
2786 color[2] = light.ambient.b * light.multiplier;
2787 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
2788 color[0] = light.specular.r * light.multiplier;
2789 color[1] = light.specular.g * light.multiplier;
2790 color[2] = light.specular.b * light.multiplier;
2791 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
2795 Vector3D positionVector;
2796 if(light.flags.spot)
2798 if(lightObject.flags.root || !lightObject.parent)
2800 positionVector = lightObject.transform.position;
2801 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2805 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
2806 if(display.display3D.camera)
2807 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
2813 if(!light.direction.x && !light.direction.y && !light.direction.z)
2815 Vector3Df vector { 0,0,-1 };
2817 mat.RotationQuaternion(light.orientation);
2818 positionVector.MultMatrixf(vector, mat);
2822 positionVector = light.direction;
2827 position[0] = (float)positionVector.x;
2828 position[1] = (float)positionVector.y;
2829 position[2] = (float)positionVector.z;
2831 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2834 // Display Light Position
2835 glDisable(GL_LIGHTING);
2836 glDisable(GL_DEPTH_TEST);
2840 glVertex3fv(position);
2842 glEnable(GL_DEPTH_TEST);
2843 glEnable(GL_LIGHTING);
2847 if(lightObject.flags.root || !lightObject.parent)
2849 positionVector = light.target.transform.position;
2850 positionVector.Subtract(positionVector, display.camera.cPosition);
2854 positionVector.MultMatrix(light.target.transform.position,
2855 lightObject.light.target.parent.matrix);
2856 positionVector.Subtract(positionVector, display.camera.cPosition);
2859 position[0] = positionVector.x;
2860 position[1] = positionVector.y;
2861 position[2] = positionVector.z;
2863 glDisable(GL_LIGHTING);
2864 glDisable(GL_DEPTH_TEST);
2868 glVertex3fv(position);
2870 glEnable(GL_DEPTH_TEST);
2871 glEnable(GL_LIGHTING);
2874 if(light.flags.attenuation)
2876 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
2877 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
2878 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
2881 if(light.flags.spot)
2884 #define MAXLIGHT 0.9
2885 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
2886 // Figure out exponent out of the hot spot
2887 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
2889 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
2890 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
2891 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
2896 Vector3Df vector { 0,0,-1 };
2897 Vector3Df direction;
2900 mat.RotationQuaternion(light.orientation);
2901 direction.MultMatrix(vector, mat);
2903 position[0] = direction.x;
2904 position[1] = direction.y;
2905 position[2] = direction.z;
2907 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
2911 glDisable(GL_LIGHT0 + id);
2915 void SetCamera(Display display, Surface surface, Camera camera)
2917 OGLDisplay oglDisplay = display.driverData;
2918 //Logf("SetCamera\n");
2920 if(surface && camera)
2922 int left = surface.box.left + surface.offset.x;
2923 int top = surface.box.top + surface.offset.y;
2924 int right = surface.box.right + surface.offset.x;
2925 int bottom = surface.box.bottom + surface.offset.y;
2926 float origX = surface.offset.x + camera.origin.x;
2927 float origY = surface.offset.y + camera.origin.y;
2929 int y = display.height - bottom - 1;
2930 int w = right - left + 1;
2931 int h = bottom - top + 1;
2934 glViewport(x, y, w, h);
2936 // *** Projection Matrix ***
2937 glMatrixMode(MatrixMode::projection);
2938 if(!display.display3D.camera)
2941 if(display.display3D.collectingHits)
2943 float pickX = display.display3D.pickX + surface.offset.x;
2944 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
2948 w / display.display3D.pickWidth, 0, 0, 0,
2949 0, h / display.display3D.pickHeight, 0, 0,
2951 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
2952 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
2955 glLoadMatrixd(pickMatrix.array);
2960 (left - origX) * camera.zMin / camera.focalX,
2961 (right - origX) * camera.zMin / camera.focalX,
2962 (bottom - origY) * camera.zMin / camera.focalY,
2963 (top - origY) * camera.zMin / camera.focalY,
2964 camera.zMin, camera.zMax);
2966 glDisable(GL_BLEND);
2968 // *** Z Inverted Identity Matrix ***
2969 glMatrixMode(MatrixMode::modelView);
2970 if(!display.display3D.camera)
2975 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
2977 // *** View Matrix ***
2978 glMultMatrixd(camera.viewMatrix.array);
2983 glEnable(GL_DEPTH_TEST);
2985 GLSetupLighting(true);
2986 #if !defined(EM_MODE) && !defined(SHADERS)
2987 glShadeModel(GL_SMOOTH);
2989 glDepthMask((byte)bool::true);
2990 oglDisplay.depthWrite = true;
2992 glEnable(GL_MULTISAMPLE_ARB);
2994 else if(surface && display.display3D.camera)
2997 oglDisplay.depthWrite = false;
2998 glViewport(0,0,display.width,display.height);
3000 glDisable(GL_CULL_FACE);
3001 glDisable(GL_DEPTH_TEST);
3003 GLSetupTexturing(false);
3004 GLSetupLighting(false);
3007 glDisableClientState(GL_COLOR_ARRAY);
3009 #if !defined(SHADERS) && !defined(EM_MODE)
3010 glShadeModel(GL_FLAT);
3013 glDisable(GL_MULTISAMPLE_ARB);
3015 // *** Restore 2D MODELVIEW Matrix ***
3018 // *** Restore 2D PROJECTION Matrix ***
3019 glMatrixMode(MatrixMode::projection);
3025 void ApplyMaterial(Display display, Material material, Mesh mesh)
3027 //Logf("ApplyMaterial\n");
3030 if(material.flags.doubleSided)
3032 #if !defined(EM_MODE) && !defined(SHADERS)
3033 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3035 glDisable(GL_CULL_FACE);
3039 #if !defined(EM_MODE) && !defined(SHADERS)
3040 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3042 glEnable(GL_CULL_FACE);
3046 GLSetupFog(!material.flags.noFog);
3049 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3051 Bitmap map = material.baseMap;
3052 GLSetupTexturing(true);
3053 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3055 glMatrixMode(GL_TEXTURE);
3057 if(material.uScale && material.vScale)
3058 glScalef(material.uScale, material.vScale, 1);
3059 glMatrixMode(MatrixMode::modelView);
3061 if(material.flags.tile)
3063 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3064 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3068 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3069 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3073 GLSetupTexturing(false);
3075 #if defined(SHADERS)
3076 shader_setMaterial(material, mesh.flags.colors);
3077 #elif defined(EM_MODE)
3078 glimtkColor4f(material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity);
3080 if(mesh.flags.colors)
3082 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3083 glEnable(GL_COLOR_MATERIAL);
3087 glDisable(GL_COLOR_MATERIAL);
3089 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3090 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3093 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3094 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3098 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3099 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3102 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3103 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3106 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3110 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3112 OGLMesh oglMesh = mesh.data;
3115 if(!mesh.flags.vertices)
3117 oglMesh.vertices.free();
3118 delete mesh.vertices;
3120 if(!mesh.flags.normals)
3122 oglMesh.normals.free();
3123 delete mesh.normals;
3125 if(!mesh.flags.texCoords1)
3127 oglMesh.texCoords.free();
3128 delete mesh.texCoords;
3130 if(!mesh.flags.texCoords2)
3132 oglMesh.texCoords2.free();
3133 // delete mesh.texCoords2;
3135 if(!mesh.flags.colors)
3137 oglMesh.colors.free();
3148 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3150 bool result = false;
3153 mesh.data = OGLMesh { };
3156 if(mesh.nVertices == nVertices)
3158 // Same number of vertices, adding features (Leaves the other features pointers alone)
3159 if(mesh.flags != flags)
3161 if(!mesh.flags.vertices && flags.vertices)
3163 if(flags.doubleVertices)
3165 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3168 mesh.vertices = new Vector3Df[nVertices];
3170 if(!mesh.flags.normals && flags.normals)
3172 if(flags.doubleNormals)
3174 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3177 mesh.normals = new Vector3Df[nVertices];
3179 if(!mesh.flags.texCoords1 && flags.texCoords1)
3181 mesh.texCoords = new Pointf[nVertices];
3183 if(!mesh.flags.colors && flags.colors)
3185 mesh.colors = new ColorRGBAf[nVertices];
3191 // New number of vertices, reallocate all current and new features
3192 flags |= mesh.flags;
3195 if(flags.doubleVertices)
3197 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3200 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3204 if(flags.doubleNormals)
3206 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3209 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3211 if(flags.texCoords1)
3213 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3217 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3225 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3227 OGLMesh oglMesh = mesh.data;
3228 if(!flags) flags = mesh.flags;
3233 oglMesh.vertices.upload(
3234 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3237 oglMesh.normals.upload(
3238 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3240 if(flags.texCoords1)
3241 oglMesh.texCoords.upload(
3242 mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3245 oglMesh.colors.upload(
3246 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3250 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3257 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3261 oglIndices.buffer.free();
3262 delete oglIndices.indices;
3267 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3269 OGLIndices oglIndices = OGLIndices { };
3272 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3273 oglIndices.nIndices = nIndices;
3278 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3285 if(!oglIndices.buffer.buffer)
3286 glGenBuffers(1, &oglIndices.buffer.buffer);
3287 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3288 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3289 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3293 oglIndices.buffer.upload(
3294 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3295 oglIndices.indices); //GL_STATIC_DRAW_ARB);
3299 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3302 return oglIndices.indices;
3305 void SelectMesh(Display display, Mesh mesh)
3307 //Logf("SelectMesh\n");
3309 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3311 #if defined(__WIN32__)
3312 if(glUnlockArraysEXT)
3314 if(!vboAvailable && display.display3D.mesh)
3315 glUnlockArraysEXT();
3320 OGLMesh oglMesh = mesh.data;
3322 // *** Vertex Stream ***
3323 glEnableClientState(GL_VERTEX_ARRAY);
3324 if(!display.display3D.collectingHits && oglMesh)
3326 oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3328 // *** Normals Stream ***
3329 if(mesh.normals || mesh.flags.normals)
3331 glEnableClientState(GL_NORMAL_ARRAY);
3332 oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3335 glDisableClientState(GL_NORMAL_ARRAY);
3337 // *** Texture Coordinates Stream ***
3338 if(mesh.texCoords || mesh.flags.texCoords1)
3340 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3341 oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3344 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3346 // *** Color Stream ***
3347 if(mesh.colors || mesh.flags.colors)
3349 glEnableClientState(GL_COLOR_ARRAY);
3350 oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3353 glDisableClientState(GL_COLOR_ARRAY);
3357 noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3358 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3360 glEnableClientState(GL_NORMAL_ARRAY);
3361 noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
3364 glDisableClientState(GL_NORMAL_ARRAY);
3365 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3367 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3368 noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3371 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3372 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3374 glEnableClientState(GL_COLOR_ARRAY);
3375 noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
3378 glDisableClientState(GL_COLOR_ARRAY);
3381 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3383 #if defined(__WIN32__)
3387 glLockArraysEXT(0, mesh.nVertices);
3393 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3395 //Logf("DrawPrimitives\n");
3397 if(primitive->type.vertexRange)
3398 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
3401 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
3402 // HACK TO SPEED THINGS UP...
3404 /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
3405 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
3408 glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
3411 OGLIndices oglIndices = primitive->data;
3412 MeshFeatures flags = mesh.flags;
3413 for(c = 0; c<primitive->nIndices; c++)
3415 uint16 index = ((uint16 *) oglIndices.indices)[c];
3416 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
3417 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
3418 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
3419 glVertex3fv((float *)&mesh.vertices[index]);
3428 OGLIndices oglIndices = primitive->data;
3429 GLEAB eab = ((!display.display3D.collectingHits && oglIndices) ? oglIndices.buffer : noEAB);
3431 eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
3432 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3433 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3434 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3439 void PushMatrix(Display display)
3444 void PopMatrix(Display display, bool setMatrix)
3449 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3451 Matrix matrix = transMatrix;
3452 Camera camera = useCamera ? display.display3D.camera : null;
3457 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3462 matrix.m[3][0] - camera.cPosition.x,
3463 matrix.m[3][1] - camera.cPosition.y,
3464 matrix.m[3][2] - camera.cPosition.z);
3476 glMultMatrixd(matrix.array);
3481 public void UseSingleGLContext(bool useSingle)
3483 useSingleGLContext = useSingle;
3486 default dllexport void *
3487 #if defined(__WIN32__)
3488 __attribute__((stdcall))
3490 IS_GLGetContext(DisplaySystem displaySystem)
3494 #if defined(__WIN32__)
3495 OGLSystem system = displaySystem.driverData;
3497 #elif defined(__ANDROID__) || defined(__ODROID__)
3499 #elif defined(__EMSCRIPTEN__)
3501 OGLSystem system = displaySystem.driverData;
3502 return system.glContext;