3 namespace gfx::drivers;
5 #if defined(__ANDROID__)
6 #include <android/native_activity.h>
9 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
10 # include "gl_compat_4_4.h"
13 #if defined(__ANDROID__) || defined(__ODROID__)
22 #define GL_BGRA_EXT 0x80E1
24 #if defined(__ANDROID__)
25 #include <android/log.h>
26 #define printf(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "ecere-app", __VA_ARGS__))
32 while((e = glGetError()) && nCount++ < 10)
33 printf("GL error %d!\n", e);
36 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
38 #if defined(__unix__) || defined(__APPLE__)
40 #if !defined(__MINGW32__)
41 #define GL_GLEXT_PROTOTYPES
44 #define pointer _pointer
47 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
49 #define property _property
53 #define Window X11Window
54 #define Cursor X11Cursor
56 #define Display X11Display
58 #define KeyCode X11KeyCode
59 #define Picture X11Picture
60 #define Glyph X11Glyph
64 #include <X11/Xutil.h>
66 #include <X11/extensions/XShm.h>
69 #include <X11/extensions/Xrender.h>
70 #include <X11/extensions/shape.h>
89 #if defined(__APPLE__)
90 #include <OpenGl/gl.h>
93 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
95 #if defined(__WIN32__)
96 //#define WIN32_LEAN_AND_MEAN
98 #define _WIN32_WINNT 0x0502
104 #if defined(__ANDROID__) || defined(__ODROID__)
110 #define property _property
113 #define Window X11Window
114 #define Cursor X11Cursor
116 #define Display X11Display
118 #define KeyCode X11KeyCode
119 #define Picture X11Picture
123 #include <GLES/glext.h>
138 #elif defined(__EMSCRIPTEN__)
144 #define property _property
147 #include <GLES2/gl2.h>
149 #include <emscripten/emscripten.h>
150 #include <emscripten/html5.h>
163 #if defined(__unix__) || defined(__APPLE__)
165 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
171 /* OpenGL Versions Features Quick Reference
173 | OpenGL 1.1 | OpenGL 1.5 | GL ES 1.1 | OpenGL 2 | GL 3 (Compat) | GL 3 (Core) | GL ES 2 | WebGL 1 | GL ES 3 | WebGL 2
174 =======================================================================================================================================================================
175 glBegin() | X | X | - | X | X | - | - | - | - | -
176 glLoadMatrix() | X | X | - | X | X | - | - | - | - | -
177 glLineWidth() | X | X | - | X | X | - | - | - | - | -
178 glPointSize() | X | X | - | X | X | - | - | - | - | -
179 glLineStipple() | X | X | - | X | X | - | - | - | - | -
180 glPolygonStipple() | X | X | - | X | X | - | - | - | - | -
181 glColorMaterial() | X | X | - | X | X | - | - | - | - | -
182 GL_QUADS | X | X | - | X | X | - | - | - | - | -
183 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
184 GL_INT / GL_DOUBLE | X | X | - | X | X | X | - | - | - | -
185 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
186 GL_SELECT | X | X | - | (Slow) | (Slow) | (Slow) | - | - | - | -
187 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
188 Non ² Textures | - | - | - | X | X | X | - | - | - | -
189 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
190 glVertexPointer() (PTR) | X | X | X | X | X | - | - | - | - | -
191 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
192 glVertexPointer() (VBO) | - | X | X | X | X | - | - | - | - | -
193 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
194 glBufferData() | - | X | X | X | X | X | X | X | X | X
195 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
196 glMapBuffer() | - | X | OES x | X | X | X | OES x | - | OES x | -
197 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
198 glBindFramebuffer() | - | - | OES x | - | X | X | X | X | X | X
199 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
200 glVertexAttribPointer() (PTR) | - | - | - | X | X | X | X | - | X | -
201 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
202 glVertexAttribPointer() (VBO) | - | - | - | X | X | X | X | X | X | X
203 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
204 GLSL Version | - | - | - | 1.10 | 1.30 | 1.30 | 1.00 | 1.00 | 3.00 | 3.00
205 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
206 bool legacy :1; // | X | X | - | X | X | - | - | - | - | -
207 bool shaders :1; // | - | - | - | X | X | X | X | X | X | X
208 bool nonPow2Textures :1; // | - | - | - | X | X | X | - | - | - | -
209 bool vertexBuffer :1; // | - | X | X | X | X | X | X | X | X | X
210 bool frameBuffer :1; // | - | - | ~ | - | X | X | X | X | X | X
211 // bool mapBuffer :1; // | - | X | ~ | X | X | X | ~ | - | ~ | -
214 // Compiled In Capabilities
215 #define ENABLE_GL_SHADERS (!defined(_GLES))
216 #define ENABLE_GL_FFP (!defined(_GLES2))
217 #define ENABLE_GL_POINTER (!defined(__EMSCRIPTEN__))
218 #define ENABLE_GL_FBO (!defined(__EMSCRIPTEN__))
219 #define ENABLE_GL_LEGACY (!defined(_GLES) && !defined(_GLES2))
220 #define ENABLE_GL_INTDBL (!defined(_GLES) && !defined(_GLES2))
221 #define ENABLE_GL_MAPBUF (!defined(_GLES) && !defined(_GLES2))
222 #define ENABLE_GL_SELECT (!defined(_GLES) && !defined(_GLES2))
223 #define ENABLE_GL_COLORMAT (ENABLE_GL_FFP && !defined(_GLES))
225 #if ENABLE_GL_SHADERS && ENABLE_GL_FFP
226 #define GLEnableClientState (shaders ? glEnableVertexAttribArray : glEnableClientState)
227 #define GLDisableClientState (shaders ? glDisableVertexAttribArray : glDisableClientState)
228 #define VERTICES (shaders ? GLBufferContents::vertex : GL_VERTEX_ARRAY)
229 #define NORMALS (shaders ? GLBufferContents::normal : GL_NORMAL_ARRAY)
230 #define TEXTURECOORDS (shaders ? GLBufferContents::texCoord : GL_TEXTURE_COORD_ARRAY)
231 #define COLORS (shaders ? GLBufferContents::color : GL_COLOR_ARRAY)
232 #define GLVertexPointer(n, t, s, p) (shaders ? glVertexAttribPointer(GLBufferContents::vertex, n, t, GL_FALSE, s, p) : glVertexPointer(n, t, s, p))
233 #define GLTexCoordPointer(n, t, s, p) (shaders ? glVertexAttribPointer(GLBufferContents::texCoord, n, t, GL_FALSE, s, p) : glTexCoordPointer(n, t, s, p))
234 #elif ENABLE_GL_SHADERS
235 #define GLEnableClientState glEnableVertexAttribArray
236 #define GLDisableClientState glDisableVertexAttribArray
237 #define VERTICES GLBufferContents::vertex
238 #define NORMALS GLBufferContents::normal
239 #define TEXTURECOORDS GLBufferContents::texCoord
240 #define COLORS GLBufferContents::color
241 #define GLVertexPointer(n, t, s, p) glVertexAttribPointer(GLBufferContents::vertex, n, t, GL_FALSE, s, p)
242 #define GLTexCoordPointer(n, t, s, p) glVertexAttribPointer(GLBufferContents::texCoord, n, t, GL_FALSE, s, p)
244 #define GLEnableClientState glEnableClientState
245 #define GLDisableClientState glDisableClientState
246 #define VERTICES GL_VERTEX_ARRAY
247 #define NORMALS GL_NORMAL_ARRAY
248 #define TEXTURECOORDS GL_TEXTURE_COORD_ARRAY
249 #define COLORS GL_COLOR_ARRAY
250 #define GLVertexPointer glVertexPointer
251 #define GLTexCoordPointer glTexCoordPointer
254 #define GL_ARRAY_BUFFER_ARB 0x8892
255 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
256 #define GL_STATIC_DRAW_ARB 0x88E4
257 #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
258 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
260 #define GL_MULTISAMPLE_ARB 0x809D
262 #if defined(__WIN32__)
265 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
266 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
268 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
269 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
271 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
272 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
273 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
274 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
275 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
276 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
277 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
278 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
279 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
280 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = null;
281 static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = null;
283 #elif !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
285 GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
286 GLAPI void APIENTRY glUnlockArraysEXT (void);
294 #if defined(__ANDROID__) || defined(__ODROID__)
295 // Frame Buffer Extensions
296 #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
297 #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
298 #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
299 #define glBindFramebuffer glBindFramebufferOES
300 #define glBindRenderbuffer glBindRenderbufferOES
301 #define glFramebufferTexture2D glFramebufferTexture2DOES
302 #define glGenFramebuffers glGenFramebuffersOES
303 #define glGenRenderbuffers glGenRenderbuffersOES
304 #define glDeleteFramebuffers glDeleteFramebuffersOES
305 #define glDeleteRenderbuffers glDeleteRenderbuffersOES
307 // TOFIX: Grab Screen and BlitDI/StretchDI will have wrong colors
309 #define GL_BGRA_EXT GL_RGBA
312 #if !ENABLE_GL_INTDBL
313 #define GL_INT 0x1404
314 #define GL_UNSIGNED_INT 0x1405
315 #define GL_DOUBLE 0x140A
318 #if ENABLE_GL_STIPPLES
319 #define GLLineStipple (stipples ? glLineStipple : glsupLineStipple)
321 #define GLLineStipple glsupLineStipple
324 #if ENABLE_GL_COLORMAT
325 #define GLColorMaterial(a,b) glColorMaterial(a,b)
327 #define GLColorMaterial(a,b)
331 #define GLLightModeli glsupLightModeli
333 #define GLLightModeli glLightModeli
337 #define GLRecti(x1, y1, x2, y2) (immediate && !shaders ? glRecti(x1, y1, x2, y2) : glimtkRecti(capabilities, x1, y1, x2, y2))
338 #define GLBegin(m) (immediate && !shaders ? glBegin(m) : glimtkBegin(m))
339 #define GLTexCoord2i (immediate && !shaders ? glTexCoord2i : glimtkTexCoord2i)
340 #define GLVertex2i (immediate && !shaders ? glVertex2i : glimtkVertex2i)
341 #define GLTexCoord2d (immediate && !shaders ? glTexCoord2d : glimtkTexCoord2d)
342 #define GLVertex2d (immediate && !shaders ? glVertex2d : glimtkVertex2d)
343 #define GLTexCoord2f (immediate && !shaders ? glTexCoord2f : glimtkTexCoord2f)
344 #define GLVertex2f (immediate && !shaders ? glVertex2f : glimtkVertex2f)
345 #define GLEnd() (immediate && !shaders ? glEnd() : glimtkEnd(capabilities))
346 #define GLColor3f(a,b,c) (immediate && !shaders ? glColor3f(a,b,c) : glimtkColor3f(shaders, a,b,c))
347 #define GLColor4ub(a,b,c,d) (immediate && !shaders ? glColor4ub(a,b,c,d) : glimtkColor4ub(shaders,a,b,c,d))
348 #define GLColor4f(a,b,c,d) (immediate && !shaders ? glColor4f(a,b,c,d) : glimtkColor4f(shaders,a,b,c,d))
349 #define GLColor4fv(v) (immediate && !shaders ? glColor4fv(v) : glimtkColor4fv(shaders, v))
350 #define GLNormal3fv (immediate && !shaders ? glNormal3fv : glimtkNormal3fv)
351 #define GLNormal3f (immediate && !shaders ? glNormal3f : glimtkNormal3f)
352 #define GLTexCoord2fv (immediate && !shaders ? glTexCoord2fv : glimtkTexCoord2fv)
353 #define GLVertex3d (immediate && !shaders ? glVertex3d : glimtkVertex3d)
354 #define GLVertex3dv (immediate && !shaders ? glVertex3dv : glimtkVertex3dv)
355 #define GLVertex3f (immediate && !shaders ? glVertex3f : glimtkVertex3f)
356 #define GLVertex3fv (immediate && !shaders ? glVertex3fv : glimtkVertex3fv)
358 #define GLLoadMatrixd(m) (fixedFunction && !shaders ? glLoadMatrixd(m) : glmsLoadMatrixd(shaders, m))
359 #define GLMultMatrixd(m) (fixedFunction && !shaders ? glMultMatrixd(m) : glmsMultMatrixd(shaders, m))
360 #define GLFrustum(a,b,c,d,e,f) (fixedFunction && !shaders ? glFrustum(a,b,c,d,e,f) : glmsFrustum(shaders, a,b,c,d,e,f))
361 #define GLOrtho(a,b,c,d,e,f) (fixedFunction && !shaders ? glOrtho(a,b,c,d,e,f) : glmsOrtho(shaders, a,b,c,d,e,f))
362 #define GLScaled(x, y, z) (fixedFunction && !shaders ? glScaled(x, y, z) : glmsScaled(shaders, x,y,z))
363 #define GLScalef(x, y, z) (fixedFunction && !shaders ? glScalef(x, y, z) : glmsScaled(shaders, x,y,z))
364 #define GLTranslated(x, y, z) (fixedFunction && !shaders ? glTranslated(x,y,z) : glmsTranslated(shaders, x,y,z))
365 #define GLRotated(a, x, y, z) (fixedFunction && !shaders ? glRotated : glmsRotated)
366 #define GLMatrixMode(m) (fixedFunction && !shaders ? glMatrixMode(m) : glmsMatrixMode(shaders, m))
367 #define GLLoadIdentity() (fixedFunction && !shaders ? glLoadIdentity() : glmsLoadIdentity(shaders))
368 #define GLPushMatrix (fixedFunction && !shaders ? glPushMatrix : glmsPushMatrix)
369 #define GLPopMatrix() (fixedFunction && !shaders ? glPopMatrix() : glmsPopMatrix(shaders))
371 #define GLRecti(x1, y1, x2, y2) glimtkRecti(capabilities, x1, y1, x2, y2)
372 #define GLBegin(m) glimtkBegin(m)
373 #define GLTexCoord2i glimtkTexCoord2i
374 #define GLVertex2i glimtkVertex2i
375 #define GLTexCoord2d glimtkTexCoord2d
376 #define GLVertex2d glimtkVertex2d
377 #define GLTexCoord2f glimtkTexCoord2f
378 #define GLVertex2f glimtkVertex2f
379 #define GLEnd() glimtkEnd(capabilities)
380 #define GLColor3f(a,b,c) glimtkColor3f(shaders, a,b,c)
381 #define GLColor4ub(a,b,c,d) glimtkColor4ub(shaders,a,b,c,d)
382 #define GLColor4f(a,b,c,d) glimtkColor4f(shaders,a,b,c,d)
383 #define GLColor4fv(v) glimtkColor4fv(shaders, v)
384 #define GLNormal3fv glimtkNormal3fv
385 #define GLNormal3f glimtkNormal3f
386 #define GLTexCoord2fv glimtkTexCoord2fv
387 #define GLVertex3d glimtkVertex3d
388 #define GLVertex3dv glimtkVertex3dv
389 #define GLVertex3f glimtkVertex3f
390 #define GLVertex3fv glimtkVertex3fv
392 #define GLLoadMatrixd(m) glmsLoadMatrixd(shaders, m)
393 #define GLMultMatrixd(m) glmsMultMatrixd(shaders, m)
394 #define GLFrustum(a,b,c,d,e,f) glmsFrustum(shaders, a,b,c,d,e,f)
395 #define GLOrtho(a,b,c,d,e,f) glmsOrtho(shaders, a,b,c,d,e,f)
396 #define GLScaled(a,b,c) glmsScaled(shaders, a,b,c)
397 #define GLScalef(a,b,c) glmsScaled(shaders, a,b,c)
398 #define GLTranslated(a,b,c) glmsTranslated(shaders, a,b,c)
399 #define GLRotated(a, x, y, z) glmsRotated(shaders, a, x, y, z)
400 #define GLMatrixMode(m) glmsMatrixMode(shaders, m)
401 #define GLLoadIdentity() glmsLoadIdentity(shaders)
402 #define GLPushMatrix glmsPushMatrix
403 #define GLPopMatrix() glmsPopMatrix(shaders)
406 #define GLLoadMatrix GLLoadMatrixd
407 #define GLMultMatrix GLMultMatrixd
408 #define GLGetMatrix GLGetDoublev
409 #define GLTranslate GLTranslated
410 #define GLScale GLScaled
412 static GLuint stippleTexture;
413 static bool stippleEnabled;
414 // TOCHECK: Do we really need to pass shaders?
415 public void glsupLineStipple( bool shaders, int i, unsigned short j )
418 bool fixedFunction = false;
422 for(x = 0; x < 16; x++)
424 bool v = (j & (1 << x)) != 0;
425 texture[x] = v ? 0xFFFFFFFF : 0;
428 glGenTextures(1, &stippleTexture);
429 glBindTexture(GL_TEXTURE_2D, stippleTexture);
430 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
432 // TOOD: Special shading code for stippling?
433 GLSetupTexturing(shaders, true);
434 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
435 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
436 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
437 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
438 GLMatrixMode(GL_TEXTURE);
440 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
441 GLScaled(i/16.0, 1, 1.0f);
442 GLTranslated(0.5, 0.5, 0);
443 GLMatrixMode(MatrixMode::projection);
447 public void glsupLightModeli( unsigned int pname, int param )
449 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
450 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
453 void glFogi( unsigned int pname, int param ) { }
454 void glPolygonMode( unsigned int i, unsigned int j ) { }
455 void glBlendFuncSeparate(int a, int b, int c, int d)
462 #if defined(_GLES) || defined(_GLES2)
463 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
466 #if !ENABLE_GL_SELECT
468 // *** Picking won't be supported for now ***
469 void glPushName( unsigned int i ) { }
470 void glLoadName( unsigned int i ) { }
475 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
476 static inline uint getPrimitiveType(bool quadsSupport, RenderPrimitiveType type)
478 static int primitiveTypes[RenderPrimitiveType] =
480 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN,
482 GLIMTKMode::quadStrip,
485 // NOTE: This will only work for single quads
486 return (type == quads && !quadsSupport) ? GL_TRIANGLE_FAN : primitiveTypes[type];
489 public void GLSetupTexturing(bool shaders, bool enable)
491 #if ENABLE_GL_SHADERS
493 shader_texturing(enable);
498 (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
502 public void GLSetupFog(bool shaders, bool enable)
504 #if ENABLE_GL_SHADERS
511 (enable ? glEnable : glDisable)(GL_FOG);
515 bool lightingEnabled;
517 public void GLSetupLighting(bool shaders, bool enable)
519 lightingEnabled = enable;
520 #if ENABLE_GL_SHADERS
522 shader_lighting(enable);
527 (enable ? glEnable : glDisable)(GL_LIGHTING);
532 static int displayWidth, displayHeight;
534 #define GL_CLAMP_TO_EDGE 0x812F
536 static bool useSingleGLContext = false;
537 class OGLDisplay : struct
539 #if defined(__WIN32__)
550 byte * pboMemory1, * pboMemory2;
552 #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
553 GLXContext glContext;
556 XShmSegmentInfo shminfo;
558 XShmSegmentInfo shminfoShape;
563 X11Picture windowPicture;
564 X11Picture pixmapPicture;
566 X11Picture shapePicture;
569 GLCapabilities capabilities, originalCapabilities;
571 ColorAlpha * flippingBuffer;
572 int flipBufH, flipBufW;
577 #if defined(_DEBUG) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
578 // #define GL_DEBUGGING
582 static void APIENTRY openglCallbackFunction(GLenum source,
587 const GLchar* message,
588 const void* userParam)
590 if(severity == GL_DEBUG_SEVERITY_NOTIFICATION)
592 PrintLn("---------------------opengl-callback-start------------");
593 PrintLn("message: ", message);
597 case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
598 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
599 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
600 case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
601 case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
602 case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
609 case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
610 case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
611 case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
612 default: PrintLn("(other)");
614 PrintLn("---------------------opengl-callback-end--------------");
618 class OGLSystem : struct
622 #if ENABLE_GL_SHADERS
627 #if defined(__WIN32__)
628 PIXELFORMATDESCRIPTOR pfd;
633 #elif defined(__EMSCRIPTEN__)
634 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
635 #elif !defined(__ANDROID__) && !defined(__ODROID__)
636 XVisualInfo * visualInfo;
637 GLXContext glContext;
638 GLXDrawable glxDrawable;
640 GLCapabilities capabilities;
643 class OGLSurface : struct
651 float foreground[4], background[4], bitmapMult[4];
654 class OGLMesh : struct
663 class OGLIndices : struct
674 static void setupDebugging()
676 if(glDebugMessageCallback)
678 GLuint unusedIds = 0;
680 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
682 glDebugMessageCallback(openglCallbackFunction, null);
683 glDebugMessageControl(GL_DONT_CARE,
693 #if defined(__WIN32__)
694 static HGLRC winCreateContext(HDC hdc, int * contextVersion, bool * isCompatible)
697 if(wglCreateContextAttribsARB)
699 int versions[12][2] =
701 { 4, 5 }, { 4, 4 }, { 4, 3 }, { 4, 2 }, { 4, 1 }, { 4, 0 },
702 { 3, 3 }, { 3, 2 }, { 3, 1 }, { 3, 0 },
706 bool tryingCompat = true;
710 for(v = 0; !result && v < sizeof(versions) / sizeof(versions[0]); v++)
712 int v0 = versions[v][0], v1 = versions[v][1];
713 if(!tryingCompat || v0 >= 3)
715 bool coreNotion = v0 > 3 || (v0 == 3 && v1 >= 3);
718 WGL_CONTEXT_MAJOR_VERSION_ARB, v0, WGL_CONTEXT_MINOR_VERSION_ARB, v1,
720 WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
722 WGL_CONTEXT_PROFILE_MASK_ARB, coreNotion ? (tryingCompat ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB) : 0,
725 result = wglCreateContextAttribsARB(hdc, null, attribs);
728 if(contextVersion) *contextVersion = v0;
729 if(isCompatible) *isCompatible = tryingCompat || !coreNotion;
734 tryingCompat = false;
741 if(contextVersion) *contextVersion = 1;
742 if(isCompatible) *isCompatible = true;
743 result = wglCreateContext(hdc);
749 class OpenGLDisplayDriver : DisplayDriver
751 class_property(name) = "OpenGL";
753 bool LockSystem(DisplaySystem displaySystem)
755 #if defined(__EMSCRIPTEN__)
756 OGLSystem oglSystem = displaySystem.driverData;
757 emscripten_webgl_make_context_current(oglSystem.glc);
758 #elif !defined(__ANDROID__) && !defined(__ODROID__)
759 OGLSystem oglSystem = displaySystem.driverData;
760 if(useSingleGLContext) return true;
761 #if defined(__WIN32__)
762 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
763 #elif defined(__unix__) || defined(__APPLE__)
764 //if(previous) return true;
765 // printf("Making SYSTEM current\n");
766 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
767 //previous = oglSystem.glContext;
770 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
771 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
775 void UnlockSystem(DisplaySystem displaySystem)
777 if(useSingleGLContext) return;
778 #if defined(__WIN32__)
779 wglMakeCurrent(null, null);
780 #elif defined(__unix__) || defined(__APPLE__)
781 // printf("Making NULL current\n");
782 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
784 glXMakeCurrent(xGlobalDisplay, None, null);
790 bool Lock(Display display)
792 #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
793 OGLDisplay oglDisplay = display.driverData;
794 if(useSingleGLContext) return true;
795 #if defined(__WIN32__)
796 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
797 #elif defined(__unix__) || defined(__APPLE__)
798 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
799 // printf(" Making DISPLAY current\n");
800 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
803 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
804 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
808 void Unlock(Display display)
810 if(useSingleGLContext) return;
811 //printf(" Making NULL current\n");
812 //glXMakeCurrent(xGlobalDisplay, None, null);
814 LockSystem(display.displaySystem);
817 void DestroyDisplay(Display display)
819 OGLDisplay oglDisplay = display.driverData;
823 #if defined(__WIN32__)
824 wglMakeCurrent( null, null );
827 wglDeleteContext(oglDisplay.glrc);
829 if(oglDisplay.hdc && oglDisplay.pBuffer)
830 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
832 if(oglDisplay.pBuffer)
833 wglDestroyPbufferARB(oglDisplay.pBuffer);
836 ReleaseDC(display.window, oglDisplay.hdc);
838 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
839 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
841 #elif defined(__unix__) || defined(__APPLE__)
842 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
844 if(oglDisplay.shapePixmap)
845 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
846 if(oglDisplay.pixmap)
847 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
850 if(oglDisplay.shminfoShape.shmid != -1)
852 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
853 if(oglDisplay.shminfo.shmaddr != (void *)-1)
854 shmdt(oglDisplay.shminfo.shmaddr);
855 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
858 if(oglDisplay.shapeImage)
860 if(oglDisplay.shminfoShape.shmid != -1)
862 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
863 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
864 shmdt(oglDisplay.shminfoShape.shmaddr);
865 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
867 XDestroyImage(oglDisplay.shapeImage);
868 oglDisplay.shapeImage = None;
871 glXMakeCurrent(xGlobalDisplay, None, null);
873 if(oglDisplay.glContext)
874 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
877 delete oglDisplay.flippingBuffer;
879 display.driverData = null;
883 #if !defined(__EMSCRIPTEN__)
884 void ::CheckCapabilities(OGLSystem oglSystem, OGLDisplay oglDisplay)
886 GLCapabilities capabilities;
888 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
891 printf("extensions: %s\n", extensions);
894 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
897 capabilities = { fixedFunction = true, vertexBuffer = true, frameBuffer = extensions && strstr(extensions, "GL_OES_framebuffer_object") };
898 #elif defined(_GLES2)
899 capabilities = { shaders = true, vertexBuffer = true, frameBuffer = true };
903 nonPow2Textures = extensions && strstr(extensions, "GL_ARB_texture_non_power_of_two");
906 legacy = glBegin != null;
907 immediate = glBegin != null;
908 fixedFunction = glBegin != null;
909 quads = glBegin != null;
911 #if ENABLE_GL_SHADERS
912 shaders = glCreateProgram != null;
915 shaders = glBindFramebuffer != null;
917 vertexBuffer = glBindBuffer != null;
918 // mapBuffer = glMapBuffer != null;
923 PrintLn("max texture size: ", oglSystem.maxTextureSize);
925 if(oglDisplay) oglDisplay.capabilities = capabilities;
926 if(oglSystem) oglSystem.capabilities = capabilities;
930 bool CreateDisplaySystem(DisplaySystem displaySystem)
933 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
934 #if defined(__ANDROID__) || defined(__ODROID__)
935 bool shaders = false;
939 oglSystem.capabilities = { fixedFunction = true, vertexBuffer = true, frameBuffer = true };
940 #elif defined(_GLES2)
941 oglSystem.capabilities = { shaders = true, vertexBuffer = true, frameBuffer = true };
943 oglSystem.capabilities = { shaders = true, fixedFunction = true, immediate = true, legacy = true, quads = true, intAndDouble = true, vertexBuffer = true, frameBuffer = true, nonPow2Textures = true };
947 PrintLn("OpenGL driver's CreateDisplaySystem()");
951 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
953 oglSystem.hdc = GetDC(oglSystem.hwnd);
957 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
958 oglSystem.pfd.nVersion = 1;
959 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
960 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
961 oglSystem.pfd.cColorBits = 24;
962 oglSystem.pfd.cAlphaBits = 8;
963 oglSystem.pfd.cDepthBits = 24;
964 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
966 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
967 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
969 if(oglSystem.pfd.cColorBits > 8)
971 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
972 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
975 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
977 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
978 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
979 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
980 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
981 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
982 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
983 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
984 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
985 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
986 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
987 wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
989 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
990 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
992 // eSystem_LoggingMode(LOG_MSGBOX, null);
994 if(wglChoosePixelFormatARB)
999 float fAttributes[] = {0,0};
1002 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
1003 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1004 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1005 WGL_COLOR_BITS_ARB,24,
1006 WGL_ALPHA_BITS_ARB,8,
1007 WGL_DEPTH_BITS_ARB,16,
1008 WGL_STENCIL_BITS_ARB,0,
1009 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
1010 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1011 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1015 //Log("Found wglChoosePixelFormatARB\n");
1017 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1018 if(!valid || !numFormats)
1020 //Log("Can't find 4x multi sampling\n");
1021 iAttributes[19] = 2;
1022 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1023 if(!valid || !numFormats)
1025 // Log("Can't find 2x multi sampling\n");
1026 iAttributes[16] = 0;
1027 iAttributes[17] = 0;
1028 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1031 if(valid && numFormats)
1033 oglSystem.format = pixelFormat;
1034 wglMakeCurrent(null, null);
1035 wglDeleteContext(oglSystem.glrc);
1037 // *** DescribePixelFormat does not support WGL pixel formats! ***
1038 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1039 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1040 //Log("Successfully set pixel format\n");
1043 PrintLn("winCreateContext()");
1045 oglSystem.glrc = winCreateContext(oglSystem.hdc, null, null);
1047 PrintLn("wglMakeCurrent()");
1050 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1054 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
1058 wglMakeCurrent(null, null);
1060 //eSystem_DumpErrors(true);
1064 #elif defined(__unix__) || defined(__APPLE__)
1065 #if defined(__ANDROID__) || defined(__ODROID__)
1066 #if defined(__ANDROID__)
1067 egl_init_display(guiApp.desktop.windowHandle);
1068 #elif defined(__ODROID__)
1069 egl_init_display((uint)displaySystem.window);
1071 CheckCapabilities(oglSystem, null);
1073 // TODO: Clean this up? Needed here?
1074 GLEnableClientState(VERTICES);
1076 // Initialize GL state.
1077 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1078 glEnable(GL_CULL_FACE);
1079 glShadeModel(GL_SMOOTH);
1080 glDisable(GL_DEPTH_TEST);
1082 glDisable(GL_CULL_FACE);
1083 glDisable(GL_DEPTH_TEST);
1085 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1088 matrixStack[0][0].Identity();
1089 matrixStack[1][0].Identity();
1090 matrixStack[2][0].Identity();
1092 GLMatrixMode(GL_MODELVIEW);
1093 GLScaled(1.0, 1.0, -1.0);
1094 GLMatrixMode(GL_PROJECTION);
1095 glShadeModel(GL_FLAT);
1098 GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1099 glFogi(GL_FOG_MODE, GL_EXP);
1100 glFogf(GL_FOG_DENSITY, 0);
1101 glEnable(GL_NORMALIZE);
1102 glDepthFunc(GL_LESS);
1104 glDisable(GL_MULTISAMPLE_ARB);
1106 glViewport(0,0,eglWidth,eglHeight);
1108 GLOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
1110 glabCurArrayBuffer = 0;
1111 glabCurElementBuffer = 0;
1114 #elif defined(__EMSCRIPTEN__)
1116 EmscriptenWebGLContextAttributes attribs = { 0 };
1118 attribs.antialias = 1;
1125 EM_BOOL premultipliedAlpha;
1126 EM_BOOL preserveDrawingBuffer;
1127 EM_BOOL preferLowPowerToHighPerformance;
1128 EM_BOOL failIfMajorPerformanceCaveat;
1131 EM_BOOL enableExtensionsByDefault;
1134 emscripten_webgl_init_context_attributes(&attribs);
1135 oglSystem.maxTextureSize = 16384;
1136 oglSystem.glc = emscripten_webgl_create_context("canvas", &attribs);
1137 if(emscripten_webgl_make_context_current(oglSystem.glc) == EMSCRIPTEN_RESULT_SUCCESS)
1140 /*glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1141 glEnable(GL_BLEND);*/
1145 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1146 XSetWindowAttributes attr;
1151 #ifndef ECERE_MINIGLX
1152 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1155 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1159 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
1160 attr.background_pixel = 0;
1161 attr.border_pixel = 0;
1162 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1163 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1164 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1166 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1167 oglSystem.visualInfo->visual, mask, &attr );
1169 if(oglSystem.visualInfo)
1171 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1172 if(oglSystem.glContext)
1174 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1175 glXMakeCurrent(xGlobalDisplay, None, null);
1182 displaySystem.flags.alpha = true;
1183 displaySystem.flags.flipping = true;
1184 displaySystem.pixelFormat = pixelFormat888;
1188 void DestroyDisplaySystem(DisplaySystem displaySystem)
1190 OGLSystem oglSystem = displaySystem.driverData;
1193 glDeleteTextures(1, &stippleTexture);
1197 #if ENABLE_GL_SHADERS
1198 if(oglSystem.shadingProgram)
1199 glDeleteProgram(oglSystem.shadingProgram);
1200 if(oglSystem.fragmentShader)
1201 glDeleteShader(oglSystem.fragmentShader);
1202 if(oglSystem.vertexShader)
1203 glDeleteShader(oglSystem.vertexShader);
1208 #if defined(__WIN32__)
1209 wglMakeCurrent( null, null );
1212 wglDeleteContext(oglSystem.glrc);
1215 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1216 DestroyWindow(oglSystem.hwnd);
1218 #elif defined(__unix__) || defined(__APPLE__)
1219 #if defined(__ANDROID__) || defined(__ODROID__)
1221 #elif defined(__EMSCRIPTEN__)
1222 emscripten_webgl_destroy_context(oglSystem.glc);
1224 if(oglSystem.visualInfo)
1226 #ifdef ECERE_MINIGLX
1227 __miniglx_XFree(oglSystem.visualInfo);
1229 XFree(oglSystem.visualInfo);
1233 if(oglSystem.glxDrawable)
1235 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1236 oglSystem.glxDrawable = 0;
1243 /*static */bool ::initialDisplaySetup(Display display)
1245 OGLDisplay oglDisplay = display.driverData;
1246 GLCapabilities capabilities = oglDisplay.capabilities;
1248 bool shaders = capabilities.shaders;
1249 #if ENABLE_GL_LEGACY
1250 bool fixedFunction = capabilities.fixedFunction;
1252 #if ENABLE_GL_SHADERS
1254 loadShaders(display.displaySystem, "<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
1255 #if ENABLE_GL_LEGACY
1258 glDisableVertexAttribArray(GLBufferContents::color);
1259 glDisableVertexAttribArray(GLBufferContents::normal);
1260 glDisableVertexAttribArray(GLBufferContents::texCoord);
1261 glDisableVertexAttribArray(GLBufferContents::vertex);
1267 GLEnableClientState(VERTICES);
1269 GLABBindBuffer(GL_ARRAY_BUFFER, 0);
1270 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1272 #if defined(__WIN32__)
1273 if(glBlendFuncSeparate)
1274 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1276 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1278 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1282 GLMatrixMode(MatrixMode::modelView);
1283 GLLoadIdentity(); // For setting up GLES stack
1284 GLScaled(1.0, 1.0, -1.0);
1285 // glTranslatef(0.375f, 0.375f, 0.0f);
1286 // glTranslatef(-0.625f, -0.625f, 0.0f);
1287 GLMatrixMode(MatrixMode::projection);
1289 if(display.width && display.height)
1290 GLOrtho(0,display.width,display.height,0,0.0,1.0);
1295 glShadeModel(GL_FLAT);
1297 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
1298 GLLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1300 GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1301 glFogi(GL_FOG_MODE, GL_EXP);
1302 glFogf(GL_FOG_DENSITY, 0);
1303 glEnable(GL_NORMALIZE);
1306 glDepthFunc(GL_LESS);
1308 glDisable(GL_MULTISAMPLE_ARB);
1309 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1310 display.ambient = Color { 50,50,50 };
1315 bool CreateDisplay(Display display)
1317 bool result = false;
1318 OGLDisplay oglDisplay = display.driverData;
1319 OGLSystem oglSystem = display.displaySystem.driverData;
1322 oglDisplay = display.driverData = OGLDisplay { };
1323 oglDisplay.capabilities = oglSystem.capabilities;
1325 #if defined(__WIN32__) || defined(USEPBUFFER)
1326 if(!display.alphaBlend)
1329 #if defined(__WIN32__)
1330 oglDisplay.hdc = GetDC(display.window);
1331 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1332 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, null, null)))
1334 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1335 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1339 ReleaseDC(display.window, oglDisplay.hdc);
1340 #elif defined(__unix__) || defined(__APPLE__)
1341 # if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1344 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1346 #if defined(__APPLE__)
1347 XVisualInfo template = { 0 };
1348 XWindowAttributes winAttr;
1350 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1351 template.visualid = XVisualIDFromVisual(winAttr.visual);
1352 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1354 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1355 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1356 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1357 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1359 // visualInfo = oglSystem.visualInfo;
1364 //printf("visualInfo is not null\n");
1365 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1366 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1367 //XFree(visualInfo);
1370 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1371 if(oglDisplay.glContext)
1373 //printf("CreateDisplay Got a Context\n");
1374 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1380 #if defined(__WIN32__) || defined(USEPBUFFER)
1384 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1389 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
1392 PrintLn("Calling ogl_LoadFunctions() in CreateDisplay()");
1394 if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
1395 PrintLn("ogl_LoadFunctions() failed!");
1398 PrintLn("CheckCapabilities()");
1400 CheckCapabilities(oglSystem, oglDisplay);
1403 PrintLn("vboAvailable is: ", vboAvailable);
1406 # ifdef GL_DEBUGGING
1412 #if defined(__EMSCRIPTEN__)
1413 emscripten_webgl_make_context_current(oglSystem.glc);
1418 GLCapabilities capabilities = *&display.glCapabilities;
1419 // PrintLn("Available OpenGL Capabilities: ", oglDisplay.capabilities);
1420 // PrintLn("Desired OpenGL Capabilities: ", capabilities);
1422 oglDisplay.originalCapabilities = oglDisplay.capabilities;
1424 // Re-enable shaders if no fixed function support
1425 if(!oglDisplay.capabilities.fixedFunction)
1426 capabilities.shaders = true;
1427 // Re-enable fixed function if no shaders support
1428 if(!oglDisplay.capabilities.shaders)
1429 capabilities.fixedFunction = true;
1431 #if !ENABLE_GL_POINTER
1432 // Re-enable vertex buffer if no pointer support
1433 capabilities.vertexBuffer = true;
1436 oglDisplay.capabilities &= capabilities;
1438 // PrintLn("Selected OpenGL Capabilities: ", oglDisplay.capabilities);
1439 oglSystem.capabilities = oglDisplay.capabilities;
1442 initialDisplaySetup(display);
1445 if(!useSingleGLContext)
1447 #if defined(__WIN32__)
1448 wglMakeCurrent(null, null);
1449 #elif defined(__unix__) || defined(__APPLE__)
1450 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1453 glXMakeCurrent(xGlobalDisplay, None, null);
1459 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
1466 bool DisplaySize(Display display, int width, int height)
1468 OGLDisplay oglDisplay = display.driverData;
1469 GLCapabilities capabilities = oglDisplay.capabilities;
1470 #if ENABLE_GL_LEGACY
1471 bool fixedFunction = capabilities.fixedFunction;
1473 bool shaders = capabilities.shaders;
1474 bool result = false;
1476 #if defined(__WIN32__) || defined(USEPBUFFER)
1477 OGLSystem oglSystem = display.displaySystem.driverData;
1478 if(display.alphaBlend)
1480 #if defined(__WIN32__)
1481 const int attributes[]=
1483 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1484 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1486 int pixelFormat = 0;
1487 if(wglChoosePixelFormatARB)
1491 float fAttributes[] = {0,0};
1494 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
1495 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1496 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1497 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1498 WGL_COLOR_BITS_ARB,24,
1499 WGL_ALPHA_BITS_ARB,8,
1500 WGL_DEPTH_BITS_ARB,16,
1501 WGL_STENCIL_BITS_ARB,0,
1502 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
1503 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1504 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1508 //Log("Found wglChoosePixelFormatARB\n");
1510 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1511 if(!valid || !numFormats)
1513 //Log("Can't find 4x multi sampling\n");
1514 iAttributes[19] = 2;
1515 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1516 if(!valid || !numFormats)
1518 // Log("Can't find 2x multi sampling\n");
1519 iAttributes[16] = 0;
1520 iAttributes[17] = 0;
1521 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1522 if(!valid || !numFormats)
1526 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
1527 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
1528 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1529 WGL_COLOR_BITS_ARB,24,
1530 WGL_ALPHA_BITS_ARB,8,
1531 WGL_DEPTH_BITS_ARB,16,
1534 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1538 if(valid && numFormats)
1540 wglMakeCurrent(null, null);
1544 wglMakeCurrent( null, null );
1545 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
1546 if(oglDisplay.hdc && oglDisplay.pBuffer)
1547 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1549 wglDestroyPbufferARB(oglDisplay.pBuffer);
1551 if(!useSingleGLContext)
1552 wglMakeCurrent( null, null );
1555 wglDeleteContext(oglDisplay.glrc);
1557 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
1558 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
1559 if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, null, null)))
1562 HDC hdc = GetDC(display.window);
1564 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1565 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1567 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
1568 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
1570 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
1572 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
1576 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1577 oglDisplay.memDC = CreateCompatibleDC(hdc);
1578 SetMapMode(oglDisplay.memDC, MM_TEXT);
1579 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1580 info->bmiHeader.biPlanes = 1;
1581 info->bmiHeader.biCompression = BI_RGB;
1582 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
1583 info->bmiHeader.biWidth = width;
1584 info->bmiHeader.biHeight = height;
1585 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
1588 SelectObject(oglDisplay.memDC, newBitmap);
1589 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1592 PIXELFORMATDESCRIPTOR pfd = { 0 };
1593 pfd.nSize = (short)sizeof(pfd);
1595 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
1596 pfd.iPixelType = PFD_TYPE_RGBA;
1597 pfd.cColorBits = 32;
1598 //pfd.cAlphaBits = 8;
1599 pfd.cDepthBits = 24;
1600 pfd.iLayerType = PFD_MAIN_PLANE;
1602 oglDisplay.hdc = oglDisplay.memDC;
1604 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
1605 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
1606 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
1608 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
1609 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1610 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1615 const int imageSize = width * height * 4;
1617 glGenBuffersARB(2, oglDisplay.imageBuffers);
1619 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1620 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
1621 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1622 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
1625 oglDisplay.memBitmap = newBitmap;
1626 oglDisplay.stride = width;
1632 ReleaseDC(display.window, hdc);
1634 #elif defined(__unix__) || defined(__APPLE__)
1635 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1640 GLX_DOUBLEBUFFER, True,
1646 GLX_STENCIL_SIZE, 1,
1647 //GLX_DEPTH_SIZE, 24,
1648 GLX_RENDER_TYPE, GLX_RGBA_BIT,
1649 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
1655 GLX_PBUFFER_WIDTH, width,
1656 GLX_PBUFFER_HEIGHT, height,
1657 GLX_LARGEST_PBUFFER, False,
1661 // choose a pixel format that meets our minimum requirements
1664 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
1667 if(oglDisplay.pixmap)
1669 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1670 oglDisplay.pixmap = None;
1672 if(oglDisplay.shapePixmap)
1674 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1675 oglDisplay.shapePixmap = None;
1678 // Free Shared Memory Pixmap
1679 if(oglDisplay.image)
1681 if(oglDisplay.shminfoShape.shmid != -1)
1683 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1684 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1685 shmdt(oglDisplay.shminfo.shmaddr);
1686 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1688 XDestroyImage(oglDisplay.image);
1689 oglDisplay.image = None;
1691 if(oglDisplay.shapeImage)
1693 if(oglDisplay.shminfoShape.shmid != -1)
1695 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1696 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1697 shmdt(oglDisplay.shminfoShape.shmaddr);
1698 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1700 XDestroyImage(oglDisplay.shapeImage);
1701 oglDisplay.shapeImage = None;
1704 if(oglDisplay.windowPicture)
1705 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
1706 if(oglDisplay.pixmapPicture)
1707 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
1709 if(oglDisplay.pixmap)
1710 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1712 if(oglDisplay.glContext)
1713 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1714 if(oglDisplay.pBuffer)
1715 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
1717 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
1718 if(oglDisplay.pBuffer)
1720 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
1721 if(oglDisplay.glContext)
1723 glXMakeCurrent(xGlobalDisplay, None, null);
1724 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1726 // Initialize Shared Memory Pixmap
1727 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
1728 ZPixmap, null, &oglDisplay.shminfo, width, height);
1729 if(oglDisplay.image)
1731 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
1732 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
1733 if(oglDisplay.shminfo.shmid != -1)
1735 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
1736 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1738 oglDisplay.shminfo.readOnly = False;
1739 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
1741 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
1742 &oglDisplay.shminfo, width, height, 32);
1744 // Initialize Shared Memory Shape Pixmap
1745 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
1746 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
1747 if(oglDisplay.shapeImage)
1749 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
1750 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
1751 if(oglDisplay.shminfoShape.shmid != -1)
1753 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
1754 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1756 oglDisplay.shminfoShape.readOnly = False;
1757 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
1759 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
1760 &oglDisplay.shminfoShape, width, height, 1);
1761 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
1764 XRenderPictureAttributes attributes = { 0 };
1765 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
1766 #if !defined(__APPLE__)
1767 attributes.repeat = RepeatNormal;
1769 attributes.repeat = 1;
1771 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
1772 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
1773 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
1774 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
1777 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
1778 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
1795 CreateDisplay(display);
1796 #if defined(__WIN32__)
1797 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1798 #elif defined(__unix__) || defined(__APPLE__)
1799 #if defined(__ANDROID__) || defined(__ODROID__)
1802 #elif defined(__EMSCRIPTEN__)
1803 emscripten_webgl_make_context_current(oglSystem.glc);
1805 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1813 if(display.alphaBlend && result)
1814 initialDisplaySetup(display);
1816 if(!result && display.alphaBlend)
1818 printf("Alpha blending windows not supported on this display\n");
1825 glViewport(0,0,width,height);
1826 GLMatrixMode(MatrixMode::projection);
1828 GLOrtho(0,width,height,0,0.0,1.0);
1829 displayWidth = display.width = width;
1830 displayHeight = display.height = height;
1832 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
1834 oglDisplay.flipBufW = width;
1835 oglDisplay.flipBufH = height;
1836 #if defined(_GLES) || defined(_GLES2)
1839 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
1842 if(oglDisplay.flippingBuffer || !width || !height)
1848 void DisplayPosition(Display display, int x, int y)
1850 OGLDisplay oglDisplay = display.driverData;
1856 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
1860 void RestorePalette(Display display)
1864 void StartUpdate(Display display)
1868 void EndUpdate(Display display)
1872 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1876 void Update(Display display, Box updateBox)
1878 #if defined(__WIN32__) || defined(USEPBUFFER)
1879 OGLDisplay oglDisplay = display.driverData;
1882 #if !defined(__ANDROID__)
1887 #if defined(__WIN32__) || defined(USEPBUFFER)
1888 if(display.alphaBlend)
1890 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1891 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
1892 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1893 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1894 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
1897 #if defined(__WIN32__)
1899 POINT point = { oglDisplay.x, oglDisplay.y};
1900 POINT srcPoint = { 0, 0 };
1901 BLENDFUNCTION blend = { 0 };
1903 size.cx = display.width;
1904 size.cy = display.height;
1905 blend.BlendOp = AC_SRC_OVER;
1906 blend.BlendFlags = 0;
1907 blend.SourceConstantAlpha = 255;
1908 blend.AlphaFormat = AC_SRC_ALPHA;
1911 // Process partial images. Mapping the buffer waits for
1912 // outstanding DMA transfers into the buffer to finish.
1913 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1914 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
1916 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1917 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
1920 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
1921 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
1924 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
1927 // Unmap the image buffers
1928 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1929 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1931 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1932 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
1934 // Bind two different buffer objects and start the glReadPixels
1935 // asynchronously. Each call will return directly after
1936 // starting the DMA transfer.
1937 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
1938 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1940 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
1941 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
1945 #elif defined(__unix__) || defined(__APPLE__)
1946 #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
1948 XTransform transform =
1951 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
1952 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
1953 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1956 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
1957 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1958 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
1959 #if !defined(__APPLE__)
1960 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1962 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
1964 XFlush(xGlobalDisplay);
1972 #if defined(__WIN32__)
1973 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
1974 SwapBuffers(oglDisplay.hdc);
1975 //ecere::sys::Sleep(0.1);
1976 #elif defined(__unix__) || defined(__APPLE__)
1977 #if defined(__ANDROID__) || defined(__ODROID__)
1979 #elif defined(__EMSCRIPTEN__)
1981 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
1987 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
1989 if(bitmap.driverData)
1991 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
1992 glDeleteTextures(1, &tex);
1993 bitmap.driverData = 0;
1995 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
1998 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
2000 OGLSystem oglSystem = displaySystem.driverData;
2001 GLCapabilities capabilities = oglSystem.capabilities;
2002 bool result = false;
2004 GLuint glBitmap = 0;
2006 uint w = width, h = height;
2007 if(!capabilities.nonPow2Textures)
2012 w = Min(w, oglSystem.maxTextureSize);
2013 h = Min(h, oglSystem.maxTextureSize);
2015 glGenTextures(1, &glBitmap);
2016 glBindTexture(GL_TEXTURE_2D, glBitmap);
2018 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2020 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2021 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2023 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2024 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2027 if(!capabilities.shaders)
2028 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2031 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
2033 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2034 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2038 bitmap.driverData = (void *)(uintptr)glBitmap;
2039 bitmap.driver = displaySystem.driver;
2047 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
2049 bool result = false;
2050 OGLSystem oglSystem = displaySystem.driverData;
2051 GLCapabilities capabilities = oglSystem.capabilities;
2052 Bitmap convBitmap = bitmap;
2056 convBitmap.Copy(bitmap);
2059 // Pre process the bitmap... First make it 32 bit
2060 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
2063 uint w = bitmap.width, h = bitmap.height;
2064 GLuint glBitmap = 0;
2065 if(!capabilities.nonPow2Textures)
2070 w = Min(w, oglSystem.maxTextureSize);
2071 h = Min(h, oglSystem.maxTextureSize);
2075 while(w * 2 < h) w *= 2;
2076 while(h * 2 < w) h *= 2;
2079 // Switch ARGB to RGBA
2080 //if(bitmap.format != pixelFormatRGBA)
2082 for(c=0; c<bitmap.size; c++)
2084 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
2086 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
2087 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
2090 // convBitmap.pixelFormat = pixelFormat888;
2093 glGenTextures(1, &glBitmap);
2096 //int error = glGetError();
2100 glBindTexture(GL_TEXTURE_2D, glBitmap);
2101 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2103 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
2104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2106 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2108 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
2109 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
2111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2113 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
2114 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
2118 if(!capabilities.shaders)
2119 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2124 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
2129 if(bitmap.width != w || bitmap.height != h)
2131 mipMap = Bitmap { };
2132 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
2134 Surface mipSurface = mipMap.GetSurface(0,0,null);
2135 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
2145 mipMap = convBitmap;
2152 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2153 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2154 //printf("Calling glTexImage2D\n");
2155 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2156 //printf("width = %d (Should be %d, %d)\n", width, w, h);
2157 if((error = glGetError()))
2159 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2160 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2164 if(mipMap != convBitmap)
2169 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2170 bitmap.driverData = (void *)(uintptr)glBitmap;
2171 bitmap.driver = displaySystem.driver;
2176 FreeBitmap(displaySystem, bitmap);
2177 else if(oglSystem.loadingFont)
2179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2180 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2181 oglSystem.loadingFont = false;
2187 void ReleaseSurface(Display display, Surface surface)
2189 glDisable(GL_SCISSOR_TEST);
2190 delete surface.driverData;
2191 surface.driverData = null;
2194 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2199 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2201 bool result = false;
2202 OGLDisplay oglDisplay = display.driverData;
2203 GLCapabilities capabilities = oglDisplay.capabilities;
2204 #if ENABLE_GL_LEGACY
2205 bool fixedFunction = capabilities.fixedFunction;
2207 bool shaders = capabilities.shaders;
2208 OGLSurface oglSurface = surface.driverData = OGLSurface { };
2212 if(displayWidth != display.width || displayHeight != display.height)
2214 displayWidth = display.width;
2215 displayHeight = display.height;
2217 glViewport(0,0,display.width,display.height);
2219 GLOrtho(0,display.width,display.height,0,0.0,1.0);
2222 surface.offset.x = x;
2223 surface.offset.y = y;
2224 surface.unclippedBox = surface.box = clip;
2225 oglSurface.bitmapMult[0] = 1;
2226 oglSurface.bitmapMult[1] = 1;
2227 oglSurface.bitmapMult[2] = 1;
2228 oglSurface.bitmapMult[3] = 1;
2230 glEnable(GL_SCISSOR_TEST);
2233 (display.height) -(y+clip.bottom)-1,
2234 clip.right-clip.left+1,
2235 clip.bottom-clip.top+1);
2241 void Clip(Display display, Surface surface, Box clip)
2248 box.Clip(surface.unclippedBox);
2252 box = surface.box = surface.unclippedBox;
2253 box.left += surface.offset.x;
2254 box.top += surface.offset.y;
2255 box.right+= surface.offset.x;
2256 box.bottom += surface.offset.y;
2259 box.left,display.height - box.bottom - 1,
2260 box.right-box.left+1, box.bottom-box.top+1);
2263 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2265 bool result = false;
2266 OGLDisplay oglDisplay = display.driverData;
2267 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2269 if(oglDisplay.flippingBuffer)
2271 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2274 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2280 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2281 #if ENABLE_GL_LEGACY
2282 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2283 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2284 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2286 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2289 for(row = 0; row<h; row++)
2290 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2297 void SetForeground(Display display, Surface surface, ColorAlpha color)
2299 OGLSurface oglSurface = surface.driverData;
2301 oglSurface.foreground[0] = color.color.r/255.0f;
2302 oglSurface.foreground[1] = color.color.g/255.0f;
2303 oglSurface.foreground[2] = color.color.b/255.0f;
2304 //oglSurface.foreground[3] = 1.0f;
2305 oglSurface.foreground[3] = color.a/255.0f;
2307 //if(!oglSurface.foreground[3])printf("bug");
2310 void SetBackground(Display display, Surface surface, ColorAlpha color)
2312 OGLSurface oglSurface = surface.driverData;
2314 oglSurface.background[0] = color.color.r/255.0f;
2315 oglSurface.background[1] = color.color.g/255.0f;
2316 oglSurface.background[2] = color.color.b/255.0f;
2317 //oglSurface.background[3] = 1.0;
2318 oglSurface.background[3] = color.a/255.0f;
2321 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2323 OGLSurface oglSurface = surface.driverData;
2325 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2326 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2327 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2328 oglSurface.bitmapMult[3] = color.a/255.0f;
2331 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2336 void PutPixel(Display display, Surface surface,int x,int y)
2338 OGLSurface oglSurface = surface.driverData;
2339 OGLDisplay oglDisplay = display.driverData;
2340 GLCapabilities capabilities = oglDisplay.capabilities;
2341 #if ENABLE_GL_LEGACY
2342 bool immediate = capabilities.immediate;
2344 bool shaders = capabilities.shaders;
2346 GLColor4fv(oglSurface.foreground);
2348 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2349 GLVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2354 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2356 OGLDisplay oglDisplay = display.driverData;
2357 GLCapabilities capabilities = oglDisplay.capabilities;
2358 #if ENABLE_GL_LEGACY
2359 bool immediate = capabilities.immediate;
2361 bool shaders = capabilities.shaders;
2363 OGLSurface oglSurface = surface.driverData;
2364 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2379 x1 += surface.offset.x;
2380 y1 += surface.offset.y;
2381 x2 += surface.offset.x;
2382 y2 += surface.offset.y;
2384 GLColor4fv(oglSurface.foreground);
2388 GLTexCoord2f(0.5f, 0);
2389 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2390 GLTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2391 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2399 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2400 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2406 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2408 OGLSurface oglSurface = surface.driverData;
2409 OGLDisplay oglDisplay = display.driverData;
2410 GLCapabilities capabilities = oglDisplay.capabilities;
2411 #if ENABLE_GL_LEGACY
2412 bool immediate = capabilities.immediate;
2414 bool shaders = capabilities.shaders;
2415 x1 += surface.offset.x;
2416 y1 += surface.offset.y;
2417 x2 += surface.offset.x;
2418 y2 += surface.offset.y;
2420 GLColor4fv(oglSurface.foreground);
2425 GLTexCoord2f(0.5f, 0);
2426 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2427 GLTexCoord2f(y2-y1 + 0.5f, 0);
2428 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2430 GLTexCoord2f(0.5f, 0);
2431 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2432 GLTexCoord2f(x2 - x1 + 0.5f, 0);
2433 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2435 GLTexCoord2f(0.5f, 0);
2436 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2437 GLTexCoord2f(y1 - y2 + 0.5f, 0);
2438 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2440 GLTexCoord2f(0.5f, 0);
2441 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2442 GLTexCoord2f(x1 - x2 + 0.5f, 0);
2443 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2447 GLBegin(GL_LINE_LOOP);
2454 GLVertex2f(x1 + 0.5f, y1 + 0.5f);
2455 GLVertex2f(x1 + 0.5f, y2 + 0.5f);
2456 GLVertex2f(x2 + 0.5f, y2 + 0.5f);
2457 GLVertex2f(x2 + 0.5f, y1 + 0.5f);
2462 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2464 OGLSurface oglSurface = surface.driverData;
2465 OGLDisplay oglDisplay = display.driverData;
2466 GLCapabilities capabilities = oglDisplay.capabilities;
2467 #if ENABLE_GL_LEGACY
2468 bool immediate = capabilities.immediate;
2470 bool shaders = capabilities.shaders;
2472 GLColor4fv(oglSurface.background);
2474 GLRecti(x1+surface.offset.x, y1+surface.offset.y,
2475 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2477 GLRectf(x1+surface.offset.x, y1+surface.offset.y,
2478 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2482 void Clear(Display display, Surface surface, ClearType type)
2484 OGLDisplay oglDisplay = display.driverData;
2485 OGLSurface oglSurface = surface.driverData;
2488 if(type != depthBuffer)
2489 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2490 if(type != colorBuffer && !oglDisplay.depthWrite)
2492 glDepthMask((byte)bool::true);
2494 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2495 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2496 if(type != colorBuffer && !oglDisplay.depthWrite)
2498 glDepthMask((byte)bool::false);
2502 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2507 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2509 OGLSurface oglSurface = surface.driverData;
2510 OGLDisplay oglDisplay = display.driverData;
2511 GLCapabilities capabilities = oglDisplay.capabilities;
2512 #if ENABLE_GL_LEGACY
2513 bool immediate = capabilities.immediate;
2514 bool fixedFunction = capabilities.fixedFunction;
2516 bool shaders = capabilities.shaders;
2518 if(!oglSurface.writingText)
2520 // glTranslatef(-0.375f, -0.375f, 0.0f);
2521 GLSetupTexturing(shaders, true);
2522 GLColor4fv(oglSurface.bitmapMult);
2524 else if(oglSurface.xOffset)
2525 GLTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
2527 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2528 GLBegin(GLIMTKMode::quads);
2532 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
2533 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2534 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
2535 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2536 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2537 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2538 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2539 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2544 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2545 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2546 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2547 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2548 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2549 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2550 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2551 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2554 GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
2555 GLVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
2556 GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
2557 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
2558 GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
2559 GLVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
2560 GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
2561 GLVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
2565 if(!oglSurface.writingText)
2567 GLSetupTexturing(shaders, false);
2569 //glTranslate(0.375, 0.375, 0.0);
2571 else if(oglSurface.xOffset)
2572 GLTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
2575 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2577 OGLSurface oglSurface = surface.driverData;
2578 OGLDisplay oglDisplay = display.driverData;
2579 GLCapabilities capabilities = oglDisplay.capabilities;
2580 #if ENABLE_GL_LEGACY
2581 bool immediate = capabilities.immediate;
2583 bool shaders = capabilities.shaders;
2585 //glTranslate(-0.375, -0.375, 0.0);
2587 GLSetupTexturing(shaders, true);
2588 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
2590 GLColor4fv(oglSurface.bitmapMult);
2592 GLBegin(GLIMTKMode::quads);
2596 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2597 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2599 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2600 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2602 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2603 GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
2605 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2606 GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
2610 GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
2611 GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
2613 GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
2614 GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
2616 GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
2617 GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
2619 GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
2620 GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
2625 GLSetupTexturing(shaders, false);
2627 //glTranslate(0.375, 0.375, 0.0);
2630 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2632 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2635 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2637 float s2dw,s2dh,d2sw,d2sh;
2638 //bool flipX = false, flipY = false;
2640 if(Sgn(w) != Sgn(sw))
2646 if(Sgn(h) != Sgn(sh))
2658 //Clip against the edges of the source
2661 dx+=(int)((0-sx) * s2dw);
2662 w-=(int)((0-sx) * s2dw);
2668 dy+=(int)((0-sy) * s2dh);
2669 h-=(int)((0-sy) * s2dh);
2674 if(sx+sw>bitmap.width-1)
2676 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
2677 sw-=sx+sw-(bitmap.width-1)-1;
2679 if(sy+sh>(bitmap.height-1))
2681 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
2682 sh-=sy+sh-(bitmap.height-1)-1;
2684 //Clip against the edges of the surfaceination
2685 if(dx<surface.box.left)
2688 sx+=(int)((surface.box.left-dx)*d2sw);
2689 sw-=(int)((surface.box.left-dx)*d2sw);
2690 w-=surface.box.left-dx;
2691 dx=surface.box.left;
2693 if(dy<surface.box.top)
2695 sy+=(int)((surface.box.top-dy)*d2sh);
2696 sh-=(int)((surface.box.top-dy)*d2sh);
2697 h-=surface.box.top-dy;
2700 if(dx+w>surface.box.right)
2702 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
2703 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
2704 w-=dx+w-surface.box.right-1;
2706 if(dy+h>surface.box.bottom)
2708 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
2709 h-=dy+h-surface.box.bottom-1;
2711 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
2713 dx += surface.offset.x;
2714 dy += surface.offset.y;
2716 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2718 #if ENABLE_GL_LEGACY
2719 OGLDisplay oglDisplay = display.driverData;
2720 GLCapabilities capabilities = oglDisplay.capabilities;
2721 bool legacy = capabilities.legacy;
2724 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2725 #if ENABLE_GL_LEGACY
2728 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2729 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2730 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2731 glRasterPos2d(dx,dy);
2732 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
2733 glPixelZoom(s2dw, -s2dh);
2734 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2735 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2736 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2737 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2740 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2744 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2746 //Clip against the edges of the source
2759 if(sx+w>bitmap.width-1)
2760 w-=sx+w-(bitmap.width-1)-1;
2761 if(sy+h>bitmap.height-1)
2762 h-=sy+h-(bitmap.height-1)-1;
2763 //Clip against the edges of the surfaceination
2764 if(dx<surface.box.left)
2767 sx+=surface.box.left-dx;
2768 w-=surface.box.left-dx;
2769 dx=surface.box.left;
2771 if(dy<surface.box.top)
2773 sy+=surface.box.top-dy;
2774 h-=surface.box.top-dy;
2777 if(dx+w>surface.box.right)
2779 //if(flip) sx+=dx+w-surface.box.right-1;
2780 w-=dx+w-surface.box.right-1;
2782 if(dy+h>surface.box.bottom)
2783 h-=dy+h-surface.box.bottom-1;
2787 dx += surface.offset.x;
2788 dy += surface.offset.y;
2790 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
2792 #if ENABLE_GL_LEGACY
2793 OGLDisplay oglDisplay = display.driverData;
2794 GLCapabilities capabilities = oglDisplay.capabilities;
2795 bool legacy = capabilities.legacy;
2797 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2798 #if ENABLE_GL_LEGACY
2801 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
2802 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
2803 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
2804 glRasterPos2d(dx,dy);
2806 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
2807 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2808 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2809 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2812 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2816 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2818 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
2821 void UnloadFont(DisplaySystem displaySystem, Font font)
2823 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
2826 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2829 OGLSystem oglSystem = displaySystem.driverData;
2830 oglSystem.loadingFont = true;
2831 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2835 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2837 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2840 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2842 OGLSurface oglSurface = surface.driverData;
2843 OGLSystem oglSystem = display.displaySystem.driverData;
2844 OGLDisplay oglDisplay = display.driverData;
2845 GLCapabilities capabilities = oglDisplay.capabilities;
2846 #if ENABLE_GL_LEGACY
2847 bool immediate = capabilities.immediate;
2849 bool shaders = capabilities.shaders;
2850 oglSystem.loadingFont = true;
2852 //glTranslated(-0.375, -0.375, 0.0);
2854 if(surface.textOpacity)
2856 int w = 0, h, adv = 0;
2857 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
2859 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
2862 oglSurface.writingText = true;
2864 GLSetupTexturing(shaders, true);
2866 if(surface.font.outlineSize)
2868 ColorAlpha outlineColor = surface.outlineColor;
2869 GLColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
2870 oglSurface.writingOutline = true;
2871 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2872 oglSurface.writingOutline = false;
2874 GLColor4fv(oglSurface.foreground);
2876 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
2877 oglSurface.writingText = false;
2878 oglSystem.loadingFont = false;
2880 GLSetupTexturing(shaders, false);
2882 //glTranslated(0.375, 0.375, 0.0);
2885 void TextFont(Display display, Surface surface, Font font)
2887 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
2890 void TextOpacity(Display display, Surface surface, bool opaque)
2892 OGLSurface oglSurface = surface.driverData;
2893 oglSurface.opaqueText = opaque;
2896 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2898 OGLSurface oglSurface = surface.driverData;
2899 OGLSystem oglSystem = display.displaySystem.driverData;
2900 oglSystem.loadingFont = true;
2901 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
2902 oglSystem.loadingFont = false;
2905 void DrawingChar(Display display, Surface surface, char character)
2910 void LineStipple(Display display, Surface surface, uint32 stipple)
2912 OGLDisplay oglDisplay = display.driverData;
2913 GLCapabilities capabilities = oglDisplay.capabilities;
2914 #if ENABLE_GL_LEGACY
2915 bool legacy = capabilities.legacy;
2916 bool fixedFunction = capabilities.fixedFunction;
2918 bool shaders = capabilities.shaders;
2922 #if ENABLE_GL_LEGACY
2925 stippleEnabled = true;
2926 glLineStipple(1, (uint16)stipple);
2927 glEnable(GL_LINE_STIPPLE);
2931 glsupLineStipple(shaders, 1, (uint16)stipple);
2935 #if ENABLE_GL_LEGACY
2937 glDisable(GL_LINE_STIPPLE);
2941 stippleEnabled = false;
2942 GLMatrixMode(GL_TEXTURE);
2944 GLMatrixMode(MatrixMode::projection);
2945 GLSetupTexturing(shaders, false); // TODO: Special shading code for stipple?
2950 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
2951 void SetRenderState(Display display, RenderState state, uint value)
2953 OGLDisplay oglDisplay = display.driverData;
2954 GLCapabilities capabilities = oglDisplay.capabilities;
2955 #if ENABLE_GL_LEGACY
2956 bool legacy = capabilities.legacy;
2958 bool shaders = capabilities.shaders;
2963 #ifndef __EMSCRIPTEN__
2965 glEnable(GL_MULTISAMPLE_ARB);
2967 glDisable(GL_MULTISAMPLE_ARB);
2971 #if ENABLE_GL_LEGACY
2973 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
2977 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
2980 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
2981 oglDisplay.depthWrite = (bool)value;
2985 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
2986 #if ENABLE_GL_SHADERS
2988 shader_fogColor(color[0], color[1], color[2]);
2993 glFogfv(GL_FOG_COLOR, (float *)&color);
2998 #if ENABLE_GL_SHADERS
3000 shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
3005 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
3009 //#if !defined(__EMSCRIPTEN__)
3010 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
3015 #if ENABLE_GL_SHADERS
3017 shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
3023 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3024 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
3031 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
3036 #if defined(__WIN32__)
3037 if(wglSwapIntervalEXT)
3038 wglSwapIntervalEXT(value ? 1 : 0);
3045 void SetLight(Display display, int id, Light light)
3047 OGLDisplay oglDisplay = display.driverData;
3048 GLCapabilities capabilities = oglDisplay.capabilities;
3049 bool shaders = capabilities.shaders;
3051 #if ENABLE_GL_SHADERS
3053 shader_setLight(display, id, light);
3061 Object lightObject = light.lightObject;
3062 float position[4] = { 0, 0, 0, 0 };
3063 float color[4] = { 0, 0, 0, 1 };
3065 glEnable(GL_LIGHT0 + id);
3067 if(!light.multiplier) light.multiplier = 1.0f;
3069 color[0] = light.diffuse.r * light.multiplier;
3070 color[1] = light.diffuse.g * light.multiplier;
3071 color[2] = light.diffuse.b * light.multiplier;
3072 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
3074 color[0] = light.ambient.r * light.multiplier;
3075 color[1] = light.ambient.g * light.multiplier;
3076 color[2] = light.ambient.b * light.multiplier;
3077 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
3078 color[0] = light.specular.r * light.multiplier;
3079 color[1] = light.specular.g * light.multiplier;
3080 color[2] = light.specular.b * light.multiplier;
3081 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
3085 Vector3D positionVector;
3086 if(light.flags.spot)
3088 if(lightObject.flags.root || !lightObject.parent)
3090 positionVector = lightObject.transform.position;
3091 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3095 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
3096 if(display.display3D.camera)
3097 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3103 if(!light.direction.x && !light.direction.y && !light.direction.z)
3105 Vector3Df vector { 0,0,-1 };
3107 mat.RotationQuaternion(light.orientation);
3108 positionVector.MultMatrixf(vector, mat);
3112 positionVector = light.direction;
3117 position[0] = (float)positionVector.x;
3118 position[1] = (float)positionVector.y;
3119 position[2] = (float)positionVector.z;
3121 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3124 // Display Light Position
3125 glDisable(GL_LIGHTING);
3126 glDisable(GL_DEPTH_TEST);
3130 glVertex3fv(position);
3132 glEnable(GL_DEPTH_TEST);
3133 glEnable(GL_LIGHTING);
3137 if(lightObject.flags.root || !lightObject.parent)
3139 positionVector = light.target.transform.position;
3140 positionVector.Subtract(positionVector, display.camera.cPosition);
3144 positionVector.MultMatrix(light.target.transform.position,
3145 lightObject.light.target.parent.matrix);
3146 positionVector.Subtract(positionVector, display.camera.cPosition);
3149 position[0] = positionVector.x;
3150 position[1] = positionVector.y;
3151 position[2] = positionVector.z;
3153 glDisable(GL_LIGHTING);
3154 glDisable(GL_DEPTH_TEST);
3158 glVertex3fv(position);
3160 glEnable(GL_DEPTH_TEST);
3161 glEnable(GL_LIGHTING);
3164 if(light.flags.attenuation)
3166 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
3167 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
3168 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
3171 if(light.flags.spot)
3174 #define MAXLIGHT 0.9
3175 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
3176 // Figure out exponent out of the hot spot
3177 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
3179 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
3180 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
3181 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
3186 Vector3Df vector { 0,0,-1 };
3187 Vector3Df direction;
3190 mat.RotationQuaternion(light.orientation);
3191 direction.MultMatrix(vector, mat);
3193 position[0] = direction.x;
3194 position[1] = direction.y;
3195 position[2] = direction.z;
3197 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3201 glDisable(GL_LIGHT0 + id);
3206 void SetCamera(Display display, Surface surface, Camera camera)
3208 OGLDisplay oglDisplay = display.driverData;
3209 GLCapabilities capabilities = oglDisplay.capabilities;
3210 #if ENABLE_GL_LEGACY
3211 bool fixedFunction = capabilities.fixedFunction;
3213 bool shaders = capabilities.shaders;
3215 if(surface && camera)
3217 int left = surface.box.left + surface.offset.x;
3218 int top = surface.box.top + surface.offset.y;
3219 int right = surface.box.right + surface.offset.x;
3220 int bottom = surface.box.bottom + surface.offset.y;
3221 float origX = surface.offset.x + camera.origin.x;
3222 float origY = surface.offset.y + camera.origin.y;
3224 int y = display.height - bottom - 1;
3225 int w = right - left + 1;
3226 int h = bottom - top + 1;
3229 glViewport(x, y, w, h);
3231 // *** Projection Matrix ***
3232 GLMatrixMode(MatrixMode::projection);
3233 if(!display.display3D.camera)
3236 if(display.display3D.collectingHits)
3238 float pickX = display.display3D.pickX + surface.offset.x;
3239 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3243 w / display.display3D.pickWidth, 0, 0, 0,
3244 0, h / display.display3D.pickHeight, 0, 0,
3246 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3247 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3250 GLLoadMatrixd(pickMatrix.array);
3255 (left - origX) * camera.zMin / camera.focalX,
3256 (right - origX) * camera.zMin / camera.focalX,
3257 (bottom - origY) * camera.zMin / camera.focalY,
3258 (top - origY) * camera.zMin / camera.focalY,
3259 camera.zMin, camera.zMax);
3261 glDisable(GL_BLEND);
3263 // *** Z Inverted Identity Matrix ***
3264 GLMatrixMode(MatrixMode::modelView);
3265 if(!display.display3D.camera)
3270 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3272 // *** View Matrix ***
3273 GLMultMatrixd(camera.viewMatrix.array);
3278 glEnable(GL_DEPTH_TEST);
3280 GLSetupLighting(shaders, true);
3283 glShadeModel(GL_SMOOTH);
3285 glDepthMask((byte)bool::true);
3286 oglDisplay.depthWrite = true;
3288 #ifndef __EMSCRIPTEN__
3289 glEnable(GL_MULTISAMPLE_ARB);
3292 else if(surface && display.display3D.camera)
3295 oglDisplay.depthWrite = false;
3296 glViewport(0,0,display.width,display.height);
3298 glDisable(GL_CULL_FACE);
3299 glDisable(GL_DEPTH_TEST);
3301 GLSetupTexturing(shaders, false);
3302 GLSetupLighting(shaders, false);
3303 GLSetupFog(shaders, false);
3305 GLDisableClientState(COLORS);
3307 #if ENABLE_GL_SHADERS
3309 shader_setPerVertexColor(false);
3314 glShadeModel(GL_FLAT);
3317 #if !defined(__EMSCRIPTEN__)
3318 glDisable(GL_MULTISAMPLE_ARB);
3321 // *** Restore 2D MODELVIEW Matrix ***
3324 // *** Restore 2D PROJECTION Matrix ***
3325 GLMatrixMode(MatrixMode::projection);
3331 void ApplyMaterial(Display display, Material material, Mesh mesh)
3333 OGLDisplay oglDisplay = display.driverData;
3334 GLCapabilities capabilities = oglDisplay.capabilities;
3335 #if ENABLE_GL_LEGACY
3336 bool fixedFunction = capabilities.fixedFunction;
3338 bool shaders = capabilities.shaders;
3341 if(material.flags.doubleSided)
3345 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3347 glDisable(GL_CULL_FACE);
3353 GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3355 glEnable(GL_CULL_FACE);
3359 GLSetupFog(shaders, !material.flags.noFog);
3362 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3364 Bitmap map = material.baseMap;
3365 GLSetupTexturing(shaders, true);
3366 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3368 GLMatrixMode(GL_TEXTURE);
3370 if(material.uScale && material.vScale)
3371 GLScalef(material.uScale, material.vScale, 1);
3372 GLMatrixMode(MatrixMode::modelView);
3374 if(material.flags.tile)
3376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3377 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3381 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3382 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3386 GLSetupTexturing(shaders, false);
3388 #if ENABLE_GL_SHADERS
3390 shader_setMaterial(material, mesh.flags.colors);
3396 if(mesh.flags.colors)
3398 GLColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3399 glEnable(GL_COLOR_MATERIAL);
3403 glDisable(GL_COLOR_MATERIAL);
3405 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3406 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3409 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3410 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3414 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3415 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3418 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3419 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3422 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3427 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3429 OGLMesh oglMesh = mesh.data;
3432 OGLDisplay oglSystem = displaySystem.driverData;
3433 GLCapabilities capabilities = oglSystem.capabilities;
3434 bool vertexBuffer = capabilities.vertexBuffer;
3435 if(!mesh.flags.vertices)
3437 oglMesh.vertices.free(vertexBuffer);
3438 delete mesh.vertices;
3440 if(!mesh.flags.normals)
3442 oglMesh.normals.free(vertexBuffer);
3443 delete mesh.normals;
3445 if(!mesh.flags.texCoords1)
3447 oglMesh.texCoords.free(vertexBuffer);
3448 delete mesh.texCoords;
3450 if(!mesh.flags.texCoords2)
3452 oglMesh.texCoords2.free(vertexBuffer);
3453 // delete mesh.texCoords2;
3455 if(!mesh.flags.colors)
3457 oglMesh.colors.free(vertexBuffer);
3468 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3470 bool result = false;
3473 mesh.data = OGLMesh { };
3476 if(mesh.nVertices == nVertices)
3478 // Same number of vertices, adding features (Leaves the other features pointers alone)
3479 if(mesh.flags != flags)
3481 if(!mesh.flags.vertices && flags.vertices)
3483 if(flags.doubleVertices)
3485 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3488 mesh.vertices = new Vector3Df[nVertices];
3490 if(!mesh.flags.normals && flags.normals)
3492 if(flags.doubleNormals)
3494 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3497 mesh.normals = new Vector3Df[nVertices];
3499 if(!mesh.flags.texCoords1 && flags.texCoords1)
3501 mesh.texCoords = new Pointf[nVertices];
3503 if(!mesh.flags.colors && flags.colors)
3505 mesh.colors = new ColorRGBAf[nVertices];
3511 // New number of vertices, reallocate all current and new features
3512 flags |= mesh.flags;
3515 if(flags.doubleVertices)
3517 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3520 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3524 if(flags.doubleNormals)
3526 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3529 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3531 if(flags.texCoords1)
3533 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3537 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3545 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3547 OGLSystem oglSystem = displaySystem.driverData;
3548 GLCapabilities capabilities = oglSystem.capabilities;
3549 bool vertexBuffer = capabilities.vertexBuffer;
3552 OGLMesh oglMesh = mesh.data;
3553 if(!flags) flags = mesh.flags;
3555 oglMesh.vertices.upload(vertexBuffer,
3556 mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
3559 oglMesh.normals.upload(vertexBuffer,
3560 mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
3562 if(flags.texCoords1)
3563 oglMesh.texCoords.upload(vertexBuffer,
3564 mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
3567 oglMesh.colors.upload(vertexBuffer,
3568 mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
3572 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3579 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3581 OGLSystem oglSystem = displaySystem.driverData;
3582 GLCapabilities capabilities = oglSystem.capabilities;
3583 bool vertexBuffer = capabilities.vertexBuffer;
3586 oglIndices.buffer.free(vertexBuffer);
3587 delete oglIndices.indices;
3592 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
3594 OGLIndices oglIndices = OGLIndices { };
3597 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
3598 oglIndices.nIndices = nIndices;
3603 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
3605 OGLSystem oglSystem = displaySystem.driverData;
3606 GLCapabilities capabilities = oglSystem.capabilities;
3607 bool vertexBuffer = capabilities.vertexBuffer;
3610 #if !ENABLE_GL_INTDBL
3613 if(!oglIndices.buffer.buffer)
3614 glGenBuffers(1, &oglIndices.buffer.buffer);
3615 if(glabCurElementBuffer != oglIndices.buffer.buffer)
3616 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
3617 glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
3621 oglIndices.buffer.upload(vertexBuffer,
3622 nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
3623 oglIndices.indices); //GL_STATIC_DRAW_ARB);
3627 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
3630 return oglIndices.indices;
3633 void SelectMesh(Display display, Mesh mesh)
3635 OGLDisplay oglDisplay = display.driverData;
3636 GLCapabilities capabilities = oglDisplay.capabilities;
3637 #if ENABLE_GL_SHADERS && ENABLE_GL_FFP
3638 bool shaders = capabilities.shaders;
3641 #if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3642 bool vertexBuffer = capabilities.vertexBuffer;
3644 #if defined(__WIN32__)
3645 if(glUnlockArraysEXT)
3647 if(!vertexBuffer && display.display3D.mesh)
3648 glUnlockArraysEXT();
3653 OGLMesh oglMesh = mesh.data;
3655 // *** Vertex Stream ***
3656 GLEnableClientState(VERTICES);
3657 if(!display.display3D.collectingHits && oglMesh)
3659 oglMesh.vertices.use(capabilities, vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
3661 // *** Normals Stream ***
3662 if(mesh.normals || mesh.flags.normals)
3664 GLEnableClientState(NORMALS);
3665 oglMesh.normals.use(capabilities, normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
3668 GLDisableClientState(NORMALS);
3670 // *** Texture Coordinates Stream ***
3671 if(mesh.texCoords || mesh.flags.texCoords1)
3673 GLEnableClientState(TEXTURECOORDS);
3674 oglMesh.texCoords.use(capabilities, texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
3677 GLDisableClientState(TEXTURECOORDS);
3679 // *** Color Stream ***
3680 if(mesh.colors || mesh.flags.colors)
3682 GLEnableClientState(COLORS);
3683 oglMesh.colors.use(capabilities, color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
3686 GLDisableClientState(COLORS);
3690 noAB.use(capabilities, vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
3691 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
3693 GLEnableClientState(NORMALS);
3694 noAB.use(capabilities, normal, 3, GL_FLOAT, 0, mesh.normals);
3697 GLDisableClientState(NORMALS);
3698 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
3700 GLEnableClientState(TEXTURECOORDS);
3701 noAB.use(capabilities, texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
3704 GLDisableClientState(TEXTURECOORDS);
3705 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
3707 GLEnableClientState(COLORS);
3708 noAB.use(capabilities, color, 4, GL_FLOAT, 0, mesh.colors);
3711 GLDisableClientState(COLORS);
3714 #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
3716 #if defined(__WIN32__)
3720 glLockArraysEXT(0, mesh.nVertices);
3725 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
3727 OGLDisplay oglDisplay = display.driverData;
3728 GLCapabilities capabilities = oglDisplay.capabilities;
3729 bool vertexBuffer = capabilities.vertexBuffer;
3731 if(primitive->type.vertexRange)
3732 glDrawArrays(getPrimitiveType(oglDisplay.capabilities.quads, primitive->type.primitiveType), primitive->first, primitive->nVertices);
3735 OGLIndices oglIndices = primitive->data;
3736 GLEAB eab = ((!display.display3D.collectingHits && oglIndices && vertexBuffer) ? oglIndices.buffer : noEAB);
3737 #if !ENABLE_GL_INTDBL
3738 if(!vertexBuffer && primitive->type.indices32bit)
3740 uint16 * temp = new uint16[primitive->nIndices];
3741 uint32 * src = (uint32 *)(oglIndices ? oglIndices.indices : primitive->indices);
3743 for(i = 0; i < primitive->nIndices; i++)
3744 temp[i] = (uint16)src[i];
3745 eab.draw(vertexBuffer, getPrimitiveType(oglDisplay.capabilities.quads, primitive->type.primitiveType), primitive->nIndices, GL_UNSIGNED_SHORT, temp);
3750 eab.draw(vertexBuffer, getPrimitiveType(oglDisplay.capabilities.quads, primitive->type.primitiveType), primitive->nIndices,
3751 primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
3752 eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
3753 GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3757 void PushMatrix(Display display)
3759 #if ENABLE_GL_LEGACY
3760 OGLDisplay oglDisplay = display.driverData;
3761 GLCapabilities capabilities = oglDisplay.capabilities;
3762 bool fixedFunction = capabilities.fixedFunction;
3763 bool shaders = capabilities.shaders;
3768 void PopMatrix(Display display, bool setMatrix)
3770 OGLDisplay oglDisplay = display.driverData;
3771 GLCapabilities capabilities = oglDisplay.capabilities;
3772 #if ENABLE_GL_LEGACY
3773 bool fixedFunction = capabilities.fixedFunction;
3775 bool shaders = capabilities.shaders;
3779 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
3781 OGLDisplay oglDisplay = display.driverData;
3782 GLCapabilities capabilities = oglDisplay.capabilities;
3783 #if ENABLE_GL_LEGACY
3784 bool fixedFunction = capabilities.fixedFunction;
3786 bool shaders = capabilities.shaders;
3787 Matrix matrix = transMatrix;
3788 Camera camera = useCamera ? display.display3D.camera : null;
3793 GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3798 matrix.m[3][0] - camera.cPosition.x,
3799 matrix.m[3][1] - camera.cPosition.y,
3800 matrix.m[3][2] - camera.cPosition.z);
3812 GLMultMatrixd(matrix.array);
3817 public void UseSingleGLContext(bool useSingle)
3819 useSingleGLContext = useSingle;
3822 default dllexport void *
3823 #if defined(__WIN32__)
3824 __attribute__((stdcall))
3826 IS_GLGetContext(DisplaySystem displaySystem)
3830 #if defined(__WIN32__)
3831 OGLSystem system = displaySystem.driverData;
3833 #elif defined(__ANDROID__) || defined(__ODROID__)
3835 #elif defined(__EMSCRIPTEN__)
3836 OGLSystem system = displaySystem.driverData;
3837 return (void *)system.glc;
3839 OGLSystem system = displaySystem.driverData;
3840 return system.glContext;