diff --git a/bin/assets/ui/breeze.css b/bin/assets/ui/breeze.css index 9cbf2c076..0e03ea909 100644 --- a/bin/assets/ui/breeze.css +++ b/bin/assets/ui/breeze.css @@ -248,7 +248,9 @@ pushbutton:disabled, selectbutton:disabled, textinput:disabled, textedit:disabled, -textarea:disabled { +textarea:disabled, +DropDownList:disabled, +DropDownModelList:disabled { color: var(--disabled-color); border-color: var(--disabled-border); } diff --git a/include/eepp/config.hpp b/include/eepp/config.hpp index 3e08a7de9..ad960ba4a 100644 --- a/include/eepp/config.hpp +++ b/include/eepp/config.hpp @@ -195,8 +195,8 @@ #endif #if ( EE_PLATFORM == EE_PLATFORM_WIN || EE_PLATFORM == EE_PLATFORM_MACOS || \ - defined( EE_X11_PLATFORM ) ) && \ - !defined( EE_GLES ) + defined( EE_X11_PLATFORM ) ) && \ + !defined( EE_GLES ) && defined( EE_ENABLE_GLEW ) #define EE_GLEW_AVAILABLE #endif @@ -317,9 +317,9 @@ typedef unsigned long long Uint64; #endif #if defined( __x86_64__ ) || defined( _M_X64 ) - #define EE_ARCH_X86_64 +#define EE_ARCH_X86_64 #elif defined( __aarch64__ ) || defined( _M_ARM64 ) - #define EE_ARCH_ARM64 +#define EE_ARCH_ARM64 #endif #if defined( EE_LINUX_64 ) || defined( EE_SPARC_64 ) || defined( __osf__ ) || \ diff --git a/include/eepp/core/utf.hpp b/include/eepp/core/utf.hpp index 4eabebcaf..e18b5e33a 100644 --- a/include/eepp/core/utf.hpp +++ b/include/eepp/core/utf.hpp @@ -668,6 +668,20 @@ template <> class Utf<32> { //////////////////////////////////////////////////////////// template static Uint32 decodeWide( In input ); + //////////////////////////////////////////////////////////// + /// \brief Decode wide characters to UTF-32 + /// + /// This function does not exist in other specializations + /// of efsw::Utf<>, it is defined for convenience (it is used by + /// several other conversion functions). + /// + /// \param input Input wide character + /// + /// \return Converted character + /// + //////////////////////////////////////////////////////////// + template static Uint32 decodeWide( In& it, In end ); + //////////////////////////////////////////////////////////// /// \brief Encode a single UTF-32 character to ANSI /// diff --git a/include/eepp/core/utf.inl b/include/eepp/core/utf.inl index 2573f8a43..b83756021 100644 --- a/include/eepp/core/utf.inl +++ b/include/eepp/core/utf.inl @@ -484,7 +484,7 @@ template Out Utf<32>::fromWide(In begin, In end, Out output) { while (begin < end) - *output++ = decodeWide(*begin++); + *output++ = decodeWide(begin, end); return output; } @@ -594,13 +594,69 @@ Uint32 Utf<32>::decodeAnsi(In input, const std::locale& locale) template Uint32 Utf<32>::decodeWide(In input) { - // The encoding of wide characters is not well defined and is left to the system; - // however we can safely assume that it is UCS-2 on Windows and - // UCS-4 on Unix systems. - // In both cases, a simple copy is enough (UCS-2 is a subset of UCS-4, - // and UCS-4 *is* UTF-32). + // We have no context to combine surrogate pairs, so the only safe thing on a 16‑bit wchar_t + // platform is to reject surrogate code units. + const Uint32 replacement = 0xFFFD; + const Uint32 code = static_cast( input ); - return input; +#if WCHAR_MAX == 0xFFFF + // UTF-16: Reject surrogate code units + if ( code >= 0xD800u && code <= 0xDFFFu ) + return replacement; // Cannot form a full code point here +#else + // UTF-32: emit single wchar_t codepoint + if ( code > 0x10FFFFu || ( code >= 0xD800u && code <= 0xDFFFu ) ) + return replacement; +#endif + + return code; +} + +template Uint32 Utf<32>::decodeWide(In& it, In end) { + // The encoding of wide characters is not well defined and is left to the system; + // Previously we assumed + // UCS-2 on Windows and UCS-4 on Unix and just copied wchar_t to UTF-32, + // which broke for characters outside the BMP (surrogate pairs were copied + // as invalid code points). Treat 16-bit wchar_t as UTF-16 (handling + // surrogates) and 32-bit wchar_t as UTF-32 with validation, producing valid + // Unicode values in all cases. + + const Uint32 replacement = 0xFFFD; + +#if WCHAR_MAX == 0xFFFF + // UTF-16 + const Uint32 w1 = static_cast( *it++ ); + + if ( w1 >= 0xD800u && w1 <= 0xDBFFu ) { + // High surrogate + if ( it != end ) { + const Uint32 w2 = static_cast( *it ); + if ( w2 >= 0xDC00u && w2 <= 0xDFFFu ) { + // Valid surrogate pair + ++it; + return 0x10000u + ( ( w1 - 0xD800u ) << 10 ) + ( w2 - 0xDC00u ); + } + } + // Unpaired or invalid second unit + return replacement; + } else if ( w1 >= 0xDC00u && w1 <= 0xDFFFu ) { + // Unpaired low surrogate + return replacement; + } else { + // BMP code point + return w1; + } +#else + // UTF-32: emit single wchar_t codepoint + const Uint32 code = static_cast( *it++ ); + + // Validate scalar value + if ( code > 0x10FFFFu || ( code >= 0xD800u && code <= 0xDFFFu ) ) { + return replacement; + } + + return code; +#endif } template @@ -641,36 +697,58 @@ Out Utf<32>::encodeAnsi(Uint32 codepoint, Out output, char replacement, const st #ifndef EE_NO_WIDECHAR template -Out Utf<32>::encodeWide(Uint32 codepoint, Out output, wchar_t replacement) -{ +Out Utf<32>::encodeWide(Uint32 codepoint, Out output, wchar_t replacement) { // The encoding of wide characters is not well defined and is left to the system; - // however we can safely assume that it is UCS-2 on Windows and - // UCS-4 on Unix systems. - // For UCS-2 we need to check if the source characters fits in (UCS-2 is a subset of UCS-4). - // For UCS-4 we can do a direct copy (UCS-4 *is* UTF-32). + // Previously we assumed + // UCS-2 on Windows and UCS-4 on Unix and just copied wchar_t to UTF-32, + // which broke for characters outside the BMP (surrogate pairs were copied + // as invalid code points). Treat 16-bit wchar_t as UTF-16 (handling + // surrogates) and 32-bit wchar_t as UTF-32 with validation, producing valid + // Unicode values in all cases. + +#if WCHAR_MAX == 0xFFFF + // UTF-16 + if ( codepoint <= 0xFFFF ) { + // Exclude surrogate range + if ( codepoint < 0xD800 || codepoint > 0xDFFF ) { + *output++ = static_cast( codepoint ); + } else { + // Invalid code point -> replacement + if ( replacement ) { + + - switch (sizeof(wchar_t)) - { - case 4: - { - *output++ = static_cast(codepoint); - break; - } - default: - { - if ((codepoint <= 0xFFFF) && ((codepoint < 0xD800) || (codepoint > 0xDFFF))) - { - *output++ = static_cast(codepoint); - } - else if (replacement) - { *output++ = replacement; } - break; + } + } else if ( codepoint <= 0x10FFFF ) { + // Encode surrogate pair + codepoint -= 0x10000; + + wchar_t high = 0xD800 + ( codepoint >> 10 ); + wchar_t low = 0xDC00 + ( codepoint & 0x3FF ); + + *output++ = high; + *output++ = low; + } else { + // Invalid Unicode range + if ( replacement ) { + *output++ = replacement; } } +#else + // UTF-32: emit single wchar_t codepoint + // Validate code point for UCS-4 + if ( codepoint <= 0x10FFFF && !( codepoint >= 0xD800 && codepoint <= 0xDFFF ) ) { + // Direct copy + *output++ = static_cast( codepoint ); + } else if ( replacement ) { + *output++ = replacement; + } +#endif + return output; } #endif diff --git a/include/eepp/graphics/renderer/opengl.hpp b/include/eepp/graphics/renderer/opengl.hpp index 68dc78233..6eaaba95f 100644 --- a/include/eepp/graphics/renderer/opengl.hpp +++ b/include/eepp/graphics/renderer/opengl.hpp @@ -16,9 +16,13 @@ #include #else #if EE_PLATFORM == EE_PLATFORM_WIN +#ifndef APIENTRY #define APIENTRY __stdcall +#endif +#ifndef WINGDIAPI #define WINGDIAPI __declspec( dllimport ) #endif +#endif #include #endif @@ -28,9 +32,123 @@ #include #elif EE_PLATFORM == EE_PLATFORM_MACOS #include +#elif EE_PLATFORM == EE_PLATFORM_HAIKU || EE_PLATFORM == EE_PLATFORM_BSD || \ + EE_PLATFORM == EE_PLATFORM_SOLARIS +#include +#elif EE_PLATFORM == EE_PLATFORM_WIN +typedef char GLchar; #endif #endif +#ifndef GL_TEXTURE0 +#define GL_TEXTURE0 0x84C0 +#endif +#ifndef GL_COMPRESSED_RGBA +#define GL_COMPRESSED_RGBA 0x84EE +#endif +#ifndef GL_TEXTURE_COMPRESSED_IMAGE_SIZE +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#endif +#ifndef GL_TEXTURE_COMPRESSED +#define GL_TEXTURE_COMPRESSED 0x86A1 +#endif +#ifndef GL_ARRAY_BUFFER +#define GL_ARRAY_BUFFER 0x8892 +#endif +#ifndef GL_ELEMENT_ARRAY_BUFFER +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#endif +#ifndef GL_STREAM_DRAW +#define GL_STREAM_DRAW 0x88E0 +#endif +#ifndef GL_STATIC_DRAW +#define GL_STATIC_DRAW 0x88E4 +#endif +#ifndef GL_DYNAMIC_DRAW +#define GL_DYNAMIC_DRAW 0x88E8 +#endif +#ifndef GL_FRAGMENT_SHADER +#define GL_FRAGMENT_SHADER 0x8B30 +#endif +#ifndef GL_VERTEX_SHADER +#define GL_VERTEX_SHADER 0x8B31 +#endif +#ifndef GL_COMPILE_STATUS +#define GL_COMPILE_STATUS 0x8B81 +#endif +#ifndef GL_LINK_STATUS +#define GL_LINK_STATUS 0x8B82 +#endif +#ifndef GL_INFO_LOG_LENGTH +#define GL_INFO_LOG_LENGTH 0x8B84 +#endif +#ifndef GL_SHADING_LANGUAGE_VERSION +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#endif +#ifndef GL_VERTEX_PROGRAM_POINT_SIZE +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#endif +#ifndef GL_FUNC_ADD +#define GL_FUNC_ADD 0x8006 +#endif +#ifndef GL_FUNC_SUBTRACT +#define GL_FUNC_SUBTRACT 0x800A +#endif +#ifndef GL_FUNC_REVERSE_SUBTRACT +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#endif +#ifndef GL_POINT_SPRITE +#define GL_POINT_SPRITE 0x8861 +#endif +#ifndef GL_COORD_REPLACE +#define GL_COORD_REPLACE 0x8862 +#endif +#ifndef GL_FRAMEBUFFER +#define GL_FRAMEBUFFER 0x8D40 +#endif +#ifndef GL_RENDERBUFFER +#define GL_RENDERBUFFER 0x8D41 +#endif +#ifndef GL_FRAMEBUFFER_COMPLETE +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#endif +#ifndef GL_COLOR_ATTACHMENT0 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#endif +#ifndef GL_DEPTH_ATTACHMENT +#define GL_DEPTH_ATTACHMENT 0x8D00 +#endif +#ifndef GL_STENCIL_ATTACHMENT +#define GL_STENCIL_ATTACHMENT 0x8D20 +#endif +#ifndef GL_FRAMEBUFFER_BINDING +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#endif +#ifndef GL_RENDERBUFFER_BINDING +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#endif +#ifndef GL_READ_FRAMEBUFFER +#define GL_READ_FRAMEBUFFER 0x8CA8 +#endif +#ifndef GL_DRAW_FRAMEBUFFER +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#endif +#ifndef GL_STENCIL_INDEX8 +#define GL_STENCIL_INDEX8 0x8D48 +#endif +#ifndef GL_RGBA8 +#define GL_RGBA8 0x8058 +#endif +#ifndef GL_RGB8 +#define GL_RGB8 0x8051 +#endif +#ifndef GL_VERTEX_ARRAY_BINDING +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#endif +#ifndef GL_NUM_EXTENSIONS +#define GL_NUM_EXTENSIONS 0x821D +#endif + #else //! Mobile platform ( Android / iPhone / Maemo ) #ifndef GL_GLEXT_PROTOTYPES @@ -245,6 +363,10 @@ typedef char GLchar; #define GL_STENCIL_INDEX GL_STENCIL_INDEX8_OES #endif +#ifndef GL_STENCIL_INDEX8 +#define GL_STENCIL_INDEX8 GL_STENCIL_INDEX +#endif + #define GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_OES #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES #define GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_OES @@ -277,7 +399,7 @@ typedef char GLchar; #endif #ifndef GL_MULTISAMPLE -#define GL_MULTISAMPLE 0x809D +#define GL_MULTISAMPLE 0x809D #endif #include diff --git a/include/eepp/graphics/renderer/renderer.hpp b/include/eepp/graphics/renderer/renderer.hpp index 7e346841c..830f768ee 100644 --- a/include/eepp/graphics/renderer/renderer.hpp +++ b/include/eepp/graphics/renderer/renderer.hpp @@ -96,6 +96,8 @@ class EE_API Renderer { void activeTexture( unsigned int texture ); + void clientActiveTextureImpl( unsigned int texture ); + void blendFunc( unsigned int sfactor, unsigned int dfactor ); void blendFuncSeparate( unsigned int sfactorRGB, unsigned int dfactorRGB, @@ -241,6 +243,73 @@ class EE_API Renderer { void genVertexArrays( int n, unsigned int* arrays ); + void genBuffers( int n, unsigned int* buffers ); + + void deleteBuffers( int n, const unsigned int* buffers ); + + void bindBuffer( unsigned int target, unsigned int buffer ); + + void bufferData( unsigned int target, IntPtr size, const void* data, unsigned int usage ); + + void bufferSubData( unsigned int target, IntPtr offset, IntPtr size, const void* data ); + + void vertexAttribPointer( unsigned int index, int size, unsigned int type, bool normalized, + int stride, const void* pointer ); + + void enableVertexAttribArray( unsigned int index ); + + void disableVertexAttribArray( unsigned int index ); + + unsigned int createShader( unsigned int type ); + + void deleteShader( unsigned int shader ); + + void shaderSource( unsigned int shader, int count, const char* const* strings, + const int* lengths ); + + void compileShader( unsigned int shader ); + + void getShaderiv( unsigned int shader, unsigned int pname, int* params ); + + void getShaderInfoLog( unsigned int shader, int maxLength, int* length, char* infoLog ); + + unsigned int createProgram(); + + void deleteProgram( unsigned int program ); + + void attachShader( unsigned int program, unsigned int shader ); + + void linkProgram( unsigned int program ); + + void useProgram( unsigned int program ); + + void getProgramiv( unsigned int program, unsigned int pname, int* params ); + + void getProgramInfoLog( unsigned int program, int maxLength, int* length, char* infoLog ); + + int getUniformLocation( unsigned int program, const char* name ); + + int getAttribLocation( unsigned int program, const char* name ); + + void uniform1i( int location, int value ); + + void uniform1f( int location, float value ); + + void uniform2fv( int location, int count, const float* value ); + + void uniform3fv( int location, int count, const float* value ); + + void uniform4f( int location, float x, float y, float z, float w ); + + void uniform4fv( int location, int count, const float* value ); + + void uniformMatrix4fv( int location, int count, bool transpose, const float* value ); + + void compressedTexImage2D( unsigned int target, int level, unsigned int internalFormat, + int width, int height, int border, int imageSize, const void* data ); + + void getCompressedTexImage( unsigned int target, int level, void* pixels ); + const bool& quadsSupported() const; const int& quadVertex() const; diff --git a/include/eepp/graphics/renderer/rendererhelper.hpp b/include/eepp/graphics/renderer/rendererhelper.hpp index 401dba51f..2218f179a 100644 --- a/include/eepp/graphics/renderer/rendererhelper.hpp +++ b/include/eepp/graphics/renderer/rendererhelper.hpp @@ -31,7 +31,8 @@ enum GraphicsLibraryExtension { EEGL_IMG_texture_compression_pvrtc, EEGL_OES_compressed_ETC1_RGB8_texture, EEGL_EXT_blend_minmax, - EEGL_EXT_blend_subtract + EEGL_EXT_blend_subtract, + EEGL_ARB_ES3_compatibility, }; /// Graphics Library Renderer version available. diff --git a/include/eepp/ui/abstract/uiabstracttableview.hpp b/include/eepp/ui/abstract/uiabstracttableview.hpp index 4c06f52ee..beb8dce2f 100644 --- a/include/eepp/ui/abstract/uiabstracttableview.hpp +++ b/include/eepp/ui/abstract/uiabstracttableview.hpp @@ -148,6 +148,8 @@ class EE_API UIAbstractTableView : public UIAbstractView { void setSetupCellCb( const std::function& onSetupCellCb ); + void resetSearchText(); + protected: friend class EE::UI::UITableHeaderColumn; friend class EE::UI::UIDropDownModelList; diff --git a/include/eepp/ui/uifiledialog.hpp b/include/eepp/ui/uifiledialog.hpp index 1725c184f..e4ee9da7a 100644 --- a/include/eepp/ui/uifiledialog.hpp +++ b/include/eepp/ui/uifiledialog.hpp @@ -129,6 +129,10 @@ class EE_API UIFileDialog : public UIWindow { virtual void scheduledUpdate( const Time& time ); + nlohmann::json serialize() const; + + void unserialize( const nlohmann::json& json ); + protected: std::string mCurPath; std::string mFilePatterns; diff --git a/include/eepp/ui/uimultimodelview.hpp b/include/eepp/ui/uimultimodelview.hpp index 41bbc2e12..332e2e5d4 100644 --- a/include/eepp/ui/uimultimodelview.hpp +++ b/include/eepp/ui/uimultimodelview.hpp @@ -19,7 +19,7 @@ class EE_API UIMultiModelView : public UIStackWidget { void setViewMode( const ViewMode& mode ); - UIAbstractView* getCurrentView() const; + UIAbstractTableView* getCurrentView() const; std::shared_ptr getModel() const; diff --git a/include/eepp/ui/uiwindow.hpp b/include/eepp/ui/uiwindow.hpp index 7b8725eeb..cf829ae07 100644 --- a/include/eepp/ui/uiwindow.hpp +++ b/include/eepp/ui/uiwindow.hpp @@ -1,6 +1,7 @@ #ifndef EE_UICUIWINDOW_HPP #define EE_UICUIWINDOW_HPP +#include #include #include @@ -202,6 +203,10 @@ class EE_API UIWindow : public UIWidget { void setCheckEphemeralCloseFn( std::function fn ); + virtual nlohmann::json serialize() const; + + virtual void unserialize( const nlohmann::json& json ); + protected: enum UI_RESIZE_TYPE { RESIZE_NONE, diff --git a/premake4.lua b/premake4.lua index 2fd647e3a..5b524fb29 100644 --- a/premake4.lua +++ b/premake4.lua @@ -158,6 +158,7 @@ newoption { trigger = "with-static-eepp", description = "Force to build the demo newoption { trigger = "with-static-backend", description = "It will try to compile the library with a static backend (only for gcc and mingw).\n\t\t\t\tThe backend should be placed in libs/your_platform/libYourBackend.a" } newoption { trigger = "with-gles2", description = "Compile with GLES2 support" } newoption { trigger = "with-gles1", description = "Compile with GLES1 support" } +newoption { trigger = "with-glew", description = "Compile with GLEW support (disabled by default)." } newoption { trigger = "without-mojoal", description = "Compile without mojoAL as OpenAL implementation (that requires SDL2 backend). Instead it will use openal-soft." } newoption { trigger = "use-frameworks", description = "In macOS it will try to link the external libraries from its frameworks. For example, instead of linking against SDL2 it will link against SDL2.framework." } newoption { trigger = "with-mold-linker", description = "Tries to use the mold linker instead of the default linker of the toolchain" } @@ -221,6 +222,14 @@ function os.is_real( os_name ) return os.get_real() == os_name end +function glew_supported() + return not os.is_real("haiku") and not os.is_real("ios") and not os.is_real("android") and not os.is_real("emscripten") +end + +function glew_enabled() + return _OPTIONS["with-glew"] and glew_supported() +end + if os.is_real("haiku") and not os.is64bit() then premake.gcc.cc = "gcc-x86" premake.gcc.cxx = "g++-x86" @@ -710,6 +719,10 @@ function parse_args() defines { "EE_GLES1", "SOIL_GLES1" } end + if glew_enabled() then + defines { "EE_ENABLE_GLEW" } + end + if _OPTIONS["thread-sanitizer"] then buildoptions { "-fsanitize=thread" } linkoptions { "-fsanitize=thread" } @@ -776,7 +789,7 @@ function add_static_links() links { "mbedtls-static" } end - if not os.is_real("haiku") and not os.is_real("ios") and not os.is_real("android") and not os.is_real("emscripten") then + if glew_enabled() then links{ "glew-static" } end end @@ -1130,7 +1143,7 @@ solution "eepp" includedirs { "src/thirdparty/SOIL2" } build_base_configuration( "SOIL2" ) - if not os.is_real("haiku") and not os.is_real("ios") and not os.is_real("android") and not os.is_real("emscripten") then + if glew_enabled() then project "glew-static" kind "StaticLib" language "C" diff --git a/premake5.lua b/premake5.lua index ac5d7cc53..2a7c981c2 100644 --- a/premake5.lua +++ b/premake5.lua @@ -8,6 +8,7 @@ newoption { trigger = "with-static-eepp", description = "Force to build the demo newoption { trigger = "with-static-backend", description = "It will try to compile the library with a static backend (only for gcc and mingw).\n\t\t\t\tThe backend should be placed in libs/your_platform/libYourBackend.a" } newoption { trigger = "with-gles2", description = "Compile with GLES2 support" } newoption { trigger = "with-gles1", description = "Compile with GLES1 support" } +newoption { trigger = "with-glew", description = "Compile with GLEW support (disabled by default)." } newoption { trigger = "without-mojoal", description = "Compile without mojoAL as OpenAL implementation (that requires SDL2 backend). Instead it will use openal-soft." } newoption { trigger = "use-frameworks", description = "In macOS it will try to link the external libraries from its frameworks. For example, instead of linking against SDL2 it will link against SDL2.framework." } newoption { trigger = "windows-vc-build", description = "This is used to build the framework in Visual Studio downloading its external dependencies and making them available to the VS project without having to install them manually." } @@ -185,6 +186,14 @@ function is_sdl3_backend() return false end +function glew_supported() + return not os.istarget("haiku") and not os.istarget("ios") and not os.istarget("android") and not os.istarget("emscripten") +end + +function glew_enabled() + return _OPTIONS["with-glew"] and glew_supported() +end + function get_sdl_version_dir() if sdl_version_dir_override then return sdl_version_dir_override @@ -640,6 +649,10 @@ function parse_args() defines { "EE_GLES1", "SOIL_GLES1" } end + if glew_enabled() then + defines { "EE_ENABLE_GLEW" } + end + if _OPTIONS["thread-sanitizer"] then buildoptions { "-fsanitize=thread" } linkoptions { "-fsanitize=thread" } @@ -707,7 +720,7 @@ function add_static_links() links { "mbedtls-static" } end - if not os.istarget("haiku") and not os.istarget("ios") and not os.istarget("android") and not os.istarget("emscripten") then + if glew_enabled() then links{ "glew-static" } end end @@ -1068,6 +1081,7 @@ workspace "eepp" select_backend() generate_os_links() parse_args() + location("./make/" .. os.target() .. "/") objdir("obj/" .. os.target() .. "/") @@ -1128,19 +1142,23 @@ workspace "eepp" build_base_configuration( "SOIL2" ) target_dir_thirdparty() - project "glew-static" - kind "StaticLib" - language "C" - defines { "GLEW_NO_GLU", "GLEW_STATIC" } - files { "src/thirdparty/glew/*.c" } - incdirs { "include/thirdparty/glew" } - build_base_configuration( "glew" ) - target_dir_thirdparty() - filter { "action:vs*", "options:arch=arm64" } - buildoptions{ "/bigobj", "/O1", "/Zm200" } + if glew_enabled() then + project "glew-static" + kind "StaticLib" + language "C" + defines { "GLEW_NO_GLU", "GLEW_STATIC" } + files { "src/thirdparty/glew/*.c" } + incdirs { "include/thirdparty/glew" } + build_base_configuration( "glew" ) + target_dir_thirdparty() + filter { "action:vs*", "options:arch=arm64" } + buildoptions{ "/bigobj", "/O1", "/Zm200" } - filter { "action:vs*", "options:arch=aarch64" } - buildoptions{ "/bigobj", "/O1", "/Zm200" } + filter { "action:vs*", "options:arch=aarch64" } + buildoptions{ "/bigobj", "/O1", "/Zm200" } + + filter {} + end project "mbedtls-static" kind "StaticLib" diff --git a/projects/linux/ee.config b/projects/linux/ee.config index 504769613..df92f577d 100644 --- a/projects/linux/ee.config +++ b/projects/linux/ee.config @@ -3,7 +3,6 @@ #define EE_DEBUG #define EE_MEMORY_MANAGER #define EE_SHADERS_SUPPORTED -#define EE_GLEW_AVAILABLE #define EE_SSL_SUPPORT #define EE_OPENSSL #define EE_BACKEND_SDL2 diff --git a/projects/macos/ee.config b/projects/macos/ee.config index 041783d1f..780fa71a3 100644 --- a/projects/macos/ee.config +++ b/projects/macos/ee.config @@ -2,7 +2,6 @@ #define EE_DEBUG #define EE_MEMORY_MANAGER #define EE_SHADERS_SUPPORTED -#define EE_GLEW_AVAILABLE #define EE_SSL_SUPPORT #define EE_OPENSSL #define EE_BACKEND_SDL2 diff --git a/projects/windows/ee.config b/projects/windows/ee.config index 9358a2eb0..9ab7adde2 100644 --- a/projects/windows/ee.config +++ b/projects/windows/ee.config @@ -3,7 +3,6 @@ #define EE_DEBUG #define EE_MEMORY_MANAGER #define EE_SHADERS_SUPPORTED -#define EE_GLEW_AVAILABLE #define EE_SSL_SUPPORT #define EE_OPENSSL #define EE_BACKEND_SDL2 diff --git a/src/eepp/graphics/image.cpp b/src/eepp/graphics/image.cpp index 06a268ee1..51e902b06 100644 --- a/src/eepp/graphics/image.cpp +++ b/src/eepp/graphics/image.cpp @@ -647,12 +647,12 @@ bool Image::isImageExtension( const std::string& path ) { return ( ext == "png" || ext == "tga" || ext == "bmp" || ext == "jpg" || ext == "gif" || ext == "jpeg" || ext == "dds" || ext == "psd" || ext == "hdr" || ext == "pic" || ext == "pvr" || ext == "pkm" || ext == "svg" || ext == "qoi" || ext == "webp" || - ext == "jpe" ); + ext == "jpe" || ext == "astc" ); } std::vector Image::getImageExtensionsSupported() { - return std::vector{ "png", "tga", "bmp", "jpg", "gif", "jpeg", "dds", "psd", - "hdr", "pic", "pvr", "pkm", "svg", "qoi", "webp", "jpe" }; + return std::vector{ "png", "tga", "bmp", "jpg", "gif", "jpeg", "dds", "psd", "hdr", + "pic", "pvr", "pkm", "svg", "qoi", "webp", "jpe", "astc" }; } std::string Image::getLastFailureReason() { diff --git a/src/eepp/graphics/renderer/openglext.hpp b/src/eepp/graphics/renderer/openglext.hpp index 212aefd56..340005955 100644 --- a/src/eepp/graphics/renderer/openglext.hpp +++ b/src/eepp/graphics/renderer/openglext.hpp @@ -18,4 +18,85 @@ #include +#ifndef APIENTRY +#define APIENTRY +#endif + +namespace EE { namespace Graphics { + +typedef const GLubyte*( APIENTRY* pglGetStringiFunc )( unsigned int, unsigned int ); +typedef void( APIENTRY* pglGenFramebuffers )( GLsizei n, GLuint* framebuffers ); +typedef void( APIENTRY* pglBindFramebuffer )( GLenum target, GLuint framebuffer ); +typedef void( APIENTRY* pglFramebufferTexture2D )( GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level ); +typedef void( APIENTRY* pglDeleteFramebuffers )( GLsizei n, const GLuint* framebuffers ); +typedef void( APIENTRY* pglGenRenderbuffers )( GLsizei n, GLuint* renderbuffers ); +typedef void( APIENTRY* pglDeleteRenderbuffers )( GLsizei n, const GLuint* renderbuffers ); +typedef void( APIENTRY* pglRenderbufferStorage )( GLenum target, GLenum internalformat, + GLsizei width, GLsizei height ); +typedef void( APIENTRY* pglFramebufferRenderbuffer )( GLenum target, GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer ); +typedef GLenum( APIENTRY* pglCheckFramebufferStatus )( GLenum target ); +typedef void( APIENTRY* pglBindRenderbuffer )( GLenum target, GLuint renderbuffer ); +typedef void( APIENTRY* pglBlendFuncSeparate )( GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorAlpha, GLenum dfactorAlpha ); +typedef void( APIENTRY* pglDiscardFramebufferEXT )( GLenum target, GLsizei numAttachments, + const GLenum* attachments ); +typedef void( APIENTRY* pglBlendEquationSeparate )( GLenum modeRGB, GLenum modeAlpha ); +typedef void( APIENTRY* pglBlitFramebufferEXT )( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter ); +typedef void( APIENTRY* pglActiveTexture )( GLenum texture ); +typedef void( APIENTRY* pglClientActiveTexture )( GLenum texture ); +typedef void( APIENTRY* pglGenBuffers )( GLsizei n, GLuint* buffers ); +typedef void( APIENTRY* pglDeleteBuffers )( GLsizei n, const GLuint* buffers ); +typedef void( APIENTRY* pglBindBuffer )( GLenum target, GLuint buffer ); +typedef void( APIENTRY* pglBufferData )( GLenum target, IntPtr size, const void* data, + GLenum usage ); +typedef void( APIENTRY* pglBufferSubData )( GLenum target, IntPtr offset, IntPtr size, + const void* data ); +typedef void( APIENTRY* pglVertexAttribPointer )( GLuint index, GLint size, GLenum type, + GLboolean normalized, GLsizei stride, + const void* pointer ); +typedef void( APIENTRY* pglEnableVertexAttribArray )( GLuint index ); +typedef void( APIENTRY* pglDisableVertexAttribArray )( GLuint index ); +typedef GLuint( APIENTRY* pglCreateShader )( GLenum type ); +typedef void( APIENTRY* pglDeleteShader )( GLuint shader ); +typedef void( APIENTRY* pglShaderSource )( GLuint shader, GLsizei count, + const GLchar* const* strings, const GLint* lengths ); +typedef void( APIENTRY* pglCompileShader )( GLuint shader ); +typedef void( APIENTRY* pglGetShaderiv )( GLuint shader, GLenum pname, GLint* params ); +typedef void( APIENTRY* pglGetShaderInfoLog )( GLuint shader, GLsizei maxLength, GLsizei* length, + GLchar* infoLog ); +typedef GLuint( APIENTRY* pglCreateProgram )(); +typedef void( APIENTRY* pglDeleteProgram )( GLuint program ); +typedef void( APIENTRY* pglAttachShader )( GLuint program, GLuint shader ); +typedef void( APIENTRY* pglLinkProgram )( GLuint program ); +typedef void( APIENTRY* pglUseProgram )( GLuint program ); +typedef void( APIENTRY* pglGetProgramiv )( GLuint program, GLenum pname, GLint* params ); +typedef void( APIENTRY* pglGetProgramInfoLog )( GLuint program, GLsizei maxLength, GLsizei* length, + GLchar* infoLog ); +typedef GLint( APIENTRY* pglGetUniformLocation )( GLuint program, const GLchar* name ); +typedef GLint( APIENTRY* pglGetAttribLocation )( GLuint program, const GLchar* name ); +typedef void( APIENTRY* pglUniform1i )( GLint location, GLint value ); +typedef void( APIENTRY* pglUniform1f )( GLint location, GLfloat value ); +typedef void( APIENTRY* pglUniform2fv )( GLint location, GLsizei count, const GLfloat* value ); +typedef void( APIENTRY* pglUniform3fv )( GLint location, GLsizei count, const GLfloat* value ); +typedef void( APIENTRY* pglUniform4f )( GLint location, GLfloat x, GLfloat y, GLfloat z, + GLfloat w ); +typedef void( APIENTRY* pglUniform4fv )( GLint location, GLsizei count, const GLfloat* value ); +typedef void( APIENTRY* pglUniformMatrix4fv )( GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value ); +typedef void( APIENTRY* pglCompressedTexImage2D )( GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, + const void* data ); +typedef void( APIENTRY* pglGetCompressedTexImage )( GLenum target, GLint level, void* pixels ); +typedef void( APIENTRY* pglBindVertexArray )( GLuint array ); +typedef void( APIENTRY* pglDeleteVertexArrays )( GLsizei n, const GLuint* arrays ); +typedef void( APIENTRY* pglGenVertexArrays )( GLsizei n, GLuint* arrays ); + +}} // namespace EE::Graphics + #endif diff --git a/src/eepp/graphics/renderer/renderer.cpp b/src/eepp/graphics/renderer/renderer.cpp index 737bb8888..68b3fec29 100644 --- a/src/eepp/graphics/renderer/renderer.cpp +++ b/src/eepp/graphics/renderer/renderer.cpp @@ -9,34 +9,15 @@ namespace EE { namespace Graphics { -#ifndef APIENTRY -#define APIENTRY +#if defined( EE_GLEW_AVAILABLE ) || defined( EE_GLES2 ) +#define EEGL_LOAD_PROC( type, variable, function ) static type variable = (type)function +#else +#define EEGL_LOAD_PROC( type, variable, function ) \ + static type variable = NULL; \ + if ( NULL == variable ) \ + variable = (type)getProcAddress( #function ) #endif -typedef const GLubyte*( APIENTRY* pglGetStringiFunc )( unsigned int, unsigned int ); -typedef void( APIENTRY* pglGenFramebuffers )( GLsizei n, GLuint* framebuffers ); -typedef void( APIENTRY* pglBindFramebuffer )( GLenum target, GLuint framebuffer ); -typedef void( APIENTRY* pglFramebufferTexture2D )( GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, GLint level ); -typedef void( APIENTRY* pglDeleteFramebuffers )( GLsizei n, const GLuint* framebuffers ); -typedef void( APIENTRY* pglGenRenderbuffers )( GLsizei n, GLuint* renderbuffers ); -typedef void( APIENTRY* pglDeleteRenderbuffers )( GLsizei n, const GLuint* renderbuffers ); -typedef void( APIENTRY* pglRenderbufferStorage )( GLenum target, GLenum internalformat, - GLsizei width, GLsizei height ); -typedef void( APIENTRY* pglFramebufferRenderbuffer )( GLenum target, GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer ); -typedef GLenum( APIENTRY* pglCheckFramebufferStatus )( GLenum target ); -typedef void( APIENTRY* pglBindRenderbuffer )( GLenum target, GLuint renderbuffer ); -typedef void( APIENTRY* pglBlendFuncSeparate )( GLenum sfactorRGB, GLenum dfactorRGB, - GLenum sfactorAlpha, GLenum dfactorAlpha ); -typedef void( APIENTRY* pglDiscardFramebufferEXT )( GLenum target, GLsizei numAttachments, - const GLenum* attachments ); -typedef void( APIENTRY* pglBlendEquationSeparate )( GLenum modeRGB, GLenum modeAlpha ); -typedef void( APIENTRY* pglBlitFramebufferEXT )( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter ); - Renderer* GLi = NULL; Renderer* Renderer::sSingleton = NULL; @@ -230,7 +211,30 @@ void Renderer::writeExtension( Uint8 Pos, Uint32 BitWrite ) { BitOp::writeBitKey( &mExtensions, Pos, BitWrite ); } +static void getGLVersion( int* major, int* minor, int* is_es ) { + const char* version = (const char*)glGetString( GL_VERSION ); + const char* number = version; + *major = 0; + *minor = 0; + *is_es = 0; + if ( NULL == version ) + return; + if ( strncmp( version, "OpenGL ES", 9 ) == 0 ) { + *is_es = 1; + number = version + 9; + while ( *number && ( *number < '0' || *number > '9' ) ) + ++number; + } + sscanf( number, "%d.%d", major, minor ); +} + void Renderer::init() { + int major; + int minor; + int is_es; + getGLVersion( &major, &minor, &is_es ); + const int glVersion = major * 100 + minor * 10; + #ifdef EE_GLEW_AVAILABLE #if EE_PLATFORM != EE_PLATFORM_MACOS glewExperimental = 1; @@ -245,7 +249,9 @@ void Renderer::init() { writeExtension( EEGL_ARB_shader_objects, GLEW_ARB_shader_objects ); writeExtension( EEGL_ARB_vertex_shader, GLEW_ARB_vertex_shader ); writeExtension( EEGL_ARB_fragment_shader, GLEW_ARB_fragment_shader ); - writeExtension( EEGL_EXT_framebuffer_object, GLEW_EXT_framebuffer_object ); + writeExtension( EEGL_EXT_framebuffer_object, GLEW_EXT_framebuffer_object || + GLEW_ARB_framebuffer_object || + GLEW_VERSION_3_0 ); writeExtension( EEGL_ARB_multitexture, GLEW_ARB_multitexture ); writeExtension( EEGL_EXT_texture_compression_s3tc, GLEW_EXT_texture_compression_s3tc ); writeExtension( EEGL_ARB_vertex_buffer_object, GLEW_ARB_vertex_buffer_object ); @@ -258,25 +264,38 @@ void Renderer::init() { #endif { writeExtension( EEGL_ARB_texture_non_power_of_two, - isExtension( "GL_ARB_texture_non_power_of_two" ) ); - writeExtension( EEGL_ARB_point_parameters, isExtension( "GL_ARB_point_parameters" ) ); - writeExtension( EEGL_ARB_point_sprite, isExtension( "GL_ARB_point_sprite" ) ); + glVersion >= 200 || isExtension( "GL_ARB_texture_non_power_of_two" ) ); + writeExtension( EEGL_ARB_point_parameters, + glVersion >= 140 || isExtension( "GL_ARB_point_parameters" ) ); + writeExtension( EEGL_ARB_point_sprite, + glVersion >= 200 || isExtension( "GL_ARB_point_sprite" ) ); writeExtension( EEGL_ARB_shading_language_100, - isExtension( "GL_ARB_shading_language_100" ) ); - writeExtension( EEGL_ARB_shader_objects, isExtension( "GL_ARB_shader_objects" ) ); - writeExtension( EEGL_ARB_vertex_shader, isExtension( "GL_ARB_vertex_shader" ) ); - writeExtension( EEGL_ARB_fragment_shader, isExtension( "GL_ARB_fragment_shader" ) ); - writeExtension( EEGL_EXT_framebuffer_object, isExtension( "GL_EXT_framebuffer_object" ) ); - writeExtension( EEGL_ARB_multitexture, isExtension( "GL_ARB_multitexture" ) ); + glVersion >= 200 || isExtension( "GL_ARB_shading_language_100" ) ); + writeExtension( EEGL_ARB_shader_objects, + glVersion >= 200 || isExtension( "GL_ARB_shader_objects" ) ); + writeExtension( EEGL_ARB_vertex_shader, + glVersion >= 200 || isExtension( "GL_ARB_vertex_shader" ) ); + writeExtension( EEGL_ARB_fragment_shader, + glVersion >= 200 || isExtension( "GL_ARB_fragment_shader" ) ); + writeExtension( EEGL_EXT_framebuffer_object, + glVersion >= 300 || isExtension( "GL_ARB_framebuffer_object" ) || + isExtension( "GL_EXT_framebuffer_object" ) ); + writeExtension( EEGL_ARB_multitexture, + glVersion >= 130 || isExtension( "GL_ARB_multitexture" ) ); writeExtension( EEGL_EXT_texture_compression_s3tc, isExtension( "GL_EXT_texture_compression_s3tc" ) ); writeExtension( EEGL_ARB_vertex_buffer_object, - isExtension( "GL_ARB_vertex_buffer_object" ) ); - writeExtension( EEGL_ARB_pixel_buffer_object, isExtension( "GL_ARB_pixel_buffer_object" ) ); - writeExtension( EEGL_ARB_vertex_array_object, isExtension( "GL_ARB_vertex_array_object" ) ); - writeExtension( EEGL_EXT_blend_func_separate, isExtension( "GL_EXT_blend_func_separate" ) ); - writeExtension( EEGL_EXT_blend_minmax, isExtension( "GL_EXT_blend_minmax" ) ); - writeExtension( EEGL_EXT_blend_subtract, isExtension( "GL_EXT_blend_subtract" ) ); + glVersion >= 150 || isExtension( "GL_ARB_vertex_buffer_object" ) ); + writeExtension( EEGL_ARB_pixel_buffer_object, + glVersion >= 210 || isExtension( "GL_ARB_pixel_buffer_object" ) ); + writeExtension( EEGL_ARB_vertex_array_object, + glVersion >= 300 || isExtension( "GL_ARB_vertex_array_object" ) ); + writeExtension( EEGL_EXT_blend_func_separate, + glVersion >= 140 || isExtension( "GL_EXT_blend_func_separate" ) ); + writeExtension( EEGL_EXT_blend_minmax, + glVersion >= 140 || isExtension( "GL_EXT_blend_minmax" ) ); + writeExtension( EEGL_EXT_blend_subtract, + glVersion >= 140 || isExtension( "GL_EXT_blend_subtract" ) ); } // NVIDIA added support for GL_OES_compressed_ETC1_RGB8_texture in desktop GPUs @@ -284,6 +303,9 @@ void Renderer::init() { writeExtension( EEGL_OES_compressed_ETC1_RGB8_texture, isExtension( "GL_OES_compressed_ETC1_RGB8_texture" ) ); + writeExtension( EEGL_ARB_ES3_compatibility, + isExtension( "GL_ARB_ES3_compatibility" ) || ( is_es && major >= 3 ) ); + #ifdef EE_GLES writeExtension( EEGL_ARB_point_parameters, 1 ); @@ -466,7 +488,24 @@ void Renderer::bindTexture( unsigned int target, unsigned int texture ) { } void Renderer::activeTexture( unsigned int texture ) { - glActiveTexture( texture ); + EEGL_LOAD_PROC( pglActiveTexture, eeglActiveTexture, glActiveTexture ); + + if ( NULL != eeglActiveTexture ) + eeglActiveTexture( texture ); +} + +void Renderer::clientActiveTextureImpl( unsigned int texture ) { +#if defined( EE_GLEW_AVAILABLE ) || ( defined( EE_GLES1 ) && !defined( EE_GLES2 ) ) + static pglClientActiveTexture eeglClientActiveTexture = + (pglClientActiveTexture)glClientActiveTexture; +#else + static pglClientActiveTexture eeglClientActiveTexture = NULL; + if ( NULL == eeglClientActiveTexture ) + eeglClientActiveTexture = (pglClientActiveTexture)getProcAddress( "glClientActiveTexture" ); +#endif + + if ( NULL != eeglClientActiveTexture ) + eeglClientActiveTexture( texture ); } void Renderer::blendFunc( unsigned int sfactor, unsigned int dfactor ) { @@ -500,7 +539,7 @@ void Renderer::blitFrameBuffer( int srcX0, int srcY0, int srcX1, int srcY1, int static pglBlitFramebufferEXT eeglBlitFramebufferEXT = NULL; if ( NULL == eeglBlitFramebufferEXT ) - eeglBlitFramebufferEXT = (pglBlitFramebufferEXT)getProcAddress( "glBlitFramebufferEXT" ); + eeglBlitFramebufferEXT = (pglBlitFramebufferEXT)getProcAddress( "glBlitFramebuffer" ); if ( NULL != eeglBlitFramebufferEXT ) eeglBlitFramebufferEXT( srcX0, srcY1, srcX1, srcY0, dstX0, dstY0, dstX1, dstY1, mask, @@ -510,9 +549,9 @@ void Renderer::blitFrameBuffer( int srcX0, int srcY0, int srcX1, int srcY1, int void Renderer::setShader( ShaderProgram* Shader ) { #ifdef EE_SHADERS_SUPPORTED if ( NULL != Shader ) { - glUseProgram( Shader->getHandler() ); + useProgram( Shader->getHandler() ); } else { - glUseProgram( 0 ); + useProgram( 0 ); } #endif } @@ -718,17 +757,19 @@ ClippingMask* Renderer::getClippingMask() const { void* Renderer::getProcAddress( std::string proc ) { void* addr = NULL; -#ifdef EE_GLES - if ( version() == GLv_ES1 ) - addr = SOIL_GL_GetProcAddress( ( proc + "OES" ).c_str() ); -#endif - - if ( NULL == addr ) - addr = SOIL_GL_GetProcAddress( proc.c_str() ); + addr = SOIL_GL_GetProcAddress( proc.c_str() ); if ( NULL == addr ) addr = SOIL_GL_GetProcAddress( ( proc + "EXT" ).c_str() ); + if ( NULL == addr ) + addr = SOIL_GL_GetProcAddress( ( proc + "ARB" ).c_str() ); + +#ifdef EE_GLES + if ( NULL == addr ) + addr = SOIL_GL_GetProcAddress( ( proc + "OES" ).c_str() ); +#endif + return addr; } @@ -862,10 +903,249 @@ void Renderer::deleteFramebuffers( int n, const unsigned int* framebuffers ) { eeglDeleteFramebuffers( n, framebuffers ); } +void Renderer::genBuffers( int n, unsigned int* buffers ) { + EEGL_LOAD_PROC( pglGenBuffers, eeglGenBuffers, glGenBuffers ); + + if ( NULL != eeglGenBuffers ) + eeglGenBuffers( n, buffers ); +} + +void Renderer::deleteBuffers( int n, const unsigned int* buffers ) { + EEGL_LOAD_PROC( pglDeleteBuffers, eeglDeleteBuffers, glDeleteBuffers ); + + if ( NULL != eeglDeleteBuffers ) + eeglDeleteBuffers( n, buffers ); +} + +void Renderer::bindBuffer( unsigned int target, unsigned int buffer ) { + EEGL_LOAD_PROC( pglBindBuffer, eeglBindBuffer, glBindBuffer ); + + if ( NULL != eeglBindBuffer ) + eeglBindBuffer( target, buffer ); +} + +void Renderer::bufferData( unsigned int target, IntPtr size, const void* data, + unsigned int usage ) { + EEGL_LOAD_PROC( pglBufferData, eeglBufferData, glBufferData ); + + if ( NULL != eeglBufferData ) + eeglBufferData( target, size, data, usage ); +} + +void Renderer::bufferSubData( unsigned int target, IntPtr offset, IntPtr size, const void* data ) { + EEGL_LOAD_PROC( pglBufferSubData, eeglBufferSubData, glBufferSubData ); + + if ( NULL != eeglBufferSubData ) + eeglBufferSubData( target, offset, size, data ); +} + +void Renderer::vertexAttribPointer( unsigned int index, int size, unsigned int type, + bool normalized, int stride, const void* pointer ) { + EEGL_LOAD_PROC( pglVertexAttribPointer, eeglVertexAttribPointer, glVertexAttribPointer ); + + if ( NULL != eeglVertexAttribPointer ) + eeglVertexAttribPointer( index, size, type, normalized ? GL_TRUE : GL_FALSE, stride, + pointer ); +} + +void Renderer::enableVertexAttribArray( unsigned int index ) { + EEGL_LOAD_PROC( pglEnableVertexAttribArray, eeglEnableVertexAttribArray, + glEnableVertexAttribArray ); + + if ( NULL != eeglEnableVertexAttribArray ) + eeglEnableVertexAttribArray( index ); +} + +void Renderer::disableVertexAttribArray( unsigned int index ) { + EEGL_LOAD_PROC( pglDisableVertexAttribArray, eeglDisableVertexAttribArray, + glDisableVertexAttribArray ); + + if ( NULL != eeglDisableVertexAttribArray ) + eeglDisableVertexAttribArray( index ); +} + +unsigned int Renderer::createShader( unsigned int type ) { + EEGL_LOAD_PROC( pglCreateShader, eeglCreateShader, glCreateShader ); + + return NULL != eeglCreateShader ? eeglCreateShader( type ) : 0; +} + +void Renderer::deleteShader( unsigned int shader ) { + EEGL_LOAD_PROC( pglDeleteShader, eeglDeleteShader, glDeleteShader ); + + if ( NULL != eeglDeleteShader ) + eeglDeleteShader( shader ); +} + +void Renderer::shaderSource( unsigned int shader, int count, const char* const* strings, + const int* lengths ) { + EEGL_LOAD_PROC( pglShaderSource, eeglShaderSource, glShaderSource ); + + if ( NULL != eeglShaderSource ) + eeglShaderSource( shader, count, strings, lengths ); +} + +void Renderer::compileShader( unsigned int shader ) { + EEGL_LOAD_PROC( pglCompileShader, eeglCompileShader, glCompileShader ); + + if ( NULL != eeglCompileShader ) + eeglCompileShader( shader ); +} + +void Renderer::getShaderiv( unsigned int shader, unsigned int pname, int* params ) { + EEGL_LOAD_PROC( pglGetShaderiv, eeglGetShaderiv, glGetShaderiv ); + + if ( NULL != eeglGetShaderiv ) + eeglGetShaderiv( shader, pname, params ); +} + +void Renderer::getShaderInfoLog( unsigned int shader, int maxLength, int* length, char* infoLog ) { + EEGL_LOAD_PROC( pglGetShaderInfoLog, eeglGetShaderInfoLog, glGetShaderInfoLog ); + + if ( NULL != eeglGetShaderInfoLog ) + eeglGetShaderInfoLog( shader, maxLength, length, infoLog ); +} + +unsigned int Renderer::createProgram() { + EEGL_LOAD_PROC( pglCreateProgram, eeglCreateProgram, glCreateProgram ); + + return NULL != eeglCreateProgram ? eeglCreateProgram() : 0; +} + +void Renderer::deleteProgram( unsigned int program ) { + EEGL_LOAD_PROC( pglDeleteProgram, eeglDeleteProgram, glDeleteProgram ); + + if ( NULL != eeglDeleteProgram ) + eeglDeleteProgram( program ); +} + +void Renderer::attachShader( unsigned int program, unsigned int shader ) { + EEGL_LOAD_PROC( pglAttachShader, eeglAttachShader, glAttachShader ); + + if ( NULL != eeglAttachShader ) + eeglAttachShader( program, shader ); +} + +void Renderer::linkProgram( unsigned int program ) { + EEGL_LOAD_PROC( pglLinkProgram, eeglLinkProgram, glLinkProgram ); + + if ( NULL != eeglLinkProgram ) + eeglLinkProgram( program ); +} + +void Renderer::useProgram( unsigned int program ) { + EEGL_LOAD_PROC( pglUseProgram, eeglUseProgram, glUseProgram ); + + if ( NULL != eeglUseProgram ) + eeglUseProgram( program ); +} + +void Renderer::getProgramiv( unsigned int program, unsigned int pname, int* params ) { + EEGL_LOAD_PROC( pglGetProgramiv, eeglGetProgramiv, glGetProgramiv ); + + if ( NULL != eeglGetProgramiv ) + eeglGetProgramiv( program, pname, params ); +} + +void Renderer::getProgramInfoLog( unsigned int program, int maxLength, int* length, + char* infoLog ) { + EEGL_LOAD_PROC( pglGetProgramInfoLog, eeglGetProgramInfoLog, glGetProgramInfoLog ); + + if ( NULL != eeglGetProgramInfoLog ) + eeglGetProgramInfoLog( program, maxLength, length, infoLog ); +} + +int Renderer::getUniformLocation( unsigned int program, const char* name ) { + EEGL_LOAD_PROC( pglGetUniformLocation, eeglGetUniformLocation, glGetUniformLocation ); + + return NULL != eeglGetUniformLocation ? eeglGetUniformLocation( program, name ) : -1; +} + +int Renderer::getAttribLocation( unsigned int program, const char* name ) { + EEGL_LOAD_PROC( pglGetAttribLocation, eeglGetAttribLocation, glGetAttribLocation ); + + return NULL != eeglGetAttribLocation ? eeglGetAttribLocation( program, name ) : -1; +} + +void Renderer::uniform1i( int location, int value ) { + EEGL_LOAD_PROC( pglUniform1i, eeglUniform1i, glUniform1i ); + + if ( NULL != eeglUniform1i ) + eeglUniform1i( location, value ); +} + +void Renderer::uniform1f( int location, float value ) { + EEGL_LOAD_PROC( pglUniform1f, eeglUniform1f, glUniform1f ); + + if ( NULL != eeglUniform1f ) + eeglUniform1f( location, value ); +} + +void Renderer::uniform2fv( int location, int count, const float* value ) { + EEGL_LOAD_PROC( pglUniform2fv, eeglUniform2fv, glUniform2fv ); + + if ( NULL != eeglUniform2fv ) + eeglUniform2fv( location, count, value ); +} + +void Renderer::uniform3fv( int location, int count, const float* value ) { + EEGL_LOAD_PROC( pglUniform3fv, eeglUniform3fv, glUniform3fv ); + + if ( NULL != eeglUniform3fv ) + eeglUniform3fv( location, count, value ); +} + +void Renderer::uniform4f( int location, float x, float y, float z, float w ) { + EEGL_LOAD_PROC( pglUniform4f, eeglUniform4f, glUniform4f ); + + if ( NULL != eeglUniform4f ) + eeglUniform4f( location, x, y, z, w ); +} + +void Renderer::uniform4fv( int location, int count, const float* value ) { + EEGL_LOAD_PROC( pglUniform4fv, eeglUniform4fv, glUniform4fv ); + + if ( NULL != eeglUniform4fv ) + eeglUniform4fv( location, count, value ); +} + +void Renderer::uniformMatrix4fv( int location, int count, bool transpose, const float* value ) { + EEGL_LOAD_PROC( pglUniformMatrix4fv, eeglUniformMatrix4fv, glUniformMatrix4fv ); + + if ( NULL != eeglUniformMatrix4fv ) + eeglUniformMatrix4fv( location, count, transpose ? GL_TRUE : GL_FALSE, value ); +} + +void Renderer::compressedTexImage2D( unsigned int target, int level, unsigned int internalFormat, + int width, int height, int border, int imageSize, + const void* data ) { + EEGL_LOAD_PROC( pglCompressedTexImage2D, eeglCompressedTexImage2D, glCompressedTexImage2D ); + + if ( NULL != eeglCompressedTexImage2D ) + eeglCompressedTexImage2D( target, level, internalFormat, width, height, border, imageSize, + data ); +} + +void Renderer::getCompressedTexImage( unsigned int target, int level, void* pixels ) { +#ifdef EE_GLES + (void)target; + (void)level; + (void)pixels; +#else + EEGL_LOAD_PROC( pglGetCompressedTexImage, eeglGetCompressedTexImage, glGetCompressedTexImage ); + + if ( NULL != eeglGetCompressedTexImage ) + eeglGetCompressedTexImage( target, level, pixels ); +#endif +} + void Renderer::bindVertexArray( unsigned int array ) { #if !defined( EE_GLES ) + EEGL_LOAD_PROC( pglBindVertexArray, eeglBindVertexArray, glBindVertexArray ); + if ( mCurVAO != array ) { - glBindVertexArray( array ); + if ( NULL != eeglBindVertexArray ) + eeglBindVertexArray( array ); mCurVAO = array; } @@ -874,13 +1154,19 @@ void Renderer::bindVertexArray( unsigned int array ) { void Renderer::deleteVertexArrays( int n, const unsigned int* arrays ) { #if !defined( EE_GLES ) - glDeleteVertexArrays( n, arrays ); + EEGL_LOAD_PROC( pglDeleteVertexArrays, eeglDeleteVertexArrays, glDeleteVertexArrays ); + + if ( NULL != eeglDeleteVertexArrays ) + eeglDeleteVertexArrays( n, arrays ); #endif } void Renderer::genVertexArrays( int n, unsigned int* arrays ) { #if !defined( EE_GLES ) - glGenVertexArrays( n, arrays ); + EEGL_LOAD_PROC( pglGenVertexArrays, eeglGenVertexArrays, glGenVertexArrays ); + + if ( NULL != eeglGenVertexArrays ) + eeglGenVertexArrays( n, arrays ); #endif } diff --git a/src/eepp/graphics/renderer/renderergl.cpp b/src/eepp/graphics/renderer/renderergl.cpp index 1a8d2e04a..7df0a006f 100644 --- a/src/eepp/graphics/renderer/renderergl.cpp +++ b/src/eepp/graphics/renderer/renderergl.cpp @@ -223,7 +223,7 @@ void RendererGL::texCoordPointer( int size, unsigned int type, int stride, const } void RendererGL::clientActiveTexture( unsigned int texture ) { - glClientActiveTexture( texture ); + clientActiveTextureImpl( texture ); } void RendererGL::pointSize( float size ) { @@ -236,10 +236,10 @@ void RendererGL::clip2DPlaneEnable( const Int32& x, const Int32& y, const Int32& const Int32& Height ) { Rectf r( x, y, x + Width, y + Height ); - double clip_left[] = {1.0, 0.0, 0.0, -r.Left}; - double clip_right[] = {-1.0, 0.0, 0.0, r.Right}; - double clip_top[] = {0.0, 1.0, 0.0, -r.Top}; - double clip_bottom[] = {0.0, -1.0, 0.0, r.Bottom}; + double clip_left[] = { 1.0, 0.0, 0.0, -r.Left }; + double clip_right[] = { -1.0, 0.0, 0.0, r.Right }; + double clip_top[] = { 0.0, 1.0, 0.0, -r.Top }; + double clip_bottom[] = { 0.0, -1.0, 0.0, r.Bottom }; GLi->enable( GL_CLIP_PLANE0 ); GLi->enable( GL_CLIP_PLANE1 ); @@ -261,7 +261,8 @@ void RendererGL::clip2DPlaneDisable() { void RendererGL::clipPlane( unsigned int plane, const double* equation ) { #ifdef EE_GLES1 - float clip[] = {(float)equation[0], (float)equation[1], (float)equation[2], (float)equation[3]}; + float clip[] = { (float)equation[0], (float)equation[1], (float)equation[2], + (float)equation[3] }; glClipPlane( plane, clip ); #else diff --git a/src/eepp/graphics/renderer/renderergl3.cpp b/src/eepp/graphics/renderer/renderergl3.cpp index 536f9d474..3a681bb3b 100644 --- a/src/eepp/graphics/renderer/renderergl3.cpp +++ b/src/eepp/graphics/renderer/renderergl3.cpp @@ -167,7 +167,7 @@ void RendererGL3::setShader( ShaderProgram* Shader ) { mTextureUnits[i] = mCurShader->getAttributeLocation( EEGL3_TEXTUREUNIT_NAMES[i] ); } - glUseProgram( mCurShader->getHandler() ); + useProgram( mCurShader->getHandler() ); if ( -1 != mAttribsLoc[EEGL_VERTEX_ARRAY] ) enableClientState( GL_VERTEX_ARRAY ); @@ -290,7 +290,7 @@ void RendererGL3::enableClientState( unsigned int array ) { if ( -1 != ( state = mTextureUnits[mCurActiveTex] ) ) { mTextureUnitsStates[mCurActiveTex] = 1; - glEnableVertexAttribArray( state ); + enableVertexAttribArray( state ); } } else { Int32 Pos = array - GL_VERTEX_ARRAY; @@ -298,7 +298,7 @@ void RendererGL3::enableClientState( unsigned int array ) { if ( -1 != ( state = mAttribsLoc[Pos] ) ) { mAttribsLocStates[Pos] = 1; - glEnableVertexAttribArray( state ); + enableVertexAttribArray( state ); } } } @@ -310,7 +310,7 @@ void RendererGL3::disableClientState( unsigned int array ) { if ( -1 != ( state = mTextureUnits[mCurActiveTex] ) ) { mTextureUnitsStates[mCurActiveTex] = 0; - glDisableVertexAttribArray( state ); + disableVertexAttribArray( state ); } } else { Int32 Pos = array - GL_VERTEX_ARRAY; @@ -318,7 +318,7 @@ void RendererGL3::disableClientState( unsigned int array ) { if ( -1 != ( state = mAttribsLoc[Pos] ) ) { mAttribsLocStates[Pos] = 0; - glDisableVertexAttribArray( state ); + disableVertexAttribArray( state ); } } } @@ -331,10 +331,10 @@ void RendererGL3::vertexPointer( int size, unsigned int type, int stride, const if ( 0 == mAttribsLocStates[EEGL_VERTEX_ARRAY] ) { mAttribsLocStates[EEGL_VERTEX_ARRAY] = 1; - glEnableVertexAttribArray( index ); + enableVertexAttribArray( index ); } - glVertexAttribPointer( index, size, type, GL_FALSE, stride, pointer ); + vertexAttribPointer( index, size, type, false, stride, pointer ); } } @@ -346,13 +346,13 @@ void RendererGL3::colorPointer( int size, unsigned int type, int stride, const v if ( 0 == mAttribsLocStates[EEGL_COLOR_ARRAY] ) { mAttribsLocStates[EEGL_COLOR_ARRAY] = 1; - glEnableVertexAttribArray( index ); + enableVertexAttribArray( index ); } if ( type == GL_UNSIGNED_BYTE ) { - glVertexAttribPointer( index, size, type, GL_TRUE, stride, pointer ); + vertexAttribPointer( index, size, type, true, stride, pointer ); } else { - glVertexAttribPointer( index, size, type, GL_FALSE, stride, pointer ); + vertexAttribPointer( index, size, type, false, stride, pointer ); } } } @@ -365,10 +365,10 @@ void RendererGL3::texCoordPointer( int size, unsigned int type, int stride, cons if ( 0 == mTextureUnitsStates[mCurActiveTex] ) { mTextureUnitsStates[mCurActiveTex] = 1; - glEnableVertexAttribArray( index ); + enableVertexAttribArray( index ); } - glVertexAttribPointer( index, size, type, GL_FALSE, stride, pointer ); + vertexAttribPointer( index, size, type, false, stride, pointer ); } } @@ -423,10 +423,10 @@ void RendererGL3::clip2DPlaneEnable( const Int32& x, const Int32& y, const Int32 GLi->enable( GL_CLIP_PLANE2 ); GLi->enable( GL_CLIP_PLANE3 ); - glUniform4fv( mPlanes[0], 1, static_cast( &vclip_left[0] ) ); - glUniform4fv( mPlanes[1], 1, static_cast( &vclip_right[0] ) ); - glUniform4fv( mPlanes[2], 1, static_cast( &vclip_top[0] ) ); - glUniform4fv( mPlanes[3], 1, static_cast( &vclip_bottom[0] ) ); + uniform4fv( mPlanes[0], 1, static_cast( &vclip_left[0] ) ); + uniform4fv( mPlanes[1], 1, static_cast( &vclip_right[0] ) ); + uniform4fv( mPlanes[2], 1, static_cast( &vclip_top[0] ) ); + uniform4fv( mPlanes[3], 1, static_cast( &vclip_bottom[0] ) ); } void RendererGL3::clip2DPlaneDisable() { @@ -451,7 +451,7 @@ void RendererGL3::clipPlane( unsigned int plane, const double* equation ) { } else { std::string planeNum( "dgl_ClipPlane[" + String::toString( nplane ) + "]" ); - location = glGetUniformLocation( mCurShader->getHandler(), (GLchar*)&planeNum[0] ); + location = getUniformLocation( mCurShader->getHandler(), &planeNum[0] ); } glm::vec4 teq( equation[0], equation[1], equation[2], equation[3] ); @@ -460,7 +460,7 @@ void RendererGL3::clipPlane( unsigned int plane, const double* equation ) { glm::inverse( mStack->mModelViewMatrix .top() ); /// Apply the inverse of the model view matrix to the equation - glUniform4f( location, (float)teq[0], (float)teq[1], (float)teq[2], (float)teq[3] ); + uniform4f( location, (float)teq[0], (float)teq[1], (float)teq[2], (float)teq[3] ); } float RendererGL3::pointSize() { diff --git a/src/eepp/graphics/renderer/renderergl3cp.cpp b/src/eepp/graphics/renderer/renderergl3cp.cpp index 2a65760e7..96244aa7e 100644 --- a/src/eepp/graphics/renderer/renderergl3cp.cpp +++ b/src/eepp/graphics/renderer/renderergl3cp.cpp @@ -59,7 +59,7 @@ RendererGL3CP::RendererGL3CP() : RendererGL3CP::~RendererGL3CP() { for ( Uint32 i = 0; i < eeARRAY_SIZE( mVBO ); i++ ) { if ( 0 != mVBO[i] ) { - glDeleteBuffers( 1, &mVBO[i] ); + deleteBuffers( 1, &mVBO[i] ); } } @@ -128,7 +128,7 @@ void RendererGL3CP::init() { genVertexArrays( 1, &mVAO ); bindVertexArray( mVAO ); - glGenBuffers( EEGL_ARRAY_STATES_COUNT + 5, &mVBO[0] ); + genBuffers( EEGL_ARRAY_STATES_COUNT + 5, &mVBO[0] ); allocateBuffers( mVBOSizeAlloc ); @@ -194,7 +194,7 @@ void RendererGL3CP::setShader( ShaderProgram* Shader ) { mTextureUnits[i] = mCurShader->getAttributeLocation( EEGL3CP_TEXTUREUNIT_NAMES[i] ); } - glUseProgram( mCurShader->getHandler() ); + useProgram( mCurShader->getHandler() ); if ( -1 != mAttribsLoc[EEGL_VERTEX_ARRAY] ) enableClientState( GL_VERTEX_ARRAY ); @@ -317,7 +317,7 @@ void RendererGL3CP::enableClientState( unsigned int array ) { if ( -1 != ( state = mTextureUnits[mCurActiveTex] ) ) { mTextureUnitsStates[mCurActiveTex] = 1; - glEnableVertexAttribArray( state ); + enableVertexAttribArray( state ); } } else { Int32 Pos = array - GL_VERTEX_ARRAY; @@ -325,7 +325,7 @@ void RendererGL3CP::enableClientState( unsigned int array ) { if ( -1 != ( state = mAttribsLoc[Pos] ) ) { mAttribsLocStates[Pos] = 1; - glEnableVertexAttribArray( state ); + enableVertexAttribArray( state ); } } } @@ -337,7 +337,7 @@ void RendererGL3CP::disableClientState( unsigned int array ) { if ( -1 != ( state = mTextureUnits[mCurActiveTex] ) ) { mTextureUnitsStates[mCurActiveTex] = 0; - glDisableVertexAttribArray( state ); + disableVertexAttribArray( state ); } } else { Int32 Pos = array - GL_VERTEX_ARRAY; @@ -345,7 +345,7 @@ void RendererGL3CP::disableClientState( unsigned int array ) { if ( -1 != ( state = mAttribsLoc[Pos] ) ) { mAttribsLocStates[Pos] = 0; - glDisableVertexAttribArray( state ); + disableVertexAttribArray( state ); } } } @@ -365,19 +365,19 @@ void RendererGL3CP::vertexPointer( int size, unsigned int type, int stride, cons allocateBuffers( allocate ); } - glBindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_VERTEX_ARRAY] ); - glBufferSubData( GL_ARRAY_BUFFER, 0, allocate, pointer ); + bindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_VERTEX_ARRAY] ); + bufferSubData( GL_ARRAY_BUFFER, 0, allocate, pointer ); if ( 0 == mAttribsLocStates[EEGL_VERTEX_ARRAY] ) { mAttribsLocStates[EEGL_VERTEX_ARRAY] = 1; - glEnableVertexAttribArray( index ); + enableVertexAttribArray( index ); } if ( type == GL_UNSIGNED_BYTE ) { - glVertexAttribPointer( index, size, type, GL_TRUE, stride, 0 ); + vertexAttribPointer( index, size, type, true, stride, 0 ); } else { - glVertexAttribPointer( index, size, type, GL_FALSE, stride, 0 ); + vertexAttribPointer( index, size, type, false, stride, 0 ); } } } @@ -397,19 +397,19 @@ void RendererGL3CP::colorPointer( int size, unsigned int type, int stride, const allocateBuffers( allocate ); } - glBindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_COLOR_ARRAY] ); - glBufferSubData( GL_ARRAY_BUFFER, 0, allocate, pointer ); + bindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_COLOR_ARRAY] ); + bufferSubData( GL_ARRAY_BUFFER, 0, allocate, pointer ); if ( 0 == mAttribsLocStates[EEGL_COLOR_ARRAY] ) { mAttribsLocStates[EEGL_COLOR_ARRAY] = 1; - glEnableVertexAttribArray( index ); + enableVertexAttribArray( index ); } if ( type == GL_UNSIGNED_BYTE ) { - glVertexAttribPointer( index, size, type, GL_TRUE, stride, 0 ); + vertexAttribPointer( index, size, type, true, stride, 0 ); } else { - glVertexAttribPointer( index, size, type, GL_FALSE, stride, 0 ); + vertexAttribPointer( index, size, type, false, stride, 0 ); } } } @@ -429,16 +429,16 @@ void RendererGL3CP::texCoordPointer( int size, unsigned int type, int stride, co allocateBuffers( allocate ); } - glBindBuffer( GL_ARRAY_BUFFER, mCurTexCoordArray ); - glBufferSubData( GL_ARRAY_BUFFER, 0, allocate, pointer ); + bindBuffer( GL_ARRAY_BUFFER, mCurTexCoordArray ); + bufferSubData( GL_ARRAY_BUFFER, 0, allocate, pointer ); if ( 0 == mTextureUnitsStates[mCurActiveTex] ) { mTextureUnitsStates[mCurActiveTex] = 1; - glEnableVertexAttribArray( index ); + enableVertexAttribArray( index ); } - glVertexAttribPointer( index, size, type, GL_FALSE, stride, 0 ); + vertexAttribPointer( index, size, type, false, stride, 0 ); } } @@ -493,10 +493,10 @@ void RendererGL3CP::clip2DPlaneEnable( const Int32& x, const Int32& y, const Int GLi->enable( GL_CLIP_PLANE2 ); GLi->enable( GL_CLIP_PLANE3 ); - glUniform4fv( mPlanes[0], 1, static_cast( &vclip_left[0] ) ); - glUniform4fv( mPlanes[1], 1, static_cast( &vclip_right[0] ) ); - glUniform4fv( mPlanes[2], 1, static_cast( &vclip_top[0] ) ); - glUniform4fv( mPlanes[3], 1, static_cast( &vclip_bottom[0] ) ); + uniform4fv( mPlanes[0], 1, static_cast( &vclip_left[0] ) ); + uniform4fv( mPlanes[1], 1, static_cast( &vclip_right[0] ) ); + uniform4fv( mPlanes[2], 1, static_cast( &vclip_top[0] ) ); + uniform4fv( mPlanes[3], 1, static_cast( &vclip_bottom[0] ) ); } void RendererGL3CP::clip2DPlaneDisable() { @@ -521,7 +521,7 @@ void RendererGL3CP::clipPlane( unsigned int plane, const double* equation ) { } else { std::string planeNum( "dgl_ClipPlane[" + String::toString( nplane ) + "]" ); - location = glGetUniformLocation( mCurShader->getHandler(), (GLchar*)&planeNum[0] ); + location = getUniformLocation( mCurShader->getHandler(), &planeNum[0] ); } glm::vec4 teq( equation[0], equation[1], equation[2], equation[3] ); @@ -530,7 +530,7 @@ void RendererGL3CP::clipPlane( unsigned int plane, const double* equation ) { glm::inverse( mStack->mModelViewMatrix .top() ); /// Apply the inverse of the model view matrix to the equation - glUniform4f( location, (float)teq[0], (float)teq[1], (float)teq[2], (float)teq[3] ); + uniform4f( location, (float)teq[0], (float)teq[1], (float)teq[2], (float)teq[3] ); } float RendererGL3CP::pointSize() { @@ -573,23 +573,23 @@ void RendererGL3CP::allocateBuffers( const Uint32& size ) { mVBOSizeAlloc = size; - glBindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_VERTEX_ARRAY] ); - glBufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); + bindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_VERTEX_ARRAY] ); + bufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); - glBindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_COLOR_ARRAY] ); - glBufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); + bindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_COLOR_ARRAY] ); + bufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); - glBindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_TEXTURE_COORD_ARRAY] ); - glBufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); + bindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_TEXTURE_COORD_ARRAY] ); + bufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); - glBindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_TEXTURE_COORD_ARRAY + 1] ); - glBufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); + bindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_TEXTURE_COORD_ARRAY + 1] ); + bufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); - glBindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_TEXTURE_COORD_ARRAY + 2] ); - glBufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); + bindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_TEXTURE_COORD_ARRAY + 2] ); + bufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); - glBindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_TEXTURE_COORD_ARRAY + 3] ); - glBufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); + bindBuffer( GL_ARRAY_BUFFER, mVBO[EEGL_TEXTURE_COORD_ARRAY + 3] ); + bufferData( GL_ARRAY_BUFFER, mVBOSizeAlloc, NULL, GL_STREAM_DRAW ); } }} // namespace EE::Graphics diff --git a/src/eepp/graphics/renderer/renderergles2.cpp b/src/eepp/graphics/renderer/renderergles2.cpp index 3e97d4eb5..aa7911a50 100644 --- a/src/eepp/graphics/renderer/renderergles2.cpp +++ b/src/eepp/graphics/renderer/renderergles2.cpp @@ -221,7 +221,7 @@ void RendererGLES2::setShader( ShaderProgram* Shader ) { mTextureUnits[i] = mCurShader->getAttributeLocation( EEGLES2_TEXTUREUNIT_NAMES[i] ); } - glUseProgram( mCurShader->getHandler() ); + useProgram( mCurShader->getHandler() ); if ( -1 != mAttribsLoc[EEGL_VERTEX_ARRAY] ) enableClientState( GL_VERTEX_ARRAY ); @@ -361,7 +361,7 @@ void RendererGLES2::enableClientState( unsigned int array ) { if ( -1 != ( state = mTextureUnits[mCurActiveTex] ) ) { mTextureUnitsStates[mCurActiveTex] = 1; - glEnableVertexAttribArray( state ); + enableVertexAttribArray( state ); } } else { Int32 Pos = array - GL_VERTEX_ARRAY; @@ -369,7 +369,7 @@ void RendererGLES2::enableClientState( unsigned int array ) { if ( -1 != ( state = mAttribsLoc[Pos] ) ) { mAttribsLocStates[Pos] = 1; - glEnableVertexAttribArray( state ); + enableVertexAttribArray( state ); } } } @@ -381,7 +381,7 @@ void RendererGLES2::disableClientState( unsigned int array ) { if ( -1 != ( state = mTextureUnits[mCurActiveTex] ) ) { mTextureUnitsStates[mCurActiveTex] = 0; - glDisableVertexAttribArray( state ); + disableVertexAttribArray( state ); } } else { Int32 Pos = array - GL_VERTEX_ARRAY; @@ -389,7 +389,7 @@ void RendererGLES2::disableClientState( unsigned int array ) { if ( -1 != ( state = mAttribsLoc[Pos] ) ) { mAttribsLocStates[Pos] = 0; - glDisableVertexAttribArray( state ); + disableVertexAttribArray( state ); } } } @@ -402,10 +402,10 @@ void RendererGLES2::vertexPointer( int size, unsigned int type, int stride, cons if ( 0 == mAttribsLocStates[EEGL_VERTEX_ARRAY] ) { mAttribsLocStates[EEGL_VERTEX_ARRAY] = 1; - glEnableVertexAttribArray( index ); + enableVertexAttribArray( index ); } - glVertexAttribPointer( index, size, type, GL_FALSE, stride, pointer ); + vertexAttribPointer( index, size, type, false, stride, pointer ); } } @@ -417,13 +417,13 @@ void RendererGLES2::colorPointer( int size, unsigned int type, int stride, const if ( 0 == mAttribsLocStates[EEGL_COLOR_ARRAY] ) { mAttribsLocStates[EEGL_COLOR_ARRAY] = 1; - glEnableVertexAttribArray( index ); + enableVertexAttribArray( index ); } if ( type == GL_UNSIGNED_BYTE ) { - glVertexAttribPointer( index, size, type, GL_TRUE, stride, pointer ); + vertexAttribPointer( index, size, type, true, stride, pointer ); } else { - glVertexAttribPointer( index, size, type, GL_FALSE, stride, pointer ); + vertexAttribPointer( index, size, type, false, stride, pointer ); } } } @@ -450,10 +450,10 @@ void RendererGLES2::texCoordPointer( int size, unsigned int type, int stride, co if ( 0 == mTextureUnitsStates[mCurActiveTex] ) { mTextureUnitsStates[mCurActiveTex] = 1; - glEnableVertexAttribArray( index ); + enableVertexAttribArray( index ); } - glVertexAttribPointer( index, size, type, GL_FALSE, stride, pointer ); + vertexAttribPointer( index, size, type, false, stride, pointer ); } } @@ -511,10 +511,10 @@ void RendererGLES2::clip2DPlaneEnable( const Int32& x, const Int32& y, const Int GLi->enable( GL_CLIP_PLANE2 ); GLi->enable( GL_CLIP_PLANE3 ); - glUniform4fv( mPlanes[0], 1, static_cast( &vclip_left[0] ) ); - glUniform4fv( mPlanes[1], 1, static_cast( &vclip_right[0] ) ); - glUniform4fv( mPlanes[2], 1, static_cast( &vclip_top[0] ) ); - glUniform4fv( mPlanes[3], 1, static_cast( &vclip_bottom[0] ) ); + uniform4fv( mPlanes[0], 1, static_cast( &vclip_left[0] ) ); + uniform4fv( mPlanes[1], 1, static_cast( &vclip_right[0] ) ); + uniform4fv( mPlanes[2], 1, static_cast( &vclip_top[0] ) ); + uniform4fv( mPlanes[3], 1, static_cast( &vclip_bottom[0] ) ); } void RendererGLES2::clip2DPlaneDisable() { @@ -543,7 +543,7 @@ void RendererGLES2::clipPlane( unsigned int plane, const double* equation ) { } else { std::string planeNum( "dgl_ClipPlane[" + String::toString( nplane ) + "]" ); - location = glGetUniformLocation( mCurShader->getHandler(), (GLchar*)&planeNum[0] ); + location = getUniformLocation( mCurShader->getHandler(), &planeNum[0] ); } glm::vec4 teq( equation[0], equation[1], equation[2], equation[3] ); @@ -552,7 +552,7 @@ void RendererGLES2::clipPlane( unsigned int plane, const double* equation ) { glm::inverse( mStack->mModelViewMatrix .top() ); /// Apply the inverse of the model view matrix to the equation - glUniform4f( location, (float)teq[0], (float)teq[1], (float)teq[2], (float)teq[3] ); + uniform4f( location, (float)teq[0], (float)teq[1], (float)teq[2], (float)teq[3] ); } float RendererGLES2::pointSize() { diff --git a/src/eepp/graphics/shader.cpp b/src/eepp/graphics/shader.cpp index a3ebea993..738fa89ce 100644 --- a/src/eepp/graphics/shader.cpp +++ b/src/eepp/graphics/shader.cpp @@ -89,7 +89,7 @@ Shader::Shader( const Uint32& Type, const char** Data, const Uint32& NumLines ) Shader::~Shader() { if ( 0 != mGLId ) { #ifdef EE_SHADERS_SUPPORTED - glDeleteShader( mGLId ); + GLi->deleteShader( mGLId ); #endif } } @@ -99,7 +99,7 @@ void Shader::Init( const Uint32& Type ) { mValid = false; mCompiled = false; #ifdef EE_SHADERS_SUPPORTED - mGLId = glCreateShader( mType ); + mGLId = GLi->createShader( mType ); #endif } @@ -201,7 +201,7 @@ void Shader::setSource( const std::string& Source ) { #ifdef EE_SHADERS_SUPPORTED const char* src = reinterpret_cast( &mSource[0] ); - glShaderSource( mGLId, 1, &src, NULL ); + GLi->shaderSource( mGLId, 1, &src, NULL ); #endif } @@ -241,22 +241,21 @@ bool Shader::compile() { #ifdef EE_SHADERS_SUPPORTED - glCompileShader( getId() ); + GLi->compileShader( getId() ); mCompiled = true; int Compiled; - glGetShaderiv( getId(), GL_COMPILE_STATUS, &Compiled ); + GLi->getShaderiv( getId(), GL_COMPILE_STATUS, &Compiled ); mValid = 0 != Compiled; if ( !mValid ) { int logsize = 0, logarraysize = 0; - glGetShaderiv( getId(), GL_INFO_LOG_LENGTH, &logarraysize ); + GLi->getShaderiv( getId(), GL_INFO_LOG_LENGTH, &logarraysize ); if ( logarraysize > 0 ) { mCompileLog.resize( logarraysize - 1 ); - glGetShaderInfoLog( getId(), logarraysize, &logsize, - reinterpret_cast( &mCompileLog[0] ) ); + GLi->getShaderInfoLog( getId(), logarraysize, &logsize, &mCompileLog[0] ); } Log::error( "Couldn't compile shader %s. Log follows:\n", getName().c_str() ); diff --git a/src/eepp/graphics/shaderprogram.cpp b/src/eepp/graphics/shaderprogram.cpp index 95c4dcb27..838d26575 100644 --- a/src/eepp/graphics/shaderprogram.cpp +++ b/src/eepp/graphics/shaderprogram.cpp @@ -148,7 +148,7 @@ ShaderProgram::ShaderProgram( const char** VertexShaderData, const Uint32& NumLi ShaderProgram::~ShaderProgram() { if ( getHandler() > 0 ) { #ifdef EE_SHADERS_SUPPORTED - glDeleteProgram( getHandler() ); + GLi->deleteProgram( getHandler() ); #endif } @@ -176,7 +176,7 @@ void ShaderProgram::removeFromManager() { void ShaderProgram::init() { if ( GLi->shadersSupported() && 0 == getHandler() ) { #ifdef EE_SHADERS_SUPPORTED - mHandler = glCreateProgram(); + mHandler = GLi->createProgram(); #endif mValid = false; mUniformLocations.clear(); @@ -215,7 +215,7 @@ void ShaderProgram::addShader( Shader* Shader ) { if ( 0 != getHandler() ) { #ifdef EE_SHADERS_SUPPORTED - glAttachShader( getHandler(), Shader->getId() ); + GLi->attachShader( getHandler(), Shader->getId() ); #endif mShaders.push_back( Shader ); @@ -229,20 +229,19 @@ void ShaderProgram::addShaders( const std::vector& Shaders ) { bool ShaderProgram::link() { #ifdef EE_SHADERS_SUPPORTED - glLinkProgram( getHandler() ); + GLi->linkProgram( getHandler() ); Int32 linked; - glGetProgramiv( getHandler(), GL_LINK_STATUS, &linked ); + GLi->getProgramiv( getHandler(), GL_LINK_STATUS, &linked ); mValid = 0 != linked; int logsize = 0, logarraysize = 0; - glGetProgramiv( getHandler(), GL_INFO_LOG_LENGTH, &logarraysize ); + GLi->getProgramiv( getHandler(), GL_INFO_LOG_LENGTH, &logarraysize ); if ( logarraysize > 0 ) { mLinkLog.resize( logarraysize ); - glGetProgramInfoLog( getHandler(), logarraysize, &logsize, - reinterpret_cast( &mLinkLog[0] ) ); + GLi->getProgramInfoLog( getHandler(), logarraysize, &logsize, &mLinkLog[0] ); mLinkLog.resize( logsize ); } @@ -283,7 +282,7 @@ Int32 ShaderProgram::getUniformLocation( const std::string& Name ) { std::map::iterator it = mUniformLocations.find( Name ); if ( it == mUniformLocations.end() ) { #ifdef EE_SHADERS_SUPPORTED - Int32 Location = glGetUniformLocation( getHandler(), Name.c_str() ); + Int32 Location = GLi->getUniformLocation( getHandler(), Name.c_str() ); mUniformLocations[Name] = Location; #endif } @@ -297,7 +296,7 @@ Int32 ShaderProgram::getAttributeLocation( const std::string& Name ) { std::map::iterator it = mAttributeLocations.find( Name ); if ( it == mAttributeLocations.end() ) { #ifdef EE_SHADERS_SUPPORTED - Int32 Location = glGetAttribLocation( getHandler(), Name.c_str() ); + Int32 Location = GLi->getAttribLocation( getHandler(), Name.c_str() ); mAttributeLocations[Name] = Location; #endif } @@ -332,7 +331,7 @@ bool ShaderProgram::setUniform( const std::string& Name, Int32 Value ) { bool ShaderProgram::setUniform( const Int32& Location, Int32 Value ) { if ( -1 != Location ) { #ifdef EE_SHADERS_SUPPORTED - glUniform1i( Location, Value ); + GLi->uniform1i( Location, Value ); #endif return true; @@ -344,7 +343,7 @@ bool ShaderProgram::setUniform( const Int32& Location, Int32 Value ) { bool ShaderProgram::setUniform( const Int32& Location, float Value ) { if ( -1 != Location ) { #ifdef EE_SHADERS_SUPPORTED - glUniform1f( Location, Value ); + GLi->uniform1f( Location, Value ); #endif return true; @@ -356,7 +355,7 @@ bool ShaderProgram::setUniform( const Int32& Location, float Value ) { bool ShaderProgram::setUniform( const Int32& Location, Vector2ff Value ) { if ( -1 != Location ) { #ifdef EE_SHADERS_SUPPORTED - glUniform2fv( Location, 1, reinterpret_cast( &Value ) ); + GLi->uniform2fv( Location, 1, reinterpret_cast( &Value ) ); #endif return true; @@ -368,7 +367,7 @@ bool ShaderProgram::setUniform( const Int32& Location, Vector2ff Value ) { bool ShaderProgram::setUniform( const Int32& Location, Vector3ff Value ) { if ( -1 != Location ) { #ifdef EE_SHADERS_SUPPORTED - glUniform3fv( Location, 1, reinterpret_cast( &Value ) ); + GLi->uniform3fv( Location, 1, reinterpret_cast( &Value ) ); #endif return true; @@ -380,7 +379,7 @@ bool ShaderProgram::setUniform( const Int32& Location, Vector3ff Value ) { bool ShaderProgram::setUniform( const Int32& Location, float x, float y, float z, float w ) { if ( -1 != Location ) { #ifdef EE_SHADERS_SUPPORTED - glUniform4f( Location, x, y, z, w ); + GLi->uniform4f( Location, x, y, z, w ); #endif return true; @@ -392,7 +391,7 @@ bool ShaderProgram::setUniform( const Int32& Location, float x, float y, float z bool ShaderProgram::setUniformMatrix( const Int32& Location, const float* Value ) { if ( -1 != Location ) { #ifdef EE_SHADERS_SUPPORTED - glUniformMatrix4fv( Location, 1, false, Value ); + GLi->uniformMatrix4fv( Location, 1, false, Value ); #endif return true; @@ -430,7 +429,7 @@ void ShaderProgram::enableVertexAttribArray( const std::string& Name ) { void ShaderProgram::enableVertexAttribArray( const Int32& Location ) { #ifdef EE_SHADERS_SUPPORTED - glEnableVertexAttribArray( Location ); + GLi->enableVertexAttribArray( Location ); #endif } @@ -440,7 +439,7 @@ void ShaderProgram::disableVertexAttribArray( const std::string& Name ) { void ShaderProgram::disableVertexAttribArray( const Int32& Location ) { #ifdef EE_SHADERS_SUPPORTED - glDisableVertexAttribArray( Location ); + GLi->disableVertexAttribArray( Location ); #endif } diff --git a/src/eepp/graphics/texture.cpp b/src/eepp/graphics/texture.cpp index 09740f5a8..74a4025b3 100644 --- a/src/eepp/graphics/texture.cpp +++ b/src/eepp/graphics/texture.cpp @@ -39,8 +39,7 @@ Texture::Texture() : mFlags( 0 ), mClampMode( ClampMode::ClampToEdge ), mFilter( Filter::Linear ), - mCoordinateType( CoordinateType::Normalized ) { -} + mCoordinateType( CoordinateType::Normalized ) {} Texture::Texture( const Texture& Copy ) : DrawableResource( Drawable::TEXTURE, Copy.mName ), @@ -166,7 +165,7 @@ Uint8* Texture::iLock( const bool& ForceRGBA, const bool& KeepFormat ) { allocate( (unsigned int)size ); if ( KeepFormat && ( mFlags & TEX_FLAG_COMPRESSED ) ) { - glGetCompressedTexImage( GL_TEXTURE_2D, 0, reinterpret_cast( &mPixels[0] ) ); + GLi->getCompressedTexImage( GL_TEXTURE_2D, 0, reinterpret_cast( &mPixels[0] ) ); } else { Uint32 Channel = GL_RGBA; @@ -476,8 +475,8 @@ void Texture::reload() { &width, &height, mChannels, mTexture, flags | SOIL_FLAG_COMPRESS_TO_DXT ); else - glCompressedTexImage2D( mTexture, 0, mInternalFormat, width, height, 0, mSize, - &mPixels[0] ); + GLi->compressedTexImage2D( mTexture, 0, mInternalFormat, width, height, 0, + mSize, &mPixels[0] ); } else { mTexture = SOIL_create_OGL_texture( reinterpret_cast( &mPixels[0] ), &width, &height, mChannels, mTexture, flags ); diff --git a/src/eepp/graphics/textureloader.cpp b/src/eepp/graphics/textureloader.cpp index abf7e318a..d664172b7 100644 --- a/src/eepp/graphics/textureloader.cpp +++ b/src/eepp/graphics/textureloader.cpp @@ -145,7 +145,8 @@ void TextureLoader::loadFromFile() { loadFile(); mDirectUpload = true; } else if ( Image::Format::PKM == mImgType && - GLi->isExtension( EEGL_OES_compressed_ETC1_RGB8_texture ) ) { + GLi->isExtension( EEGL_OES_compressed_ETC1_RGB8_texture ) && + GLi->isExtension( EEGL_ARB_ES3_compatibility ) ) { loadFile(); mIsCompressed = mDirectUpload = true; stbi__pkm_info_from_memory( mPixels, mSize, &mImgWidth, &mImgHeight, &mChannels ); @@ -201,7 +202,8 @@ void TextureLoader::loadFromMemory() { memcpy( mPixels, mImagePtr, mSize ); mDirectUpload = true; } else if ( Image::Format::PKM == mImgType && - GLi->isExtension( EEGL_OES_compressed_ETC1_RGB8_texture ) ) { + GLi->isExtension( EEGL_OES_compressed_ETC1_RGB8_texture ) && + GLi->isExtension( EEGL_ARB_ES3_compatibility ) ) { mPixels = (Uint8*)eeMalloc( mSize ); memcpy( mPixels, mImagePtr, mSize ); stbi__pkm_info_from_memory( mPixels, mSize, &mImgWidth, &mImgHeight, &mChannels ); @@ -250,7 +252,8 @@ void TextureLoader::loadFromStream() { mStream->seek( 0 ); mDirectUpload = true; } else if ( Image::Format::PKM == mImgType && - GLi->isExtension( EEGL_OES_compressed_ETC1_RGB8_texture ) ) { + GLi->isExtension( EEGL_OES_compressed_ETC1_RGB8_texture ) && + GLi->isExtension( EEGL_ARB_ES3_compatibility ) ) { mSize = mStream->getSize(); mPixels = (Uint8*)eeMalloc( mSize ); mStream->seek( 0 ); @@ -316,8 +319,8 @@ void TextureLoader::loadFromPixels() { tTexId = SOIL_direct_load_PVR_from_memory( mPixels, mSize, SOIL_CREATE_NEW_ID, flags, 0 ); } else if ( Image::Format::PKM == mImgType ) { - tTexId = SOIL_direct_load_ETC1_from_memory( mPixels, mSize, - SOIL_CREATE_NEW_ID, flags ); + tTexId = SOIL_direct_load_PKM_from_memory( mPixels, mSize, + SOIL_CREATE_NEW_ID, flags ); } } else { if ( NULL != mColorKey ) { diff --git a/src/eepp/graphics/vertexbuffervbo.cpp b/src/eepp/graphics/vertexbuffervbo.cpp index 64acd37f6..2ea72e365 100644 --- a/src/eepp/graphics/vertexbuffervbo.cpp +++ b/src/eepp/graphics/vertexbuffervbo.cpp @@ -65,14 +65,14 @@ bool VertexBufferVBO::compile() { if ( mPosArray.empty() ) return false; - glGenBuffers( 1, (unsigned int*)&mArrayHandle[i] ); - glBindBuffer( GL_ARRAY_BUFFER, mArrayHandle[i] ); + GLi->genBuffers( 1, (unsigned int*)&mArrayHandle[i] ); + GLi->bindBuffer( GL_ARRAY_BUFFER, mArrayHandle[i] ); if ( !mArrayHandle[i] ) return false; - glBufferData( GL_ARRAY_BUFFER, mPosArray.size() * sizeof( Vector2f ), - &( mPosArray[0] ), usageType ); + GLi->bufferData( GL_ARRAY_BUFFER, mPosArray.size() * sizeof( Vector2f ), + &( mPosArray[0] ), usageType ); break; } case VERTEX_FLAG_TEXTURE0: @@ -82,28 +82,28 @@ bool VertexBufferVBO::compile() { if ( mTexCoordArray[i - 1].empty() ) return false; - glGenBuffers( 1, (unsigned int*)&mArrayHandle[i] ); - glBindBuffer( GL_ARRAY_BUFFER, mArrayHandle[i] ); + GLi->genBuffers( 1, (unsigned int*)&mArrayHandle[i] ); + GLi->bindBuffer( GL_ARRAY_BUFFER, mArrayHandle[i] ); if ( !mArrayHandle[i] ) return false; - glBufferData( GL_ARRAY_BUFFER, - mTexCoordArray[i - 1].size() * sizeof( Vector2f ), - &mTexCoordArray[i - 1][0], usageType ); + GLi->bufferData( GL_ARRAY_BUFFER, + mTexCoordArray[i - 1].size() * sizeof( Vector2f ), + &mTexCoordArray[i - 1][0], usageType ); break; case VERTEX_FLAG_COLOR: { if ( mColorArray.empty() ) return false; - glGenBuffers( 1, (unsigned int*)&mArrayHandle[i] ); - glBindBuffer( GL_ARRAY_BUFFER, mArrayHandle[i] ); + GLi->genBuffers( 1, (unsigned int*)&mArrayHandle[i] ); + GLi->bindBuffer( GL_ARRAY_BUFFER, mArrayHandle[i] ); if ( !mArrayHandle[i] ) return false; - glBufferData( GL_ARRAY_BUFFER, mColorArray.size() * sizeof( Color ), - &mColorArray[0], usageType ); + GLi->bufferData( GL_ARRAY_BUFFER, mColorArray.size() * sizeof( Color ), + &mColorArray[0], usageType ); break; } default: @@ -113,19 +113,19 @@ bool VertexBufferVBO::compile() { } if ( GLv_3CP != GLi->version() ) { - glBindBuffer( GL_ARRAY_BUFFER, 0 ); + GLi->bindBuffer( GL_ARRAY_BUFFER, 0 ); } // Create the VBO index array if ( VERTEX_FLAG_QUERY( mVertexFlags, VERTEX_FLAG_USE_INDICES ) && !mIndexArray.empty() ) { - glGenBuffers( 1, (unsigned int*)&mElementHandle ); + GLi->genBuffers( 1, (unsigned int*)&mElementHandle ); - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mElementHandle ); + GLi->bindBuffer( GL_ELEMENT_ARRAY_BUFFER, mElementHandle ); - glBufferData( GL_ELEMENT_ARRAY_BUFFER, getIndexCount() * sizeof( Uint32 ), &mIndexArray[0], - usageType ); + GLi->bufferData( GL_ELEMENT_ARRAY_BUFFER, getIndexCount() * sizeof( Uint32 ), + &mIndexArray[0], usageType ); - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); + GLi->bindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); } mCompiled = true; @@ -162,11 +162,11 @@ void VertexBufferVBO::draw() { if ( mElemDraw < 0 ) lSize = getIndexCount(); - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mElementHandle ); + GLi->bindBuffer( GL_ELEMENT_ARRAY_BUFFER, mElementHandle ); GLi->drawElements( mDrawType, lSize, GL_UNSIGNED_INT, (char*)NULL ); - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); + GLi->bindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); } else { GLi->drawArrays( mDrawType, 0, getVertexCount() ); } @@ -202,7 +202,7 @@ void VertexBufferVBO::setVertexStates() { GLi->clientActiveTexture( GL_TEXTURE0 + i ); GLi->enableClientState( GL_TEXTURE_COORD_ARRAY ); - glBindBuffer( GL_ARRAY_BUFFER, mArrayHandle[VERTEX_FLAG_TEXTURE0 + i] ); + GLi->bindBuffer( GL_ARRAY_BUFFER, mArrayHandle[VERTEX_FLAG_TEXTURE0 + i] ); #ifdef EE_GL3_ENABLED if ( GLv_3 == GLi->version() || GLv_3CP == GLi->version() || @@ -216,8 +216,9 @@ void VertexBufferVBO::setVertexStates() { EEGL_TEXTURE_COORD_ARRAY ) ); if ( -1 != index ) - glVertexAttribPointer( index, VertexElementCount[VERTEX_FLAG_TEXTURE0 + i], - GL_FP, GL_FALSE, 0, 0 ); + GLi->vertexAttribPointer( index, + VertexElementCount[VERTEX_FLAG_TEXTURE0 + i], + GL_FP, false, 0, 0 ); } else #endif { @@ -237,7 +238,7 @@ void VertexBufferVBO::setVertexStates() { } else { if ( VERTEX_FLAG_QUERY( mVertexFlags, VERTEX_FLAG_TEXTURE0 ) ) { GLi->enableClientState( GL_TEXTURE_COORD_ARRAY ); - glBindBuffer( GL_ARRAY_BUFFER, mArrayHandle[VERTEX_FLAG_TEXTURE0] ); + GLi->bindBuffer( GL_ARRAY_BUFFER, mArrayHandle[VERTEX_FLAG_TEXTURE0] ); #ifdef EE_GL3_ENABLED if ( GLv_3 == GLi->version() || GLv_3CP == GLi->version() || @@ -251,8 +252,8 @@ void VertexBufferVBO::setVertexStates() { EEGL_TEXTURE_COORD_ARRAY ) ); if ( -1 != index ) - glVertexAttribPointer( index, VertexElementCount[VERTEX_FLAG_TEXTURE0], GL_FP, - GL_FALSE, 0, 0 ); + GLi->vertexAttribPointer( index, VertexElementCount[VERTEX_FLAG_TEXTURE0], + GL_FP, false, 0, 0 ); } else #endif { @@ -272,7 +273,7 @@ void VertexBufferVBO::setVertexStates() { /// POSITION if ( VERTEX_FLAG_QUERY( mVertexFlags, VERTEX_FLAG_POSITION ) ) { GLi->enableClientState( GL_VERTEX_ARRAY ); - glBindBuffer( GL_ARRAY_BUFFER, mArrayHandle[VERTEX_FLAG_POSITION] ); + GLi->bindBuffer( GL_ARRAY_BUFFER, mArrayHandle[VERTEX_FLAG_POSITION] ); #ifdef EE_GL3_ENABLED if ( GLv_3 == GLi->version() || GLv_3CP == GLi->version() || GLv_ES2 == GLi->version() ) { @@ -283,8 +284,8 @@ void VertexBufferVBO::setVertexStates() { : GLi->getRendererGLES2()->getStateIndex( EEGL_VERTEX_ARRAY ) ); if ( -1 != index ) - glVertexAttribPointer( index, VertexElementCount[VERTEX_FLAG_POSITION], GL_FP, - GL_FALSE, 0, 0 ); + GLi->vertexAttribPointer( index, VertexElementCount[VERTEX_FLAG_POSITION], GL_FP, + false, 0, 0 ); } else #endif { @@ -298,7 +299,7 @@ void VertexBufferVBO::setVertexStates() { /// COLOR if ( VERTEX_FLAG_QUERY( mVertexFlags, VERTEX_FLAG_COLOR ) ) { GLi->enableClientState( GL_COLOR_ARRAY ); - glBindBuffer( GL_ARRAY_BUFFER, mArrayHandle[VERTEX_FLAG_COLOR] ); + GLi->bindBuffer( GL_ARRAY_BUFFER, mArrayHandle[VERTEX_FLAG_COLOR] ); #ifdef EE_GL3_ENABLED if ( GLv_3 == GLi->version() || GLv_3CP == GLi->version() || GLv_ES2 == GLi->version() ) { @@ -309,8 +310,8 @@ void VertexBufferVBO::setVertexStates() { : GLi->getRendererGLES2()->getStateIndex( EEGL_COLOR_ARRAY ) ); if ( -1 != index ) - glVertexAttribPointer( index, VertexElementCount[VERTEX_FLAG_COLOR], - GL_UNSIGNED_BYTE, GL_TRUE, 0, 0 ); + GLi->vertexAttribPointer( index, VertexElementCount[VERTEX_FLAG_COLOR], + GL_UNSIGNED_BYTE, true, 0, 0 ); } else #endif { @@ -337,26 +338,26 @@ void VertexBufferVBO::update( const Uint32& types, bool indices ) { for ( Int32 i = 0; i < VERTEX_FLAGS_COUNT; i++ ) { if ( VERTEX_FLAG_QUERY( mVertexFlags, i ) && VERTEX_FLAG_QUERY( types, i ) ) { - glBindBuffer( GL_ARRAY_BUFFER, mArrayHandle[i] ); + GLi->bindBuffer( GL_ARRAY_BUFFER, mArrayHandle[i] ); if ( mArrayHandle[i] ) { switch ( i ) { case VERTEX_FLAG_POSITION: { - glBufferData( GL_ARRAY_BUFFER, mPosArray.size() * sizeof( Vector2f ), - &( mPosArray[0] ), usageType ); + GLi->bufferData( GL_ARRAY_BUFFER, mPosArray.size() * sizeof( Vector2f ), + &( mPosArray[0] ), usageType ); break; } case VERTEX_FLAG_TEXTURE0: case VERTEX_FLAG_TEXTURE1: case VERTEX_FLAG_TEXTURE2: case VERTEX_FLAG_TEXTURE3: - glBufferData( GL_ARRAY_BUFFER, - mTexCoordArray[i - 1].size() * sizeof( Vector2f ), - &mTexCoordArray[i - 1][0], usageType ); + GLi->bufferData( GL_ARRAY_BUFFER, + mTexCoordArray[i - 1].size() * sizeof( Vector2f ), + &mTexCoordArray[i - 1][0], usageType ); break; case VERTEX_FLAG_COLOR: { - glBufferData( GL_ARRAY_BUFFER, mColorArray.size() * sizeof( Color ), - &mColorArray[0], usageType ); + GLi->bufferData( GL_ARRAY_BUFFER, mColorArray.size() * sizeof( Color ), + &mColorArray[0], usageType ); break; } default: @@ -366,15 +367,15 @@ void VertexBufferVBO::update( const Uint32& types, bool indices ) { } } - glBindBuffer( GL_ARRAY_BUFFER, 0 ); + GLi->bindBuffer( GL_ARRAY_BUFFER, 0 ); if ( VERTEX_FLAG_QUERY( mVertexFlags, VERTEX_FLAG_USE_INDICES ) && indices ) { - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mElementHandle ); + GLi->bindBuffer( GL_ELEMENT_ARRAY_BUFFER, mElementHandle ); - glBufferData( GL_ELEMENT_ARRAY_BUFFER, getIndexCount() * sizeof( Uint32 ), &mIndexArray[0], - usageType ); + GLi->bufferData( GL_ELEMENT_ARRAY_BUFFER, getIndexCount() * sizeof( Uint32 ), + &mIndexArray[0], usageType ); - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); + GLi->bindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); } mBuffersSet = false; @@ -389,7 +390,7 @@ void VertexBufferVBO::reload() { void VertexBufferVBO::unbind() { if ( GLv_3CP != GLi->version() ) { - glBindBuffer( GL_ARRAY_BUFFER, 0 ); + GLi->bindBuffer( GL_ARRAY_BUFFER, 0 ); } if ( !mTextured ) { @@ -414,13 +415,13 @@ void VertexBufferVBO::clear() { for ( Int32 i = 0; i < VERTEX_FLAGS_COUNT; i++ ) { if ( VERTEX_FLAG_QUERY( mVertexFlags, i ) && mArrayHandle[i] ) { - glDeleteBuffers( 1, (unsigned int*)&mArrayHandle[i] ); + GLi->deleteBuffers( 1, (unsigned int*)&mArrayHandle[i] ); mArrayHandle[i] = 0; } } if ( VERTEX_FLAG_QUERY( mVertexFlags, VERTEX_FLAG_USE_INDICES ) && mElementHandle ) { - glDeleteBuffers( 1, (unsigned int*)&mElementHandle ); + GLi->deleteBuffers( 1, (unsigned int*)&mElementHandle ); mElementHandle = 0; } diff --git a/src/eepp/math/easing.cpp b/src/eepp/math/easing.cpp index edb944b97..365cbe39a 100644 --- a/src/eepp/math/easing.cpp +++ b/src/eepp/math/easing.cpp @@ -1,4 +1,5 @@ #include +#include namespace EE { namespace Math { namespace easing { @@ -70,7 +71,7 @@ double getSlope( double aT, double aA1, double aA2 ) { double binarySubdivide( double aX, double aA, double aB, double mX1, double mX2 ) { double currentX, currentT; - size_t i = 0; + std::size_t i = 0; do { currentT = aA + ( aB - aA ) / 2.0; currentX = calcBezier( currentT, mX1, mX2 ) - aX; @@ -84,7 +85,7 @@ double binarySubdivide( double aX, double aA, double aB, double mX1, double mX2 } double newtonRaphsonIterate( double aX, double aGuessT, double mX1, double mX2 ) { - for ( size_t i = 0; i < NEWTON_ITERATIONS; ++i ) { + for ( std::size_t i = 0; i < NEWTON_ITERATIONS; ++i ) { double currentSlope = getSlope( aGuessT, mX1, mX2 ); if ( currentSlope == 0.0 ) { return aGuessT; @@ -104,12 +105,12 @@ double cubicBezierInterpolation( double x1, double y1, double x2, double y2, dou // Precompute samples table double sampleValues[kSplineTableSize]; - for ( size_t i = 0; i < kSplineTableSize; ++i ) + for ( std::size_t i = 0; i < kSplineTableSize; ++i ) sampleValues[i] = calcBezier( i * kSampleStepSize, x1, x2 ); auto getTForX = [&sampleValues, x1, x2]( double aX ) { double intervalStart = 0.0; - size_t currentSample = 1; + std::size_t currentSample = 1; double lastSample = kSplineTableSize - 1; for ( ; currentSample != lastSample && sampleValues[currentSample] <= aX; diff --git a/src/eepp/ui/abstract/uiabstracttableview.cpp b/src/eepp/ui/abstract/uiabstracttableview.cpp index 2b8e2eb29..dd6e331a2 100644 --- a/src/eepp/ui/abstract/uiabstracttableview.cpp +++ b/src/eepp/ui/abstract/uiabstracttableview.cpp @@ -539,8 +539,7 @@ UITableRow* UIAbstractTableView::createRow() { } } ); rowWidget->on( Event::MouseClick, [this]( const Event* event ) { - if ( !( event->asMouseEvent()->getFlags() & ( EE_BUTTON_LMASK ) ) || - !isRowSelection() ) + if ( !( event->asMouseEvent()->getFlags() & ( EE_BUTTON_LMASK ) ) || !isRowSelection() ) return; auto index = event->getNode()->asType()->getCurIndex(); @@ -919,12 +918,8 @@ Uint32 UIAbstractTableView::onTextInput( const TextInputEvent& event ) { return 0; if ( mSearchTextAction ) removeAction( mSearchTextAction ); - mSearchTextAction = Actions::Runnable::New( - [this] { - mSearchTextAction = nullptr; - mSearchText = ""; - }, - Milliseconds( 750 ) ); + mSearchTextAction = + Actions::Runnable::New( [this] { resetSearchText(); }, Milliseconds( 750 ) ); runAction( mSearchTextAction ); mSearchText += String::trim( String::toLower( event.getText() ) ); if ( mSearchText.empty() ) @@ -960,6 +955,13 @@ Uint32 UIAbstractTableView::onTextInput( const TextInputEvent& event ) { return 1; } +void UIAbstractTableView::resetSearchText() { + if ( mSearchTextAction ) + removeAction( mSearchTextAction ); + mSearchTextAction = nullptr; + mSearchText = ""; +} + bool UIAbstractTableView::tryBeginEditing( KeyBindings::Shortcut fromShortcut ) { if ( isEditable() && getSelection().first().isValid() && getModel() && getModel()->isEditable( getSelection().first() ) && diff --git a/src/eepp/ui/blocklayouter.cpp b/src/eepp/ui/blocklayouter.cpp index 9dd665581..3fd9fe173 100644 --- a/src/eepp/ui/blocklayouter.cpp +++ b/src/eepp/ui/blocklayouter.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,11 @@ static bool isStretchedFlexItem( UIHTMLWidget* widget ) { return false; } +static bool isTableCellInTableRow( UIWidget* widget ) { + return widget && widget->isType( UI_TYPE_HTML_TABLE_CELL ) && widget->getParent() && + widget->getParent()->isType( UI_TYPE_HTML_TABLE_ROW ); +} + Float BlockLayouter::getMinIntrinsicWidth() { computeIntrinsicWidths(); return mMinIntrinsicWidth; @@ -106,7 +112,8 @@ void BlockLayouter::updateLayout() { { mContainer->lengthFromValue( *prop ), mContainer->getPixelsSize().getHeight() } ); } - if ( mContainer->getLayoutHeightPolicy() == SizePolicy::Fixed && mContainer->getUIStyle() && + if ( !isTableCellInTableRow( mContainer ) && + mContainer->getLayoutHeightPolicy() == SizePolicy::Fixed && mContainer->getUIStyle() && ( prop = mContainer->getUIStyle()->getProperty( PropertyId::Height ) ) ) { mContainer->setInternalPixelsSize( { mContainer->getPixelsSize().getWidth(), mContainer->lengthFromValue( *prop ) } ); diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index 99f243dcb..2612f0e55 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -45,6 +45,9 @@ bool TextDocument::fileMightBeBinary( const std::string& file ) { (char)0x06 }; // Empty ZIP static constexpr std::array ZIP_SPANNED = { 'P', 'K', (char)0x07, (char)0x08 }; // Spanned ZIP + static constexpr std::array ASTC_MAGIC = { (char)0x13, (char)0xAB, (char)0xA1, + (char)0x5C }; + static constexpr std::array PKM_MAGIC = { 'P', 'K', 'M', ' ' }; // UTF-8/UTF-16/UTF-32 BOMs (to avoid misclassifying as binary) static constexpr std::array UTF8_BOM = { (char)0xEF, (char)0xBB, (char)0xBF }; static constexpr std::array UTF16BE_BOM = { (char)0xFE, (char)0xFF }; @@ -90,6 +93,8 @@ bool TextDocument::fileMightBeBinary( const std::string& file ) { std::equal( ZIP_MAGIC.begin(), ZIP_MAGIC.end(), buffer.begin() ) || std::equal( ZIP_EMPTY.begin(), ZIP_EMPTY.end(), buffer.begin() ) || std::equal( ZIP_SPANNED.begin(), ZIP_SPANNED.end(), buffer.begin() ) || + std::equal( ASTC_MAGIC.begin(), ASTC_MAGIC.end(), buffer.begin() ) || + std::equal( PKM_MAGIC.begin(), PKM_MAGIC.end(), buffer.begin() ) || ( bytesRead >= 5 && std::equal( PDF_MAGIC.begin(), PDF_MAGIC.end(), buffer.begin() ) ) ) { return true; // Known binary file type diff --git a/src/eepp/ui/doc/textformat.cpp b/src/eepp/ui/doc/textformat.cpp index c1556d9d1..f9097b69d 100644 --- a/src/eepp/ui/doc/textformat.cpp +++ b/src/eepp/ui/doc/textformat.cpp @@ -110,21 +110,23 @@ struct ShiftJIS { return {}; Uint8 first = view[0]; - if ( first < 0x7F ) + if ( first <= 0x7F || ( first >= 0xA1 && first <= 0xDF ) ) return { first, TextDecodeResult::Status::Valid, 1 }; - if ( view.size() < 2 && - ( ( first >= secondByteRange1.first && first <= secondByteRange1.second ) || - ( first >= secondByteRange2.first && first <= secondByteRange2.second ) ) ) { - return { first, TextDecodeResult::Status::Valid, 1 }; - } + const bool isLeadByte = + ( first >= firstByteRange1.first && first <= firstByteRange1.second ) || + ( first >= firstByteRange2.first && first <= firstByteRange2.second ); + + if ( !isLeadByte ) + return { first, TextDecodeResult::Status::Invalid, 1 }; + + if ( view.size() < 2 ) + return { first, TextDecodeResult::Status::Truncated, 1 }; Uint8 second = view[1]; - if ( ( ( first >= firstByteRange1.first && first <= firstByteRange1.second ) || - ( first >= firstByteRange2.first && first <= firstByteRange2.second ) ) && - ( ( second >= secondByteRange1.first && second <= secondByteRange1.second ) || - ( second >= secondByteRange2.first && second <= secondByteRange2.second ) ) ) { + if ( ( second >= secondByteRange1.first && second <= secondByteRange1.second ) || + ( second >= secondByteRange2.first && second <= secondByteRange2.second ) ) { return { getUnit( view.data() ), TextDecodeResult::Status::Valid, 2 }; } diff --git a/src/eepp/ui/tablelayouter.cpp b/src/eepp/ui/tablelayouter.cpp index 0a44f840b..d2b2158be 100644 --- a/src/eepp/ui/tablelayouter.cpp +++ b/src/eepp/ui/tablelayouter.cpp @@ -8,6 +8,36 @@ static inline Float sanitizeFloat( Float val ) { return std::isfinite( val ) ? val : 0.f; } +static Float specifiedHeightPx( UIWidget* widget ) { + if ( widget == nullptr || widget->getUIStyle() == nullptr ) + return 0.f; + + const StyleSheetProperty* prop = widget->getUIStyle()->getProperty( PropertyId::Height ); + if ( prop == nullptr ) + return 0.f; + + return sanitizeFloat( widget->lengthFromValue( *prop ) ); +} + +static Float normalFlowChildrenBottomPx( UIWidget* widget ) { + if ( widget == nullptr ) + return 0.f; + + Float bottom = 0.f; + for ( Node* child = widget->getFirstChild(); child; child = child->getNextNode() ) { + if ( !child->isWidget() || !child->isVisible() ) + continue; + if ( child->isType( UI_TYPE_HTML_WIDGET ) && child->asType()->isOutOfFlow() ) + continue; + + UIWidget* childWidget = child->asType(); + const Float childTop = childWidget->getPixelsPosition().y; + bottom = std::max( bottom, childTop + childWidget->getPixelsSize().getHeight() ); + bottom = std::max( bottom, childTop + normalFlowChildrenBottomPx( childWidget ) ); + } + return sanitizeFloat( bottom ); +} + void TableLayouter::setTableLayout( TableLayout layout ) { if ( layout != mTableLayout ) { mTableLayout = layout; @@ -479,9 +509,9 @@ void TableLayouter::updateLayout() { Uint32 colIndex = 0; for ( Uint32 c = 0; c < columnCount; ++c ) { UIHTMLTableCell* cell = mCells[start + c]; - cell->beginAttributesTransaction(); - cell->setLayoutWidthPolicy( SizePolicy::Fixed ); - cell->setLayoutHeightPolicy( SizePolicy::WrapContent ); + Float cellSpecifiedHeight = specifiedHeightPx( cell ); + cell->mWidthPolicy = SizePolicy::Fixed; + cell->mHeightPolicy = SizePolicy::WrapContent; Uint32 cellColspan = cell->getColSpan(); Float cellWidth = 0; for ( Uint32 j = 0; j < cellColspan && ( colIndex + j ) < maxCols; ++j ) { @@ -490,19 +520,30 @@ void TableLayouter::updateLayout() { if ( cellColspan > 1 ) cellWidth += ( cellColspan - 1 ) * mCellspacing; cell->setPixelsSize( cellWidth, cell->getPixelsSize().getHeight() ); - cell->updateLayout(); - cell->setLayoutHeightPolicy( SizePolicy::Fixed ); - cell->endAttributesTransaction(); - rowHeight = std::max( rowHeight, cell->getPixelsSize().getHeight() ); + cell->UIRichText::updateLayout(); + cell->mHeightPolicy = SizePolicy::Fixed; + // CSS Tables: a single-row table-cell height contributes to the row minimum + // height. It must not clamp content that needs more space. + Float cellMinHeight = + std::max( cell->getPixelsSize().getHeight(), cellSpecifiedHeight ); + if ( cellSpecifiedHeight > 0.f ) + cellMinHeight = std::max( cellMinHeight, normalFlowChildrenBottomPx( cell ) ); + rowHeight = std::max( rowHeight, cellMinHeight ); colIndex += cellColspan; } + UIHTMLTableRow* row = mRows[r]; + // CSS Tables: row height is also a minimum, not a hard height. + if ( row->getLayoutHeightPolicy() == SizePolicy::Fixed ) + rowHeight = std::max( rowHeight, specifiedHeightPx( row ) ); + Float currentX = mCellspacing; colIndex = 0; for ( Uint32 c = 0; c < columnCount; ++c ) { UIHTMLTableCell* cell = mCells[start + c]; - cell->beginAttributesTransaction(); cell->setPixelsPosition( currentX, 0 ); + cell->mWidthPolicy = SizePolicy::Fixed; + cell->mHeightPolicy = SizePolicy::Fixed; Uint32 cellColspan = cell->getColSpan(); Float cellWidth = 0; for ( Uint32 j = 0; j < cellColspan && ( colIndex + j ) < maxCols; ++j ) { @@ -510,19 +551,11 @@ void TableLayouter::updateLayout() { } if ( cellColspan > 1 ) cellWidth += ( cellColspan - 1 ) * mCellspacing; - cell->setPixelsSize( cellWidth, rowHeight ); - cell->endAttributesTransaction(); + cell->setInternalPixelsSize( { cellWidth, rowHeight } ); currentX += cellWidth + mCellspacing; colIndex += cellColspan; } - UIHTMLTableRow* row = mRows[r]; - // Respect the row's specified height (e.g., ) - if ( row->getLayoutHeightPolicy() == SizePolicy::Fixed ) { - Float rowSpecifiedHeight = row->getPropertyHeight(); - if ( rowSpecifiedHeight > 0.f ) - rowHeight = std::max( rowHeight, rowSpecifiedHeight ); - } row->setPixelsSize( containerWidth - paddingH, rowHeight ); if ( r == 0 && mCells[start]->getParent() && diff --git a/src/eepp/ui/uifiledialog.cpp b/src/eepp/ui/uifiledialog.cpp index a5dbbf1fa..fd30c2b44 100644 --- a/src/eepp/ui/uifiledialog.cpp +++ b/src/eepp/ui/uifiledialog.cpp @@ -11,6 +11,9 @@ #include #include #include + +#include + #include #include #include @@ -180,7 +183,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa if ( event->asKeyEvent()->getKeyCode() == KEY_BACKSPACE ) goFolderUp(); } ); - mMultiView->on( Event::OnModelEvent, [&]( const Event* event ) { + mMultiView->on( Event::OnModelEvent, [this]( const Event* event ) { const ModelEvent* modelEvent = static_cast( event ); if ( modelEvent->getModelEventType() == ModelEventType::Open ) { Variant vPath( @@ -195,6 +198,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa shouldOpenFolder = true; } } + mMultiView->getCurrentView()->resetSearchText(); openFileOrFolder( shouldOpenFolder ); } } @@ -341,24 +345,28 @@ void UIFileDialog::setTheme( UITheme* Theme ) { if ( icon ) { mButtonUp->setText( "" ); mButtonUp->setIcon( icon ); + mButtonUp->setTooltipText( i18n( "uifiledialog_go_up", "Up" ) ); } icon = getUISceneNode()->findIconDrawable( "folder-add", PixelDensity::dpToPxI( 16 ) ); if ( icon ) { mButtonNewFolder->setText( "" ); mButtonNewFolder->setIcon( icon ); + mButtonNewFolder->setTooltipText( i18n( "uifiledialog_new_folder", "New Folder" ) ); } icon = getUISceneNode()->findIconDrawable( "list-view", PixelDensity::dpToPxI( 16 ) ); if ( icon ) { mButtonListView->setText( "" ); mButtonListView->setIcon( icon ); + mButtonListView->setTooltipText( i18n( "uifiledialog_list", "List" ) ); } icon = getUISceneNode()->findIconDrawable( "table-view", PixelDensity::dpToPxI( 16 ) ); if ( icon ) { mButtonTableView->setText( "" ); mButtonTableView->setIcon( icon ); + mButtonTableView->setTooltipText( i18n( "uifiledialog_table", "Table" ) ); } onThemeLoaded(); @@ -1064,4 +1072,16 @@ void UIFileDialog::scheduledUpdate( const Time& time ) { } } +nlohmann::json UIFileDialog::serialize() const { + nlohmann::json j = UIWindow::serialize(); + j["view_mode"] = static_cast( getViewMode() ); + return j; +} + +void UIFileDialog::unserialize( const nlohmann::json& j ) { + UIWindow::unserialize( j ); + if ( j.contains( "view_mode" ) ) + setViewMode( static_cast( j["view_mode"].get() ) ); +} + }} // namespace EE::UI diff --git a/src/eepp/ui/uimultimodelview.cpp b/src/eepp/ui/uimultimodelview.cpp index c133e25f2..c54f34126 100644 --- a/src/eepp/ui/uimultimodelview.cpp +++ b/src/eepp/ui/uimultimodelview.cpp @@ -64,7 +64,7 @@ void UIMultiModelView::setViewMode( const ViewMode& mode ) { } } -UIAbstractView* UIMultiModelView::getCurrentView() const { +UIAbstractTableView* UIMultiModelView::getCurrentView() const { switch ( mMode ) { case Table: return mTable; diff --git a/src/eepp/ui/uiwindow.cpp b/src/eepp/ui/uiwindow.cpp index a90d6d7e4..3c138c777 100644 --- a/src/eepp/ui/uiwindow.cpp +++ b/src/eepp/ui/uiwindow.cpp @@ -18,6 +18,8 @@ #include #include +#include + #define PUGIXML_HEADER_ONLY #include @@ -1843,4 +1845,66 @@ void UIWindow::setCheckEphemeralCloseFn( std::function mCheckEphemeralCloseFn = fn; } +nlohmann::json UIWindow::serialize() const { + nlohmann::json j; + j["size"]["dp"]["width"] = getSize().asInt().x; + j["size"]["dp"]["height"] = getSize().asInt().y; + j["size"]["percentage"]["width"] = getPixelsSize().x / getUISceneNode()->getSize().x; + j["size"]["percentage"]["height"] = getPixelsSize().y / getUISceneNode()->getSize().y; + j["position"]["dp"]["x"] = getPosition().asInt().x; + j["position"]["dp"]["y"] = getPosition().asInt().y; + j["position"]["percentage"]["x"] = getPixelsPosition().x / getUISceneNode()->getSize().x; + j["position"]["percentage"]["y"] = getPixelsPosition().y / getUISceneNode()->getSize().y; + return j; +} + +void UIWindow::unserialize( const nlohmann::json& j ) { + if ( !j.contains( "size" ) && !j.contains( "position" ) ) + return; + + const Sizef& viewSize( getUISceneNode()->getSize() ); + bool useDp = true; + + if ( j.contains( "size" ) && j["size"].contains( "dp" ) ) { + const auto& dp = j["size"]["dp"]; + Sizef sz( dp["width"].get(), dp["height"].get() ); + if ( sz.getWidth() > viewSize.getWidth() || sz.getHeight() > viewSize.getHeight() ) + useDp = false; + } + + if ( useDp && j.contains( "position" ) && j["position"].contains( "dp" ) ) { + const auto& dp = j["position"]["dp"]; + Vector2f pos( dp["x"].get(), dp["y"].get() ); + Sizef sz( getSize() ); + if ( j.contains( "size" ) && j["size"].contains( "dp" ) ) + sz = Sizef( j["size"]["dp"]["width"].get(), + j["size"]["dp"]["height"].get() ); + if ( pos.x + sz.getWidth() > viewSize.getWidth() || + pos.y + sz.getHeight() > viewSize.getHeight() ) + useDp = false; + } + + if ( useDp ) { + if ( j.contains( "size" ) && j["size"].contains( "dp" ) ) { + const auto& dp = j["size"]["dp"]; + setSize( Sizef( dp["width"].get(), dp["height"].get() ) ); + } + if ( j.contains( "position" ) && j["position"].contains( "dp" ) ) { + const auto& dp = j["position"]["dp"]; + setPosition( Vector2f( dp["x"].get(), dp["y"].get() ) ); + } + } else { + if ( j.contains( "size" ) && j["size"].contains( "percentage" ) ) { + const auto& pct = j["size"]["percentage"]; + setSize( Sizef( pct["width"].get() * viewSize.getWidth(), + pct["height"].get() * viewSize.getHeight() ) ); + } + if ( j.contains( "position" ) && j["position"].contains( "percentage" ) ) { + const auto& pct = j["position"]["percentage"]; + setPosition( Vector2f( pct["x"].get() * viewSize.getWidth(), + pct["y"].get() * viewSize.getHeight() ) ); + } + } +} + }} // namespace EE::UI diff --git a/src/tests/test_all/test.cpp b/src/tests/test_all/test.cpp index 7a9f5ba63..3455fbc9a 100644 --- a/src/tests/test_all/test.cpp +++ b/src/tests/test_all/test.cpp @@ -565,17 +565,18 @@ void EETest::createBaseUI() { Event::MouseClick, [this]( auto event ) { onMainClick( event ); } ); #ifdef EE_PLATFORM_TOUCH - UISkin nSkin( "button-te" ); - nSkin.setStateDrawable( UIState::getStateNumber( "normal" ), - TF->loadFromFile( MyPath + "sprites/button-te_normal.png" ) ); - nSkin.setStateDrawable( UIState::getStateNumber( "pressed" ), - TF->loadFromFile( MyPath + "sprites/button-te_mdown.png" ) ); + UISkin* nSkin = UISkin::New( "button-te" ); + nSkin->setStateDrawable( UIState::getStateNumber( "normal" ), + TF->loadFromFile( MyPath + "sprites/button-te_normal.png" ) ); + nSkin->setStateDrawable( UIState::getStateNumber( "pressed" ), + TF->loadFromFile( MyPath + "sprites/button-te_mdown.png" ) ); Sizef screenSize = SceneManager::instance()->getUISceneNode()->getSize(); mShowMenu = UIPushButton::New(); mShowMenu->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent ); mShowMenu->setPadding( Rectf( 16, 0, 16, 0 ) ); - mShowMenu->setSkin( nSkin ); + mShowMenu->setSkin( *nSkin ); + eeSAFE_DELETE( nSkin ); mShowMenu->setText( "Show Menu" ); mShowMenu->setPosition( screenSize.getWidth() - mShowMenu->getSize().getWidth() - 32, screenSize.getHeight() - mShowMenu->getSize().getHeight() - 9 ); diff --git a/src/tests/unit_tests/richtext_tests.cpp b/src/tests/unit_tests/richtext_tests.cpp index 5c87b1042..484abe2fa 100644 --- a/src/tests/unit_tests/richtext_tests.cpp +++ b/src/tests/unit_tests/richtext_tests.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include using namespace EE; @@ -1869,6 +1870,122 @@ UTEST( UIHTMLTable, basicLayout ) { destroyRichTextScene( sceneNode ); } +UTEST( UIHTMLTable, cellHeightIsMinimumForInlineContentHitTest ) { + auto sceneNode = createRichTextScene(); + ASSERT_TRUE( sceneNode != nullptr ); + + String xml = R"xml( + + + + +
+ Link +
+ )xml"; + + sceneNode->loadLayoutFromString( xml ); + sceneNode->update( Time::Zero ); + + auto* table = sceneNode->find( "table" ); + auto* cell = sceneNode->find( "cell" ); + auto* link = sceneNode->find( "link" ); + ASSERT_TRUE( table != nullptr ); + ASSERT_TRUE( cell != nullptr ); + ASSERT_TRUE( link != nullptr ); + ASSERT_FALSE( link->getHitBoxes().empty() ); + + const Rectf& hitBox = link->getHitBoxes().front(); + EXPECT_GT( cell->getPixelsSize().getHeight(), 10.f ); + EXPECT_GE( cell->getPixelsSize().getHeight(), link->getPixelsPosition().y + hitBox.Bottom ); + + Vector2f hitPos = link->convertToWorldSpace( + { hitBox.Left + 1.f, eemax( hitBox.Top, hitBox.Bottom - 1.f ) } ); + Node* hitNode = table->overFind( hitPos ); + EXPECT_EQ( hitNode, link ); + + destroyRichTextScene( sceneNode ); +} + +UTEST( UIHTMLTable, cellHeightStretchesToRowMinimum ) { + auto sceneNode = createRichTextScene(); + ASSERT_TRUE( sceneNode != nullptr ); + + String xml = R"xml( + + + + + +
+ )xml"; + + sceneNode->loadLayoutFromString( xml ); + sceneNode->update( Time::Zero ); + + auto* logo = sceneNode->find( "logo" ); + auto* nav = sceneNode->find( "nav" ); + ASSERT_TRUE( logo != nullptr ); + ASSERT_TRUE( nav != nullptr ); + + EXPECT_GT( logo->getPixelsSize().getHeight(), 10.f ); + EXPECT_EQ( nav->getPixelsSize().getHeight(), logo->getPixelsSize().getHeight() ); + + destroyRichTextScene( sceneNode ); +} + +UTEST( UIHTMLTable, tableCellAnchorHoverRelayoutsRichText ) { + auto sceneNode = createRichTextScene(); + ASSERT_TRUE( sceneNode != nullptr ); + + String xml = R"xml( + + + + + + +
+ )xml"; + + sceneNode->loadLayoutFromString( xml ); + sceneNode->update( Time::Zero ); + + auto* nav = sceneNode->find( "nav" ); + auto* link = sceneNode->find( "link" ); + ASSERT_TRUE( nav != nullptr ); + ASSERT_TRUE( link != nullptr ); + ASSERT_FALSE( link->getHitBoxes().empty() ); + auto renderedAnchorStyle = [&nav]() -> Uint32 { + for ( const auto& line : nav->getRichText().getLines() ) { + for ( const auto& span : line.spans ) { + if ( span.type == RichText::RenderSpan::Type::Text && span.text && + span.text->getString() == "Nav" ) + return span.text->getStyle(); + } + } + return 0; + }; + + EXPECT_FALSE( ( renderedAnchorStyle() & Text::Underlined ) != 0 ); + EXPECT_GT( nav->getPixelsSize().getHeight(), 10.f ); + + const Rectf& hitBox = link->getHitBoxes().front(); + Vector2f hoverPos = link->convertToWorldSpace( { hitBox.Left + 1.f, hitBox.Top + 1.f } ); + EXPECT_EQ( sceneNode->overFind( hoverPos ), link ); + + sceneNode->getEventDispatcher()->getInput()->setMousePos( hoverPos.asInt() ); + sceneNode->update( Time::Zero ); + + EXPECT_TRUE( ( renderedAnchorStyle() & Text::Underlined ) != 0 ); + EXPECT_GT( nav->getPixelsSize().getHeight(), 10.f ); + + destroyRichTextScene( sceneNode ); +} + UTEST( UIRichText, WhitespaceCollapseBRTest ) { auto sceneNode = createRichTextScene(); ASSERT_TRUE( sceneNode != nullptr ); diff --git a/src/tests/unit_tests/textformat_tests.cpp b/src/tests/unit_tests/textformat_tests.cpp index c94116e0a..e79c2d4a0 100644 --- a/src/tests/unit_tests/textformat_tests.cpp +++ b/src/tests/unit_tests/textformat_tests.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,20 @@ UTEST( TextFormat, autodetect ) { } } +UTEST( TextFormat, autodetectSingleInvalidShiftJISByte ) { + const char data[] = { static_cast( 0xFF ) }; + IOStreamMemory stream( data, sizeof( data ) ); + auto textFormat = TextFormat::autodetect( stream ); + EXPECT_EQ( textFormat.encoding, TextFormat::Encoding::Latin1 ); +} + +UTEST( TextFormat, autodetectTruncatedShiftJISLeadByte ) { + const char data[] = { static_cast( 0x81 ) }; + IOStreamMemory stream( data, sizeof( data ) ); + auto textFormat = TextFormat::autodetect( stream ); + EXPECT_EQ( textFormat.encoding, TextFormat::Encoding::Latin1 ); +} + UTEST( TextFormat, autodetectProject ) { std::string projectRoot = Sys::getProcessPath(); FileSystem::dirRemoveSlashAtEnd( projectRoot ); diff --git a/src/thirdparty/SOIL2 b/src/thirdparty/SOIL2 index d6bf0ade3..af13ed898 160000 --- a/src/thirdparty/SOIL2 +++ b/src/thirdparty/SOIL2 @@ -1 +1 @@ -Subproject commit d6bf0ade3f7668581fbdc6e44f35713cd5100d41 +Subproject commit af13ed898a05fb1dbd4c16306e630f9caf27a6f6 diff --git a/src/thirdparty/efsw b/src/thirdparty/efsw index c694c94c4..495963460 160000 --- a/src/thirdparty/efsw +++ b/src/thirdparty/efsw @@ -1 +1 @@ -Subproject commit c694c94c47caff1b3ce41f6b4309426ac354cf7f +Subproject commit 49596346078f5903af250b39d9b183e9f3db9733 diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 419d6cea8..6ee61776c 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -3365,9 +3365,13 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { auto menu = cevent->getMenu(); UIPopUpMenu* compareMenu = UIPopUpMenu::New(); - compareMenu->add( i18n( "compare_to_ellipsis", "Compare to..." ) ) + compareMenu + ->add( i18n( "compare_to_ellipsis", "Compare to..." ), nullptr, + getKeybind( "compare-to" ) ) ->setId( "compare-to" ); - compareMenu->add( i18n( "compare_with_clipboard", "Compare with clipboard" ) ) + compareMenu + ->add( i18n( "compare_with_clipboard", "Compare with clipboard" ), nullptr, + getKeybind( "compare-with-clipboard" ) ) ->setId( "compare-with-clipboard" ); menu->addSeparator(); @@ -3376,12 +3380,12 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { if ( ext == "md" || ext == "markdown" ) { menu->addSeparator(); menu->add( i18n( "show_markdown_preview", "Show Markdown Live Preview" ), - findIcon( "filetype-md" ) ) + findIcon( "filetype-md" ), getKeybind( "show-markdown-preview" ) ) ->setId( "show-markdown-preview" ); } else if ( ext == "diff" || ext == "patch" ) { menu->addSeparator(); menu->add( i18n( "show_diff_preview", "Show Diff Preview" ), - findIcon( "filetype-diff" ) ) + findIcon( "filetype-diff" ), getKeybind( "show-diff-preview" ) ) ->setId( "show-diff-preview" ); } } );