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
91 //#include <GLES/gl.h>
92 //#include <EGL/egl.h>
94 //#include <GLES2/gl.h>
95 //#include <EGL/egl.h>
97 //#include <GLES2/gl2.h>
99 #include <emscripten/emscripten.h>
107 #include <GL/glext.h>
115 #if defined(__unix__) || defined(__APPLE__)
117 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
123 static double nearPlane = 1;
125 public double glesGetNearPlane()
130 public void glesSetNearPlane(double value)
135 #define glLoadMatrix glLoadMatrixd
136 #define glMultMatrix glMultMatrixd
137 #define glGetMatrix glGetDoublev
138 #define glTranslate glTranslated
139 #define glScale glScaled
142 #define glVertex3v glVertex3dv
143 #define glNormal3v glNormal3dv
147 //#ifdef VERTEX_FORMAT_DOUBLE
149 #define glLoadMatrix glLoadMatrixd
150 #define glMultMatrix glMultMatrixd
151 #define glGetMatrix glGetDoublev
152 #define glVertex3v glVertex3dv
153 #define glNormal3v glNormal3dv
154 #define glTranslate glTranslated
155 #define glScale glScaled
156 //#define GL_VERTEX_FORMAT GL_DOUBLE
160 #define glLoadMatrix glLoadMatrixf
161 #define glMultMatrix glMultMatrixf
162 #define glGetMatrix glGetFloatv
163 #define glVertex3v glVertex3fv
164 #define glNormal3v glNormal3fv
165 #define glTranslate glTranslatef
166 #define glScale glScalef
167 //#define GL_VERTEX_FORMAT GL_FLOAT
172 #define GL_ARRAY_BUFFER_ARB 0x8892
173 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
174 #define GL_STATIC_DRAW_ARB 0x88E4
175 #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
176 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
178 #define GL_MULTISAMPLE_ARB 0x809D
180 #if defined(__WIN32__)
182 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
183 #define WGL_SAMPLES_ARB 0x2042
185 #define WGL_WGLEXT_VERSION 1
186 #define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
187 #define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
188 #define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
189 #define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
190 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
191 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
192 #define WGL_DRAW_TO_BITMAP_ARB 0x2002
193 #define WGL_ACCELERATION_ARB 0x2003
194 #define WGL_NEED_PALETTE_ARB 0x2004
195 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
196 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
197 #define WGL_SWAP_METHOD_ARB 0x2007
198 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
199 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
200 #define WGL_TRANSPARENT_ARB 0x200A
201 #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
202 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
203 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
204 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
205 #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
206 #define WGL_SHARE_DEPTH_ARB 0x200C
207 #define WGL_SHARE_STENCIL_ARB 0x200D
208 #define WGL_SHARE_ACCUM_ARB 0x200E
209 #define WGL_SUPPORT_GDI_ARB 0x200F
210 #define WGL_SUPPORT_OPENGL_ARB 0x2010
211 #define WGL_DOUBLE_BUFFER_ARB 0x2011
212 #define WGL_STEREO_ARB 0x2012
213 #define WGL_PIXEL_TYPE_ARB 0x2013
214 #define WGL_COLOR_BITS_ARB 0x2014
215 #define WGL_RED_BITS_ARB 0x2015
216 #define WGL_RED_SHIFT_ARB 0x2016
217 #define WGL_GREEN_BITS_ARB 0x2017
218 #define WGL_GREEN_SHIFT_ARB 0x2018
219 #define WGL_BLUE_BITS_ARB 0x2019
220 #define WGL_BLUE_SHIFT_ARB 0x201A
221 #define WGL_ALPHA_BITS_ARB 0x201B
222 #define WGL_ALPHA_SHIFT_ARB 0x201C
223 #define WGL_ACCUM_BITS_ARB 0x201D
224 #define WGL_ACCUM_RED_BITS_ARB 0x201E
225 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
226 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
227 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
228 #define WGL_DEPTH_BITS_ARB 0x2022
229 #define WGL_STENCIL_BITS_ARB 0x2023
230 #define WGL_AUX_BUFFERS_ARB 0x2024
231 #define WGL_NO_ACCELERATION_ARB 0x2025
232 #define WGL_GENERIC_ACCELERATION_ARB 0x2026
233 #define WGL_FULL_ACCELERATION_ARB 0x2027
234 #define WGL_SWAP_EXCHANGE_ARB 0x2028
235 #define WGL_SWAP_COPY_ARB 0x2029
236 #define WGL_SWAP_UNDEFINED_ARB 0x202A
237 #define WGL_TYPE_RGBA_ARB 0x202B
238 #define WGL_TYPE_COLORINDEX_ARB 0x202C
239 #define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
240 #define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
241 #define WGL_DRAW_TO_PBUFFER_ARB 0x202D
242 #define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
243 #define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
244 #define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
245 #define WGL_PBUFFER_LARGEST_ARB 0x2033
246 #define WGL_PBUFFER_WIDTH_ARB 0x2034
247 #define WGL_PBUFFER_HEIGHT_ARB 0x2035
248 #define WGL_PBUFFER_LOST_ARB 0x2036
249 #define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
250 #define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
251 #define WGL_DRAW_TO_WINDOW_EXT 0x2001
252 #define WGL_DRAW_TO_BITMAP_EXT 0x2002
253 #define WGL_ACCELERATION_EXT 0x2003
254 #define WGL_NEED_PALETTE_EXT 0x2004
255 #define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
256 #define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
257 #define WGL_SWAP_METHOD_EXT 0x2007
258 #define WGL_NUMBER_OVERLAYS_EXT 0x2008
259 #define WGL_NUMBER_UNDERLAYS_EXT 0x2009
260 #define WGL_TRANSPARENT_EXT 0x200A
261 #define WGL_TRANSPARENT_VALUE_EXT 0x200B
262 #define WGL_SHARE_DEPTH_EXT 0x200C
263 #define WGL_SHARE_STENCIL_EXT 0x200D
264 #define WGL_SHARE_ACCUM_EXT 0x200E
265 #define WGL_SUPPORT_GDI_EXT 0x200F
266 #define WGL_SUPPORT_OPENGL_EXT 0x2010
267 #define WGL_DOUBLE_BUFFER_EXT 0x2011
268 #define WGL_STEREO_EXT 0x2012
269 #define WGL_PIXEL_TYPE_EXT 0x2013
270 #define WGL_COLOR_BITS_EXT 0x2014
271 #define WGL_RED_BITS_EXT 0x2015
272 #define WGL_RED_SHIFT_EXT 0x2016
273 #define WGL_GREEN_BITS_EXT 0x2017
274 #define WGL_GREEN_SHIFT_EXT 0x2018
275 #define WGL_BLUE_BITS_EXT 0x2019
276 #define WGL_BLUE_SHIFT_EXT 0x201A
277 #define WGL_ALPHA_BITS_EXT 0x201B
278 #define WGL_ALPHA_SHIFT_EXT 0x201C
279 #define WGL_ACCUM_BITS_EXT 0x201D
280 #define WGL_ACCUM_RED_BITS_EXT 0x201E
281 #define WGL_ACCUM_GREEN_BITS_EXT 0x201F
282 #define WGL_ACCUM_BLUE_BITS_EXT 0x2020
283 #define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
284 #define WGL_DEPTH_BITS_EXT 0x2022
285 #define WGL_STENCIL_BITS_EXT 0x2023
286 #define WGL_AUX_BUFFERS_EXT 0x2024
287 #define WGL_NO_ACCELERATION_EXT 0x2025
288 #define WGL_GENERIC_ACCELERATION_EXT 0x2026
289 #define WGL_FULL_ACCELERATION_EXT 0x2027
290 #define WGL_SWAP_EXCHANGE_EXT 0x2028
291 #define WGL_SWAP_COPY_EXT 0x2029
292 #define WGL_SWAP_UNDEFINED_EXT 0x202A
293 #define WGL_TYPE_RGBA_EXT 0x202B
294 #define WGL_TYPE_COLORINDEX_EXT 0x202C
295 #define WGL_DRAW_TO_PBUFFER_EXT 0x202D
296 #define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
297 #define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
298 #define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
299 #define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
300 #define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
301 #define WGL_PBUFFER_LARGEST_EXT 0x2033
302 #define WGL_PBUFFER_WIDTH_EXT 0x2034
303 #define WGL_PBUFFER_HEIGHT_EXT 0x2035
304 #define WGL_DEPTH_FLOAT_EXT 0x2040
305 #define WGL_SAMPLE_BUFFERS_3DFX 0x2060
306 #define WGL_SAMPLES_3DFX 0x2061
307 #define WGL_SAMPLE_BUFFERS_EXT 0x2041
308 #define WGL_SAMPLES_EXT 0x2042
309 #define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
310 #define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
311 #define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
312 #define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
313 #define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
314 #define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
315 #define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
316 #define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
317 #define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
318 #define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
319 #define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
320 #define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
321 #define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
322 #define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
323 #define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
324 #define WGL_ARB_buffer_region 1
325 #define WGL_ARB_extensions_string 1
326 #define WGL_ARB_pixel_format 1
327 #define WGL_ARB_make_current_read 1
328 #define WGL_ARB_pbuffer 1
329 #define WGL_EXT_display_color_table 1
330 #define WGL_EXT_extensions_string 1
331 #define WGL_EXT_make_current_read 1
332 #define WGL_EXT_pbuffer 1
333 #define WGL_EXT_pixel_format 1
334 #define WGL_EXT_swap_control 1
335 #define WGL_WGL_EXT_depth_float 1
336 #define WGL_WGL_3DFX_multisample 1
337 #define WGL_WGL_EXT_multisample 1
338 #define WGL_NV_allocate_memory 1
341 typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum target);
342 typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
343 typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum target);
344 typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
345 typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
349 typedef int (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
350 typedef int (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
351 typedef int (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
352 typedef int (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
354 typedef int (APIENTRY * PFNWGLCHOOSEPIXELFORMATARBPROC) ();
355 typedef void * (APIENTRY * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
356 typedef HDC (APIENTRY * PFNWGLGETPBUFFERDCARBPROC) (void * hPbuffer);
357 typedef int (APIENTRY * PFNWGLRELEASEPBUFFERDCARBPROC) (void * hPbuffer, HDC hDC);
358 typedef BOOL (APIENTRY * PFNWGLDESTROYPBUFFERARBPROC) (void * hPbuffer);
359 typedef BOOL (APIENTRY * PFNWGLQUERYPBUFFERARBPROC) (void * hPbuffer, int iAttribute, int *piValue);
360 typedef const char * (APIENTRY * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
361 typedef BOOL (APIENTRY * PFNWGLBINDTEXIMAGEARBPROC) (void * hPbuffer, int iBuffer);
362 typedef BOOL (APIENTRY * PFNWGLRELEASETEXIMAGEARBPROC) (void * hPbuffer, int iBuffer);
364 static PFNGLMAPBUFFERARBPROC glMapBufferARB = null;
365 static PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = null;
366 static PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = null;
367 static PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = null;
368 static PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = null;
369 static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
370 static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
371 static PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate = null;
373 static PFNGLGENBUFFERSARBPROC glGenBuffersARB = null;
374 static PFNGLBINDBUFFERARBPROC glBindBufferARB = null;
375 static PFNGLBUFFERDATAARBPROC glBufferDataARB = null;
376 static PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = null;
377 static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
378 static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
379 static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
380 static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
381 static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
382 static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
383 static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
384 static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
385 static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
387 #define glBufferData glBufferDataARB
389 #ifdef WGL_WGLEXT_PROTOTYPES
390 extern BOOL WINAPI wglSwapIntervalEXT (int);
391 extern int WINAPI wglGetSwapIntervalEXT (void);
392 #endif /* WGL_WGLEXT_PROTOTYPES */
393 typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
394 typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
396 static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
398 #elif defined(__ANDROID__)
400 #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
401 #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
402 #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
404 #define GL_POLYGON_STIPPLE 0xFFFF
405 #define GL_LINE_STIPPLE 0xFFFF
406 #define GL_LINE 0xFFFF
407 #define GL_FILL 0xFFFF
408 #define GL_ALL_ATTRIB_BITS 0xFFFF
409 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
415 #define GL_QUAD_STRIP 0
416 //#define GL_DOUBLE 0
417 //#define GL_UNSIGNED_INT 0
420 //#define GL_LINE_STIPPLE 0
421 #define GL_BGRA_EXT 0
422 #define GL_UNPACK_ROW_LENGTH 0
423 #define GL_UNPACK_SKIP_PIXELS 0
424 #define GL_UNPACK_SKIP_ROWS 0
426 #define GL_PACK_ROW_LENGTH 0
427 #define GL_PACK_SKIP_ROWS 0
428 #define GL_PACK_SKIP_PIXELS 0
432 #if defined(ECERE_NO3D) || defined(ECERE_VANILLA)
440 FillBytesBy4(this, 0, sizeof(Matrix) >> 2);
441 m[0][0]=m[1][1]=m[2][2]=m[3][3]=1;
444 void Transpose(Matrix source)
449 m[j][i] = source.m[i][j];
452 void Multiply(Matrix a, Matrix b)
454 // We need a full matrix multiplication for the Projection matrix
455 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];
456 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];
457 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];
458 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];
460 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];
461 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];
462 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];
463 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];
465 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];
466 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];
467 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];
468 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];
470 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];
471 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];
472 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];
473 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];
478 // Our own matrix stack
479 static Matrix matrixStack[3][32];
480 static int matrixIndex[3];
481 static int curStack = 0;
485 // OpenGL ES Porting Kit
486 #if defined(__ANDROID__)
487 #define glBindFramebuffer glBindFramebufferOES
488 #define glBindRenderbuffer glBindRenderbufferOES
489 #define glFramebufferTexture2D glFramebufferTexture2DOES
490 #define glGenFramebuffers glGenFramebuffersOES
491 #define glGenRenderbuffers glGenRenderbuffersOES
492 #define glDeleteFramebuffers glDeleteFramebuffersOES
493 #define glDeleteRenderbuffers glDeleteRenderbuffersOES
495 #define GL_INT 0x1404
496 #define GL_UNSIGNED_INT 0x1405
497 #define GL_DOUBLE 0x140A
501 #define glDrawElementsi(type, count, start) glDrawElements(type, count, GL_UNSIGNED_SHORT, start)
503 #define glBufferDatai glesBufferDatai
504 #define glBufferDatad glesBufferDatad
505 #define glVertexPointeri glesVertexPointeri
506 #define glVertexPointerd glesVertexPointerd
508 #define glRecti glesRecti
509 #define glBegin glesBegin
510 #define glTexCoord2i glesTexCoord2i
511 #define glVertex2i glesVertex2i
512 #define glTexCoord2d glesTexCoord2d
513 #define glVertex2d glesVertex2d
514 #define glTexCoord2f glesTexCoord2f
515 #define glVertex2f glesVertex2f
516 #define glEnd glesEnd
517 #define glColor3f glesColor3f
518 #define glColor4ub glesColor4ub
519 #define glColor4fv glesColor4fv
520 #define glLineStipple glesLineStipple
521 #define glNormal3fv glesNormal3fv
522 #define glTexCoord2fv glesTexCoord2fv
523 #define glColorMaterial glesColorMaterial
525 #define glLoadMatrixd glesLoadMatrixd
526 #define glMultMatrixd glesMultMatrixd
527 #define glFrustum glesFrustum
528 #define glOrtho glesOrtho
529 #define glScaled glesScaled
530 #define glTranslated glesTranslated
531 #define glRotated glesRotated
532 #define glVertex3d glesVertex3d
533 #define glVertex3dv glesVertex3dv
534 #define glVertex3f glesVertex3f
535 #define glVertex3fv glesVertex3fv
536 #define glLightModeli glesLightModeli
540 #define glVertexPointerd(nc, s, p, nv) glVertexPointer(nc, GL_DOUBLE, s, p)
541 #define glDrawElementsi(type, count, start) glDrawElements(type, count, GL_UNSIGNED_INT, start)
545 #if defined(__ANDROID__)
546 static EGLDisplay eglDisplay;
547 static EGLSurface eglSurface;
548 static EGLContext eglContext;
549 static int eglWidth, eglHeight;
551 static bool egl_init_display(ANativeWindow* window)
553 const EGLint attribs[] =
555 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
559 EGL_DEPTH_SIZE, 16, //24,
560 /*EGL_SAMPLE_BUFFERS, 1,
561 EGL_SAMPLES, 0, //2,*/
570 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
571 eglInitialize(display, 0, 0);
572 eglChooseConfig(display, attribs, &config, 1, &numConfigs);
573 eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
575 surface = eglCreateWindowSurface(display, config, window, null);
576 context = eglCreateContext(display, config, null, null);
578 if(!eglMakeCurrent(display, surface, surface, context))
581 eglQuerySurface(display, surface, EGL_WIDTH, &w);
582 eglQuerySurface(display, surface, EGL_HEIGHT, &h);
584 eglDisplay = display;
585 eglContext = context;
586 eglSurface = surface;
590 glEnableClientState(GL_VERTEX_ARRAY);
592 // Initialize GL state.
593 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
594 glEnable(GL_CULL_FACE);
595 glShadeModel(GL_SMOOTH);
596 glDisable(GL_DEPTH_TEST);
598 glDisable(GL_CULL_FACE);
599 glDisable(GL_DEPTH_TEST);
601 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
604 matrixStack[0][0].Identity();
605 matrixStack[1][0].Identity();
606 matrixStack[2][0].Identity();
608 glesMatrixMode(GL_MODELVIEW);
609 glScaled(1.0, 1.0, -1.0);
610 glesMatrixMode(GL_PROJECTION);
611 glShadeModel(GL_FLAT);
613 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
614 glFogi(GL_FOG_MODE, GL_EXP);
615 glFogf(GL_FOG_DENSITY, 0);
616 glEnable(GL_NORMALIZE);
617 glDepthFunc(GL_LESS);
619 glDisable(GL_MULTISAMPLE_ARB);
623 glOrtho(0,w,h,0,0.0,1.0);
625 currentVertexBuffer = 0;
629 static void egl_term_display()
633 glDeleteTextures(1, &stippleTexture);
636 if(eglDisplay != EGL_NO_DISPLAY)
638 eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
639 if(eglContext != EGL_NO_CONTEXT)
640 eglDestroyContext(eglDisplay, eglContext);
641 if(eglSurface != EGL_NO_SURFACE)
642 eglDestroySurface(eglDisplay, eglSurface);
643 eglTerminate(eglDisplay);
645 eglDisplay = EGL_NO_DISPLAY;
646 eglContext = EGL_NO_CONTEXT;
647 eglSurface = EGL_NO_SURFACE;
652 // OpenGL Immediate Mode Porting Kit
653 static int beginCount;
654 static int vertexCount;
655 static int normalCount;
656 static float *vertexPointer;
657 static float *normalPointer;
658 static GLenum beginMode = -1;
659 static uint beginBufferSize, normalBufferSize;
660 static int numVertexCoords = 2;
661 static bool vertexColorValues = false;
662 static int vertexStride = 4;
663 static int vertexOffset = 2;
665 public void glesRecti(int a, int b, int c, int d)
675 public void glesBegin(GLenum mode)
680 vertexColorValues = false;
687 normalBufferSize = beginBufferSize = 1024; // default number of vertices
688 vertexPointer = new float[beginBufferSize * vertexStride];
689 normalPointer = new float[normalBufferSize * 3];
693 public void glesTexCoord2f(float x, float y)
695 int count = vertexCount;
697 if(vertexCount + numVertexCoords > beginBufferSize)
699 beginBufferSize = beginBufferSize + beginBufferSize/2;
700 vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
703 vertexPointer[count*vertexStride ] = x;
704 vertexPointer[count*vertexStride+1] = y;
707 if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
709 vertexPointer[count*vertexStride ] = vertexPointer[(count-4)*vertexStride];
710 vertexPointer[count*vertexStride+1] = vertexPointer[(count-4)*vertexStride+1];
712 vertexPointer[count*vertexStride ] = vertexPointer[(count-3)*vertexStride];
713 vertexPointer[count*vertexStride+1] = vertexPointer[(count-3)*vertexStride+1];
717 public void glesTexCoord2i(int x, int y) { glesTexCoord2f((float)x, (float)y); }
718 public void glesTexCoord2d(double x, double y) { glesTexCoord2f((float)x, (float)y); }
719 public void glesTexCoord2fv(float * a) { glesTexCoord2f(a[0], a[1]); }
721 public void glesVertex2f(float x, float y)
724 vertexStride = vertexOffset + numVertexCoords;
726 if(vertexCount + 4 > beginBufferSize)
728 beginBufferSize = beginBufferSize + beginBufferSize/2;
729 vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
732 vertexPointer[vertexCount*vertexStride+vertexOffset] = x;
733 vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = y;
736 if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
738 vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset];
739 vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset + 1];
741 vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset];
742 vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset + 1];
747 public void glesVertex2i(int x, int y) { glesVertex2f((float)x, (float)y); }
748 public void glesVertex2d(double x, double y) { glesVertex2f((float)x, (float)y); }
750 public void glesEnd(void)
752 int mode = beginMode;
753 if(mode == GL_QUADS) mode = GL_TRIANGLES;
754 else if(mode == GL_POLYGON) mode = GL_TRIANGLE_FAN;
757 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
758 glTexCoordPointer(2, GL_FLOAT, vertexStride * sizeof(float), vertexPointer);
759 if(vertexColorValues)
761 glEnableClientState(GL_COLOR_ARRAY);
762 glColorPointer(4, GL_FLOAT, vertexStride * sizeof(float), vertexPointer + 2);
764 glVertexPointer (numVertexCoords, GL_FLOAT, (vertexStride)*sizeof(float),vertexPointer+vertexOffset);
765 if(normalCount && normalCount == vertexCount)
767 glEnableClientState(GL_NORMAL_ARRAY);
768 glNormalPointer (GL_FLOAT, 3*sizeof(float),normalPointer);
771 glDrawArrays(mode, 0, vertexCount);
773 glDisableClientState(GL_NORMAL_ARRAY);
774 if(vertexColorValues)
775 glDisableClientState(GL_COLOR_ARRAY);
776 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
778 vertexColorValues = false;
784 static float *floatVPBuffer = null;
785 static short *shortVPBuffer = null;
786 static unsigned int shortVPSize = 0, floatVPSize = 0;
789 //static float *floatVPBuffer = null; // For floats we reuse floatVPBuffer
790 static unsigned short *shortBDBuffer = null;
791 static unsigned int shortBDSize = 0/*, floatVPSize = 0*/;
793 public void glesVertexPointeri(int numCoords, int stride, int *pointer, int numVertices)
798 if(numVertices*numCoords > shortVPSize)
800 shortVPSize = numVertices*numCoords;
801 shortVPBuffer = renew shortVPBuffer short[shortVPSize];
803 for(i = 0; i < numVertices*numCoords; i++)
804 shortVPBuffer[i] = (short)pointer[i];
805 glVertexPointer(numCoords, GL_SHORT, stride, shortVPBuffer);
808 glVertexPointer(numCoords, GL_SHORT, stride, 0);
811 public void glesVertexPointerd(int numCoords, int stride, double *pointer, int numVertices)
816 if(numVertices*numCoords > floatVPSize)
818 floatVPSize = numVertices*numCoords;
819 floatVPBuffer = renew floatVPBuffer float[floatVPSize];
821 for(i = 0; i < numVertices*numCoords; i++)
822 floatVPBuffer[i] = (float)pointer[i];
823 glVertexPointer(numCoords, GL_FLOAT, stride, floatVPBuffer);
826 glVertexPointer(numCoords, GL_FLOAT, stride, 0);
829 public void glesTexReuseIntVP(int numCoords)
831 glTexCoordPointer(numCoords, GL_SHORT, 0, floatVPBuffer);
834 public void glesTexReuseDoubleVP(int numCoords)
836 glTexCoordPointer(numCoords, GL_FLOAT, 0, floatVPBuffer);
839 public void glesColor4f(float r, float g, float b, float a)
841 if(beginMode != (GLenum)-1)
843 int count = vertexCount;
845 vertexColorValues = true;
847 vertexStride = vertexOffset + numVertexCoords;
849 if(vertexCount + vertexStride > beginBufferSize)
851 beginBufferSize = beginBufferSize + beginBufferSize/2;
852 vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
855 vertexPointer[count*vertexStride + 2] = r;
856 vertexPointer[count*vertexStride + 3] = g;
857 vertexPointer[count*vertexStride + 4] = b;
858 vertexPointer[count*vertexStride + 5] = a;
861 if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
863 vertexPointer[count*vertexStride + 2] = vertexPointer[(count-4) * vertexStride + 2];
864 vertexPointer[count*vertexStride + 3] = vertexPointer[(count-4) * vertexStride + 3];
865 vertexPointer[count*vertexStride + 4] = vertexPointer[(count-4) * vertexStride + 4];
866 vertexPointer[count*vertexStride + 5] = vertexPointer[(count-4) * vertexStride + 5];
868 vertexPointer[count*vertexStride + 2] = vertexPointer[(count-3) * vertexStride + 2];
869 vertexPointer[count*vertexStride + 3] = vertexPointer[(count-3) * vertexStride + 3];
870 vertexPointer[count*vertexStride + 4] = vertexPointer[(count-3) * vertexStride + 4];
871 vertexPointer[count*vertexStride + 5] = vertexPointer[(count-3) * vertexStride + 5];
876 glColor4f(r, g, b, a);
879 public void glesColor3f( float r, float g, float b )
881 glesColor4f(r, g, b, 1.0f);
884 public void glesColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
886 glesColor4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f);
889 public void glesColor4fv(float * a)
891 glesColor4f(a[0], a[1], a[2], a[3]);
894 public void glesBufferDatad(int target, int size, void * data, int usage)
896 int numElems = size/sizeof(double);
897 double * dblPtr = (double *)data;
899 if (numElems > floatVPSize)
901 floatVPSize = numElems;
902 floatVPBuffer = renew floatVPBuffer float[floatVPSize];
904 for (i=0; i< numElems; i++)
905 floatVPBuffer[i] = (float)dblPtr[i];
907 glBufferData(target, numElems*sizeof(float), floatVPBuffer, usage);
910 public void glesBufferDatai(int target, int size, void * data, int usage)
912 int numElems = size/sizeof(unsigned int);
913 unsigned int * pointer = (unsigned int *)data;
915 if (numElems > shortBDSize)
917 shortBDSize = numElems;
918 shortBDBuffer = renew shortBDBuffer uint16[shortBDSize];
920 for (i=0; i< numElems; i++)
921 shortBDBuffer[i] = (unsigned short)pointer[i];
923 glBufferData(target, numElems*sizeof(unsigned short), shortBDBuffer, usage);
926 // *** Our Custom Matrix Stack ***
928 static void LoadCurMatrix()
930 double * i = matrixStack[curStack][matrixIndex[curStack]].array;
933 (float)i[0],(float)i[1],(float)i[2],(float)i[3],
934 (float)i[4],(float)i[5],(float)i[6],(float)i[7],
935 (float)i[8],(float)i[9],(float)i[10],(float)i[11],
936 (float)i[12],(float)i[13],(float)i[14],(float)i[15]
941 public void glesLoadIdentity()
943 matrixStack[curStack][matrixIndex[curStack]].Identity();
947 public void glesPushMatrix()
949 if(matrixIndex[curStack] + 1 < sizeof(matrixStack[0]) / sizeof(Matrix))
951 matrixIndex[curStack]++;
952 memcpy(matrixStack[curStack][matrixIndex[curStack]].array, matrixStack[curStack][matrixIndex[curStack]-1].array, sizeof(Matrix));
956 public void glesPopMatrix()
958 if(matrixIndex[curStack] > 0)
960 matrixIndex[curStack]--;
965 public void glesLoadMatrixd(double * i)
967 memcpy(matrixStack[curStack][matrixIndex[curStack]].array, i, sizeof(Matrix));
971 public void glesOrtho( double l, double r, double b, double t, double n, double f )
975 (2 / (r - l)), 0, 0, 0,
976 0, (2 / (t - b)), 0, 0,
977 0, 0, (-2 / (f - n)), 0,
978 (-(r + l) / (r - l)), (-(t + b) / (t - b)), (-(f + n) / (f - n)), 1
981 res.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
982 matrixStack[curStack][matrixIndex[curStack]] = res;
986 public void glesFrustum( double l, double r, double b, double t, double n, double f )
996 double A = ((r + l) / (r - l));
997 double B = ((t + b) / (t - b));
998 double C = (-(f + n) / (f - n));
999 double D = (-2*f*n/(f-n));
1002 (2.0*n / (r - l)), 0, 0, 0,
1003 0, (2.0*n / (t - b)), 0, 0,
1008 res.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
1009 matrixStack[curStack][matrixIndex[curStack]] = res;
1014 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1015 public void glesRotated( double a, double b, double c, double d )
1020 q.RotationAxis({(float)b,(float)c,(float)-d}, a );
1021 m.RotationQuaternion(q);
1022 r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
1023 matrixStack[curStack][matrixIndex[curStack]] = r;
1026 public void glesScaled( double a, double b, double c )
1032 r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
1033 matrixStack[curStack][matrixIndex[curStack]] = r;
1037 public void glesTranslated( double a, double b, double c )
1043 r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
1044 matrixStack[curStack][matrixIndex[curStack]] = r;
1048 public void glesMultMatrixd( double * i )
1051 r.Multiply((Matrix *)i, matrixStack[curStack][matrixIndex[curStack]]);
1052 matrixStack[curStack][matrixIndex[curStack]] = r;
1057 public void glesMatrixMode(int mode)
1059 curStack = (mode == GL_MODELVIEW) ? 0 : (mode == GL_PROJECTION) ? 1 : 2;
1065 #define glPushMatrix glesPushMatrix
1066 #define glPopMatrix glesPopMatrix
1067 #define glLoadIdentity glesLoadIdentity
1068 #define glMatrixMode glesMatrixMode
1072 /* Using the built-in matrix stack
1073 void glesLoadMatrixd( double * i )
1077 (float)i[0],(float)i[1],(float)i[2],(float)i[3],
1078 (float)i[4],(float)i[5],(float)i[6],(float)i[7],
1079 (float)i[8],(float)i[9],(float)i[10],(float)i[11],
1080 (float)i[12],(float)i[13],(float)i[14],(float)i[15]
1085 void glesOrtho( double l, double r, double b, double t, double n, double f )
1087 float matrix[4][4] =
1089 { (float)(2 / (r - l)), 0, 0, 0 },
1090 { 0, (float)(2 / (t - b)), 0, 0 },
1091 { 0, 0, (float)(-2 / (f - n)), 0 },
1092 { (float)(-(r + l) / (r - l)), (float)(-(t + b) / (t - b)), (float)(-(f + n) / (f - n)), 1 }
1094 glMultMatrixf((float *)matrix);
1097 void glesFrustum( double l, double r, double b, double t, double n, double f )
1099 float A = (float)((r + l) / (r - l));
1100 float B = (float)((t + b) / (t - b));
1101 float C = (float)(-(f + n) / (f - n));
1102 float D = (float)(-2*f*n/(f-n));
1103 float matrix[4][4] =
1105 { (float)(2*n / (r - l)), 0, 0, 0 },
1106 { 0, (float)(2*n / (t - b)), 0, 0 },
1110 glMultMatrixf((float *)matrix);
1113 void glesRotated( double a, double b, double c, double d ) { glRotatef((float)a, (float)b, (float)c, (float)d); }
1114 void glesScaled( double a, double b, double c ) { glScalef((float)a, (float)b, (float)c); }
1115 void glesTranslated( double a, double b, double c ) { glTranslatef((float)a, (float)b, (float)c); }
1117 void glesMultMatrixd( double * i )
1121 (float)i[0], (float)i[1], (float)i[2], (float)i[3],
1122 (float)i[4], (float)i[5], (float)i[6], (float)i[7],
1123 (float)i[8], (float)i[9], (float)i[10], (float)i[11],
1124 (float)i[12], (float)i[13], (float)i[14], (float)i[15]
1130 // Need to do these...
1131 public void glesVertex3f( float x, float y, float z )
1133 numVertexCoords = 3;
1134 vertexStride = vertexOffset + numVertexCoords;
1136 if(vertexCount + vertexStride > beginBufferSize)
1138 beginBufferSize = beginBufferSize + beginBufferSize/2;
1139 vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
1142 vertexPointer[vertexCount*vertexStride+vertexOffset] = x;
1143 vertexPointer[vertexCount*vertexStride+vertexOffset+1] = y;
1144 vertexPointer[vertexCount*vertexStride+vertexOffset+2] = z;
1147 if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
1149 vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset];
1150 vertexPointer[vertexCount*vertexStride+vertexOffset+1] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset+1];
1151 vertexPointer[vertexCount*vertexStride+vertexOffset+2] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset+2];
1153 vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset];
1154 vertexPointer[vertexCount*vertexStride+vertexOffset+1] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset+1];
1155 vertexPointer[vertexCount*vertexStride+vertexOffset+2] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset+2];
1161 public void glesVertex3d( double x, double y, double z ) { glesVertex3f((float)x, (float)y, (float)z); }
1162 public void glesVertex3fv( float* coords ) { glesVertex3f(coords[0], coords[1], coords[2]); }
1163 public void glesVertex3dv( double* coords ) { glesVertex3f((float)coords[0], (float)coords[1], (float)coords[2]); }
1165 public void glesNormal3f(float x, float y, float z)
1167 normalCount = vertexCount;
1168 if(vertexCount + 4 > normalBufferSize)
1170 normalBufferSize = normalBufferSize + normalBufferSize/2;
1171 normalPointer = renew normalPointer float[normalBufferSize * 2];
1174 normalPointer[normalCount*3+0] = x;
1175 normalPointer[normalCount*3+1] = y;
1176 normalPointer[normalCount*3+2] = z;
1179 if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
1181 normalPointer[normalCount*3+0] = normalPointer[(normalCount-4)*3+0];
1182 normalPointer[normalCount*3+1] = normalPointer[(normalCount-4)*3+1];
1183 normalPointer[normalCount*3+2] = normalPointer[(normalCount-4)*3+2];
1185 normalPointer[normalCount*3+0] = normalPointer[(normalCount-3)*3+0];
1186 normalPointer[normalCount*3+1] = normalPointer[(normalCount-3)*3+1];
1187 normalPointer[normalCount*3+2] = normalPointer[(normalCount-3)*3+2];
1191 public void glesNormal3fd(double x, double y, double z) { glesNormal3f((float)x, (float)y, (float)z); }
1192 public void glesNormal3fv(float * coords) { glesNormal3f(coords[0], coords[1], coords[2]); }
1194 public void glesColorMaterial(int a, int b)
1196 PrintLn("glColorMaterial stub");
1199 public void glesTerminate()
1201 delete vertexPointer;
1202 delete normalPointer;
1203 beginBufferSize = 0;
1205 delete floatVPBuffer;
1208 delete shortVPBuffer;
1211 delete shortBDBuffer;
1215 static GLuint stippleTexture;
1216 #if defined(_GLES) || defined(__EMSCRIPTEN__)
1217 static bool stippleEnabled;
1220 public void glesLineStipple( int i, unsigned short j )
1224 for(x = 0; x < 16; x++)
1226 bool v = (j & (1 << x)) != 0;
1227 texture[x] = v ? 0xFFFFFFFF : 0;
1230 glGenTextures(1, &stippleTexture);
1231 glBindTexture(GL_TEXTURE_2D, stippleTexture);
1232 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
1233 glEnable(GL_TEXTURE_2D);
1234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1235 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1236 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1238 glMatrixMode(GL_TEXTURE);
1240 //glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
1241 glScaled(i/16.0, 1, 1.0f);
1242 glTranslated(0.5, 0.5, 0);
1243 glMatrixMode(GL_PROJECTION);
1246 public void glesLightModeli( unsigned int pname, int param )
1248 #if !defined(__EMSCRIPTEN__)
1249 if(pname == GL_LIGHT_MODEL_TWO_SIDE)
1250 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
1255 void glClearDepth( double depth ) { glClearDepthf((float)depth); }
1256 void glFogi( unsigned int pname, int param ) { }
1257 void glPolygonMode( unsigned int i, unsigned int j ) { }
1260 // *** Picking won't be supported for now ***
1261 void glPushName( unsigned int i ) { }
1262 void glLoadName( unsigned int i ) { }
1263 void glPopName() { }
1265 // Probably replace by regular glBlendFunc ...
1266 void glBlendFuncSeparate(int a, int b, int c, int d)
1271 // For direct pixel blitting...
1272 void glRasterPos2d(double a, double b) { }
1273 void glPixelZoom(float a, float b) { }
1274 void glDrawPixels(int a, int b, int c, int d, void * e) { }
1278 #if !defined(__APPLE__) && !defined(__WIN32__)
1279 void (APIENTRY * glBindBufferARB) (GLenum target, GLuint buffer);
1280 void (APIENTRY * glGenBuffersARB) (GLsizei n, GLuint *buffers);
1281 void (APIENTRY * glDeleteBuffersARB) (GLsizei n, const GLuint *buffers);
1282 void (APIENTRY * glBufferDataARB) (GLenum target, int size, const GLvoid *data, GLenum usage);
1285 static int currentVertexBuffer;
1287 bool GLSelectVBO(uint vbo)
1289 if(currentVertexBuffer != vbo)
1291 GLBindBuffer(GL_ARRAY_BUFFER, vbo);
1292 currentVertexBuffer = vbo;
1298 void GLGenBuffers(int count, uint * buffer)
1300 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1301 glGenBuffers(count, buffer);
1303 #if defined(__WIN32__)
1306 glGenBuffersARB(count, buffer);
1310 void GLDeleteBuffers(int count, GLuint * buffer)
1312 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1313 glDeleteBuffers(count, buffer);
1315 #if defined(__WIN32__)
1316 if(glDeleteBuffersARB)
1318 glDeleteBuffersARB(count, buffer);
1322 void GLBindBuffer(int target, uint buffer)
1324 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1325 glBindBuffer(target, buffer);
1327 #if defined(__WIN32__)
1330 glBindBufferARB(target, buffer);
1332 currentVertexBuffer = buffer;
1335 public void GLVertexPointer(int numCoords, int glType, int stride, void *ptr, int numVertices)
1338 if(glType == GL_DOUBLE)
1339 glesVertexPointerd(numCoords, stride, ptr, numVertices);
1340 else if(glType == GL_INT)
1341 glesVertexPointeri(numCoords, stride, ptr, numVertices);
1344 glVertexPointer(numCoords, glType, stride, ptr);
1347 public void GLBufferData(int type, GLenum target, int size, const GLvoid *data, GLenum usage)
1350 if(type == GL_DOUBLE)
1351 glesBufferDatad(target, size, (void *)data, usage);
1352 else if(type == GL_UNSIGNED_INT)
1353 glesBufferDatai(target, size, (void *)data, usage);
1357 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1358 glBufferData(target, size, data, usage);
1361 #if defined(__WIN32__)
1364 glBufferDataARB(target, size, data, usage);
1368 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1369 static int primitiveTypes[RenderPrimitiveType] =
1371 GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, GL_LINE_STRIP
1376 // Non OpenGL ES friendly stuff
1380 //#undef GL_UNSIGNED_INT
1385 #undef GL_QUAD_STRIP
1386 #undef GL_POLYGON_STIPPLE
1387 #undef GL_LINE_STIPPLE
1390 #undef GL_ALL_ATTRIB_BITS
1391 #undef GL_LIGHT_MODEL_LOCAL_VIEWER
1395 static int displayWidth, displayHeight;
1397 #define GL_CLAMP_TO_EDGE 0x812F
1399 static bool vboAvailable;
1401 static bool useSingleGLContext = false;
1402 class OGLDisplay : struct
1404 #if defined(__WIN32__)
1414 int imageBuffers[2];
1415 byte * pboMemory1, * pboMemory2;
1417 #elif !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
1418 GLXContext glContext;
1421 XShmSegmentInfo shminfo;
1423 XShmSegmentInfo shminfoShape;
1424 XImage * shapeImage;
1428 X11Picture windowPicture;
1429 X11Picture pixmapPicture;
1431 X11Picture shapePicture;
1434 ColorAlpha * flippingBuffer;
1435 int flipBufH, flipBufW;
1440 class OGLSystem : struct
1445 #if defined(__WIN32__)
1446 PIXELFORMATDESCRIPTOR pfd;
1451 #elif !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
1452 XVisualInfo * visualInfo;
1453 GLXContext glContext;
1454 GLXDrawable glxDrawable;
1458 class OGLSurface : struct
1464 bool writingOutline;
1466 float foreground[4], background[4], bitmapMult[4];
1469 class OGLMesh : struct
1478 class OGLIndices : struct
1488 class OpenGLDisplayDriver : DisplayDriver
1490 class_property(name) = "OpenGL";
1492 bool LockSystem(DisplaySystem displaySystem)
1494 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
1495 OGLSystem oglSystem = displaySystem.driverData;
1496 if(useSingleGLContext) return true;
1497 #if defined(__WIN32__)
1498 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1499 #elif defined(__unix__) || defined(__APPLE__)
1500 //if(previous) return true;
1501 // printf("Making SYSTEM current\n");
1502 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)oglSystem.glxDrawable, oglSystem.glContext);
1503 //previous = oglSystem.glContext;
1509 void UnlockSystem(DisplaySystem displaySystem)
1511 if(useSingleGLContext) return;
1512 #if defined(__WIN32__)
1513 wglMakeCurrent(null, null);
1514 #elif defined(__unix__) || defined(__APPLE__)
1515 // printf("Making NULL current\n");
1516 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1518 glXMakeCurrent(xGlobalDisplay, None, null);
1524 bool Lock(Display display)
1526 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
1527 OGLDisplay oglDisplay = display.driverData;
1528 if(useSingleGLContext) return true;
1529 #if defined(__WIN32__)
1530 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1531 #elif defined(__unix__) || defined(__APPLE__)
1532 // if(previous) glXMakeCurrent(xGlobalDisplay, None, null);
1533 // printf(" Making DISPLAY current\n");
1534 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1540 void Unlock(Display display)
1542 if(useSingleGLContext) return;
1543 //printf(" Making NULL current\n");
1544 //glXMakeCurrent(xGlobalDisplay, None, null);
1546 LockSystem(display.displaySystem);
1549 void DestroyDisplay(Display display)
1551 OGLDisplay oglDisplay = display.driverData;
1555 #if defined(__WIN32__)
1556 wglMakeCurrent( null, null );
1559 wglDeleteContext(oglDisplay.glrc);
1561 if(oglDisplay.hdc && oglDisplay.pBuffer)
1562 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
1564 if(oglDisplay.pBuffer)
1565 wglDestroyPbufferARB(oglDisplay.pBuffer);
1568 ReleaseDC(display.window, oglDisplay.hdc);
1570 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
1571 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
1573 #elif defined(__unix__) || defined(__APPLE__)
1574 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1576 if(oglDisplay.shapePixmap)
1577 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
1578 if(oglDisplay.pixmap)
1579 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
1580 if(oglDisplay.image)
1582 if(oglDisplay.shminfoShape.shmid != -1)
1584 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
1585 if(oglDisplay.shminfo.shmaddr != (void *)-1)
1586 shmdt(oglDisplay.shminfo.shmaddr);
1587 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
1590 if(oglDisplay.shapeImage)
1592 if(oglDisplay.shminfoShape.shmid != -1)
1594 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
1595 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
1596 shmdt(oglDisplay.shminfoShape.shmaddr);
1597 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
1599 XDestroyImage(oglDisplay.shapeImage);
1600 oglDisplay.shapeImage = None;
1603 glXMakeCurrent(xGlobalDisplay, None, null);
1605 if(oglDisplay.glContext)
1606 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
1609 delete oglDisplay.flippingBuffer;
1611 display.driverData = null;
1615 void ::CheckExtensions(OGLSystem oglSystem)
1617 const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
1619 oglSystem.pow2textures = strstr(extensions, "GL_ARB_texture_non_power_of_two") ? false : true;
1620 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
1623 bool CreateDisplaySystem(DisplaySystem displaySystem)
1625 bool result = false;
1626 OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
1629 oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
1631 oglSystem.hdc = GetDC(oglSystem.hwnd);
1635 oglSystem.pfd.nSize = (short)sizeof(oglSystem.pfd);
1636 oglSystem.pfd.nVersion = 1;
1637 oglSystem.pfd.dwFlags = PFD_DRAW_TO_WINDOW /*PFD_DRAW_TO_BITMAP*/ | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
1638 oglSystem.pfd.iPixelType = PFD_TYPE_RGBA;
1639 oglSystem.pfd.cColorBits = 24;
1640 oglSystem.pfd.cAlphaBits = 8;
1641 oglSystem.pfd.cDepthBits = 24;
1642 oglSystem.pfd.iLayerType = PFD_MAIN_PLANE;
1644 oglSystem.format = ChoosePixelFormat(oglSystem.hdc, &oglSystem.pfd);
1645 DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1647 if(oglSystem.pfd.cColorBits > 8)
1649 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1650 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
1653 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1655 // Get Pointers To The GL Functions
1656 glActiveTextureARB = (void *) wglGetProcAddress("glActiveTextureARB");
1657 glMultiTexCoord2fARB = (void *) wglGetProcAddress("glMultiTexCoord2fARB");
1658 glClientActiveTextureARB = (void *) wglGetProcAddress("glClientActiveTextureARB");
1659 glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
1660 glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
1661 glGenBuffersARB = (void *) wglGetProcAddress("glGenBuffersARB");
1662 glBindBufferARB = (void *) wglGetProcAddress("glBindBufferARB");
1663 glBufferDataARB = (void *) wglGetProcAddress("glBufferDataARB");
1664 glMapBufferARB = (void *) wglGetProcAddress("glMapBufferARB");
1665 glUnmapBufferARB = (void *) wglGetProcAddress("glUnmapBufferARB");
1666 glDeleteBuffersARB = (void *) wglGetProcAddress("glDeleteBuffersARB");
1667 glBlendFuncSeparate = (void *) wglGetProcAddress("glBlendFuncSeparate");
1669 wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
1670 wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
1671 wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
1672 wglGetPbufferDCARB = (void *)wglGetProcAddress("wglGetPbufferDCARB");
1673 wglQueryPbufferARB = (void *)wglGetProcAddress("wglQueryPbufferARB");
1674 wglDestroyPbufferARB = (void *)wglGetProcAddress("wglDestroyPbufferARB");
1675 wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
1676 wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
1677 wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
1679 wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
1681 vboAvailable = glBindBufferARB != null;
1683 // eSystem_LoggingMode(LOG_MSGBOX, null);
1685 if(wglChoosePixelFormatARB)
1690 float fAttributes[] = {0,0};
1693 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
1694 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
1695 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
1696 WGL_COLOR_BITS_ARB,24,
1697 WGL_ALPHA_BITS_ARB,8,
1698 WGL_DEPTH_BITS_ARB,16,
1699 WGL_STENCIL_BITS_ARB,0,
1700 WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
1701 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
1702 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
1706 //Log("Found wglChoosePixelFormatARB\n");
1708 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1709 if(!valid || !numFormats)
1711 //Log("Can't find 4x multi sampling\n");
1712 iAttributes[19] = 2;
1713 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1714 if(!valid || !numFormats)
1716 // Log("Can't find 2x multi sampling\n");
1717 iAttributes[16] = 0;
1718 iAttributes[17] = 0;
1719 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
1722 if(valid && numFormats)
1724 oglSystem.format = pixelFormat;
1725 wglMakeCurrent(null, null);
1726 wglDeleteContext(oglSystem.glrc);
1728 // *** DescribePixelFormat does not support WGL pixel formats! ***
1729 //DescribePixelFormat(oglSystem.hdc, oglSystem.format, sizeof(oglSystem.pfd), &oglSystem.pfd);
1730 SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
1731 //Log("Successfully set pixel format\n");
1733 oglSystem.glrc = wglCreateContext(oglSystem.hdc);
1734 wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
1738 eSystem_Logf("Can't find wglChoosePixelFormatARB\n");*/
1742 CheckExtensions(oglSystem);
1744 wglMakeCurrent(null, null);
1746 //eSystem_DumpErrors(true);
1750 #elif defined(__unix__) || defined(__APPLE__)
1751 vboAvailable = true;
1752 #if defined(__ANDROID__)
1753 egl_init_display(guiApp.desktop.windowHandle);
1754 CheckExtensions(oglSystem);
1756 #elif defined(__EMSCRIPTEN__)
1757 if(glfwInit() == GL_TRUE)
1759 const int width = 640, height = 480;
1760 if(glfwOpenWindow(width, height, 8, 8, 8, 8, 16, 0, GLFW_WINDOW) == GL_TRUE)
1762 //glfwSwapBuffers();
1766 printf("glfwOpenWindow() failed\n"); //glfwTerminate();
1769 printf("glfwInit() failed\n"); //glfwTerminate();
1772 X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
1773 XSetWindowAttributes attr;
1778 #ifndef ECERE_MINIGLX
1779 GLX_USE_GL, GLX_DEPTH_SIZE, 1,
1782 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
1786 oglSystem.visualInfo = glXChooseVisual( xGlobalDisplay, DefaultScreen( xGlobalDisplay ), attrList );
1787 attr.background_pixel = 0;
1788 attr.border_pixel = 0;
1789 attr.colormap = XCreateColormap( xGlobalDisplay, root, oglSystem.visualInfo->visual, AllocNone);
1790 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
1791 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
1793 oglSystem.glxDrawable = XCreateWindow( xGlobalDisplay, root, 0, 0, 1, 1, 0, oglSystem.visualInfo->depth, InputOutput,
1794 oglSystem.visualInfo->visual, mask, &attr );
1796 if(oglSystem.visualInfo)
1798 oglSystem.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, null, True);
1799 if(oglSystem.glContext)
1801 glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
1803 CheckExtensions(oglSystem);
1804 glXMakeCurrent(xGlobalDisplay, None, null);
1811 displaySystem.flags.alpha = true;
1812 displaySystem.flags.flipping = true;
1813 displaySystem.pixelFormat = pixelFormat888;
1817 void DestroyDisplaySystem(DisplaySystem displaySystem)
1819 OGLSystem oglSystem = displaySystem.driverData;
1821 #if defined(__WIN32__)
1822 wglMakeCurrent( null, null );
1825 wglDeleteContext(oglSystem.glrc);
1828 ReleaseDC(oglSystem.hwnd, oglSystem.hdc);
1829 DestroyWindow(oglSystem.hwnd);
1831 #elif defined(__unix__) || defined(__APPLE__)
1832 #if defined(__ANDROID__)
1834 #elif defined(__EMSCRIPTEN__)
1837 if(oglSystem.visualInfo)
1839 #ifdef ECERE_MINIGLX
1840 __miniglx_XFree(oglSystem.visualInfo);
1842 XFree(oglSystem.visualInfo);
1846 if(oglSystem.glxDrawable)
1848 XDestroyWindow(xGlobalDisplay, oglSystem.glxDrawable);
1849 oglSystem.glxDrawable = 0;
1856 bool CreateDisplay(Display display)
1858 bool result = false;
1859 OGLDisplay oglDisplay = display.driverData;
1860 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
1861 OGLSystem oglSystem = display.displaySystem.driverData;
1864 oglDisplay = display.driverData = OGLDisplay { };
1865 //printf("Inside CreateDisplay\n");
1867 #if defined(__WIN32__) || defined(USEPBUFFER)
1868 if(!display.alphaBlend)
1871 #if defined(__WIN32__)
1872 oglDisplay.hdc = GetDC(display.window);
1873 SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
1874 if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
1876 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
1877 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
1881 ReleaseDC(display.window, oglDisplay.hdc);
1882 #elif defined(__unix__) || defined(__APPLE__)
1883 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1885 XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
1887 #if defined(__APPLE__)
1888 XVisualInfo template = { 0 };
1889 XWindowAttributes winAttr;
1891 XGetWindowAttributes(xGlobalDisplay, (X11Window)display.window, &winAttr);
1892 template.visualid = XVisualIDFromVisual(winAttr.visual);
1893 visualInfo = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &template, &n);
1895 printf("XGetVisualInfo visual ID = %d\n", template.visualid);
1896 printf("visualInfo visual ID = %d\n", visualInfo->visualid);
1897 printf("oglSystem.visualInfo visual ID = %d\n", oglSystem.visualInfo->visualid);
1898 printf("((XWindowData)display.windowDriverData).visual visual ID = %d\n", ((XWindowData)display.windowDriverData).visual->visualid);
1900 // visualInfo = oglSystem.visualInfo;
1905 //printf("visualInfo is not null\n");
1906 // printf("Creating Display Context, sharing with %x!\n", oglSystem.glContext);
1907 oglDisplay.glContext = glXCreateContext(xGlobalDisplay, visualInfo, oglSystem.glContext, True);
1908 //XFree(visualInfo);
1911 // oglDisplay.glContext = glXCreateContext(xGlobalDisplay, oglSystem.visualInfo, oglSystem.glContext, True);
1912 if(oglDisplay.glContext)
1914 //printf("CreateDisplay Got a Context\n");
1915 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
1921 #if defined(__WIN32__) || defined(USEPBUFFER)
1927 #if defined(__WIN32__)
1928 if(glBlendFuncSeparate)
1929 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1931 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1933 #if !defined(__OLDX__)
1934 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1936 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1941 glMatrixMode(GL_MODELVIEW);
1942 glScaled(1.0, 1.0, -1.0);
1943 // glTranslatef(0.375f, 0.375f, 0.0f);
1944 // glTranslatef(-0.625f, -0.625f, 0.0f);
1945 glMatrixMode(GL_PROJECTION);
1946 glShadeModel(GL_FLAT);
1948 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, true);
1949 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1950 glFogi(GL_FOG_MODE, GL_EXP);
1951 glFogf(GL_FOG_DENSITY, 0);
1952 glEnable(GL_NORMALIZE);
1953 glDepthFunc(GL_LESS);
1955 glDisable(GL_MULTISAMPLE_ARB);
1957 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1958 display.ambient = Color { 50,50,50 };
1961 if(!useSingleGLContext)
1963 #if defined(__WIN32__)
1964 wglMakeCurrent(null, null);
1965 #elif defined(__unix__) || defined(__APPLE__)
1966 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
1969 glXMakeCurrent(xGlobalDisplay, None, null);
1977 bool DisplaySize(Display display, int width, int height)
1979 OGLDisplay oglDisplay = display.driverData;
1981 bool result = false;
1983 //printf("Inside DisplaySize\n");
1984 #if defined(__WIN32__) || defined(USEPBUFFER)
1985 OGLSystem oglSystem = display.displaySystem.driverData;
1986 if(display.alphaBlend)
1988 #if defined(__WIN32__)
1989 const int attributes[]=
1991 /*WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
1992 WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, */0
1994 int pixelFormat = 0;
1995 if(wglChoosePixelFormatARB)
1999 float fAttributes[] = {0,0};
2002 //WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
2003 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
2004 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
2005 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
2006 WGL_COLOR_BITS_ARB,24,
2007 WGL_ALPHA_BITS_ARB,8,
2008 WGL_DEPTH_BITS_ARB,16,
2009 WGL_STENCIL_BITS_ARB,0,
2010 WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
2011 WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
2012 WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
2016 //Log("Found wglChoosePixelFormatARB\n");
2018 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
2019 if(!valid || !numFormats)
2021 //Log("Can't find 4x multi sampling\n");
2022 iAttributes[19] = 2;
2023 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
2024 if(!valid || !numFormats)
2026 // Log("Can't find 2x multi sampling\n");
2027 iAttributes[16] = 0;
2028 iAttributes[17] = 0;
2029 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
2030 if(!valid || !numFormats)
2034 WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
2035 //WGL_DRAW_TO_BITMAP_ARB,GL_TRUE,
2036 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
2037 WGL_COLOR_BITS_ARB,24,
2038 WGL_ALPHA_BITS_ARB,8,
2039 WGL_DEPTH_BITS_ARB,16,
2042 valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
2046 if(valid && numFormats)
2048 wglMakeCurrent(null, null);
2052 wglMakeCurrent( null, null );
2053 wglMakeCurrent( oglDisplay.hdc, oglDisplay.glrc );
2054 if(oglDisplay.hdc && oglDisplay.pBuffer)
2055 wglReleasePbufferDCARB(oglDisplay.pBuffer, oglDisplay.hdc);
2057 wglDestroyPbufferARB(oglDisplay.pBuffer);
2059 if(!useSingleGLContext)
2060 wglMakeCurrent( null, null );
2063 wglDeleteContext(oglDisplay.glrc);
2065 oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
2066 oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
2067 if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
2070 HDC hdc = GetDC(display.window);
2072 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
2073 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
2075 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_WIDTH_ARB, &width);
2076 //wglQueryPbufferARB(pBuffer, WGL_PBUFFER_HEIGHT_ARB, &height);
2078 // glDeleteBuffersARB(2, oglDisplay.imageBuffers);
2080 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
2084 if(oglDisplay.memDC) DeleteDC(oglDisplay.memDC);
2085 oglDisplay.memDC = CreateCompatibleDC(hdc);
2086 SetMapMode(oglDisplay.memDC, MM_TEXT);
2087 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2088 info->bmiHeader.biPlanes = 1;
2089 info->bmiHeader.biCompression = BI_RGB;
2090 info->bmiHeader.biBitCount = 32; //(uint16)GetDeviceCaps(hdc, BITSPIXEL);
2091 info->bmiHeader.biWidth = width;
2092 info->bmiHeader.biHeight = height;
2093 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &oglDisplay.picture, null, 0);
2096 SelectObject(oglDisplay.memDC, newBitmap);
2097 if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
2100 PIXELFORMATDESCRIPTOR pfd = { 0 };
2101 pfd.nSize = (short)sizeof(pfd);
2103 pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
2104 pfd.iPixelType = PFD_TYPE_RGBA;
2105 pfd.cColorBits = 32;
2106 //pfd.cAlphaBits = 8;
2107 pfd.cDepthBits = 24;
2108 pfd.iLayerType = PFD_MAIN_PLANE;
2110 oglDisplay.hdc = oglDisplay.memDC;
2112 pixelFormat = ChoosePixelFormat(oglSystem.hdc, &pfd);
2113 DescribePixelFormat(oglDisplay.hdc, pixelFormat, sizeof(pfd), &pfd);
2114 SetPixelFormat(oglDisplay.hdc, pixelFormat, &pfd);
2116 oglDisplay.glrc = wglCreateContext(oglDisplay.hdc);
2117 wglShareLists(oglSystem.glrc, oglDisplay.glrc);
2118 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
2123 const int imageSize = width * height * 4;
2125 glGenBuffersARB(2, oglDisplay.imageBuffers);
2127 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2128 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize, null, GL_STREAM_READ);
2129 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2130 // glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, imageSize / 2, null, GL_STREAM_READ);
2133 oglDisplay.memBitmap = newBitmap;
2134 oglDisplay.stride = width;
2140 ReleaseDC(display.window, hdc);
2142 #elif defined(__unix__) || defined(__APPLE__)
2143 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
2148 GLX_DOUBLEBUFFER, True,
2154 GLX_STENCIL_SIZE, 1,
2155 //GLX_DEPTH_SIZE, 24,
2156 GLX_RENDER_TYPE, GLX_RGBA_BIT,
2157 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
2163 GLX_PBUFFER_WIDTH, width,
2164 GLX_PBUFFER_HEIGHT, height,
2165 GLX_LARGEST_PBUFFER, False,
2169 // choose a pixel format that meets our minimum requirements
2172 GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
2175 if(oglDisplay.pixmap)
2177 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
2178 oglDisplay.pixmap = None;
2180 if(oglDisplay.shapePixmap)
2182 XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
2183 oglDisplay.shapePixmap = None;
2186 // Free Shared Memory Pixmap
2187 if(oglDisplay.image)
2189 if(oglDisplay.shminfoShape.shmid != -1)
2191 XShmDetach(xGlobalDisplay, &oglDisplay.shminfo);
2192 if(oglDisplay.shminfo.shmaddr != (void *)-1)
2193 shmdt(oglDisplay.shminfo.shmaddr);
2194 shmctl(oglDisplay.shminfo.shmid, IPC_RMID, 0);
2196 XDestroyImage(oglDisplay.image);
2197 oglDisplay.image = None;
2199 if(oglDisplay.shapeImage)
2201 if(oglDisplay.shminfoShape.shmid != -1)
2203 XShmDetach(xGlobalDisplay, &oglDisplay.shminfoShape);
2204 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
2205 shmdt(oglDisplay.shminfoShape.shmaddr);
2206 shmctl(oglDisplay.shminfoShape.shmid, IPC_RMID, 0);
2208 XDestroyImage(oglDisplay.shapeImage);
2209 oglDisplay.shapeImage = None;
2212 if(oglDisplay.windowPicture)
2213 XRenderFreePicture(xGlobalDisplay, oglDisplay.windowPicture);
2214 if(oglDisplay.pixmapPicture)
2215 XRenderFreePicture(xGlobalDisplay, oglDisplay.pixmapPicture);
2217 if(oglDisplay.pixmap)
2218 XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
2220 if(oglDisplay.glContext)
2221 glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
2222 if(oglDisplay.pBuffer)
2223 glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
2225 oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
2226 if(oglDisplay.pBuffer)
2228 oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
2229 if(oglDisplay.glContext)
2231 glXMakeCurrent(xGlobalDisplay, None, null);
2232 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
2234 // Initialize Shared Memory Pixmap
2235 oglDisplay.image = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 32,
2236 ZPixmap, null, &oglDisplay.shminfo, width, height);
2237 if(oglDisplay.image)
2239 oglDisplay.shminfo.shmid = shmget(IPC_PRIVATE,
2240 oglDisplay.image->bytes_per_line * oglDisplay.image->height, IPC_CREAT|0777);
2241 if(oglDisplay.shminfo.shmid != -1)
2243 oglDisplay.shminfo.shmaddr = shmat(oglDisplay.shminfo.shmid, 0, 0);
2244 if(oglDisplay.shminfo.shmaddr != (void *)-1)
2246 oglDisplay.shminfo.readOnly = False;
2247 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfo))
2249 oglDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfo.shmaddr,
2250 &oglDisplay.shminfo, width, height, 32);
2252 // Initialize Shared Memory Shape Pixmap
2253 oglDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 1,
2254 ZPixmap, null, &oglDisplay.shminfoShape, width, height);
2255 if(oglDisplay.shapeImage)
2257 oglDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE,
2258 oglDisplay.shapeImage->bytes_per_line * oglDisplay.shapeImage->height, IPC_CREAT|0777);
2259 if(oglDisplay.shminfoShape.shmid != -1)
2261 oglDisplay.shminfoShape.shmaddr = shmat(oglDisplay.shminfoShape.shmid, 0, 0);
2262 if(oglDisplay.shminfoShape.shmaddr != (void *)-1)
2264 oglDisplay.shminfoShape.readOnly = False;
2265 if(XShmAttach(xGlobalDisplay, &oglDisplay.shminfoShape))
2267 oglDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, oglDisplay.shminfoShape.shmaddr,
2268 &oglDisplay.shminfoShape, width, height, 1);
2269 //oglDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
2272 XRenderPictureAttributes attributes = { 0 };
2273 XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
2274 #if !defined(__APPLE__) && !defined(__OLDX__)
2275 attributes.repeat = RepeatNormal;
2277 attributes.repeat = 1;
2279 oglDisplay.pixmapPicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.pixmap, format, CPRepeat, &attributes);
2280 oglDisplay.windowPicture = XRenderCreatePicture(xGlobalDisplay, (X11Window)display.window, format, 0, &attributes);
2281 oglDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, oglDisplay.shapePixmap,
2282 XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
2285 oglDisplay.picture = oglDisplay.shminfo.shmaddr;
2286 oglDisplay.stride = oglDisplay.image->bytes_per_line / 4;
2303 CreateDisplay(display);
2304 #if defined(__WIN32__)
2305 wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
2306 #elif defined(__unix__) || defined(__APPLE__)
2307 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
2311 glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
2318 if(!result && display.alphaBlend)
2320 printf("Alpha blending windows not supported on this display\n");
2327 glViewport(0,0,width,height);
2329 glOrtho(0,width,height,0,0.0,1.0);
2330 displayWidth = display.width = width;
2331 displayHeight = display.height = height;
2333 if(!oglDisplay.flippingBuffer || oglDisplay.flipBufW < width || oglDisplay.flipBufH < height)
2335 oglDisplay.flipBufW = width;
2336 oglDisplay.flipBufH = height;
2340 oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
2343 if(oglDisplay.flippingBuffer || !width || !height)
2349 void DisplayPosition(Display display, int x, int y)
2351 OGLDisplay oglDisplay = display.driverData;
2357 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
2361 void RestorePalette(Display display)
2365 void StartUpdate(Display display)
2369 void EndUpdate(Display display)
2373 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
2377 void Update(Display display, Box updateBox)
2379 #if defined(__WIN32__) || defined(USEPBUFFER)
2380 OGLDisplay oglDisplay = display.driverData;
2382 //Logf("DisplayScreen\n");
2386 #if defined(__WIN32__) || defined(USEPBUFFER)
2387 if(display.alphaBlend)
2389 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2390 glPixelStorei(GL_PACK_ROW_LENGTH, oglDisplay.stride);
2391 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2392 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2393 glReadPixels(0,0,display.width,display.height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, oglDisplay.picture);
2396 #if defined(__WIN32__)
2398 POINT point = { oglDisplay.x, oglDisplay.y};
2399 POINT srcPoint = { 0, 0 };
2400 BLENDFUNCTION blend = { 0 };
2402 size.cx = display.width;
2403 size.cy = display.height;
2404 blend.BlendOp = AC_SRC_OVER;
2405 blend.BlendFlags = 0;
2406 blend.SourceConstantAlpha = 255;
2407 blend.AlphaFormat = AC_SRC_ALPHA;
2410 // Process partial images. Mapping the buffer waits for
2411 // outstanding DMA transfers into the buffer to finish.
2412 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2413 oglDisplay.pboMemory1 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
2415 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2416 // oglDisplay.pboMemory2 = (byte *)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_ONLY);
2419 memcpy(oglDisplay.picture, oglDisplay.pboMemory1, display.width * display.height * 4);
2420 //memcpy(oglDisplay.picture + display.width * display.height * 4 / 2, oglDisplay.pboMemory2, display.width * display.height * 4/ 2);
2423 UpdateLayeredWindow(display.window, hdc, &point, &size, oglDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
2426 // Unmap the image buffers
2427 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2428 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
2430 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2431 // glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
2433 // Bind two different buffer objects and start the glReadPixels
2434 // asynchronously. Each call will return directly after
2435 // starting the DMA transfer.
2436 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[0]);
2437 glReadPixels(0, 0, display.width, display.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
2439 // glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, oglDisplay.imageBuffers[1]);
2440 // glReadPixels(0, display.height/2, display.width, display.height/2, GL_BGRA, GL_UNSIGNED_BYTE, 0);
2444 #elif defined(__unix__) || defined(__APPLE__)
2445 #if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
2447 XTransform transform =
2450 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0 * (1 << 16)) },
2451 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0 * (1<<16)) },
2452 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
2455 XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
2456 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
2457 XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
2458 #if !defined(__APPLE__) && !defined(__OLDX__)
2459 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
2461 XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
2463 XFlush(xGlobalDisplay);
2471 #if defined(__WIN32__)
2472 //wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
2473 SwapBuffers(oglDisplay.hdc);
2474 #elif defined(__unix__) || defined(__APPLE__)
2475 #if defined(__ANDROID__)
2476 eglSwapBuffers(eglDisplay, eglSurface);
2477 #elif defined(__EMSCRIPTEN__)
2480 glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
2484 //Logf("Out of DisplayScreen\n");
2487 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
2489 if(bitmap.driverData)
2491 GLuint tex = (GLuint)(uintptr)bitmap.driverData;
2492 glDeleteTextures(1, &tex);
2493 bitmap.driverData = 0;
2495 bitmap.driver = ((subclass(DisplayDriver))class(LFBDisplayDriver));
2498 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
2500 OGLSystem oglSystem = displaySystem.driverData;
2501 bool result = false;
2503 GLuint glBitmap = 0;
2505 uint w = width, h = height;
2506 if(oglSystem.pow2textures)
2511 w = Min(w, oglSystem.maxTextureSize);
2512 h = Min(h, oglSystem.maxTextureSize);
2514 glGenTextures(1, &glBitmap);
2515 glBindTexture(GL_TEXTURE_2D, glBitmap);
2517 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2519 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2520 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2522 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2523 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2525 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2527 mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
2529 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2530 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2534 bitmap.driverData = (void *)(uintptr)glBitmap;
2535 bitmap.driver = displaySystem.driver;
2543 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
2545 bool result = false;
2546 OGLSystem oglSystem = displaySystem.driverData;
2547 Bitmap convBitmap = bitmap;
2551 convBitmap.Copy(bitmap);
2554 // Pre process the bitmap... First make it 32 bit
2555 if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
2558 uint w = bitmap.width, h = bitmap.height;
2559 GLuint glBitmap = 0;
2560 if(oglSystem.pow2textures)
2565 w = Min(w, oglSystem.maxTextureSize);
2566 h = Min(h, oglSystem.maxTextureSize);
2570 while(w * 2 < h) w *= 2;
2571 while(h * 2 < w) h *= 2;
2574 // Switch ARGB to RGBA
2575 //if(bitmap.format != pixelFormatRGBA)
2577 for(c=0; c<bitmap.size; c++)
2579 // ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
2581 ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
2582 ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
2585 // convBitmap.pixelFormat = pixelFormat888;
2588 glGenTextures(1, &glBitmap);
2591 //int error = glGetError();
2595 glBindTexture(GL_TEXTURE_2D, glBitmap);
2596 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
2598 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2599 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
2600 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2602 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
2603 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
2605 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2606 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2608 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2612 for(level = 0; result && (w > 1 || h > 1); level++, w >>= 1, h >>= 1)
2615 if(bitmap.width != w || bitmap.height != h)
2617 mipMap = Bitmap { };
2618 if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
2620 Surface mipSurface = mipMap.GetSurface(0,0,null);
2621 mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
2631 mipMap = convBitmap;
2638 // glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2639 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
2640 //printf("Calling glTexImage2D\n");
2641 //glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
2642 //printf("width = %d (Should be %d, %d)\n", width, w, h);
2643 if((error = glGetError()))
2645 //Logf("OpenGL Bitmap MakeDD error: %d...\n", error);
2646 //printf("OpenGL Bitmap MakeDD error: %d...\n", error);
2650 if(mipMap != convBitmap)
2655 convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
2656 bitmap.driverData = (void *)(uintptr)glBitmap;
2657 bitmap.driver = displaySystem.driver;
2660 FreeBitmap(displaySystem, bitmap);
2661 else if(oglSystem.loadingFont)
2663 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2664 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2665 oglSystem.loadingFont = false;
2671 void ReleaseSurface(Display display, Surface surface)
2673 glDisable(GL_SCISSOR_TEST);
2674 delete surface.driverData;
2675 surface.driverData = null;
2678 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
2683 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
2685 bool result = false;
2686 OGLSurface oglSurface = surface.driverData = OGLSurface { };
2688 //Logf("GetSurface\n");
2692 if(displayWidth != display.width || displayHeight != display.height)
2694 displayWidth = display.width;
2695 displayHeight = display.height;
2697 glViewport(0,0,display.width,display.height);
2699 glOrtho(0,display.width,display.height,0,0.0,1.0);
2702 surface.offset.x = x;
2703 surface.offset.y = y;
2704 surface.unclippedBox = surface.box = clip;
2705 oglSurface.bitmapMult[0] = 1;
2706 oglSurface.bitmapMult[1] = 1;
2707 oglSurface.bitmapMult[2] = 1;
2708 oglSurface.bitmapMult[3] = 1;
2710 glEnable(GL_SCISSOR_TEST);
2713 (display.height) -(y+clip.bottom)-1,
2714 clip.right-clip.left+1,
2715 clip.bottom-clip.top+1);
2721 void Clip(Display display, Surface surface, Box clip)
2730 box.Clip(surface.unclippedBox);
2734 box = surface.box = surface.unclippedBox;
2735 box.left += surface.offset.x;
2736 box.top += surface.offset.y;
2737 box.right+= surface.offset.x;
2738 box.bottom += surface.offset.y;
2741 box.left,display.height - box.bottom - 1,
2742 box.right-box.left+1, box.bottom-box.top+1);
2745 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
2747 bool result = false;
2748 OGLDisplay oglDisplay = display.driverData;
2749 ColorAlpha * flippingBuffer = oglDisplay.flippingBuffer;
2751 if(oglDisplay.flippingBuffer)
2753 if(bitmap.pixelFormat != pixelFormat888 || bitmap.width < w || bitmap.height < h)
2756 bitmap.Allocate(null, w,h,w, pixelFormat888, false);
2762 glPixelStorei(GL_PACK_ALIGNMENT, 4);
2763 glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
2764 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
2765 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
2766 glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
2769 for(row = 0; row<h; row++)
2770 CopyBytesBy4(((ColorAlpha *)bitmap.picture) + row * w, ((ColorAlpha *)flippingBuffer) + (h-row-1) * w, w);
2777 void SetForeground(Display display, Surface surface, ColorAlpha color)
2779 OGLSurface oglSurface = surface.driverData;
2781 //Logf("SetForeground\n");
2783 oglSurface.foreground[0] = color.color.r/255.0f;
2784 oglSurface.foreground[1] = color.color.g/255.0f;
2785 oglSurface.foreground[2] = color.color.b/255.0f;
2786 //oglSurface.foreground[3] = 1.0f;
2787 oglSurface.foreground[3] = color.a/255.0f;
2789 //if(!oglSurface.foreground[3])printf("bug");
2792 void SetBackground(Display display, Surface surface, ColorAlpha color)
2794 OGLSurface oglSurface = surface.driverData;
2796 //Logf("SetBackground\n");
2798 oglSurface.background[0] = color.color.r/255.0f;
2799 oglSurface.background[1] = color.color.g/255.0f;
2800 oglSurface.background[2] = color.color.b/255.0f;
2801 //oglSurface.background[3] = 1.0;
2802 oglSurface.background[3] = color.a/255.0f;
2805 void SetBlitTint(Display display, Surface surface, ColorAlpha color)
2807 OGLSurface oglSurface = surface.driverData;
2809 oglSurface.bitmapMult[0] = color.color.r/255.0f;
2810 oglSurface.bitmapMult[1] = color.color.g/255.0f;
2811 oglSurface.bitmapMult[2] = color.color.b/255.0f;
2812 oglSurface.bitmapMult[3] = color.a/255.0f;
2815 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
2820 void PutPixel(Display display, Surface surface,int x,int y)
2822 OGLSurface oglSurface = surface.driverData;
2824 //Logf("PutPixel\n");
2826 glColor4fv(oglSurface.foreground);
2828 // glVertex2i(x+surface.offset.x, y+surface.offset.y);
2829 glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
2834 void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
2836 OGLSurface oglSurface = surface.driverData;
2837 float x1 = _x1, x2 = _x2, y1 = _y1, y2 = _y2;
2852 x1 += surface.offset.x;
2853 y1 += surface.offset.y;
2854 x2 += surface.offset.x;
2855 y2 += surface.offset.y;
2859 glColor4fv(oglSurface.foreground);
2861 #if defined(_GLES) || defined(__EMSCRIPTEN__)
2864 glTexCoord2f(0.5f, 0);
2865 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2866 glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
2867 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2876 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2877 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2883 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
2885 OGLSurface oglSurface = surface.driverData;
2886 x1 += surface.offset.x;
2887 y1 += surface.offset.y;
2888 x2 += surface.offset.x;
2889 y2 += surface.offset.y;
2891 //Logf("Rectangle\n");
2893 glColor4fv(oglSurface.foreground);
2894 #if defined(_GLES) || defined(__EMSCRIPTEN__)
2899 glTexCoord2f(0.5f, 0);
2900 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2901 glTexCoord2f(y2-y1 + 0.5f, 0);
2902 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2904 glTexCoord2f(0.5f, 0);
2905 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2906 glTexCoord2f(x2 - x1 + 0.5f, 0);
2907 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2909 glTexCoord2f(0.5f, 0);
2910 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2911 glTexCoord2f(y1 - y2 + 0.5f, 0);
2912 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2914 glTexCoord2f(0.5f, 0);
2915 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2916 glTexCoord2f(x1 - x2 + 0.5f, 0);
2917 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2922 glBegin(GL_LINE_LOOP);
2929 glVertex2f(x1 + 0.5f, y1 + 0.5f);
2930 glVertex2f(x1 + 0.5f, y2 + 0.5f);
2931 glVertex2f(x2 + 0.5f, y2 + 0.5f);
2932 glVertex2f(x2 + 0.5f, y1 + 0.5f);
2937 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
2939 OGLSurface oglSurface = surface.driverData;
2942 glColor4fv(oglSurface.background);
2944 #ifdef __EMSCRIPTEN__
2946 glVertex2f(x1+surface.offset.x, y1+surface.offset.y);
2947 glVertex2f(x1+surface.offset.x, y2+surface.offset.y+1);
2948 glVertex2f(x2+surface.offset.x+1, y2+surface.offset.y+1);
2949 glVertex2f(x2+surface.offset.x+1, y1+surface.offset.y);
2952 glRecti(x1+surface.offset.x, y1+surface.offset.y,
2953 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2956 glRectf(x1+surface.offset.x, y1+surface.offset.y,
2957 x2+surface.offset.x + 1, y2+surface.offset.y + 1);
2961 void Clear(Display display, Surface surface, ClearType type)
2963 OGLDisplay oglDisplay = display.driverData;
2964 OGLSurface oglSurface = surface.driverData;
2967 if(type != depthBuffer)
2968 glClearColor(oglSurface.background[0], oglSurface.background[1], oglSurface.background[2], oglSurface.background[3]);
2969 if(type != colorBuffer && !oglDisplay.depthWrite)
2971 glDepthMask((byte)bool::true);
2973 glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
2974 ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
2975 if(type != colorBuffer && !oglDisplay.depthWrite)
2977 glDepthMask((byte)bool::false);
2981 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
2986 void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
2988 OGLSurface oglSurface = surface.driverData;
2990 #if !defined(__OLDX__)
2991 // WHY DO WE HAVE GL_ONE HERE ?
2992 /*if(glBlendFuncSeparate && !oglSurface.writingText)
2993 glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
2996 if(!oglSurface.writingText)
2998 // glTranslatef(-0.375f, -0.375f, 0.0f);
2999 glEnable(GL_TEXTURE_2D);
3000 glColor4fv(oglSurface.bitmapMult);
3002 else if(oglSurface.xOffset)
3003 glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
3005 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
3010 glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
3011 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
3012 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
3013 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
3014 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
3015 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
3016 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
3017 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
3022 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
3023 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
3024 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
3025 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
3026 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
3027 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
3028 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
3029 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
3032 glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
3033 glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
3034 glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
3035 glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
3036 glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
3037 glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
3038 glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
3039 glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
3043 if(!oglSurface.writingText)
3045 glDisable(GL_TEXTURE_2D);
3047 //glTranslate(0.375, 0.375, 0.0);
3049 else if(oglSurface.xOffset)
3050 glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
3052 #if !defined(__OLDX__)
3053 /*if(glBlendFuncSeparate && !oglSurface.writingText)
3054 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
3058 void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3060 OGLSurface oglSurface = surface.driverData;
3062 //glTranslate(-0.375, -0.375, 0.0);
3064 //Logf("Stretch\n");
3066 #if !defined(__OLDX__)
3067 /*if(glBlendFuncSeparate)
3068 glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
3071 glEnable(GL_TEXTURE_2D);
3072 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
3074 glColor4fv(oglSurface.bitmapMult);
3080 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
3081 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
3083 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
3084 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
3086 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
3087 glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
3089 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
3090 glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
3094 glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
3095 glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
3097 glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
3098 glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
3100 glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
3101 glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
3103 glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
3104 glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
3109 glDisable(GL_TEXTURE_2D);
3111 //glTranslate(0.375, 0.375, 0.0);
3112 #if !defined(__OLDX__)
3113 /*if(glBlendFuncSeparate)
3114 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
3119 void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3121 Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
3124 void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3126 #if !defined(__EMSCRIPTEN__)
3127 float s2dw,s2dh,d2sw,d2sh;
3128 //bool flipX = false, flipY = false;
3130 //Logf("StretchDI\n");
3132 if(Sgn(w) != Sgn(sw))
3138 if(Sgn(h) != Sgn(sh))
3150 //Clip against the edges of the source
3153 dx+=(int)((0-sx) * s2dw);
3154 w-=(int)((0-sx) * s2dw);
3160 dy+=(int)((0-sy) * s2dh);
3161 h-=(int)((0-sy) * s2dh);
3166 if(sx+sw>bitmap.width-1)
3168 w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
3169 sw-=sx+sw-(bitmap.width-1)-1;
3171 if(sy+sh>(bitmap.height-1))
3173 h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
3174 sh-=sy+sh-(bitmap.height-1)-1;
3176 //Clip against the edges of the surfaceination
3177 if(dx<surface.box.left)
3180 sx+=(int)((surface.box.left-dx)*d2sw);
3181 sw-=(int)((surface.box.left-dx)*d2sw);
3182 w-=surface.box.left-dx;
3183 dx=surface.box.left;
3185 if(dy<surface.box.top)
3187 sy+=(int)((surface.box.top-dy)*d2sh);
3188 sh-=(int)((surface.box.top-dy)*d2sh);
3189 h-=surface.box.top-dy;
3192 if(dx+w>surface.box.right)
3194 //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
3195 sw-=(int)((dx+w-surface.box.right-1)*d2sw);
3196 w-=dx+w-surface.box.right-1;
3198 if(dy+h>surface.box.bottom)
3200 sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
3201 h-=dy+h-surface.box.bottom-1;
3203 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
3205 dx += surface.offset.x;
3206 dy += surface.offset.y;
3208 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
3210 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3211 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
3212 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
3213 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
3214 glRasterPos2d(dx,dy);
3215 //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
3216 glPixelZoom(s2dw, -s2dh);
3217 glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
3218 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3219 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3220 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3221 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3226 void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
3228 #if !defined(__EMSCRIPTEN__)
3231 //Clip against the edges of the source
3244 if(sx+w>bitmap.width-1)
3245 w-=sx+w-(bitmap.width-1)-1;
3246 if(sy+h>bitmap.height-1)
3247 h-=sy+h-(bitmap.height-1)-1;
3248 //Clip against the edges of the surfaceination
3249 if(dx<surface.box.left)
3252 sx+=surface.box.left-dx;
3253 w-=surface.box.left-dx;
3254 dx=surface.box.left;
3256 if(dy<surface.box.top)
3258 sy+=surface.box.top-dy;
3259 h-=surface.box.top-dy;
3262 if(dx+w>surface.box.right)
3264 //if(flip) sx+=dx+w-surface.box.right-1;
3265 w-=dx+w-surface.box.right-1;
3267 if(dy+h>surface.box.bottom)
3268 h-=dy+h-surface.box.bottom-1;
3272 dx += surface.offset.x;
3273 dy += surface.offset.y;
3275 if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
3277 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3278 glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
3279 glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
3280 glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
3281 glRasterPos2d(dx,dy);
3283 glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
3284 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3285 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3286 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3287 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3292 void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
3294 StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
3297 void UnloadFont(DisplaySystem displaySystem, Font font)
3299 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
3302 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
3305 OGLSystem oglSystem = displaySystem.driverData;
3306 oglSystem.loadingFont = true;
3307 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
3311 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
3313 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
3316 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
3318 OGLSurface oglSurface = surface.driverData;
3319 OGLSystem oglSystem = display.displaySystem.driverData;
3320 oglSystem.loadingFont = true;
3322 //glTranslated(-0.375, -0.375, 0.0);
3326 if(surface.textOpacity)
3329 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
3330 display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
3333 oglSurface.writingText = true;
3335 glEnable(GL_TEXTURE_2D);
3337 if(surface.outline.size)
3339 ColorAlpha outlineColor = surface.outline.color;
3340 glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
3341 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3342 //glEnable(GL_BLEND);
3344 oglSurface.writingOutline = true;
3345 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
3346 oglSurface.writingOutline = false;
3348 glColor4fv(oglSurface.foreground);
3350 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
3351 oglSurface.writingText = false;
3352 oglSystem.loadingFont = false;
3354 glDisable(GL_TEXTURE_2D);
3356 //glTranslated(0.375, 0.375, 0.0);
3359 void TextFont(Display display, Surface surface, Font font)
3361 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
3364 void TextOpacity(Display display, Surface surface, bool opaque)
3366 OGLSurface oglSurface = surface.driverData;
3367 oglSurface.opaqueText = opaque;
3370 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
3372 OGLSurface oglSurface = surface.driverData;
3373 OGLSystem oglSystem = display.displaySystem.driverData;
3374 oglSystem.loadingFont = true;
3375 FontExtent(display.displaySystem, oglSurface.font, text, len, width, height);
3376 oglSystem.loadingFont = false;
3379 void DrawingChar(Display display, Surface surface, char character)
3384 void LineStipple(Display display, Surface surface, uint32 stipple)
3386 //Logf("Stipple\n");
3390 #if defined(_GLES) || defined(__EMSCRIPTEN__)
3391 stippleEnabled = true;
3392 glesLineStipple(1, (uint16)stipple);
3394 glLineStipple(1, (uint16)stipple);
3395 glEnable(GL_LINE_STIPPLE);
3400 #if defined(_GLES) || defined(__EMSCRIPTEN__)
3401 stippleEnabled = false;
3402 glMatrixMode(GL_TEXTURE);
3404 glMatrixMode(GL_PROJECTION);
3405 glDisable(GL_TEXTURE_2D);
3407 glDisable(GL_LINE_STIPPLE);
3411 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
3412 void SetRenderState(Display display, RenderState state, uint value)
3414 OGLDisplay oglDisplay = display.driverData;
3415 //Logf("RenderState\n");
3421 glEnable(GL_MULTISAMPLE_ARB);
3423 glDisable(GL_MULTISAMPLE_ARB);
3427 glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
3431 if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
3434 if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
3435 oglDisplay.depthWrite = (bool)value;
3439 float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3440 glFogfv(GL_FOG_COLOR, (float *)&color);
3444 glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
3447 if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
3451 float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
3452 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
3457 if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
3462 #if defined(__WIN32__)
3463 wglSwapIntervalEXT(value ? 1 : 0);
3470 void SetLight(Display display, int id, Light light)
3472 //Logf("SetLight\n");
3476 Object lightObject = light.lightObject;
3477 float position[4] = { 0, 0, 0, 0 };
3478 float color[4] = { 0, 0, 0, 1 };
3480 glEnable(GL_LIGHT0 + id);
3482 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
3483 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
3484 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
3487 if(!light.multiplier) light.multiplier = 1.0f;
3489 color[0] = light.diffuse.r * light.multiplier;
3490 color[1] = light.diffuse.g * light.multiplier;
3491 color[2] = light.diffuse.b * light.multiplier;
3492 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
3494 color[0] = light.ambient.r * light.multiplier;
3495 color[1] = light.ambient.g * light.multiplier;
3496 color[2] = light.ambient.b * light.multiplier;
3497 glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
3498 color[0] = light.specular.r * light.multiplier;
3499 color[1] = light.specular.g * light.multiplier;
3500 color[2] = light.specular.b * light.multiplier;
3501 glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
3505 Vector3D positionVector;
3506 if(light.flags.spot)
3508 if(lightObject.flags.root || !lightObject.parent)
3510 positionVector = lightObject.transform.position;
3511 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3515 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
3516 if(display.display3D.camera)
3517 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
3523 if(!light.direction.x && !light.direction.y && !light.direction.z)
3525 Vector3Df vector { 0,0,-1 };
3527 mat.RotationQuaternion(light.orientation);
3528 positionVector.MultMatrixf(vector, mat);
3532 positionVector = light.direction;
3537 position[0] = (float)positionVector.x;
3538 position[1] = (float)positionVector.y;
3539 position[2] = (float)positionVector.z;
3541 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3544 // Display Light Position
3545 glDisable(GL_LIGHTING);
3546 glDisable(GL_DEPTH_TEST);
3550 glVertex3fv(position);
3552 glEnable(GL_DEPTH_TEST);
3553 glEnable(GL_LIGHTING);
3557 if(lightObject.flags.root || !lightObject.parent)
3559 positionVector = light.target.transform.position;
3560 positionVector.Subtract(positionVector, display.camera.cPosition);
3564 positionVector.MultMatrix(light.target.transform.position,
3565 lightObject.light.target.parent.matrix);
3566 positionVector.Subtract(positionVector, display.camera.cPosition);
3569 position[0] = positionVector.x;
3570 position[1] = positionVector.y;
3571 position[2] = positionVector.z;
3573 glDisable(GL_LIGHTING);
3574 glDisable(GL_DEPTH_TEST);
3578 glVertex3fv(position);
3580 glEnable(GL_DEPTH_TEST);
3581 glEnable(GL_LIGHTING);
3584 if(light.flags.attenuation)
3586 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
3587 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
3588 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
3591 if(light.flags.spot)
3594 #define MAXLIGHT 0.9
3595 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
3596 // Figure out exponent out of the hot spot
3597 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
3599 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
3600 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
3601 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
3607 Vector3Df vector { 0,0,-1 };
3608 Vector3Df direction;
3611 mat.RotationQuaternion(light.orientation);
3612 direction.MultMatrix(vector, mat);
3614 position[0] = direction.x;
3615 position[1] = direction.y;
3616 position[2] = direction.z;
3618 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
3622 glDisable(GL_LIGHT0 + id);
3625 void SetCamera(Display display, Surface surface, Camera camera)
3627 OGLDisplay oglDisplay = display.driverData;
3628 //Logf("SetCamera\n");
3632 int left = surface.box.left + surface.offset.x;
3633 int top = surface.box.top + surface.offset.y;
3634 int right = surface.box.right + surface.offset.x;
3635 int bottom = surface.box.bottom + surface.offset.y;
3636 float origX = surface.offset.x + camera.origin.x;
3637 float origY = surface.offset.y + camera.origin.y;
3639 int y = display.height - bottom - 1;
3640 int w = right - left + 1;
3641 int h = bottom - top + 1;
3644 glViewport(x, y, w, h);
3646 // *** Projection Matrix ***
3647 if(!display.display3D.camera)
3650 glMatrixMode(GL_PROJECTION);
3651 if(display.display3D.collectingHits)
3653 float pickX = display.display3D.pickX + surface.offset.x;
3654 float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
3658 w / display.display3D.pickWidth, 0, 0, 0,
3659 0, h / display.display3D.pickHeight, 0, 0,
3661 (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
3662 (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
3665 glLoadMatrixd(pickMatrix.array);
3670 (left - origX) * camera.zMin / camera.focalX,
3671 (right - origX) * camera.zMin / camera.focalX,
3672 (bottom - origY) * camera.zMin / camera.focalY,
3673 (top - origY) * camera.zMin / camera.focalY,
3674 camera.zMin, camera.zMax);
3676 glDisable(GL_BLEND);
3678 // *** Z Inverted Identity Matrix ***
3679 glMatrixMode(GL_MODELVIEW);
3680 if(!display.display3D.camera)
3685 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
3687 // *** View Matrix ***
3688 glMultMatrixd(camera.viewMatrix.array);
3693 glEnable(GL_DEPTH_TEST);
3694 glEnable(GL_LIGHTING);
3695 glShadeModel(GL_SMOOTH);
3696 glDepthMask((byte)bool::true);
3697 oglDisplay.depthWrite = true;
3699 glEnable(GL_MULTISAMPLE_ARB);
3701 else if(display.display3D.camera)
3703 oglDisplay.depthWrite = false;
3704 glViewport(0,0,display.width,display.height);
3706 glDisable(GL_CULL_FACE);
3707 glDisable(GL_DEPTH_TEST);
3708 glDisable(GL_LIGHTING);
3710 glDisable(GL_TEXTURE_2D);
3711 glShadeModel(GL_FLAT);
3713 glDisable(GL_MULTISAMPLE_ARB);
3715 // *** Restore 2D MODELVIEW Matrix ***
3718 // *** Restore 2D PROJECTION Matrix ***
3719 glMatrixMode(GL_PROJECTION);
3723 GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
3726 void ApplyMaterial(Display display, Material material, Mesh mesh)
3728 //Logf("ApplyMaterial\n");
3731 if(material.flags.doubleSided)
3733 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
3734 glDisable(GL_CULL_FACE);
3738 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
3739 glEnable(GL_CULL_FACE);
3743 if(material.flags.noFog)
3749 if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
3751 Bitmap map = material.baseMap;
3752 glEnable(GL_TEXTURE_2D);
3753 glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
3755 glMatrixMode(GL_TEXTURE);
3757 if(material.uScale && material.vScale)
3758 glScalef(material.uScale, material.vScale, 1);
3759 glMatrixMode(GL_MODELVIEW);
3761 if(material.flags.tile)
3763 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3764 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3768 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3769 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3773 glDisable(GL_TEXTURE_2D);
3775 if(mesh.flags.colors)
3777 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
3778 glEnable(GL_COLOR_MATERIAL);
3782 glDisable(GL_COLOR_MATERIAL);
3784 float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
3785 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
3788 float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
3789 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
3793 float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
3794 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
3797 float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
3798 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
3801 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
3804 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
3806 OGLMesh oglMesh = mesh.data;
3809 if(!mesh.flags.vertices)
3811 if(oglMesh.vertices)
3813 GLDeleteBuffers(1, &oglMesh.vertices);
3814 oglMesh.vertices = 0;
3816 delete mesh.vertices;
3818 if(!mesh.flags.normals)
3822 GLDeleteBuffers(1, &oglMesh.normals);
3823 oglMesh.normals = 0;
3825 delete mesh.normals;
3827 if(!mesh.flags.texCoords1)
3829 if(oglMesh.texCoords)
3831 GLDeleteBuffers(1, &oglMesh.texCoords);
3832 oglMesh.texCoords = 0;
3834 delete mesh.texCoords;
3836 if(!mesh.flags.texCoords2)
3838 if(oglMesh.texCoords2)
3840 GLDeleteBuffers(1, &oglMesh.texCoords2);
3841 oglMesh.texCoords2 = 0;
3844 delete mesh.texCoords2;
3847 if(!mesh.flags.colors)
3851 GLDeleteBuffers(1, &oglMesh.colors);
3863 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
3865 bool result = false;
3868 mesh.data = OGLMesh { };
3871 OGLMesh oglMesh = mesh.data;
3872 if(mesh.nVertices == nVertices)
3874 // Same number of vertices, adding features (Leaves the other features pointers alone)
3875 if(mesh.flags != flags)
3877 if(!mesh.flags.vertices && flags.vertices)
3879 if(flags.doubleVertices)
3881 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
3884 mesh.vertices = new Vector3Df[nVertices];
3885 if(!oglMesh.vertices)
3886 GLGenBuffers(1, &oglMesh.vertices);
3888 if(!mesh.flags.normals && flags.normals)
3890 if(flags.doubleNormals)
3892 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
3895 mesh.normals = new Vector3Df[nVertices];
3896 if(!oglMesh.normals)
3897 GLGenBuffers( 1, &oglMesh.normals);
3899 if(!mesh.flags.texCoords1 && flags.texCoords1)
3901 mesh.texCoords = new Pointf[nVertices];
3902 if(!oglMesh.texCoords)
3903 GLGenBuffers( 1, &oglMesh.texCoords);
3905 if(!mesh.flags.colors && flags.colors)
3907 mesh.colors = new ColorRGBAf[nVertices];
3909 GLGenBuffers( 1, &oglMesh.colors);
3915 // New number of vertices, reallocate all current and new features
3916 flags |= mesh.flags;
3919 if(flags.doubleVertices)
3921 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
3924 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
3925 if(!oglMesh.vertices)
3926 GLGenBuffers(1, &oglMesh.vertices);
3930 if(flags.doubleNormals)
3932 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
3935 mesh.normals = renew mesh.normals Vector3Df[nVertices];
3936 if(!oglMesh.normals)
3937 GLGenBuffers( 1, &oglMesh.normals);
3939 if(flags.texCoords1)
3941 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
3942 if(!oglMesh.texCoords)
3943 GLGenBuffers( 1, &oglMesh.texCoords);
3947 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
3949 GLGenBuffers( 1, &oglMesh.colors);
3957 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3959 OGLMesh oglMesh = mesh.data;
3960 if(!flags) flags = mesh.flags;
3964 if(flags.vertices && oglMesh.vertices)
3966 GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices);
3967 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 );
3970 if(flags.normals && oglMesh.normals)
3972 GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
3973 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 );
3976 if(flags.texCoords1 && oglMesh.texCoords)
3978 GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
3979 GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(Pointf), mesh.texCoords, GL_STATIC_DRAW_ARB );
3982 if(flags.colors && oglMesh.colors)
3984 GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
3985 GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, GL_STATIC_DRAW_ARB );
3988 GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
3992 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
3999 void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
4003 if(oglIndices.buffer)
4004 GLDeleteBuffers(1, &oglIndices.buffer);
4005 delete oglIndices.indices;
4010 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
4012 OGLIndices oglIndices = OGLIndices { };
4015 oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
4016 GLGenBuffers( 1, &oglIndices.buffer);
4017 oglIndices.nIndices = nIndices;
4022 void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
4026 GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
4027 GLBufferData( indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, GL_ELEMENT_ARRAY_BUFFER_ARB, nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
4028 oglIndices.indices, GL_STATIC_DRAW_ARB);
4029 GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
4033 uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
4036 return oglIndices.indices;
4039 void SelectMesh(Display display, Mesh mesh)
4041 //Logf("SelectMesh\n");
4043 #if !defined( __ANDROID__) && !defined(__APPLE__)
4045 #if defined(__WIN32__)
4046 if(glUnlockArraysEXT)
4048 if(!vboAvailable && display.display3D.mesh)
4049 glUnlockArraysEXT();
4054 OGLMesh oglMesh = mesh.data;
4056 // *** Vertex Stream ***
4057 glEnableClientState(GL_VERTEX_ARRAY);
4058 if(!display.display3D.collectingHits && oglMesh)
4060 GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices );
4061 if(mesh.flags.doubleVertices)
4062 glVertexPointerd(3, 0, (double *)(vboAvailable ? null : mesh.vertices), mesh.nVertices);
4064 glVertexPointer(3, GL_FLOAT, 0, vboAvailable ? null : mesh.vertices);
4066 // *** Normals Stream ***
4067 if(mesh.normals || mesh.flags.normals)
4069 glEnableClientState(GL_NORMAL_ARRAY);
4070 GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
4071 glNormalPointer(/*mesh.flags.doubleNormals ? GL_DOUBLE : */GL_FLOAT, 0, vboAvailable ? null : mesh.normals);
4074 glDisableClientState(GL_NORMAL_ARRAY);
4076 // *** Texture Coordinates Stream ***
4077 if(mesh.texCoords || mesh.flags.texCoords1)
4079 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4080 GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
4081 glTexCoordPointer(2, GL_FLOAT, 0, vboAvailable ? null : mesh.texCoords);
4084 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4086 // *** Color Stream ***
4087 if(mesh.colors || mesh.flags.colors)
4089 glEnableClientState(GL_COLOR_ARRAY);
4090 GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
4091 glColorPointer(4, GL_FLOAT, 0, vboAvailable ? null : mesh.colors);
4094 glDisableClientState(GL_COLOR_ARRAY);
4099 GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
4100 if(mesh.flags.doubleVertices)
4101 glVertexPointerd(3, 0, (double *)mesh.vertices, mesh.nVertices);
4103 glVertexPointer(3, GL_FLOAT, 0, mesh.vertices);
4104 if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
4106 glEnableClientState(GL_NORMAL_ARRAY);
4107 glNormalPointer(/*mesh.flags.doubleNormals ? GL_DOUBLE : */GL_FLOAT, 0, mesh.normals);
4110 glDisableClientState(GL_NORMAL_ARRAY);
4111 if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
4113 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4114 glTexCoordPointer(2, GL_FLOAT, 0, mesh.texCoords);
4117 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4118 if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
4120 glEnableClientState(GL_COLOR_ARRAY);
4121 glColorPointer(4, GL_FLOAT, 0, mesh.colors);
4124 glDisableClientState(GL_COLOR_ARRAY);
4127 #if !defined(__ANDROID__) && !defined(__APPLE__)
4129 #if defined(__WIN32__)
4133 glLockArraysEXT(0, mesh.nVertices);
4138 GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
4141 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
4143 //Logf("DrawPrimitives\n");
4145 if(primitive->type.vertexRange)
4146 glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
4149 // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
4150 // HACK TO SPEED THINGS UP...
4152 /*GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
4153 if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
4156 glBegin(primitiveTypes[primitive->type.primitiveType]);
4159 OGLIndices oglIndices = primitive->data;
4160 MeshFeatures flags = mesh.flags;
4161 for(c = 0; c<primitive->nIndices; c++)
4163 uint16 index = ((uint16 *) oglIndices.indices)[c];
4164 if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
4165 if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
4166 if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
4167 glVertex3fv((float *)&mesh.vertices[index]);
4175 OGLIndices oglIndices = primitive->data;
4177 if(!display.display3D.collectingHits && vboAvailable && oglIndices)
4179 GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
4180 if(primitive->type.indices32bit)
4181 glDrawElementsi(primitiveTypes[primitive->type.primitiveType], primitive->nIndices, 0);
4183 glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices, GL_UNSIGNED_SHORT, 0);
4184 GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
4188 if(primitive->type.indices32bit)
4189 glDrawElementsi(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
4190 oglIndices ? oglIndices.indices : primitive->indices);
4192 glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
4193 GL_UNSIGNED_SHORT, oglIndices ? oglIndices.indices : primitive->indices);
4199 void PushMatrix(Display display)
4204 void PopMatrix(Display display, bool setMatrix)
4209 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
4211 Matrix matrix = transMatrix;
4212 Camera camera = useCamera ? display.display3D.camera : null;
4217 glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
4222 matrix.m[3][0] - camera.cPosition.x,
4223 matrix.m[3][1] - camera.cPosition.y,
4224 matrix.m[3][2] - camera.cPosition.z);
4236 glMultMatrixd(matrix.array);
4241 public void UseSingleGLContext(bool useSingle)
4243 useSingleGLContext = useSingle;
4246 default dllexport void *
4247 #if defined(__WIN32__)
4248 __attribute__((stdcall))
4250 IS_GLGetContext(DisplaySystem displaySystem)
4254 #if defined(__WIN32__)
4255 OGLSystem system = displaySystem.driverData;
4257 #elif defined(__ANDROID__)
4259 #elif defined(__EMSCRIPTEN__)
4261 OGLSystem system = displaySystem.driverData;
4262 return system.glContext;