-// We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
-// #define USEPBUFFER
+#if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
+
+// #define DIAGNOSTICS
+#if defined(_DEBUG) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
+ #define GL_DEBUGGING
+#endif
+
+import "Display"
+
+import "glab"
+import "immediate"
+import "matrixStack"
+import "defaultShader"
namespace gfx::drivers;
-// OpenGL Extensions
+#include "gl123es.h"
+
+// ********** GL PLATFORMS INCLUDES **********
+// UNIX
#if defined(__unix__) || defined(__APPLE__)
-#if !defined(__MINGW32__)
- #define GL_GLEXT_PROTOTYPES
-#endif
+ // EGL
+ #if defined(__ANDROID__) || defined(__ODROID__)
+ import "egl"
-#ifdef ECERE_MINIGLX
+ #if defined(__ANDROID__)
+ #include <android/native_activity.h>
+ #include <android/log.h>
+ #define printf(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "ecere-app", __VA_ARGS__))
+ #endif
-//#include <GL/miniglx.h>
+ // Emscripten
+ #elif defined(__EMSCRIPTEN__)
+ #define property _property
+ #define uint _uint
-#else
+ #include <emscripten/emscripten.h>
+ #include <emscripten/html5.h>
- #if !defined(__ANDROID__)
+ #undef property
+ #undef uint
+
+ // GLX
+ #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
+ #define pointer _pointer
+ #define GL_GLEXT_PROTOTYPES
#define property _property
#define new _new
#define Time X11Time
#define KeyCode X11KeyCode
#define Picture X11Picture
+ #define Glyph X11Glyph
#define uint _uint
#include <X11/Xlib.h>
#undef Time
#undef KeyCode
#undef Picture
+ #undef Glyph
#undef uint
#undef new
#undef property
#undef class
+ #undef pointer
- #endif
+ #if !defined(__APPLE__)
+ default GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
+ default GLAPI void APIENTRY glUnlockArraysEXT (void);
+ #endif
-#endif
+ import "XInterface"
-#endif
+ // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
+ // #define USEPBUFFER
-#if defined(__APPLE__)
-#include <OpenGl/gl.h>
-#endif
+ #endif
-#if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
+// Apple
+#elif defined(__APPLE__)
+ #include <OpenGl/gl.h>
-#if defined(__WIN32__)
- #define WIN32_LEAN_AND_MEAN
+// WGL
+#elif defined(__WIN32__)
+ //#define WIN32_LEAN_AND_MEAN
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0502
#define String Sting_
#include <windows.h>
#undef String
-#endif
-
-#if defined(__ANDROID__)
-
- #include <GLES/gl.h>
- #include <EGL/egl.h>
-
-#else
-
- #include <GL/gl.h>
- #include <GL/glext.h>
+ #include "wglDefs.h"
#endif
-import "Display"
-
-#if defined(__unix__) || defined(__APPLE__)
-
- #ifndef __ANDROID__
- import "XInterface"
- #endif
-
+#if defined(__WIN32__)
+#elif !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
+default:
+private:
#endif
-static double nearPlane = 1;
-
-#define glLoadMatrix glLoadMatrixd
-#define glMultMatrix glMultMatrixd
-#define glGetMatrix glGetDoublev
-#define glTranslate glTranslated
-#define glScale glScaled
-
-/*
-#define glVertex3v glVertex3dv
-#define glNormal3v glNormal3dv
+/* OpenGL Versions Features Quick Reference
+
+ | OpenGL 1.1 | OpenGL 1.5 | GL ES 1.1 | OpenGL 2 | GL 3 (Compat) | GL 3 (Core) | GL ES 2 | WebGL 1 | GL ES 3 | WebGL 2
+ =======================================================================================================================================================================
+ glBegin() | X | X | - | X | X | - | - | - | - | -
+ glLoadMatrix() | X | X | - | X | X | - | - | - | - | -
+ glLineWidth() | X | X | - | X | X | - | - | - | - | -
+ glPointSize() | X | X | - | X | X | - | - | - | - | -
+ glLineStipple() | X | X | - | X | X | - | - | - | - | -
+ glPolygonStipple() | X | X | - | X | X | - | - | - | - | -
+ glColorMaterial() | X | X | - | X | X | - | - | - | - | -
+ GL_QUADS | X | X | - | X | X | - | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ GL_INT / GL_DOUBLE | X | X | - | X | X | X | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ GL_SELECT | X | X | - | (Slow) | (Slow) | (Slow) | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Non ² Textures | - | - | - | X | X | X | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glVertexPointer() (PTR) | X | X | X | X | X | - | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glVertexPointer() (VBO) | - | X | X | X | X | - | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glBufferData() | - | X | X | X | X | X | X | X | X | X
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glMapBuffer() | - | X | OES x | X | X | X | OES x | - | OES x | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glBindFramebuffer() | - | - | OES x | - | X | X | X | X | X | X
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glVertexAttribPointer() (PTR) | - | - | - | X | X | X | X | - | X | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glVertexAttribPointer() (VBO) | - | - | - | X | X | X | X | X | X | X
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ GLSL Version | - | - | - | 1.10 | 1.30 | 1.30 | 1.00 | 1.00 | 3.00 | 3.00
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ bool legacy :1; // | X | X | - | X | X | - | - | - | - | -
+ bool shaders :1; // | - | - | - | X | X | X | X | X | X | X
+ bool nonPow2Textures :1; // | - | - | - | X | X | X | - | - | - | -
+ bool vertexBuffer :1; // | - | X | X | X | X | X | X | X | X | X
+ bool frameBuffer :1; // | - | - | ~ | - | X | X | X | X | X | X
+// bool mapBuffer :1; // | - | X | ~ | X | X | X | ~ | - | ~ | -
*/
-/*
-//#ifdef VERTEX_FORMAT_DOUBLE
+default:
+// Capabilities Global set to capabilities of Display being rendered to
+GLCapabilities glCaps;
+// Requiring Graphics Reload:
+bool glCaps_nonPow2Textures, glCaps_vertexBuffer, glCaps_quads, glCaps_intAndDouble, glCaps_legacyFormats, glCaps_compatible, glCaps_vertexPointer;
+// Might toggle without Reload:
+bool glCaps_core, glCaps_shaders, glCaps_fixedFunction, glCaps_immediate, glCaps_legacy, glCaps_pointSize, glCaps_frameBuffer, glCaps_vao, glCaps_select;
+// bool mapBuffer;
+private:
-#define glLoadMatrix glLoadMatrixd
-#define glMultMatrix glMultMatrixd
-#define glGetMatrix glGetDoublev
-#define glVertex3v glVertex3dv
-#define glNormal3v glNormal3dv
-#define glTranslate glTranslated
-#define glScale glScaled
-//#define GL_VERTEX_FORMAT GL_DOUBLE
-#else
-
-#define glLoadMatrix glLoadMatrixf
-#define glMultMatrix glMultMatrixf
-#define glGetMatrix glGetFloatv
-#define glVertex3v glVertex3fv
-#define glNormal3v glNormal3fv
-#define glTranslate glTranslatef
-#define glScale glScalef
-//#define GL_VERTEX_FORMAT GL_FLOAT
-
-#endif
+// ********** Errors and Debugging **********
+/*
+void CheckGLErrors()
+{
+ int e, nCount = 0;
+ while((e = glGetError()) && nCount++ < 10)
+ printf("GL error %d!\n", e);
+}
*/
-
-#define GL_ARRAY_BUFFER_ARB 0x8892
-#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
-#define GL_STATIC_DRAW_ARB 0x88E4
-#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
-#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
-
-#define GL_MULTISAMPLE_ARB 0x809D
-
-#if defined(__WIN32__)
-
- #define WGL_SAMPLE_BUFFERS_ARB 0x2041
- #define WGL_SAMPLES_ARB 0x2042
-
- #define WGL_WGLEXT_VERSION 1
- #define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
- #define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
- #define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
- #define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
- #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
- #define WGL_DRAW_TO_WINDOW_ARB 0x2001
- #define WGL_DRAW_TO_BITMAP_ARB 0x2002
- #define WGL_ACCELERATION_ARB 0x2003
- #define WGL_NEED_PALETTE_ARB 0x2004
- #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
- #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
- #define WGL_SWAP_METHOD_ARB 0x2007
- #define WGL_NUMBER_OVERLAYS_ARB 0x2008
- #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
- #define WGL_TRANSPARENT_ARB 0x200A
- #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
- #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
- #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
- #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
- #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
- #define WGL_SHARE_DEPTH_ARB 0x200C
- #define WGL_SHARE_STENCIL_ARB 0x200D
- #define WGL_SHARE_ACCUM_ARB 0x200E
- #define WGL_SUPPORT_GDI_ARB 0x200F
- #define WGL_SUPPORT_OPENGL_ARB 0x2010
- #define WGL_DOUBLE_BUFFER_ARB 0x2011
- #define WGL_STEREO_ARB 0x2012
- #define WGL_PIXEL_TYPE_ARB 0x2013
- #define WGL_COLOR_BITS_ARB 0x2014
- #define WGL_RED_BITS_ARB 0x2015
- #define WGL_RED_SHIFT_ARB 0x2016
- #define WGL_GREEN_BITS_ARB 0x2017
- #define WGL_GREEN_SHIFT_ARB 0x2018
- #define WGL_BLUE_BITS_ARB 0x2019
- #define WGL_BLUE_SHIFT_ARB 0x201A
- #define WGL_ALPHA_BITS_ARB 0x201B
- #define WGL_ALPHA_SHIFT_ARB 0x201C
- #define WGL_ACCUM_BITS_ARB 0x201D
- #define WGL_ACCUM_RED_BITS_ARB 0x201E
- #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
- #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
- #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
- #define WGL_DEPTH_BITS_ARB 0x2022
- #define WGL_STENCIL_BITS_ARB 0x2023
- #define WGL_AUX_BUFFERS_ARB 0x2024
- #define WGL_NO_ACCELERATION_ARB 0x2025
- #define WGL_GENERIC_ACCELERATION_ARB 0x2026
- #define WGL_FULL_ACCELERATION_ARB 0x2027
- #define WGL_SWAP_EXCHANGE_ARB 0x2028
- #define WGL_SWAP_COPY_ARB 0x2029
- #define WGL_SWAP_UNDEFINED_ARB 0x202A
- #define WGL_TYPE_RGBA_ARB 0x202B
- #define WGL_TYPE_COLORINDEX_ARB 0x202C
- #define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
- #define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
- #define WGL_DRAW_TO_PBUFFER_ARB 0x202D
- #define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
- #define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
- #define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
- #define WGL_PBUFFER_LARGEST_ARB 0x2033
- #define WGL_PBUFFER_WIDTH_ARB 0x2034
- #define WGL_PBUFFER_HEIGHT_ARB 0x2035
- #define WGL_PBUFFER_LOST_ARB 0x2036
- #define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
- #define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
- #define WGL_DRAW_TO_WINDOW_EXT 0x2001
- #define WGL_DRAW_TO_BITMAP_EXT 0x2002
- #define WGL_ACCELERATION_EXT 0x2003
- #define WGL_NEED_PALETTE_EXT 0x2004
- #define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
- #define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
- #define WGL_SWAP_METHOD_EXT 0x2007
- #define WGL_NUMBER_OVERLAYS_EXT 0x2008
- #define WGL_NUMBER_UNDERLAYS_EXT 0x2009
- #define WGL_TRANSPARENT_EXT 0x200A
- #define WGL_TRANSPARENT_VALUE_EXT 0x200B
- #define WGL_SHARE_DEPTH_EXT 0x200C
- #define WGL_SHARE_STENCIL_EXT 0x200D
- #define WGL_SHARE_ACCUM_EXT 0x200E
- #define WGL_SUPPORT_GDI_EXT 0x200F
- #define WGL_SUPPORT_OPENGL_EXT 0x2010
- #define WGL_DOUBLE_BUFFER_EXT 0x2011
- #define WGL_STEREO_EXT 0x2012
- #define WGL_PIXEL_TYPE_EXT 0x2013
- #define WGL_COLOR_BITS_EXT 0x2014
- #define WGL_RED_BITS_EXT 0x2015
- #define WGL_RED_SHIFT_EXT 0x2016
- #define WGL_GREEN_BITS_EXT 0x2017
- #define WGL_GREEN_SHIFT_EXT 0x2018
- #define WGL_BLUE_BITS_EXT 0x2019
- #define WGL_BLUE_SHIFT_EXT 0x201A
- #define WGL_ALPHA_BITS_EXT 0x201B
- #define WGL_ALPHA_SHIFT_EXT 0x201C
- #define WGL_ACCUM_BITS_EXT 0x201D
- #define WGL_ACCUM_RED_BITS_EXT 0x201E
- #define WGL_ACCUM_GREEN_BITS_EXT 0x201F
- #define WGL_ACCUM_BLUE_BITS_EXT 0x2020
- #define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
- #define WGL_DEPTH_BITS_EXT 0x2022
- #define WGL_STENCIL_BITS_EXT 0x2023
- #define WGL_AUX_BUFFERS_EXT 0x2024
- #define WGL_NO_ACCELERATION_EXT 0x2025
- #define WGL_GENERIC_ACCELERATION_EXT 0x2026
- #define WGL_FULL_ACCELERATION_EXT 0x2027
- #define WGL_SWAP_EXCHANGE_EXT 0x2028
- #define WGL_SWAP_COPY_EXT 0x2029
- #define WGL_SWAP_UNDEFINED_EXT 0x202A
- #define WGL_TYPE_RGBA_EXT 0x202B
- #define WGL_TYPE_COLORINDEX_EXT 0x202C
- #define WGL_DRAW_TO_PBUFFER_EXT 0x202D
- #define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
- #define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
- #define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
- #define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
- #define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
- #define WGL_PBUFFER_LARGEST_EXT 0x2033
- #define WGL_PBUFFER_WIDTH_EXT 0x2034
- #define WGL_PBUFFER_HEIGHT_EXT 0x2035
- #define WGL_DEPTH_FLOAT_EXT 0x2040
- #define WGL_SAMPLE_BUFFERS_3DFX 0x2060
- #define WGL_SAMPLES_3DFX 0x2061
- #define WGL_SAMPLE_BUFFERS_EXT 0x2041
- #define WGL_SAMPLES_EXT 0x2042
- #define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
- #define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
- #define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
- #define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
- #define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
- #define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
- #define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
- #define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
- #define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
- #define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
- #define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
- #define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
- #define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
- #define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
- #define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
- #define WGL_ARB_buffer_region 1
- #define WGL_ARB_extensions_string 1
- #define WGL_ARB_pixel_format 1
- #define WGL_ARB_make_current_read 1
- #define WGL_ARB_pbuffer 1
- #define WGL_EXT_display_color_table 1
- #define WGL_EXT_extensions_string 1
- #define WGL_EXT_make_current_read 1
- #define WGL_EXT_pbuffer 1
- #define WGL_EXT_pixel_format 1
- #define WGL_EXT_swap_control 1
- #define WGL_WGL_EXT_depth_float 1
- #define WGL_WGL_3DFX_multisample 1
- #define WGL_WGL_EXT_multisample 1
- #define WGL_NV_allocate_memory 1
-
- /*
- typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum target);
- typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
- typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum target);
- typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
- typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
- */
-
- /*
- typedef int (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
- typedef int (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
- typedef int (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
- typedef int (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
- */
- typedef int (APIENTRY * PFNWGLCHOOSEPIXELFORMATARBPROC) ();
- typedef void * (APIENTRY * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
- typedef HDC (APIENTRY * PFNWGLGETPBUFFERDCARBPROC) (void * hPbuffer);
- typedef int (APIENTRY * PFNWGLRELEASEPBUFFERDCARBPROC) (void * hPbuffer, HDC hDC);
- typedef BOOL (APIENTRY * PFNWGLDESTROYPBUFFERARBPROC) (void * hPbuffer);
- typedef BOOL (APIENTRY * PFNWGLQUERYPBUFFERARBPROC) (void * hPbuffer, int iAttribute, int *piValue);
- typedef const char * (APIENTRY * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
- typedef BOOL (APIENTRY * PFNWGLBINDTEXIMAGEARBPROC) (void * hPbuffer, int iBuffer);
- typedef BOOL (APIENTRY * PFNWGLRELEASETEXIMAGEARBPROC) (void * hPbuffer, int iBuffer);
-
- static PFNGLMAPBUFFERARBPROC glMapBufferARB = null;
- static PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = null;
- static PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = null;
- static PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = null;
- static PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = null;
- static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
- static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
- static PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate = null;
-
- static PFNGLGENBUFFERSARBPROC glGenBuffersARB = null;
- static PFNGLBINDBUFFERARBPROC glBindBufferARB = null;
- static PFNGLBUFFERDATAARBPROC glBufferDataARB = null;
- static PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = null;
- static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
- static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
- static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
- static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
- static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
- static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
- static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
- static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
- static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
-
- #define glBufferData glBufferDataARB
-
- #ifdef WGL_WGLEXT_PROTOTYPES
- extern BOOL WINAPI wglSwapIntervalEXT (int);
- extern int WINAPI wglGetSwapIntervalEXT (void);
- #endif /* WGL_WGLEXT_PROTOTYPES */
- typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
- typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
-
- static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
-
-#endif
-
-// Our own matrix stack
-static Matrix matrixStack[3][32];
-static int matrixIndex[3];
-static int curStack = 0;
-
-#if defined(_GLES)
-
- // OpenGL ES Porting Kit
-
- #define glBindFramebuffer glBindFramebufferOES
- #define glBindRenderbuffer glBindRenderbufferOES
- #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
- #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
- #define glFramebufferTexture2D glFramebufferTexture2DOES
- #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
- #define glGenFramebuffers glGenFramebuffersOES
- #define glGenRenderbuffers glGenRenderbuffersOES
- #define glDeleteFramebuffers glDeleteFramebuffersOES
- #define glDeleteRenderbuffers glDeleteRenderbuffersOES
-
-#if defined(__ANDROID__)
- #define GL_POLYGON_STIPPLE 0xFFFF
- #define GL_LINE_STIPPLE 0xFFFF
- #define GL_LINE 0xFFFF
- #define GL_FILL 0xFFFF
- #define GL_ALL_ATTRIB_BITS 0xFFFF
- #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
- #define GL_INT 0x1404
- #define GL_UNSIGNED_INT 0x1405
- #define GL_DOUBLE 0x140A
- #define GL_POLYGON 9
- #define GL_QUADS 7
+#ifdef GL_DEBUGGING
+#ifndef APIENTRY
#define APIENTRY
#endif
-
- #define glDrawElementsi(type, count, start) glDrawElements(type, count, GL_UNSIGNED_SHORT, start)
-
- #define glBufferDatai glesBufferDatai
- #define glBufferDatad glesBufferDatad
- #define glVertexPointeri glesVertexPointeri
- #define glVertexPointerd glesVertexPointerd
-
- #define glRecti glesRecti
- #define glBegin glesBegin
- #define glTexCoord2i glesTexCoord2i
- #define glVertex2i glesVertex2i
- #define glTexCoord2d glesTexCoord2d
- #define glVertex2d glesVertex2d
- #define glTexCoord2f glesTexCoord2f
- #define glVertex2f glesVertex2f
- #define glEnd glesEnd
- #define glColor3f glesColor3f
- #define glColor4ub glesColor4ub
- #define glColor4fv glesColor4fv
- #define glLineStipple glesLineStipple
- #define glNormal3fv glesNormal3fv
- #define glTexCoord2fv glesTexCoord2fv
- #define glColorMaterial glesColorMaterial
-
- #define glLoadMatrixd glesLoadMatrixd
- #define glMultMatrixd glesMultMatrixd
- #define glFrustum glesFrustum
- #define glOrtho glesOrtho
- #define glScaled glesScaled
- #define glTranslated glesTranslated
- #define glRotated glesRotated
- #define glVertex3d glesVertex3d
- #define glVertex3dv glesVertex3dv
- #define glVertex3f glesVertex3f
- #define glVertex3fv glesVertex3fv
- #define glLightModeli glesLightModeli
-
-#if defined(__ANDROID__)
- //#define GL_QUADS 0
- #define GL_QUAD_STRIP 0
- //#define GL_DOUBLE 0
- //#define GL_UNSIGNED_INT 0
- //#define GL_FILL 0
- //#define GL_LINE 0
- //#define GL_LINE_STIPPLE 0
- #define GL_BGRA_EXT 0
- #define GL_UNPACK_ROW_LENGTH 0
- #define GL_UNPACK_SKIP_PIXELS 0
- #define GL_UNPACK_SKIP_ROWS 0
- #define GL_RGBA8 0
- #define GL_PACK_ROW_LENGTH 0
- #define GL_PACK_SKIP_ROWS 0
- #define GL_PACK_SKIP_PIXELS 0
-#endif
-
-#else
-
-#define glVertexPointerd(nc, s, p, nv) glVertexPointer(nc, GL_DOUBLE, s, p)
-#define glDrawElementsi(type, count, start) glDrawElements(type, count, GL_UNSIGNED_INT, start)
-
-#endif
-
-#if defined(__ANDROID__)
- static EGLDisplay eglDisplay;
- static EGLSurface eglSurface;
- static EGLContext eglContext;
- static int eglWidth, eglHeight;
-
- static bool egl_init_display(ANativeWindow* window)
- {
- const EGLint attribs[] =
- {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_BLUE_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_RED_SIZE, 8,
- EGL_DEPTH_SIZE, 16, //24,
- /*EGL_SAMPLE_BUFFERS, 1,
- EGL_SAMPLES, 0, //2,*/
- EGL_NONE
- };
- EGLint w, h, format;
- EGLint numConfigs;
- EGLConfig config;
- EGLSurface surface;
- EGLContext context;
-
- EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglInitialize(display, 0, 0);
- eglChooseConfig(display, attribs, &config, 1, &numConfigs);
- eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
-
- surface = eglCreateWindowSurface(display, config, window, null);
- context = eglCreateContext(display, config, null, null);
-
- if(!eglMakeCurrent(display, surface, surface, context))
- return false;
-
- eglQuerySurface(display, surface, EGL_WIDTH, &w);
- eglQuerySurface(display, surface, EGL_HEIGHT, &h);
-
- eglDisplay = display;
- eglContext = context;
- eglSurface = surface;
- eglWidth = w;
- eglHeight = h;
-
- glEnableClientState(GL_VERTEX_ARRAY);
- /*
- // Initialize GL state.
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
- glEnable(GL_CULL_FACE);
- glShadeModel(GL_SMOOTH);
- glDisable(GL_DEPTH_TEST);
- */
- glDisable(GL_CULL_FACE);
- glDisable(GL_DEPTH_TEST);
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- matrixStack[0][0].Identity();
- matrixStack[1][0].Identity();
- matrixStack[2][0].Identity();
-
- glesMatrixMode(GL_MODELVIEW);
- glScaled(1.0, 1.0, -1.0);
- glesMatrixMode(GL_PROJECTION);
- glShadeModel(GL_FLAT);
-
- glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
- glFogi(GL_FOG_MODE, GL_EXP);
- glFogf(GL_FOG_DENSITY, 0);
- glEnable(GL_NORMALIZE);
- glDepthFunc(GL_LESS);
- glClearDepth(1.0);
- glDisable(GL_MULTISAMPLE_ARB);
-
- glViewport(0,0,w,h);
- glesLoadIdentity();
- glOrtho(0,w,h,0,0.0,1.0);
-
- currentVertexBuffer = 0;
- return true;
- }
-
- static void egl_term_display()
- {
- if(stippleTexture)
- {
- glDeleteTextures(1, &stippleTexture);
- stippleTexture = 0;
- }
- if(eglDisplay != EGL_NO_DISPLAY)
- {
- eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if(eglContext != EGL_NO_CONTEXT)
- eglDestroyContext(eglDisplay, eglContext);
- if(eglSurface != EGL_NO_SURFACE)
- eglDestroySurface(eglDisplay, eglSurface);
- eglTerminate(eglDisplay);
- }
- eglDisplay = EGL_NO_DISPLAY;
- eglContext = EGL_NO_CONTEXT;
- eglSurface = EGL_NO_SURFACE;
- }
-
-#endif
-
-// OpenGL Immediate Mode Porting Kit
-static int beginCount;
-static int vertexCount;
-static int normalCount;
-static float *vertexPointer;
-static float *normalPointer;
-static GLenum beginMode;
-static unsigned int beginBufferSize, normalBufferSize;
-static int numVertexCoords = 2;
-
-public void glesRecti(int a, int b, int c, int d)
-{
- glBegin(GL_QUADS);
- glVertex2i(a, b);
- glVertex2i(a, d);
- glVertex2i(c, d);
- glVertex2i(c, b);
- glEnd();
-}
-
-public void glesBegin(GLenum mode)
-{
- beginMode = mode;
- beginCount = 0;
- vertexCount = 0;
- if(!vertexPointer)
- {
- normalBufferSize = beginBufferSize = 1024; // default number of vertices
- vertexPointer = new float[beginBufferSize * 5];
- normalPointer = new float[normalBufferSize * 3];
- }
-}
-
-public void glesTexCoord2f(float x, float y)
-{
- int count = vertexCount;
-
- if(vertexCount + numVertexCoords > beginBufferSize)
- {
- beginBufferSize = beginBufferSize + beginBufferSize/2;
- vertexPointer = renew vertexPointer float[beginBufferSize * 5];
- }
-
- vertexPointer[count*(2+numVertexCoords) ] = x;
- vertexPointer[count*(2+numVertexCoords)+1] = y;
- count++;
-
- if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
- {
- vertexPointer[count*(2+numVertexCoords) ] = vertexPointer[(count-4)*(2+numVertexCoords)];
- vertexPointer[count*(2+numVertexCoords)+1] = vertexPointer[(count-4)*(2+numVertexCoords)+1];
- count++;
- vertexPointer[count*(2+numVertexCoords) ] = vertexPointer[(count-3)*(2+numVertexCoords)];
- vertexPointer[count*(2+numVertexCoords)+1] = vertexPointer[(count-3)*(2+numVertexCoords)+1];
- count++;
- }
-}
-public void glesTexCoord2i(int x, int y) { glesTexCoord2f((float)x, (float)y); }
-public void glesTexCoord2d(double x, double y) { glesTexCoord2f((float)x, (float)y); }
-public void glesTexCoord2fv(float * a) { glesTexCoord2f(a[0], a[1]); }
-
-public void glesVertex2f(float x, float y)
-{
- numVertexCoords = 2;
- if(vertexCount + 4 > beginBufferSize)
- {
- beginBufferSize = beginBufferSize + beginBufferSize/2;
- vertexPointer = renew vertexPointer float[beginBufferSize * 5];
- }
-
- vertexPointer[vertexCount*4+2] = x;
- vertexPointer[vertexCount*4+3] = y;
- vertexCount++;
-
- if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
- {
- vertexPointer[vertexCount*4+2] = vertexPointer[(vertexCount-4)*4+2];
- vertexPointer[vertexCount*4+3] = vertexPointer[(vertexCount-4)*4+3];
- vertexCount++;
- vertexPointer[vertexCount*4+2] = vertexPointer[(vertexCount-3)*4+2];
- vertexPointer[vertexCount*4+3] = vertexPointer[(vertexCount-3)*4+3];
- vertexCount++;
- }
- beginCount++;
-}
-public void glesVertex2i(int x, int y) { glesVertex2f((float)x, (float)y); }
-public void glesVertex2d(double x, double y) { glesVertex2f((float)x, (float)y); }
-
-public void glesEnd(void)
-{
- int mode = beginMode;
- if(mode == GL_QUADS) mode = GL_TRIANGLES;
- else if(mode == GL_POLYGON) mode = GL_TRIANGLE_FAN;
- GLSelectVBO(0);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(numVertexCoords, GL_FLOAT, (numVertexCoords+2)*sizeof(float),vertexPointer);
- glVertexPointer (numVertexCoords, GL_FLOAT, (numVertexCoords+2)*sizeof(float),vertexPointer+2);
- if(normalCount && normalCount == vertexCount)
- {
- glEnableClientState(GL_NORMAL_ARRAY);
- glNormalPointer (GL_FLOAT, 3*sizeof(float),normalPointer);
- }
-
- glDrawArrays(mode, 0, vertexCount);
- if(normalCount)
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- normalCount = 0;
-}
-
-// Vertex Pointer
-static float *floatVPBuffer = null;
-static short *shortVPBuffer = null;
-static unsigned int shortVPSize = 0, floatVPSize = 0;
-
-// Buffer Data
-//static float *floatVPBuffer = null; // For floats we reuse floatVPBuffer
-static unsigned short *shortBDBuffer = null;
-static unsigned int shortBDSize = 0/*, floatVPSize = 0*/;
-
-public void glesVertexPointeri(int numCoords, int stride, int *pointer, int numVertices)
-{
- if(pointer)
- {
- int i;
- if(numVertices*numCoords > shortVPSize)
- {
- shortVPSize = numVertices*numCoords;
- shortVPBuffer = renew shortVPBuffer short[shortVPSize];
- }
- for(i = 0; i < numVertices*numCoords; i++)
- shortVPBuffer[i] = (short)pointer[i];
- glVertexPointer(numCoords, GL_SHORT, stride, shortVPBuffer);
- }
- else
- glVertexPointer(numCoords, GL_SHORT, stride, 0);
-}
-
-public void glesVertexPointerd(int numCoords, int stride, double *pointer, int numVertices)
-{
- if(pointer)
- {
- int i;
- if(numVertices*numCoords > floatVPSize)
- {
- floatVPSize = numVertices*numCoords;
- floatVPBuffer = renew floatVPBuffer float[floatVPSize];
- }
- for(i = 0; i < numVertices*numCoords; i++)
- floatVPBuffer[i] = (float)pointer[i];
- glVertexPointer(numCoords, GL_FLOAT, stride, floatVPBuffer);
- }
- else
- glVertexPointer(numCoords, GL_FLOAT, stride, 0);
-}
-
-public void glesTexReuseIntVP(int numCoords)
-{
- glTexCoordPointer(numCoords, GL_SHORT, 0, floatVPBuffer);
-}
-
-public void glesTexReuseDoubleVP(int numCoords)
-{
- glTexCoordPointer(numCoords, GL_FLOAT, 0, floatVPBuffer);
-}
-
-public void glesColor3f( float r, float g, float b )
-{
- glColor4f(r, g, b, 1.0f);
-}
-
-public void glesColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
-{
- glColor4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f);
-}
-
-public void glesColor4fv(float * a)
-{
- glColor4f(a[0], a[1], a[2], a[3]);
-}
-
-public void glesBufferDatad(int target, int size, void * data, int usage)
+static void APIENTRY openglCallbackFunction(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar* message,
+ const void* userParam)
{
- int numElems = size/sizeof(double);
- double * dblPtr = (double *)data;
- int i;
- if (numElems > floatVPSize)
+ if(severity == GL_DEBUG_SEVERITY_NOTIFICATION)
+ return;
+ PrintLn("---------------------opengl-callback-start------------");
+ PrintLn("message: ", message);
+ PrintLn("type: ");
+ switch (type)
{
- floatVPSize = numElems;
- floatVPBuffer = renew floatVPBuffer float[floatVPSize];
+ case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
+ case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
+ case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
+ case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
}
- for (i=0; i< numElems; i++)
- floatVPBuffer[i] = (float)dblPtr[i];
- glBufferData(target, numElems*sizeof(float), floatVPBuffer, usage);
-}
-
-public void glesBufferDatai(int target, int size, void * data, int usage)
-{
- int numElems = size/sizeof(unsigned int);
- unsigned int * pointer = (unsigned int *)data;
- int i;
- if (numElems > shortBDSize)
+ PrintLn("id: ", id);
+ Print("severity: ");
+ switch (severity)
{
- shortBDSize = numElems;
- shortBDBuffer = renew shortBDBuffer uint16[shortBDSize];
+ case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
+ case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
+ case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
+ default: PrintLn("(other)");
}
- for (i=0; i< numElems; i++)
- shortBDBuffer[i] = (unsigned short)pointer[i];
-
- glBufferData(target, numElems*sizeof(unsigned short), shortBDBuffer, usage);
+ PrintLn("---------------------opengl-callback-end--------------");
}
-// *** Our Custom Matrix Stack ***
-
-static void LoadCurMatrix()
+static void setupDebugging()
{
- double * i = matrixStack[curStack][matrixIndex[curStack]].array;
- float m[16] =
+ if(glDebugMessageCallback)
{
- (float)i[0],(float)i[1],(float)i[2],(float)i[3],
- (float)i[4],(float)i[5],(float)i[6],(float)i[7],
- (float)i[8],(float)i[9],(float)i[10],(float)i[11],
- (float)i[12],(float)i[13],(float)i[14],(float)i[15]
- };
- glLoadMatrixf(m);
-}
+ GLuint unusedIds = 0;
-public void glesLoadIdentity()
-{
- matrixStack[curStack][matrixIndex[curStack]].Identity();
- LoadCurMatrix();
-}
+ glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
-public void glesPushMatrix()
-{
- if(matrixIndex[curStack] + 1 < sizeof(matrixStack[0]) / sizeof(Matrix))
- {
- matrixIndex[curStack]++;
- memcpy(matrixStack[curStack][matrixIndex[curStack]].array, matrixStack[curStack][matrixIndex[curStack]-1].array, sizeof(Matrix));
+ glDebugMessageCallback(openglCallbackFunction, null);
+ glDebugMessageControl(GL_DONT_CARE,
+ GL_DONT_CARE,
+ GL_DONT_CARE,
+ 0,
+ &unusedIds,
+ GL_TRUE);
}
}
-
-public void glesPopMatrix()
-{
- if(matrixIndex[curStack] > 0)
- {
- matrixIndex[curStack]--;
- LoadCurMatrix();
- }
-}
-
-public void glesLoadMatrixd(double * i)
-{
- memcpy(matrixStack[curStack][matrixIndex[curStack]].array, i, sizeof(Matrix));
- LoadCurMatrix();
-}
-
-public void glesOrtho( double l, double r, double b, double t, double n, double f )
-{
- Matrix m
- { {
- (2 / (r - l)), 0, 0, 0,
- 0, (2 / (t - b)), 0, 0,
- 0, 0, (-2 / (f - n)), 0,
- (-(r + l) / (r - l)), (-(t + b) / (t - b)), (-(f + n) / (f - n)), 1
- } };
- Matrix res;
- res.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
- matrixStack[curStack][matrixIndex[curStack]] = res;
- LoadCurMatrix();
-}
-
-public void glesFrustum( double l, double r, double b, double t, double n, double f )
-{
- nearPlane = n;
- n = 1;
- l /= nearPlane;
- r /= nearPlane;
- b /= nearPlane;
- t /= nearPlane;
- f /= nearPlane;
- {
- double A = ((r + l) / (r - l));
- double B = ((t + b) / (t - b));
- double C = (-(f + n) / (f - n));
- double D = (-2*f*n/(f-n));
- Matrix m
- { {
- (2.0*n / (r - l)), 0, 0, 0,
- 0, (2.0*n / (t - b)), 0, 0,
- A, B, C,-1,
- 0, 0, D, 0
- } };
- Matrix res;
- res.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
- matrixStack[curStack][matrixIndex[curStack]] = res;
- LoadCurMatrix();
- }
-}
-
-public void glesRotated( double a, double b, double c, double d )
-{
- Quaternion q;
- Matrix m, r;
-
- q.RotationAxis({(float)b,(float)c,(float)-d}, a );
- m.RotationQuaternion(q);
- r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
- matrixStack[curStack][matrixIndex[curStack]] = r;
- LoadCurMatrix();
-}
-public void glesScaled( double a, double b, double c )
-{
- Matrix m, r;
-
- m.Identity();
- m.Scale(a,b,c);
- r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
- matrixStack[curStack][matrixIndex[curStack]] = r;
- LoadCurMatrix();
-}
-
-public void glesTranslated( double a, double b, double c )
-{
- Matrix m, r;
-
- m.Identity();
- m.Translate(a,b,c);
- r.Multiply(m, matrixStack[curStack][matrixIndex[curStack]]);
- matrixStack[curStack][matrixIndex[curStack]] = r;
- LoadCurMatrix();
-}
-
-public void glesMultMatrixd( double * i )
-{
- Matrix r;
- r.Multiply((Matrix *)i, matrixStack[curStack][matrixIndex[curStack]]);
- matrixStack[curStack][matrixIndex[curStack]] = r;
- LoadCurMatrix();
-}
-
-public void glesMatrixMode(int mode)
-{
- curStack = (mode == GL_MODELVIEW) ? 0 : (mode == GL_PROJECTION) ? 1 : 2;
- glMatrixMode(mode);
-}
-
-#if defined(_GLES)
-
-#define glPushMatrix glesPushMatrix
-#define glPopMatrix glesPopMatrix
-#define glLoadIdentity glesLoadIdentity
-#define glMatrixMode glesMatrixMode
-
#endif
-/* Using the built-in matrix stack
-void glesLoadMatrixd( double * i )
-{
- float m[16] =
- {
- (float)i[0],(float)i[1],(float)i[2],(float)i[3],
- (float)i[4],(float)i[5],(float)i[6],(float)i[7],
- (float)i[8],(float)i[9],(float)i[10],(float)i[11],
- (float)i[12],(float)i[13],(float)i[14],(float)i[15]
- };
- glLoadMatrixf(m);
-}
-
-void glesOrtho( double l, double r, double b, double t, double n, double f )
-{
- float matrix[4][4] =
- {
- { (float)(2 / (r - l)), 0, 0, 0 },
- { 0, (float)(2 / (t - b)), 0, 0 },
- { 0, 0, (float)(-2 / (f - n)), 0 },
- { (float)(-(r + l) / (r - l)), (float)(-(t + b) / (t - b)), (float)(-(f + n) / (f - n)), 1 }
- };
- glMultMatrixf((float *)matrix);
-}
-
-void glesFrustum( double l, double r, double b, double t, double n, double f )
-{
- float A = (float)((r + l) / (r - l));
- float B = (float)((t + b) / (t - b));
- float C = (float)(-(f + n) / (f - n));
- float D = (float)(-2*f*n/(f-n));
- float matrix[4][4] =
- {
- { (float)(2*n / (r - l)), 0, 0, 0 },
- { 0, (float)(2*n / (t - b)), 0, 0 },
- { A, B, C,-1 },
- { 0, 0, D, 0 }
- };
- glMultMatrixf((float *)matrix);
-}
-
-void glesRotated( double a, double b, double c, double d ) { glRotatef((float)a, (float)b, (float)c, (float)d); }
-void glesScaled( double a, double b, double c ) { glScalef((float)a, (float)b, (float)c); }
-void glesTranslated( double a, double b, double c ) { glTranslatef((float)a, (float)b, (float)c); }
-
-void glesMultMatrixd( double * i )
-{
- float m[16] =
- {
- (float)i[0], (float)i[1], (float)i[2], (float)i[3],
- (float)i[4], (float)i[5], (float)i[6], (float)i[7],
- (float)i[8], (float)i[9], (float)i[10], (float)i[11],
- (float)i[12], (float)i[13], (float)i[14], (float)i[15]
- };
- glMultMatrixf(m);
-}
-*/
-
-// Need to do these...
-public void glesVertex3f( float x, float y, float z )
-{
- numVertexCoords = 3;
- if(vertexCount + 4 > beginBufferSize)
- {
- beginBufferSize = beginBufferSize + beginBufferSize/2;
- vertexPointer = renew vertexPointer float[beginBufferSize * 5];
- }
-
- vertexPointer[vertexCount*5+2] = x;
- vertexPointer[vertexCount*5+3] = y;
- vertexPointer[vertexCount*5+4] = z;
- vertexCount++;
-
- if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
- {
- vertexPointer[vertexCount*5+2] = vertexPointer[(vertexCount-4)*5+2];
- vertexPointer[vertexCount*5+3] = vertexPointer[(vertexCount-4)*5+3];
- vertexPointer[vertexCount*5+4] = vertexPointer[(vertexCount-4)*5+4];
- vertexCount++;
- vertexPointer[vertexCount*5+2] = vertexPointer[(vertexCount-3)*5+2];
- vertexPointer[vertexCount*5+3] = vertexPointer[(vertexCount-3)*5+3];
- vertexPointer[vertexCount*5+4] = vertexPointer[(vertexCount-3)*5+4];
- vertexCount++;
- }
- beginCount++;
-}
-
-public void glesVertex3d( double x, double y, double z ) { glesVertex3f((float)x, (float)y, (float)z); }
-public void glesVertex3fv( float* coords ) { glesVertex3f(coords[0], coords[1], coords[2]); }
-public void glesVertex3dv( double* coords ) { glesVertex3f((float)coords[0], (float)coords[1], (float)coords[2]); }
-
-public void glesNormal3f(float x, float y, float z)
-{
- normalCount = vertexCount;
- if(vertexCount + 4 > normalBufferSize)
- {
- normalBufferSize = normalBufferSize + normalBufferSize/2;
- normalPointer = renew normalPointer float[normalBufferSize * 2];
- }
-
- normalPointer[normalCount*3+0] = x;
- normalPointer[normalCount*3+1] = y;
- normalPointer[normalCount*3+2] = z;
- normalCount++;
-
- if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
- {
- normalPointer[normalCount*3+0] = normalPointer[(normalCount-4)*3+0];
- normalPointer[normalCount*3+1] = normalPointer[(normalCount-4)*3+1];
- normalPointer[normalCount*3+2] = normalPointer[(normalCount-4)*3+2];
- normalCount++;
- normalPointer[normalCount*3+0] = normalPointer[(normalCount-3)*3+0];
- normalPointer[normalCount*3+1] = normalPointer[(normalCount-3)*3+1];
- normalPointer[normalCount*3+2] = normalPointer[(normalCount-3)*3+2];
- normalCount++;
- }
-}
-public void glesNormal3fd(double x, double y, double z) { glesNormal3f((float)x, (float)y, (float)z); }
-public void glesNormal3fv(float * coords) { glesNormal3f(coords[0], coords[1], coords[2]); }
-
-public void glesColorMaterial(int a, int b)
-{
- PrintLn("glColorMaterial stub");
-}
-
-public void glesTerminate()
-{
- delete vertexPointer;
- delete normalPointer;
- beginBufferSize = 0;
-
- delete floatVPBuffer;
- shortVPSize = 0;
-
- delete shortVPBuffer;
- floatVPSize = 0;
-
- delete shortBDBuffer;
- shortBDSize = 0;
-}
static GLuint stippleTexture;
-#if defined(_GLES)
static bool stippleEnabled;
-#endif
-public void glesLineStipple( int i, unsigned short j )
+public void glsupLineStipple( int i, uint16 j )
{
uint texture[1*16];
int x;
glGenTextures(1, &stippleTexture);
glBindTexture(GL_TEXTURE_2D, stippleTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
- glEnable(GL_TEXTURE_2D);
+
+ // TOOD: Special shading code for stippling?
+ GLSetupTexturing(true);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
+ GLMatrixMode(GL_TEXTURE);
+ GLLoadIdentity();
//glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
- glScaled(i/16.0, 1, 1.0f);
- glTranslated(0.5, 0.5, 0);
- glMatrixMode(GL_PROJECTION);
+ GLScaled(i/16.0, 1, 1.0f);
+ GLTranslated(0.5, 0.5, 0);
+ GLMatrixMode(MatrixMode::projection);
}
-public void glesLightModeli( unsigned int pname, int param )
-{
- if(pname == GL_LIGHT_MODEL_TWO_SIDE)
- glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
-}
+ // Exported to build _GLES version...
+ public void glsupLightModeli( unsigned int pname, int param )
+ {
+#if ENABLE_GL_FFP
+ if(pname == GL_LIGHT_MODEL_TWO_SIDE)
+ glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
+#endif
+ }
-#ifdef __ANDROID__
+#ifdef _GLES
+ void glFogi( unsigned int pname, int param ) { }
+ void glPolygonMode( unsigned int i, unsigned int j ) { }
+ void glBlendFuncSeparate(int a, int b, int c, int d)
+ {
+ glBlendFunc(a, b);
+ }
+
+#endif
+
+#if defined(_GLES) || defined(_GLES2)
void glClearDepth( double depth ) { glClearDepthf((float)depth); }
-void glFogi( unsigned int pname, int param ) { }
-void glPolygonMode( unsigned int i, unsigned int j ) { }
+#endif
+#if !ENABLE_GL_SELECT
// *** Picking won't be supported for now ***
void glPushName( unsigned int i ) { }
void glLoadName( unsigned int i ) { }
void glPopName() { }
-// Probably replace by regular glBlendFunc ...
-void glBlendFuncSeparate(int a, int b, int c, int d)
-{
- glBlendFunc(a, b);
-}
-
-// For direct pixel blitting...
-void glRasterPos2d(double a, double b) { }
-void glPixelZoom(float a, float b) { }
-void glDrawPixels(int a, int b, int c, int d, void * e) { }
-
-#endif
-
-#if !defined(__APPLE__) && !defined(__WIN32__)
-void (APIENTRY * glBindBufferARB) (GLenum target, GLuint buffer);
-void (APIENTRY * glGenBuffersARB) (GLsizei n, GLuint *buffers);
-void (APIENTRY * glDeleteBuffersARB) (GLsizei n, const GLuint *buffers);
-void (APIENTRY * glBufferDataARB) (GLenum target, int size, const GLvoid *data, GLenum usage);
#endif
-static int currentVertexBuffer;
-
-bool GLSelectVBO(uint vbo)
+#if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
+static inline uint getPrimitiveType(RenderPrimitiveType type)
{
- if(currentVertexBuffer != vbo)
+ static int primitiveTypes[RenderPrimitiveType] =
{
- GLBindBuffer(GL_ARRAY_BUFFER, vbo);
- currentVertexBuffer = vbo;
- return true;
- }
- return false;
+ GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN,
+ GLIMTKMode::quads,
+ GLIMTKMode::quadStrip,
+ GL_LINE_STRIP
+ };
+ // NOTE: This will only work for single quads
+ return (type == quads && !glCaps_quads) ? GL_TRIANGLE_FAN : primitiveTypes[type];
}
-void GLGenBuffers(int count, uint * buffer)
+public void GLSetupTexturing(bool enable)
{
-#ifdef __ANDROID__
- glGenBuffers(count, buffer);
-#else
-#if defined(__WIN32__)
- if(glGenBuffersARB)
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.texturing(enable);
#endif
- glGenBuffersARB(count, buffer);
-#endif
-}
-void GLDeleteBuffers(int count, GLuint * buffer)
-{
-#ifdef __ANDROID__
- glDeleteBuffers(count, buffer);
-#else
-#if defined(__WIN32__)
- if(glDeleteBuffersARB)
-#endif
- glDeleteBuffersARB(count, buffer);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
#endif
}
-void GLBindBuffer(int target, uint buffer)
+public void GLSetupFog(bool enable)
{
-#ifdef __ANDROID__
- glBindBuffer(target, buffer);
-#else
-#if defined(__WIN32__)
- if(glBindBufferARB)
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.fog(enable);
#endif
- glBindBufferARB(target, buffer);
-#endif
-}
-public void GLVertexPointer(int numCoords, int glType, int stride, void *ptr, int numVertices)
-{
-#ifdef _GLES
- if(glType == GL_DOUBLE)
- glesVertexPointerd(numCoords, stride, ptr, numVertices);
- else if(glType == GL_INT)
- glesVertexPointeri(numCoords, stride, ptr, numVertices);
- else
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ (enable ? glEnable : glDisable)(GL_FOG);
#endif
- glVertexPointer(numCoords, glType, stride, ptr);
}
-public void GLBufferData(int type, GLenum target, int size, const GLvoid *data, GLenum usage)
+bool lightingEnabled;
+
+public void GLSetupLighting(bool enable)
{
-#ifdef _GLES
- if(type == GL_DOUBLE)
- glesBufferDatad(target, size, (void *)data, usage);
- else if(type == GL_UNSIGNED_INT)
- glesBufferDatai(target, size, (void *)data, usage);
- else
+ lightingEnabled = enable;
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.lighting(enable);
#endif
-#ifdef __ANDROID__
- glBufferData(target, size, data, usage);
-#else
-
-#if defined(__WIN32__)
- if(glBufferDataARB)
-#endif
- glBufferDataARB(target, size, data, usage);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ (enable ? glEnable : glDisable)(GL_LIGHTING);
#endif
}
-
-#if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
-static int primitiveTypes[RenderPrimitiveType] =
-{
- GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, GL_LINE_STRIP
-};
#endif
+/*static */GLuint lastBlitTex;
-// Non OpenGL ES friendly stuff
-
-#if defined(_GLES)
-
-//#undef GL_UNSIGNED_INT
-//#undef GL_DOUBLE
-#undef GL_INT
-//#undef GL_POLYGON
-//#undef GL_QUADS
-#undef GL_QUAD_STRIP
-#undef GL_POLYGON_STIPPLE
-#undef GL_LINE_STIPPLE
-#undef GL_LINE
-#undef GL_FILL
-#undef GL_ALL_ATTRIB_BITS
-#undef GL_LIGHT_MODEL_LOCAL_VIEWER
-
-#endif
+Shader activeShader;
static int displayWidth, displayHeight;
#define GL_CLAMP_TO_EDGE 0x812F
-static bool vboAvailable;
-
static bool useSingleGLContext = false;
class OGLDisplay : struct
{
+ GLCapabilities capabilities, originalCapabilities;
+ bool compat;
+ int version;
+
+ ColorAlpha * flippingBuffer;
+ int flipBufH, flipBufW;
+ bool depthWrite;
+ int x, y;
+ uint vao;
+ int maxTMU;
+
#if defined(__WIN32__)
HDC hdc;
HGLRC glrc;
int imageBuffers[2];
byte * pboMemory1, * pboMemory2;
*/
-#elif !defined(__ANDROID__)
+#elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
GLXContext glContext;
Pixmap pixmap;
Pixmap shapePixmap;
X11Picture shapePicture;
#endif
-
- ColorAlpha * flippingBuffer;
- int flipBufH, flipBufW;
- bool depthWrite;
- int x, y;
};
class OGLSystem : struct
{
int maxTextureSize;
bool loadingFont;
- bool pow2textures;
#if defined(__WIN32__)
PIXELFORMATDESCRIPTOR pfd;
int format;
HDC hdc;
HGLRC glrc;
HWND hwnd;
-#elif !defined(__ANDROID__)
+#elif defined(__EMSCRIPTEN__)
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
+#elif !defined(__ANDROID__) && !defined(__ODROID__)
XVisualInfo * visualInfo;
GLXContext glContext;
GLXDrawable glxDrawable;
#endif
+ GLCapabilities capabilities;
+ bool compat;
+ int version;
+
+ // Buffer Data
+ uint16 *shortBDBuffer;
+ uint shortBDSize;
};
class OGLSurface : struct
bool opaqueText;
int xOffset;
bool writingText;
+ bool writingOutline;
float foreground[4], background[4], bitmapMult[4];
} OGLSurface;
class OGLMesh : struct
{
- uint vertices;
- uint normals;
- uint texCoords;
- uint texCoords2;
- uint colors;
+ GLAB vertices;
+ GLAB normals;
+ GLAB tangents;
+ GLAB lightVectors;
+ GLAB texCoords;
+ GLAB texCoords2;
+ GLAB colors;
};
class OGLIndices : struct
{
uint16 * indices;
- uint buffer;
+ GLEAB buffer;
uint nIndices;
};
int current;
void * previous;
+#if defined(__WIN32__)
+static HGLRC winCreateContext(HDC hdc, int * contextVersion, bool * isCompatible, bool compatible)
+{
+ HGLRC result = 0;
+ if(wglCreateContextAttribsARB)
+ {
+ int versions[12][2] =
+ {
+ { 4, 5 }, { 4, 4 }, { 4, 3 }, { 4, 2 }, { 4, 1 }, { 4, 0 },
+ { 3, 3 }, { 3, 2 }, { 3, 1 }, { 3, 0 },
+ { 2, 1 }, { 2, 0 }
+ };
+
+ bool tryingCompat = compatible;
+ int v = 0;
+ while(!result)
+ {
+ for(v = 0; !result && v < sizeof(versions) / sizeof(versions[0]); v++)
+ {
+ int v0 = versions[v][0], v1 = versions[v][1];
+ if(!tryingCompat || v0 >= 3)
+ {
+ bool coreNotion = v0 > 3 || (v0 == 3 && v1 >= 3);
+ int attribs[] =
+ {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, v0, WGL_CONTEXT_MINOR_VERSION_ARB, v1,
+ #ifdef _DEBUG
+ WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
+ #endif
+ coreNotion ? WGL_CONTEXT_PROFILE_MASK_ARB : 0, coreNotion ? (tryingCompat ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB) : 0,
+ 0,0
+ };
+ result = wglCreateContextAttribsARB(hdc, null, attribs);
+ if(result)
+ {
+ if(contextVersion) *contextVersion = v0;
+ if(isCompatible) *isCompatible = tryingCompat || !coreNotion;
+ }
+ }
+ }
+ if(tryingCompat)
+ tryingCompat = false;
+ else
+ break;
+ }
+ }
+ if(!result)
+ {
+ if(contextVersion) *contextVersion = 1;
+ if(isCompatible) *isCompatible = true;
+ result = wglCreateContext(hdc);
+ }
+ return result;
+}
+#endif
+
class OpenGLDisplayDriver : DisplayDriver
{
class_property(name) = "OpenGL";
bool LockSystem(DisplaySystem displaySystem)
{
-#if !defined(__ANDROID__)
+#if defined(__EMSCRIPTEN__)
+ OGLSystem oglSystem = displaySystem.driverData;
+ emscripten_webgl_make_context_current(oglSystem.glc);
+#elif !defined(__ANDROID__) && !defined(__ODROID__)
OGLSystem oglSystem = displaySystem.driverData;
if(useSingleGLContext) return true;
#if defined(__WIN32__)
//previous = oglSystem.glContext;
#endif
#endif
+ GLABBindBuffer(GL_ARRAY_BUFFER, 0);
+ GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return true;
}
wglMakeCurrent(null, null);
#elif defined(__unix__) || defined(__APPLE__)
// printf("Making NULL current\n");
- #if defined(__ANDROID__)
+ #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
#else
glXMakeCurrent(xGlobalDisplay, None, null);
#endif
bool Lock(Display display)
{
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
OGLDisplay oglDisplay = display.driverData;
if(useSingleGLContext) return true;
#if defined(__WIN32__)
glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
#endif
#endif
+ GLABBindBuffer(GL_ARRAY_BUFFER, 0);
+ GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return true;
}
if(oglDisplay.memBitmap) DeleteObject(oglDisplay.memBitmap);
#elif defined(__unix__) || defined(__APPLE__)
- #if defined(__ANDROID__)
+ #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
#else
if(oglDisplay.shapePixmap)
XFreePixmap(xGlobalDisplay, oglDisplay.shapePixmap);
}
}
- void ::CheckExtensions(OGLSystem oglSystem)
+#if !defined(__EMSCRIPTEN__)
+ void ::CheckCapabilities(OGLSystem oglSystem, OGLDisplay oglDisplay, bool canCheckExtensions)
{
- const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
- if(extensions)
- oglSystem.pow2textures = strstr(extensions, "GL_ARB_texture_non_power_of_two") ? false : true;
+ GLCapabilities capabilities;
+#if !defined(_GLES2)
+ const char * extensions = (canCheckExtensions && (!oglDisplay || oglDisplay.compat)) ? (const char *)glGetString(GL_EXTENSIONS) : null;
+#endif
+#ifdef DIAGNOSTICS
+ printf("extensions: %s\n", extensions);
+#endif
+
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
+
+#if defined(_GLES)
+ capabilities = { fixedFunction = true, vertexPointer = true, vertexBuffer = true, pointSize = true, legacyFormats = true, frameBuffer = extensions && strstr(extensions, "GL_OES_framebuffer_object") };
+#elif defined(_GLES2)
+ capabilities = { glCaps_shaders = true, vertexBuffer = true, pointSize = true, frameBuffer = true, legacyFormats = true };
+#else
+ capabilities =
+ {
+ nonPow2Textures = glGetStringi || (extensions && (strstr(extensions, "GL_ARB_texture_non_power_of_two")));
+ intAndDouble = true;
+#ifdef GL_DEBUGGING
+ debug = true;
+#endif
+ compatible = oglDisplay.compat;
+ pointSize = oglDisplay.compat;
+#if ENABLE_GL_LEGACY
+ legacy = glBegin != null && oglDisplay.compat;
+ legacyFormats = glBegin != null && oglDisplay.compat;
+ immediate = glBegin != null && oglDisplay.compat;
+ fixedFunction = glBegin != null && oglDisplay.compat;
+ quads = glBegin != null && oglDisplay.compat;
+ select = glSelectBuffer != null && oglDisplay.compat;
+#endif
+#if ENABLE_GL_SHADERS
+ shaders = glCreateProgram != null;
+#endif
+#if ENABLE_GL_POINTER
+ vertexPointer = oglDisplay.compat;
+#endif
+#if ENABLE_GL_VAO
+ vao = glBindVertexArray != null && !oglDisplay.compat;
+#endif
+#if ENABLE_GL_FBO
+ frameBuffer = glBindFramebuffer != null;
+#endif
+ vertexBuffer = glBindBuffer != null;
+ // mapBuffer = glMapBuffer != null;
+ };
+#endif
+
+#ifdef DIAGNOSTICS
+ PrintLn("max texture size: ", oglSystem.maxTextureSize);
+#endif
+ if(oglDisplay) oglDisplay.capabilities = capabilities;
+ if(oglSystem) oglSystem.capabilities = capabilities;
}
+#endif
bool CreateDisplaySystem(DisplaySystem displaySystem)
{
bool result = false;
OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
+#ifdef _GLES
+ oglSystem.capabilities = { fixedFunction = true, vertexBuffer = true, frameBuffer = true, pointSize = true };
+#elif defined(_GLES2)
+ oglSystem.capabilities = { shaders = true, vertexBuffer = true, frameBuffer = true, pointSize = true };
+#else
+ oglSystem.capabilities = { compatible = glCaps_compatible, shaders = true, fixedFunction = true, immediate = true, legacy = true, pointSize = true, quads = true, intAndDouble = true, vertexBuffer = true, frameBuffer = true, vao = true, nonPow2Textures = true };
+#endif
+
+#ifdef DIAGNOSTICS
+ PrintLn("OpenGL driver's CreateDisplaySystem()");
+#endif
+
#ifdef __WIN32__
oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
{
wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
- // Get Pointers To The GL Functions
- glActiveTextureARB = (void *) wglGetProcAddress("glActiveTextureARB");
- glMultiTexCoord2fARB = (void *) wglGetProcAddress("glMultiTexCoord2fARB");
- glClientActiveTextureARB = (void *) wglGetProcAddress("glClientActiveTextureARB");
- glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
- glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
- glGenBuffersARB = (void *) wglGetProcAddress("glGenBuffersARB");
- glBindBufferARB = (void *) wglGetProcAddress("glBindBufferARB");
- glBufferDataARB = (void *) wglGetProcAddress("glBufferDataARB");
- glMapBufferARB = (void *) wglGetProcAddress("glMapBufferARB");
- glUnmapBufferARB = (void *) wglGetProcAddress("glUnmapBufferARB");
- glDeleteBuffersARB = (void *) wglGetProcAddress("glDeleteBuffersARB");
- glBlendFuncSeparate = (void *) wglGetProcAddress("glBlendFuncSeparate");
-
wglChoosePixelFormatARB = (void *) wglGetProcAddress("wglChoosePixelFormatARB");
wglGetExtensionsStringARB = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
wglCreatePbufferARB = (void *)wglGetProcAddress("wglCreatePbufferARB");
wglReleasePbufferDCARB = (void *)wglGetProcAddress("wglReleasePbufferDCARB");
wglBindTexImageARB = (void *)wglGetProcAddress("wglBindTexImageARB");
wglReleaseTexImageARB = (void *)wglGetProcAddress("wglReleaseTexImageARB");
-
wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT");
+ wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
- vboAvailable = glBindBufferARB != null;
+ glLockArraysEXT = (void *) wglGetProcAddress("glLockArraysEXT" );
+ glUnlockArraysEXT = (void *) wglGetProcAddress("glUnlockArraysEXT");
// eSystem_LoggingMode(LOG_MSGBOX, null);
if(wglChoosePixelFormatARB)
{
- int pixelFormat;
- int valid;
- int numFormats;
- float fAttributes[] = {0,0};
- int iAttributes[] =
+ int pixelFormat;
+ int valid;
+ int numFormats;
+ float fAttributes[] = {0,0};
+ int iAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
- WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
- WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
- WGL_COLOR_BITS_ARB,24,
- WGL_ALPHA_BITS_ARB,8,
- WGL_DEPTH_BITS_ARB,16,
- WGL_STENCIL_BITS_ARB,0,
- WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
- WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
- WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
- 0,0
+ WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
+ WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
+ WGL_COLOR_BITS_ARB,24,
+ WGL_ALPHA_BITS_ARB,8,
+ WGL_DEPTH_BITS_ARB,16,
+ WGL_STENCIL_BITS_ARB,0,
+ WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
+ WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
+ WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
+ 0,0
};
//Log("Found wglChoosePixelFormatARB\n");
- valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
- if(!valid || !numFormats)
- {
+ valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
+ if(!valid || !numFormats)
+ {
//Log("Can't find 4x multi sampling\n");
- iAttributes[19] = 2;
- valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
+ iAttributes[19] = 2;
+ valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
if(!valid || !numFormats)
{
// Log("Can't find 2x multi sampling\n");
iAttributes[17] = 0;
valid = wglChoosePixelFormatARB(oglSystem.hdc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
}
- }
+ }
if(valid && numFormats)
{
oglSystem.format = pixelFormat;
SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
//Log("Successfully set pixel format\n");
- oglSystem.glrc = wglCreateContext(oglSystem.hdc);
- wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
+#ifdef DIAGNOSTICS
+ PrintLn("winCreateContext()");
+#endif
+ oglSystem.glrc = winCreateContext(oglSystem.hdc, &oglSystem.version, &oglSystem.compat, displaySystem.glCapabilities.compatible);
+#ifdef DIAGNOSTICS
+ PrintLn("wglMakeCurrent()");
+#endif
+ if(oglSystem.glrc)
+ wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
}
}
/*else
result = true;
- CheckExtensions(oglSystem);
-
wglMakeCurrent(null, null);
//eSystem_DumpErrors(true);
}
}
#elif defined(__unix__) || defined(__APPLE__)
- vboAvailable = true;
- #if defined(__ANDROID__)
+ #if defined(__ANDROID__) || defined(__ODROID__)
+ #if defined(__ANDROID__)
egl_init_display(guiApp.desktop.windowHandle);
- CheckExtensions(oglSystem);
+ #elif defined(__ODROID__)
+ egl_init_display((uint)displaySystem.window);
+ #endif
+ CheckCapabilities(oglSystem, null, true);
+
+ // TODO: Clean this up? Needed here?
+ GLEnableClientState(VERTICES);
+ /*
+ // Initialize GL state.
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ glEnable(GL_CULL_FACE);
+ glShadeModel(GL_SMOOTH);
+ glDisable(GL_DEPTH_TEST);
+ */
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ matrixStack[0][0].Identity();
+ matrixStack[1][0].Identity();
+ matrixStack[2][0].Identity();
+
+ GLMatrixMode(GL_MODELVIEW);
+ GLScaled(1.0, 1.0, -1.0);
+ GLMatrixMode(GL_PROJECTION);
+ glShadeModel(GL_FLAT);
+
+#if !defined(_GLES)
+ if(!glCaps_shaders)
+ ;//GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+#endif
+ glFogi(GL_FOG_MODE, GL_EXP);
+ glFogf(GL_FOG_DENSITY, 0);
+ glEnable(GL_NORMALIZE);
+ glDepthFunc(GL_LESS);
+ glClearDepth(1.0);
+ glDisable(GL_MULTISAMPLE);
+
+ glViewport(0,0,eglWidth,eglHeight);
+ GLLoadIdentity();
+ GLOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
+
+ glabCurArrayBuffer = 0;
+ glabCurElementBuffer = 0;
+
result = true;
+ #elif defined(__EMSCRIPTEN__)
+ {
+ EmscriptenWebGLContextAttributes attribs = { 0 };
+ attribs.depth = 1;
+ attribs.antialias = 1;
+
+ /*
+ EM_BOOL alpha;
+ EM_BOOL depth;
+ EM_BOOL stencil;
+ EM_BOOL antialias;
+ EM_BOOL premultipliedAlpha;
+ EM_BOOL preserveDrawingBuffer;
+ EM_BOOL preferLowPowerToHighPerformance;
+ EM_BOOL failIfMajorPerformanceCaveat;
+ int majorVersion;
+ int minorVersion;
+ EM_BOOL enableExtensionsByDefault;
+ */
+
+ emscripten_webgl_init_context_attributes(&attribs);
+ oglSystem.maxTextureSize = 16384;
+ oglSystem.glc = emscripten_webgl_create_context("canvas", &attribs);
+ if(emscripten_webgl_make_context_current(oglSystem.glc) == EMSCRIPTEN_RESULT_SUCCESS)
+ result = true;
+
+ /*glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);*/
+ }
#else
{
X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
if(oglSystem.glContext)
{
glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
- // Setup Extensions
- CheckExtensions(oglSystem);
glXMakeCurrent(xGlobalDisplay, None, null);
result = true;
}
void DestroyDisplaySystem(DisplaySystem displaySystem)
{
OGLSystem oglSystem = displaySystem.driverData;
+ if(stippleTexture)
+ {
+ glDeleteTextures(1, &stippleTexture);
+ stippleTexture = 0;
+ }
+
+#if ENABLE_GL_SHADERS
+ defaultShader.free();
+ activeShader = null;
+#endif
+
+ delete oglSystem.shortBDBuffer;
+ glimtkTerminate();
#if defined(__WIN32__)
wglMakeCurrent( null, null );
DestroyWindow(oglSystem.hwnd);
#elif defined(__unix__) || defined(__APPLE__)
- #if defined(__ANDROID__)
+ #if defined(__ANDROID__) || defined(__ODROID__)
egl_term_display();
+ #elif defined(__EMSCRIPTEN__)
+ emscripten_webgl_destroy_context(oglSystem.glc);
#else
if(oglSystem.visualInfo)
{
XFree(oglSystem.visualInfo);
#endif
}
+ if(oglSystem.glContext)
+ glXDestroyContext(xGlobalDisplay, oglSystem.glContext);
if(oglSystem.glxDrawable)
{
delete oglSystem;
}
+ /*static */bool ::initialDisplaySetup(Display display, bool canCheckExtensions, bool loadExtensions)
+ {
+ OGLDisplay oglDisplay = display.driverData;
+ OGLSystem oglSystem = display.displaySystem.driverData;
+ bool result = true;
+
+#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
+ if(loadExtensions && ogl_LoadFunctions() == ogl_LOAD_FAILED)
+ PrintLn("ogl_LoadFunctions() failed!");
+ CheckCapabilities(oglSystem, oglDisplay, canCheckExtensions);
+#endif
+
+ {
+ GLCapabilities capabilities = *&display.glCapabilities;
+ // PrintLn("Available OpenGL Capabilities: ", oglDisplay.capabilities);
+ // PrintLn("Desired OpenGL Capabilities: ", capabilities);
+
+ oglDisplay.originalCapabilities = oglDisplay.capabilities;
+
+ // Re-enable glCaps_shaders if no fixed function support
+ if(!oglDisplay.capabilities.fixedFunction)
+ capabilities.shaders = true;
+ // Re-enable fixed function if no glCaps_shaders support
+ if(!oglDisplay.capabilities.shaders)
+ {
+ capabilities.fixedFunction = true;
+ capabilities.shaders = false;
+ }
+
+ if(!capabilities.shaders && !capabilities.fixedFunction)
+ {
+ capabilities.fixedFunction = oglDisplay.capabilities.fixedFunction;
+ capabilities.shaders = oglDisplay.capabilities.shaders;
+ }
+
+ // Disable things that don't work with glCaps_shaders
+ if(capabilities.shaders)
+ {
+ capabilities.fixedFunction = false;
+ capabilities.legacy = false;
+ capabilities.immediate = false;
+ }
+
+ #if !ENABLE_GL_POINTER
+ // Re-enable vertex buffer if no pointer support
+ capabilities.vertexBuffer = true;
+ #endif
+
+ oglDisplay.capabilities &= capabilities;
+
+ // PrintLn("Selected OpenGL Capabilities: ", oglDisplay.capabilities);
+ oglSystem.capabilities = oglDisplay.capabilities;
+ }
+
+ #ifdef GL_DEBUGGING
+ if(oglDisplay.capabilities.debug)
+ setupDebugging();
+ #else
+ oglDisplay.capabilities.debug = false;
+ #endif
+
+#if ENABLE_GL_VAO
+ if(oglDisplay.capabilities.vao)
+ {
+ glGenVertexArrays(1, &oglDisplay.vao);
+ glBindVertexArray(oglDisplay.vao);
+ }
+#endif
+
+ oglSystem.capabilities = oglDisplay.capabilities;
+ SETCAPS(oglDisplay.capabilities);
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+#if ENABLE_GL_LEGACY
+ if(oglDisplay.compat)
+ {
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+#endif
+ defaultShader.select();
+ }
+#if ENABLE_GL_LEGACY
+ else
+ {
+ glDisableVertexAttribArray(GLBufferContents::color);
+ glDisableVertexAttribArray(GLBufferContents::normal);
+ glDisableVertexAttribArray(GLBufferContents::texCoord);
+ glDisableVertexAttribArray(GLBufferContents::vertex);
+ glDisableVertexAttribArray(GLBufferContents::tangent1);
+ glDisableVertexAttribArray(GLBufferContents::tangent2);
+#if ENABLE_GL_VAO
+ glBindVertexArray(0);
+#endif
+ glUseProgram(0);
+ }
+#endif
+
+#endif
+
+#if ENABLE_GL_VAO
+ if(glCaps_vao)
+ glBindVertexArray(oglDisplay.vao);
+#endif
+
+ GLEnableClientState(VERTICES);
+
+ GLABBindBuffer(GL_ARRAY_BUFFER, 0);
+ GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+#if defined(__WIN32__)
+ if(glBlendFuncSeparate)
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ else
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+#else
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+#endif
+ glEnable(GL_BLEND);
+
+ GLMatrixMode(MatrixMode::texture);
+ GLLoadIdentity();
+
+ GLMatrixMode(MatrixMode::modelView);
+ GLLoadIdentity(); // For setting up GLES stack
+ GLScaled(1.0, 1.0, -1.0);
+ // glTranslatef(0.375f, 0.375f, 0.0f);
+ // glTranslatef(-0.625f, -0.625f, 0.0f);
+ GLMatrixMode(MatrixMode::projection);
+ GLLoadIdentity();
+ if(display.width && display.height)
+ GLOrtho(0,display.width,display.height,0,0.0,1.0);
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ glShadeModel(GL_FLAT);
+
+ #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
+ GLLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+
+#if !defined(_GLES)
+ ;//GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+#endif
+ glFogi(GL_FOG_MODE, GL_EXP);
+ glFogf(GL_FOG_DENSITY, 0);
+ glEnable(GL_NORMALIZE);
+ }
+#endif
+ glDepthFunc(GL_LESS);
+ glClearDepth(1.0);
+#if !defined(__EMSCRIPTEN__)
+ glDisable(GL_MULTISAMPLE);
+#endif
+
+#if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
+ display.ambient = Color { 50,50,50 };
+#endif
+ return result;
+ }
+
bool CreateDisplay(Display display)
{
bool result = false;
OGLDisplay oglDisplay = display.driverData;
-#if !defined(__ANDROID__)
OGLSystem oglSystem = display.displaySystem.driverData;
-#endif
+
if(!oglDisplay)
oglDisplay = display.driverData = OGLDisplay { };
- //printf("Inside CreateDisplay\n");
+ oglDisplay.capabilities = oglSystem.capabilities;
#if defined(__WIN32__) || defined(USEPBUFFER)
if(!display.alphaBlend)
#endif
{
- #if defined(__WIN32__)
+#if defined(__WIN32__)
oglDisplay.hdc = GetDC(display.window);
SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
- if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
+ if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, &oglDisplay.version, &oglDisplay.compat, (*&display.glCapabilities).compatible)))
{
wglShareLists(oglSystem.glrc, oglDisplay.glrc);
wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
}
else
ReleaseDC(display.window, oglDisplay.hdc);
- #elif defined(__unix__) || defined(__APPLE__)
- #if defined(__ANDROID__)
- #else
+#elif defined(__unix__) || defined(__APPLE__)
+# if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
+ result = true;
+# else
XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
/*
#if defined(__APPLE__)
// visualInfo = oglSystem.visualInfo;
//#endif
*/
+#if !defined(__APPLE__)
+ oglDisplay.compat = true;
+ oglDisplay.version = 4;
+#endif
+
if(visualInfo)
{
//printf("visualInfo is not null\n");
glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
result = true;
}
- #endif
- #endif
+# endif
+#endif
}
#if defined(__WIN32__) || defined(USEPBUFFER)
else
+ {
+ oglDisplay.compat = (*&display.glCapabilities).compatible;
result = true;
+ wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
+ }
#endif
if(result)
{
-#if defined(__WIN32__)
- if(glBlendFuncSeparate)
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- else
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-#else
-#if !defined(__OLDX__)
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-#else
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-#endif
+#if defined(__EMSCRIPTEN__)
+ emscripten_webgl_make_context_current(oglSystem.glc);
#endif
- glEnable(GL_BLEND);
-
- glMatrixMode(GL_MODELVIEW);
- glScaled(1.0, 1.0, -1.0);
- // glTranslatef(0.375f, 0.375f, 0.0f);
- // glTranslatef(-0.625f, -0.625f, 0.0f);
- glMatrixMode(GL_PROJECTION);
- glShadeModel(GL_FLAT);
- // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, true);
- glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
- glFogi(GL_FOG_MODE, GL_EXP);
- glFogf(GL_FOG_DENSITY, 0);
- glEnable(GL_NORMALIZE);
- glDepthFunc(GL_LESS);
- glClearDepth(1.0);
- glDisable(GL_MULTISAMPLE_ARB);
- }
-#if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
- display.ambient = Color { 50,50,50 };
+#if defined(__WIN32__) || defined(USEPBUFFER)
+ initialDisplaySetup(display, !display.alphaBlend, true);
+#else
+ initialDisplaySetup(display, true, true);
#endif
+ }
if(!useSingleGLContext)
{
#if defined(__WIN32__)
wglMakeCurrent(null, null);
#elif defined(__unix__) || defined(__APPLE__)
- #if defined(__ANDROID__)
+ #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
result = true;
#else
glXMakeCurrent(xGlobalDisplay, None, null);
#endif
#endif
}
-
+ else
+ {
+ #if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
+ result = true;
+ #endif
+ }
return result;
}
bool DisplaySize(Display display, int width, int height)
{
OGLDisplay oglDisplay = display.driverData;
-
bool result = false;
- //printf("Inside DisplaySize\n");
#if defined(__WIN32__) || defined(USEPBUFFER)
OGLSystem oglSystem = display.displaySystem.driverData;
if(display.alphaBlend)
{
//WGL_DRAW_TO_BITMAP_ARB, GL_TRUE,
WGL_DRAW_TO_PBUFFER_ARB,GL_TRUE,
- WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
- WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
- WGL_COLOR_BITS_ARB,24,
- WGL_ALPHA_BITS_ARB,8,
- WGL_DEPTH_BITS_ARB,16,
- WGL_STENCIL_BITS_ARB,0,
- WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
- WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
- WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
- 0,0
+ WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
+ WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
+ WGL_COLOR_BITS_ARB,24,
+ WGL_ALPHA_BITS_ARB,8,
+ WGL_DEPTH_BITS_ARB,16,
+ WGL_STENCIL_BITS_ARB,0,
+ WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
+ WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
+ WGL_SAMPLES_ARB, 4, // Check For 4x Multisampling
+ 0,0
};
//Log("Found wglChoosePixelFormatARB\n");
oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
- if((oglDisplay.glrc = wglCreateContext(oglDisplay.hdc)))
+ if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, null, null, oglDisplay.capabilities.compatible)))
{
BITMAPINFO * info;
HDC hdc = GetDC(display.window);
ReleaseDC(display.window, hdc);
}
#elif defined(__unix__) || defined(__APPLE__)
- #if defined(__ANDROID__)
+ #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
result = true;
#else
- int attrib[] =
- {
- GLX_DOUBLEBUFFER, True,
+ int attrib[] =
+ {
+ GLX_DOUBLEBUFFER, True,
GLX_DEPTH_SIZE, 1,
- GLX_RED_SIZE, 8,
- GLX_GREEN_SIZE, 8,
- GLX_BLUE_SIZE, 8,
- GLX_ALPHA_SIZE, 8,
- GLX_STENCIL_SIZE, 1,
- //GLX_DEPTH_SIZE, 24,
- GLX_RENDER_TYPE, GLX_RGBA_BIT,
- GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
- None
- };
-
- int PBattrib[] =
- {
- GLX_PBUFFER_WIDTH, width,
- GLX_PBUFFER_HEIGHT, height,
- GLX_LARGEST_PBUFFER, False,
+ GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8,
+ GLX_ALPHA_SIZE, 8,
+ GLX_STENCIL_SIZE, 1,
+ //GLX_DEPTH_SIZE, 24,
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
+ None
+ };
+
+ int PBattrib[] =
+ {
+ GLX_PBUFFER_WIDTH, width,
+ GLX_PBUFFER_HEIGHT, height,
+ GLX_LARGEST_PBUFFER, False,
None
- };
+ };
- // choose a pixel format that meets our minimum requirements
- int count = 0;
+ // choose a pixel format that meets our minimum requirements
+ int count = 0;
- GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
+ GLXFBConfig *config = glXChooseFBConfig(xGlobalDisplay, DefaultScreen(xGlobalDisplay), attrib, &count);
if(config)
{
if(oglDisplay.pixmap)
XFreePixmap(xGlobalDisplay, oglDisplay.pixmap);
if(oglDisplay.glContext)
- glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
+ glXDestroyContext(xGlobalDisplay, oglDisplay.glContext);
if(oglDisplay.pBuffer)
glXDestroyPbuffer(xGlobalDisplay, oglDisplay.pBuffer);
- oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
+ oglDisplay.pBuffer = glXCreatePbuffer(xGlobalDisplay, config[0], PBattrib);
if(oglDisplay.pBuffer)
{
- oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
+ oglDisplay.glContext = glXCreateNewContext(xGlobalDisplay, config[0], GLX_RGBA_TYPE, oglSystem.glContext, True);
if(oglDisplay.glContext)
{
glXMakeCurrent(xGlobalDisplay, None, null);
{
XRenderPictureAttributes attributes = { 0 };
XRenderPictFormat * format = XRenderFindStandardFormat(xGlobalDisplay, /*PictStandardRGB24*/ PictStandardARGB32);
- #if !defined(__APPLE__) && !defined(__OLDX__)
+ #if !defined(__APPLE__)
attributes.repeat = RepeatNormal;
#else
attributes.repeat = 1;
#if defined(__WIN32__)
wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
#elif defined(__unix__) || defined(__APPLE__)
- #if defined(__ANDROID__)
+ #if defined(__ANDROID__) || defined(__ODROID__)
width = eglWidth;
height = eglHeight;
+ #elif defined(__EMSCRIPTEN__)
+ emscripten_webgl_make_context_current(oglSystem.glc);
#else
glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
#endif
else
#endif
result = true;
+
+ SETCAPS(oglDisplay.capabilities);
+
+ if(display.alphaBlend && result)
+ initialDisplaySetup(display, true, false);
+
if(!result && display.alphaBlend)
{
printf("Alpha blending windows not supported on this display\n");
result = false;
glViewport(0,0,width,height);
- glLoadIdentity();
- glOrtho(0,width,height,0,0.0,1.0);
+ GLMatrixMode(MatrixMode::projection);
+ GLLoadIdentity();
+ GLOrtho(0,width,height,0,0.0,1.0);
displayWidth = display.width = width;
displayHeight = display.height = height;
{
oglDisplay.flipBufW = width;
oglDisplay.flipBufH = height;
-#ifdef _GLES
+#if defined(_GLES) || defined(_GLES2)
result = true;
#else
oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
void StartUpdate(Display display)
{
+#if ENABLE_GL_VAO
+ if(glCaps_vao)
+ {
+ OGLDisplay oglDisplay = display.driverData;
+ glBindVertexArray(oglDisplay.vao);
+ }
+#endif
+ GLABBindBuffer(GL_ARRAY_BUFFER, 0);
+ GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+#if ENABLE_GL_SHADERS
+ activeProgram = 0;
+#endif
}
void EndUpdate(Display display)
#if defined(__WIN32__) || defined(USEPBUFFER)
OGLDisplay oglDisplay = display.driverData;
#endif
- //Logf("DisplayScreen\n");
- glFlush();
- glFinish();
+#if !defined(__ANDROID__)
+ /*glFlush();
+ glFinish();*/
+#endif
+
#if defined(__WIN32__) || defined(USEPBUFFER)
if(display.alphaBlend)
{
ReleaseDC(0, hdc);
#elif defined(__unix__) || defined(__APPLE__)
- #if defined(__ANDROID__)
+ #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
#else
XTransform transform =
{
XRenderSetPictureTransform(xGlobalDisplay, oglDisplay.pixmapPicture, &transform);
XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.shapePicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
XRenderComposite(xGlobalDisplay, PictOpSrc, oglDisplay.pixmapPicture, None, oglDisplay.windowPicture, 0, 0, 0, 0, 0, 0, display.width, display.height);
- #if !defined(__APPLE__) && !defined(__OLDX__)
+ #if !defined(__APPLE__)
XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, oglDisplay.shapePixmap, ShapeSet);
#else
XShapeCombineMask(xGlobalDisplay, display.window, 2, 0, 0, oglDisplay.shapePixmap, ShapeSet);
#if defined(__WIN32__)
//wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
SwapBuffers(oglDisplay.hdc);
+ //ecere::sys::Sleep(0.1);
#elif defined(__unix__) || defined(__APPLE__)
- #if defined(__ANDROID__)
- eglSwapBuffers(eglDisplay, eglSurface);
+ #if defined(__ANDROID__) || defined(__ODROID__)
+ egl_swap_buffers();
+ #elif defined(__EMSCRIPTEN__)
#else
glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
#endif
#endif
}
- //Logf("Out of DisplayScreen\n");
}
void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
{
OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities capabilities = oglSystem.capabilities;
bool result = false;
Bitmap mipMap { };
GLuint glBitmap = 0;
uint w = width, h = height;
- if(oglSystem.pow2textures)
+ if(!capabilities.nonPow2Textures)
{
w = pow2i(w);
h = pow2i(h);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+#if ENABLE_GL_FFP
+ if(!capabilities.shaders)
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+#endif
mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
return result;
}
- bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
+ bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps, uint cubeMapFace)
{
bool result = false;
OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities capabilities = oglSystem.capabilities;
+ Bitmap convBitmap = bitmap;
+ bool oldStyleCubeMap = (cubeMapFace >> 3) != 0;
+ int face = (cubeMapFace & 7) - 1;
+ if(bitmap.keepData)
+ {
+ convBitmap = { };
+ convBitmap.Copy(bitmap);
+ }
// Pre process the bitmap... First make it 32 bit
- if(/*bitmap.pixelFormat == pixelFormatRGBA || */bitmap.Convert(null, pixelFormat888, null))
+ if(/*bitmap.pixelFormat == pixelFormatRGBA || */convBitmap.Convert(null, pixelFormat888, null))
{
int c, level;
uint w = bitmap.width, h = bitmap.height;
- GLuint glBitmap = 0;
- if(oglSystem.pow2textures)
+ GLuint glBitmap = cubeMapFace && face > 0 ? (GLuint)(uintptr)bitmap.driverData : 0;
+ int target = cubeMapFace ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
+ if(!capabilities.nonPow2Textures)
{
w = pow2i(w);
h = pow2i(h);
// Switch ARGB to RGBA
//if(bitmap.format != pixelFormatRGBA)
{
- for(c=0; c<bitmap.size; c++)
+ int size = convBitmap.stride * convBitmap.height;
+ for(c = 0; c < size; c++)
{
// ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
// TODO:
- ColorAlpha color = ((ColorAlpha *)bitmap.picture)[c];
- ((ColorRGBA *)bitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
+ ColorAlpha color = ((ColorAlpha *)convBitmap.picture)[c];
+ ((ColorRGBA *)convBitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
+ }
+ }
+ // convBitmap.pixelFormat = pixelFormat888;
+
+ if(cubeMapFace && oldStyleCubeMap)
+ {
+ if(face == 0 || face == 1 || face == 4 || face == 5)
+ {
+ uint w = convBitmap.width;
+ uint32 * tmp = new uint [convBitmap.width];
+ int x, y;
+ for(y = 0; y < convBitmap.height; y++)
+ {
+ uint32 * pic = (uint32 *)((byte *)convBitmap.picture + y * w * 4);
+ for(x = 0; x < w; x++)
+ tmp[x] = pic[w-1-x];
+ memcpy(pic, tmp, w*4);
+ }
+ delete tmp;
+ }
+ else if(face == 2 || face == 3)
+ {
+ int y;
+ Bitmap tmp { };
+ tmp.Allocate(null, convBitmap.width, convBitmap.height, 0, convBitmap.pixelFormat, false);
+ for(y = 0; y < convBitmap.height; y++)
+ {
+ memcpy(tmp.picture + convBitmap.width * 4 * y,
+ convBitmap.picture + (convBitmap.height-1-y) * convBitmap.width * 4,
+ convBitmap.width * 4);
+ }
+ memcpy(convBitmap.picture, tmp.picture, convBitmap.sizeBytes);
+ delete tmp;
}
}
- bitmap.pixelFormat = pixelFormat888;
glGetError();
- glGenTextures(1, &glBitmap);
+ if(!glBitmap)
+ glGenTextures(1, &glBitmap);
if(glBitmap == 0)
{
//int error = glGetError();
return false;
}
- glBindTexture(GL_TEXTURE_2D, glBitmap);
+ glBindTexture(target, glBitmap);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ //glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ //glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ //glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+#ifndef GL_TEXTURE_WRAP_R
+ #define GL_TEXTURE_WRAP_R 0x8072
+#endif
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+#if !defined(__EMSCRIPTEN__)
+ if(cubeMapFace)
+ glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+#endif
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
+#endif
+#if ENABLE_GL_FFP
+ if(!capabilities.shaders)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+#endif
result = true;
if(bitmap.width != w || bitmap.height != h)
{
mipMap = Bitmap { };
- if(mipMap.Allocate(null, w, h, w, bitmap.pixelFormat, false))
+ if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
{
Surface mipSurface = mipMap.GetSurface(0,0,null);
- mipSurface.Filter(bitmap, 0,0,0,0, w, h, bitmap.width, bitmap.height);
+ mipSurface.blend = false;
+ mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
delete mipSurface;
}
else
}
}
else
- mipMap = bitmap;
+ mipMap = convBitmap;
if(result)
{
//int width = 0;
glGetError();
// glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
- glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
+ glTexImage2D(cubeMapFace ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
//printf("Calling glTexImage2D\n");
//glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
//printf("width = %d (Should be %d, %d)\n", width, w, h);
result = false;
}
}
- if(mipMap != bitmap)
+ if(mipMap != convBitmap)
delete mipMap;
if(!mipMaps) break;
}
- if(!bitmap.keepData)
- bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
+ convBitmap.driver.FreeBitmap(convBitmap.displaySystem, convBitmap);
bitmap.driverData = (void *)(uintptr)glBitmap;
bitmap.driver = displaySystem.driver;
+ if(bitmap.keepData)
+ delete convBitmap;
if(!result)
FreeBitmap(displaySystem, bitmap);
else if(oglSystem.loadingFont)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
oglSystem.loadingFont = false;
}
}
bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
{
bool result = false;
+ OGLDisplay oglDisplay = display.driverData;
OGLSurface oglSurface = surface.driverData = OGLSurface { };
-
- //Logf("GetSurface\n");
-
if(oglSurface)
{
+ SETCAPS(oglDisplay.capabilities);
if(displayWidth != display.width || displayHeight != display.height)
{
displayWidth = display.width;
displayHeight = display.height;
glViewport(0,0,display.width,display.height);
- glLoadIdentity();
- glOrtho(0,display.width,display.height,0,0.0,1.0);
+ GLLoadIdentity();
+ GLOrtho(0,display.width,display.height,0,0.0,1.0);
}
surface.offset.x = x;
{
Box box;
- //Logf("Clip\n");
-
if(clip != null)
{
box = clip;
uint row;
glPixelStorei(GL_PACK_ALIGNMENT, 4);
+#if ENABLE_GL_LEGACY
glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+#endif
glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
// Need a flip...
{
OGLSurface oglSurface = surface.driverData;
- //Logf("SetForeground\n");
-
oglSurface.foreground[0] = color.color.r/255.0f;
oglSurface.foreground[1] = color.color.g/255.0f;
oglSurface.foreground[2] = color.color.b/255.0f;
{
OGLSurface oglSurface = surface.driverData;
- //Logf("SetBackground\n");
-
oglSurface.background[0] = color.color.r/255.0f;
oglSurface.background[1] = color.color.g/255.0f;
oglSurface.background[2] = color.color.b/255.0f;
void PutPixel(Display display, Surface surface,int x,int y)
{
OGLSurface oglSurface = surface.driverData;
-
- //Logf("PutPixel\n");
-
- glColor4fv(oglSurface.foreground);
- glBegin(GL_POINTS);
+ GLColor4fv(oglSurface.foreground);
+ GLBegin(GL_POINTS);
// glVertex2i(x+surface.offset.x, y+surface.offset.y);
- glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
-
- glEnd();
+ GLVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
+ GLEnd();
}
void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
x2 += surface.offset.x;
y2 += surface.offset.y;
- //Logf("Line\n");
-
- glColor4fv(oglSurface.foreground);
- glBegin(GL_LINES);
-#ifdef _GLES
+ GLColor4fv(oglSurface.foreground);
+ GLBegin(GL_LINES);
if(stippleEnabled)
{
- glTexCoord2f(0.5f, 0);
- glVertex2f(x1 + 0.5f, y1 + 0.5f);
- glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
+ GLTexCoord2f(0.5f, 0);
+ GLVertex2f(x1 + 0.5f, y1 + 0.5f);
+ GLTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
+ GLVertex2f(x2 + 0.5f, y2 + 0.5f);
}
else
-#endif
{
/*
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
+ GLVertex2i(x1, y1);
+ GLVertex2i(x2, y2);
*/
- glVertex2f(x1 + 0.5f, y1 + 0.5f);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
+ GLVertex2f(x1 + 0.5f, y1 + 0.5f);
+ GLVertex2f(x2 + 0.5f, y2 + 0.5f);
}
- glEnd();
+ GLEnd();
}
void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
x2 += surface.offset.x;
y2 += surface.offset.y;
- //Logf("Rectangle\n");
-
- glColor4fv(oglSurface.foreground);
-#ifdef _GLES
+ GLColor4fv(oglSurface.foreground);
if(stippleEnabled)
{
- glBegin(GL_LINES);
-
- glTexCoord2f(0.5f, 0);
- glVertex2f(x1 + 0.5f, y1 + 0.5f);
- glTexCoord2f(y2-y1 + 0.5f, 0);
- glVertex2f(x1 + 0.5f, y2 + 0.5f);
-
- glTexCoord2f(0.5f, 0);
- glVertex2f(x1 + 0.5f, y2 + 0.5f);
- glTexCoord2f(x2 - x1 + 0.5f, 0);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
-
- glTexCoord2f(0.5f, 0);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
- glTexCoord2f(y1 - y2 + 0.5f, 0);
- glVertex2f(x2 + 0.5f, y1 + 0.5f);
-
- glTexCoord2f(0.5f, 0);
- glVertex2f(x2 + 0.5f, y1 + 0.5f);
- glTexCoord2f(x1 - x2 + 0.5f, 0);
- glVertex2f(x1 + 0.5f, y1 + 0.5f);
+ GLBegin(GL_LINES);
+
+ GLTexCoord2f(0.5f, 0);
+ GLVertex2f(x1 + 0.5f, y1 + 0.5f);
+ GLTexCoord2f(y2-y1 + 0.5f, 0);
+ GLVertex2f(x1 + 0.5f, y2 + 0.5f);
+
+ GLTexCoord2f(0.5f, 0);
+ GLVertex2f(x1 + 0.5f, y2 + 0.5f);
+ GLTexCoord2f(x2 - x1 + 0.5f, 0);
+ GLVertex2f(x2 + 0.5f, y2 + 0.5f);
+
+ GLTexCoord2f(0.5f, 0);
+ GLVertex2f(x2 + 0.5f, y2 + 0.5f);
+ GLTexCoord2f(y1 - y2 + 0.5f, 0);
+ GLVertex2f(x2 + 0.5f, y1 + 0.5f);
+
+ GLTexCoord2f(0.5f, 0);
+ GLVertex2f(x2 + 0.5f, y1 + 0.5f);
+ GLTexCoord2f(x1 - x2 + 0.5f, 0);
+ GLVertex2f(x1 + 0.5f, y1 + 0.5f);
}
else
-#endif
{
- glBegin(GL_LINE_LOOP);
+ GLBegin(GL_LINE_LOOP);
/*
glVertex2i(x1, y1);
glVertex2i(x1, y2);
glVertex2i(x2, y2);
glVertex2i(x2, y1);
*/
- glVertex2f(x1 + 0.5f, y1 + 0.5f);
- glVertex2f(x1 + 0.5f, y2 + 0.5f);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
- glVertex2f(x2 + 0.5f, y1 + 0.5f);
+ GLVertex2f(x1 + 0.5f, y1 + 0.5f);
+ GLVertex2f(x1 + 0.5f, y2 + 0.5f);
+ GLVertex2f(x2 + 0.5f, y2 + 0.5f);
+ GLVertex2f(x2 + 0.5f, y1 + 0.5f);
}
- glEnd();
+ GLEnd();
}
void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
{
OGLSurface oglSurface = surface.driverData;
- //Logf("Area\n");
- glColor4fv(oglSurface.background);
- glRecti(x1+surface.offset.x, y1+surface.offset.y,
- x2+surface.offset.x + 1, y2+surface.offset.y + 1);
+ GLColor4fv(oglSurface.background);
+ GLRecti(x1+surface.offset.x, y1+surface.offset.y,
+ x2+surface.offset.x + 1, y2+surface.offset.y + 1);
/*
- glRectf(x1+surface.offset.x, y1+surface.offset.y,
+ GLRectf(x1+surface.offset.x, y1+surface.offset.y,
x2+surface.offset.x + 1, y2+surface.offset.y + 1);
*/
}
void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
{
OGLSurface oglSurface = surface.driverData;
-
-#if !defined(__OLDX__)
- // WHY DO WE HAVE GL_ONE HERE ?
- /*if(glBlendFuncSeparate && !oglSurface.writingText)
- glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
-#endif
+ GLuint tex = (GLuint)(uintptr)bitmap.driverData;
+ if(!tex) return;
if(!oglSurface.writingText)
{
// glTranslatef(-0.375f, -0.375f, 0.0f);
- glEnable(GL_TEXTURE_2D);
- glColor4fv(oglSurface.bitmapMult);
+ GLSetupTexturing(true);
+ GLColor4fv(oglSurface.bitmapMult);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ GLBegin(GLIMTKMode::quads);
+ }
+ else if(lastBlitTex != tex)
+ {
+ if(lastBlitTex)
+ GLEnd();
+ glBindTexture(GL_TEXTURE_2D, tex);
+ GLBegin(GLIMTKMode::quads);
+ lastBlitTex = tex;
}
- else if(oglSurface.xOffset)
- glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
-
- glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
- glBegin(GL_QUADS);
if(h < 0)
{
- glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
- glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
+ GLTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
+ GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
}
else
{
/*
- glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
- glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
+ GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
+ GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
*/
- glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
- glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
- glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
- glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
- glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
- glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
- glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
- glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
+ GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
+ GLVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
+ GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
+ GLVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
}
- glEnd();
-
if(!oglSurface.writingText)
{
- glDisable(GL_TEXTURE_2D);
-
+ GLEnd();
+ GLSetupTexturing(false);
//glTranslate(0.375, 0.375, 0.0);
}
- else if(oglSurface.xOffset)
- glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
-
-#if !defined(__OLDX__)
- /*if(glBlendFuncSeparate && !oglSurface.writingText)
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
-#endif
}
void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
//glTranslate(-0.375, -0.375, 0.0);
- //Logf("Stretch\n");
-
-#if !defined(__OLDX__)
- /*if(glBlendFuncSeparate)
- glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
-#endif
-
- glEnable(GL_TEXTURE_2D);
+ GLSetupTexturing(true);
glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
- glColor4fv(oglSurface.bitmapMult);
+ GLColor4fv(oglSurface.bitmapMult);
- glBegin(GL_QUADS);
+ GLBegin(GLIMTKMode::quads);
if(h < 0)
{
- glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
+ GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
- glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
+ GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
}
else
{
- glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
+ GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
- glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
+ GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
}
- glEnd();
+ GLEnd();
- glDisable(GL_TEXTURE_2D);
+ GLSetupTexturing(false);
//glTranslate(0.375, 0.375, 0.0);
-#if !defined(__OLDX__)
- /*if(glBlendFuncSeparate)
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);*/
-#endif
-
}
void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
float s2dw,s2dh,d2sw,d2sh;
//bool flipX = false, flipY = false;
- //Logf("StretchDI\n");
-
if(Sgn(w) != Sgn(sw))
{
w = Abs(w);
if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
- glRasterPos2d(dx,dy);
- //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
- glPixelZoom(s2dw, -s2dh);
- glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
+#if ENABLE_GL_LEGACY
+ if(glCaps_legacy)
+ {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
+ glRasterPos2d(dx,dy);
+ //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
+ glPixelZoom(s2dw, -s2dh);
+ glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ }
+#endif
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
}
}
void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
{
- //Logf("BlitDI\n");
-
//Clip against the edges of the source
if(sx<0)
{
if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
- glRasterPos2d(dx,dy);
- glPixelZoom(1,-1);
- glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
+#if ENABLE_GL_LEGACY
+ if(glCaps_legacy)
+ {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
+ glRasterPos2d(dx,dy);
+ glPixelZoom(1,-1);
+ glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ }
+#endif
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
}
}
((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
}
- Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
+ Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
{
Font font;
OGLSystem oglSystem = displaySystem.driverData;
oglSystem.loadingFont = true;
- font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
+ font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
return font;
}
- void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
+ void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
{
- ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
+ ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
}
- void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
+ void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
{
- OGLSurface oglSurface = surface.driverData;
- OGLSystem oglSystem = display.displaySystem.driverData;
- oglSystem.loadingFont = true;
+ if(len && text[0] && surface.font)
+ {
+ OGLSurface oglSurface = surface.driverData;
+ OGLSystem oglSystem = display.displaySystem.driverData;
+ oglSystem.loadingFont = true;
+
+ //glTranslated(-0.375, -0.375, 0.0);
- //glTranslated(-0.375, -0.375, 0.0);
+ if(surface.textOpacity)
+ {
+ int w = 0, h, adv = 0;
+ FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
+ w += adv;
+ display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
+ }
- //Logf("Blit\n");
+ oglSurface.writingText = true;
- if(surface.textOpacity)
- {
- int w, h;
- FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
- display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
- }
+ GLSetupTexturing(true);
- oglSurface.writingText = true;
+ x <<= 6;
+ if(surface.font.outlineSize)
+ {
+ ColorAlpha outlineColor = surface.outlineColor;
+ int fx = x;
+
+ GLColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
+ oglSurface.writingOutline = true;
+ lastBlitTex = 0;
+ oglSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &fx, y, prevGlyph, rPrevGlyph, null);
+ if(lastBlitTex) GLEnd();
+ oglSurface.writingOutline = false;
+ }
+ GLColor4fv(oglSurface.foreground);
- glEnable(GL_TEXTURE_2D);
- glColor4fv(oglSurface.foreground);
+ lastBlitTex = 0;
+ oglSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &x, y, prevGlyph, rPrevGlyph, null);
- ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
- oglSurface.writingText = false;
- oglSystem.loadingFont = false;
+ if(lastBlitTex) GLEnd();
+ lastBlitTex = 0;
+
+ oglSurface.writingText = false;
+ oglSystem.loadingFont = false;
- glDisable(GL_TEXTURE_2D);
+ GLSetupTexturing(false);
- //glTranslated(0.375, 0.375, 0.0);
+ //glTranslated(0.375, 0.375, 0.0);
+ }
}
void TextFont(Display display, Surface surface, Font font)
oglSurface.opaqueText = opaque;
}
- void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
+ void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
{
OGLSurface oglSurface = surface.driverData;
OGLSystem oglSystem = display.displaySystem.driverData;
oglSystem.loadingFont = true;
- FontExtent(display.displaySystem, oglSurface.font, text, len, width, height);
+ FontExtent(display.displaySystem, oglSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
oglSystem.loadingFont = false;
}
void LineStipple(Display display, Surface surface, uint32 stipple)
{
- //Logf("Stipple\n");
-
if(stipple)
{
-#if defined(_GLES)
- stippleEnabled = true;
- glesLineStipple(1, (uint16)stipple);
-#else
- glLineStipple(1, (uint16)stipple);
- glEnable(GL_LINE_STIPPLE);
+#if ENABLE_GL_LEGACY
+ if(glCaps_legacy)
+ {
+ glLineStipple(1, (uint16)stipple);
+ glEnable(GL_LINE_STIPPLE);
+ }
+ else
#endif
+ {
+ stippleEnabled = true;
+ glsupLineStipple(1, (uint16)stipple);
+ }
}
else
{
-#if defined(_GLES)
- stippleEnabled = false;
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glDisable(GL_TEXTURE_2D);
-#else
- glDisable(GL_LINE_STIPPLE);
+#if ENABLE_GL_LEGACY
+ if(glCaps_legacy)
+ glDisable(GL_LINE_STIPPLE);
+ else
#endif
+ {
+ stippleEnabled = false;
+ GLMatrixMode(GL_TEXTURE);
+ GLLoadIdentity();
+ GLMatrixMode(MatrixMode::projection);
+ GLSetupTexturing(false); // TODO: Special shading code for stipple?
+ }
+ }
+ }
+#if ENABLE_GL_FFP
+ void ::disableRemainingTMUs(Display display, int lastTMU)
+ {
+ OGLDisplay oglDisplay = display.driverData;
+ int t;
+ for(t = lastTMU; t < oglDisplay.maxTMU; t++)
+ {
+ glActiveTexture(GL_TEXTURE0 + t);
+ glClientActiveTexture(GL_TEXTURE0 + t);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_CUBE_MAP);
+ GLDisableClientState(TEXCOORDS);
}
+ glActiveTexture(GL_TEXTURE0);
+ glClientActiveTexture(GL_TEXTURE0);
+ oglDisplay.maxTMU = lastTMU;
}
+#endif
+
#if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
void SetRenderState(Display display, RenderState state, uint value)
{
OGLDisplay oglDisplay = display.driverData;
- //Logf("RenderState\n");
-
switch(state)
{
case antiAlias:
+#ifndef __EMSCRIPTEN__
if(value)
- glEnable(GL_MULTISAMPLE_ARB);
+ glEnable(GL_MULTISAMPLE);
else
- glDisable(GL_MULTISAMPLE_ARB);
+ glDisable(GL_MULTISAMPLE);
+#endif
break;
case fillMode:
-#if !defined(_GLES)
- glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
+#if ENABLE_GL_LEGACY
+ if(glCaps_legacy)
+ glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
#endif
break;
case depthTest:
case fogColor:
{
float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
- glFogfv(GL_FOG_COLOR, (float *)&color);
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.setFogColor(color[0], color[1], color[2]);
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ glFogfv(GL_FOG_COLOR, (float *)&color);
+#endif
break;
}
case fogDensity:
- glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.setFogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
+#endif
break;
case blend:
+//#if !defined(__EMSCRIPTEN__)
if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
+//#endif
break;
case ambient:
{
- float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
+ }
+#endif
break;
}
case alphaWrite:
case vSync:
{
#if defined(__WIN32__)
- wglSwapIntervalEXT(value ? 1 : 0);
+ if(wglSwapIntervalEXT)
+ wglSwapIntervalEXT(value ? 1 : 0);
#endif
break;
}
void SetLight(Display display, int id, Light light)
{
- //Logf("SetLight\n");
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.setLight(display, id, light);
+#endif
- if(light != null)
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
{
- Object lightObject = light.lightObject;
- float position[4] = { 0, 0, 0, 0 };
- float color[4] = { 0, 0, 0, 1 };
+ if(light != null && !light.flags.off)
+ {
+ Object lightObject = light.lightObject;
+ float position[4] = { 0, 0, 0, 0 };
+ float color[4] = { 0, 0, 0, 1 };
+ Vector3D l;
- glEnable(GL_LIGHT0 + id);
- /*
- glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
- glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
- glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
- */
+ glEnable(GL_LIGHT0 + id);
- if(!light.multiplier) light.multiplier = 1.0f;
+ if(!light.multiplier) light.multiplier = 1.0f;
- color[0] = light.diffuse.r * light.multiplier;
- color[1] = light.diffuse.g * light.multiplier;
- color[2] = light.diffuse.b * light.multiplier;
- glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
+ GLFlushMatrices();
- color[0] = light.ambient.r * light.multiplier;
- color[1] = light.ambient.g * light.multiplier;
- color[2] = light.ambient.b * light.multiplier;
- glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
- color[0] = light.specular.r * light.multiplier;
- color[1] = light.specular.g * light.multiplier;
- color[2] = light.specular.b * light.multiplier;
- glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
+ color[0] = light.diffuse.r * light.multiplier;
+ color[1] = light.diffuse.g * light.multiplier;
+ color[2] = light.diffuse.b * light.multiplier;
+ glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
- if(lightObject)
- {
- Vector3D positionVector;
- if(light.flags.spot)
+ color[0] = light.ambient.r * light.multiplier;
+ color[1] = light.ambient.g * light.multiplier;
+ color[2] = light.ambient.b * light.multiplier;
+ glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
+
+ color[0] = light.specular.r * light.multiplier;
+ color[1] = light.specular.g * light.multiplier;
+ color[2] = light.specular.b * light.multiplier;
+ glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
+
+ if(lightObject)
{
- if(lightObject.flags.root || !lightObject.parent)
+ // Positional Lights, including Spot Lights (and omni light with flags.spot not set)
+ Matrix * mat = &lightObject.matrix;
+ l = { mat->m[3][0], mat->m[3][1], mat->m[3][2] };
+ if(display.display3D && display.display3D.camera)
+ l.Subtract(l, display.display3D.camera.cPosition);
+
+ position[0] = (float)l.x, position[1] = (float)l.y, position[2] = (float)l.z, position[3] = 1;
+
+ if(light.flags.attenuation)
{
- positionVector = lightObject.transform.position;
- positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
+ glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
+ glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
+ glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
}
else
{
- positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
- if(display.display3D.camera)
- positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
+ glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, 1);
+ glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, 0);
+ glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, 0);
}
- position[3] = 1;
- }
- else
- {
- if(!light.direction.x && !light.direction.y && !light.direction.z)
+
+ if((light.flags.spot && light.fallOff < 360) || (lightObject && (light.direction.x || light.direction.y || light.direction.z)))
{
- Vector3Df vector { 0,0,-1 };
- Matrix mat;
- mat.RotationQuaternion(light.orientation);
- positionVector.MultMatrixf(vector, mat);
+ // Figure out exponent out of the hot spot
+ #define MAXLIGHT 0.9
+ float exponent = light.flags.spot ? (float)(log(MAXLIGHT) / log(cos(light.hotSpot / 2))) : 1;
+ Degrees cutOff = light.flags.spot ? light.fallOff/2 : 90;
+ float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
+
+ glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
+ glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)cutOff);
+ glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
}
else
{
- positionVector = light.direction;
- position[3] = 1;
+ float d[4] = { 0, 0, 1, 0 };
+ glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, d);
+ glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, 180);
+ glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, 1);
}
- }
- position[0] = (float)positionVector.x;
- position[1] = (float)positionVector.y;
- position[2] = (float)positionVector.z;
-
- glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
+ /*
+ if(lightObject)
+ {
+ // Display Light Position
+ glDisable(GL_LIGHTING);
+ glDisable(GL_DEPTH_TEST);
+ glColor3f(1,1,1);
+ glPointSize(10);
+ glBegin(GL_POINTS);
+ glVertex3fv(position);
+ glEnd();
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_LIGHTING);
+
+
+ // Display Target
+ if(lightObject.flags.root || !lightObject.parent)
+ {
+ positionVector = light.target.transform.position;
+ positionVector.Subtract(positionVector, display.camera.cPosition);
+ }
+ else
+ {
+ positionVector.MultMatrix(light.target.transform.position,
+ lightObject.light.target.parent.matrix);
+ positionVector.Subtract(positionVector, display.camera.cPosition);
+ }
- /*
- // Display Light Position
- glDisable(GL_LIGHTING);
- glDisable(GL_DEPTH_TEST);
- glColor3f(1,1,1);
- glPointSize(10);
- glBegin(GL_POINTS);
- glVertex3fv(position);
- glEnd();
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
-
-
- // Display Target
- if(lightObject.flags.root || !lightObject.parent)
- {
- positionVector = light.target.transform.position;
- positionVector.Subtract(positionVector, display.camera.cPosition);
+ position[0] = positionVector.x;
+ position[1] = positionVector.y;
+ position[2] = positionVector.z;
+
+ glDisable(GL_LIGHTING);
+ glDisable(GL_DEPTH_TEST);
+ glColor3f(1,1,0);
+ glPointSize(10);
+ glBegin(GL_POINTS);
+ glVertex3fv(position);
+ glEnd();
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_LIGHTING);
+ }
+ */
}
else
{
- positionVector.MultMatrix(light.target.transform.position,
- lightObject.light.target.parent.matrix);
- positionVector.Subtract(positionVector, display.camera.cPosition);
+ // Directional Light
+ Vector3D vector { 0,0,-1 };
+ Vector3D direction;
+ Matrix mat;
+ mat.RotationQuaternion(light.orientation);
+ direction.MultMatrix(vector, mat);
+ l.Normalize(direction);
+ position[0] = (float)l.x, position[1] = (float)l.y, position[2] = (float)l.z, position[3] = 0;
}
-
- position[0] = positionVector.x;
- position[1] = positionVector.y;
- position[2] = positionVector.z;
-
- glDisable(GL_LIGHTING);
- glDisable(GL_DEPTH_TEST);
- glColor3f(1,1,0);
- glPointSize(10);
- glBegin(GL_POINTS);
- glVertex3fv(position);
- glEnd();
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
- */
-
- if(light.flags.attenuation)
- {
- glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
- glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
- glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
- }
-
- if(light.flags.spot)
+ glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
+ if(display.display3D)
{
- float exponent = 0;
- #define MAXLIGHT 0.9
- float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
- // Figure out exponent out of the hot spot
- exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
-
- glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
- glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
- glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
+ Matrix m;
+ Vector3Df v { position[0], position[1], position[2] };
+ Vector3Df l;
+ float * lp = display.display3D.light0Pos;
+ if(display.display3D.camera)
+ m = display.display3D.camera.viewMatrix;
+ else
+ m.Identity();
+ l.MultMatrix(v, m);
+ lp[0] = l.x;
+ lp[1] =-l.y;
+ lp[2] =-l.z;
+ lp[3] = position[3];
}
}
else
- {
-
- Vector3Df vector { 0,0,-1 };
- Vector3Df direction;
- Matrix mat;
-
- mat.RotationQuaternion(light.orientation);
- direction.MultMatrix(vector, mat);
-
- position[0] = direction.x;
- position[1] = direction.y;
- position[2] = direction.z;
-
- glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
- }
+ glDisable(GL_LIGHT0 + id);
}
- else
- glDisable(GL_LIGHT0 + id);
+#endif
}
void SetCamera(Display display, Surface surface, Camera camera)
{
OGLDisplay oglDisplay = display.driverData;
- //Logf("SetCamera\n");
- if(camera)
+ if(surface && camera)
{
int left = surface.box.left + surface.offset.x;
int top = surface.box.top + surface.offset.y;
// *** ViewPort ***
glViewport(x, y, w, h);
+ GLMatrixMode(MatrixMode::texture);
+ if(!display.display3D.camera)
+ GLPushMatrix();
+ GLLoadIdentity();
+
// *** Projection Matrix ***
+ GLMatrixMode(MatrixMode::projection);
if(!display.display3D.camera)
- glPushMatrix();
- else
- glMatrixMode(GL_PROJECTION);
+ GLPushMatrix();
+
if(display.display3D.collectingHits)
{
float pickX = display.display3D.pickX + surface.offset.x;
(h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
}
};
- glLoadMatrixd(pickMatrix.array);
+ GLLoadMatrixd(pickMatrix.array);
}
else
- glLoadIdentity();
- glFrustum(
+ GLLoadIdentity();
+ GLFrustum(
(left - origX) * camera.zMin / camera.focalX,
(right - origX) * camera.zMin / camera.focalX,
(bottom - origY) * camera.zMin / camera.focalY,
glDisable(GL_BLEND);
// *** Z Inverted Identity Matrix ***
- glMatrixMode(GL_MODELVIEW);
+ GLMatrixMode(MatrixMode::modelView);
if(!display.display3D.camera)
- glPushMatrix();
+ GLPushMatrix();
- glLoadIdentity();
+ GLLoadIdentity();
- glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
+ GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
// *** View Matrix ***
- glMultMatrixd(camera.viewMatrix.array);
+ GLMultMatrixd(camera.viewMatrix.array);
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ defaultShader.select();
+ defaultShader.setCamera(camera);
+ }
+#endif
// *** Lights ***
// ...
glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
- glShadeModel(GL_SMOOTH);
+
+ GLSetupLighting(true);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ glShadeModel(GL_SMOOTH);
+#endif
glDepthMask((byte)bool::true);
oglDisplay.depthWrite = true;
- glEnable(GL_MULTISAMPLE_ARB);
+#ifndef __EMSCRIPTEN__
+ glEnable(GL_MULTISAMPLE);
+#endif
}
- else if(display.display3D.camera)
+ else if(surface && display.display3D.camera)
{
+ nearPlane = 1;
oglDisplay.depthWrite = false;
glViewport(0,0,display.width,display.height);
- glDisable(GL_CULL_FACE);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_LIGHTING);
- glDisable(GL_FOG);
- glDisable(GL_TEXTURE_2D);
- glShadeModel(GL_FLAT);
- glEnable(GL_BLEND);
- glDisable(GL_MULTISAMPLE_ARB);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+
+ GLDisableClientState(COLORS);
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ GLDisableClientState(TANGENTS1);
+ GLDisableClientState(TANGENTS2);
+ }
+#endif
+ GLDisableClientState(NORMALS);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ GLDisableClientState(LIGHTVECTORS);
+#endif
+
+ // *** Restore 2D MODELVIEW Matrix ***
+ GLMatrixMode(MatrixMode::modelView);
+ GLPopMatrix();
+
+ // *** Restore 2D TEXTURE Matrix ***
+ GLMatrixMode(MatrixMode::texture);
+ GLPopMatrix();
+
+ // *** Restore 2D PROJECTION Matrix ***
+ GLMatrixMode(MatrixMode::projection);
+ GLPopMatrix();
+
+ // NOTE: We expect the 2D projection matrix to be the active one for GetSurface to call glOrtho()
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.select();
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ disableRemainingTMUs(display, 0);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ glDisable(GL_TEXTURE_CUBE_MAP);
+ #if _GLES
+ glDisable(GL_TEXTURE_GEN_STR);
+ #else
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ #endif
+ }
+#endif
+
+ GLSetupTexturing(false);
+ GLSetupLighting(false);
+ GLSetupFog(false);
- // *** Restore 2D MODELVIEW Matrix ***
- glPopMatrix();
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ defaultShader.setPerVertexColor(false);
+ defaultShader.setMaterial(null, 0);
+ }
+#endif
- // *** Restore 2D PROJECTION Matrix ***
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ glShadeModel(GL_FLAT);
+#endif
+ glEnable(GL_BLEND);
+#if !defined(__EMSCRIPTEN__)
+ glDisable(GL_MULTISAMPLE);
+#endif
}
-
- GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
}
void ApplyMaterial(Display display, Material material, Mesh mesh)
{
- //Logf("ApplyMaterial\n");
+ Shader shader = material.shader ? material.shader : defaultShader;
+ MaterialFlags flags = material.flags;
+#if ENABLE_GL_FFP
+ static int lastSeparate = 0;
+ int tmu = 0;
+ bool normalMapped = false;
+ OGLMesh oglMesh = mesh ? mesh.data : null;
+#endif
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders && shader)
+ shader.select();
+#endif
// Basic Properties
- if(material.flags.doubleSided)
+ if(flags.doubleSided)
{
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !flags.singleSideLight);
+#endif
glDisable(GL_CULL_FACE);
}
else
{
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
+#endif
glEnable(GL_CULL_FACE);
}
// Fog
- if(material.flags.noFog)
- glDisable(GL_FOG);
- else
- glEnable(GL_FOG);
+ GLSetupFog(!flags.noFog);
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ activeShader.setMaterial(material, mesh.flags);
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ if(material.bumpMap && mesh.lightVectors)
+ {
+ float color[4] = { 1,1,1,1 };
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu++);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
+ glDisable(GL_TEXTURE_CUBE_MAP);
+ glEnable(GL_TEXTURE_2D);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ if(0) //((DefaultShaderBits)defaultShader.state).debugging)
+ {
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
+ }
+
+ #if _GLES
+ glDisable(GL_TEXTURE_GEN_STR);
+ #else
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ #endif
+ glDisable(GL_LIGHTING);
+ lightingEnabled = false;
+ GLMatrixMode(GL_TEXTURE);
+ GLLoadIdentity();
+ if(material.uScale && material.vScale)
+ GLScalef(material.uScale, material.vScale, 1);
+ GLMatrixMode(MatrixMode::modelView);
+
+ if(flags.tile)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ }
+ else
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu);
+
+ normalMapped = true;
+
+ // Modulate base color
+ if(material.diffuse.r < 1 || material.diffuse.g < 1 || material.diffuse.b < 1)
+ {
+ tmu++;
+ glDisable(GL_TEXTURE_CUBE_MAP);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+
+ color[0] = material.diffuse.r, color[1] = material.diffuse.g, color[2] = material.diffuse.b, color[3] = 1.0;
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu);
+ }
+
+ // Add ambient light
+ {
+ ColorRGB ambient { material.ambient.r * 0.2f, material.ambient.g * 0.2f, material.ambient.g * 0.2f };
+ if(ambient.r > 0 || ambient.g > 0 || ambient.b > 0)
+ {
+ tmu++;
+ glDisable(GL_TEXTURE_CUBE_MAP);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+
+ color[0] = ambient.r, color[1] = ambient.g, color[2] = ambient.b, color[3] = 1.0;
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu);
+ }
+ }
+ }
+ else
+ {
+ GLDisableClientState(LIGHTVECTORS);
+ if(!lightingEnabled)
+ {
+ glEnable(GL_LIGHTING);
+ lightingEnabled = true;
+ }
+ }
+ }
+#endif
// Maps
- if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
+ if(flags.cubeMap || (material.baseMap && (mesh.texCoords || mesh.flags.texCoords1)))
{
Bitmap map = material.baseMap;
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
+ int diffuseTarget = flags.cubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- if(material.uScale && material.vScale)
- glScalef(material.uScale, material.vScale, 1);
- glMatrixMode(GL_MODELVIEW);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu++);
+ glEnable(diffuseTarget);
+ glDisable(flags.cubeMap ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP);
+ }
+#endif
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders && !flags.cubeMap)
+ GLSetupTexturing(true);
+#endif
+
+ glBindTexture(diffuseTarget, (GLuint)(uintptr)map.driverData);
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ /* // This did not have the desired effect with a GL_ALPHA texture
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+ */
+
+ if(flags.cubeMap)
+ {
+ #if _GLES
+ glEnable(GL_TEXTURE_GEN_STR);
+ // GL_OBJECT_LINEAR: No extension support?
+ // glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ #else
+ GLfloat xPlane[] = { 1.0f, 0.0f, 0.0f, 0 };
+ GLfloat yPlane[] = { 0.0f,-1.0f, 0.0f, 0 };
+ GLfloat zPlane[] = { 0.0f, 0.0f,-1.0f, 0 };
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_R, GL_OBJECT_PLANE, zPlane);
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, xPlane);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, yPlane);
+
+ glEnable(GL_TEXTURE_GEN_R);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ #endif
+
+ GLDisableClientState(TEXCOORDS);
+ }
+ else
+ {
+ #if _GLES
+ glDisable(GL_TEXTURE_GEN_STR);
+ #else
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ #endif
- if(material.flags.tile)
+ if(tmu > 1)
+ oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
+ GLEnableClientState(TEXCOORDS);
+ }
+ glClientActiveTexture(GL_TEXTURE0);
+ }
+#endif
+ if(flags.tile)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
else
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
else
- glDisable(GL_TEXTURE_2D);
+ {
+ GLSetupTexturing(false);
+ }
- if(mesh.flags.colors)
+#if ENABLE_GL_FFP && !defined(_GLES)
+ if(!glCaps_shaders)
{
- glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
+ int separate = material.flags.separateSpecular ? GL_SEPARATE_SPECULAR_COLOR : GL_SINGLE_COLOR;
+ if(separate != lastSeparate)
+ {
+ GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, separate);
+ lastSeparate = separate;
+ }
}
- else
+#endif
+
+ if((flags.cubeMap && material.baseMap) ||
+ (mesh.texCoords && (material.baseMap || material.bumpMap || material.specularMap || material.reflectMap)))
{
- glDisable(GL_COLOR_MATERIAL);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
{
- float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
+ glActiveTexture(GL_TEXTURE0 + tmu - 1);
+ glClientActiveTexture(GL_TEXTURE0 + tmu - 1);
}
+#endif
+ GLMatrixMode(GL_TEXTURE);
+ GLLoadIdentity();
+ if(material.uScale && material.vScale)
+ GLScalef(material.uScale, material.vScale, 1);
+ GLMatrixMode(MatrixMode::modelView);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
{
- float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
+ glActiveTexture(GL_TEXTURE0);
+ glClientActiveTexture(GL_TEXTURE0);
}
+#endif
}
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
{
- float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
+ if(material.envMap && material.refractiveIndex)
+ {
+ float color[4] = { material.opacity, material.opacity, material.opacity, 1.0 };
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu++);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, (GLuint)(uintptr)material.envMap.driverData);
+ glEnable(GL_TEXTURE_CUBE_MAP);
+ #if _GLES
+ glEnable(GL_TEXTURE_GEN_STR);
+ glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ #else
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glEnable(GL_TEXTURE_GEN_R);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ #endif
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+ if(normalMapped)
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ else
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+
+ if(!normalMapped)
+ {
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
+ }
+
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
+
+ GLMatrixMode(MatrixMode::texture);
+ {
+ double * s = display.display3D.camera.viewMatrix.array;
+ double k = 2.0;
+ Matrix m
+ { {
+ k*s[0],-k*s[4],-k*s[8], 0,
+ k*s[1],-k*s[5],-k*s[9], 0,
+ k*s[2],-k*s[6],-k*s[10],0,
+ 0,0,0,1
+ } };
+ GLLoadMatrixd(m.array);
+ }
+ GLMatrixMode(MatrixMode::modelView);
+ }
+
+ if(material.envMap && material.reflectivity)
+ {
+ float color[4] = { 1.0f - material.reflectivity, 1.0f - material.reflectivity, 1.0f - material.reflectivity, 1.0 };
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu++);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, (GLuint)(uintptr)material.envMap.driverData);
+ glEnable(GL_TEXTURE_CUBE_MAP);
+ #if _GLES
+ glEnable(GL_TEXTURE_GEN_STR);
+ glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ #else
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glEnable(GL_TEXTURE_GEN_R);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ #endif
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+ if(normalMapped)
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ else
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+
+ if(!normalMapped)
+ {
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
+ }
+
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
+
+ GLMatrixMode(MatrixMode::texture);
+ {
+ double * s = display.display3D.camera.inverseTranspose.array;
+ Matrix m
+ { {
+ s[0],s[1],-s[2],0,
+ s[4],-s[5],-s[6],0,
+ -s[8],s[9],s[10],0,
+ 0,0,0,1
+ } };
+ GLLoadMatrixd(m.array);
+ }
+ GLMatrixMode(MatrixMode::modelView);
+ }
}
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
{
- float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
- }
+ disableRemainingTMUs(display, tmu);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
+ if(mesh.flags.colors)
+ {
+ GLColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+ }
+ else
+ {
+ glDisable(GL_COLOR_MATERIAL);
+ {
+ float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
+ }
+ {
+ float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
+ }
+ }
+ if(material.power > 0.1)
+ {
+ float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
+ }
+ else
+ {
+ float color[4] = { 0,0,0,0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
+ }
+ {
+ float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
+ }
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
+ }
+#endif
}
void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
OGLMesh oglMesh = mesh.data;
if(oglMesh)
{
+ OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
+ SETCAPS(oglSystem.capabilities);
+
if(!mesh.flags.vertices)
{
- if(oglMesh.vertices)
- {
- GLDeleteBuffers(1, &oglMesh.vertices);
- oglMesh.vertices = 0;
- }
+ oglMesh.vertices.free();
delete mesh.vertices;
}
if(!mesh.flags.normals)
{
- if(oglMesh.normals)
- {
- GLDeleteBuffers(1, &oglMesh.normals);
- oglMesh.normals = 0;
- }
+ oglMesh.normals.free();
delete mesh.normals;
}
+ if(!mesh.flags.tangents)
+ {
+ oglMesh.tangents.free();
+ delete mesh.tangents;
+ }
+ if(!mesh.flags.lightVectors)
+ {
+ oglMesh.lightVectors.free();
+ delete mesh.lightVectors;
+ }
if(!mesh.flags.texCoords1)
{
- if(oglMesh.texCoords)
- {
- GLDeleteBuffers(1, &oglMesh.texCoords);
- oglMesh.texCoords = 0;
- }
+ oglMesh.texCoords.free();
delete mesh.texCoords;
}
if(!mesh.flags.texCoords2)
{
- if(oglMesh.texCoords2)
- {
- GLDeleteBuffers(1, &oglMesh.texCoords2);
- oglMesh.texCoords2 = 0;
- }
- /*
- delete mesh.texCoords2;
- */
+ oglMesh.texCoords2.free();
+ // delete mesh.texCoords2;
}
if(!mesh.flags.colors)
{
- if(oglMesh.colors)
- {
- GLDeleteBuffers(1, &oglMesh.colors);
- oglMesh.colors = 0;
- }
+ oglMesh.colors.free();
+ delete mesh.colors;
}
if(!mesh.flags)
{
delete oglMesh;
mesh.data = null;
}
+ SETCAPS(caps);
}
}
mesh.data = OGLMesh { };
if(mesh.data)
{
- OGLMesh oglMesh = mesh.data;
if(mesh.nVertices == nVertices)
{
// Same number of vertices, adding features (Leaves the other features pointers alone)
}
else
mesh.vertices = new Vector3Df[nVertices];
- if(!oglMesh.vertices)
- GLGenBuffers(1, &oglMesh.vertices);
}
if(!mesh.flags.normals && flags.normals)
{
}
else
mesh.normals = new Vector3Df[nVertices];
- if(!oglMesh.normals)
- GLGenBuffers( 1, &oglMesh.normals);
+ }
+ if(!mesh.flags.tangents && flags.tangents)
+ {
+ mesh.tangents = new Vector3Df[2*nVertices];
+ }
+ if(!mesh.flags.lightVectors && flags.lightVectors)
+ {
+ mesh.lightVectors = new ColorRGB[nVertices];
}
if(!mesh.flags.texCoords1 && flags.texCoords1)
{
mesh.texCoords = new Pointf[nVertices];
- if(!oglMesh.texCoords)
- GLGenBuffers( 1, &oglMesh.texCoords);
}
if(!mesh.flags.colors && flags.colors)
{
mesh.colors = new ColorRGBAf[nVertices];
- if(!oglMesh.colors)
- GLGenBuffers( 1, &oglMesh.colors);
}
}
}
}
else
mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
- if(!oglMesh.vertices)
- GLGenBuffers(1, &oglMesh.vertices);
}
if(flags.normals)
{
}
else
mesh.normals = renew mesh.normals Vector3Df[nVertices];
- if(!oglMesh.normals)
- GLGenBuffers( 1, &oglMesh.normals);
}
if(flags.texCoords1)
{
mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
- if(!oglMesh.texCoords)
- GLGenBuffers( 1, &oglMesh.texCoords);
}
if(flags.colors)
{
mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
- if(!oglMesh.colors)
- GLGenBuffers( 1, &oglMesh.colors);
+ }
+ if(flags.tangents)
+ {
+ mesh.tangents = renew mesh.tangents Vector3Df[2 * nVertices];
+ }
+ if(flags.lightVectors)
+ {
+ mesh.lightVectors = renew mesh.lightVectors ColorRGB[nVertices];
}
}
result = true;
void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
{
- OGLMesh oglMesh = mesh.data;
- if(!flags) flags = mesh.flags;
+ OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
+ SETCAPS(oglSystem.capabilities);
- if(vboAvailable)
+ if(glCaps_vertexBuffer)
{
- if(flags.vertices && oglMesh.vertices)
- {
- GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices);
- 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 );
- }
+ OGLMesh oglMesh = mesh.data;
+ if(!flags) flags = mesh.flags;
+ if(flags.vertices)
+ oglMesh.vertices.allocate(
+ mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, staticDraw);
- if(flags.normals && oglMesh.normals)
- {
- GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
- 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 );
- }
+ if(flags.normals)
+ oglMesh.normals.allocate(
+ mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, staticDraw);
- if(flags.texCoords1 && oglMesh.texCoords)
- {
- GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
- GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(Pointf), mesh.texCoords, GL_STATIC_DRAW_ARB );
- }
+ if(flags.texCoords1)
+ oglMesh.texCoords.allocate(
+ mesh.nVertices * sizeof(Pointf), mesh.texCoords, staticDraw);
- if(flags.colors && oglMesh.colors)
- {
- GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
- GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, GL_STATIC_DRAW_ARB );
- }
+ if(flags.colors)
+ oglMesh.colors.allocate(
+ mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, staticDraw);
- GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
+ if(flags.tangents)
+ oglMesh.tangents.allocate(mesh.nVertices * 2*sizeof(Vector3Df), mesh.tangents, staticDraw);
+
+ if(flags.lightVectors)
+ oglMesh.lightVectors.allocate(mesh.nVertices * sizeof(ColorRGB), mesh.lightVectors, staticDraw);
}
+ SETCAPS(caps);
}
bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
{
bool result = true;
- return result;
+ return result;
}
void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
{
+ OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
+ SETCAPS(oglSystem.capabilities);
+
if(oglIndices)
{
- if(oglIndices.buffer)
- GLDeleteBuffers(1, &oglIndices.buffer);
+ oglIndices.buffer.free();
delete oglIndices.indices;
delete oglIndices;
}
+ SETCAPS(caps);
}
void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
if(oglIndices)
{
oglIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
- GLGenBuffers( 1, &oglIndices.buffer);
oglIndices.nIndices = nIndices;
}
return oglIndices;
void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
{
- if(vboAvailable)
+ OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
+ SETCAPS(oglSystem.capabilities);
+
+ if(glCaps_vertexBuffer)
{
- GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
- GLBufferData( indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, GL_ELEMENT_ARRAY_BUFFER_ARB, nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
- oglIndices.indices, GL_STATIC_DRAW_ARB);
- GLBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ if(!glCaps_intAndDouble && indices32bit)
+ {
+ if(!oglIndices.buffer.buffer)
+ glGenBuffers(1, &oglIndices.buffer.buffer);
+ if(glabCurElementBuffer != oglIndices.buffer.buffer)
+ GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
+
+ {
+ uint * pointer = (uint *)oglIndices.indices;
+ int i;
+ uint16 * b;
+ if(nIndices > oglSystem.shortBDSize)
+ {
+ oglSystem.shortBDSize = nIndices;
+ oglSystem.shortBDBuffer = renew oglSystem.shortBDBuffer uint16[oglSystem.shortBDSize];
+ }
+ b = oglSystem.shortBDBuffer;
+ for(i = 0; i < nIndices; i++)
+ b[i] = (uint16)pointer[i];
+
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, nIndices * sizeof(uint16), b, GL_STATIC_DRAW);
+ }
+ }
+ else
+ oglIndices.buffer.allocate(
+ nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
+ oglIndices.indices, staticDraw);
}
+ SETCAPS(caps);
}
uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
void SelectMesh(Display display, Mesh mesh)
{
- //Logf("SelectMesh\n");
-
-#if !defined( __ANDROID__) && !defined(__APPLE__)
-
+#if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
#if defined(__WIN32__)
if(glUnlockArraysEXT)
#endif
- if(!vboAvailable && display.display3D.mesh)
+ if(!glCaps_vertexBuffer && display.display3D.mesh)
glUnlockArraysEXT();
-
#endif
if(mesh)
{
OGLMesh oglMesh = mesh.data;
// *** Vertex Stream ***
- glEnableClientState(GL_VERTEX_ARRAY);
+ GLEnableClientState(VERTICES);
if(!display.display3D.collectingHits && oglMesh)
{
- GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices );
- if(mesh.flags.doubleVertices)
- glVertexPointerd(3, 0, (double *)(vboAvailable ? null : mesh.vertices), mesh.nVertices);
- else
- glVertexPointer(3, GL_FLOAT, 0, vboAvailable ? null : mesh.vertices);
+ oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
// *** Normals Stream ***
if(mesh.normals || mesh.flags.normals)
{
- glEnableClientState(GL_NORMAL_ARRAY);
- GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
- glNormalPointer(/*mesh.flags.doubleNormals ? GL_DOUBLE : */GL_FLOAT, 0, vboAvailable ? null : mesh.normals);
+ GLEnableClientState(NORMALS);
+ oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
}
else
- glDisableClientState(GL_NORMAL_ARRAY);
+ GLDisableClientState(NORMALS);
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ // *** Tangents Stream ***
+ if(mesh.tangents || mesh.flags.tangents)
+ {
+ GLEnableClientState(TANGENTS1);
+ GLEnableClientState(TANGENTS2);
+ oglMesh.tangents.use(tangent1, 3, GL_FLOAT, sizeof(Vector3Df)*2, oglMesh.tangents.buffer ? null : mesh.tangents);
+ oglMesh.tangents.use(tangent2, 3, GL_FLOAT, sizeof(Vector3Df)*2, oglMesh.tangents.buffer ? (void *)sizeof(Vector3Df) : mesh.tangents+1);
+ }
+ else
+ {
+ GLDisableClientState(TANGENTS1);
+ GLDisableClientState(TANGENTS2);
+ }
+ }
+#endif
// *** Texture Coordinates Stream ***
if(mesh.texCoords || mesh.flags.texCoords1)
{
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
- glTexCoordPointer(2, GL_FLOAT, 0, vboAvailable ? null : mesh.texCoords);
+ GLEnableClientState(TEXCOORDS);
+ oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
}
else
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ GLDisableClientState(TEXCOORDS);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ // *** Normal Map Aligned Light Vector ***
+ if(mesh.lightVectors || mesh.flags.lightVectors)
+ {
+ GLEnableClientState(LIGHTVECTORS);
+ oglMesh.lightVectors.use(lightVector, 3, GL_FLOAT, 0, oglMesh.lightVectors.buffer ? null : mesh.lightVectors);
+ }
+ else
+ GLDisableClientState(LIGHTVECTORS);
+ }
+ else
+#endif
// *** Color Stream ***
if(mesh.colors || mesh.flags.colors)
{
- glEnableClientState(GL_COLOR_ARRAY);
- GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
- glColorPointer(4, GL_FLOAT, 0, vboAvailable ? null : mesh.colors);
+ GLEnableClientState(COLORS);
+ oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
}
else
- glDisableClientState(GL_COLOR_ARRAY);
-
+ GLDisableClientState(COLORS);
}
else
{
- GLBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
- if(mesh.flags.doubleVertices)
- glVertexPointerd(3, 0, (double *)mesh.vertices, mesh.nVertices);
- else
- glVertexPointer(3, GL_FLOAT, 0, mesh.vertices);
+ noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
{
- glEnableClientState(GL_NORMAL_ARRAY);
- glNormalPointer(/*mesh.flags.doubleNormals ? GL_DOUBLE : */GL_FLOAT, 0, mesh.normals);
+ GLEnableClientState(NORMALS);
+ noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
}
else
- glDisableClientState(GL_NORMAL_ARRAY);
+ GLDisableClientState(NORMALS);
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ if((mesh.tangents || mesh.flags.tangents) && !display.display3D.collectingHits)
+ {
+ GLEnableClientState(TANGENTS1);
+ GLEnableClientState(TANGENTS2);
+ noAB.use(tangent1, 3, GL_FLOAT, sizeof(Vector3Df)*2, mesh.tangents);
+ noAB.use(tangent2, 3, GL_FLOAT, sizeof(Vector3Df)*2, mesh.tangents+1);
+ }
+ else
+ {
+ GLDisableClientState(TANGENTS1);
+ GLDisableClientState(TANGENTS2);
+ }
+ }
+#endif
+
if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
{
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 0, mesh.texCoords);
+ GLEnableClientState(TEXCOORDS);
+ noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
+ }
+ else
+ GLDisableClientState(TEXCOORDS);
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ if((mesh.lightVectors || mesh.flags.lightVectors) && !display.display3D.collectingHits)
+ {
+ GLEnableClientState(LIGHTVECTORS);
+ noAB.use(lightVector, 3, GL_FLOAT, sizeof(ColorRGB), mesh.lightVectors);
+ }
+ else
+ GLDisableClientState(LIGHTVECTORS);
}
else
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+#endif
if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
{
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(4, GL_FLOAT, 0, mesh.colors);
+ GLEnableClientState(COLORS);
+ noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
}
else
- glDisableClientState(GL_COLOR_ARRAY);
+ GLDisableClientState(COLORS);
}
-#if !defined(__ANDROID__) && !defined(__APPLE__)
+#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
#if defined(__WIN32__)
if(glLockArraysEXT)
#endif
- if(!vboAvailable)
+ if(!glCaps_vertexBuffer)
glLockArraysEXT(0, mesh.nVertices);
-
#endif
}
- else
- GLBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
}
void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
{
- //Logf("DrawPrimitives\n");
-
if(primitive->type.vertexRange)
- glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
+ {
+ GLFlushMatrices();
+ glDrawArrays(getPrimitiveType(primitive->type.primitiveType), primitive->first, primitive->nVertices);
+ }
else
{
- // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
- // HACK TO SPEED THINGS UP...
-#ifndef __ANDROID__
- /*GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
- if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
- {
- int c;
- glBegin(primitiveTypes[primitive->type.primitiveType]);
- if(primitive->data)
- {
- OGLIndices oglIndices = primitive->data;
- MeshFeatures flags = mesh.flags;
- for(c = 0; c<primitive->nIndices; c++)
- {
- uint16 index = ((uint16 *) oglIndices.indices)[c];
- if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
- if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
- if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
- glVertex3fv((float *)&mesh.vertices[index]);
- }
- }
- glEnd();
- }
- else*/
-#endif
+ OGLIndices oglIndices = primitive->data;
+ GLEAB eab = ((!display.display3D.collectingHits && oglIndices && glCaps_vertexBuffer) ? oglIndices.buffer : noEAB);
+ if(!glCaps_intAndDouble && !glCaps_vertexBuffer && primitive->type.indices32bit)
{
- OGLIndices oglIndices = primitive->data;
-
- if(!display.display3D.collectingHits && vboAvailable && oglIndices)
- {
- GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, oglIndices.buffer);
- if(primitive->type.indices32bit)
- glDrawElementsi(primitiveTypes[primitive->type.primitiveType], primitive->nIndices, 0);
- else
- glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices, GL_UNSIGNED_SHORT, 0);
- GLBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
- }
- else
- {
- if(primitive->type.indices32bit)
- glDrawElementsi(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
- oglIndices ? oglIndices.indices : primitive->indices);
- else
- glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
- GL_UNSIGNED_SHORT, oglIndices ? oglIndices.indices : primitive->indices);
- }
+ uint16 * temp = new uint16[primitive->nIndices];
+ uint32 * src = (uint32 *)(oglIndices ? oglIndices.indices : primitive->indices);
+ int i;
+ for(i = 0; i < primitive->nIndices; i++)
+ temp[i] = (uint16)src[i];
+ eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices, GL_UNSIGNED_SHORT, temp);
+ delete temp;
}
+ else
+ eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices,
+ primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
+ eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
+ GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
}
void PushMatrix(Display display)
{
- glPushMatrix();
+ GLPushMatrix();
}
void PopMatrix(Display display, bool setMatrix)
{
- glPopMatrix();
+ GLPopMatrix();
}
void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
if(viewSpace)
{
- glLoadIdentity();
- glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
+ GLLoadIdentity();
+ GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
}
else if(camera)
{
- glTranslated(
+ GLTranslated(
matrix.m[3][0] - camera.cPosition.x,
matrix.m[3][1] - camera.cPosition.y,
matrix.m[3][2] - camera.cPosition.z);
}
else
- glTranslated(
+ GLTranslated(
matrix.m[3][0],
matrix.m[3][1],
matrix.m[3][2]);
matrix.m[3][1] = 0;
matrix.m[3][2] = 0;
- glMultMatrixd(matrix.array);
+ GLMultMatrixd(matrix.array);
}
#endif
}
#if defined(__WIN32__)
OGLSystem system = displaySystem.driverData;
return system.glrc;
-#elif !defined(__ANDROID__)
+#elif defined(__ANDROID__) || defined(__ODROID__)
+ return eglContext;
+#elif defined(__EMSCRIPTEN__)
OGLSystem system = displaySystem.driverData;
- return system.glContext;
+ return (void *)system.glc;
#else
- return eglContext;
+ OGLSystem system = displaySystem.driverData;
+ return system.glContext;
#endif
}
return null;