1 // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
4 namespace gfx::drivers;
7 #if defined(__unix__) || defined(__APPLE__)
9 #if !defined(__MINGW32__)
10 #define GL_GLEXT_PROTOTYPES
13 #define pointer _pointer
17 //#include <GL/miniglx.h>
21 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
23 #define property _property
27 #define Window X11Window
28 #define Cursor X11Cursor
30 #define Display X11Display
32 #define KeyCode X11KeyCode
33 #define Picture X11Picture
37 #include <X11/Xutil.h>
39 #include <X11/extensions/XShm.h>
42 #include <X11/extensions/Xrender.h>
43 #include <X11/extensions/shape.h>
63 #if defined(__APPLE__)
64 #include <OpenGl/gl.h>
67 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
69 #if defined(__WIN32__)
70 #define WIN32_LEAN_AND_MEAN
72 #define _WIN32_WINNT 0x0502
78 #if defined(__ANDROID__)
83 #elif defined(__EMSCRIPTEN__)
85 #define property _property
90 //#include <GLES/gl.h>
91 //#include <EGL/egl.h>
93 //#include <GLES2/gl.h>
94 //#include <EGL/egl.h>
96 //#include <GLES2/gl2.h>
98 #include <emscripten/emscripten.h>
106 #include <GL/glext.h>
114 #if defined(__unix__) || defined(__APPLE__)
116 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
122 static double nearPlane = 1;
124 public double glesGetNearPlane()
129 public void glesSetNearPlane(double value)
134 #define glLoadMatrix glLoadMatrixd
135 #define glMultMatrix glMultMatrixd
136 #define glGetMatrix glGetDoublev
137 #define glTranslate glTranslated
138 #define glScale glScaled
141 #define glVertex3v glVertex3dv
142 #define glNormal3v glNormal3dv
146 //#ifdef VERTEX_FORMAT_DOUBLE
148 #define glLoadMatrix glLoadMatrixd
149 #define glMultMatrix glMultMatrixd
150 #define glGetMatrix glGetDoublev
151 #define glVertex3v glVertex3dv
152 #define glNormal3v glNormal3dv
153 #define glTranslate glTranslated
154 #define glScale glScaled
155 //#define GL_VERTEX_FORMAT GL_DOUBLE
159 #define glLoadMatrix glLoadMatrixf
160 #define glMultMatrix glMultMatrixf
161 #define glGetMatrix glGetFloatv
162 #define glVertex3v glVertex3fv
163 #define glNormal3v glNormal3fv
164 #define glTranslate glTranslatef
165 #define glScale glScalef
166 //#define GL_VERTEX_FORMAT GL_FLOAT
171 #define GL_ARRAY_BUFFER_ARB 0x8892
172 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
173 #define GL_STATIC_DRAW_ARB 0x88E4
174 #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
175 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
177 #define GL_MULTISAMPLE_ARB 0x809D
179 #if defined(__WIN32__)
181 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
182 #define WGL_SAMPLES_ARB 0x2042
184 #define WGL_WGLEXT_VERSION 1
185 #define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
186 #define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
187 #define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
188 #define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
189 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
190 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
191 #define WGL_DRAW_TO_BITMAP_ARB 0x2002
192 #define WGL_ACCELERATION_ARB 0x2003
193 #define WGL_NEED_PALETTE_ARB 0x2004
194 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
195 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
196 #define WGL_SWAP_METHOD_ARB 0x2007
197 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
198 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
199 #define WGL_TRANSPARENT_ARB 0x200A
200 #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
201 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
202 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
203 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
204 #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
205 #define WGL_SHARE_DEPTH_ARB 0x200C
206 #define WGL_SHARE_STENCIL_ARB 0x200D
207 #define WGL_SHARE_ACCUM_ARB 0x200E
208 #define WGL_SUPPORT_GDI_ARB 0x200F
209 #define WGL_SUPPORT_OPENGL_ARB 0x2010
210 #define WGL_DOUBLE_BUFFER_ARB 0x2011
211 #define WGL_STEREO_ARB 0x2012
212 #define WGL_PIXEL_TYPE_ARB 0x2013
213 #define WGL_COLOR_BITS_ARB 0x2014
214 #define WGL_RED_BITS_ARB 0x2015
215 #define WGL_RED_SHIFT_ARB 0x2016
216 #define WGL_GREEN_BITS_ARB 0x2017
217 #define WGL_GREEN_SHIFT_ARB 0x2018
218 #define WGL_BLUE_BITS_ARB 0x2019
219 #define WGL_BLUE_SHIFT_ARB 0x201A
220 #define WGL_ALPHA_BITS_ARB 0x201B
221 #define WGL_ALPHA_SHIFT_ARB 0x201C
222 #define WGL_ACCUM_BITS_ARB 0x201D
223 #define WGL_ACCUM_RED_BITS_ARB 0x201E
224 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
225 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
226 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
227 #define WGL_DEPTH_BITS_ARB 0x2022
228 #define WGL_STENCIL_BITS_ARB 0x2023
229 #define WGL_AUX_BUFFERS_ARB 0x2024
230 #define WGL_NO_ACCELERATION_ARB 0x2025
231 #define WGL_GENERIC_ACCELERATION_ARB 0x2026
232 #define WGL_FULL_ACCELERATION_ARB 0x2027
233 #define WGL_SWAP_EXCHANGE_ARB 0x2028
234 #define WGL_SWAP_COPY_ARB 0x2029
235 #define WGL_SWAP_UNDEFINED_ARB 0x202A
236 #define WGL_TYPE_RGBA_ARB 0x202B
237 #define WGL_TYPE_COLORINDEX_ARB 0x202C
238 #define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
239 #define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
240 #define WGL_DRAW_TO_PBUFFER_ARB 0x202D
241 #define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
242 #define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
243 #define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
244 #define WGL_PBUFFER_LARGEST_ARB 0x2033
245 #define WGL_PBUFFER_WIDTH_ARB 0x2034
246 #define WGL_PBUFFER_HEIGHT_ARB 0x2035
247 #define WGL_PBUFFER_LOST_ARB 0x2036
248 #define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
249 #define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
250 #define WGL_DRAW_TO_WINDOW_EXT 0x2001
251 #define WGL_DRAW_TO_BITMAP_EXT 0x2002
252 #define WGL_ACCELERATION_EXT 0x2003
253 #define WGL_NEED_PALETTE_EXT 0x2004
254 #define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
255 #define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
256 #define WGL_SWAP_METHOD_EXT 0x2007
257 #define WGL_NUMBER_OVERLAYS_EXT 0x2008
258 #define WGL_NUMBER_UNDERLAYS_EXT 0x2009
259 #define WGL_TRANSPARENT_EXT 0x200A
260 #define WGL_TRANSPARENT_VALUE_EXT 0x200B
261 #define WGL_SHARE_DEPTH_EXT 0x200C
262 #define WGL_SHARE_STENCIL_EXT 0x200D
263 #define WGL_SHARE_ACCUM_EXT 0x200E
264 #define WGL_SUPPORT_GDI_EXT 0x200F
265 #define WGL_SUPPORT_OPENGL_EXT 0x2010
266 #define WGL_DOUBLE_BUFFER_EXT 0x2011
267 #define WGL_STEREO_EXT 0x2012
268 #define WGL_PIXEL_TYPE_EXT 0x2013
269 #define WGL_COLOR_BITS_EXT 0x2014
270 #define WGL_RED_BITS_EXT 0x2015
271 #define WGL_RED_SHIFT_EXT 0x2016
272 #define WGL_GREEN_BITS_EXT 0x2017
273 #define WGL_GREEN_SHIFT_EXT 0x2018
274 #define WGL_BLUE_BITS_EXT 0x2019
275 #define WGL_BLUE_SHIFT_EXT 0x201A
276 #define WGL_ALPHA_BITS_EXT 0x201B
277 #define WGL_ALPHA_SHIFT_EXT 0x201C
278 #define WGL_ACCUM_BITS_EXT 0x201D
279 #define WGL_ACCUM_RED_BITS_EXT 0x201E
280 #define WGL_ACCUM_GREEN_BITS_EXT 0x201F
281 #define WGL_ACCUM_BLUE_BITS_EXT 0x2020
282 #define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
283 #define WGL_DEPTH_BITS_EXT 0x2022
284 #define WGL_STENCIL_BITS_EXT 0x2023
285 #define WGL_AUX_BUFFERS_EXT 0x2024
286 #define WGL_NO_ACCELERATION_EXT 0x2025
287 #define WGL_GENERIC_ACCELERATION_EXT 0x2026
288 #define WGL_FULL_ACCELERATION_EXT 0x2027
289 #define WGL_SWAP_EXCHANGE_EXT 0x2028
290 #define WGL_SWAP_COPY_EXT 0x2029
291 #define WGL_SWAP_UNDEFINED_EXT 0x202A
292 #define WGL_TYPE_RGBA_EXT 0x202B
293 #define WGL_TYPE_COLORINDEX_EXT 0x202C
294 #define WGL_DRAW_TO_PBUFFER_EXT 0x202D
295 #define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
296 #define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
297 #define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
298 #define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
299 #define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
300 #define WGL_PBUFFER_LARGEST_EXT 0x2033
301 #define WGL_PBUFFER_WIDTH_EXT 0x2034
302 #define WGL_PBUFFER_HEIGHT_EXT 0x2035
303 #define WGL_DEPTH_FLOAT_EXT 0x2040
304 #define WGL_SAMPLE_BUFFERS_3DFX 0x2060
305 #define WGL_SAMPLES_3DFX 0x2061
306 #define WGL_SAMPLE_BUFFERS_EXT 0x2041
307 #define WGL_SAMPLES_EXT 0x2042
308 #define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
309 #define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
310 #define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
311 #define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
312 #define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
313 #define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
314 #define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
315 #define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
316 #define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
317 #define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
318 #define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
319 #define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
320 #define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
321 #define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
322 #define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
323 #define WGL_ARB_buffer_region 1
324 #define WGL_ARB_extensions_string 1
325 #define WGL_ARB_pixel_format 1
326 #define WGL_ARB_make_current_read 1
327 #define WGL_ARB_pbuffer 1
328 #define WGL_EXT_display_color_table 1
329 #define WGL_EXT_extensions_string 1
330 #define WGL_EXT_make_current_read 1
331 #define WGL_EXT_pbuffer 1
332 #define WGL_EXT_pixel_format 1
333 #define WGL_EXT_swap_control 1
334 #define WGL_WGL_EXT_depth_float 1
335 #define WGL_WGL_3DFX_multisample 1
336 #define WGL_WGL_EXT_multisample 1
337 #define WGL_NV_allocate_memory 1
340 typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum target);
341 typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
342 typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum target);
343 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
344 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
348 typedef int (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
349 typedef int (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
350 typedef int (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
351 typedef int (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
353 typedef int (APIENTRY * PFNWGLCHOOSEPIXELFORMATARBPROC) ();
354 typedef void * (APIENTRY * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
355 typedef HDC (APIENTRY * PFNWGLGETPBUFFERDCARBPROC) (void * hPbuffer);
356 typedef int (APIENTRY * PFNWGLRELEASEPBUFFERDCARBPROC) (void * hPbuffer, HDC hDC);
357 typedef BOOL (APIENTRY * PFNWGLDESTROYPBUFFERARBPROC) (void * hPbuffer);
358 typedef BOOL (APIENTRY * PFNWGLQUERYPBUFFERARBPROC) (void * hPbuffer, int iAttribute, int *piValue);
359 typedef const char * (APIENTRY * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
360 typedef BOOL (APIENTRY * PFNWGLBINDTEXIMAGEARBPROC) (void * hPbuffer, int iBuffer);
361 typedef BOOL (APIENTRY * PFNWGLRELEASETEXIMAGEARBPROC) (void * hPbuffer, int iBuffer);
363 static PFNGLMAPBUFFERARBPROC glMapBufferARB = null;
364 static PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = null;
365 static PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = null;
366 static PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = null;
367 static PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = null;
368 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
369 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
370 static PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate = null;
372 static PFNGLGENBUFFERSARBPROC glGenBuffersARB = null;
373 static PFNGLBINDBUFFERARBPROC glBindBufferARB = null;
374 static PFNGLBUFFERDATAARBPROC glBufferDataARB = null;
375 static PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = null;
376 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
377 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
378 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
379 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
380 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
381 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
382 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
383 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
384 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
386 #define glBufferData glBufferDataARB
388 #ifdef WGL_WGLEXT_PROTOTYPES
389 extern BOOL WINAPI wglSwapIntervalEXT (int);
390 extern int WINAPI wglGetSwapIntervalEXT (void);
391 #endif /* WGL_WGLEXT_PROTOTYPES */
392 typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
393 typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
395 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
397 #elif defined(__ANDROID__)
399 #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
400 #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
401 #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
403 #define GL_POLYGON_STIPPLE 0xFFFF
404 #define GL_LINE_STIPPLE 0xFFFF
405 #define GL_LINE 0xFFFF
406 #define GL_FILL 0xFFFF
407 #define GL_ALL_ATTRIB_BITS 0xFFFF
408 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
414 #define GL_QUAD_STRIP 0
415 //#define GL_DOUBLE 0
416 //#define GL_UNSIGNED_INT 0
419 //#define GL_LINE_STIPPLE 0
420 #define GL_BGRA_EXT 0
421 #define GL_UNPACK_ROW_LENGTH 0
422 #define GL_UNPACK_SKIP_PIXELS 0
423 #define GL_UNPACK_SKIP_ROWS 0
425 #define GL_PACK_ROW_LENGTH 0
426 #define GL_PACK_SKIP_ROWS 0
427 #define GL_PACK_SKIP_PIXELS 0
431 #if defined(ECERE_NO3D) || defined(ECERE_VANILLA)
439 FillBytesBy4(this, 0, sizeof(Matrix) >> 2);
440 m[0][0]=m[1][1]=m[2][2]=m[3][3]=1;
443 void Transpose(Matrix source)
448 m[j][i] = source.m[i][j];
451 void Multiply(Matrix a, Matrix b)
453 // We need a full matrix multiplication for the Projection matrix
454 m[0][0]=a.m[0][0]*b.m[0][0] + a.m[0][1]*b.m[1][0] + a.m[0][2]*b.m[2][0] + a.m[0][3]*b.m[3][0];
455 m[0][1]=a.m[0][0]*b.m[0][1] + a.m[0][1]*b.m[1][1] + a.m[0][2]*b.m[2][1] + a.m[0][3]*b.m[3][1];
456 m[0][2]=a.m[0][0]*b.m[0][2] + a.m[0][1]*b.m[1][2] + a.m[0][2]*b.m[2][2] + a.m[0][3]*b.m[3][2];
457 m[0][3]=a.m[0][0]*b.m[0][3] + a.m[0][1]*b.m[1][3] + a.m[0][2]*b.m[2][3] + a.m[0][3]*b.m[3][3];
459 m[1][0]=a.m[1][0]*b.m[0][0] + a.m[1][1]*b.m[1][0] + a.m[1][2]*b.m[2][0] + a.m[1][3]*b.m[3][0];
460 m[1][1]=a.m[1][0]*b.m[0][1] + a.m[1][1]*b.m[1][1] + a.m[1][2]*b.m[2][1] + a.m[1][3]*b.m[3][1];
461 m[1][2]=a.m[1][0]*b.m[0][2] + a.m[1][1]*b.m[1][2] + a.m[1][2]*b.m[2][2] + a.m[1][3]*b.m[3][2];
462 m[1][3]=a.m[1][0]*b.m[0][3] + a.m[1][1]*b.m[1][3] + a.m[1][2]*b.m[2][3] + a.m[1][3]*b.m[3][3];
464 m[2][0]=a.m[2][0]*b.m[0][0] + a.m[2][1]*b.m[1][0] + a.m[2][2]*b.m[2][0] + a.m[2][3]*b.m[3][0];
465 m[2][1]=a.m[2][0]*b.m[0][1] + a.m[2][1]*b.m[1][1] + a.m[2][2]*b.m[2][1] + a.m[2][3]*b.m[3][1];
466 m[2][2]=a.m[2][0]*b.m[0][2] + a.m[2][1]*b.m[1][2] + a.m[2][2]*b.m[2][2] + a.m[2][3]*b.m[3][2];
467 m[2][3]=a.m[2][0]*b.m[0][3] + a.m[2][1]*b.m[1][3] + a.m[2][2]*b.m[2][3] + a.m[2][3]*b.m[3][3];
469 m[3][0]=a.m[3][0]*b.m[0][0] + a.m[3][1]*b.m[1][0] + a.m[3][2]*b.m[2][0] + a.m[3][3]*b.m[3][0];
470 m[3][1]=a.m[3][0]*b.m[0][1] + a.m[3][1]*b.m[1][1] + a.m[3][2]*b.m[2][1] + a.m[3][3]*b.m[3][1];
471 m[3][2]=a.m[3][0]*b.m[0][2] + a.m[3][1]*b.m[1][2] + a.m[3][2]*b.m[2][2] + a.m[3][3]*b.m[3][2];
472 m[3][3]=a.m[3][0]*b.m[0][3] + a.m[3][1]*b.m[1][3] + a.m[3][2]*b.m[2][3] + a.m[3][3]*b.m[3][3];
477 // Our own matrix stack
478 static Matrix matrixStack[3][32];
479 static int matrixIndex[3];
480 static int curStack = 0;
484 // OpenGL ES Porting Kit
485 #if defined(__ANDROID__)
486 #define glBindFramebuffer glBindFramebufferOES
487 #define glBindRenderbuffer glBindRenderbufferOES
488 #define glFramebufferTexture2D glFramebufferTexture2DOES
489 #define glGenFramebuffers glGenFramebuffersOES
490 #define glGenRenderbuffers glGenRenderbuffersOES
491 #define glDeleteFramebuffers glDeleteFramebuffersOES
492 #define glDeleteRenderbuffers glDeleteRenderbuffersOES
494 #define GL_INT 0x1404
495 #define GL_UNSIGNED_INT 0x1405
496 #define GL_DOUBLE 0x140A
500 #define glDrawElementsi(type, count, start) glDrawElements(type, count, GL_UNSIGNED_SHORT, start)
502 #define glBufferDatai glesBufferDatai
503 #define glBufferDatad glesBufferDatad
504 #define glVertexPointeri glesVertexPointeri
505 #define glVertexPointerd glesVertexPointerd
507 #define glRecti glesRecti
508 #define glBegin glesBegin
509 #define glTexCoord2i glesTexCoord2i
510 #define glVertex2i glesVertex2i
511 #define glTexCoord2d glesTexCoord2d
512 #define glVertex2d glesVertex2d
513 #define glTexCoord2f glesTexCoord2f
514 #define glVertex2f glesVertex2f
515 #define glEnd glesEnd
516 #define glColor3f glesColor3f
517 #define glColor4ub glesColor4ub
518 #define glColor4fv glesColor4fv
519 #define glLineStipple glesLineStipple
520 #define glNormal3fv glesNormal3fv
521 #define glTexCoord2fv glesTexCoord2fv
522 #define glColorMaterial glesColorMaterial
524 #define glLoadMatrixd glesLoadMatrixd
525 #define glMultMatrixd glesMultMatrixd
526 #define glFrustum glesFrustum
527 #define glOrtho glesOrtho
528 #define glScaled glesScaled
529 #define glTranslated glesTranslated
530 #define glRotated glesRotated
531 #define glVertex3d glesVertex3d
532 #define glVertex3dv glesVertex3dv
533 #define glVertex3f glesVertex3f
534 #define glVertex3fv glesVertex3fv
535 #define glLightModeli glesLightModeli
539 #define glVertexPointerd(nc, s, p, nv) glVertexPointer(nc, GL_DOUBLE, s, p)
540 #define glDrawElementsi(type, count, start) glDrawElements(type, count, GL_UNSIGNED_INT, start)
544 #if defined(__ANDROID__)
545 static EGLDisplay eglDisplay;
546 static EGLSurface eglSurface;
547 static EGLContext eglContext;
548 static int eglWidth, eglHeight;
550 static bool egl_init_display(ANativeWindow* window)
552 const EGLint attribs[] =
554 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
558 EGL_DEPTH_SIZE, 16, //24,
559 /*EGL_SAMPLE_BUFFERS, 1,
560 EGL_SAMPLES, 0, //2,*/
569 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
570 eglInitialize(display, 0, 0);
571 eglChooseConfig(display, attribs, &config, 1, &numConfigs);
572 eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
574 surface = eglCreateWindowSurface(display, config, window, null);
575 context = eglCreateContext(display, config, null, null);
577 if(!eglMakeCurrent(display, surface, surface, context))
580 eglQuerySurface(display, surface, EGL_WIDTH, &w);
581 eglQuerySurface(display, surface, EGL_HEIGHT, &h);
583 eglDisplay = display;
584 eglContext = context;
585 eglSurface = surface;
589 glEnableClientState(GL_VERTEX_ARRAY);
591 // Initialize GL state.
592 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
593 glEnable(GL_CULL_FACE);
594 glShadeModel(GL_SMOOTH);
595 glDisable(GL_DEPTH_TEST);
597 glDisable(GL_CULL_FACE);
598 glDisable(GL_DEPTH_TEST);
600 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
603 matrixStack[0][0].Identity();
604 matrixStack[1][0].Identity();
605 matrixStack[2][0].Identity();
607 glesMatrixMode(GL_MODELVIEW);
608 glScaled(1.0, 1.0, -1.0);
609 glesMatrixMode(GL_PROJECTION);
610 glShadeModel(GL_FLAT);
612 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
613 glFogi(GL_FOG_MODE, GL_EXP);
614 glFogf(GL_FOG_DENSITY, 0);
615 glEnable(GL_NORMALIZE);
616 glDepthFunc(GL_LESS);
618 glDisable(GL_MULTISAMPLE_ARB);
622 glOrtho(0,w,h,0,0.0,1.0);
624 currentVertexBuffer = 0;
628 static void egl_term_display()
632 glDeleteTextures(1, &stippleTexture);
635 if(eglDisplay != EGL_NO_DISPLAY)
637 eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
638 if(eglContext != EGL_NO_CONTEXT)
639 eglDestroyContext(eglDisplay, eglContext);
640 if(eglSurface != EGL_NO_SURFACE)
641 eglDestroySurface(eglDisplay, eglSurface);
642 eglTerminate(eglDisplay);
644 eglDisplay = EGL_NO_DISPLAY;
645 eglContext = EGL_NO_CONTEXT;
646 eglSurface = EGL_NO_SURFACE;
651 // OpenGL Immediate Mode Porting Kit
652 static int beginCount;
653 static int vertexCount;
654 static int normalCount;
655 static float *vertexPointer;
656 static float *normalPointer;
657 static GLenum beginMode = -1;
658 static uint beginBufferSize, normalBufferSize;
659 static int numVertexCoords = 2;
660 static bool vertexColorValues = false;
661 static int vertexStride = 4;
662 static int vertexOffset = 2;
664 public void glesRecti(int a, int b, int c, int d)
674 public void glesBegin(GLenum mode)
679 vertexColorValues = false;
686 normalBufferSize = beginBufferSize = 1024; // default number of vertices
687 vertexPointer = new float[beginBufferSize * vertexStride];
688 normalPointer = new float[normalBufferSize * 3];
692 public void glesTexCoord2f(float x, float y)
694 int count = vertexCount;
696 if(vertexCount + numVertexCoords > beginBufferSize)
698 beginBufferSize = beginBufferSize + beginBufferSize/2;
699 vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
702 vertexPointer[count*vertexStride ] = x;
703 vertexPointer[count*vertexStride+1] = y;
706 if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
708 vertexPointer[count*vertexStride ] = vertexPointer[(count-4)*vertexStride];
709 vertexPointer[count*vertexStride+1] = vertexPointer[(count-4)*vertexStride+1];
711 vertexPointer[count*vertexStride ] = vertexPointer[(count-3)*vertexStride];
712 vertexPointer[count*vertexStride+1] = vertexPointer[(count-3)*vertexStride+1];
716 public void glesTexCoord2i(int x, int y) { glesTexCoord2f((float)x, (float)y); }
717 public void glesTexCoord2d(double x, double y) { glesTexCoord2f((float)x, (float)y); }
718 public void glesTexCoord2fv(float * a) { glesTexCoord2f(a[0], a[1]); }
720 public void glesVertex2f(float x, float y)
723 vertexStride = vertexOffset + numVertexCoords;
725 if(vertexCount + 4 > beginBufferSize)
727 beginBufferSize = beginBufferSize + beginBufferSize/2;
728 vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
731 vertexPointer[vertexCount*vertexStride+vertexOffset] = x;
732 vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = y;
735 if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
737 vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset];
738 vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset + 1];
740 vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset];
741 vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset + 1];
746 public void glesVertex2i(int x, int y) { glesVertex2f((float)x, (float)y); }
747 public void glesVertex2d(double x, double y) { glesVertex2f((float)x, (float)y); }
749 public void glesEnd(void)
751 int mode = beginMode;
752 if(mode == GL_QUADS) mode = GL_TRIANGLES;
753 else if(mode == GL_POLYGON) mode = GL_TRIANGLE_FAN;
756 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
757 glTexCoordPointer(2, GL_FLOAT, vertexStride * sizeof(float), vertexPointer);
758 if(vertexColorValues)
760 glEnableClientState(GL_COLOR_ARRAY);
761 glColorPointer(4, GL_FLOAT, vertexStride * sizeof(float), vertexPointer + 2);
763 glVertexPointer (numVertexCoords, GL_FLOAT, (vertexStride)*sizeof(float),vertexPointer+vertexOffset);
764 if(normalCount && normalCount == vertexCount)
766 glEnableClientState(GL_NORMAL_ARRAY);
767 glNormalPointer (GL_FLOAT, 3*sizeof(float),normalPointer);
770 glDrawArrays(mode, 0, vertexCount);
772 glDisableClientState(GL_NORMAL_ARRAY);
773 if(vertexColorValues)
774 glDisableClientState(GL_COLOR_ARRAY);
775 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
777 vertexColorValues = false;
783 static float *floatVPBuffer = null;
784 static short *shortVPBuffer = null;
785 static unsigned int shortVPSize = 0, floatVPSize = 0;
788 //static float *floatVPBuffer = null; // For floats we reuse floatVPBuffer
789 static unsigned short *shortBDBuffer = null;
790 static unsigned int shortBDSize = 0/*, floatVPSize = 0*/;
792 public void glesVertexPointeri(int numCoords, int stride, int *pointer, int numVertices)
797 if(numVertices*numCoords > shortVPSize)
799 shortVPSize = numVertices*numCoords;
800 shortVPBuffer = renew shortVPBuffer short[shortVPSize];
802 for(i = 0; i < numVertices*numCoords; i++)
803 shortVPBuffer[i] = (short)pointer[i];
804 glVertexPointer(numCoords, GL_SHORT, stride, shortVPBuffer);
807 glVertexPointer(numCoords, GL_SHORT, stride, 0);
810 public void glesVertexPointerd(int numCoords, int stride, double *pointer, int numVertices)
815 if(numVertices*numCoords > floatVPSize)
817 floatVPSize = numVertices*numCoords;
818 floatVPBuffer = renew floatVPBuffer float[floatVPSize];
820 for(i = 0; i < numVertices*numCoords; i++)
821 floatVPBuffer[i] = (float)pointer[i];
822 glVertexPointer(numCoords, GL_FLOAT, stride, floatVPBuffer);
825 glVertexPointer(numCoords, GL_FLOAT, stride, 0);
828 public void glesTexReuseIntVP(int numCoords)
830 glTexCoordPointer(numCoords, GL_SHORT, 0, floatVPBuffer);
833 public void glesTexReuseDoubleVP(int numCoords)
835 glTexCoordPointer(numCoords, GL_FLOAT, 0, floatVPBuffer);
838 public void glesColor4f(float r, float g, float b, float a)
840 if(beginMode != (GLenum)-1)
842 int count = vertexCount;
844 vertexColorValues = true;
846 vertexStride = vertexOffset + numVertexCoords;
848 if(vertexCount + vertexStride > beginBufferSize)
850 beginBufferSize = beginBufferSize + beginBufferSize/2;
851 vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
854 vertexPointer[count*vertexStride + 2] = r;
855 vertexPointer[count*vertexStride + 3] = g;
856 vertexPointer[count*vertexStride + 4] = b;
857 vertexPointer[count*vertexStride + 5] = a;
860 if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
862 vertexPointer[count*vertexStride + 2] = vertexPointer[(count-4) * vertexStride + 2];
863 vertexPointer[count*vertexStride + 3] = vertexPointer[(count-4) * vertexStride + 3];
864 vertexPointer[count*vertexStride + 4] = vertexPointer[(count-4) * vertexStride + 4];
865 vertexPointer[count*vertexStride + 5] = vertexPointer[(count-4) * vertexStride + 5];
867 vertexPointer[count*vertexStride + 2] = vertexPointer[(count-3) * vertexStride + 2];
868 vertexPointer[count*vertexStride + 3] = vertexPointer[(count-3) * vertexStride + 3];
869 vertexPointer[count*vertexStride + 4] = vertexPointer[(count-3) * vertexStride + 4];
870 vertexPointer[count*vertexStride + 5] = vertexPointer[(count-3) * vertexStride + 5];
875 glColor4f(r, g, b, a);
878 public void glesColor3f( float r, float g, float b )
880 glesColor4f(r, g, b, 1.0f);
883 public void glesColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
885 glesColor4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f);
888 public void glesColor4fv(float * a)
890 glesColor4f(a[0], a[1], a[2], a[3]);
893 public void glesBufferDatad(int target, int size, void * data, int usage)
895 int numElems = size/sizeof(double);
896 double * dblPtr = (double *)data;
898 if (numElems > floatVPSize)
900 floatVPSize = numElems;
901 floatVPBuffer = renew floatVPBuffer float[floatVPSize];
903 for (i=0; i< numElems; i++)
904 floatVPBuffer[i] = (float)dblPtr[i];
906 glBufferData(target, numElems*sizeof(float), floatVPBuffer, usage);
909 public void glesBufferDatai(int target, int size, void * data, int usage)
911 int numElems = size/sizeof(unsigned int);
912 unsigned int * pointer = (unsigned int *)data;
914 if (numElems > shortBDSize)
916 shortBDSize = numElems;
917 shortBDBuffer = renew shortBDBuffer uint16[shortBDSize];
919 for (i=0; i< numElems; i++)
920 shortBDBuffer[i] = (unsigned short)pointer[i];
922 glBufferData(target, numElems*sizeof(unsigned short), shortBDBuffer, usage);
925 // *** Our Custom Matrix Stack ***
927 static void LoadCurMatrix()
929 double * i = matrixStack[curStack][matrixIndex[curStack]].array;
932 (float)i[0],(float)i[1],(float)i[2],(float)i[3],
933 (float)i[4],(float)i[5],(float)i[6],(float)i[7],
934 (float)i[8],(float)i[9],(float)i[10],(float)i[11],
935 (float)i[12],(float)i[13],(float)i[14],(float)i[15]
940 public void glesLoadIdentity()
942 matrixStack[curStack][matrixIndex[curStack]].Identity();
946 public void glesPushMatrix()
948 if(matrixIndex[curStack] + 1 < sizeof(matrixStack[0]) / sizeof(Matrix))
950 matrixIndex[curStack]++;
951 memcpy(matrixStack[curStack][matrixIndex[curStack]].array, matrixStack[curStack][matrixIndex[curStack]-1].array, sizeof(Matrix));
955 public void glesPopMatrix()
957 if(matrixIndex[curStack] > 0)
959 matrixIndex[curStack]--;
964 public void glesLoadMatrixd(double * i)
966 memcpy(matrixStack[curStack][matrixIndex[curStack]].array, i, sizeof(Matrix));
970 public void glesOrtho( double l, double r, double b, double t, double n, double f )
974 (2 / (r - l)), 0, 0, 0,
975 0, (2 / (t - b)), 0, 0,
976 0, 0, (-2 / (f - n)), 0,
977 (-(r + l) / (r - l)), (-(t + b) / (t - b)), (-(f + n) / (f - n)), 1
980 res.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
981 matrixStack[curStack][matrixIndex[curStack]] = res;
985 public void glesFrustum( double l, double r, double b, double t, double n, double f )
995 double A = ((r + l) / (r - l));
996 double B = ((t + b) / (t - b));
997 double C = (-(f + n) / (f - n));
998 double D = (-2*f*n/(f-n));
1001 (2.0*n / (r - l)), 0, 0, 0,
1002 0, (2.0*n / (t - b)), 0, 0,
1007 res.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
1008 matrixStack[curStack][matrixIndex[curStack]] = res;
1013 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1014 public void glesRotated( double a, double b, double c, double d )
1019 q.RotationAxis({(float)b,(float)c,(float)-d}, a );
1020 m.RotationQuaternion(q);
1021 r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
1022 matrixStack[curStack][matrixIndex[curStack]] = r;
1025 public void glesScaled( double a, double b, double c )
1031 r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
1032 matrixStack[curStack][matrixIndex[curStack]] = r;
1036 public void glesTranslated( double a, double b, double c )
1042 r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
1043 matrixStack[curStack][matrixIndex[curStack]] = r;
1047 public void glesMultMatrixd( double * i )
1050 r.Multiply((Matrix *)i, matrixStack[curStack][matrixIndex[curStack]]);
1051 matrixStack[curStack][matrixIndex[curStack]] = r;
1056 public void glesMatrixMode(int mode)
1058 curStack = (mode == GL_MODELVIEW) ? 0 : (mode == GL_PROJECTION) ? 1 : 2;
1064 #define glPushMatrix glesPushMatrix
1065 #define glPopMatrix glesPopMatrix
1066 #define glLoadIdentity glesLoadIdentity
1067 #define glMatrixMode glesMatrixMode
1071 /* Using the built-in matrix stack
1072 void glesLoadMatrixd( double * i )
1076 (float)i[0],(float)i[1],(float)i[2],(float)i[3],
1077 (float)i[4],(float)i[5],(float)i[6],(float)i[7],
1078 (float)i[8],(float)i[9],(float)i[10],(float)i[11],
1079 (float)i[12],(float)i[13],(float)i[14],(float)i[15]
1084 void glesOrtho( double l, double r, double b, double t, double n, double f )
1086 float matrix[4][4] =
1088 { (float)(2 / (r - l)), 0, 0, 0 },
1089 { 0, (float)(2 / (t - b)), 0, 0 },
1090 { 0, 0, (float)(-2 / (f - n)), 0 },
1091 { (float)(-(r + l) / (r - l)), (float)(-(t + b) / (t - b)), (float)(-(f + n) / (f - n)), 1 }
1093 glMultMatrixf((float *)matrix);
1096 void glesFrustum( double l, double r, double b, double t, double n, double f )
1098 float A = (float)((r + l) / (r - l));
1099 float B = (float)((t + b) / (t - b));
1100 float C = (float)(-(f + n) / (f - n));
1101 float D = (float)(-2*f*n/(f-n));
1102 float matrix[4][4] =
1104 { (float)(2*n / (r - l)), 0, 0, 0 },
1105 { 0, (float)(2*n / (t - b)), 0, 0 },
1109 glMultMatrixf((float *)matrix);
1112 void glesRotated( double a, double b, double c, double d ) { glRotatef((float)a, (float)b, (float)c, (float)d); }
1113 void glesScaled( double a, double b, double c ) { glScalef((float)a, (float)b, (float)c); }
1114 void glesTranslated( double a, double b, double c ) { glTranslatef((float)a, (float)b, (float)c); }
1116 void glesMultMatrixd( double * i )
1120 (float)i[0], (float)i[1], (float)i[2], (float)i[3],
1121 (float)i[4], (float)i[5], (float)i[6], (float)i[7],
1122 (float)i[8], (float)i[9], (float)i[10], (float)i[11],
1123 (float)i[12], (float)i[13], (float)i[14], (float)i[15]
1129 // Need to do these...
1130 public void glesVertex3f( float x, float y, float z )
1132 numVertexCoords = 3;
1133 vertexStride = vertexOffset + numVertexCoords;
1135 if(vertexCount + vertexStride > beginBufferSize)
1137 beginBufferSize = beginBufferSize + beginBufferSize/2;
1138 vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
1141 vertexPointer[vertexCount*vertexStride+vertexOffset] = x;
1142 vertexPointer[vertexCount*vertexStride+vertexOffset+1] = y;
1143 vertexPointer[vertexCount*vertexStride+vertexOffset+2] = z;
1146 if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
1148 vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset];
1149 vertexPointer[vertexCount*vertexStride+vertexOffset+1] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset+1];
1150 vertexPointer[vertexCount*vertexStride+vertexOffset+2] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset+2];
1152 vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset];
1153 vertexPointer[vertexCount*vertexStride+vertexOffset+1] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset+1];
1154 vertexPointer[vertexCount*vertexStride+vertexOffset+2] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset+2];
1160 public void glesVertex3d( double x, double y, double z ) { glesVertex3f((float)x, (float)y, (float)z); }
1161 public void glesVertex3fv( float* coords ) { glesVertex3f(coords[0], coords[1], coords[2]); }
1162 public void glesVertex3dv( double* coords ) { glesVertex3f((float)coords[0], (float)coords[1], (float)coords[2]); }
1164 public void glesNormal3f(float x, float y, float z)
1166 normalCount = vertexCount;
1167 if(vertexCount + 4 > normalBufferSize)
1169 normalBufferSize = normalBufferSize + normalBufferSize/2;
1170 normalPointer = renew normalPointer float[normalBufferSize * 2];
1173 normalPointer[normalCount*3+0] = x;
1174 normalPointer[normalCount*3+1] = y;
1175 normalPointer[normalCount*3+2] = z;
1178 if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
1180 normalPointer[normalCount*3+0] = normalPointer[(normalCount-4)*3+0];
1181 normalPointer[normalCount*3+1] = normalPointer[(normalCount-4)*3+1];
1182 normalPointer[normalCount*3+2] = normalPointer[(normalCount-4)*3+2];
1184 normalPointer[normalCount*3+0] = normalPointer[(normalCount-3)*3+0];
1185 normalPointer[normalCount*3+1] = normalPointer[(normalCount-3)*3+1];
1186 normalPointer[normalCount*3+2] = normalPointer[(normalCount-3)*3+2];
1190 public void glesNormal3fd(double x, double y, double z) { glesNormal3f((float)x, (float)y, (float)z); }
1191 public void glesNormal3fv(float * coords) { glesNormal3f(coords[0], coords[1], coords[2]); }
1193 public void glesColorMaterial(int a, int b)
1195 PrintLn("glColorMaterial stub");
1198 public void glesTerminate()
1200 delete vertexPointer;
1201 delete normalPointer;
1202 beginBufferSize = 0;
1204 delete floatVPBuffer;
1207 delete shortVPBuffer;
1210 delete shortBDBuffer;
1214 static GLuint stippleTexture;
1215 #if defined(_GLES) || defined(__EMSCRIPTEN__)
1216 static bool stippleEnabled;
1219 public void glesLineStipple( int i, unsigned short j )
1223 for(x = 0; x < 16; x++)
1225 bool v = (j & (1 << x)) != 0;
1226 texture[x] = v ? 0xFFFFFFFF : 0;
1229 glGenTextures(1, &stippleTexture);
1230 glBindTexture(GL_TEXTURE_2D, stippleTexture);
1231 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
1232 glEnable(GL_TEXTURE_2D);
1233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1235 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1236 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1237 glMatrixMode(GL_TEXTURE);
1239 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
1240 glScaled(i/16.0, 1, 1.0f);
1241 glTranslated(0.5, 0.5, 0);
1242 glMatrixMode(GL_PROJECTION);
1245 public void glesLightModeli( unsigned int pname, int param )
1247 #if !defined(__EMSCRIPTEN__)
1248 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
1249 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
1254 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
1255 void glFogi( unsigned int pname, int param ) { }
1256 void glPolygonMode( unsigned int i, unsigned int j ) { }
1259 // *** Picking won't be supported for now ***
1260 void glPushName( unsigned int i ) { }
1261 void glLoadName( unsigned int i ) { }
1262 void glPopName() { }
1264 // Probably replace by regular glBlendFunc ...
1265 void glBlendFuncSeparate(int a, int b, int c, int d)
1270 // For direct pixel blitting...
1271 void glRasterPos2d(double a, double b) { }
1272 void glPixelZoom(float a, float b) { }
1273 void glDrawPixels(int a, int b, int c, int d, void * e) { }
1277 #if !defined(__APPLE__) && !defined(__WIN32__)
1278 void (APIENTRY * glBindBufferARB) (GLenum target, GLuint buffer);
1279 void (APIENTRY * glGenBuffersARB) (GLsizei n, GLuint *buffers);
1280 void (APIENTRY * glDeleteBuffersARB) (GLsizei n, const GLuint *buffers);
1281 void (APIENTRY * glBufferDataARB) (GLenum target, int size, const GLvoid *data, GLenum usage);
1284 static int currentVertexBuffer;
1286 bool GLSelectVBO(uint vbo)
1288 if(currentVertexBuffer != vbo)
1290 GLBindBuffer(GL_ARRAY_BUFFER, vbo);
1291 currentVertexBuffer = vbo;
1297 void GLGenBuffers(int count, uint * buffer)
1299 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1300 glGenBuffers(count, buffer);
1302 #if defined(__WIN32__)
1305 glGenBuffersARB(count, buffer);
1309 void GLDeleteBuffers(int count, GLuint * buffer)
1311 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1312 glDeleteBuffers(count, buffer);
1314 #if defined(__WIN32__)
1315 if(glDeleteBuffersARB)
1317 glDeleteBuffersARB(count, buffer);
1321 void GLBindBuffer(int target, uint buffer)
1323 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1324 glBindBuffer(target, buffer);
1326 #if defined(__WIN32__)
1329 glBindBufferARB(target, buffer);
1331 currentVertexBuffer = buffer;
1334 public void GLVertexPointer(int numCoords, int glType, int stride, void *ptr, int numVertices)
1337 if(glType == GL_DOUBLE)
1338 glesVertexPointerd(numCoords, stride, ptr, numVertices);
1339 else if(glType == GL_INT)
1340 glesVertexPointeri(numCoords, stride, ptr, numVertices);
1343 glVertexPointer(numCoords, glType, stride, ptr);
1346 public void GLBufferData(int type, GLenum target, int size, const GLvoid *data, GLenum usage)
1349 if(type == GL_DOUBLE)
1350 glesBufferDatad(target, size, (void *)data, usage);
1351 else if(type == GL_UNSIGNED_INT)
1352 glesBufferDatai(target, size, (void *)data, usage);
1356 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1357 glBufferData(target, size, data, usage);
1360 #if defined(__WIN32__)
1363 glBufferDataARB(target, size, data, usage);
1367 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1368 static int primitiveTypes[RenderPrimitiveType] =
1370 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, GL_LINE_STRIP
1375 // Non OpenGL ES friendly stuff
1379 //#undef GL_UNSIGNED_INT
1384 #undef GL_QUAD_STRIP
1385 #undef GL_POLYGON_STIPPLE
1386 #undef GL_LINE_STIPPLE
1389 #undef GL_ALL_ATTRIB_BITS
1390 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
1394 static int displayWidth, displayHeight;
1396 #define GL_CLAMP_TO_EDGE 0x812F
1398 static bool vboAvailable;
1400 static bool useSingleGLContext = false;
1401 class OGLDisplay : struct
1403 #if defined(__WIN32__)
1413 int imageBuffers[2];
1414 byte * pboMemory1, * pboMemory2;
1416 #elif !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
1417 GLXContext glContext;
1420 XShmSegmentInfo shminfo;
1422 XShmSegmentInfo shminfoShape;
1423 XImage * shapeImage;
1427 X11Picture windowPicture;
1428 X11Picture pixmapPicture;
1430 X11Picture shapePicture;
1433 ColorAlpha * flippingBuffer;
1434 int flipBufH, flipBufW;
1439 class OGLSystem : struct
1444 #if defined(__WIN32__)
1445 PIXELFORMATDESCRIPTOR pfd;
1450 #elif !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
1451 XVisualInfo * visualInfo;
1452 GLXContext glContext;
1453 GLXDrawable glxDrawable;
1457 class OGLSurface : struct
1463 bool writingOutline;
1465 float foreground[4], background[4], bitmapMult[4];
1468 class OGLMesh : struct
1477 class OGLIndices : struct
1487 class OpenGLDisplayDriver : DisplayDriver
1489 class_property(name) = "OpenGL";
1491 bool LockSystem(DisplaySystem displaySystem)
1493 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
1494 OGLSystem oglSystem = displaySystem.driverData;
1495 if(useSingleGLContext) return true;
1496 #if defined(__WIN32__)
1497 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1498 #elif defined(__unix__) || defined(__APPLE__)
1499 //if(previous) return true;
1500 // printf("Making SYSTEM current\n");
1501 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
1502 //previous = oglSystem.glContext;
1508 void UnlockSystem(DisplaySystem displaySystem)
1510 if(useSingleGLContext) return;
1511 #if defined(__WIN32__)
1512 wglMakeCurrent(null, null);
1513 #elif defined(__unix__) || defined(__APPLE__)
1514 // printf("Making NULL current\n");
1515 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1517 glXMakeCurrent(xGlobalDisplay, None, null);
1523 bool Lock(Display display)
1525 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
1526 OGLDisplay oglDisplay = display.driverData;
1527 if(useSingleGLContext) return true;
1528 #if defined(__WIN32__)
1529 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1530 #elif defined(__unix__) || defined(__APPLE__)
1531 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
1532 // printf(" Making DISPLAY current\n");
1533 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1539 void Unlock(Display display)
1541 if(useSingleGLContext) return;
1542 //printf(" Making NULL current\n");
1543 //glXMakeCurrent(xGlobalDisplay, None, null);
1545 LockSystem(display.displaySystem);
1548 void DestroyDisplay(Display display)
1550 OGLDisplay oglDisplay = display.driverData;
1554 #if defined(__WIN32__)
1555 wglMakeCurrent( null, null );
1558 wglDeleteContext(oglDisplay.glrc);
1560 if(oglDisplay.hdc && oglDisplay.pBuffer)
1561 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1563 if(oglDisplay.pBuffer)
1564 wglDestroyPbufferARB(oglDisplay.pBuffer);
1567 ReleaseDC(display.window, oglDisplay.hdc);
1569 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1570 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1572 #elif defined(__unix__) || defined(__APPLE__)
1573 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1575 if(oglDisplay.shapePixmap)
1576 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1577 if(oglDisplay.pixmap)
1578 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1579 if(oglDisplay.image)
1581 if(oglDisplay.shminfoShape.shmid != -1)
1583 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1584 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1585 shmdt(oglDisplay.shminfo.shmaddr);
1586 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1589 if(oglDisplay.shapeImage)
1591 if(oglDisplay.shminfoShape.shmid != -1)
1593 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1594 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1595 shmdt(oglDisplay.shminfoShape.shmaddr);
1596 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1598 XDestroyImage(oglDisplay.shapeImage);
1599 oglDisplay.shapeImage = None;
1602 glXMakeCurrent(xGlobalDisplay, None, null);
1604 if(oglDisplay.glContext)
1605 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1608 delete oglDisplay.flippingBuffer;
1610 display.driverData = null;
1614 void ::CheckExtensions(OGLSystem oglSystem)
1616 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
1618 oglSystem.pow2textures = strstr(extensions, "GL_ARB_texture_non_power_of_two") ? false : true;
1619 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
1622 bool CreateDisplaySystem(DisplaySystem displaySystem)
1624 bool result = false;
1625 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
1628 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
1630 oglSystem.hdc = GetDC(oglSystem.hwnd);
1634 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
1635 oglSystem.pfd.nVersion = 1;
1636 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
1637 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
1638 oglSystem.pfd.cColorBits = 24;
1639 oglSystem.pfd.cAlphaBits = 8;
1640 oglSystem.pfd.cDepthBits = 24;
1641 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
1643 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
1644 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1646 if(oglSystem.pfd.cColorBits > 8)
1648 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1649 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
1652 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1654 // Get Pointers To The GL Functions
1655 glActiveTextureARB = (void *) wglGetProcAddress("glActiveTextureARB");
1656 glMultiTexCoord2fARB = (void *) wglGetProcAddress("glMultiTexCoord2fARB");
1657 glClientActiveTextureARB = (void *) wglGetProcAddress("glClientActiveTextureARB");
1658 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
1659 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
1660 glGenBuffersARB = (void *) wglGetProcAddress("glGenBuffersARB");
1661 glBindBufferARB = (void *) wglGetProcAddress("glBindBufferARB");
1662 glBufferDataARB = (void *) wglGetProcAddress("glBufferDataARB");
1663 glMapBufferARB = (void *) wglGetProcAddress("glMapBufferARB");
1664 glUnmapBufferARB = (void *) wglGetProcAddress("glUnmapBufferARB");
1665 glDeleteBuffersARB = (void *) wglGetProcAddress("glDeleteBuffersARB");
1666 glBlendFuncSeparate = (void *) wglGetProcAddress("glBlendFuncSeparate");
1668 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
1669 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
1670 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
1671 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
1672 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
1673 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
1674 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
1675 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
1676 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
1678 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
1680 vboAvailable = glBindBufferARB != null;
1682 // eSystem_LoggingMode(LOG_MSGBOX, null);
1684 if(wglChoosePixelFormatARB)
1689 float fAttributes[] = {0,0};
1692 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
1693 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1694 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1695 WGL_COLOR_BITS_ARB,24,
1696 WGL_ALPHA_BITS_ARB,8,
1697 WGL_DEPTH_BITS_ARB,16,
1698 WGL_STENCIL_BITS_ARB,0,
1699 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
1700 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1701 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1705 //Log("Found wglChoosePixelFormatARB\n");
1707 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1708 if(!valid || !numFormats)
1710 //Log("Can't find 4x multi sampling\n");
1711 iAttributes[19] = 2;
1712 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1713 if(!valid || !numFormats)
1715 // Log("Can't find 2x multi sampling\n");
1716 iAttributes[16] = 0;
1717 iAttributes[17] = 0;
1718 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1721 if(valid && numFormats)
1723 oglSystem.format = pixelFormat;
1724 wglMakeCurrent(null, null);
1725 wglDeleteContext(oglSystem.glrc);
1727 // *** DescribePixelFormat does not support WGL pixel formats! ***
1728 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1729 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1730 //Log("Successfully set pixel format\n");
1732 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
1733 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1737 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
1741 CheckExtensions(oglSystem);
1743 wglMakeCurrent(null, null);
1745 //eSystem_DumpErrors(true);
1749 #elif defined(__unix__) || defined(__APPLE__)
1750 vboAvailable = true;
1751 #if defined(__ANDROID__)
1752 egl_init_display(guiApp.desktop.windowHandle);
1753 CheckExtensions(oglSystem);
1755 #elif defined(__EMSCRIPTEN__)
1756 if(glfwInit() == GL_TRUE)
1758 const int width = 640, height = 480;
1759 if(glfwOpenWindow(width, height, 8, 8, 8, 8, 16, 0, GLFW_WINDOW) == GL_TRUE)
1761 //glfwSwapBuffers();
1765 printf("glfwOpenWindow() failed\n"); //glfwTerminate();
1768 printf("glfwInit() failed\n"); //glfwTerminate();
1771 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1772 XSetWindowAttributes attr;
1777 #ifndef ECERE_MINIGLX
1778 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1781 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1785 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
1786 attr.background_pixel = 0;
1787 attr.border_pixel = 0;
1788 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1789 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1790 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1792 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1793 oglSystem.visualInfo->visual, mask, &attr );
1795 if(oglSystem.visualInfo)
1797 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1798 if(oglSystem.glContext)
1800 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1802 CheckExtensions(oglSystem);
1803 glXMakeCurrent(xGlobalDisplay, None, null);
1810 displaySystem.flags.alpha = true;
1811 displaySystem.flags.flipping = true;
1812 displaySystem.pixelFormat = pixelFormat888;
1816 void DestroyDisplaySystem(DisplaySystem displaySystem)
1818 OGLSystem oglSystem = displaySystem.driverData;
1820 #if defined(__WIN32__)
1821 wglMakeCurrent( null, null );
1824 wglDeleteContext(oglSystem.glrc);
1827 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1828 DestroyWindow(oglSystem.hwnd);
1830 #elif defined(__unix__) || defined(__APPLE__)
1831 #if defined(__ANDROID__)
1833 #elif defined(__EMSCRIPTEN__)
1836 if(oglSystem.visualInfo)
1838 #ifdef ECERE_MINIGLX
1839 __miniglx_XFree(oglSystem.visualInfo);
1841 XFree(oglSystem.visualInfo);
1845 if(oglSystem.glxDrawable)
1847 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1848 oglSystem.glxDrawable = 0;
1855 bool CreateDisplay(Display display)
1857 bool result = false;
1858 OGLDisplay oglDisplay = display.driverData;
1859 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
1860 OGLSystem oglSystem = display.displaySystem.driverData;
1863 oglDisplay = display.driverData = OGLDisplay { };
1864 //printf("Inside CreateDisplay\n");
1866 #if defined(__WIN32__) || defined(USEPBUFFER)
1867 if(!display.alphaBlend)
1870 #if defined(__WIN32__)
1871 oglDisplay.hdc = GetDC(display.window);
1872 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1873 if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
1875 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1876 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1880 ReleaseDC(display.window, oglDisplay.hdc);
1881 #elif defined(__unix__) || defined(__APPLE__)
1882 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1884 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1886 #if defined(__APPLE__)
1887 XVisualInfo template = { 0 };
1888 XWindowAttributes winAttr;
1890 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1891 template.visualid = XVisualIDFromVisual(winAttr.visual);
1892 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1894 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1895 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1896 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1897 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1899 // visualInfo = oglSystem.visualInfo;
1904 //printf("visualInfo is not null\n");
1905 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1906 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1907 //XFree(visualInfo);
1910 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1911 if(oglDisplay.glContext)
1913 //printf("CreateDisplay Got a Context\n");
1914 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1920 #if defined(__WIN32__) || defined(USEPBUFFER)
1926 #if defined(__WIN32__)
1927 if(glBlendFuncSeparate)
1928 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1930 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1932 #if !defined(__OLDX__)
1933 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1935 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1940 glMatrixMode(GL_MODELVIEW);
1941 glScaled(1.0, 1.0, -1.0);
1942 // glTranslatef(0.375f, 0.375f, 0.0f);
1943 // glTranslatef(-0.625f, -0.625f, 0.0f);
1944 glMatrixMode(GL_PROJECTION);
1945 glShadeModel(GL_FLAT);
1947 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, true);
1948 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1949 glFogi(GL_FOG_MODE, GL_EXP);
1950 glFogf(GL_FOG_DENSITY, 0);
1951 glEnable(GL_NORMALIZE);
1952 glDepthFunc(GL_LESS);
1954 glDisable(GL_MULTISAMPLE_ARB);
1956 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1957 display.ambient = Color { 50,50,50 };
1960 if(!useSingleGLContext)
1962 #if defined(__WIN32__)
1963 wglMakeCurrent(null, null);
1964 #elif defined(__unix__) || defined(__APPLE__)
1965 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1968 glXMakeCurrent(xGlobalDisplay, None, null);
1976 bool DisplaySize(Display display, int width, int height)
1978 OGLDisplay oglDisplay = display.driverData;
1980 bool result = false;
1982 //printf("Inside DisplaySize\n");
1983 #if defined(__WIN32__) || defined(USEPBUFFER)
1984 OGLSystem oglSystem = display.displaySystem.driverData;
1985 if(display.alphaBlend)
1987 #if defined(__WIN32__)
1988 const int attributes[]=
1990 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1991 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1993 int pixelFormat = 0;
1994 if(wglChoosePixelFormatARB)
1998 float fAttributes[] = {0,0};
2001 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
2002 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
2003 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
2004 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
2005 WGL_COLOR_BITS_ARB,24,
2006 WGL_ALPHA_BITS_ARB,8,
2007 WGL_DEPTH_BITS_ARB,16,
2008 WGL_STENCIL_BITS_ARB,0,
2009 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
2010 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
2011 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
2015 //Log("Found wglChoosePixelFormatARB\n");
2017 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
2018 if(!valid || !numFormats)
2020 //Log("Can't find 4x multi sampling\n");
2021 iAttributes[19] = 2;
2022 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
2023 if(!valid || !numFormats)
2025 // Log("Can't find 2x multi sampling\n");
2026 iAttributes[16] = 0;
2027 iAttributes[17] = 0;
2028 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
2029 if(!valid || !numFormats)
2033 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
2034 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
2035 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
2036 WGL_COLOR_BITS_ARB,24,
2037 WGL_ALPHA_BITS_ARB,8,
2038 WGL_DEPTH_BITS_ARB,16,
2041 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
2045 if(valid && numFormats)
2047 wglMakeCurrent(null, null);
2051 wglMakeCurrent( null, null );
2052 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
2053 if(oglDisplay.hdc && oglDisplay.pBuffer)
2054 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
2056 wglDestroyPbufferARB(oglDisplay.pBuffer);
2058 if(!useSingleGLContext)
2059 wglMakeCurrent( null, null );
2062 wglDeleteContext(oglDisplay.glrc);
2064 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
2065 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
2066 if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
2069 HDC hdc = GetDC(display.window);
2071 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
2072 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
2074 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
2075 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
2077 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
2079 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
2083 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
2084 oglDisplay.memDC = CreateCompatibleDC(hdc);
2085 SetMapMode(oglDisplay.memDC, MM_TEXT);
2086 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2087 info->bmiHeader.biPlanes = 1;
2088 info->bmiHeader.biCompression = BI_RGB;
2089 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
2090 info->bmiHeader.biWidth = width;
2091 info->bmiHeader.biHeight = height;
2092 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
2095 SelectObject(oglDisplay.memDC, newBitmap);
2096 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
2099 PIXELFORMATDESCRIPTOR pfd = { 0 };
2100 pfd.nSize = (short)sizeof(pfd);
2102 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
2103 pfd.iPixelType = PFD_TYPE_RGBA;
2104 pfd.cColorBits = 32;
2105 //pfd.cAlphaBits = 8;
2106 pfd.cDepthBits = 24;
2107 pfd.iLayerType = PFD_MAIN_PLANE;
2109 oglDisplay.hdc = oglDisplay.memDC;
2111 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
2112 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
2113 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
2115 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
2116 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
2117 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
2122 const int imageSize = width * height * 4;
2124 glGenBuffersARB(2, oglDisplay.imageBuffers);
2126 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2127 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
2128 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2129 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
2132 oglDisplay.memBitmap = newBitmap;
2133 oglDisplay.stride = width;
2139 ReleaseDC(display.window, hdc);
2141 #elif defined(__unix__) || defined(__APPLE__)
2142 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
2147 GLX_DOUBLEBUFFER, True,
2153 GLX_STENCIL_SIZE, 1,
2154 //GLX_DEPTH_SIZE, 24,
2155 GLX_RENDER_TYPE, GLX_RGBA_BIT,
2156 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
2162 GLX_PBUFFER_WIDTH, width,
2163 GLX_PBUFFER_HEIGHT, height,
2164 GLX_LARGEST_PBUFFER, False,
2168 // choose a pixel format that meets our minimum requirements
2171 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
2174 if(oglDisplay.pixmap)
2176 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
2177 oglDisplay.pixmap = None;
2179 if(oglDisplay.shapePixmap)
2181 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
2182 oglDisplay.shapePixmap = None;
2185 // Free Shared Memory Pixmap
2186 if(oglDisplay.image)
2188 if(oglDisplay.shminfoShape.shmid != -1)
2190 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
2191 if(oglDisplay.shminfo.shmaddr != (void *)-1)
2192 shmdt(oglDisplay.shminfo.shmaddr);
2193 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
2195 XDestroyImage(oglDisplay.image);
2196 oglDisplay.image = None;
2198 if(oglDisplay.shapeImage)
2200 if(oglDisplay.shminfoShape.shmid != -1)
2202 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
2203 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
2204 shmdt(oglDisplay.shminfoShape.shmaddr);
2205 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
2207 XDestroyImage(oglDisplay.shapeImage);
2208 oglDisplay.shapeImage = None;
2211 if(oglDisplay.windowPicture)
2212 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
2213 if(oglDisplay.pixmapPicture)
2214 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
2216 if(oglDisplay.pixmap)
2217 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
2219 if(oglDisplay.glContext)
2220 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
2221 if(oglDisplay.pBuffer)
2222 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
2224 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
2225 if(oglDisplay.pBuffer)
2227 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
2228 if(oglDisplay.glContext)
2230 glXMakeCurrent(xGlobalDisplay, None, null);
2231 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
2233 // Initialize Shared Memory Pixmap
2234 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
2235 ZPixmap, null, &oglDisplay.shminfo, width, height);
2236 if(oglDisplay.image)
2238 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
2239 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
2240 if(oglDisplay.shminfo.shmid != -1)
2242 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
2243 if(oglDisplay.shminfo.shmaddr != (void *)-1)
2245 oglDisplay.shminfo.readOnly = False;
2246 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
2248 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
2249 &oglDisplay.shminfo, width, height, 32);
2251 // Initialize Shared Memory Shape Pixmap
2252 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
2253 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
2254 if(oglDisplay.shapeImage)
2256 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
2257 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
2258 if(oglDisplay.shminfoShape.shmid != -1)
2260 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
2261 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
2263 oglDisplay.shminfoShape.readOnly = False;
2264 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
2266 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
2267 &oglDisplay.shminfoShape, width, height, 1);
2268 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
2271 XRenderPictureAttributes attributes = { 0 };
2272 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
2273 #if !defined(__APPLE__) && !defined(__OLDX__)
2274 attributes.repeat = RepeatNormal;
2276 attributes.repeat = 1;
2278 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
2279 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
2280 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
2281 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
2284 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
2285 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
2302 CreateDisplay(display);
2303 #if defined(__WIN32__)
2304 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
2305 #elif defined(__unix__) || defined(__APPLE__)
2306 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
2310 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
2317 if(!result && display.alphaBlend)
2319 printf("Alpha blending windows not supported on this display\n");
2326 glViewport(0,0,width,height);
2328 glOrtho(0,width,height,0,0.0,1.0);
2329 displayWidth = display.width = width;
2330 displayHeight = display.height = height;
2332 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
2334 oglDisplay.flipBufW = width;
2335 oglDisplay.flipBufH = height;
2339 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
2342 if(oglDisplay.flippingBuffer || !width || !height)
2348 void DisplayPosition(Display display, int x, int y)
2350 OGLDisplay oglDisplay = display.driverData;
2356 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
2360 void RestorePalette(Display display)
2364 void StartUpdate(Display display)
2368 void EndUpdate(Display display)
2372 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
2376 void Update(Display display, Box updateBox)
2378 #if defined(__WIN32__) || defined(USEPBUFFER)
2379 OGLDisplay oglDisplay = display.driverData;
2381 //Logf("DisplayScreen\n");
2385 #if defined(__WIN32__) || defined(USEPBUFFER)
2386 if(display.alphaBlend)
2388 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2389 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
2390 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2391 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2392 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
2395 #if defined(__WIN32__)
2397 POINT point = { oglDisplay.x, oglDisplay.y};
2398 POINT srcPoint = { 0, 0 };
2399 BLENDFUNCTION blend = { 0 };
2401 size.cx = display.width;
2402 size.cy = display.height;
2403 blend.BlendOp = AC_SRC_OVER;
2404 blend.BlendFlags = 0;
2405 blend.SourceConstantAlpha = 255;
2406 blend.AlphaFormat = AC_SRC_ALPHA;
2409 // Process partial images. Mapping the buffer waits for
2410 // outstanding DMA transfers into the buffer to finish.
2411 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2412 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
2414 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2415 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
2418 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
2419 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
2422 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
2425 // Unmap the image buffers
2426 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2427 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
2429 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2430 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
2432 // Bind two different buffer objects and start the glReadPixels
2433 // asynchronously. Each call will return directly after
2434 // starting the DMA transfer.
2435 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2436 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
2438 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2439 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
2443 #elif defined(__unix__) || defined(__APPLE__)
2444 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
2446 XTransform transform =
2449 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
2450 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
2451 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
2454 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
2455 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
2456 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
2457 #if !defined(__APPLE__) && !defined(__OLDX__)
2458 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
2460 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
2462 XFlush(xGlobalDisplay);
2470 #if defined(__WIN32__)
2471 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
2472 SwapBuffers(oglDisplay.hdc);
2473 #elif defined(__unix__) || defined(__APPLE__)
2474 #if defined(__ANDROID__)
2475 eglSwapBuffers(eglDisplay, eglSurface);
2476 #elif defined(__EMSCRIPTEN__)
2479 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
2483 //Logf("Out of DisplayScreen\n");
2486 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
2488 if(bitmap.driverData)
2490 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
2491 glDeleteTextures(1, &tex);
2492 bitmap.driverData = 0;
2494 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
2497 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
2499 OGLSystem oglSystem = displaySystem.driverData;
2500 bool result = false;
2502 GLuint glBitmap = 0;
2504 uint w = width, h = height;
2505 if(oglSystem.pow2textures)
2510 w = Min(w, oglSystem.maxTextureSize);
2511 h = Min(h, oglSystem.maxTextureSize);
2513 glGenTextures(1, &glBitmap);
2514 glBindTexture(GL_TEXTURE_2D, glBitmap);
2516 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2518 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2519 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2521 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2522 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2524 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2526 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
2528 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2529 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2533 bitmap.driverData = (void *)(uintptr)glBitmap;
2534 bitmap.driver = displaySystem.driver;
2542 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
2544 bool result = false;
2545 OGLSystem oglSystem = displaySystem.driverData;
2546 Bitmap convBitmap = bitmap;
2550 convBitmap.Copy(bitmap);
2553 // Pre process the bitmap... First make it 32 bit
2554 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
2557 uint w = bitmap.width, h = bitmap.height;
2558 GLuint glBitmap = 0;
2559 if(oglSystem.pow2textures)
2564 w = Min(w, oglSystem.maxTextureSize);
2565 h = Min(h, oglSystem.maxTextureSize);
2569 while(w * 2 < h) w *= 2;
2570 while(h * 2 < w) h *= 2;
2573 // Switch ARGB to RGBA
2574 //if(bitmap.format != pixelFormatRGBA)
2576 for(c=0; c<bitmap.size; c++)
2578 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
2580 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
2581 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
2584 // convBitmap.pixelFormat = pixelFormat888;
2587 glGenTextures(1, &glBitmap);
2590 //int error = glGetError();
2594 glBindTexture(GL_TEXTURE_2D, glBitmap);
2595 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2597 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2598 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
2599 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2601 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
2602 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
2604 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2605 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2607 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2611 for(level = 0; result && (w > 1 || h > 1); level++, w >>= 1, h >>= 1)
2614 if(bitmap.width != w || bitmap.height != h)
2616 mipMap = Bitmap { };
2617 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
2619 Surface mipSurface = mipMap.GetSurface(0,0,null);
2620 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
2630 mipMap = convBitmap;
2637 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2638 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2639 //printf("Calling glTexImage2D\n");
2640 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2641 //printf("width = %d (Should be %d, %d)\n", width, w, h);
2642 if((error = glGetError()))
2644 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2645 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2649 if(mipMap != convBitmap)
2654 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2655 bitmap.driverData = (void *)(uintptr)glBitmap;
2656 bitmap.driver = displaySystem.driver;
2659 FreeBitmap(displaySystem, bitmap);
2660 else if(oglSystem.loadingFont)
2662 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2663 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2664 oglSystem.loadingFont = false;
2670 void ReleaseSurface(Display display, Surface surface)
2672 glDisable(GL_SCISSOR_TEST);
2673 delete surface.driverData;
2674 surface.driverData = null;
2677 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2682 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2684 bool result = false;
2685 OGLSurface oglSurface = surface.driverData = OGLSurface { };
2687 //Logf("GetSurface\n");
2691 if(displayWidth != display.width || displayHeight != display.height)
2693 displayWidth = display.width;
2694 displayHeight = display.height;
2696 glViewport(0,0,display.width,display.height);
2698 glOrtho(0,display.width,display.height,0,0.0,1.0);
2701 surface.offset.x = x;
2702 surface.offset.y = y;
2703 surface.unclippedBox = surface.box = clip;
2704 oglSurface.bitmapMult[0] = 1;
2705 oglSurface.bitmapMult[1] = 1;
2706 oglSurface.bitmapMult[2] = 1;
2707 oglSurface.bitmapMult[3] = 1;
2709 glEnable(GL_SCISSOR_TEST);
2712 (display.height) -(y+clip.bottom)-1,
2713 clip.right-clip.left+1,
2714 clip.bottom-clip.top+1);
2720 void Clip(Display display, Surface surface, Box clip)
2729 box.Clip(surface.unclippedBox);
2733 box = surface.box = surface.unclippedBox;
2734 box.left += surface.offset.x;
2735 box.top += surface.offset.y;
2736 box.right+= surface.offset.x;
2737 box.bottom += surface.offset.y;
2740 box.left,display.height - box.bottom - 1,
2741 box.right-box.left+1, box.bottom-box.top+1);
2744 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2746 bool result = false;
2747 OGLDisplay oglDisplay = display.driverData;
2748 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2750 if(oglDisplay.flippingBuffer)
2752 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2755 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2761 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2762 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2763 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2764 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2765 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2768 for(row = 0; row<h; row++)
2769 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2776 void SetForeground(Display display, Surface surface, ColorAlpha color)
2778 OGLSurface oglSurface = surface.driverData;
2780 //Logf("SetForeground\n");
2782 oglSurface.foreground[0] = color.color.r/255.0f;
2783 oglSurface.foreground[1] = color.color.g/255.0f;
2784 oglSurface.foreground[2] = color.color.b/255.0f;
2785 //oglSurface.foreground[3] = 1.0f;
2786 oglSurface.foreground[3] = color.a/255.0f;
2788 //if(!oglSurface.foreground[3])printf("bug");
2791 void SetBackground(Display display, Surface surface, ColorAlpha color)
2793 OGLSurface oglSurface = surface.driverData;
2795 //Logf("SetBackground\n");
2797 oglSurface.background[0] = color.color.r/255.0f;
2798 oglSurface.background[1] = color.color.g/255.0f;
2799 oglSurface.background[2] = color.color.b/255.0f;
2800 //oglSurface.background[3] = 1.0;
2801 oglSurface.background[3] = color.a/255.0f;
2804 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2806 OGLSurface oglSurface = surface.driverData;
2808 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2809 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2810 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2811 oglSurface.bitmapMult[3] = color.a/255.0f;
2814 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2819 void PutPixel(Display display, Surface surface,int x,int y)
2821 OGLSurface oglSurface = surface.driverData;
2823 //Logf("PutPixel\n");
2825 glColor4fv(oglSurface.foreground);
2827 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2828 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2833 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2835 OGLSurface oglSurface = surface.driverData;
2836 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2851 x1 += surface.offset.x;
2852 y1 += surface.offset.y;
2853 x2 += surface.offset.x;
2854 y2 += surface.offset.y;
2858 glColor4fv(oglSurface.foreground);
2860 #if defined(_GLES) || defined(__EMSCRIPTEN__)
2863 glTexCoord2f(0.5f, 0);
2864 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2865 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2866 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2875 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2876 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2882 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2884 OGLSurface oglSurface = surface.driverData;
2885 x1 += surface.offset.x;
2886 y1 += surface.offset.y;
2887 x2 += surface.offset.x;
2888 y2 += surface.offset.y;
2890 //Logf("Rectangle\n");
2892 glColor4fv(oglSurface.foreground);
2893 #if defined(_GLES) || defined(__EMSCRIPTEN__)
2898 glTexCoord2f(0.5f, 0);
2899 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2900 glTexCoord2f(y2-y1 + 0.5f, 0);
2901 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2903 glTexCoord2f(0.5f, 0);
2904 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2905 glTexCoord2f(x2 - x1 + 0.5f, 0);
2906 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2908 glTexCoord2f(0.5f, 0);
2909 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2910 glTexCoord2f(y1 - y2 + 0.5f, 0);
2911 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2913 glTexCoord2f(0.5f, 0);
2914 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2915 glTexCoord2f(x1 - x2 + 0.5f, 0);
2916 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2921 glBegin(GL_LINE_LOOP);
2928 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2929 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2930 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2931 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2936 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2938 OGLSurface oglSurface = surface.driverData;
2941 glColor4fv(oglSurface.background);
2943 #ifdef __EMSCRIPTEN__
2945 glVertex2f(x1+surface.offset.x, y1+surface.offset.y);
2946 glVertex2f(x1+surface.offset.x, y2+surface.offset.y+1);
2947 glVertex2f(x2+surface.offset.x+1, y2+surface.offset.y+1);
2948 glVertex2f(x2+surface.offset.x+1, y1+surface.offset.y);
2951 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2952 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2955 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2956 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2960 void Clear(Display display, Surface surface, ClearType type)
2962 OGLDisplay oglDisplay = display.driverData;
2963 OGLSurface oglSurface = surface.driverData;
2966 if(type != depthBuffer)
2967 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2968 if(type != colorBuffer && !oglDisplay.depthWrite)
2970 glDepthMask((byte)bool::true);
2972 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2973 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2974 if(type != colorBuffer && !oglDisplay.depthWrite)
2976 glDepthMask((byte)bool::false);
2980 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2985 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2987 OGLSurface oglSurface = surface.driverData;
2989 #if !defined(__OLDX__)
2990 // WHY DO WE HAVE GL_ONE HERE ?
2991 /*if(glBlendFuncSeparate && !oglSurface.writingText)
2992 glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2995 if(!oglSurface.writingText)
2997 // glTranslatef(-0.375f, -0.375f, 0.0f);
2998 glEnable(GL_TEXTURE_2D);
2999 glColor4fv(oglSurface.bitmapMult);
3001 else if(oglSurface.xOffset)
3002 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
3004 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
3009 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
3010 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
3011 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
3012 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
3013 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
3014 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
3015 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
3016 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
3021 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
3022 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
3023 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
3024 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
3025 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
3026 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
3027 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
3028 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
3031 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
3032 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
3033 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
3034 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
3035 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
3036 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
3037 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
3038 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
3042 if(!oglSurface.writingText)
3044 glDisable(GL_TEXTURE_2D);
3046 //glTranslate(0.375, 0.375, 0.0);
3048 else if(oglSurface.xOffset)
3049 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
3051 #if !defined(__OLDX__)
3052 /*if(glBlendFuncSeparate && !oglSurface.writingText)
3053 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
3057 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3059 OGLSurface oglSurface = surface.driverData;
3061 //glTranslate(-0.375, -0.375, 0.0);
3063 //Logf("Stretch\n");
3065 #if !defined(__OLDX__)
3066 /*if(glBlendFuncSeparate)
3067 glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
3070 glEnable(GL_TEXTURE_2D);
3071 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
3073 glColor4fv(oglSurface.bitmapMult);
3079 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
3080 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
3082 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
3083 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
3085 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
3086 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
3088 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
3089 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
3093 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
3094 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
3096 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
3097 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
3099 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
3100 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
3102 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
3103 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
3108 glDisable(GL_TEXTURE_2D);
3110 //glTranslate(0.375, 0.375, 0.0);
3111 #if !defined(__OLDX__)
3112 /*if(glBlendFuncSeparate)
3113 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
3118 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3120 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
3123 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3125 #if !defined(__EMSCRIPTEN__)
3126 float s2dw,s2dh,d2sw,d2sh;
3127 //bool flipX = false, flipY = false;
3129 //Logf("StretchDI\n");
3131 if(Sgn(w) != Sgn(sw))
3137 if(Sgn(h) != Sgn(sh))
3149 //Clip against the edges of the source
3152 dx+=(int)((0-sx) * s2dw);
3153 w-=(int)((0-sx) * s2dw);
3159 dy+=(int)((0-sy) * s2dh);
3160 h-=(int)((0-sy) * s2dh);
3165 if(sx+sw>bitmap.width-1)
3167 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
3168 sw-=sx+sw-(bitmap.width-1)-1;
3170 if(sy+sh>(bitmap.height-1))
3172 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
3173 sh-=sy+sh-(bitmap.height-1)-1;
3175 //Clip against the edges of the surfaceination
3176 if(dx<surface.box.left)
3179 sx+=(int)((surface.box.left-dx)*d2sw);
3180 sw-=(int)((surface.box.left-dx)*d2sw);
3181 w-=surface.box.left-dx;
3182 dx=surface.box.left;
3184 if(dy<surface.box.top)
3186 sy+=(int)((surface.box.top-dy)*d2sh);
3187 sh-=(int)((surface.box.top-dy)*d2sh);
3188 h-=surface.box.top-dy;
3191 if(dx+w>surface.box.right)
3193 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
3194 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
3195 w-=dx+w-surface.box.right-1;
3197 if(dy+h>surface.box.bottom)
3199 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
3200 h-=dy+h-surface.box.bottom-1;
3202 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
3204 dx += surface.offset.x;
3205 dy += surface.offset.y;
3207 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
3209 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3210 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
3211 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
3212 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
3213 glRasterPos2d(dx,dy);
3214 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
3215 glPixelZoom(s2dw, -s2dh);
3216 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
3217 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3218 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3219 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3220 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3225 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
3227 #if !defined(__EMSCRIPTEN__)
3230 //Clip against the edges of the source
3243 if(sx+w>bitmap.width-1)
3244 w-=sx+w-(bitmap.width-1)-1;
3245 if(sy+h>bitmap.height-1)
3246 h-=sy+h-(bitmap.height-1)-1;
3247 //Clip against the edges of the surfaceination
3248 if(dx<surface.box.left)
3251 sx+=surface.box.left-dx;
3252 w-=surface.box.left-dx;
3253 dx=surface.box.left;
3255 if(dy<surface.box.top)
3257 sy+=surface.box.top-dy;
3258 h-=surface.box.top-dy;
3261 if(dx+w>surface.box.right)
3263 //if(flip) sx+=dx+w-surface.box.right-1;
3264 w-=dx+w-surface.box.right-1;
3266 if(dy+h>surface.box.bottom)
3267 h-=dy+h-surface.box.bottom-1;
3271 dx += surface.offset.x;
3272 dy += surface.offset.y;
3274 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
3276 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3277 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
3278 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
3279 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
3280 glRasterPos2d(dx,dy);
3282 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
3283 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3284 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3285 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3286 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3291 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3293 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
3296 void UnloadFont(DisplaySystem displaySystem, Font font)
3298 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
3301 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
3304 OGLSystem oglSystem = displaySystem.driverData;
3305 oglSystem.loadingFont = true;
3306 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
3310 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
3312 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
3315 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
3317 OGLSurface oglSurface = surface.driverData;
3318 OGLSystem oglSystem = display.displaySystem.driverData;
3319 oglSystem.loadingFont = true;
3321 //glTranslated(-0.375, -0.375, 0.0);
3325 if(surface.textOpacity)
3328 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
3329 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
3332 oglSurface.writingText = true;
3334 glEnable(GL_TEXTURE_2D);
3336 if(surface.outline.size)
3338 ColorAlpha outlineColor = surface.outline.color;
3339 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
3340 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3341 //glEnable(GL_BLEND);
3343 oglSurface.writingOutline = true;
3344 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
3345 oglSurface.writingOutline = false;
3347 glColor4fv(oglSurface.foreground);
3349 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
3350 oglSurface.writingText = false;
3351 oglSystem.loadingFont = false;
3353 glDisable(GL_TEXTURE_2D);
3355 //glTranslated(0.375, 0.375, 0.0);
3358 void TextFont(Display display, Surface surface, Font font)
3360 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
3363 void TextOpacity(Display display, Surface surface, bool opaque)
3365 OGLSurface oglSurface = surface.driverData;
3366 oglSurface.opaqueText = opaque;
3369 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
3371 OGLSurface oglSurface = surface.driverData;
3372 OGLSystem oglSystem = display.displaySystem.driverData;
3373 oglSystem.loadingFont = true;
3374 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height);
3375 oglSystem.loadingFont = false;
3378 void DrawingChar(Display display, Surface surface, char character)
3383 void LineStipple(Display display, Surface surface, uint32 stipple)
3385 //Logf("Stipple\n");
3389 #if defined(_GLES) || defined(__EMSCRIPTEN__)
3390 stippleEnabled = true;
3391 glesLineStipple(1, (uint16)stipple);
3393 glLineStipple(1, (uint16)stipple);
3394 glEnable(GL_LINE_STIPPLE);
3399 #if defined(_GLES) || defined(__EMSCRIPTEN__)
3400 stippleEnabled = false;
3401 glMatrixMode(GL_TEXTURE);
3403 glMatrixMode(GL_PROJECTION);
3404 glDisable(GL_TEXTURE_2D);
3406 glDisable(GL_LINE_STIPPLE);
3410 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
3411 void SetRenderState(Display display, RenderState state, uint value)
3413 OGLDisplay oglDisplay = display.driverData;
3414 //Logf("RenderState\n");
3420 glEnable(GL_MULTISAMPLE_ARB);
3422 glDisable(GL_MULTISAMPLE_ARB);
3426 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
3430 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
3433 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
3434 oglDisplay.depthWrite = (bool)value;
3438 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3439 glFogfv(GL_FOG_COLOR, (float *)&color);
3443 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
3446 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
3450 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3451 #if !defined(__EMSCRIPTEN__)
3452 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
3458 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
3463 #if defined(__WIN32__)
3464 wglSwapIntervalEXT(value ? 1 : 0);
3471 void SetLight(Display display, int id, Light light)
3473 //Logf("SetLight\n");
3477 Object lightObject = light.lightObject;
3478 float position[4] = { 0, 0, 0, 0 };
3479 float color[4] = { 0, 0, 0, 1 };
3481 glEnable(GL_LIGHT0 + id);
3483 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
3484 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
3485 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
3488 if(!light.multiplier) light.multiplier = 1.0f;
3490 color[0] = light.diffuse.r * light.multiplier;
3491 color[1] = light.diffuse.g * light.multiplier;
3492 color[2] = light.diffuse.b * light.multiplier;
3493 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
3495 color[0] = light.ambient.r * light.multiplier;
3496 color[1] = light.ambient.g * light.multiplier;
3497 color[2] = light.ambient.b * light.multiplier;
3498 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
3499 color[0] = light.specular.r * light.multiplier;
3500 color[1] = light.specular.g * light.multiplier;
3501 color[2] = light.specular.b * light.multiplier;
3502 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
3506 Vector3D positionVector;
3507 if(light.flags.spot)
3509 if(lightObject.flags.root || !lightObject.parent)
3511 positionVector = lightObject.transform.position;
3512 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3516 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
3517 if(display.display3D.camera)
3518 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3524 if(!light.direction.x && !light.direction.y && !light.direction.z)
3526 Vector3Df vector { 0,0,-1 };
3528 mat.RotationQuaternion(light.orientation);
3529 positionVector.MultMatrixf(vector, mat);
3533 positionVector = light.direction;
3538 position[0] = (float)positionVector.x;
3539 position[1] = (float)positionVector.y;
3540 position[2] = (float)positionVector.z;
3542 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3545 // Display Light Position
3546 glDisable(GL_LIGHTING);
3547 glDisable(GL_DEPTH_TEST);
3551 glVertex3fv(position);
3553 glEnable(GL_DEPTH_TEST);
3554 glEnable(GL_LIGHTING);
3558 if(lightObject.flags.root || !lightObject.parent)
3560 positionVector = light.target.transform.position;
3561 positionVector.Subtract(positionVector, display.camera.cPosition);
3565 positionVector.MultMatrix(light.target.transform.position,
3566 lightObject.light.target.parent.matrix);
3567 positionVector.Subtract(positionVector, display.camera.cPosition);
3570 position[0] = positionVector.x;
3571 position[1] = positionVector.y;
3572 position[2] = positionVector.z;
3574 glDisable(GL_LIGHTING);
3575 glDisable(GL_DEPTH_TEST);
3579 glVertex3fv(position);
3581 glEnable(GL_DEPTH_TEST);
3582 glEnable(GL_LIGHTING);
3585 if(light.flags.attenuation)
3587 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
3588 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
3589 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
3592 if(light.flags.spot)
3595 #define MAXLIGHT 0.9
3596 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
3597 // Figure out exponent out of the hot spot
3598 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
3600 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
3601 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
3602 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
3608 Vector3Df vector { 0,0,-1 };
3609 Vector3Df direction;
3612 mat.RotationQuaternion(light.orientation);
3613 direction.MultMatrix(vector, mat);
3615 position[0] = direction.x;
3616 position[1] = direction.y;
3617 position[2] = direction.z;
3619 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3623 glDisable(GL_LIGHT0 + id);
3626 void SetCamera(Display display, Surface surface, Camera camera)
3628 OGLDisplay oglDisplay = display.driverData;
3629 //Logf("SetCamera\n");
3633 int left = surface.box.left + surface.offset.x;
3634 int top = surface.box.top + surface.offset.y;
3635 int right = surface.box.right + surface.offset.x;
3636 int bottom = surface.box.bottom + surface.offset.y;
3637 float origX = surface.offset.x + camera.origin.x;
3638 float origY = surface.offset.y + camera.origin.y;
3640 int y = display.height - bottom - 1;
3641 int w = right - left + 1;
3642 int h = bottom - top + 1;
3645 glViewport(x, y, w, h);
3647 // *** Projection Matrix ***
3648 if(!display.display3D.camera)
3651 glMatrixMode(GL_PROJECTION);
3652 if(display.display3D.collectingHits)
3654 float pickX = display.display3D.pickX + surface.offset.x;
3655 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3659 w / display.display3D.pickWidth, 0, 0, 0,
3660 0, h / display.display3D.pickHeight, 0, 0,
3662 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3663 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3666 glLoadMatrixd(pickMatrix.array);
3671 (left - origX) * camera.zMin / camera.focalX,
3672 (right - origX) * camera.zMin / camera.focalX,
3673 (bottom - origY) * camera.zMin / camera.focalY,
3674 (top - origY) * camera.zMin / camera.focalY,
3675 camera.zMin, camera.zMax);
3677 glDisable(GL_BLEND);
3679 // *** Z Inverted Identity Matrix ***
3680 glMatrixMode(GL_MODELVIEW);
3681 if(!display.display3D.camera)
3686 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3688 // *** View Matrix ***
3689 glMultMatrixd(camera.viewMatrix.array);
3694 glEnable(GL_DEPTH_TEST);
3695 glEnable(GL_LIGHTING);
3696 glShadeModel(GL_SMOOTH);
3697 glDepthMask((byte)bool::true);
3698 oglDisplay.depthWrite = true;
3700 glEnable(GL_MULTISAMPLE_ARB);
3702 else if(display.display3D.camera)
3704 oglDisplay.depthWrite = false;
3705 glViewport(0,0,display.width,display.height);
3707 glDisable(GL_CULL_FACE);
3708 glDisable(GL_DEPTH_TEST);
3709 glDisable(GL_LIGHTING);
3711 glDisable(GL_TEXTURE_2D);
3712 glShadeModel(GL_FLAT);
3714 glDisable(GL_MULTISAMPLE_ARB);
3716 // *** Restore 2D MODELVIEW Matrix ***
3719 // *** Restore 2D PROJECTION Matrix ***
3720 glMatrixMode(GL_PROJECTION);
3724 GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
3727 void ApplyMaterial(Display display, Material material, Mesh mesh)
3729 //Logf("ApplyMaterial\n");
3732 if(material.flags.doubleSided)
3734 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3735 glDisable(GL_CULL_FACE);
3739 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3740 glEnable(GL_CULL_FACE);
3744 if(material.flags.noFog)
3750 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3752 Bitmap map = material.baseMap;
3753 glEnable(GL_TEXTURE_2D);
3754 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3756 glMatrixMode(GL_TEXTURE);
3758 if(material.uScale && material.vScale)
3759 glScalef(material.uScale, material.vScale, 1);
3760 glMatrixMode(GL_MODELVIEW);
3762 if(material.flags.tile)
3764 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3765 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3769 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3770 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3774 glDisable(GL_TEXTURE_2D);
3776 if(mesh.flags.colors)
3778 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3779 glEnable(GL_COLOR_MATERIAL);
3783 glDisable(GL_COLOR_MATERIAL);
3785 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3786 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3789 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3790 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3794 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3795 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3798 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3799 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3802 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3805 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3807 OGLMesh oglMesh = mesh.data;
3810 if(!mesh.flags.vertices)
3812 if(oglMesh.vertices)
3814 GLDeleteBuffers(1, &oglMesh.vertices);
3815 oglMesh.vertices = 0;
3817 delete mesh.vertices;
3819 if(!mesh.flags.normals)
3823 GLDeleteBuffers(1, &oglMesh.normals);
3824 oglMesh.normals = 0;
3826 delete mesh.normals;
3828 if(!mesh.flags.texCoords1)
3830 if(oglMesh.texCoords)
3832 GLDeleteBuffers(1, &oglMesh.texCoords);
3833 oglMesh.texCoords = 0;
3835 delete mesh.texCoords;
3837 if(!mesh.flags.texCoords2)
3839 if(oglMesh.texCoords2)
3841 GLDeleteBuffers(1, &oglMesh.texCoords2);
3842 oglMesh.texCoords2 = 0;
3845 delete mesh.texCoords2;
3848 if(!mesh.flags.colors)
3852 GLDeleteBuffers(1, &oglMesh.colors);
3864 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3866 bool result = false;
3869 mesh.data = OGLMesh { };
3872 OGLMesh oglMesh = mesh.data;
3873 if(mesh.nVertices == nVertices)
3875 // Same number of vertices, adding features (Leaves the other features pointers alone)
3876 if(mesh.flags != flags)
3878 if(!mesh.flags.vertices && flags.vertices)
3880 if(flags.doubleVertices)
3882 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3885 mesh.vertices = new Vector3Df[nVertices];
3886 if(!oglMesh.vertices)
3887 GLGenBuffers(1, &oglMesh.vertices);
3889 if(!mesh.flags.normals && flags.normals)
3891 if(flags.doubleNormals)
3893 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3896 mesh.normals = new Vector3Df[nVertices];
3897 if(!oglMesh.normals)
3898 GLGenBuffers( 1, &oglMesh.normals);
3900 if(!mesh.flags.texCoords1 && flags.texCoords1)
3902 mesh.texCoords = new Pointf[nVertices];
3903 if(!oglMesh.texCoords)
3904 GLGenBuffers( 1, &oglMesh.texCoords);
3906 if(!mesh.flags.colors && flags.colors)
3908 mesh.colors = new ColorRGBAf[nVertices];
3910 GLGenBuffers( 1, &oglMesh.colors);
3916 // New number of vertices, reallocate all current and new features
3917 flags |= mesh.flags;
3920 if(flags.doubleVertices)
3922 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3925 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3926 if(!oglMesh.vertices)
3927 GLGenBuffers(1, &oglMesh.vertices);
3931 if(flags.doubleNormals)
3933 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3936 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3937 if(!oglMesh.normals)
3938 GLGenBuffers( 1, &oglMesh.normals);
3940 if(flags.texCoords1)
3942 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3943 if(!oglMesh.texCoords)
3944 GLGenBuffers( 1, &oglMesh.texCoords);
3948 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3950 GLGenBuffers( 1, &oglMesh.colors);
3958 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3960 OGLMesh oglMesh = mesh.data;
3961 if(!flags) flags = mesh.flags;
3965 if(flags.vertices && oglMesh.vertices)
3967 GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices);
3968 GLBufferData( mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, GL_STATIC_DRAW_ARB );
3971 if(flags.normals && oglMesh.normals)
3973 GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
3974 GLBufferData( mesh.flags.doubleNormals ? GL_DOUBLE : GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, GL_STATIC_DRAW_ARB );
3977 if(flags.texCoords1 && oglMesh.texCoords)
3979 GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
3980 GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(Pointf), mesh.texCoords, GL_STATIC_DRAW_ARB );
3983 if(flags.colors && oglMesh.colors)
3985 GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
3986 GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, GL_STATIC_DRAW_ARB );
3989 GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
3993 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
4000 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
4004 if(oglIndices.buffer)
4005 GLDeleteBuffers(1, &oglIndices.buffer);
4006 delete oglIndices.indices;
4011 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
4013 OGLIndices oglIndices = OGLIndices { };
4016 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
4017 GLGenBuffers( 1, &oglIndices.buffer);
4018 oglIndices.nIndices = nIndices;
4023 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
4027 GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
4028 GLBufferData( indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, GL_ELEMENT_ARRAY_BUFFER_ARB, nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
4029 oglIndices.indices, GL_STATIC_DRAW_ARB);
4030 GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
4034 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
4037 return oglIndices.indices;
4040 void SelectMesh(Display display, Mesh mesh)
4042 //Logf("SelectMesh\n");
4044 #if !defined( __ANDROID__) && !defined(__APPLE__)
4046 #if defined(__WIN32__)
4047 if(glUnlockArraysEXT)
4049 if(!vboAvailable && display.display3D.mesh)
4050 glUnlockArraysEXT();
4055 OGLMesh oglMesh = mesh.data;
4057 // *** Vertex Stream ***
4058 glEnableClientState(GL_VERTEX_ARRAY);
4059 if(!display.display3D.collectingHits && oglMesh)
4061 GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices );
4062 if(mesh.flags.doubleVertices)
4063 glVertexPointerd(3, 0, (double *)(vboAvailable ? null : mesh.vertices), mesh.nVertices);
4065 glVertexPointer(3, GL_FLOAT, 0, vboAvailable ? null : mesh.vertices);
4067 // *** Normals Stream ***
4068 if(mesh.normals || mesh.flags.normals)
4070 glEnableClientState(GL_NORMAL_ARRAY);
4071 GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
4072 glNormalPointer(/*mesh.flags.doubleNormals ? GL_DOUBLE : */GL_FLOAT, 0, vboAvailable ? null : mesh.normals);
4075 glDisableClientState(GL_NORMAL_ARRAY);
4077 // *** Texture Coordinates Stream ***
4078 if(mesh.texCoords || mesh.flags.texCoords1)
4080 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4081 GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
4082 glTexCoordPointer(2, GL_FLOAT, 0, vboAvailable ? null : mesh.texCoords);
4085 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4087 // *** Color Stream ***
4088 if(mesh.colors || mesh.flags.colors)
4090 glEnableClientState(GL_COLOR_ARRAY);
4091 GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
4092 glColorPointer(4, GL_FLOAT, 0, vboAvailable ? null : mesh.colors);
4095 glDisableClientState(GL_COLOR_ARRAY);
4100 GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
4101 if(mesh.flags.doubleVertices)
4102 glVertexPointerd(3, 0, (double *)mesh.vertices, mesh.nVertices);
4104 glVertexPointer(3, GL_FLOAT, 0, mesh.vertices);
4105 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
4107 glEnableClientState(GL_NORMAL_ARRAY);
4108 glNormalPointer(/*mesh.flags.doubleNormals ? GL_DOUBLE : */GL_FLOAT, 0, mesh.normals);
4111 glDisableClientState(GL_NORMAL_ARRAY);
4112 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
4114 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4115 glTexCoordPointer(2, GL_FLOAT, 0, mesh.texCoords);
4118 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4119 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
4121 glEnableClientState(GL_COLOR_ARRAY);
4122 glColorPointer(4, GL_FLOAT, 0, mesh.colors);
4125 glDisableClientState(GL_COLOR_ARRAY);
4128 #if !defined(__ANDROID__) && !defined(__APPLE__)
4130 #if defined(__WIN32__)
4134 glLockArraysEXT(0, mesh.nVertices);
4139 GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
4142 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
4144 //Logf("DrawPrimitives\n");
4146 if(primitive->type.vertexRange)
4147 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
4150 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
4151 // HACK TO SPEED THINGS UP...
4153 /*GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
4154 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
4157 glBegin(primitiveTypes[primitive->type.primitiveType]);
4160 OGLIndices oglIndices = primitive->data;
4161 MeshFeatures flags = mesh.flags;
4162 for(c = 0; c<primitive->nIndices; c++)
4164 uint16 index = ((uint16 *) oglIndices.indices)[c];
4165 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
4166 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
4167 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
4168 glVertex3fv((float *)&mesh.vertices[index]);
4176 OGLIndices oglIndices = primitive->data;
4178 if(!display.display3D.collectingHits && vboAvailable && oglIndices)
4180 GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
4181 if(primitive->type.indices32bit)
4182 glDrawElementsi(primitiveTypes[primitive->type.primitiveType], primitive->nIndices, 0);
4184 glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices, GL_UNSIGNED_SHORT, 0);
4185 GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
4189 if(primitive->type.indices32bit)
4190 glDrawElementsi(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
4191 oglIndices ? oglIndices.indices : primitive->indices);
4193 glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
4194 GL_UNSIGNED_SHORT, oglIndices ? oglIndices.indices : primitive->indices);
4200 void PushMatrix(Display display)
4205 void PopMatrix(Display display, bool setMatrix)
4210 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
4212 Matrix matrix = transMatrix;
4213 Camera camera = useCamera ? display.display3D.camera : null;
4218 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
4223 matrix.m[3][0] - camera.cPosition.x,
4224 matrix.m[3][1] - camera.cPosition.y,
4225 matrix.m[3][2] - camera.cPosition.z);
4237 glMultMatrixd(matrix.array);
4242 public void UseSingleGLContext(bool useSingle)
4244 useSingleGLContext = useSingle;
4247 default dllexport void *
4248 #if defined(__WIN32__)
4249 __attribute__((stdcall))
4251 IS_GLGetContext(DisplaySystem displaySystem)
4255 #if defined(__WIN32__)
4256 OGLSystem system = displaySystem.driverData;
4258 #elif defined(__ANDROID__)
4260 #elif defined(__EMSCRIPTEN__)
4262 OGLSystem system = displaySystem.driverData;
4263 return system.glContext;